ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/external/subpack/libs/afalg_engine/Config.in b/external/subpack/libs/afalg_engine/Config.in
new file mode 100644
index 0000000..a81a892
--- /dev/null
+++ b/external/subpack/libs/afalg_engine/Config.in
@@ -0,0 +1,30 @@
+if PACKAGE_libopenssl-afalg_sync
+    comment "Build Options"
+
+    config AFALG_DIGESTS
+	bool "Build support for digest acceleration"
+	help
+	    Digests are fast in software, and accessing AF_ALG adds latency, so
+	    you'll need a large request (16KB) just to match software speed.
+	    This increases memory usage, and has problems when process fork
+	    with open digest contexts (openssh will not work because of it).
+
+    config AFALG_UPDATE_CTR_IV
+	bool "Don't rely on kernel to update CTR IV"
+	default y
+	help
+	    Don't count on the kernel driver to update the CTR-mode counter
+	    (IV).  At least one driver does not update the IV as a workaround
+	    for DMA issues.  With this option turned on, the engine will keep
+	    track of the counter, and the IV will be sent with every update.
+	    If fallback is enabled, then the counter needs to be updated by
+	    the engine anyway, and sent with the request everytime there's a
+	    switch from software to hardware, so this won't bring much gain in
+	    that case.
+
+    config AFALG_ZERO_COPY
+	bool "Use Zero-Copy Mode"
+	help
+	    Uses a Zero-Copy interface.  Even though it is supposed to improve
+	    performance, actual measurements indicate otherwise.
+endif
diff --git a/external/subpack/libs/afalg_engine/Makefile b/external/subpack/libs/afalg_engine/Makefile
new file mode 100644
index 0000000..a835359
--- /dev/null
+++ b/external/subpack/libs/afalg_engine/Makefile
@@ -0,0 +1,60 @@
+# Copyright (C) 2019 Eneas Ulir de Queiroz <cotequeiroz@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:=afalg_engine
+PKG_VERSION:=1.2.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/cotequeiroz/afalg_engine/archive/v$(PKG_VERSION)
+PKG_HASH:=3f0f6ee9ea7a5ea9c668ec16f8c492aa024a82dca78d0fbe30fd256f9da95d65
+
+PKG_MAINTAINER:=Eneas U de Queiroz <cotequeiroz@gmail.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_AFALG_DIGESTS \
+	CONFIG_AFALG_FALLBACK \
+	CONFIG_AFALG_UPDATE_CTR_IV \
+	CONFIG_AFALG_ZERO_COPY
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+include $(INCLUDE_DIR)/openssl-module.mk
+
+$(eval $(call Package/openssl/add-engine,afalg,libopenssl-afalg_sync))
+define Package/libopenssl-afalg_sync
+    $(call Package/openssl/engine/Default)
+    TITLE:=AF_ALG engine using sync crypto API
+    URL:=https://github.com/cotequeiroz/afalg_engine
+    DEPENDS += @!OPENSSL_ENGINE_BUILTIN_AFALG +kmod-crypto-user
+    CONFLICTS:=libopenssl-afalg
+    MENU:=1
+endef
+
+define Package/libopenssl-afalg_sync/description
+    This is an alternate AF_ALG engine for openssl, based on the devcrypto
+    engine, but using the AF_ALG interface instead of /dev/crypto
+
+    It is different than the AF_ALG engine that ships with OpenSSL:
+     - it is faster
+     - it uses sync calls, instead of async
+     - it suports more algorithms
+endef
+
+define Package/libopenssl-afalg_sync/config
+    source "$(SOURCE)/Config.in"
+endef
+
+CMAKE_OPTIONS += \
+	-DOPENSSL_ENGINES_DIR=/usr/lib/$(ENGINES_DIR) \
+	-DDIGESTS=$(if $(CONFIG_AFALG_DIGESTS),ON,OFF) \
+	-DUPDATE_CTR_IV=$(if $(CONFIG_AFALG_UPDATE_CTR_IV),ON,OFF) \
+	-DUSE_ZERO_COPY=$(if $(CONFIG_AFALG_ZERO_COPY),ON,OFF)
+
+$(eval $(call BuildPackage,libopenssl-afalg_sync))
diff --git a/external/subpack/libs/afalg_engine/files/afalg.cnf b/external/subpack/libs/afalg_engine/files/afalg.cnf
new file mode 100644
index 0000000..82f0cfa
--- /dev/null
+++ b/external/subpack/libs/afalg_engine/files/afalg.cnf
@@ -0,0 +1,32 @@
+[afalg_sect]
+# Leave this alone and configure algorithms with CIPERS/DIGESTS below
+default_algorithms = ALL
+
+# The following commands are only available if using the alternative
+# (sync) AFALG engine
+# Configuration commands:
+# Run 'openssl engine -t -c -vv -pre DUMP_INFO devcrypto' to see a
+# list of supported algorithms, along with their driver, whether they
+# are hw accelerated or not, and the engine's configuration commands.
+
+# USE_SOFTDRIVERS: specifies whether to use software (not accelerated)
+# drivers (0=use only accelerated drivers, 1=allow all drivers, 2=use
+# if acceleration can't be determined) [default=2]
+#USE_SOFTDRIVERS = 2
+
+# CIPHERS: either ALL, NONE, NO_ECB (all except ECB-mode) or a
+# comma-separated list of ciphers to enable [default=NO_ECB]
+# Starting in 1.2.0, if you use a cipher list, each cipher may be
+# followed by a colon (:) and the minimum request length to use
+# AF_ALG drivers for that cipher; smaller requests are processed by
+# softare; a negative value will use the default for that cipher
+#CIPHERS=AES-128-CBC:1024, AES-256-CBC:768, DES-EDE3-CBC:0
+
+# DIGESTS: either ALL, NONE, or a comma-separated list of digests to
+# enable [default=NONE]
+# It is strongly recommended not to enable digests; their performance
+# is poor, and there are many cases in which they will not work,
+# especially when calling fork with open crypto contexts.  Openssh,
+# for example, does this, and you may not be able to login.
+#DIGESTS = NONE
+
diff --git a/external/subpack/libs/afalg_engine/test.sh b/external/subpack/libs/afalg_engine/test.sh
new file mode 100644
index 0000000..19a3eda
--- /dev/null
+++ b/external/subpack/libs/afalg_engine/test.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+test_afalg_engine() {
+	opkg install openssl-util
+	openssl engine -t -c -v -pre DUMP_INFO afalg
+}
+
+case "$1" in
+	libopenssl-afalg_sync)
+		test_afalg_engine
+		;;
+	*)
+		echo "Unexpected package '$1'" >&2
+		exit 1
+		;;
+esac
diff --git a/external/subpack/libs/alsa-lib/Makefile b/external/subpack/libs/alsa-lib/Makefile
new file mode 100644
index 0000000..ee12dc3
--- /dev/null
+++ b/external/subpack/libs/alsa-lib/Makefile
@@ -0,0 +1,124 @@
+#
+# Copyright (C) 2006-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:=alsa-lib
+PKG_VERSION:=1.2.11
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://www.alsa-project.org/files/pub/lib/ \
+		https://distfiles.gentoo.org/distfiles/
+PKG_HASH:=9f3f2f69b995f9ad37359072fbc69a3a88bfba081fc83e9be30e14662795bb4d
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>, \
+		Peter Wagner <tripolar@gmx.at>
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=no-mips16 no-lto
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/alsa-lib
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=ALSA (Advanced Linux Sound Architecture) library
+  URL:=https://www.alsa-project.org/
+  DEPENDS:=@AUDIO_SUPPORT +kmod-sound-core +libpthread +librt
+  LICENSE:=LGPL-2.1-or-later
+  LICENSE_FILES:=COPYING
+endef
+
+define Package/alsa-lib/description
+ This is the library package for alsa, needed by some userspace programs.
+ You must have enabled the ALSA support in the kernel.
+endef
+
+define Package/aserver
+  SECTION:=sound
+  CATEGORY:=Sound
+  TITLE:=ALSA (Advanced Linux Sound Architecture) server
+  URL:=https://www.alsa-project.org/
+  DEPENDS:=+alsa-lib
+  LICENSE:=GPL-2.0-or-later
+  LICENSE_FILES:=aserver/COPYING
+endef
+
+define Package/aserver/description
+ This is the aserver application for ALSA.
+endef
+
+define Package/alsa-lib/conffiles
+/etc/asound.conf
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS+= \
+		--disable-python \
+		--disable-debug \
+		--without-debug \
+		--without-versioned \
+		$(SOFT_FLOAT_CONFIG_OPTION)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/alsa \
+		$(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libasound.{la,so*} \
+		$(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libatopology.{la,so*} \
+		$(1)/usr/lib/
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/alsa.pc \
+		$(1)/usr/lib/pkgconfig/
+
+	$(INSTALL_DIR) $(1)/usr/share/aclocal
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/share/aclocal/alsa.m4 \
+		$(1)/usr/share/aclocal/
+endef
+
+define Package/alsa-lib/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libasound.so.* \
+		$(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libatopology.so.* \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/share/alsa/{cards,ctl,pcm}
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/share/alsa/alsa.conf \
+		$(1)/usr/share/alsa/
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/share/alsa/ctl/* \
+		$(1)/usr/share/alsa/ctl/
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/share/alsa/pcm/* \
+		$(1)/usr/share/alsa/pcm/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/share/alsa/cards/* \
+		$(1)/usr/share/alsa/cards/
+endef
+
+define Package/aserver/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/aserver $(1)/usr/bin
+endef
+
+$(eval $(call BuildPackage,alsa-lib))
+$(eval $(call BuildPackage,aserver))
diff --git a/external/subpack/libs/alsa-lib/patches/100-link_fix.patch b/external/subpack/libs/alsa-lib/patches/100-link_fix.patch
new file mode 100644
index 0000000..96813e9
--- /dev/null
+++ b/external/subpack/libs/alsa-lib/patches/100-link_fix.patch
@@ -0,0 +1,22 @@
+--- a/src/Makefile.in
++++ b/src/Makefile.in
+@@ -497,7 +497,7 @@ clean-libLTLIBRARIES:
+ 	}
+ 
+ libasound.la: $(libasound_la_OBJECTS) $(libasound_la_DEPENDENCIES) $(EXTRA_libasound_la_DEPENDENCIES) 
+-	$(AM_V_CCLD)$(libasound_la_LINK) -rpath $(libdir) $(libasound_la_OBJECTS) $(libasound_la_LIBADD) $(LIBS)
++	$(AM_V_CCLD)$(libasound_la_LINK) -rpath $(DESTDIR)$(libdir) $(libasound_la_OBJECTS) $(libasound_la_LIBADD) $(LIBS)
+ 
+ mostlyclean-compile:
+ 	-rm -f *.$(OBJEXT)
+--- a/src/pcm/scopes/Makefile.in
++++ b/src/pcm/scopes/Makefile.in
+@@ -411,7 +411,7 @@ clean-pkglibLTLIBRARIES:
+ 	}
+ 
+ scope-level.la: $(scope_level_la_OBJECTS) $(scope_level_la_DEPENDENCIES) $(EXTRA_scope_level_la_DEPENDENCIES) 
+-	$(AM_V_CCLD)$(scope_level_la_LINK) -rpath $(pkglibdir) $(scope_level_la_OBJECTS) $(scope_level_la_LIBADD) $(LIBS)
++	$(AM_V_CCLD)$(scope_level_la_LINK) -rpath $(DESTDIR)$(pkglibdir) $(scope_level_la_OBJECTS) $(scope_level_la_LIBADD) $(LIBS)
+ 
+ mostlyclean-compile:
+ 	-rm -f *.$(OBJEXT)
diff --git a/external/subpack/libs/alsa-lib/patches/200-usleep.patch b/external/subpack/libs/alsa-lib/patches/200-usleep.patch
new file mode 100644
index 0000000..91d0b77
--- /dev/null
+++ b/external/subpack/libs/alsa-lib/patches/200-usleep.patch
@@ -0,0 +1,34 @@
+--- a/src/pcm/pcm_shm.c
++++ b/src/pcm/pcm_shm.c
+@@ -46,6 +46,14 @@
+ #include <netdb.h>
+ #include "aserver.h"
+ 
++#if _POSIX_C_SOURCE >= 200809L
++#define usleep(a) \
++	do { \
++		const struct timespec req = {0, a * 1000}; \
++		nanosleep(&req, NULL); \
++	} while(0)
++#endif
++
+ #ifndef PIC
+ /* entry for static linking */
+ const char *_snd_module_pcm_shm = "";
+--- a/src/ucm/ucm_local.h
++++ b/src/ucm/ucm_local.h
+@@ -61,6 +61,14 @@
+ #define SEQUENCE_ELEMENT_TYPE_DEV_DISABLE_SEQ	14
+ #define SEQUENCE_ELEMENT_TYPE_DEV_DISABLE_ALL	15
+ 
++#if _POSIX_C_SOURCE >= 200809L
++#define usleep(a) \
++	do { \
++		const struct timespec req = {0, a * 1000}; \
++		nanosleep(&req, NULL); \
++	} while(0)
++#endif
++
+ struct ucm_value {
+         struct list_head list;
+         char *name;
diff --git a/external/subpack/libs/alsa-ucm-conf/Makefile b/external/subpack/libs/alsa-ucm-conf/Makefile
new file mode 100644
index 0000000..f86d44c
--- /dev/null
+++ b/external/subpack/libs/alsa-ucm-conf/Makefile
@@ -0,0 +1,47 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=alsa-ucm-conf
+PKG_VERSION:=1.2.11
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://www.alsa-project.org/files/pub/lib/ \
+		https://distfiles.gentoo.org/distfiles/
+PKG_HASH:=387c01cf30e2a1676d7b8f72b2681cf219abca70dd1ec2a9e33add5bf3feae81
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/alsa-ucm-conf
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=Sound
+  TITLE:=ALSA Use Case Manager configuration (and topologies)
+  URL:=https://www.alsa-project.org/
+  PKGARCH:=all
+endef
+
+define Package/alsa-ucm-conf/description
+ This is a set of configuration files needed for some ALS utilities like alsactl.
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/alsa-ucm-conf/install
+	$(INSTALL_DIR) $(1)/usr/share/alsa
+	$(CP) $(PKG_BUILD_DIR)/ucm2 $(1)/usr/share/alsa
+endef
+
+$(eval $(call BuildPackage,alsa-ucm-conf))
diff --git a/external/subpack/libs/apr-util/Makefile b/external/subpack/libs/apr-util/Makefile
new file mode 100644
index 0000000..f953263
--- /dev/null
+++ b/external/subpack/libs/apr-util/Makefile
@@ -0,0 +1,173 @@
+#
+# Copyright (C) 2007-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:=apr-util
+PKG_VERSION:=1.6.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@APACHE/apr/
+PKG_HASH:=a41076e3710746326c3945042994ad9a4fcac0ce0277dd8fea076fec3c9772b5
+PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
+
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_CPE_ID:=cpe:/a:apache:apr-util
+
+PKG_CONFIG_DEPENDS := \
+	CONFIG_PACKAGE_libaprutil-crypto-openssl \
+	CONFIG_PACKAGE_libaprutil-dbd-mysql \
+	CONFIG_PACKAGE_libaprutil-dbd-odbc \
+	CONFIG_PACKAGE_libaprutil-dbd-pgsql \
+	CONFIG_PACKAGE_libaprutil-dbd-sqlite3 \
+	CONFIG_PACKAGE_libaprutil-dbm-gdbm \
+	CONFIG_PACKAGE_libaprutil-ldap
+
+PKG_FIXUP:=autoreconf
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libaprutil/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=http://apr.apache.org/
+endef
+
+define Package/libaprutil
+$(call Package/libaprutil/Default)
+  DEPENDS:=+libapr +libexpat +libuuid $(ICONV_DEPENDS)
+  TITLE:=Apache Portable Runtime Utility Library
+endef
+
+## Prevent apu-iconv.m4 to append "/lib" to LDFLAGS if ICONV_PREFIX is empty
+ifeq ($(ICONV_PREFIX),)
+ICONV_PREFIX=no
+endif
+
+CONFIGURE_ARGS += \
+	--with-apr="$(STAGING_DIR)/usr/bin/apr-1-config" \
+	--with-expat="$(STAGING_DIR)/usr" \
+	--with-iconv="$(ICONV_PREFIX)" \
+	--without-sqlite2
+
+ifneq ($(CONFIG_PACKAGE_libaprutil-crypto-openssl),)
+CONFIGURE_ARGS += --with-crypto --with-openssl="$(STAGING_DIR)/usr"
+else
+CONFIGURE_ARGS += --without-crypto
+endif
+
+ifneq ($(CONFIG_PACKAGE_libaprutil-dbd-mysql),)
+CONFIGURE_ARGS += --with-mysql="$(STAGING_DIR)/usr"
+else
+CONFIGURE_ARGS += --without-mysql
+endif
+
+ifneq ($(CONFIG_PACKAGE_libaprutil-dbd-odbc),)
+CONFIGURE_ARGS += --with-odbc="$(STAGING_DIR)/usr"
+else
+CONFIGURE_ARGS += --without-odbc
+endif
+
+ifneq ($(CONFIG_PACKAGE_libaprutil-dbd-pgsql),)
+CONFIGURE_ARGS += --with-pgsql="$(STAGING_DIR)/usr"
+else
+CONFIGURE_ARGS += --without-pgsql
+endif
+
+ifneq ($(CONFIG_PACKAGE_libaprutil-dbd-sqlite3),)
+CONFIGURE_ARGS += --with-sqlite3="$(STAGING_DIR)/usr"
+else
+CONFIGURE_ARGS += --without-sqlite3
+endif
+
+ifneq ($(CONFIG_PACKAGE_libaprutil-dbm-gdbm),)
+CONFIGURE_ARGS += --with-gdbm="$(STAGING_DIR)/usr"
+else
+CONFIGURE_ARGS += --without-gdbm
+endif
+
+ifneq ($(CONFIG_PACKAGE_libaprutil-ldap),)
+CONFIGURE_ARGS += \
+	--with-ldap \
+	--with-ldap-include="$(STAGING_DIR)/usr/include" \
+	--with-ldap-lib="$(STAGING_DIR)/usr/lib"
+else
+CONFIGURE_ARGS += \
+	--without-ldap
+endif
+
+CONFIGURE_VARS += \
+	ac_cv_path_ODBC_CONFIG= \
+	apu_cv_weak_symbols=yes \
+	APR_BUILD_DIR="$(STAGING_DIR)/usr/share/build-1"
+
+ifeq ($(CONFIG_USE_GLIBC)$(CONFIG_USE_MUSL),y)
+CONFIGURE_VARS += \
+	apu_cv_explicit_bzero=yes
+endif
+
+define Package/libaprutil/install/driver
+	$(INSTALL_DIR) $(1)/usr/lib/apr-util-1
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/apr-util-1/apr_$(2)*.so \
+					$(1)/usr/lib/apr-util-1
+endef
+
+define Package/libaprutil/Driver
+define Package/libaprutil-$(subst _,-,$(1))
+$(call Package/libaprutil/Default)
+  TITLE:=libaprutil - $(2) driver
+  DEPENDS:=libaprutil $(patsubst +%,+PACKAGE_libaprutil-$(subst _,-,$(1)):%,$(3))
+endef
+define Package/libaprutil-$(subst _,-,$(1))/install
+$(foreach d,$(1),$(call Package/libaprutil/install/driver,$$(1),$(d));)
+endef
+$$(eval $$(call BuildPackage,libaprutil-$(subst _,-,$(1))))
+endef
+
+# PKG_CONFIG_DEPENDS trigger configure, but the compile afterward may be
+# incomplete if the build directory is not cleaned before. This is not a
+# general observation, yet it is valid for apr-util :/
+define Build/Compile
+	$(call Build/Compile/Default,clean all)
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin $(1)/usr/include/apr-1 \
+		$(1)/usr/lib/apr-util-1 $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/apu-1-config $(1)/usr/bin
+	$(SED) '/^prefix=\|^exec_prefix=/s|/usr|$(STAGING_DIR)/usr|' $(1)/usr/bin/apu-1-config
+	$(SED) '/^bindir=/s|/usr|$$$${prefix}|' $(1)/usr/bin/apu-1-config
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/apr-1/* $(1)/usr/include/apr-1
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/apr-util-1/apr_*.{a,so} \
+			$(1)/usr/lib/apr-util-1 2>/dev/null || :
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libaprutil-1.{a,so*} \
+						$(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/apr-util-1.pc \
+					$(1)/usr/lib/pkgconfig
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/apu-1-config $(2)/bin/apu-1-config
+endef
+
+define Package/libaprutil/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libaprutil-1.so.* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libaprutil))
+$(eval $(call Package/libaprutil/Driver,crypto_openssl,OpenSSL,+libopenssl))
+$(eval $(call Package/libaprutil/Driver,dbd_mysql,MySQL,+libmariadb))
+$(eval $(call Package/libaprutil/Driver,dbd_odbc,ODBC,+unixodbc))
+$(eval $(call Package/libaprutil/Driver,dbd_pgsql,PostgreSQL,+libpq))
+$(eval $(call Package/libaprutil/Driver,dbd_sqlite3,SQLite3,+libsqlite3))
+$(eval $(call Package/libaprutil/Driver,dbm_gdbm,GDBM dbm,+libgdbm))
+$(eval $(call Package/libaprutil/Driver,ldap,LDAP,+libopenldap))
diff --git a/external/subpack/libs/apr-util/patches/004-avoid_ldap_by_defaut.patch b/external/subpack/libs/apr-util/patches/004-avoid_ldap_by_defaut.patch
new file mode 100644
index 0000000..a086f2e
--- /dev/null
+++ b/external/subpack/libs/apr-util/patches/004-avoid_ldap_by_defaut.patch
@@ -0,0 +1,34 @@
+From: Ryan Niebur <ryanryan52@gmail.com>
+Subject: by default --avoid-ldap since apache2 is the only user, and we don't
+ want to add extra dependencies to other apr-utils rdepends
+
+--- a/apu-config.in
++++ b/apu-config.in
+@@ -30,7 +30,8 @@ includedir="@includedir@"
+ LIBS="@APRUTIL_EXPORT_LIBS@"
+ INCLUDES="@APRUTIL_INCLUDES@"
+ LDFLAGS="@APRUTIL_LDFLAGS@"
+-LDAP_LIBS="@LDADD_ldap@"
++ORIG_LDAP_LIBS="@LDADD_ldap@"
++LDAP_LIBS=""
+ DBM_LIBS="@LDADD_dbm_db@ @LDADD_dbm_gdbm@ @LDADD_dbm_ndbm@"
+ 
+ APRUTIL_LIBNAME="@APRUTIL_LIBNAME@"
+@@ -55,7 +56,7 @@ Known values for OPTION are:
+   --includedir      print location where headers are installed
+   --ldflags         print linker flags
+   --libs            print library information
+-  --avoid-ldap      do not include ldap library information with --libs
++  --avoid-ldap      do not include ldap library information with --libs (default on OpenWrt)
+   --ldap-libs       print library information to link with ldap
+   --avoid-dbm       do not include DBM library information with --libs
+   --dbm-libs        print additional library information to link with DBM
+@@ -121,7 +122,7 @@ while test $# -gt 0; do
+     flags="$flags $LDAP_LIBS $DBM_LIBS $LIBS"
+     ;;
+     --ldap-libs)
+-    flags="$flags $LDAP_LIBS"
++    flags="$flags $ORIG_LDAP_LIBS"
+     ;;
+     --dbm-libs)
+     flags="$flags $DBM_LIBS"
diff --git a/external/subpack/libs/apr-util/patches/005-apu_config_dont_list_indep_libs.patch b/external/subpack/libs/apr-util/patches/005-apu_config_dont_list_indep_libs.patch
new file mode 100644
index 0000000..7f4b565
--- /dev/null
+++ b/external/subpack/libs/apr-util/patches/005-apu_config_dont_list_indep_libs.patch
@@ -0,0 +1,31 @@
+From: Peter Samuelson <peter@p12n.org>
+Subject: Prevent recursive linking of dependent libraries by apr-util users.
+
+---
+ apr-util.pc.in |    5 +++--
+ apu-config.in  |    2 +-
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/apr-util.pc.in
++++ b/apr-util.pc.in
+@@ -8,6 +8,7 @@ Name: APR Utils
+ Description: Companion library for APR
+ Version: @APRUTIL_DOTTED_VERSION@
+ # assume that apr-util requires libapr of same major version
+-Requires: apr-@APRUTIL_MAJOR_VERSION@
+-Libs: -L${libdir} -l@APRUTIL_LIBNAME@ @LDADD_ldap@ @APRUTIL_EXPORT_LIBS@
++Requires.private: apr-@APRUTIL_MAJOR_VERSION@
++Libs: -L${libdir} -l@APRUTIL_LIBNAME@ @LDADD_ldap@
++Libs.private: @APRUTIL_EXPORT_LIBS@
+ Cflags: -I${includedir}
+--- a/apu-config.in
++++ b/apu-config.in
+@@ -27,7 +27,7 @@ bindir="@bindir@"
+ libdir="@libdir@"
+ includedir="@includedir@"
+ 
+-LIBS="@APRUTIL_EXPORT_LIBS@"
++LIBS=
+ INCLUDES="@APRUTIL_INCLUDES@"
+ LDFLAGS="@APRUTIL_LDFLAGS@"
+ ORIG_LDAP_LIBS="@LDADD_ldap@"
diff --git a/external/subpack/libs/apr-util/patches/006-avoid_db_by-default.patch b/external/subpack/libs/apr-util/patches/006-avoid_db_by-default.patch
new file mode 100644
index 0000000..033bbbf
--- /dev/null
+++ b/external/subpack/libs/apr-util/patches/006-avoid_db_by-default.patch
@@ -0,0 +1,35 @@
+From: Stefan Fritsch <sf@debian.org>
+Subject: Make apu-config not output dbm libs by default. See #622081
+
+--- a/apu-config.in
++++ b/apu-config.in
+@@ -32,7 +32,8 @@ INCLUDES="@APRUTIL_INCLUDES@"
+ LDFLAGS="@APRUTIL_LDFLAGS@"
+ ORIG_LDAP_LIBS="@LDADD_ldap@"
+ LDAP_LIBS=""
+-DBM_LIBS="@LDADD_dbm_db@ @LDADD_dbm_gdbm@ @LDADD_dbm_ndbm@"
++ORIG_DBM_LIBS="@LDADD_dbm_db@ @LDADD_dbm_gdbm@ @LDADD_dbm_ndbm@"
++DBM_LIBS=""
+ 
+ APRUTIL_LIBNAME="@APRUTIL_LIBNAME@"
+ 
+@@ -58,8 +59,8 @@ Known values for OPTION are:
+   --libs            print library information
+   --avoid-ldap      do not include ldap library information with --libs (default on OpenWrt)
+   --ldap-libs       print library information to link with ldap
+-  --avoid-dbm       do not include DBM library information with --libs
+-  --dbm-libs        print additional library information to link with DBM
++  --avoid-dbm       do not include DBM library information with --libs (default on OpenWrt)
++  --dbm-libs        print library information to link with DBM
+   --srcdir          print APR-util source directory
+   --link-ld         print link switch(es) for linking to APR-util
+   --link-libtool    print the libtool inputs for linking to APR-util
+@@ -125,7 +126,7 @@ while test $# -gt 0; do
+     flags="$flags $ORIG_LDAP_LIBS"
+     ;;
+     --dbm-libs)
+-    flags="$flags $DBM_LIBS"
++    flags="$flags $ORIG_DBM_LIBS"
+     ;;
+     --includedir)
+     if test "$location" = "installed"; then
diff --git a/external/subpack/libs/apr/Makefile b/external/subpack/libs/apr/Makefile
new file mode 100644
index 0000000..20ec064
--- /dev/null
+++ b/external/subpack/libs/apr/Makefile
@@ -0,0 +1,105 @@
+#
+# Copyright (C) 2007-2011 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:=apr
+PKG_VERSION:=1.7.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@APACHE/apr/
+PKG_HASH:=cd0f5d52b9ab1704c72160c5ee3ed5d3d4ca2df4a7f8ab564e3cb352b67232f2
+
+PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
+
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_CPE_ID:=cpe:/a:apache:portable_runtime
+
+PKG_BUILD_PARALLEL:=1
+
+PKG_FIXUP:=autoreconf
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libapr
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libpthread +librt +libuuid
+  TITLE:=Apache Portable Runtime Library
+  URL:=https://apr.apache.org/
+endef
+
+CONFIGURE_ARGS += \
+	--with-devrandom=/dev/urandom \
+	$(call autoconf_bool,CONFIG_IPV6,ipv6)
+
+# XXX: ac_cv_sizeof_struct_iovec=1 is just to trick configure
+# XXX: don't set apr_cv_use_lfs64=yes, see
+#      https://www.openwall.com/lists/musl/2020/02/03/18
+# XXX: the atomic builtins used require 8-byte intrinsics, which are available
+#      on all 64-bit architectures and some arm as well as x86 32-bit platforms
+CONFIGURE_VARS += \
+	ap_cv_atomic_builtins=$(if $(CONFIG_ARCH_64BIT),yes,no) \
+	ac_cv_file__dev_zero=yes \
+	ac_cv_func_pthread_mutexattr_setpshared=yes \
+	ac_cv_func_sem_open=yes \
+	ac_cv_func_setpgrp_void=yes \
+	ac_cv_mmap__dev_zero=yes \
+	ac_cv_negative_eai=yes \
+	ac_cv_o_nonblock_inherited=no \
+	ac_cv_sizeof_struct_iovec=1 \
+	ac_cv_struct_rlimit=yes \
+	apr_cv_accept4=yes \
+	apr_cv_dup3=yes \
+	apr_cv_epoll=yes \
+	apr_cv_epoll_create1=yes \
+	apr_cv_gai_addrconfig=yes \
+	apr_cv_mutex_recursive=yes \
+	apr_cv_mutex_robust_shared=yes \
+	apr_cv_process_shared_works=yes \
+	apr_cv_pthreads_lib=-lpthread \
+	apr_cv_sock_cloexec=yes \
+	apr_cv_tcp_nodelay_with_cork=yes
+
+ifeq ($(call qstrip,$(CONFIG_LIBC)),musl)
+CONFIGURE_VARS += \
+	ac_cv_strerror_r_rc_int=yes
+endif
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin $(1)/usr/include/apr-1 \
+		$(1)/usr/lib/pkgconfig $(1)/usr/share/build-1
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/apr-1-config \
+						$(1)/usr/bin
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/apr-1/* \
+					$(1)/usr/include/apr-1
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libapr-1.{a,so*} $(1)/usr/lib
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/apr-1.pc \
+						$(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/share/build-1/* $(1)/usr/share/build-1
+	$(SED) '/^prefix=\|^exec_prefix=/s|/usr|$(STAGING_DIR)/usr|' \
+					$(1)/usr/bin/apr-1-config
+	$(SED) '/^bindir=/s|/usr|$$$${prefix}|' $(1)/usr/bin/apr-1-config
+	$(SED) '/^datadir=/s|/usr|$$$${prefix}|' $(1)/usr/bin/apr-1-config
+	$(SED) '/^datarootdir=/s|/usr|$$$${prefix}|' $(1)/usr/bin/apr-1-config
+	$(SED) 's,/usr/share/build-1,$(STAGING_DIR)/usr/share/build-1,g' \
+				$(1)/usr/share/build-1/apr_rules.mk
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/apr-1-config $(2)/bin/apr-1-config
+endef
+
+define Package/libapr/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libapr-1.so.* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libapr))
diff --git a/external/subpack/libs/avahi/Makefile b/external/subpack/libs/avahi/Makefile
new file mode 100644
index 0000000..4948dfe
--- /dev/null
+++ b/external/subpack/libs/avahi/Makefile
@@ -0,0 +1,373 @@
+#
+# Copyright (C) 2007-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:=avahi
+PKG_VERSION:=0.8
+PKG_RELEASE:=9
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/lathiat/avahi/releases/download/v$(PKG_VERSION) \
+		https://avahi.org/download
+PKG_HASH:=060309d7a333d38d951bc27598c677af1796934dbd98e1024e7ad8de798fedda
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:avahi:avahi
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/avahi/Default
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=An mDNS/DNS-SD implementation
+  URL:=http://www.avahi.org/
+endef
+
+define Package/avahi/Default/description
+ Avahi is an mDNS/DNS-SD (aka RendezVous/Bonjour/ZeroConf)
+ implementation (library). It facilitates
+ service discovery on a local network -- this means that
+ you can plug your laptop or computer into a network and
+ instantly be able to view other people who you can chat with,
+ find printers to print to or find files being shared.
+ This kind of technology is already found in MacOS X
+ (branded 'Rendezvous', 'Bonjour' and sometimes 'ZeroConf')
+ and is very convenient.
+endef
+
+define Package/libavahi/Default
+  $(call Package/avahi/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  PROVIDES:=libavahi
+  DEPENDS:=+libpthread
+endef
+
+define Package/libavahi/description
+$(call Package/avahi/Default/description)
+ .
+ The libavahi package contains the mDNS/DNS-SD shared libraries,
+ used by other programs. Specifically, it provides
+ libavahi-core and libavahi-common libraries.
+endef
+
+define Package/avahi-autoipd
+  $(call Package/avahi/Default)
+  SUBMENU:=IP Addresses and Names
+  DEPENDS:=+libdaemon
+  TITLE:=IPv4LL network address configuration daemon
+endef
+
+define Package/avahi-autoipd/description
+$(call Package/avahi/Default/description)
+ .
+ This package implements IPv4LL, "Dynamic Configuration of IPv4 Link-Local
+ Addresses" (IETF RFC3927), a protocol for automatic IP address configuration
+ from the link-local 169.254.0.0/16 range without the need for a central
+ server. It is primarily intended to be used in ad-hoc networks which lack a
+ DHCP server.
+endef
+
+define Package/avahi-dbus-daemon
+  $(call Package/avahi/Default)
+  PROVIDES:=avahi-daemon
+  VARIANT:=dbus
+  SUBMENU:=IP Addresses and Names
+  DEPENDS:=+libavahi-dbus-support +libexpat +librt +libdaemon
+  TITLE+= (daemon)
+endef
+
+define Package/avahi-nodbus-daemon
+  $(call Package/avahi/Default)
+  PROVIDES:=avahi-daemon
+  VARIANT:=nodbus
+  SUBMENU:=IP Addresses and Names
+  DEPENDS:=+libavahi-nodbus-support +libexpat +librt +libdaemon
+  TITLE+= (daemon)
+  USERID:=avahi=105:avahi=105
+endef
+
+define Package/avahi-daemon/description
+$(call Package/avahi/Default/description)
+ .
+ This package contains an mDNS/DNS-SD daemon.
+endef
+
+Package/avahi-dbus-daemon/description=$(Package/avahi-daemon/description)
+Package/avahi-nodbus-daemon/description=$(Package/avahi-daemon/description)
+
+define Package/avahi-daemon/conffiles
+/etc/avahi/avahi-daemon.conf
+endef
+
+Package/avahi-dbus-daemon/conffiles=$(Package/avahi-daemon/conffiles)
+Package/avahi-nodbus-daemon/conffiles=$(Package/avahi-daemon/conffiles)
+
+define Package/avahi-daemon-service-http
+  $(call Package/avahi/Default)
+  SUBMENU:=IP Addresses and Names
+  DEPENDS:=+avahi-daemon
+  TITLE:=Announce HTTP service
+endef
+
+define Package/avahi-daemon-service-http/description
+$(call Package/avahi/Default/description)
+ .
+ This package contains the service definition for announcing HTTP service.
+endef
+
+define Package/avahi-daemon-service-http/conffiles
+/etc/avahi/services/http.service
+endef
+
+define Package/avahi-daemon-service-ssh
+  $(call Package/avahi/Default)
+  SUBMENU:=IP Addresses and Names
+  DEPENDS:=+avahi-daemon
+  TITLE:=Announce SSH service
+endef
+
+define Package/avahi-daemon-service-ssh/description
+$(call Package/avahi/Default/description)
+ .
+ This package contains the service definition for announcing SSH service.
+endef
+
+define Package/avahi-daemon-service-ssh/conffiles
+/etc/avahi/services/ssh.service
+endef
+
+define Package/avahi-dnsconfd
+  $(call Package/avahi/Default)
+  SUBMENU:=IP Addresses and Names
+  DEPENDS:=+libavahi +libdaemon +libpthread
+  TITLE:=A Unicast DNS server using avahi-daemon
+endef
+
+define Package/avahi-dnsconfd/description
+$(call Package/avahi/Default/description)
+ .
+ This package contains a Unicast DNS server from mDNS/DNS-SD configuration
+ daemon, which may be used to configure conventional DNS servers using mDNS
+ in a DHCP-like fashion. Especially useful on IPv6.
+endef
+
+define Package/libavahi-dbus-support
+  $(call Package/libavahi/Default)
+  VARIANT:=dbus
+  DEPENDS:=+dbus
+  TITLE+= (D-Bus support)
+endef
+
+define Package/libavahi-nodbus-support
+  $(call Package/libavahi/Default)
+  VARIANT:=nodbus
+  TITLE+= (No D-Bus)
+endef
+
+define Package/libavahi-dbus-support/description
+$(call Package/libavahi/description)
+ .
+ The libavahi-dbus-support package enables
+ D-Bus support in avahi, needed to support
+ the libavahi-client library and avahi-utils.
+ .
+ Selecting this package modifies the build configuration
+ so that avahi packages are built with support for D-BUS enabled;
+ it does not generate a separate binary of its own.
+ It also automatically adds the D-Bus package to the build.
+ libavahi-dbus-support is selected automatically if you select
+ libavahi-client or avahi-utils.
+endef
+
+define Package/libavahi-nodbus-support/description
+$(call Package/libavahi/description)
+ .
+ Selecting this package modifies the build configuration
+ so that avahi packages are built without support for D-BUS enabled;
+ it does not generate a separate binary of its own.
+endef
+
+define Package/libavahi-client
+  $(call Package/avahi/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  VARIANT:=dbus
+  DEPENDS:=+avahi-dbus-daemon
+  TITLE+= (libavahi-client library)
+endef
+
+define Package/libavahi-client/description
+$(call Package/avahi/Default/description)
+ .
+ This packages adds the libavahi-client library.
+ It also automatically adds the required
+ libavahi-dbus-support and the avahi-dbus-daemon packages.
+ For more information please see the avahi documentation.
+endef
+
+define Package/avahi-utils
+  $(call Package/avahi/Default)
+  SUBMENU:=IP Addresses and Names
+  VARIANT:=dbus
+  DEPENDS:=+libavahi-client +libgdbm
+  TITLE+= (utilities)
+endef
+
+define Package/avahi-utils/description
+$(call Package/avahi/Default/description)
+ .
+ This packages installs the following avahi utility programs:
+ avahi-browse, avahi-publish, avahi-resolve, avahi-set-host-name.
+ It also automatically adds the required libavahi-client package.
+ For more information please see the avahi documentation.
+endef
+
+TARGET_CFLAGS += $(FPIC) -DGETTEXT_PACKAGE
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--disable-glib \
+	--disable-gobject \
+	--disable-introspection \
+	--disable-qt3 \
+	--disable-qt4 \
+	--disable-qt5 \
+	--disable-gtk \
+	--disable-gtk3 \
+	--disable-dbm \
+	--enable-gdbm \
+	--enable-libdaemon \
+	--disable-libevent \
+	--disable-python \
+	--disable-python-dbus \
+	--disable-mono \
+	--disable-monodoc \
+	--disable-doxygen-doc \
+	--disable-doxygen-dot \
+	--disable-doxygen-man \
+	--disable-doxygen-rtf \
+	--disable-doxygen-xml \
+	--disable-doxygen-chm \
+	--disable-doxygen-chi \
+	--disable-doxygen-html \
+	--disable-doxygen-ps \
+	--disable-doxygen-pdf \
+	--disable-manpages \
+	--disable-xmltoman \
+	--disable-tests \
+	--with-xml=expat \
+	--with-distro=none \
+	--with-avahi-user=nobody \
+	--with-avahi-group=nogroup \
+	--with-avahi-priv-access-group=nogroup \
+	--with-autoipd-user=nobody \
+	--with-autoipd-group=nogroup
+
+ifeq ($(BUILD_VARIANT),dbus)
+CONFIGURE_ARGS += \
+	--enable-dbus
+else
+CONFIGURE_ARGS += \
+	--disable-dbus
+endif
+
+CONFIGURE_VARS+= \
+	CFLAGS="$$$$CFLAGS -DNDEBUG -DDISABLE_SYSTEMD" \
+	ac_cv_header_sys_capability_h=no
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libavahi-* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libavahi/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libavahi-{common,core}.so.* $(1)/usr/lib/
+endef
+
+define Package/libavahi-dbus-support/install
+	$(call Package/libavahi/install,$(1))
+	$(INSTALL_DIR) $(1)/etc/dbus-1/system.d
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/dbus-1/system.d/* $(1)/etc/dbus-1/system.d
+endef
+
+Package/libavahi-nodbus-support/install=$(Package/libavahi/install)
+
+define Package/libavahi-client/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libavahi-client.so.* $(1)/usr/lib/
+endef
+
+define Package/avahi-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+define Package/avahi-autoipd/install
+	$(INSTALL_DIR) $(1)/etc/avahi
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/etc/avahi/avahi-autoipd.action $(1)/etc/avahi/
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/avahi-autoipd $(1)/usr/sbin/
+	$(INSTALL_DIR) $(1)/lib/netifd/proto
+	$(INSTALL_BIN) ./files/netifd-autoip.sh $(1)/lib/netifd/proto/autoip.sh
+endef
+
+define Package/avahi-daemon/install
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/avahi-daemon $(1)/usr/sbin/
+	$(INSTALL_DIR) $(1)/etc/avahi
+	$(INSTALL_DATA) ./files/avahi-daemon.conf $(1)/etc/avahi/
+	# install empty service directory so that user knows where
+	# to place custom service files
+	$(INSTALL_DIR) $(1)/etc/avahi/services
+	$(INSTALL_DIR) $(1)/etc/init.d
+	$(INSTALL_BIN) ./files/avahi-daemon.init $(1)/etc/init.d/avahi-daemon
+endef
+
+Package/avahi-dbus-daemon/install=$(Package/avahi-daemon/install)
+Package/avahi-nodbus-daemon/install=$(Package/avahi-daemon/install)
+
+define Package/avahi-daemon-service-http/install
+	$(INSTALL_DIR) $(1)/etc/avahi/services
+	$(INSTALL_DATA) ./files/service-http $(1)/etc/avahi/services/http.service
+endef
+
+define Package/avahi-daemon-service-ssh/install
+	$(INSTALL_DIR) $(1)/etc/avahi/services
+	$(INSTALL_DATA) ./files/service-ssh $(1)/etc/avahi/services/ssh.service
+endef
+
+define Package/avahi-dnsconfd/install
+	$(INSTALL_DIR) $(1)/etc/avahi
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/etc/avahi/avahi-dnsconfd.action $(1)/etc/avahi/
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/avahi-dnsconfd $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,libavahi-client))
+$(eval $(call BuildPackage,avahi-utils))
+$(eval $(call BuildPackage,libavahi-dbus-support))
+$(eval $(call BuildPackage,libavahi-nodbus-support))
+$(eval $(call BuildPackage,avahi-autoipd))
+$(eval $(call BuildPackage,avahi-dbus-daemon))
+$(eval $(call BuildPackage,avahi-nodbus-daemon))
+$(eval $(call BuildPackage,avahi-daemon-service-http))
+$(eval $(call BuildPackage,avahi-daemon-service-ssh))
+$(eval $(call BuildPackage,avahi-dnsconfd))
diff --git a/external/subpack/libs/avahi/files/avahi-daemon.conf b/external/subpack/libs/avahi/files/avahi-daemon.conf
new file mode 100644
index 0000000..3ef0788
--- /dev/null
+++ b/external/subpack/libs/avahi/files/avahi-daemon.conf
@@ -0,0 +1,28 @@
+[server]
+#host-name=foo
+#domain-name=local
+use-ipv4=yes
+use-ipv6=yes
+check-response-ttl=no
+use-iff-running=no
+
+[publish]
+publish-addresses=yes
+publish-hinfo=yes
+publish-workstation=no
+publish-domain=yes
+#publish-dns-servers=192.168.1.1
+#publish-resolv-conf-dns-servers=yes
+
+[reflector]
+enable-reflector=no
+reflect-ipv=no
+
+[rlimits]
+#rlimit-as=
+rlimit-core=0
+rlimit-data=4194304
+rlimit-fsize=0
+rlimit-nofile=30
+rlimit-stack=4194304
+rlimit-nproc=3
diff --git a/external/subpack/libs/avahi/files/avahi-daemon.init b/external/subpack/libs/avahi/files/avahi-daemon.init
new file mode 100644
index 0000000..f580a31
--- /dev/null
+++ b/external/subpack/libs/avahi/files/avahi-daemon.init
@@ -0,0 +1,18 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006 OpenWrt.org
+START=61
+
+USE_PROCD=1
+PROG=avahi-daemon
+
+start_service() {
+	procd_open_instance
+	procd_set_param command "$PROG"
+	procd_append_param command -s
+	procd_set_param respawn
+	procd_close_instance
+}
+
+reload_service() {
+	procd_send_signal "$PROG"
+}
diff --git a/external/subpack/libs/avahi/files/netifd-autoip.sh b/external/subpack/libs/avahi/files/netifd-autoip.sh
new file mode 100755
index 0000000..be6725b
--- /dev/null
+++ b/external/subpack/libs/avahi/files/netifd-autoip.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. ../netifd-proto.sh
+init_proto "$@"
+
+proto_autoip_setup() {
+	local config="$1"
+	local iface="$2"
+
+	proto_export "INTERFACE=$config"
+	proto_run_command "$config" avahi-autoipd "$iface"
+}
+
+proto_autoip_teardown() {
+	local interface="$1"
+	proto_kill_command "$interface"
+}
+
+add_protocol autoip
diff --git a/external/subpack/libs/avahi/files/service-http b/external/subpack/libs/avahi/files/service-http
new file mode 100644
index 0000000..3262037
--- /dev/null
+++ b/external/subpack/libs/avahi/files/service-http
@@ -0,0 +1,10 @@
+<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
+<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
+<service-group>
+ <name replace-wildcards="yes">%h</name>
+  <service>
+   <type>_http._tcp</type>
+   <port>80</port>
+   <txt-record>path=/</txt-record>
+  </service>
+</service-group>
diff --git a/external/subpack/libs/avahi/files/service-ssh b/external/subpack/libs/avahi/files/service-ssh
new file mode 100644
index 0000000..b445851
--- /dev/null
+++ b/external/subpack/libs/avahi/files/service-ssh
@@ -0,0 +1,9 @@
+<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
+<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
+<service-group>
+ <name replace-wildcards="yes">%h</name>
+  <service>
+   <type>_ssh._tcp</type>
+   <port>22</port>
+  </service>
+</service-group>
diff --git a/external/subpack/libs/avahi/patches/010-pkgconfig.patch b/external/subpack/libs/avahi/patches/010-pkgconfig.patch
new file mode 100644
index 0000000..f5b6f7d
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/010-pkgconfig.patch
@@ -0,0 +1,178 @@
+From 229b216d274977967790e6e2cfe13dd38effa2cf Mon Sep 17 00:00:00 2001
+From: Rosen Penev <rosenp@gmail.com>
+Date: Mon, 16 Sep 2019 18:04:58 -0700
+Subject: [PATCH] pkgconfig: Match the first three parameters
+
+For consistency between projects. Might also fix several cross compilation
+cases.
+
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+---
+ avahi-client.pc.in           | 4 ++--
+ avahi-compat-howl.pc.in      | 4 ++--
+ avahi-compat-libdns_sd.pc.in | 4 ++--
+ avahi-core.pc.in             | 4 ++--
+ avahi-glib.pc.in             | 4 ++--
+ avahi-gobject.pc.in          | 4 ++--
+ avahi-libevent.pc.in         | 4 ++--
+ avahi-qt3.pc.in              | 4 ++--
+ avahi-qt4.pc.in              | 4 ++--
+ avahi-qt5.pc.in              | 4 ++--
+ avahi-sharp.pc.in            | 2 +-
+ avahi-ui-gtk3.pc.in          | 4 ++--
+ avahi-ui-sharp.pc.in         | 2 +-
+ avahi-ui.pc.in               | 4 ++--
+ 14 files changed, 26 insertions(+), 26 deletions(-)
+
+--- a/avahi-client.pc.in
++++ b/avahi-client.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include
+ 
+ Name: avahi-client
+--- a/avahi-compat-howl.pc.in
++++ b/avahi-compat-howl.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include/avahi-compat-howl/
+ 
+ Name: avahi-compat-howl
+--- a/avahi-compat-libdns_sd.pc.in
++++ b/avahi-compat-libdns_sd.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include/avahi-compat-libdns_sd/
+ 
+ Name: avahi-compat-libdns_sd
+--- a/avahi-core.pc.in
++++ b/avahi-core.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include
+ 
+ Name: avahi-core
+--- a/avahi-glib.pc.in
++++ b/avahi-glib.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include
+ 
+ Name: avahi-glib
+--- a/avahi-gobject.pc.in
++++ b/avahi-gobject.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include
+ 
+ Name: avahi-gobject
+--- a/avahi-libevent.pc.in
++++ b/avahi-libevent.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include
+ 
+ Name: avahi-libevent
+--- a/avahi-qt3.pc.in
++++ b/avahi-qt3.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include
+ 
+ Name: avahi-qt3
+--- a/avahi-qt4.pc.in
++++ b/avahi-qt4.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include
+ 
+ Name: avahi-qt4
+--- a/avahi-qt5.pc.in
++++ b/avahi-qt5.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include
+ 
+ Name: avahi-qt5
+--- a/avahi-sharp.pc.in
++++ b/avahi-sharp.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+ exec_prefix=@prefix@
+-libdir=@libdir@
++libdir=${exec_prefix}/lib
+ 
+ Name: avahi-sharp
+ Description: Mono bindings for the Avahi mDNS/DNS-SD stack
+--- a/avahi-ui-gtk3.pc.in
++++ b/avahi-ui-gtk3.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include
+ 
+ Name: avahi-ui
+--- a/avahi-ui-sharp.pc.in
++++ b/avahi-ui-sharp.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+ exec_prefix=@prefix@
+-libdir=@libdir@
++libdir=${exec_prefix}/lib
+ 
+ Name: avahi-ui-sharp
+ Description: Mono bindings for the Avahi mDNS/DNS-SD stack
+--- a/avahi-ui.pc.in
++++ b/avahi-ui.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@prefix@
+-exec_prefix=${prefix}
+-libdir=@libdir@
++exec_prefix=@prefix@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include
+ 
+ Name: avahi-ui
diff --git a/external/subpack/libs/avahi/patches/020-revert-runtime-dir-systemd-change.patch b/external/subpack/libs/avahi/patches/020-revert-runtime-dir-systemd-change.patch
new file mode 100644
index 0000000..6a6f903
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/020-revert-runtime-dir-systemd-change.patch
@@ -0,0 +1,11 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -1004,7 +1004,7 @@ AC_DEFINE_UNQUOTED(AVAHI_AUTOIPD_GROUP,"
+ #
+ # Avahi runtime dir
+ #
+-avahi_runtime_dir="/run"
++avahi_runtime_dir="${localstatedir}/run"
+ avahi_socket="${avahi_runtime_dir}/avahi-daemon/socket"
+ AC_SUBST(avahi_runtime_dir)
+ AC_SUBST(avahi_socket)
diff --git a/external/subpack/libs/avahi/patches/100-p2p-no-iff_multicast-required.patch b/external/subpack/libs/avahi/patches/100-p2p-no-iff_multicast-required.patch
new file mode 100644
index 0000000..11a0dc7
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/100-p2p-no-iff_multicast-required.patch
@@ -0,0 +1,45 @@
+commit 2b6bccca5d9d8ab7f11219a639707b325910a0b1
+Author: Philip Prindeville <philipp@redfish-solutions.com>
+Date:   Thu Sep 17 00:27:55 2020 +0000
+
+    Logic for p2p on tunnels incorrectly requires IFF_MULTICAST (#305)
+    
+    Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com>
+
+--- a/avahi-core/iface-linux.c
++++ b/avahi-core/iface-linux.c
+@@ -105,8 +105,8 @@ static void netlink_callback(AvahiNetlin
+             (ifinfomsg->ifi_flags & IFF_UP) &&
+             (!m->server->config.use_iff_running || (ifinfomsg->ifi_flags & IFF_RUNNING)) &&
+             ((ifinfomsg->ifi_flags & IFF_LOOPBACK) ||
+-             (ifinfomsg->ifi_flags & IFF_MULTICAST)) &&
+-            (m->server->config.allow_point_to_point || !(ifinfomsg->ifi_flags & IFF_POINTOPOINT));
++             (ifinfomsg->ifi_flags & IFF_MULTICAST) ||
++             ((ifinfomsg->ifi_flags & IFF_POINTOPOINT) && m->server->config.allow_point_to_point));
+ 
+         /* Handle interface attributes */
+         l = NLMSG_PAYLOAD(n, sizeof(struct ifinfomsg));
+--- a/avahi-core/iface-pfroute.c
++++ b/avahi-core/iface-pfroute.c
+@@ -81,8 +81,8 @@ static void rtm_info(struct rt_msghdr *r
+     (ifm->ifm_flags & IFF_UP) &&
+     (!m->server->config.use_iff_running || (ifm->ifm_flags & IFF_RUNNING)) &&
+     ((ifm->ifm_flags & IFF_LOOPBACK) ||
+-     (ifm->ifm_flags & IFF_MULTICAST)) &&
+-    (m->server->config.allow_point_to_point || !(ifm->ifm_flags & IFF_POINTOPOINT));
++     (ifm->ifm_flags & IFF_MULTICAST) ||
++      ((ifm->ifm_flags & IFF_POINTOPOINT) && m->server->config.allow_point_to_point));
+ 
+   avahi_free(hw->name);
+   hw->name = avahi_strndup(sdl->sdl_data, sdl->sdl_nlen);
+@@ -428,8 +428,8 @@ static void if_add_interface(struct lifr
+             (flags & IFF_UP) &&
+             (!m->server->config.use_iff_running || (flags & IFF_RUNNING)) &&
+             ((flags & IFF_LOOPBACK) ||
+-            (flags & IFF_MULTICAST)) &&
+-            (m->server->config.allow_point_to_point || !(flags & IFF_POINTOPOINT));
++             (flags & IFF_MULTICAST) ||
++              ((flags & IFF_POINTOPOINT) && m->server->config.allow_point_to_point));
+         hw->name = avahi_strdup(lifreq->lifr_name);
+         hw->mtu = mtu;
+         /* TODO get mac address */
diff --git a/external/subpack/libs/avahi/patches/200-Fix-NULL-pointer-crashes-from-175.patch b/external/subpack/libs/avahi/patches/200-Fix-NULL-pointer-crashes-from-175.patch
new file mode 100644
index 0000000..fbf8e8e
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/200-Fix-NULL-pointer-crashes-from-175.patch
@@ -0,0 +1,136 @@
+From 9d31939e55280a733d930b15ac9e4dda4497680c Mon Sep 17 00:00:00 2001
+From: Tommi Rantala <tommi.t.rantala@nokia.com>
+Date: Mon, 8 Feb 2021 11:04:43 +0200
+Subject: [PATCH] Fix NULL pointer crashes from #175
+
+avahi-daemon is crashing when running "ping .local".
+The crash is due to failing assertion from NULL pointer.
+Add missing NULL pointer checks to fix it.
+
+Introduced in #175 - merge commit 8f75a045709a780c8cf92a6a21e9d35b593bdecd
+
+[Retrieved from:
+https://github.com/lathiat/avahi/commit/9d31939e55280a733d930b15ac9e4dda4497680c]
+Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+---
+ avahi-core/browse-dns-server.c   | 5 ++++-
+ avahi-core/browse-domain.c       | 5 ++++-
+ avahi-core/browse-service-type.c | 3 +++
+ avahi-core/browse-service.c      | 3 +++
+ avahi-core/browse.c              | 3 +++
+ avahi-core/resolve-address.c     | 5 ++++-
+ avahi-core/resolve-host-name.c   | 5 ++++-
+ avahi-core/resolve-service.c     | 5 ++++-
+ 8 files changed, 29 insertions(+), 5 deletions(-)
+
+--- a/avahi-core/browse-dns-server.c
++++ b/avahi-core/browse-dns-server.c
+@@ -343,7 +343,10 @@ AvahiSDNSServerBrowser *avahi_s_dns_serv
+         AvahiSDNSServerBrowser* b;
+ 
+         b = avahi_s_dns_server_browser_prepare(server, interface, protocol, domain, type, aprotocol, flags, callback, userdata);
++        if (!b)
++            return NULL;
++
+         avahi_s_dns_server_browser_start(b);
+ 
+         return b;
+-}
+\ No newline at end of file
++}
+--- a/avahi-core/browse-domain.c
++++ b/avahi-core/browse-domain.c
+@@ -253,7 +253,10 @@ AvahiSDomainBrowser *avahi_s_domain_brow
+         AvahiSDomainBrowser *b;
+ 
+         b = avahi_s_domain_browser_prepare(server, interface, protocol, domain, type, flags, callback, userdata);
++        if (!b)
++            return NULL;
++
+         avahi_s_domain_browser_start(b);
+ 
+         return b;
+-}
+\ No newline at end of file
++}
+--- a/avahi-core/browse-service-type.c
++++ b/avahi-core/browse-service-type.c
+@@ -171,6 +171,9 @@ AvahiSServiceTypeBrowser *avahi_s_servic
+         AvahiSServiceTypeBrowser *b;
+ 
+         b = avahi_s_service_type_browser_prepare(server, interface, protocol, domain, flags, callback, userdata);
++        if (!b)
++            return NULL;
++
+         avahi_s_service_type_browser_start(b);
+ 
+         return b;
+--- a/avahi-core/browse-service.c
++++ b/avahi-core/browse-service.c
+@@ -184,6 +184,9 @@ AvahiSServiceBrowser *avahi_s_service_br
+         AvahiSServiceBrowser *b;
+ 
+         b = avahi_s_service_browser_prepare(server, interface, protocol, service_type, domain, flags, callback, userdata);
++        if (!b)
++            return NULL;
++
+         avahi_s_service_browser_start(b);
+ 
+         return b;
+--- a/avahi-core/browse.c
++++ b/avahi-core/browse.c
+@@ -634,6 +634,9 @@ AvahiSRecordBrowser *avahi_s_record_brow
+         AvahiSRecordBrowser *b;
+ 
+         b = avahi_s_record_browser_prepare(server, interface, protocol, key, flags, callback, userdata);
++        if (!b)
++            return NULL;
++
+         avahi_s_record_browser_start_query(b);
+ 
+         return b;
+--- a/avahi-core/resolve-address.c
++++ b/avahi-core/resolve-address.c
+@@ -286,7 +286,10 @@ AvahiSAddressResolver *avahi_s_address_r
+         AvahiSAddressResolver *b;
+ 
+         b = avahi_s_address_resolver_prepare(server, interface, protocol, address, flags, callback, userdata);
++        if (!b)
++            return NULL;
++
+         avahi_s_address_resolver_start(b);
+ 
+         return b;
+-}
+\ No newline at end of file
++}
+--- a/avahi-core/resolve-host-name.c
++++ b/avahi-core/resolve-host-name.c
+@@ -318,7 +318,10 @@ AvahiSHostNameResolver *avahi_s_host_nam
+         AvahiSHostNameResolver *b;
+ 
+         b = avahi_s_host_name_resolver_prepare(server, interface, protocol, host_name, aprotocol, flags, callback, userdata);
++        if (!b)
++            return NULL;
++
+         avahi_s_host_name_resolver_start(b);
+ 
+         return b;
+-}
+\ No newline at end of file
++}
+--- a/avahi-core/resolve-service.c
++++ b/avahi-core/resolve-service.c
+@@ -519,7 +519,10 @@ AvahiSServiceResolver *avahi_s_service_r
+         AvahiSServiceResolver *b;
+ 
+         b = avahi_s_service_resolver_prepare(server, interface, protocol, name, type, domain, aprotocol, flags, callback, userdata);
++        if (!b)
++            return NULL;
++
+         avahi_s_service_resolver_start(b);
+ 
+         return b;
+-}
+\ No newline at end of file
++}
diff --git a/external/subpack/libs/avahi/patches/201-Avoid-infinite-loop-in-avahi-daemon-by-handling-HUP-event.patch b/external/subpack/libs/avahi/patches/201-Avoid-infinite-loop-in-avahi-daemon-by-handling-HUP-event.patch
new file mode 100644
index 0000000..6a2123f
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/201-Avoid-infinite-loop-in-avahi-daemon-by-handling-HUP-event.patch
@@ -0,0 +1,36 @@
+From: Riccardo Schirone <sirmy15@gmail.com>
+Date: Fri, 26 Mar 2021 11:50:24 +0100
+Subject: Avoid infinite-loop in avahi-daemon by handling HUP event in
+ client_work
+
+If a client fills the input buffer, client_work() disables the
+AVAHI_WATCH_IN event, thus preventing the function from executing the
+`read` syscall the next times it is called. However, if the client then
+terminates the connection, the socket file descriptor receives a HUP
+event, which is not handled, thus the kernel keeps marking the HUP event
+as occurring. While iterating over the file descriptors that triggered
+an event, the client file descriptor will keep having the HUP event and
+the client_work() function is always called with AVAHI_WATCH_HUP but
+without nothing being done, thus entering an infinite loop.
+
+See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=984938
+
+(cherry picked from commit 447affe29991ee99c6b9732fc5f2c1048a611d3b)
+---
+ avahi-daemon/simple-protocol.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/avahi-daemon/simple-protocol.c
++++ b/avahi-daemon/simple-protocol.c
+@@ -424,6 +424,11 @@ static void client_work(AvahiWatch *watc
+         }
+     }
+ 
++    if (events & AVAHI_WATCH_HUP) {
++        client_free(c);
++        return;
++    }
++
+     c->server->poll_api->watch_update(
+         watch,
+         (c->outbuf_length > 0 ? AVAHI_WATCH_OUT : 0) |
diff --git a/external/subpack/libs/avahi/patches/202-avahi_dns_packet_consume_uint32-fix-potential-undefined-b.patch b/external/subpack/libs/avahi/patches/202-avahi_dns_packet_consume_uint32-fix-potential-undefined-b.patch
new file mode 100644
index 0000000..c757d6b
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/202-avahi_dns_packet_consume_uint32-fix-potential-undefined-b.patch
@@ -0,0 +1,27 @@
+From: traffic-millions <60914101+traffic-millions@users.noreply.github.com>
+Date: Tue, 3 Mar 2020 11:15:48 +0800
+Subject: avahi_dns_packet_consume_uint32: fix potential undefined behavior
+
+avahi_dns_packet_consume_uint32 left shifts uint8_t values by 8, 16 and 24 bits to combine them into a 32-bit value. This produces an undefined behavior warning with gcc -fsanitize when fed input values of 128 or 255 however in testing no actual unexpected behavior occurs in practice and the 32-bit uint32_t is always correctly produced as the final value is immediately stored into a uint32_t and the compiler appears to handle this "correctly".
+
+Cast the intermediate values to uint32_t to prevent this warning and ensure the intended result is explicit.
+
+Closes: #267
+Closes: #268
+Reference: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19304
+Origin: upstream, 0.9, commit:b897ca43ac100d326d118e5877da710eb7f836f9
+---
+ avahi-core/dns.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/avahi-core/dns.c
++++ b/avahi-core/dns.c
+@@ -455,7 +455,7 @@ int avahi_dns_packet_consume_uint32(Avah
+         return -1;
+ 
+     d = (uint8_t*) (AVAHI_DNS_PACKET_DATA(p) + p->rindex);
+-    *ret_v = (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3];
++    *ret_v = ((uint32_t)d[0] << 24) | ((uint32_t)d[1] << 16) | ((uint32_t)d[2] << 8) | (uint32_t)d[3];
+     p->rindex += sizeof(uint32_t);
+ 
+     return 0;
diff --git a/external/subpack/libs/avahi/patches/203-Do-not-disable-timeout-cleanup-on-watch-cleanup.patch b/external/subpack/libs/avahi/patches/203-Do-not-disable-timeout-cleanup-on-watch-cleanup.patch
new file mode 100644
index 0000000..d6d5490
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/203-Do-not-disable-timeout-cleanup-on-watch-cleanup.patch
@@ -0,0 +1,22 @@
+From: Gustavo Noronha Silva <gustavo@noronha.dev.br>
+Date: Sun, 2 Jan 2022 22:29:04 -0300
+Subject: Do not disable timeout cleanup on watch cleanup
+
+This was causing timeouts to never be removed from the linked list that
+tracks them, resulting in both memory and CPU usage to grow larger over
+time.
+---
+ avahi-common/simple-watch.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/avahi-common/simple-watch.c
++++ b/avahi-common/simple-watch.c
+@@ -238,7 +238,7 @@ static void cleanup_watches(AvahiSimpleP
+             destroy_watch(w);
+     }
+ 
+-    s->timeout_req_cleanup = 0;
++    s->watch_req_cleanup = 0;
+ }
+ 
+ static AvahiTimeout* timeout_new(const AvahiPoll *api, const struct timeval *tv, AvahiTimeoutCallback callback, void *userdata) {
diff --git a/external/subpack/libs/avahi/patches/204-Emit-error-if-requested-service-is-not-found.patch b/external/subpack/libs/avahi/patches/204-Emit-error-if-requested-service-is-not-found.patch
new file mode 100644
index 0000000..c4c87b4
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/204-Emit-error-if-requested-service-is-not-found.patch
@@ -0,0 +1,54 @@
+From: =?utf-8?b?UGV0ciBNZW7FocOtaw==?= <pemensik@redhat.com>
+Date: Thu, 17 Nov 2022 01:51:53 +0100
+Subject: Emit error if requested service is not found
+
+It currently just crashes instead of replying with error. Check return
+value and emit error instead of passing NULL pointer to reply.
+
+Fixes #375
+
+(cherry picked from commit a2696da2f2c50ac43b6c4903f72290d5c3fa9f6f)
+---
+ avahi-daemon/dbus-protocol.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+--- a/avahi-daemon/dbus-protocol.c
++++ b/avahi-daemon/dbus-protocol.c
+@@ -375,10 +375,14 @@ static DBusHandlerResult dbus_get_altern
+     }
+ 
+     t = avahi_alternative_host_name(n);
+-    avahi_dbus_respond_string(c, m, t);
+-    avahi_free(t);
+-
+-    return DBUS_HANDLER_RESULT_HANDLED;
++    if (t) {
++        avahi_dbus_respond_string(c, m, t);
++        avahi_free(t);
++
++        return DBUS_HANDLER_RESULT_HANDLED;
++    } else {
++        return avahi_dbus_respond_error(c, m, AVAHI_ERR_NOT_FOUND, "Hostname not found");
++    }
+ }
+ 
+ static DBusHandlerResult dbus_get_alternative_service_name(DBusConnection *c, DBusMessage *m, DBusError *error) {
+@@ -389,10 +393,14 @@ static DBusHandlerResult dbus_get_altern
+     }
+ 
+     t = avahi_alternative_service_name(n);
+-    avahi_dbus_respond_string(c, m, t);
+-    avahi_free(t);
+-
+-    return DBUS_HANDLER_RESULT_HANDLED;
++    if (t) {
++        avahi_dbus_respond_string(c, m, t);
++        avahi_free(t);
++
++        return DBUS_HANDLER_RESULT_HANDLED;
++    } else {
++        return avahi_dbus_respond_error(c, m, AVAHI_ERR_NOT_FOUND, "Service not found");
++    }
+ }
+ 
+ static DBusHandlerResult dbus_create_new_entry_group(DBusConnection *c, DBusMessage *m, DBusError *error) {
diff --git a/external/subpack/libs/avahi/patches/205-conf-file-line-lengths.patch b/external/subpack/libs/avahi/patches/205-conf-file-line-lengths.patch
new file mode 100644
index 0000000..3ea8a1d
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/205-conf-file-line-lengths.patch
@@ -0,0 +1,11 @@
+--- a/avahi-daemon/ini-file-parser.c
++++ b/avahi-daemon/ini-file-parser.c
+@@ -50,7 +50,7 @@ AvahiIniFile* avahi_ini_file_load(const
+ 
+     line = 0;
+     while (!feof(fo)) {
+-        char ln[256], *s, *e;
++        char ln[1024], *s, *e;
+         AvahiIniFilePair *pair;
+ 
+         if (!(fgets(ln, sizeof(ln), fo)))
diff --git a/external/subpack/libs/avahi/patches/300-CVE-2023-38469.patch b/external/subpack/libs/avahi/patches/300-CVE-2023-38469.patch
new file mode 100644
index 0000000..cdc99b2
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/300-CVE-2023-38469.patch
@@ -0,0 +1,41 @@
+From a337a1ba7d15853fb56deef1f464529af6e3a1cf Mon Sep 17 00:00:00 2001
+From: Evgeny Vereshchagin <evvers@ya.ru>
+Date: Mon, 23 Oct 2023 20:29:31 +0000
+Subject: [PATCH] core: reject overly long TXT resource records
+
+Closes https://github.com/lathiat/avahi/issues/455
+
+CVE-2023-38469
+---
+ avahi-core/rr.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/avahi-core/rr.c
++++ b/avahi-core/rr.c
+@@ -32,6 +32,7 @@
+ #include <avahi-common/malloc.h>
+ #include <avahi-common/defs.h>
+ 
++#include "dns.h"
+ #include "rr.h"
+ #include "log.h"
+ #include "util.h"
+@@ -688,11 +689,17 @@ int avahi_record_is_valid(AvahiRecord *r
+         case AVAHI_DNS_TYPE_TXT: {
+ 
+             AvahiStringList *strlst;
++            size_t used = 0;
+ 
+-            for (strlst = r->data.txt.string_list; strlst; strlst = strlst->next)
++            for (strlst = r->data.txt.string_list; strlst; strlst = strlst->next) {
+                 if (strlst->size > 255 || strlst->size <= 0)
+                     return 0;
+ 
++                used += 1+strlst->size;
++                if (used > AVAHI_DNS_RDATA_MAX)
++                    return 0;
++            }
++
+             return 1;
+         }
+     }
diff --git a/external/subpack/libs/avahi/patches/301-CVE-2023-38470.patch b/external/subpack/libs/avahi/patches/301-CVE-2023-38470.patch
new file mode 100644
index 0000000..8f0e743
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/301-CVE-2023-38470.patch
@@ -0,0 +1,48 @@
+From b6cf29f98adce7355e8c51a6af1e338a5f94e16e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
+Date: Tue, 11 Apr 2023 15:29:59 +0200
+Subject: [PATCH] Ensure each label is at least one byte long
+
+The only allowed exception is single dot, where it should return empty
+string.
+
+Fixes #454.
+---
+ avahi-common/domain-test.c | 14 ++++++++++++++
+ avahi-common/domain.c      |  2 +-
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+--- a/avahi-common/domain-test.c
++++ b/avahi-common/domain-test.c
+@@ -45,6 +45,20 @@ int main(AVAHI_GCC_UNUSED int argc, AVAH
+     printf("%s\n", s = avahi_normalize_name_strdup("fo\\\\o\\..f oo."));
+     avahi_free(s);
+ 
++    printf("%s\n", s = avahi_normalize_name_strdup("."));
++    avahi_free(s);
++
++    s = avahi_normalize_name_strdup(",.=.}.=.?-.}.=.?.?.}.}.?.?.?.z.?.?.}.}."
++		    "}.?.?.?.r.=.=.}.=.?.}}.}.?.?.?.zM.=.=.?.?.}.}.?.?.}.}.}"
++		    ".?.?.?.r.=.=.}.=.?.}}.}.?.?.?.zM.=.=.?.?.}.}.?.?.?.zM.?`"
++		    "?.}.}.}.?.?.?.r.=.?.}.=.?.?.}.?.?.?.}.=.?.?.}??.}.}.?.?."
++		    "?.z.?.?.}.}.}.?.?.?.r.=.=.}.=.?.}}.}.?.?.?.zM.?`?.}.}.}."
++		    "??.?.zM.?`?.}.}.}.?.?.?.r.=.?.}.=.?.?.}.?.?.?.}.=.?.?.}?"
++		    "?.}.}.?.?.?.z.?.?.}.}.}.?.?.?.r.=.=.}.=.?.}}.}.?.?.?.zM."
++		    "?`?.}.}.}.?.?.?.r.=.=.?.?`.?.?}.}.}.?.?.?.r.=.?.}.=.?.?."
++		    "}.?.?.?.}.=.?.?.}");
++    assert(s == NULL);
++
+     printf("%i\n", avahi_domain_equal("\\065aa bbb\\.\\046cc.cc\\\\.dee.fff.", "Aaa BBB\\.\\.cc.cc\\\\.dee.fff"));
+     printf("%i\n", avahi_domain_equal("A", "a"));
+ 
+--- a/avahi-common/domain.c
++++ b/avahi-common/domain.c
+@@ -201,7 +201,7 @@ char *avahi_normalize_name(const char *s
+         }
+ 
+         if (!empty) {
+-            if (size < 1)
++            if (size < 2)
+                 return NULL;
+ 
+             *(r++) = '.';
diff --git a/external/subpack/libs/avahi/patches/302-CVE-2023-38471.patch b/external/subpack/libs/avahi/patches/302-CVE-2023-38471.patch
new file mode 100644
index 0000000..584d3c5
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/302-CVE-2023-38471.patch
@@ -0,0 +1,66 @@
+From d486bca7e7912c6a4b547a3c607db0d0d3124bbf Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Mon, 23 Oct 2023 13:38:35 +0200
+Subject: [PATCH] core: extract host name using avahi_unescape_label()
+
+Previously we could create invalid escape sequence when we split the
+string on dot. For example, from valid host name "foo\\.bar" we have
+created invalid name "foo\\" and tried to set that as the host name
+which crashed the daemon.
+
+Fixes #453
+
+CVE-2023-38471
+---
+ avahi-core/server.c | 27 +++++++++++++++++++++------
+ 1 file changed, 21 insertions(+), 6 deletions(-)
+
+--- a/avahi-core/server.c
++++ b/avahi-core/server.c
+@@ -1295,7 +1295,11 @@ static void update_fqdn(AvahiServer *s)
+ }
+ 
+ int avahi_server_set_host_name(AvahiServer *s, const char *host_name) {
+-    char *hn = NULL;
++    char label_escaped[AVAHI_LABEL_MAX*4+1];
++    char label[AVAHI_LABEL_MAX];
++    char *hn = NULL, *h;
++    size_t len;
++
+     assert(s);
+ 
+     AVAHI_CHECK_VALIDITY(s, !host_name || avahi_is_valid_host_name(host_name), AVAHI_ERR_INVALID_HOST_NAME);
+@@ -1305,17 +1309,28 @@ int avahi_server_set_host_name(AvahiServ
+     else
+         hn = avahi_normalize_name_strdup(host_name);
+ 
+-    hn[strcspn(hn, ".")] = 0;
++    h = hn;
++    if (!avahi_unescape_label((const char **)&hn, label, sizeof(label))) {
++        avahi_free(h);
++        return AVAHI_ERR_INVALID_HOST_NAME;
++    }
++
++    avahi_free(h);
+ 
+-    if (avahi_domain_equal(s->host_name, hn) && s->state != AVAHI_SERVER_COLLISION) {
+-        avahi_free(hn);
++    h = label_escaped;
++    len = sizeof(label_escaped);
++    if (!avahi_escape_label(label, strlen(label), &h, &len))
++        return AVAHI_ERR_INVALID_HOST_NAME;
++
++    if (avahi_domain_equal(s->host_name, label_escaped) && s->state != AVAHI_SERVER_COLLISION)
+         return avahi_server_set_errno(s, AVAHI_ERR_NO_CHANGE);
+-    }
+ 
+     withdraw_host_rrs(s);
+ 
+     avahi_free(s->host_name);
+-    s->host_name = hn;
++    s->host_name = avahi_strdup(label_escaped);
++    if (!s->host_name)
++        return AVAHI_ERR_NO_MEMORY;
+ 
+     update_fqdn(s);
+ 
diff --git a/external/subpack/libs/avahi/patches/303-CVE-2023-38472.patch b/external/subpack/libs/avahi/patches/303-CVE-2023-38472.patch
new file mode 100644
index 0000000..2d18926
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/303-CVE-2023-38472.patch
@@ -0,0 +1,36 @@
+From d886dc5b1d3d2b76aaa38289245acfdfa979ca6c Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Thu, 19 Oct 2023 17:36:44 +0200
+Subject: [PATCH] core: make sure there is rdata to process before parsing it
+
+Fixes #452
+
+CVE-2023-38472
+---
+ avahi-client/client-test.c      | 3 +++
+ avahi-daemon/dbus-entry-group.c | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+--- a/avahi-client/client-test.c
++++ b/avahi-client/client-test.c
+@@ -258,6 +258,9 @@ int main (AVAHI_GCC_UNUSED int argc, AVA
+     printf("%s\n", avahi_strerror(avahi_entry_group_add_service (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "Lathiat's Site", "_http._tcp", NULL, NULL, 80, "foo=bar", NULL)));
+     printf("add_record: %d\n", avahi_entry_group_add_record (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "TestX", 0x01, 0x10, 120, "\5booya", 6));
+ 
++    error = avahi_entry_group_add_record (group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "TestX", 0x01, 0x10, 120, "", 0);
++    assert(error != AVAHI_OK);
++
+     avahi_entry_group_commit (group);
+ 
+     domain = avahi_domain_browser_new (avahi, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE, 0, avahi_domain_browser_callback, (char*) "omghai3u");
+--- a/avahi-daemon/dbus-entry-group.c
++++ b/avahi-daemon/dbus-entry-group.c
+@@ -340,7 +340,7 @@ DBusHandlerResult avahi_dbus_msg_entry_g
+         if (!(r = avahi_record_new_full (name, clazz, type, ttl)))
+             return avahi_dbus_respond_error(c, m, AVAHI_ERR_NO_MEMORY, NULL);
+ 
+-        if (avahi_rdata_parse (r, rdata, size) < 0) {
++        if (!rdata || avahi_rdata_parse (r, rdata, size) < 0) {
+             avahi_record_unref (r);
+             return avahi_dbus_respond_error(c, m, AVAHI_ERR_INVALID_RDATA, NULL);
+         }
diff --git a/external/subpack/libs/avahi/patches/304-CVE-2023-38473.patch b/external/subpack/libs/avahi/patches/304-CVE-2023-38473.patch
new file mode 100644
index 0000000..7071751
--- /dev/null
+++ b/external/subpack/libs/avahi/patches/304-CVE-2023-38473.patch
@@ -0,0 +1,100 @@
+From 5edc17b7913cac824daa09fca9976c9c19e88822 Mon Sep 17 00:00:00 2001
+From: Michal Sekletar <msekleta@redhat.com>
+Date: Wed, 11 Oct 2023 17:45:44 +0200
+Subject: [PATCH] common: derive alternative host name from its unescaped
+ version
+
+Normalization of input makes sure we don't have to deal with special
+cases like unescaped dot at the end of label.
+
+Fixes #451 #487
+CVE-2023-38473
+---
+ avahi-common/alternative-test.c |  3 +++
+ avahi-common/alternative.c      | 27 +++++++++++++++++++--------
+ 2 files changed, 22 insertions(+), 8 deletions(-)
+
+--- a/avahi-common/alternative-test.c
++++ b/avahi-common/alternative-test.c
+@@ -31,6 +31,9 @@ int main(AVAHI_GCC_UNUSED int argc, AVAH
+     const char* const test_strings[] = {
+         "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+         "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXüüüüüüü",
++        ").",
++        "\\.",
++        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\\",
+         "gurke",
+         "-",
+         " #",
+--- a/avahi-common/alternative.c
++++ b/avahi-common/alternative.c
+@@ -49,15 +49,20 @@ static void drop_incomplete_utf8(char *c
+ }
+ 
+ char *avahi_alternative_host_name(const char *s) {
++    char label[AVAHI_LABEL_MAX], alternative[AVAHI_LABEL_MAX*4+1];
++    char *alt, *r, *ret;
+     const char *e;
+-    char *r;
++    size_t len;
+ 
+     assert(s);
+ 
+     if (!avahi_is_valid_host_name(s))
+         return NULL;
+ 
+-    if ((e = strrchr(s, '-'))) {
++    if (!avahi_unescape_label(&s, label, sizeof(label)))
++        return NULL;
++
++    if ((e = strrchr(label, '-'))) {
+         const char *p;
+ 
+         e++;
+@@ -74,19 +79,18 @@ char *avahi_alternative_host_name(const
+ 
+     if (e) {
+         char *c, *m;
+-        size_t l;
+         int n;
+ 
+         n = atoi(e)+1;
+         if (!(m = avahi_strdup_printf("%i", n)))
+             return NULL;
+ 
+-        l = e-s-1;
++        len = e-label-1;
+ 
+-        if (l >= AVAHI_LABEL_MAX-1-strlen(m)-1)
+-            l = AVAHI_LABEL_MAX-1-strlen(m)-1;
++        if (len >= AVAHI_LABEL_MAX-1-strlen(m)-1)
++            len = AVAHI_LABEL_MAX-1-strlen(m)-1;
+ 
+-        if (!(c = avahi_strndup(s, l))) {
++        if (!(c = avahi_strndup(label, len))) {
+             avahi_free(m);
+             return NULL;
+         }
+@@ -100,7 +104,7 @@ char *avahi_alternative_host_name(const
+     } else {
+         char *c;
+ 
+-        if (!(c = avahi_strndup(s, AVAHI_LABEL_MAX-1-2)))
++        if (!(c = avahi_strndup(label, AVAHI_LABEL_MAX-1-2)))
+             return NULL;
+ 
+         drop_incomplete_utf8(c);
+@@ -109,6 +113,13 @@ char *avahi_alternative_host_name(const
+         avahi_free(c);
+     }
+ 
++    alt = alternative;
++    len = sizeof(alternative);
++    ret = avahi_escape_label(r, strlen(r), &alt, &len);
++
++    avahi_free(r);
++    r = avahi_strdup(ret);
++
+     assert(avahi_is_valid_host_name(r));
+ 
+     return r;
diff --git a/external/subpack/libs/boost/Makefile b/external/subpack/libs/boost/Makefile
new file mode 100644
index 0000000..db610f8
--- /dev/null
+++ b/external/subpack/libs/boost/Makefile
@@ -0,0 +1,514 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+#
+# Original Boost 1.51 Makefile by Mirko Vogt <mirko@openwrt.org>
+# Dude, this "boost" is really one of the most crude stuff I ported yet.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=boost
+PKG_VERSION:=1.86.0
+PKG_SOURCE_VERSION:=1_86_0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)_$(PKG_SOURCE_VERSION).tar.bz2
+PKG_SOURCE_URL:=@SF/$(PKG_NAME)/$(PKG_NAME)/$(PKG_VERSION) https://boostorg.jfrog.io/artifactory/main/release/$(PKG_VERSION)/source/
+PKG_HASH:=1bed88e40401b2cb7a1f76d4bab499e352fa4d0c5f31c0dbae64e24d34d7513b
+
+PKG_MAINTAINER:=Carlos M. Ferreira <carlosmf.pt@gmail.com>
+PKG_LICENSE:=BSL-1.0
+PKG_LICENSE_FILES:=LICENSE_1_0.txt
+PKG_CPE_ID:=cpe:/a:boost:boost
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)_$(PKG_SOURCE_VERSION)
+HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)_$(PKG_SOURCE_VERSION)
+
+HOST_BUILD_PARALLEL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=no-mips16 gc-sections lto
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/boost/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Boost C++ source library
+  URL:=https://www.boost.org
+  DEPENDS:=+libstdcpp +libpthread +librt
+endef
+
+define Package/boost/description
+This package provides the Boost v1.86.0 libraries.
+Boost is a set of free, peer-reviewed, portable C++ source libraries.
+
+This package provides the following run-time libraries:
+ - atomic
+ - charconv
+ - chrono
+ - cobalt
+ - container
+ - context
+ - contract
+ - coroutine and coroutine2 (Coroutine is deprecated - use Coroutine2)
+ - date_time
+ - exception
+ - filesystem
+ - fiber
+ - graph
+ - - graph-parallel
+ - iostreams
+ - json
+ - locale
+ - log
+ - math
+ - nowide
+ - program_options
+ - python3
+ - random
+ - regex
+ - serialization and wserialization
+ - stackstrace
+ - system
+ - thread
+ - timer
+ - type_erasure
+ - url
+ - wave
+
+There are many more header-only libraries supported by Boost.
+See more at http://www.boost.org/doc/libs/1_86_0/
+endef
+
+PKG_BUILD_DEPENDS:=boost/host
+
+include ../../lang/python/python3-version.mk
+BOOST_PYTHON3_VER=$(PYTHON3_VERSION)
+
+BOOST_LIBS =
+
+define Package/boost-libs
+$(call Package/boost/Default)
+  TITLE+= (all libs)
+  DEPENDS+= $(BOOST_DEPENDS)
+  HIDDEN:=1
+endef
+
+define Package/boost-libs/description
+ This meta package contains only dependencies to the other libraries from
+ the boost libraries collection.
+endef
+
+# Create a meta-package of dependent libraries (for ALL)
+define Package/boost-libs/install
+  true
+endef
+
+define Package/boost/install
+  true
+endef
+
+define Package/boost
+  $(call Package/boost/Default)
+  TITLE+= packages
+endef
+
+define Package/boost/config
+	# Invisible config dependency
+	config boost-context-exclude
+		bool
+		default y if (TARGET_arc770 || TARGET_archs38)
+		default n
+
+	config boost-coroutine-exclude
+		bool
+		default y if boost-context-exclude
+		default n
+
+	config boost-fiber-exclude
+		bool
+		default y if boost-coroutine-exclude
+		default n
+
+	menu "Select Boost Options"
+		depends on PACKAGE_boost
+		comment "Boost compilation options."
+
+		choice
+			prompt "Compile Visibility."
+				default boost-compile-visibility-hidden
+				help
+					Choose Boost symbols compilation visibility.
+					-> Global:
+						- a.k.a. "default" in gcc documentation. Global symbols are considered public,
+						 they are exported from shared libraries and can be redefined by another
+						 shared library or executable.
+					-> Protected:
+						- a.k.a. "symbolic". Protected symbols are exported from shared libraries but
+						 cannot be redefined by another shared library or executable. This mode is
+						 not supported on some platforms, for example OS X.
+					-> Hidden:
+						- Hidden symbols are not exported from shared libraries and cannot be
+						 redefined by a different shared library or executable loaded in a process.
+						 In this mode, public symbols have to be explicitly marked in the source code
+						 to be exported from shared libraries. This is the recommended mode.
+
+			config boost-compile-visibility-global
+				bool "Global"
+
+			config boost-compile-visibility-protected
+				bool "Protected"
+
+			config boost-compile-visibility-hidden
+				bool "Hidden"
+		endchoice
+
+		choice
+			prompt "Compile Boost libraries."
+				default boost-static-and-shared-libs
+				help
+					Choose which version to compile.
+					-> Shared:
+						- Only Shared libs will be compiled.
+					-> Static:
+						- Only Static libs will be compiled.
+					-> Both:
+						- Both Static and Shared libs will be compiled.
+
+			config boost-shared-libs
+				bool "Shared"
+
+			config boost-static-libs
+				bool "Static"
+
+			config boost-static-and-shared-libs
+				bool "Both"
+		endchoice
+
+		choice
+			prompt "Selects Boost Runtime linkage."
+			default boost-runtime-shared
+			help
+				Choose which C and C++ runtimes to use:
+				-> Use Shared runtimes.
+				-> Use Static runtimes.
+					- Not available if Shared libs are to be built.
+				-> Use both runtimes.
+					- Not available if Shared libs are to be built.
+					- Two separate versions of Boost are built, linking each to a different runtime.
+					- This option requires "Use tagged names" option to be active.
+
+			config boost-runtime-shared
+				bool "Shared"
+
+			config boost-runtime-static
+				depends on (!boost-shared-libs && !boost-static-and-shared-libs)
+				bool "Static"
+
+			config boost-runtime-static-and-shared
+				depends on (boost-use-name-tags && !boost-shared-libs && !boost-static-and-shared-libs)
+				bool "Both"
+		endchoice
+
+		choice
+			prompt "Select a Variant."
+			default boost-variant-release
+			help
+				Chooses which boost variant should be selected:
+				-> Release: Optimizes Boost for release.
+					- Optimization: Speed;  Debug Symbols: Off; Inlining: Full; Runtime Debugging: Off.
+				-> Debug:
+					- Optimization: Off; Debug Symbols: On; Inlining: Off; Runtime Debugging: On.
+				-> Profile:
+					- Profiling: On;  Debug Symbols: On.
+
+			config boost-variant-release
+				bool "Release"
+
+			config boost-variant-debug
+				bool "Debug"
+
+			config boost-variant-profile
+				bool "Profile"
+		endchoice
+
+		config boost-use-name-tags
+			bool "Use tagged names."
+			help
+				Add name tags the lib files, to diferentiate each library version:
+				  "-mt" for multi-threading.
+				  "-d" for debugging.
+				  "-s" for runtime static link".
+				Might break compatibility with libraries that expect boost libs with default names.
+			default n
+
+		config boost-single-thread
+			depends on boost-use-name-tags
+			bool "Single thread Support."
+			help
+				Compile Boost libraries in single-thread mode.
+			default n
+
+		config boost-build-type-complete
+			depends on boost-use-name-tags
+			bool "Complete Boost Build."
+			help
+				Builds both release and debug libs. It will take much longer to compile.
+			default n
+	endmenu
+
+	menu "Select Boost libraries"
+		depends on PACKAGE_boost
+		comment "Libraries"
+
+		config boost-libs-all
+			bool "Include all Boost libraries."
+			default m if ALL
+			select PACKAGE_boost-libs
+			select boost-test-pkg
+			select boost-graph-parallel
+
+		config boost-test-pkg
+			bool "Boost test package."
+			default m if ALL
+			select PACKAGE_boost-test
+
+		config boost-graph-parallel
+			bool "Boost parallel graph support."
+			select PACKAGE_boost-graph
+			default m if ALL
+
+		$(foreach lib,$(BOOST_LIBS),
+		config PACKAGE_boost-$(lib)
+			prompt "Boost $(lib) $(if $(findstring python3,$(lib)),$(paren_left)v$(BOOST_PYTHON3_VER)$(paren_right) ,)library."
+			default m if ALL
+			$(if $(findstring fiber,$(lib)),depends on !boost-fiber-exclude,)\
+			$(if $(findstring context,$(lib)),depends on !boost-context-exclude,)
+			$(if $(findstring coroutine,$(lib)),depends on !boost-coroutine-exclude,)
+		)
+	endmenu
+endef
+
+PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_boost-test
+
+define Package/boost-test
+	$(call Package/boost/Default)
+	TITLE+= (test)
+	HIDDEN:=1
+	DEPENDS+=+boost-system +boost-timer
+endef
+
+define Build/Configure
+endef
+
+define Package/boost/Default/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/lib/libboost_$(2)*.so* $(1)/usr/lib/
+endef
+
+# 1: short name
+# 2: dependencies on other boost libraries (short name)
+# 3: dependencies on other packages
+# 4: conditional/inward dependencies
+# 5: dependencies compiled only when this package has been selected
+define DefineBoostLibrary
+  BOOST_DEPENDS+= +$(if $(4),$(4):boost-$(1),boost-$(1))
+  PKG_CONFIG_DEPENDS+= CONFIG_PACKAGE_boost-$(1)
+
+  BOOST_LIBS+= $(1)
+
+  define Package/boost-$(1)
+    $(call Package/boost/Default)
+    TITLE+= ($(1))
+    DEPENDS+= $(foreach lib,$(2),+boost-$(lib)) $(3) $(if $(4),@$(4),) $(patsubst %,+PACKAGE_boost-$(1):%,$(5))
+    HIDDEN:=1
+  endef
+
+  define Package/boost-$(1)/description
+   This package contains the Boost $(1) library.
+  endef
+
+  define Package/boost-$(1)/install
+    $(if $(CONFIG_boost-static-libs),true,$(call Package/boost/Default/install,$$(1),$(1)))
+  endef
+endef
+
+$(eval $(call DefineBoostLibrary,atomic,system))
+$(eval $(call DefineBoostLibrary,charconv,,,,libquadmath))
+$(eval $(call DefineBoostLibrary,chrono,system))
+$(eval $(call DefineBoostLibrary,cobalt,system container))
+$(eval $(call DefineBoostLibrary,container))
+$(eval $(call DefineBoostLibrary,context,chrono system,,!boost-context-exclude))
+$(eval $(call DefineBoostLibrary,contract,system))
+$(eval $(call DefineBoostLibrary,coroutine,system chrono context thread,,!boost-coroutine-exclude))
+$(eval $(call DefineBoostLibrary,date_time))
+#$(eval $(call DefineBoostLibrary,exception,,))
+$(eval $(call DefineBoostLibrary,fiber,coroutine filesystem,,!boost-fiber-exclude))
+$(eval $(call DefineBoostLibrary,filesystem,system atomic))
+$(eval $(call DefineBoostLibrary,graph,regex))
+$(eval $(call DefineBoostLibrary,iostreams,,,,zlib liblzma libbz2 libzstd))
+$(eval $(call DefineBoostLibrary,json,container))
+$(eval $(call DefineBoostLibrary,locale,system chrono thread,,,icu))
+$(eval $(call DefineBoostLibrary,log,system chrono date_time thread filesystem regex))
+$(eval $(call DefineBoostLibrary,math))
+#$(eval $(call DefineBoostLibrary,mpi,,)) # OpenMPI does no exist in OpenWRT at this time.
+$(eval $(call DefineBoostLibrary,nowide))
+$(eval $(call DefineBoostLibrary,program_options))
+$(eval $(call DefineBoostLibrary,python3,,,,python3-base))
+$(eval $(call DefineBoostLibrary,random,system))
+$(eval $(call DefineBoostLibrary,regex,,,,icu))
+$(eval $(call DefineBoostLibrary,serialization))
+$(eval $(call DefineBoostLibrary,wserialization,serialization))
+$(eval $(call DefineBoostLibrary,stacktrace))
+$(eval $(call DefineBoostLibrary,system))
+$(eval $(call DefineBoostLibrary,thread,system chrono atomic))
+$(eval $(call DefineBoostLibrary,timer,chrono))
+$(eval $(call DefineBoostLibrary,type_erasure,chrono system thread))
+$(eval $(call DefineBoostLibrary,url))
+$(eval $(call DefineBoostLibrary,wave,date_time thread filesystem))
+
+include $(INCLUDE_DIR)/host-build.mk
+
+define Host/Compile
+	# b2 does not provide a configure-script nor a Makefile
+	( cd $(HOST_BUILD_DIR)/tools/build/src/engine ; ./build.sh gcc )
+
+	( cd $(HOST_BUILD_DIR) ; \
+		./bootstrap.sh --prefix=$(STAGING_DIR_HOSTPKG) \
+			--with-libraries=context,filesystem,program_options,regex,system ;\
+		./b2 --ignore-site-config install )
+endef
+
+CONFIGURE_PREFIX:=$(PKG_INSTALL_DIR)
+TARGET_LDFLAGS += -pthread -lrt -lstdc++ -Wl,--as-needed,--print-gc-sections
+
+TARGET_CFLAGS += \
+	$(if $(CONFIG_SOFT_FLOAT),-DBOOST_NO_FENV_H) -fPIC
+
+ifeq ($(word 1,$(subst ., ,$(call qstrip,$(CONFIG_GCC_VERSION)))),11)
+    EXTRA_CXXFLAGS += -std=gnu++20
+else
+    EXTRA_CXXFLAGS += -std=gnu++23
+endif
+
+ifneq ($(findstring mips,$(ARCH)),)
+    BOOST_ABI = o32
+    ifneq ($(findstring 64,$(ARCH)),)
+        BOOST_ABI = n64
+    endif
+else ifneq ($(findstring arm,$(ARCH)),)
+    BOOST_ABI = aapcs
+else ifeq ($(ARCH),aarch64)
+    BOOST_ABI = aapcs
+else
+    BOOST_ABI = sysv
+endif
+
+comma := ,
+
+define Build/Compile
+	$(info Selected Boost API $(BOOST_ABI) for architecture $(ARCH) and cpu type $(CONFIG_CPU_TYPE) $(if $(CONFIG_CPU_SUBTYPE),and cpu subtype $(CONFIG_CPU_SUBTYPE),))
+	( cd $(PKG_BUILD_DIR) ; \
+		echo "using gcc : $(GCC_VERSION) : $(GNU_TARGET_NAME)-gcc : <compileflags>\"$(TARGET_CFLAGS)\" <cxxflags>\"$(TARGET_CXXFLAGS) $(EXTRA_CXXFLAGS)\" <linkflags>\"$(TARGET_LDFLAGS)\" ;" > \
+			tools/build/src/user-config.jam ; \
+		b2 \
+			$(CONFIGURE_ARGS) \
+			--ignore-site-config \
+			--toolset=gcc abi=$(BOOST_ABI) \
+			--disable-long-double \
+			$(if $(CONFIG_boost-compile-visibility-global), visibility=global,) \
+			$(if $(CONFIG_boost-compile-visibility-protected), visibility=protected,) \
+			$(if $(CONFIG_boost-compile-visibility-hidden), visibility=hidden,) \
+			$(if $(CONFIG_boost-variant-release), variant=release,) \
+			$(if $(CONFIG_boost-variant-debug), variant=debug,) \
+			$(if $(CONFIG_boost-variant-profile), variant=profile,) \
+			$(if $(CONFIG_boost-use-name-tags),--layout=tagged,--layout=system) \
+			$(if $(CONFIG_boost-build-type-complete),--build-type=complete,--build-type=minimal) \
+			$(if $(CONFIG_boost-shared-libs),link=shared,) \
+			$(if $(CONFIG_boost-static-libs),link=static,) \
+			$(if $(CONFIG_boost-static-and-shared-libs),link=static$(comma)shared,) \
+			$(if $(CONFIG_boost-runtime-shared),runtime-link=shared,) \
+			$(if $(CONFIG_boost-runtime-static),runtime-link=static,) \
+			$(if $(CONFIG_boost-runtime-static-and-shared),runtime-link=shared$(comma)static,) \
+			$(if $(CONFIG_boost-single-thread),threading=single,) \
+			threading=multi \
+			--without-mpi \
+			$(if $(CONFIG_boost-graph-parallel),,--without-graph_parallel) \
+			$(if $(CONFIG_PACKAGE_boost-test),,--without-test) \
+			--without-python \
+			$(foreach lib,$(BOOST_LIBS), \
+				$(if $(findstring python3,$(lib)),, \
+					$(if $(CONFIG_PACKAGE_boost-$(lib)),, \
+						$(if $(findstring wserialization,$(lib)),,--without-$(lib)) \
+					) \
+				) \
+			) \
+			$(if $(CONFIG_PACKAGE_boost-locale),boost.locale.std=off boost.locale.posix=off) \
+			\
+			$(if $(CONFIG_PACKAGE_boost-iostreams),-sNO_BZIP2=1 -sZLIB_INCLUDE=$(STAGING_DIR)/usr/include \
+				-sZLIB_LIBPATH=$(STAGING_DIR)/usr/lib) \
+			install ;\
+			$(if $(CONFIG_PACKAGE_boost-python3), \
+				echo "using gcc : $(GCC_VERSION) : $(GNU_TARGET_NAME)-gcc : <compileflags>\"$(TARGET_CFLAGS) -I$(STAGING_DIR)/usr/include/python$(BOOST_PYTHON3_VER)/ \" <cxxflags>\"$(TARGET_CXXFLAGS) $(EXTRA_CXXFLAGS)\" <linkflags>\"$(TARGET_LDFLAGS)\" ;" > \
+					tools/build/src/user-config.jam ; \
+				echo "using python : $(BOOST_PYTHON3_VER) : : $(STAGING_DIR)/usr/include/python$(BOOST_PYTHON3_VER)/ : $(STAGING_DIR)/usr/lib/libpython$(BOOST_PYTHON3_VER).so ;" >> \
+					tools/build/src/user-config.jam; \
+				b2 -a \
+					$(CONFIGURE_ARGS) \
+					--ignore-site-config \
+					--toolset=gcc abi=$(BOOST_ABI) \
+					--disable-long-double \
+					$(if $(CONFIG_boost-variant-release), variant=release,) \
+					$(if $(CONFIG_boost-variant-debug), variant=debug,) \
+					$(if $(CONFIG_boost-variant-profile), variant=profile,) \
+					$(if $(CONFIG_boost-use-name-tags),--layout=tagged,--layout=system) \
+					$(if $(CONFIG_boost-build-type-complete),--build-type=complete,--build-type=minimal) \
+					$(if $(CONFIG_boost-shared-libs),link=shared,) \
+					$(if $(CONFIG_boost-static-libs),link=static,) \
+					$(if $(CONFIG_boost-static-and-shared-libs),link=static$(comma)shared,) \
+					$(if $(CONFIG_boost-runtime-shared),runtime-link=shared,) \
+					$(if $(CONFIG_boost-runtime-static),runtime-link=static,) \
+					$(if $(CONFIG_boost-runtime-static-and-shared),runtime-link=shared$(comma)static,) \
+					$(if $(CONFIG_boost-single-thread),threading=single,) \
+					threading=multi \
+					--with-python \
+				install ;\
+			,) \
+	)
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) \
+		$(1)/usr/include/boost/
+
+	$(CP) \
+		$(PKG_INSTALL_DIR)/include/boost/* \
+		$(1)/usr/include/boost/ \
+		# copies _all_ header files - independent of <--with-library>-argument above
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	# copies all cmake files, compiled archive and shared object files
+	$(CP) -v $(PKG_INSTALL_DIR)/lib/{*.{a,so*},cmake} $(1)/usr/lib/ || :
+endef
+
+define Host/Install
+	$(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/bin
+	$(CP) $(HOST_BUILD_DIR)/tools/build/src/engine/b2 $(STAGING_DIR_HOSTPKG)/bin/
+endef
+
+define Package/boost-test/install
+	$(if $(CONFIG_boost-static-libs),true,
+		$(INSTALL_DIR) $(1)/usr/lib
+		$(CP) $(PKG_INSTALL_DIR)/lib/libboost_{unit_test_framework,prg_exec_monitor}*.so* $(1)/usr/lib/
+	)
+endef
+
+$(eval $(call HostBuild))
+
+$(foreach lib,$(BOOST_LIBS),$(eval $(call BuildPackage,boost-$(lib))))
+$(eval $(call BuildPackage,boost-test))
+$(eval $(call BuildPackage,boost-libs))
+$(eval $(call BuildPackage,boost))
diff --git a/external/subpack/libs/boringssl/Makefile b/external/subpack/libs/boringssl/Makefile
new file mode 100644
index 0000000..f912a29
--- /dev/null
+++ b/external/subpack/libs/boringssl/Makefile
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2021 Martin Schneider <martschneider@google.com>
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=boringssl
+PKG_VERSION:=20210608
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://boringssl.googlesource.com/boringssl
+PKG_SOURCE_DATE:=2021-06-08
+PKG_SOURCE_VERSION:=1f54fd9864c054dc33e15b1144e2a6a19fa0a52e
+PKG_MIRROR_HASH:=d69c6437981471451dc699742bb06a022579de1a63906c9fe398aae053fc33bf
+
+PKG_MAINTAINER:=Martin Schneider <martschneider@google.com>
+PKG_LICENSE:=OpenSSL ISC
+PKG_LICENSE_FILES:=LICENSE
+PKG_BUILD_DEPENDS:=golang/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+include ../../lang/golang/golang-values.mk
+
+define Package/boringssl
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=An implementation of the TLS protocol
+	URL:=https://boringssl.googlesource.com/boringssl/
+	DEPENDS:=+libstdcpp $(GO_ARCH_DEPENDS) @!(mips||mips64)
+endef
+
+define Package/boringssl/description
+	An implementation of the TLS protocol
+endef
+
+CMAKE_OPTIONS+=-DBUILD_SHARED_LIBS=ON
+
+define Package/boringssl/install
+	$(INSTALL_DIR) $(1)/usr/lib/boringssl
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/bin/lib{crypto,ssl}.so $(1)/usr/lib/boringssl
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib/boringssl
+	$(INSTALL_DIR) $(1)/usr/include/boringssl
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/lib{crypto,ssl}.so $(1)/usr/lib/boringssl
+	$(CP) $(PKG_BUILD_DIR)/include/* $(1)/usr/include/boringssl
+endef
+
+$(eval $(call BuildPackage,boringssl))
diff --git a/external/subpack/libs/boringssl/patches/300-support-mipsel-arch.patch b/external/subpack/libs/boringssl/patches/300-support-mipsel-arch.patch
new file mode 100644
index 0000000..2d44be7
--- /dev/null
+++ b/external/subpack/libs/boringssl/patches/300-support-mipsel-arch.patch
@@ -0,0 +1,21 @@
+From 425b44bc6f6abcd4c12e2fb72f42622e825ad700 Mon Sep 17 00:00:00 2001
+From: Martin Schneider <martschneider@google.com>
+Date: Mon, 25 Oct 2021 09:53:33 +0800
+Subject: [PATCH] Support mipsel architecture.
+
+Signed-off-by: Martin Schneider <martschneider@google.com>
+---
+ CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -489,7 +489,7 @@ elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUA
+   set(ARCH "aarch64")
+ elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm*")
+   set(ARCH "arm")
+-elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "mips")
++elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^mips*")
+   # Just to avoid the “unknown processor” error.
+   set(ARCH "generic")
+ elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ppc64le")
diff --git a/external/subpack/libs/boringssl/patches/900-add-install-target.patch b/external/subpack/libs/boringssl/patches/900-add-install-target.patch
new file mode 100644
index 0000000..2dd1250
--- /dev/null
+++ b/external/subpack/libs/boringssl/patches/900-add-install-target.patch
@@ -0,0 +1,18 @@
+From 8f62d432745a65671332281363409229c238cd1e Mon Sep 17 00:00:00 2001
+From: Martin Schneider <martschneider@google.com>
+Date: Mon, 25 Oct 2021 10:53:01 +0800
+Subject: [PATCH] Add install target to CMakeLists.txt
+
+Signed-off-by: Martin Schneider <martschneider@google.com>
+---
+ CMakeLists.txt | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -649,3 +649,5 @@ add_custom_target(
+     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+     DEPENDS all_tests bssl_shim handshaker fips_specific_tests_if_any
+     USES_TERMINAL)
++
++install(TARGETS ssl crypto DESTINATION bin)
diff --git a/external/subpack/libs/c-ares/Makefile b/external/subpack/libs/c-ares/Makefile
new file mode 100644
index 0000000..eafa3ff
--- /dev/null
+++ b/external/subpack/libs/c-ares/Makefile
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2009-2010 OpenWrt.org
+# Copyright (C) 2009 Jakob Pfeiffer
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=c-ares
+PKG_VERSION:=1.33.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/c-ares/c-ares/releases/download/v$(PKG_VERSION)
+PKG_HASH:=06869824094745872fa26efd4c48e622b9bd82a89ef0ce693dc682a23604f415
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE.md
+PKG_CPE_ID:=cpe:/a:c-ares_project:c-ares
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libcares
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Library for asyncronous DNS Requests (including name resolves)
+  URL:=https://c-ares.org/
+  MAINTAINER:=Karl Palsson <karlp@etactica.com>
+endef
+
+define Package/libcares/description
+  c-ares is a C library for asynchronous DNS requests (including name resolves)
+
+C89 compatibility, MIT licensed, builds for and runs on POSIX, Windows,
+Netware, Android and many more operating systems.
+
+endef
+
+CMAKE_OPTIONS += \
+	-DCARES_STATIC_PIC=ON \
+	-DCARES_BUILD_TOOLS=OFF
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/bin,$$$${prefix}/lib,g' $(1)/usr/lib/pkgconfig/libcares.pc
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libcares.pc
+	$(SED) 's,/usr/lib,$$$${prefix}/lib,g' $(1)/usr/lib/pkgconfig/libcares.pc
+endef
+
+define Package/libcares/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcares.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libcares))
diff --git a/external/subpack/libs/cereal/Makefile b/external/subpack/libs/cereal/Makefile
new file mode 100644
index 0000000..70d0fd5
--- /dev/null
+++ b/external/subpack/libs/cereal/Makefile
@@ -0,0 +1,48 @@
+#
+# Copyright © 2020 David Woodhouse <dwmw2@infradead.org>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=cereal
+PKG_VERSION:=1.3.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/USCiLab/cereal/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=329ea3e3130b026c03a4acc50e168e7daff4e6e661bc6a7dfec0d77b570851d5
+
+PKG_MAINTAINER:=David Woodhouse <dwmw2@infradead.org>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:usc:cereal
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_OPTIONS += \
+	-DCMAKE_CXX_FLAGS=-latomic \
+	-DJUST_INSTALL_CEREAL=ON \
+	-DSKIP_PORTABILITY_TEST=ON \
+	-DSKIP_PERFORMANCE_COMPARISON=ON \
+	-DWITH_WERROR=OFF
+
+define Package/cereal
+  BUILDONLY:=1
+  SECTION:=devel
+  CATEGORY:=Development
+  SUBMENU:=Libraries
+  TITLE:=Cereal is a library of C++ header files for serialization
+  URL:=https://github.com/USCilab/cereal
+endef
+
+
+define Package/cereal/description
+  Cereal is a library of C++ headers for serialization
+endef
+
+$(eval $(call BuildPackage,cereal))
diff --git a/external/subpack/libs/check/Makefile b/external/subpack/libs/check/Makefile
new file mode 100644
index 0000000..e888173
--- /dev/null
+++ b/external/subpack/libs/check/Makefile
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 2008-2015 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:=check
+PKG_VERSION:=0.15.2
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/libcheck/check/releases/download/$(PKG_VERSION)
+PKG_HASH:=a8de4e0bacfb4d76dd1c618ded263523b53b85d92a146d8835eb1a52932fa20a
+
+PKG_MAINTAINER:=Eduardo Abinader <eduardoabinader@gmail.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LESSER
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/check
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Unit testing framework for C
+  URL:=https://libcheck.github.io/check/
+  DEPENDS:= +libpthread +librt
+endef
+
+define Package/check/description
+  Check features a simple interface for defining unit tests, putting little in
+  the way of the developer. Tests are run in a separate address space, so Check
+  can catch both assertion failures and code errors that cause segmentation
+  faults or other signals. The output from unit tests can be used within source
+  code editors and IDEs.
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_TESTING=OFF \
+	-DCMAKE_POSITION_INDEPENDENT_CODE=ON
+
+define Package/check/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcheck.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,check))
diff --git a/external/subpack/libs/cjson/Makefile b/external/subpack/libs/cjson/Makefile
new file mode 100644
index 0000000..5c7e1e1
--- /dev/null
+++ b/external/subpack/libs/cjson/Makefile
@@ -0,0 +1,51 @@
+# This Makefile is free software, SPDX codes: GPL-2.0-or-later OR MIT
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=cJSON
+PKG_VERSION:=1.7.17
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/DaveGamble/cJSON/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=c91d1eeb7175c50d49f6ba2a25e69b46bd05cffb798382c19bfb202e467ec51c
+
+PKG_MAINTAINER:=Karl Palsson <karlp@etactica.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:cjson_project:cjson
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/cJSON
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Ultralightweight JSON parser in ANSI C
+  URL:=https://github.com/DaveGamble/cJSON
+endef
+
+define Package/cJSON/description
+ Ultralightweight JSON parser in ANSI C.
+cJSON aims to be the dumbest possible parser that you can get your
+job done with. It's a single file of C, and a single header file.
+endef
+
+CMAKE_OPTIONS += -DENABLE_CJSON_TEST=OFF
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/cjson
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/cjson/cJSON.h $(1)/usr/include/cjson
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcjson.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libcjson.pc $(1)/usr/lib/pkgconfig
+	$(SED) 's,/usr,$(STAGING_DIR)/usr,g' $(1)/usr/lib/pkgconfig/libcjson.pc
+endef
+
+define Package/cJSON/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcjson.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,cJSON))
diff --git a/external/subpack/libs/confuse/Makefile b/external/subpack/libs/confuse/Makefile
new file mode 100644
index 0000000..a3110cf
--- /dev/null
+++ b/external/subpack/libs/confuse/Makefile
@@ -0,0 +1,72 @@
+#
+# Copyright (C) 2006-2014 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:=confuse
+PKG_VERSION:=3.3
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/martinh/libconfuse/releases/download/v$(PKG_VERSION)
+PKG_HASH:=1dd50a0320e135a55025b23fcdbb3f0a81913b6d0b0a9df8cc2fdf3b3dc67010
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=ISC
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:libconfuse_project:libconfuse
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/confuse
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libConfuse is a configuration file parser library
+  URL:=https://github.com/martinh/libconfuse
+endef
+
+define Package/confuse/description
+	libConfuse is a configuration file parser library, licensed under the
+	terms of the ISC license, and written in C. It supports sections and
+	(lists of) values (strings, integers, floats, booleans or other
+	sections), as well as some other features (such as single/double-quoted
+	strings, environment variable expansion, functions and nested include
+	statements). It makes it very easy to add configuration file capability
+	to a program using a simple API.
+
+	The goal of libConfuse is not to be the configuration file parser
+	library with a gazillion of features. Instead, it aims to be easy to use
+	and quick to integrate with your code. libConfuse was called libcfg
+	before, but was changed to not confuse with other similar libraries.
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--disable-rpath \
+	--without-libiconv-prefix \
+	--without-libintl-prefix \
+	--disable-examples \
+	--with-pic
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/confuse.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libconfuse.{a,so*} $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libconfuse.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/confuse/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libconfuse.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,confuse))
diff --git a/external/subpack/libs/confuse/patches/010-CVE-2022-40320.patch b/external/subpack/libs/confuse/patches/010-CVE-2022-40320.patch
new file mode 100644
index 0000000..2dafd24
--- /dev/null
+++ b/external/subpack/libs/confuse/patches/010-CVE-2022-40320.patch
@@ -0,0 +1,37 @@
+From d73777c2c3566fb2647727bb56d9a2295b81669b Mon Sep 17 00:00:00 2001
+From: Joachim Wiberg <troglobit@gmail.com>
+Date: Fri, 2 Sep 2022 16:12:46 +0200
+Subject: [PATCH] Fix #163: unterminated username used with getpwnam()
+
+Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
+---
+ src/confuse.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/src/confuse.c
++++ b/src/confuse.c
+@@ -1863,18 +1863,20 @@ DLLIMPORT char *cfg_tilde_expand(const c
+ 			passwd = getpwuid(geteuid());
+ 			file = filename + 1;
+ 		} else {
+-			/* ~user or ~user/path */
+-			char *user;
++			char *user; /* ~user or ~user/path */
++			size_t len;
+ 
+ 			file = strchr(filename, '/');
+ 			if (file == 0)
+ 				file = filename + strlen(filename);
+ 
+-			user = malloc(file - filename);
++			len = file - filename - 1;
++			user = malloc(len + 1);
+ 			if (!user)
+ 				return NULL;
+ 
+-			strncpy(user, filename + 1, file - filename - 1);
++			strncpy(user, &filename[1], len);
++			user[len] = 0;
+ 			passwd = getpwnam(user);
+ 			free(user);
+ 		}
diff --git a/external/subpack/libs/cyrus-sasl/Makefile b/external/subpack/libs/cyrus-sasl/Makefile
new file mode 100644
index 0000000..ae036b5
--- /dev/null
+++ b/external/subpack/libs/cyrus-sasl/Makefile
@@ -0,0 +1,148 @@
+#
+# Copyright (C) 2006-2014 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:=cyrus-sasl
+PKG_VERSION:=2.1.28
+PKG_RELEASE:=3
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/cyrusimap/cyrus-sasl/releases/download/cyrus-sasl-2.1.28/
+PKG_HASH:=7ccfc6abd01ed67c1a0924b353e526f1b766b21f42d4562ee635a8ebfc5bb38c
+
+PKG_LICENSE:=BSD-4c BSD
+PKG_LICENSE_FILES:=COPYING cmulocal/COPYING saslauthd/COPYING
+PKG_CPE_ID:=cpe:/a:cmu:cyrus-sasl
+
+PKG_FIXUP:=autoreconf
+PKG_MACRO_PATHS:=cmulocal config ../cmulocal ../config
+PKG_AUTOMAKE_PATHS:=. saslauthd sasldb
+PKG_REMOVE_FILES:=aclocal.m4 saslauthd/aclocal.m4 config/libtool.m4
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libsasl2/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A general purpose authentication library
+  URL:=http://asg.web.cmu.edu/sasl/
+endef
+
+define Package/libsasl2
+  $(call Package/libsasl2/Default)
+  DEPENDS:=+libopenssl
+  TITLE+= (libraries)
+endef
+
+define Package/libsasl2-sasldb
+  $(call Package/libsasl2/Default)
+  DEPENDS:=+libsasl2 +libdb47
+  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 \
+	--enable-static \
+	--disable-sample \
+	--enable-staticdlopen \
+	--disable-java \
+	--disable-alwaystrue \
+	--disable-checkapop \
+	--enable-cram \
+	--enable-digest \
+	--enable-auth-sasldb \
+	--disable-otp \
+	--disable-srp \
+	--disable-srp-setpass \
+	--disable-krb4 \
+	--disable-gssapi \
+	--disable-gss_mutexes \
+	--enable-plain \
+	--enable-anon \
+	--disable-login \
+	--disable-ntlm \
+	--disable-sql \
+	--disable-ldapdb \
+	--with-dblib=berkeley \
+	--without-gdbm \
+	--with-devrandom="/dev/urandom" \
+	--without-pam \
+	--without-saslauthd \
+	--without-authdaemond \
+	--without-pwcheck \
+	--with-ipctype=unix \
+	--with-openssl="$(STAGING_DIR)/usr" \
+	--without-des \
+	--without-opie \
+	--without-ldap \
+	--without-mysql \
+	--without-pgsql \
+	--without-sqlite \
+	--without-rc4 \
+	--without-dmalloc \
+	--without-sfio \
+	--disable-sample
+
+define Build/Compile
+	$(MAKE) -C $(PKG_BUILD_DIR)/include \
+		CC="$(HOSTCC)" \
+		LINK="$(HOSTCC) -o makemd5 -lc" \
+		CFLAGS="" \
+		CPPFLAGS="" \
+		makemd5
+	$(MAKE) -C $(PKG_BUILD_DIR) \
+		DESTDIR="$(PKG_INSTALL_DIR)" \
+		all install
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/sasl $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsasl2.{a,so*} $(1)/usr/lib/
+	ln -sf libsasl2.a $(1)/usr/lib/libsasl.a
+	ln -sf libsasl2.so $(1)/usr/lib/libsasl.so
+	$(INSTALL_DIR) $(1)/usr/lib/sasl2
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/sasl2/lib*.{a,so*} $(1)/usr/lib/sasl2/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libsasl2.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libsasl2/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsasl2.so.* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/sasl2
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/sasl2/libanonymous.so* $(1)/usr/lib/sasl2/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/sasl2/libplain.so* $(1)/usr/lib/sasl2/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/sasl2/libcrammd5.so* $(1)/usr/lib/sasl2/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/sasl2/libdigestmd5.so* $(1)/usr/lib/sasl2/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/sasl2/libscram.so* $(1)/usr/lib/sasl2/
+endef
+
+define Package/libsasl2-sasldb/install
+	$(INSTALL_DIR) $(1)/usr/lib/sasl2
+	$(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))
diff --git a/external/subpack/libs/cyrus-sasl/patches/010-gcc14.patch b/external/subpack/libs/cyrus-sasl/patches/010-gcc14.patch
new file mode 100644
index 0000000..0ef2dad
--- /dev/null
+++ b/external/subpack/libs/cyrus-sasl/patches/010-gcc14.patch
@@ -0,0 +1,32 @@
+--- a/lib/saslutil.c
++++ b/lib/saslutil.c
+@@ -59,9 +59,7 @@
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+-#ifdef HAVE_TIME_H
+ #include <time.h>
+-#endif
+ #include "saslint.h"
+ #include <saslutil.h>
+ 
+--- a/plugins/cram.c
++++ b/plugins/cram.c
+@@ -48,6 +48,7 @@
+ #include <string.h>
+ #include <stdlib.h>
+ #include <stdio.h>
++#include <time.h>
+ #ifndef macintosh
+ #include <sys/stat.h>
+ #endif
+--- a/plugins/digestmd5.c
++++ b/plugins/digestmd5.c
+@@ -50,6 +50,7 @@
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
++#include <time.h>
+ #ifndef macintosh
+ #include <sys/types.h>
+ #include <sys/stat.h>
diff --git a/external/subpack/libs/czmq/Makefile b/external/subpack/libs/czmq/Makefile
new file mode 100644
index 0000000..169463e
--- /dev/null
+++ b/external/subpack/libs/czmq/Makefile
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://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:=czmq
+PKG_VERSION:=4.2.1
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/zeromq/czmq/releases/download/v$(PKG_VERSION)/
+PKG_HASH:=5d720a204c2a58645d6f7643af15d563a712dad98c9d32c1ed913377daa6ac39
+
+PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec1@gmail.com>
+PKG_LICENSE:=MPL-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/czmq
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=CZMQ High-level C binding for ZeroMQ
+  URL:=http://czmq.zeromq.org
+  ABI_VERSION:=4
+  DEPENDS:=+libzmq +libuuid +libmicrohttpd +liblz4 +libcurl
+endef
+
+define Package/czmq/description
+  High-level C binding for ZeroMQ which is high-performance asynchronous messaging
+  library, aimed at use in distributed or concurrent applications.
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_TESTING=OFF \
+	-DCMAKECONFIG_INSTALL_DIR=lib/cmake/czmq \
+	-DENABLE_DRAFTS=OFF
+
+define Package/czmq/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/zmakecert $(1)/usr/bin/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libczmq.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,czmq))
diff --git a/external/subpack/libs/davici/Makefile b/external/subpack/libs/davici/Makefile
new file mode 100644
index 0000000..f4a5a04
--- /dev/null
+++ b/external/subpack/libs/davici/Makefile
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2023 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See https://www.gnu.org/licenses/gpl-2.0.txt for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=davici
+PKG_VERSION:=1.4
+PKG_RELEASE=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/strongswan/davici/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=b03c5a1aad905e962271d70246d6af6c337ffd00449d990082ea02161327bde8
+
+PKG_MAINTAINER:=Lukas Voegl <lvoegl@tdt.de>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:strongswan:davici
+
+PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/davici
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Decoupled Asynchronous VICI
+  URL:=https://github.com/strongswan/davici
+endef
+
+define Package/davici/description
+  The davici library provides a client implementation of the
+  strongSwan VICI protocol for integration into external applications.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdavici.so* $(1)/usr/lib/
+endef
+
+define Package/davici/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdavici.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,davici))
diff --git a/external/subpack/libs/db/Makefile b/external/subpack/libs/db/Makefile
new file mode 100644
index 0000000..9a44eac
--- /dev/null
+++ b/external/subpack/libs/db/Makefile
@@ -0,0 +1,96 @@
+#
+# Copyright (C) 2009-2015 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:=db
+PKG_VERSION:=5.3.28
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://download.oracle.com/berkeley-db/
+PKG_HASH:=e0a992d740709892e81f9d93f06daf305cf73fb81b545afe72478043172c3628
+
+PKG_MAINTAINER:=Marcel Denia <naoir@gmx.net>
+PKG_LICENSE:=Sleepycat
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_FIXUP:=autoreconf
+PKG_BUILD_DEPENDS:=libxml2
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdb47
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Berkeley DB library
+  URL:=http://www.oracle.com/us/products/database/berkeley-db
+  PROVIDES:=libdb47-full
+  ABI_VERSION:=5
+endef
+
+define Package/libdb47/description
+  Berkeley DB library.
+endef
+
+define Package/libdb47xx
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libdb47 +libstdcpp
+  TITLE:=Berkeley DB library for C++
+  URL:=http://www.oracle.com/us/products/database/berkeley-db
+  PROVIDES:=libdb47xx-full
+  ABI_VERSION:=5
+endef
+
+define Package/libdb47xx/description
+  Berkeley DB library C++ wrapper.
+endef
+
+CONFIGURE_PATH = build_unix
+CONFIGURE_CMD = ../dist/configure
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--disable-java \
+	--with-mutex=POSIX/pthreads/library \
+	--disable-tcl \
+	--enable-compat185 \
+	--disable-debug \
+	$(if $(CONFIG_PACKAGE_libdb47xx),--enable-cxx,--disable-cxx)
+
+TARGET_CFLAGS += $(FPIC)
+
+define Build/Compile
+	+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/build_unix \
+		DESTDIR="$(PKG_INSTALL_DIR)" all
+	$(MAKE) -C $(PKG_BUILD_DIR)/build_unix \
+		DESTDIR="$(PKG_INSTALL_DIR)" install
+endef
+
+define Package/libdb47/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdb-*.so $(1)/usr/lib/
+endef
+
+define Package/libdb47xx/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdb_cxx-*.so $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/db.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/db_cxx.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdb*.{a,so} $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libdb47))
+$(eval $(call BuildPackage,libdb47xx))
diff --git a/external/subpack/libs/db/patches/010-fix-parallel-build.patch b/external/subpack/libs/db/patches/010-fix-parallel-build.patch
new file mode 100644
index 0000000..bd766e7
--- /dev/null
+++ b/external/subpack/libs/db/patches/010-fix-parallel-build.patch
@@ -0,0 +1,19 @@
+With higher paralelism it sometimes fails with:
+libtool: link: `util_log.lo' is not a valid libtool object
+make: *** [db_replicate] Error 1
+
+Upstream-Status: Inappropriate [as far as open source community is concerned, upstream is dead]
+
+Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com>
+
+--- a/dist/Makefile.in
++++ b/dist/Makefile.in
+@@ -1034,7 +1034,7 @@ db_recover: db_recover@o@ util_sig@o@ $(
+ 	    db_recover@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+ 	$(POSTLINK) $@
+ 
+-db_replicate: db_replicate@o@ util_sig@o@ $(DEF_LIB)
++db_replicate: db_replicate@o@ util_log@o@ util_sig@o@ $(DEF_LIB)
+ 	$(CCLINK) -o $@ $(LDFLAGS) \
+ 	    db_replicate@o@ util_log@o@ util_sig@o@ $(DEF_LIB) $(LIBS)
+ 	$(POSTLINK) $@
diff --git a/external/subpack/libs/db/patches/020-atomic-Rename-local-__atomic_compare_exchange-to-avo.patch b/external/subpack/libs/db/patches/020-atomic-Rename-local-__atomic_compare_exchange-to-avo.patch
new file mode 100644
index 0000000..eddce5a
--- /dev/null
+++ b/external/subpack/libs/db/patches/020-atomic-Rename-local-__atomic_compare_exchange-to-avo.patch
@@ -0,0 +1,40 @@
+From 29621d637e30982489693f2e207ce6a1790e3337 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 22 Mar 2017 15:32:26 +0000
+Subject: [PATCH] atomic: Rename local __atomic_compare_exchange to avoid clash
+ with builtins
+
+Helps building with clang
+
+Fixes
+
+../db-5.3.28/src/dbinc/atomic.h:179:19: error: definition of builtin function '__atomic_compare_exchange'
+static inline int __atomic_compare_exchange(
+
+Upstream-Status: Inappropriate [as far as open source community is concerned, upstream is dead]
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ src/dbinc/atomic.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/src/dbinc/atomic.h
++++ b/src/dbinc/atomic.h
+@@ -144,7 +144,7 @@ typedef LONG volatile *interlocked_val;
+ #define	atomic_inc(env, p)	__atomic_inc(p)
+ #define	atomic_dec(env, p)	__atomic_dec(p)
+ #define	atomic_compare_exchange(env, p, o, n)	\
+-	__atomic_compare_exchange((p), (o), (n))
++	__db_atomic_compare_exchange((p), (o), (n))
+ static inline int __atomic_inc(db_atomic_t *p)
+ {
+ 	int	temp;
+@@ -176,7 +176,7 @@ static inline int __atomic_dec(db_atomic
+  * http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
+  * which configure could be changed to use.
+  */
+-static inline int __atomic_compare_exchange(
++static inline int __db_atomic_compare_exchange(
+ 	db_atomic_t *p, atomic_value_t oldval, atomic_value_t newval)
+ {
+ 	atomic_value_t was;
diff --git a/external/subpack/libs/db/patches/030-configure-Add-explicit-tag-options-to-libtool-invoca.patch b/external/subpack/libs/db/patches/030-configure-Add-explicit-tag-options-to-libtool-invoca.patch
new file mode 100644
index 0000000..5275ab4
--- /dev/null
+++ b/external/subpack/libs/db/patches/030-configure-Add-explicit-tag-options-to-libtool-invoca.patch
@@ -0,0 +1,37 @@
+From 32e5943a3c4637d39e4d65b544dcb99e280210e3 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sun, 23 Jul 2017 10:54:26 -0700
+Subject: [PATCH] configure: Add explicit tag options to libtool invocation
+
+This helps cross compile when tag inference via heuristics
+fail because CC variable is having -fPIE -pie and libtool
+smartly removes it when building libraries
+
+Upstream-Status: Inappropriate [as far as open source community is concerned, upstream is dead]
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ dist/configure.ac | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/dist/configure.ac
++++ b/dist/configure.ac
+@@ -366,12 +366,12 @@ LIBTOOL="./libtool"
+ 
+ INSTALLER="\$(LIBTOOL) --mode=install cp -p"
+ 
+-MAKEFILE_CC="\$(LIBTOOL) --mode=compile ${MAKEFILE_CC}"
+-MAKEFILE_SOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK} -avoid-version"
+-MAKEFILE_CCLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK}"
+-MAKEFILE_CXX="\$(LIBTOOL) --mode=compile ${MAKEFILE_CXX}"
+-MAKEFILE_XSOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK} -avoid-version"
+-MAKEFILE_CXXLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK}"
++MAKEFILE_CC="\$(LIBTOOL) --tag=CC --mode=compile ${MAKEFILE_CC}"
++MAKEFILE_SOLINK="\$(LIBTOOL) --tag=CC --mode=link ${MAKEFILE_CCLINK} -avoid-version"
++MAKEFILE_CCLINK="\$(LIBTOOL) --tag=CC --mode=link ${MAKEFILE_CCLINK}"
++MAKEFILE_CXX="\$(LIBTOOL) --tag=CXX --mode=compile ${MAKEFILE_CXX}"
++MAKEFILE_XSOLINK="\$(LIBTOOL) --tag=CXX --mode=link ${MAKEFILE_CXXLINK} -avoid-version"
++MAKEFILE_CXXLINK="\$(LIBTOOL) --tag=CXX --mode=link ${MAKEFILE_CXXLINK}"
+ 
+ 
+ case "$host_os" in
diff --git a/external/subpack/libs/db/patches/040-sequence-type.patch b/external/subpack/libs/db/patches/040-sequence-type.patch
new file mode 100644
index 0000000..1d3b6f8
--- /dev/null
+++ b/external/subpack/libs/db/patches/040-sequence-type.patch
@@ -0,0 +1,76 @@
+configure wants to use host-specific types to get a 64-bit integer in db.h
+instead of using an alias such as int64_t.  This means that the header differs
+in multilib environments for no good reason, so replace the type with the alias
+in stdint.h.
+
+This then breaks the overly complicated type check but as we know that int64_t
+exists and works, we can just delete that.
+
+Upstream-Status: Inappropriate [as far as open source community is concerned, upstream is dead]
+Signed-off-by: Ross Burton <ross.burton@intel.com>
+
+--- a/dist/aclocal/sequence.m4
++++ b/dist/aclocal/sequence.m4
+@@ -21,14 +21,14 @@ AC_DEFUN(AM_SEQUENCE_CONFIGURE, [
+ 	db_cv_seq_type="no"
+ 	if test "$db_cv_build_sequence" = "yes" -a\
+ 	    "$ac_cv_sizeof_long" -eq "8"; then
+-		db_cv_seq_type="long"
++		db_cv_seq_type="int64_t"
+ 		db_cv_seq_fmt='"%ld"'
+ 		db_cv_seq_ufmt='"%lu"'
+ 		INT64_FMT='#define	INT64_FMT	"%ld"'
+ 		UINT64_FMT='#define	UINT64_FMT	"%lu"'
+ 	else if test "$db_cv_build_sequence" = "yes" -a\
+ 	    "$ac_cv_sizeof_long_long" -eq "8"; then
+-		db_cv_seq_type="long long"
++		db_cv_seq_type="int64_t"
+ 		db_cv_seq_fmt='"%lld"'
+ 		db_cv_seq_ufmt='"%llu"'
+ 		INT64_FMT='#define	INT64_FMT	"%lld"'
+@@ -38,44 +38,7 @@ AC_DEFUN(AM_SEQUENCE_CONFIGURE, [
+ 	fi
+ 	fi
+ 
+-	# Test to see if we can declare variables of the appropriate size
+-	# and format them.  If we're cross-compiling, all we get is a link
+-	# test, which won't test for the appropriate printf format strings.
+-	if test "$db_cv_build_sequence" = "yes"; then
+-		AC_TRY_RUN([
+-		main() {
+-			$db_cv_seq_type l;
+-			unsigned $db_cv_seq_type u;
+-			char buf@<:@100@:>@;
+-
+-			buf@<:@0@:>@ = 'a';
+-			l = 9223372036854775807LL;
+-			(void)snprintf(buf, sizeof(buf), $db_cv_seq_fmt, l);
+-			if (strcmp(buf, "9223372036854775807"))
+-				return (1);
+-			u = 18446744073709551615ULL;
+-			(void)snprintf(buf, sizeof(buf), $db_cv_seq_ufmt, u);
+-			if (strcmp(buf, "18446744073709551615"))
+-				return (1);
+-			return (0);
+-		}],, [db_cv_build_sequence="no"],
+-		AC_TRY_LINK(,[
+-			$db_cv_seq_type l;
+-			unsigned $db_cv_seq_type u;
+-			char buf@<:@100@:>@;
+-
+-			buf@<:@0@:>@ = 'a';
+-			l = 9223372036854775807LL;
+-			(void)snprintf(buf, sizeof(buf), $db_cv_seq_fmt, l);
+-			if (strcmp(buf, "9223372036854775807"))
+-				return (1);
+-			u = 18446744073709551615ULL;
+-			(void)snprintf(buf, sizeof(buf), $db_cv_seq_ufmt, u);
+-			if (strcmp(buf, "18446744073709551615"))
+-				return (1);
+-			return (0);
+-		],, [db_cv_build_sequence="no"]))
+-	fi
++	db_cv_build_sequence="yes"
+ 	if test "$db_cv_build_sequence" = "yes"; then
+ 		AC_SUBST(db_seq_decl)
+ 		db_seq_decl="typedef $db_cv_seq_type db_seq_t;";
diff --git a/external/subpack/libs/db/patches/050-Fix-libc-compatibility-by-renaming-atomic_init-API.patch b/external/subpack/libs/db/patches/050-Fix-libc-compatibility-by-renaming-atomic_init-API.patch
new file mode 100644
index 0000000..48d2fb4
--- /dev/null
+++ b/external/subpack/libs/db/patches/050-Fix-libc-compatibility-by-renaming-atomic_init-API.patch
@@ -0,0 +1,132 @@
+From a3569f118fd95b7ad41e1a1128e17c0b8928556d Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sun, 20 Jan 2019 18:30:23 -0800
+Subject: [PATCH] Fix libc++ compatibility by renaming atomic_init API
+
+db5 does not build because it is redefining a C++11 standard
+library identifier, atomic_init().  Therefore prefix all
+its internal defines with '__db_', to avoid collisions.
+
+Upstream-Status: Inappropriate [as far as open source community is concerned, upstream is dead]
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ src/dbinc/atomic.h     | 4 ++--
+ src/mp/mp_fget.c       | 4 ++--
+ src/mp/mp_mvcc.c       | 4 ++--
+ src/mp/mp_region.c     | 4 ++--
+ src/mutex/mut_method.c | 2 +-
+ src/mutex/mut_tas.c    | 4 ++--
+ 6 files changed, 11 insertions(+), 11 deletions(-)
+
+--- a/src/dbinc/atomic.h
++++ b/src/dbinc/atomic.h
+@@ -70,7 +70,7 @@ typedef struct {
+  * These have no memory barriers; the caller must include them when necessary.
+  */
+ #define	atomic_read(p)		((p)->value)
+-#define	atomic_init(p, val)	((p)->value = (val))
++#define	__db_atomic_init(p, val)	((p)->value = (val))
+ 
+ #ifdef HAVE_ATOMIC_SUPPORT
+ 
+@@ -206,7 +206,7 @@ static inline int __db_atomic_compare_ex
+ #define	atomic_dec(env, p)	(--(p)->value)
+ #define	atomic_compare_exchange(env, p, oldval, newval)		\
+ 	(DB_ASSERT(env, atomic_read(p) == (oldval)),		\
+-	atomic_init(p, (newval)), 1)
++	__db_atomic_init(p, (newval)), 1)
+ #else
+ #define atomic_inc(env, p)	__atomic_inc(env, p)
+ #define atomic_dec(env, p)	__atomic_dec(env, p)
+--- a/src/mp/mp_fget.c
++++ b/src/mp/mp_fget.c
+@@ -649,7 +649,7 @@ alloc:		/* Allocate a new buffer header
+ 
+ 		/* Initialize enough so we can call __memp_bhfree. */
+ 		alloc_bhp->flags = 0;
+-		atomic_init(&alloc_bhp->ref, 1);
++		__db_atomic_init(&alloc_bhp->ref, 1);
+ #ifdef DIAGNOSTIC
+ 		if ((uintptr_t)alloc_bhp->buf & (sizeof(size_t) - 1)) {
+ 			__db_errx(env, DB_STR("3025",
+@@ -955,7 +955,7 @@ alloc:		/* Allocate a new buffer header
+ 			MVCC_MPROTECT(bhp->buf, mfp->pagesize,
+ 			    PROT_READ);
+ 
+-		atomic_init(&alloc_bhp->ref, 1);
++		__db_atomic_init(&alloc_bhp->ref, 1);
+ 		MUTEX_LOCK(env, alloc_bhp->mtx_buf);
+ 		alloc_bhp->priority = bhp->priority;
+ 		alloc_bhp->pgno = bhp->pgno;
+--- a/src/mp/mp_mvcc.c
++++ b/src/mp/mp_mvcc.c
+@@ -276,7 +276,7 @@ __memp_bh_freeze(dbmp, infop, hp, bhp, n
+ #else
+ 	memcpy(frozen_bhp, bhp, SSZA(BH, buf));
+ #endif
+-	atomic_init(&frozen_bhp->ref, 0);
++	__db_atomic_init(&frozen_bhp->ref, 0);
+ 	if (mutex != MUTEX_INVALID)
+ 		frozen_bhp->mtx_buf = mutex;
+ 	else if ((ret = __mutex_alloc(env, MTX_MPOOL_BH,
+@@ -428,7 +428,7 @@ __memp_bh_thaw(dbmp, infop, hp, frozen_b
+ #endif
+ 		alloc_bhp->mtx_buf = mutex;
+ 		MUTEX_LOCK(env, alloc_bhp->mtx_buf);
+-		atomic_init(&alloc_bhp->ref, 1);
++		__db_atomic_init(&alloc_bhp->ref, 1);
+ 		F_CLR(alloc_bhp, BH_FROZEN);
+ 	}
+ 
+--- a/src/mp/mp_region.c
++++ b/src/mp/mp_region.c
+@@ -245,7 +245,7 @@ __memp_init(env, dbmp, reginfo_off, htab
+ 			     MTX_MPOOL_FILE_BUCKET, 0, &htab[i].mtx_hash)) != 0)
+ 				return (ret);
+ 			SH_TAILQ_INIT(&htab[i].hash_bucket);
+-			atomic_init(&htab[i].hash_page_dirty, 0);
++			__db_atomic_init(&htab[i].hash_page_dirty, 0);
+ 		}
+ 
+ 		/*
+@@ -302,7 +302,7 @@ no_prealloc:
+ 		} else
+ 			hp->mtx_hash = mtx_base + (i % dbenv->mp_mtxcount);
+ 		SH_TAILQ_INIT(&hp->hash_bucket);
+-		atomic_init(&hp->hash_page_dirty, 0);
++		__db_atomic_init(&hp->hash_page_dirty, 0);
+ #ifdef HAVE_STATISTICS
+ 		hp->hash_io_wait = 0;
+ 		hp->hash_frozen = hp->hash_thawed = hp->hash_frozen_freed = 0;
+--- a/src/mutex/mut_method.c
++++ b/src/mutex/mut_method.c
+@@ -474,7 +474,7 @@ atomic_compare_exchange(env, v, oldval,
+ 	MUTEX_LOCK(env, mtx);
+ 	ret = atomic_read(v) == oldval;
+ 	if (ret)
+-		atomic_init(v, newval);
++		__db_atomic_init(v, newval);
+ 	MUTEX_UNLOCK(env, mtx);
+ 
+ 	return (ret);
+--- a/src/mutex/mut_tas.c
++++ b/src/mutex/mut_tas.c
+@@ -47,7 +47,7 @@ __db_tas_mutex_init(env, mutex, flags)
+ 
+ #ifdef HAVE_SHARED_LATCHES
+ 	if (F_ISSET(mutexp, DB_MUTEX_SHARED))
+-		atomic_init(&mutexp->sharecount, 0);
++		__db_atomic_init(&mutexp->sharecount, 0);
+ 	else
+ #endif
+ 	if (MUTEX_INIT(&mutexp->tas)) {
+@@ -536,7 +536,7 @@ __db_tas_mutex_unlock(env, mutex)
+ 			F_CLR(mutexp, DB_MUTEX_LOCKED);
+ 			/* Flush flag update before zeroing count */
+ 			MEMBAR_EXIT();
+-			atomic_init(&mutexp->sharecount, 0);
++			__db_atomic_init(&mutexp->sharecount, 0);
+ 		} else {
+ 			DB_ASSERT(env, sharecount > 0);
+ 			MEMBAR_EXIT();
diff --git a/external/subpack/libs/db/patches/060-clock-Do-not-define-own-timespec.patch b/external/subpack/libs/db/patches/060-clock-Do-not-define-own-timespec.patch
new file mode 100644
index 0000000..d238b0f
--- /dev/null
+++ b/external/subpack/libs/db/patches/060-clock-Do-not-define-own-timespec.patch
@@ -0,0 +1,45 @@
+From 96b303caf70a7635953c36e5bfb9ad6e75cb7637 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 14 Feb 2020 14:12:59 -0800
+Subject: [PATCH] clock: Do not define own timespec
+
+timespec is provided by libc and its best left to libc
+os_gettime takes a db_timespec and passed its address to clock_gettime
+which assumes that db_timespec and timespec are same but actually
+its 12-bytes here and libc has 16-bytes
+
+This can cause problems especially with 64bit time_t
+
+Upstream-Status: Inappropriate [as far as open source community is concerned, upstream is dead]
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ src/dbinc/clock.h | 17 +----------------
+ 1 file changed, 1 insertion(+), 16 deletions(-)
+
+--- a/src/dbinc/clock.h
++++ b/src/dbinc/clock.h
+@@ -44,22 +44,8 @@
+ extern "C" {
+ #endif
+ 
+-/*
+- * This declaration is POSIX-compatible.  Because there are lots of different
+- * time.h include file patterns out there, it's easier to declare our own name
+- * in all cases than to try and discover if a system has a struct timespec.
+- * For the same reason, and because we'd have to #include <sys/time.h> in db.h,
+- * we don't export any timespec structures in the DB API, even in places where
+- * it would make sense, like the replication statistics information.
+- */
+-typedef struct {
+-	time_t	tv_sec;				/* seconds */
+-#ifdef HAVE_MIXED_SIZE_ADDRESSING
+-	int32_t tv_nsec;
+-#else
+-	long	tv_nsec;			/* nanoseconds */
+-#endif
+-} db_timespec;
++#include <time.h>
++#define db_timespec struct timespec
+ 
+ /* Operations on timespecs */
+ #undef	timespecclear
diff --git a/external/subpack/libs/db/patches/070-memp-stat-upstream-fix.patch b/external/subpack/libs/db/patches/070-memp-stat-upstream-fix.patch
new file mode 100644
index 0000000..a229a34
--- /dev/null
+++ b/external/subpack/libs/db/patches/070-memp-stat-upstream-fix.patch
@@ -0,0 +1,181 @@
+--- a/src/mp/mp_stat.c
++++ b/src/mp/mp_stat.c
+@@ -87,6 +87,13 @@ __memp_stat(env, gspp, fspp, flags)
+ 	u_int32_t i;
+ 	uintmax_t tmp_wait, tmp_nowait;
+ 
++	/*
++	 * The array holding the lengths related to the buffer allocated for *fspp.
++	 * The first element of the array holds the number of entries allocated.
++	 * The second element of the array holds the total number of bytes allocated.
++	 */
++	u_int32_t fsp_len[2];
++
+ 	dbmp = env->mp_handle;
+ 	mp = dbmp->reginfo[0].primary;
+ 
+@@ -193,32 +200,53 @@ __memp_stat(env, gspp, fspp, flags)
+ 	if (fspp != NULL) {
+ 		*fspp = NULL;
+ 
+-		/* Count the MPOOLFILE structures. */
+-		i = 0;
+-		len = 0;
+-		if ((ret = __memp_walk_files(env,
+-		     mp, __memp_count_files, &len, &i, flags)) != 0)
+-			return (ret);
+-
+-		if (i == 0)
+-			return (0);
+-		len += sizeof(DB_MPOOL_FSTAT *);	/* Trailing NULL */
++		while (*fspp == NULL) {
++			/* Count the MPOOLFILE structures. */
++			i = 0;
++			/*
++			 * Allow space for the first __memp_get_files() to align the
++			 * structure array to uintmax_t, DB_MPOOL_STAT's most
++			 * restrictive field.  [#23150]
++			 */
++			len = sizeof(uintmax_t);
++			if ((ret = __memp_walk_files(env,
++			     mp, __memp_count_files, &len, &i, flags)) != 0)
++				return (ret);
++
++			if (i == 0)
++				return (0);
++
++			/* 
++			 * Copy the number of DB_MPOOL_FSTAT entries and the number of
++			 * bytes allocated for them into fsp_len. Do not count the space
++			 * reserved for allignment.
++			 */
++			fsp_len[0] = i;
++			fsp_len[1] = len - sizeof(uintmax_t);
+ 
+-		/* Allocate space */
+-		if ((ret = __os_umalloc(env, len, fspp)) != 0)
+-			return (ret);
++			len += sizeof(DB_MPOOL_FSTAT *);	/* Trailing NULL */
+ 
+-		tfsp = *fspp;
+-		*tfsp = NULL;
++			/* Allocate space */
++			if ((ret = __os_umalloc(env, len, fspp)) != 0)
++				return (ret);
+ 
+-		/*
+-		 * Files may have been opened since we counted, don't walk
+-		 * off the end of the allocated space.
+-		 */
+-		if ((ret = __memp_walk_files(env,
+-		    mp, __memp_get_files, &tfsp, &i, flags)) != 0)
+-			return (ret);
++			tfsp = *fspp;
++			*tfsp = NULL;
+ 
++			/*
++			 * Files may have been opened since we counted, if we walk off
++			 * the end of the allocated space specified in fsp_len, retry.
++			 */
++			if ((ret = __memp_walk_files(env,
++			    mp, __memp_get_files, &tfsp, fsp_len, flags)) != 0) {
++				if (ret == DB_BUFFER_SMALL) {
++					__os_ufree(env, *fspp);
++					*fspp = NULL;
++					tfsp = NULL;
++				} else
++					return (ret);
++			}
++		}
+ 		*++tfsp = NULL;
+ 	}
+ 
+@@ -286,28 +314,35 @@ __memp_count_files(env, mfp, argp, count
+  * for the text file names.
+  */
+ static int
+-__memp_get_files(env, mfp, argp, countp, flags)
++__memp_get_files(env, mfp, argp, fsp_len, flags)
+ 	ENV *env;
+ 	MPOOLFILE *mfp;
+ 	void *argp;
+-	u_int32_t *countp;
++	u_int32_t fsp_len[];
+ 	u_int32_t flags;
+ {
+ 	DB_MPOOL *dbmp;
+ 	DB_MPOOL_FSTAT **tfsp, *tstruct;
+ 	char *name, *tname;
+-	size_t nlen;
++	size_t nlen, tlen;
+ 
+-	if (*countp == 0)
+-		return (0);
++	/* We walked through more files than argp was allocated for. */
++	if (fsp_len[0] == 0)
++		return DB_BUFFER_SMALL;
+ 
+ 	dbmp = env->mp_handle;
+ 	tfsp = *(DB_MPOOL_FSTAT ***)argp;
+ 
+ 	if (*tfsp == NULL) {
+-		/* Add 1 to count because we need to skip over the NULL. */
+-		tstruct = (DB_MPOOL_FSTAT *)(tfsp + *countp + 1);
+-		tname = (char *)(tstruct + *countp);
++		/*
++		 * Add 1 to count because to skip over the NULL end marker.
++		 * Align it further for DB_MPOOL_STAT's most restrictive field
++		 * because uintmax_t might require stricter alignment than
++		 * pointers; e.g., IP32 LL64 SPARC. [#23150]
++		 */
++		tstruct = (DB_MPOOL_FSTAT *)&tfsp[fsp_len[0] + 1];
++		tstruct = ALIGNP_INC(tstruct, sizeof(uintmax_t));
++		tname = (char *)&tstruct[fsp_len[0]];
+ 		*tfsp = tstruct;
+ 	} else {
+ 		tstruct = *tfsp + 1;
+@@ -317,6 +352,15 @@ __memp_get_files(env, mfp, argp, countp,
+ 
+ 	name = __memp_fns(dbmp, mfp);
+ 	nlen = strlen(name) + 1;
++
++	/* The space required for file names is larger than argp was allocated for. */
++	tlen = sizeof(DB_MPOOL_FSTAT *) + sizeof(DB_MPOOL_FSTAT) + nlen;
++	if (fsp_len[1] < tlen)
++		return DB_BUFFER_SMALL;
++	else
++		/* Count down the number of bytes left in argp. */
++		fsp_len[1] -= tlen;
++
+ 	memcpy(tname, name, nlen);
+ 	memcpy(tstruct, &mfp->stat, sizeof(mfp->stat));
+ 	tstruct->file_name = tname;
+@@ -325,7 +369,9 @@ __memp_get_files(env, mfp, argp, countp,
+ 	tstruct->st_pagesize = mfp->pagesize;
+ 
+ 	*(DB_MPOOL_FSTAT ***)argp = tfsp;
+-	(*countp)--;
++
++	/* Count down the number of entries left in argp. */
++	fsp_len[0]--;
+ 
+ 	if (LF_ISSET(DB_STAT_CLEAR))
+ 		memset(&mfp->stat, 0, sizeof(mfp->stat));
+--- a/src/mp/mp_sync.c
++++ b/src/mp/mp_sync.c
+@@ -57,11 +57,13 @@ __memp_walk_files(env, mp, func, arg, co
+ 			if ((t_ret = func(env,
+ 			    mfp, arg, countp, flags)) != 0 && ret == 0)
+ 				ret = t_ret;
+-			if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
++			if (ret != 0 &&
++			    (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == DB_BUFFER_SMALL))
+ 				break;
+ 		}
+ 		MUTEX_UNLOCK(env, hp->mtx_hash);
+-		if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
++		if (ret != 0 &&
++		    (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == DB_BUFFER_SMALL))
+ 			break;
+ 	}
+ 	return (ret);
diff --git a/external/subpack/libs/db/patches/080-mutex-leak.patch b/external/subpack/libs/db/patches/080-mutex-leak.patch
new file mode 100644
index 0000000..ef3f568
--- /dev/null
+++ b/external/subpack/libs/db/patches/080-mutex-leak.patch
@@ -0,0 +1,600 @@
+--- a/src/dbinc_auto/int_def.in
++++ b/src/dbinc_auto/int_def.in
+@@ -1373,6 +1373,7 @@
+ #define	__memp_pgread __memp_pgread@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_pg __memp_pg@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_bhfree __memp_bhfree@DB_VERSION_UNIQUE_NAME@
++#define	__memp_bh_clear_dirty __memp_bh_clear_dirty@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fget_pp __memp_fget_pp@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fget __memp_fget@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fcreate_pp __memp_fcreate_pp@DB_VERSION_UNIQUE_NAME@
+@@ -1397,6 +1398,7 @@
+ #define	__memp_fclose __memp_fclose@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_mf_discard __memp_mf_discard@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_inmemlist __memp_inmemlist@DB_VERSION_UNIQUE_NAME@
++#define	__memp_mf_mark_dead __memp_mf_mark_dead@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fput_pp __memp_fput_pp@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fput __memp_fput@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_unpin_buffers __memp_unpin_buffers@DB_VERSION_UNIQUE_NAME@
+@@ -1455,6 +1457,7 @@
+ #define	__mp_xxx_fh __mp_xxx_fh@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_sync_int __memp_sync_int@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_mf_sync __memp_mf_sync@DB_VERSION_UNIQUE_NAME@
++#define	__memp_purge_dead_files __memp_purge_dead_files@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_trickle_pp __memp_trickle_pp@DB_VERSION_UNIQUE_NAME@
+ #define	__mutex_alloc __mutex_alloc@DB_VERSION_UNIQUE_NAME@
+ #define	__mutex_alloc_int __mutex_alloc_int@DB_VERSION_UNIQUE_NAME@
+--- a/src/dbinc_auto/mp_ext.h
++++ b/src/dbinc_auto/mp_ext.h
+@@ -16,6 +16,7 @@ int __memp_bhwrite __P((DB_MPOOL *, DB_M
+ int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
+ int __memp_pg __P((DB_MPOOLFILE *, db_pgno_t, void *, int));
+ int __memp_bhfree __P((DB_MPOOL *, REGINFO *, MPOOLFILE *, DB_MPOOL_HASH *, BH *, u_int32_t));
++void __memp_bh_clear_dirty __P((ENV*, DB_MPOOL_HASH *, BH *));
+ int __memp_fget_pp __P((DB_MPOOLFILE *, db_pgno_t *, DB_TXN *, u_int32_t, void *));
+ int __memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, DB_THREAD_INFO *, DB_TXN *, u_int32_t, void *));
+ int __memp_fcreate_pp __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t));
+@@ -40,6 +41,7 @@ int __memp_fclose_pp __P((DB_MPOOLFILE *
+ int __memp_fclose __P((DB_MPOOLFILE *, u_int32_t));
+ int __memp_mf_discard __P((DB_MPOOL *, MPOOLFILE *, int));
+ int __memp_inmemlist __P((ENV *, char ***, int *));
++void __memp_mf_mark_dead __P((DB_MPOOL *, MPOOLFILE *, int*));
+ int __memp_fput_pp __P((DB_MPOOLFILE *, void *, DB_CACHE_PRIORITY, u_int32_t));
+ int __memp_fput __P((DB_MPOOLFILE *, DB_THREAD_INFO *, void *, DB_CACHE_PRIORITY));
+ int __memp_unpin_buffers __P((ENV *, DB_THREAD_INFO *));
+@@ -98,6 +100,7 @@ int __memp_fsync __P((DB_MPOOLFILE *));
+ int __mp_xxx_fh __P((DB_MPOOLFILE *, DB_FH **));
+ int __memp_sync_int __P((ENV *, DB_MPOOLFILE *, u_int32_t, u_int32_t, u_int32_t *, int *));
+ int __memp_mf_sync __P((DB_MPOOL *, MPOOLFILE *, int));
++int __memp_purge_dead_files __P((ENV *));
+ int __memp_trickle_pp __P((DB_ENV *, int, int *));
+ 
+ #if defined(__cplusplus)
+--- a/src/mp/mp_bh.c
++++ b/src/mp/mp_bh.c
+@@ -474,11 +474,8 @@ file_dead:
+ 	if (F_ISSET(bhp, BH_DIRTY | BH_TRASH)) {
+ 		MUTEX_LOCK(env, hp->mtx_hash);
+ 		DB_ASSERT(env, !SH_CHAIN_HASNEXT(bhp, vc));
+-		if (ret == 0 && F_ISSET(bhp, BH_DIRTY)) {
+-			F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
+-			DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0);
+-			atomic_dec(env, &hp->hash_page_dirty);
+-		}
++		if (ret == 0)
++			__memp_bh_clear_dirty(env, hp, bhp);
+ 
+ 		/* put the page back if necessary. */
+ 		if ((ret != 0 || BH_REFCOUNT(bhp) > 1) &&
+@@ -688,3 +685,29 @@ no_hp:	if (mfp != NULL)
+ 
+ 	return (ret);
+ }
++
++/*
++ * __memp_bh_clear_dirty --
++ *	Clear the dirty flag of of a buffer. Calls on the same buffer must be
++ *	serialized to get the accounting correct. This can be achieved by
++ *	acquiring an exclusive lock on the buffer, a shared lock on the
++ *	buffer plus an exclusive lock on the hash bucket, or some other
++ *	mechanism that guarantees single-thread access to the entire region
++ *	(e.g. during __memp_region_bhfree()).
++ *
++ * PUBLIC: void __memp_bh_clear_dirty __P((ENV*, DB_MPOOL_HASH *, BH *));
++ */
++void
++__memp_bh_clear_dirty(env, hp, bhp)
++	ENV *env;
++	DB_MPOOL_HASH *hp;
++	BH *bhp;
++{
++	COMPQUIET(env, env);
++	if (F_ISSET(bhp, BH_DIRTY)) {
++		F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
++		DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0);
++		(void)atomic_dec(env, &hp->hash_page_dirty);
++	}
++}
++
+--- a/src/mp/mp_fget.c
++++ b/src/mp/mp_fget.c
+@@ -439,12 +439,7 @@ thawed:			need_free = (atomic_dec(env, &
+ 		if (flags == DB_MPOOL_FREE) {
+ freebuf:		MUTEX_LOCK(env, hp->mtx_hash);
+ 			h_locked = 1;
+-			if (F_ISSET(bhp, BH_DIRTY)) {
+-				F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
+-				DB_ASSERT(env,
+-				   atomic_read(&hp->hash_page_dirty) > 0);
+-				atomic_dec(env, &hp->hash_page_dirty);
+-			}
++			__memp_bh_clear_dirty(env, hp, bhp);
+ 
+ 			/*
+ 			 * If the buffer we found is already freed, we're done.
+--- a/src/mp/mp_fopen.c
++++ b/src/mp/mp_fopen.c
+@@ -14,6 +14,7 @@
+ #include "dbinc/db_page.h"
+ #include "dbinc/hash.h"
+ 
++static int __memp_count_dead_mutex __P((DB_MPOOL *, u_int32_t *));
+ static int __memp_mpf_alloc __P((DB_MPOOL *,
+     DB_MPOOLFILE *, const char *, u_int32_t, u_int32_t, MPOOLFILE **));
+ static int __memp_mpf_find __P((ENV *,
+@@ -711,7 +712,11 @@ __memp_mpf_find(env, dbmfp, hp, path, fl
+ 		 */
+ 		if (LF_ISSET(DB_TRUNCATE)) {
+ 			MUTEX_LOCK(env, mfp->mutex);
+-			mfp->deadfile = 1;
++			/*
++			 * We cannot purge dead files here, because the caller
++			 * is holding the mutex of the hash bucket of mfp.
++			 */
++			__memp_mf_mark_dead(dbmp, mfp, NULL);
+ 			MUTEX_UNLOCK(env, mfp->mutex);
+ 			continue;
+ 		}
+@@ -909,10 +914,11 @@ __memp_fclose(dbmfp, flags)
+ 	MPOOLFILE *mfp;
+ 	char *rpath;
+ 	u_int32_t ref;
+-	int deleted, ret, t_ret;
++	int deleted, purge_dead, ret, t_ret;
+ 
+ 	env = dbmfp->env;
+ 	dbmp = env->mp_handle;
++	purge_dead = 0;
+ 	ret = 0;
+ 
+ 	/*
+@@ -1006,7 +1012,7 @@ __memp_fclose(dbmfp, flags)
+ 	if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) {
+ 		if (LF_ISSET(DB_MPOOL_DISCARD) ||
+ 		    F_ISSET(mfp, MP_TEMP) || mfp->unlink_on_close) {
+-			mfp->deadfile = 1;
++			__memp_mf_mark_dead(dbmp, mfp, &purge_dead);
+ 		}
+ 		if (mfp->unlink_on_close) {
+ 			if ((t_ret = __db_appname(dbmp->env, DB_APP_DATA,
+@@ -1039,6 +1045,8 @@ __memp_fclose(dbmfp, flags)
+ 	}
+ 	if (!deleted && !LF_ISSET(DB_MPOOL_NOLOCK))
+ 		MUTEX_UNLOCK(env, mfp->mutex);
++	if (purge_dead)
++		(void)__memp_purge_dead_files(env);
+ 
+ done:	/* Discard the DB_MPOOLFILE structure. */
+ 	if (dbmfp->pgcookie != NULL) {
+@@ -1093,7 +1101,7 @@ __memp_mf_discard(dbmp, mfp, hp_locked)
+ 	 * mutex so we don't deadlock.  Make sure nobody ever looks at this
+ 	 * structure again.
+ 	 */
+-	mfp->deadfile = 1;
++	__memp_mf_mark_dead(dbmp, mfp, NULL);
+ 
+ 	/* Discard the mutex we're holding and return it too the pool. */
+ 	MUTEX_UNLOCK(env, mfp->mutex);
+@@ -1218,3 +1226,104 @@ nomem:	MUTEX_UNLOCK(env, hp->mtx_hash);
+ 	*namesp = NULL;
+ 	return (ret);
+ }
++
++/*
++ * __memp_mf_mark_dead --
++ *	Mark an MPOOLFILE as dead because its contents are no longer necessary.
++ *	This happens when removing, truncation, or closing an unnamed in-memory
++ *	database. Return, in the purgep parameter, whether the caller should
++ *	call __memp_purge_dead_files() after the lock on mfp is released. The
++ *	caller must hold an exclusive lock on the mfp handle.
++ *
++ * PUBLIC: void __memp_mf_mark_dead __P((DB_MPOOL *, MPOOLFILE *, int*));
++ */
++void
++__memp_mf_mark_dead(dbmp, mfp, purgep)
++	DB_MPOOL *dbmp;	
++	MPOOLFILE *mfp;
++	int *purgep;
++{
++	ENV *env;
++#ifdef HAVE_MUTEX_SUPPORT
++	REGINFO *infop;
++	DB_MUTEXREGION *mtxregion;
++	u_int32_t mutex_max, mutex_inuse, dead_mutex;
++#endif
++
++	if (purgep != NULL)
++		*purgep = 0;
++
++	env = dbmp->env;
++
++#ifdef HAVE_MUTEX_SUPPORT
++	MUTEX_REQUIRED(env, mfp->mutex);
++
++	if (MUTEX_ON(env) && mfp->deadfile == 0) {
++		infop = &env->mutex_handle->reginfo;
++		mtxregion = infop->primary;
++
++		mutex_inuse = mtxregion->stat.st_mutex_inuse;
++		if ((mutex_max = env->dbenv->mutex_max) == 0)
++			mutex_max = infop->rp->max / mtxregion->mutex_size;
++
++		/*
++		 * Purging dead pages requires a full scan of the entire cache
++		 * buffer, so it is a slow operation. We only want to do it
++		 * when it is necessary and provides enough benefits. Below is
++		 * a simple heuristic that determines when to purge all dead
++		 * pages.
++		 */
++		if (purgep != NULL && mutex_inuse > mutex_max - 200) {
++			/*
++			 * If the mutex region is almost full and there are
++			 * many mutexes held by dead files, purge dead files.
++			 */
++			(void)__memp_count_dead_mutex(dbmp, &dead_mutex);
++			dead_mutex += mfp->block_cnt + 1;
++
++			if (dead_mutex > mutex_inuse / 20)
++				*purgep = 1;
++		}
++	}
++#endif
++
++	mfp->deadfile = 1;
++}
++
++/*
++ * __memp_count_dead_mutex --
++ *	Estimate the number of mutexes held by dead files.
++ */
++static int
++__memp_count_dead_mutex(dbmp, dead_mutex)
++	DB_MPOOL *dbmp;
++	u_int32_t *dead_mutex;
++{
++	ENV *env;
++	DB_MPOOL_HASH *hp;
++	MPOOL *mp;
++	MPOOLFILE *mfp;
++	u_int32_t mutex_per_file;
++	int busy, i;
++
++	env = dbmp->env;
++	*dead_mutex = 0;
++	mutex_per_file = 1;
++#ifndef HAVE_ATOMICFILEREAD
++	mutex_per_file = 2;
++#endif
++	mp = dbmp->reginfo[0].primary;
++	hp = R_ADDR(dbmp->reginfo, mp->ftab);
++	for (i = 0; i < MPOOL_FILE_BUCKETS; i++, hp++) {
++		busy = MUTEX_TRYLOCK(env, hp->mtx_hash);
++		if (busy)
++			continue;
++		SH_TAILQ_FOREACH(mfp, &hp->hash_bucket, q, __mpoolfile) {
++			if (mfp->deadfile)
++				*dead_mutex += mfp->block_cnt + mutex_per_file;
++		}
++		MUTEX_UNLOCK(env, hp->mtx_hash);
++	}
++
++	return (0);
++}
+--- a/src/mp/mp_method.c
++++ b/src/mp/mp_method.c
+@@ -640,7 +640,7 @@ __memp_nameop(env, fileid, newname, full
+ 	MPOOLFILE *mfp;
+ 	roff_t newname_off;
+ 	u_int32_t bucket;
+-	int locked, ret;
++	int locked, purge_dead, ret;
+ 	size_t nlen;
+ 	void *p;
+ 
+@@ -657,6 +657,7 @@ __memp_nameop(env, fileid, newname, full
+ 	nhp = NULL;
+ 	p = NULL;
+ 	locked = ret = 0;
++	purge_dead = 0;
+ 
+ 	if (!MPOOL_ON(env))
+ 		goto fsop;
+@@ -749,7 +750,7 @@ __memp_nameop(env, fileid, newname, full
+ 		 */
+ 		if (mfp->no_backing_file)
+ 			mfp->mpf_cnt--;
+-		mfp->deadfile = 1;
++		__memp_mf_mark_dead(dbmp, mfp, &purge_dead);
+ 		MUTEX_UNLOCK(env, mfp->mutex);
+ 	} else {
+ 		/*
+@@ -808,6 +809,12 @@ err:	if (p != NULL) {
+ 		if (nhp != NULL && nhp != hp)
+ 			MUTEX_UNLOCK(env, nhp->mtx_hash);
+ 	}
++	/* 
++	 * __memp_purge_dead_files() must be called when the hash bucket is
++	 * unlocked.
++	 */
++	if (purge_dead)
++		(void)__memp_purge_dead_files(env);
+ 	return (ret);
+ }
+ 
+--- a/src/mp/mp_sync.c
++++ b/src/mp/mp_sync.c
+@@ -26,6 +26,7 @@ static int __memp_close_flush_files __P(
+ static int __memp_sync_files __P((ENV *));
+ static int __memp_sync_file __P((ENV *,
+ 		MPOOLFILE *, void *, u_int32_t *, u_int32_t));
++static inline void __update_err_ret(int, int*);
+ 
+ /*
+  * __memp_walk_files --
+@@ -965,3 +966,123 @@ __bhcmp(p1, p2)
+ 		return (1);
+ 	return (0);
+ }
++
++/*
++ * __memp_purge_dead_files --
++ *	Remove all dead files and their buffers from the mpool. The caller
++ *	cannot hold any lock on the dead MPOOLFILE handles, their buffers
++ *	or their hash buckets.
++ *
++ * PUBLIC: int __memp_purge_dead_files __P((ENV *));
++ */
++int
++__memp_purge_dead_files(env)
++	ENV *env;
++{
++	BH *bhp;
++	DB_MPOOL *dbmp;
++	DB_MPOOL_HASH *hp, *hp_end;
++	REGINFO *infop;
++	MPOOL *c_mp, *mp;
++	MPOOLFILE *mfp;
++	u_int32_t i_cache;
++	int ret, t_ret, h_lock;
++
++	if (!MPOOL_ON(env))
++		return (0);
++
++	dbmp = env->mp_handle;
++	mp = dbmp->reginfo[0].primary;
++	ret = t_ret = h_lock = 0;
++
++	/*
++	 * Walk each cache's list of buffers and free all buffers whose
++	 * MPOOLFILE is marked as dead.
++	 */
++	for (i_cache = 0; i_cache < mp->nreg; i_cache++) {
++		infop = &dbmp->reginfo[i_cache]; 
++		c_mp = infop->primary;
++
++		hp = R_ADDR(infop, c_mp->htab);
++		hp_end = &hp[c_mp->htab_buckets];
++		for (; hp < hp_end; hp++) {
++			/* Skip empty buckets. */
++			if (SH_TAILQ_FIRST(&hp->hash_bucket, __bh) == NULL)
++				continue;
++
++			/* 
++			 * Search for a dead buffer. Other places that call
++			 * __memp_bhfree() acquire the buffer lock before the
++			 * hash bucket lock. Even though we acquire the two
++			 * locks in reverse order, we cannot deadlock here
++			 * because we don't block waiting for the locks.
++			 */
++			t_ret = MUTEX_TRYLOCK(env, hp->mtx_hash);
++			if (t_ret != 0) {
++				__update_err_ret(t_ret, &ret);
++				continue;
++			}
++			h_lock = 1;
++			SH_TAILQ_FOREACH(bhp, &hp->hash_bucket, hq, __bh) {
++				/* Skip buffers that are being used. */
++				if (BH_REFCOUNT(bhp) > 0)
++					continue;
++
++				mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
++				if (!mfp->deadfile)
++					continue;
++
++				/* Found a dead buffer. Prepare to free it. */
++				t_ret = MUTEX_TRYLOCK(env, bhp->mtx_buf);
++				if (t_ret != 0) {
++					__update_err_ret(t_ret, &ret);
++					continue;
++				}
++
++				DB_ASSERT(env, (!F_ISSET(bhp, BH_EXCLUSIVE) &&
++				    BH_REFCOUNT(bhp) == 0));
++				F_SET(bhp, BH_EXCLUSIVE);
++				(void)atomic_inc(env, &bhp->ref);
++
++				__memp_bh_clear_dirty(env, hp, bhp);
++
++				/*
++				 * Free the buffer. The buffer and hash bucket
++				 * are unlocked by __memp_bhfree.
++				 */
++				if ((t_ret = __memp_bhfree(dbmp, infop, mfp,
++				    hp, bhp, BH_FREE_FREEMEM)) == 0)
++					/*
++					 * Decrement hp, so the next turn will
++					 * search the same bucket again.
++					 */
++					hp--;
++				else
++					__update_err_ret(t_ret, &ret);
++
++				/*
++				 * The hash bucket is unlocked, we need to
++				 * start over again.
++				 */
++				h_lock = 0;
++				break;
++			}
++
++			if (h_lock) {
++				MUTEX_UNLOCK(env, hp->mtx_hash);
++				h_lock = 0;
++			}
++		}
++	}
++
++	return (ret);
++}
++
++static inline void
++__update_err_ret(t_ret, retp)
++	int t_ret;
++	int *retp;
++{
++	if (t_ret != 0 && t_ret != DB_LOCK_NOTGRANTED && *retp == 0)
++		*retp = t_ret;
++}
+--- a/src/mp/mp_trickle.c
++++ b/src/mp/mp_trickle.c
+@@ -67,6 +67,10 @@ __memp_trickle(env, pct, nwrotep)
+ 		return (EINVAL);
+ 	}
+ 
++	/* First we purge all dead files and their buffers. */
++	if ((ret = __memp_purge_dead_files(env)) != 0)
++		return (ret);
++
+ 	/*
+ 	 * Loop through the caches counting total/dirty buffers.
+ 	 *
+--- a/src/mutex/mut_region.c
++++ b/src/mutex/mut_region.c
+@@ -17,7 +17,7 @@
+ static db_size_t __mutex_align_size __P((ENV *));
+ static int __mutex_region_init __P((ENV *, DB_MUTEXMGR *));
+ static size_t __mutex_region_size __P((ENV *));
+-static size_t __mutex_region_max __P((ENV *));
++static size_t __mutex_region_max __P((ENV *, u_int32_t));
+ 
+ /*
+  * __mutex_open --
+@@ -34,7 +34,7 @@ __mutex_open(env, create_ok)
+ 	DB_MUTEXMGR *mtxmgr;
+ 	DB_MUTEXREGION *mtxregion;
+ 	size_t size;
+-	u_int32_t cpu_count;
++	u_int32_t cpu_count, mutex_needed;
+ 	int ret;
+ #ifndef HAVE_ATOMIC_SUPPORT
+ 	u_int i;
+@@ -61,19 +61,20 @@ __mutex_open(env, create_ok)
+ 	}
+ 
+ 	/*
+-	 * If the user didn't set an absolute value on the number of mutexes
+-	 * we'll need, figure it out.  We're conservative in our allocation,
+-	 * we need mutexes for DB handles, group-commit queues and other things
+-	 * applications allocate at run-time.  The application may have kicked
+-	 * up our count to allocate its own mutexes, add that in.
++	 * Figure out the number of mutexes we'll need.  We're conservative in
++	 * our allocation, we need mutexes for DB handles, group-commit queues
++	 * and other things applications allocate at run-time.  The application
++	 * may have kicked up our count to allocate its own mutexes, add that
++	 * in.
+ 	 */
++	mutex_needed =
++	    __lock_region_mutex_count(env) +
++	    __log_region_mutex_count(env) +
++	    __memp_region_mutex_count(env) +
++	    __txn_region_mutex_count(env);
+ 	if (dbenv->mutex_cnt == 0 &&
+ 	    F_ISSET(env, ENV_PRIVATE | ENV_THREAD) != ENV_PRIVATE)
+-		dbenv->mutex_cnt =
+-		    __lock_region_mutex_count(env) +
+-		    __log_region_mutex_count(env) +
+-		    __memp_region_mutex_count(env) +
+-		    __txn_region_mutex_count(env);
++		dbenv->mutex_cnt = mutex_needed;
+ 
+ 	if (dbenv->mutex_max != 0 && dbenv->mutex_cnt > dbenv->mutex_max)
+ 		dbenv->mutex_cnt = dbenv->mutex_max;
+@@ -90,8 +91,8 @@ __mutex_open(env, create_ok)
+ 	size = __mutex_region_size(env);
+ 	if (create_ok)
+ 		F_SET(&mtxmgr->reginfo, REGION_CREATE_OK);
+-	if ((ret = __env_region_attach(env,
+-	    &mtxmgr->reginfo, size, size + __mutex_region_max(env))) != 0)
++	if ((ret = __env_region_attach(env, &mtxmgr->reginfo,
++	    size, size + __mutex_region_max(env, mutex_needed))) != 0)
+ 		goto err;
+ 
+ 	/* If we created the region, initialize it. */
+@@ -352,9 +353,13 @@ __mutex_region_size(env)
+ 
+ 	s = sizeof(DB_MUTEXMGR) + 1024;
+ 
+-	/* We discard one mutex for the OOB slot. */
++	/* 
++	 * We discard one mutex for the OOB slot. Make sure mutex_cnt doesn't
++	 * overflow.
++	 */
+ 	s += __env_alloc_size(
+-	    (dbenv->mutex_cnt + 1) *__mutex_align_size(env));
++	    (dbenv->mutex_cnt + (dbenv->mutex_cnt == UINT32_MAX ? 0 : 1)) *
++	    __mutex_align_size(env));
+ 
+ 	return (s);
+ }
+@@ -364,28 +369,42 @@ __mutex_region_size(env)
+  *	 Return the amount of space needed to reach the maximum size.
+  */
+ static size_t
+-__mutex_region_max(env)
++__mutex_region_max(env, mutex_needed)
+ 	ENV *env;
++	u_int32_t mutex_needed;
+ {
+ 	DB_ENV *dbenv;
+-	u_int32_t max;
++	u_int32_t max, mutex_cnt;
+ 
+ 	dbenv = env->dbenv;
++	mutex_cnt = dbenv->mutex_cnt;
+ 
+-	if ((max = dbenv->mutex_max) == 0) {
++	/*
++	 * We want to limit the region size to accommodate at most UINT32_MAX
++	 * mutexes. If mutex_cnt is UINT32_MAX, no more space is allowed.
++	 */
++	if ((max = dbenv->mutex_max) == 0 && mutex_cnt != UINT32_MAX)
+ 		if (F_ISSET(env, ENV_PRIVATE | ENV_THREAD) == ENV_PRIVATE)
+-			max = dbenv->mutex_inc + 1;
+-		else
++			if (dbenv->mutex_inc + 1 < UINT32_MAX - mutex_cnt)
++				max = dbenv->mutex_inc + 1 + mutex_cnt;
++			else
++				max = UINT32_MAX;
++		else {
+ 			max = __lock_region_mutex_max(env) +
+ 			    __txn_region_mutex_max(env) +
+ 			    __log_region_mutex_max(env) +
+ 			    dbenv->mutex_inc + 100;
+-	} else if (max <= dbenv->mutex_cnt)
++			if (max < UINT32_MAX - mutex_needed)
++				max += mutex_needed;
++			else
++				max = UINT32_MAX;
++		}
++
++	if (max <= mutex_cnt)
+ 		return (0);
+ 	else
+-		max -= dbenv->mutex_cnt;
+-
+-	return ( __env_alloc_size(max * __mutex_align_size(env)));
++		return (__env_alloc_size(
++		    (max - mutex_cnt) * __mutex_align_size(env)));
+ }
+ 
+ #ifdef	HAVE_MUTEX_SYSTEM_RESOURCES
diff --git a/external/subpack/libs/db/patches/090-lemon-hash.patch b/external/subpack/libs/db/patches/090-lemon-hash.patch
new file mode 100644
index 0000000..2f55dec
--- /dev/null
+++ b/external/subpack/libs/db/patches/090-lemon-hash.patch
@@ -0,0 +1,20 @@
+--- a/lang/sql/sqlite/tool/lemon.c
++++ b/lang/sql/sqlite/tool/lemon.c
+@@ -3428,7 +3428,7 @@ void print_stack_union(
+   int maxdtlength;          /* Maximum length of any ".datatype" field. */
+   char *stddt;              /* Standardized name for a datatype */
+   int i,j;                  /* Loop counters */
+-  int hash;                 /* For hashing the name of a type */
++  unsigned hash;            /* For hashing the name of a type */
+   const char *name;         /* Name of the parser */
+ 
+   /* Allocate and initialize types[] and allocate stddt[] */
+@@ -3491,7 +3491,7 @@ void print_stack_union(
+         break;
+       }
+       hash++;
+-      if( hash>=arraysize ) hash = 0;
++      if( hash>=(unsigned)arraysize ) hash = 0;
+     }
+     if( types[hash]==0 ){
+       sp->dtnum = hash + 1;
diff --git a/external/subpack/libs/db/patches/100-mmap-high-cpu-usage.patch b/external/subpack/libs/db/patches/100-mmap-high-cpu-usage.patch
new file mode 100644
index 0000000..7faf0f7
--- /dev/null
+++ b/external/subpack/libs/db/patches/100-mmap-high-cpu-usage.patch
@@ -0,0 +1,18 @@
+Author: Filip Januš <fjanus@redhat.com>
+Date: 6 Sep 2021
+Related: https://bugzilla.redhat.com/show_bug.cgi?id=1992402
+Patch was created based on the discussion in the previous link
+--- a/src/os/os_map.c
++++ b/src/os/os_map.c
+@@ -213,7 +213,10 @@ __os_attach(env, infop, rp)
+ 	if (rp->max < rp->size)
+ 		rp->max = rp->size;
+ 	if (ret == 0 && F_ISSET(infop, REGION_CREATE)) {
+-		if (F_ISSET(dbenv, DB_ENV_REGION_INIT))
++
++		rp->size = rp->max;
++
++        if (F_ISSET(dbenv, DB_ENV_REGION_INIT))
+ 			ret = __db_file_write(env, infop->fhp,
+ 			    rp->size / MEGABYTE, rp->size % MEGABYTE, 0x00);
+ 		else
diff --git a/external/subpack/libs/db/patches/110-CVE-2019-2708.patch b/external/subpack/libs/db/patches/110-CVE-2019-2708.patch
new file mode 100644
index 0000000..a86388c
--- /dev/null
+++ b/external/subpack/libs/db/patches/110-CVE-2019-2708.patch
@@ -0,0 +1,693 @@
+--- a/src/btree/bt_cursor.c
++++ b/src/btree/bt_cursor.c
+@@ -282,6 +282,8 @@ __bamc_refresh(dbc)
+ 	 *
+ 	 * Recno uses the btree bt_ovflsize value -- it's close enough.
+ 	 */
++	if (t->bt_minkey == 0)
++		return (DB_RECOVER);
+ 	cp->ovflsize = B_MINKEY_TO_OVFLSIZE(
+ 	    dbp,  F_ISSET(dbc, DBC_OPD) ? 2 : t->bt_minkey, dbp->pgsize);
+ 
+--- a/src/btree/bt_verify.c
++++ b/src/btree/bt_verify.c
+@@ -611,7 +611,11 @@ __bam_vrfy_inp(dbp, vdp, h, pgno, nentri
+ 			isbad = 1;
+ 			goto err;
+ 		default:
+-			DB_ASSERT(env, ret != 0);
++			if (ret == 0) {
++				isbad = 1;
++				ret = DB_VERIFY_FATAL;
++				goto err;
++			}
+ 			break;
+ 		}
+ 
+@@ -922,7 +926,7 @@ __bam_vrfy_itemorder(dbp, vdp, ip, h, pg
+ 	DBT dbta, dbtb, dup_1, dup_2, *p1, *p2, *tmp;
+ 	ENV *env;
+ 	PAGE *child;
+-	db_pgno_t cpgno;
++	db_pgno_t cpgno, grandparent;
+ 	VRFY_PAGEINFO *pip;
+ 	db_indx_t i, *inp;
+ 	int adj, cmp, freedup_1, freedup_2, isbad, ret, t_ret;
+@@ -954,7 +958,8 @@ __bam_vrfy_itemorder(dbp, vdp, ip, h, pg
+ 
+ 	buf1 = buf2 = NULL;
+ 
+-	DB_ASSERT(env, !LF_ISSET(DB_NOORDERCHK));
++	if (LF_ISSET(DB_NOORDERCHK))
++		return (EINVAL);
+ 
+ 	dupfunc = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare;
+ 	if (TYPE(h) == P_LDUP)
+@@ -963,6 +968,7 @@ __bam_vrfy_itemorder(dbp, vdp, ip, h, pg
+ 		func = __bam_defcmp;
+ 		if (dbp->bt_internal != NULL) {
+ 			bt = (BTREE *)dbp->bt_internal;
++			grandparent = bt->bt_root;
+ 			if (TYPE(h) == P_IBTREE && (bt->bt_compare != NULL ||
+ 			    dupfunc != __bam_defcmp)) {
+ 				/*
+@@ -974,8 +980,24 @@ __bam_vrfy_itemorder(dbp, vdp, ip, h, pg
+ 				 */
+ 				mpf = dbp->mpf;
+ 				child = h;
++				cpgno = pgno;
+ 				while (TYPE(child) == P_IBTREE) {
++					if (NUM_ENT(child) == 0) {
++						EPRINT((env, DB_STR_A("1088",
++		    "Page %lu: internal page is empty and should not be",
++					    "%lu"), (u_long)cpgno));
++						ret = DB_VERIFY_BAD;
++						goto err;
++					}
+ 					bi = GET_BINTERNAL(dbp, child, 0);
++					if (grandparent == bi->pgno) {
++						EPRINT((env, DB_STR_A("5552",
++					      "Page %lu: found twice in the btree",
++				          "%lu"), (u_long)grandparent));
++						ret = DB_VERIFY_FATAL;
++						goto err;
++					} else
++						grandparent = cpgno;
+ 					cpgno = bi->pgno;
+ 					if (child != h &&
+ 					    (ret = __memp_fput(mpf,
+@@ -1231,7 +1253,10 @@ overflow:		if (!ovflok) {
+ 					 */
+ 					if (dup_1.data == NULL ||
+ 					    dup_2.data == NULL) {
+-						DB_ASSERT(env, !ovflok);
++						if (ovflok) {
++							isbad = 1;
++							goto err;
++						}
+ 						if (pip != NULL)
+ 							F_SET(pip,
+ 							    VRFY_INCOMPLETE);
+@@ -1569,9 +1594,10 @@ bad_prev:				isbad = 1;
+ 			    (ret = __db_vrfy_ovfl_structure(dbp, vdp,
+ 			    child->pgno, child->tlen,
+ 			    flags | DB_ST_OVFL_LEAF)) != 0) {
+-				if (ret == DB_VERIFY_BAD)
++				if (ret == DB_VERIFY_BAD) {
+ 					isbad = 1;
+-				else
++					break;
++				} else
+ 					goto done;
+ 			}
+ 
+@@ -1645,9 +1671,10 @@ bad_prev:				isbad = 1;
+ 						    stflags | DB_ST_TOPLEVEL,
+ 						    NULL, NULL, NULL)) != 0) {
+ 							if (ret ==
+-							    DB_VERIFY_BAD)
++							    DB_VERIFY_BAD) {
+ 								isbad = 1;
+-							else
++								break;
++							} else
+ 								goto err;
+ 						}
+ 					}
+@@ -1790,7 +1817,10 @@ bad_prev:				isbad = 1;
+ 			 */
+ 
+ 			/* Otherwise, __db_vrfy_childput would be broken. */
+-			DB_ASSERT(env, child->refcnt >= 1);
++			if (child->refcnt < 1) {
++				isbad = 1;
++				goto err;
++			}
+ 
+ 			/*
+ 			 * An overflow referenced more than twice here
+@@ -1807,9 +1837,10 @@ bad_prev:				isbad = 1;
+ 					if ((ret = __db_vrfy_ovfl_structure(dbp,
+ 					    vdp, child->pgno, child->tlen,
+ 					    flags)) != 0) {
+-						if (ret == DB_VERIFY_BAD)
++						if (ret == DB_VERIFY_BAD) {
+ 							isbad = 1;
+-						else
++							break;
++						} else
+ 							goto done;
+ 					}
+ 		}
+@@ -1847,9 +1878,10 @@ bad_prev:				isbad = 1;
+ 		if ((ret = __bam_vrfy_subtree(dbp, vdp, li->pgno,
+ 		    i == 0 ? NULL : li, ri, flags, &child_level,
+ 		    &child_nrecs, NULL)) != 0) {
+-			if (ret == DB_VERIFY_BAD)
++			if (ret == DB_VERIFY_BAD) {
+ 				isbad = 1;
+-			else
++				break;
++			} else
+ 				goto done;
+ 		}
+ 
+@@ -2675,7 +2707,11 @@ __bam_meta2pgset(dbp, vdp, btmeta, flags
+ 	db_pgno_t current, p;
+ 	int err_ret, ret;
+ 
+-	DB_ASSERT(dbp->env, pgset != NULL);
++	if (pgset == NULL) {
++		EPRINT((dbp->env, DB_STR("5542",
++			"Error, database contains no visible pages.")));
++		return (DB_RUNRECOVERY);
++	}
+ 
+ 	mpf = dbp->mpf;
+ 	h = NULL;
+--- a/src/db/db_conv.c
++++ b/src/db/db_conv.c
+@@ -493,8 +493,11 @@ __db_byteswap(dbp, pg, h, pagesize, pgin
+ 	db_indx_t i, *inp, len, tmp;
+ 	u_int8_t *end, *p, *pgend;
+ 
+-	if (pagesize == 0)
+-		return (0);
++	/* This function is also used to byteswap logs, so
++	 * the pagesize might not be an actual page size.
++	 */
++	if (!(pagesize >= 24 && pagesize <= DB_MAX_PGSIZE))
++		return (EINVAL);
+ 
+ 	if (pgin) {
+ 		M_32_SWAP(h->lsn.file);
+@@ -513,26 +516,41 @@ __db_byteswap(dbp, pg, h, pagesize, pgin
+ 	pgend = (u_int8_t *)h + pagesize;
+ 
+ 	inp = P_INP(dbp, h);
+-	if ((u_int8_t *)inp >= pgend)
+-		goto out;
++	if ((u_int8_t *)inp > pgend)
++		return (__db_pgfmt(env, pg));
+ 
+ 	switch (TYPE(h)) {
+ 	case P_HASH_UNSORTED:
+ 	case P_HASH:
+ 		for (i = 0; i < NUM_ENT(h); i++) {
++			if ((u_int8_t*)(inp + i) >= pgend)
++				return (__db_pgfmt(env, pg));
++			if (inp[i] == 0)
++				continue;
+ 			if (pgin)
+ 				M_16_SWAP(inp[i]);
++			if (inp[i] >= pagesize)
++				return (__db_pgfmt(env, pg));
+ 
+-			if (P_ENTRY(dbp, h, i) >= pgend)
+-				continue;
++	   		if (P_ENTRY(dbp, h, i) >= pgend)
++				return (__db_pgfmt(env, pg));
+ 
+ 			switch (HPAGE_TYPE(dbp, h, i)) {
+ 			case H_KEYDATA:
+ 				break;
+ 			case H_DUPLICATE:
++				if (LEN_HITEM(dbp, h, pagesize, i) < 
++				    HKEYDATA_SIZE(0))
++					return (__db_pgfmt(env, pg));
++
+ 				len = LEN_HKEYDATA(dbp, h, pagesize, i);
+ 				p = HKEYDATA_DATA(P_ENTRY(dbp, h, i));
+-				for (end = p + len; p < end;) {
++
++				end = p + len;
++				if (end > pgend)
++					return (__db_pgfmt(env, pg));
++
++				while (p < end) {
+ 					if (pgin) {
+ 						P_16_SWAP(p);
+ 						memcpy(&tmp,
+@@ -544,14 +562,20 @@ __db_byteswap(dbp, pg, h, pagesize, pgin
+ 						SWAP16(p);
+ 					}
+ 					p += tmp;
++					if (p >= end)
++						return (__db_pgfmt(env, pg));
+ 					SWAP16(p);
+ 				}
+ 				break;
+ 			case H_OFFDUP:
++				if ((inp[i] + HOFFDUP_SIZE) > pagesize)
++					return (__db_pgfmt(env, pg));
+ 				p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
+ 				SWAP32(p);			/* pgno */
+ 				break;
+ 			case H_OFFPAGE:
++				if ((inp[i] + HOFFPAGE_SIZE) > pagesize)
++					return (__db_pgfmt(env, pg));
+ 				p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i));
+ 				SWAP32(p);			/* pgno */
+ 				SWAP32(p);			/* tlen */
+@@ -559,7 +583,6 @@ __db_byteswap(dbp, pg, h, pagesize, pgin
+ 			default:
+ 				return (__db_pgfmt(env, pg));
+ 			}
+-
+ 		}
+ 
+ 		/*
+@@ -576,8 +599,12 @@ __db_byteswap(dbp, pg, h, pagesize, pgin
+ 	case P_LDUP:
+ 	case P_LRECNO:
+ 		for (i = 0; i < NUM_ENT(h); i++) {
++			if ((u_int8_t *)(inp + i) >= pgend)
++				return (__db_pgfmt(env, pg));
+ 			if (pgin)
+ 				M_16_SWAP(inp[i]);
++			if (inp[i] >= pagesize)
++				return (__db_pgfmt(env, pg));
+ 
+ 			/*
+ 			 * In the case of on-page duplicates, key information
+@@ -597,7 +624,7 @@ __db_byteswap(dbp, pg, h, pagesize, pgin
+ 
+ 			bk = GET_BKEYDATA(dbp, h, i);
+ 			if ((u_int8_t *)bk >= pgend)
+-				continue;
++				return (__db_pgfmt(env, pg));
+ 			switch (B_TYPE(bk->type)) {
+ 			case B_KEYDATA:
+ 				M_16_SWAP(bk->len);
+@@ -605,6 +632,8 @@ __db_byteswap(dbp, pg, h, pagesize, pgin
+ 			case B_DUPLICATE:
+ 			case B_OVERFLOW:
+ 				bo = (BOVERFLOW *)bk;
++				if (((u_int8_t *)bo + BOVERFLOW_SIZE) > pgend)
++					return (__db_pgfmt(env, pg));
+ 				M_32_SWAP(bo->pgno);
+ 				M_32_SWAP(bo->tlen);
+ 				break;
+@@ -618,12 +647,17 @@ __db_byteswap(dbp, pg, h, pagesize, pgin
+ 		break;
+ 	case P_IBTREE:
+ 		for (i = 0; i < NUM_ENT(h); i++) {
++			if ((u_int8_t *)(inp + i) > pgend)
++				return (__db_pgfmt(env, pg));
+ 			if (pgin)
+ 				M_16_SWAP(inp[i]);
++			if ((u_int16_t)(inp[i] + 
++			    BINTERNAL_SIZE(0) - 1) > pagesize)
++				break;
+ 
+ 			bi = GET_BINTERNAL(dbp, h, i);
+-			if ((u_int8_t *)bi >= pgend)
+-				continue;
++			if (((u_int8_t *)bi + BINTERNAL_SIZE(0)) > pgend)
++				return (__db_pgfmt(env, pg));
+ 
+ 			M_16_SWAP(bi->len);
+ 			M_32_SWAP(bi->pgno);
+@@ -634,6 +668,10 @@ __db_byteswap(dbp, pg, h, pagesize, pgin
+ 				break;
+ 			case B_DUPLICATE:
+ 			case B_OVERFLOW:
++				if ((u_int16_t)(inp[i] + 
++				    BINTERNAL_SIZE(BOVERFLOW_SIZE) - 1) >
++				    pagesize)
++					goto out;
+ 				bo = (BOVERFLOW *)bi->data;
+ 				M_32_SWAP(bo->pgno);
+ 				M_32_SWAP(bo->tlen);
+@@ -648,12 +686,16 @@ __db_byteswap(dbp, pg, h, pagesize, pgin
+ 		break;
+ 	case P_IRECNO:
+ 		for (i = 0; i < NUM_ENT(h); i++) {
++			if ((u_int8_t *)(inp + i) >= pgend)
++				return (__db_pgfmt(env, pg));
+ 			if (pgin)
+ 				M_16_SWAP(inp[i]);
++			if (inp[i] >= pagesize)
++				return (__db_pgfmt(env, pg));
+ 
+ 			ri = GET_RINTERNAL(dbp, h, i);
+-			if ((u_int8_t *)ri >= pgend)
+-				continue;
++			if ((((u_int8_t *)ri) + RINTERNAL_SIZE) > pgend)
++				return (__db_pgfmt(env, pg));
+ 
+ 			M_32_SWAP(ri->pgno);
+ 			M_32_SWAP(ri->nrecs);
+--- a/src/db/db_vrfy.c
++++ b/src/db/db_vrfy.c
+@@ -375,8 +375,10 @@ __db_verify(dbp, ip, name, subdb, handle
+ 		    vdp, name, 0, lp, rp, flags)) != 0) {
+ 			if (t_ret == DB_VERIFY_BAD)
+ 				isbad = 1;
+-			else
+-				goto err;
++			else {
++			    ret = t_ret;
++			    goto err;
++			}
+ 		}
+ 
+ 	/*
+@@ -764,9 +766,10 @@ __db_vrfy_walkpages(dbp, vdp, handle, ca
+ 		 */
+ 		if ((t_ret = __memp_fget(mpf, &i,
+ 		    vdp->thread_info, NULL, 0, &h)) != 0) {
+-			if (dbp->type == DB_HASH ||
++			if ((dbp->type == DB_HASH ||
+ 			    (dbp->type == DB_QUEUE &&
+-			    F_ISSET(dbp, DB_AM_INMEM))) {
++			    F_ISSET(dbp, DB_AM_INMEM))) &&
++			    t_ret != DB_RUNRECOVERY) {
+ 				if ((t_ret =
+ 				    __db_vrfy_getpageinfo(vdp, i, &pip)) != 0)
+ 					goto err1;
+@@ -936,6 +939,8 @@ err:		if (h != NULL && (t_ret = __memp_f
+ 			return (ret == 0 ? t_ret : ret);
+ 	}
+ 
++	if (ret == DB_PAGE_NOTFOUND && isbad == 1)
++		ret = 0;
+ 	return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret);
+ }
+ 
+@@ -1567,7 +1572,7 @@ __db_vrfy_meta(dbp, vdp, meta, pgno, fla
+ 	if (pgno == PGNO_BASE_MD &&
+ 	    dbtype != DB_QUEUE && meta->last_pgno != vdp->last_pgno) {
+ #ifdef HAVE_FTRUNCATE
+-		isbad = 1;
++		ret = DB_VERIFY_FATAL;
+ 		EPRINT((env, DB_STR_A("0552",
+ 		    "Page %lu: last_pgno is not correct: %lu != %lu",
+ 		    "%lu %lu %lu"), (u_long)pgno,
+@@ -1608,7 +1613,11 @@ __db_vrfy_freelist(dbp, vdp, meta, flags
+ 
+ 	env = dbp->env;
+ 	pgset = vdp->pgset;
+-	DB_ASSERT(env, pgset != NULL);
++	if (pgset == NULL) {
++		EPRINT((env, DB_STR("5543",
++			"Error, database contains no visible pages.")));
++		return (DB_RUNRECOVERY);
++	}
+ 
+ 	if ((ret = __db_vrfy_getpageinfo(vdp, meta, &pip)) != 0)
+ 		return (ret);
+@@ -1993,7 +2002,8 @@ __db_salvage_pg(dbp, vdp, pgno, h, handl
+ 	int keyflag, ret, t_ret;
+ 
+ 	env = dbp->env;
+-	DB_ASSERT(env, LF_ISSET(DB_SALVAGE));
++	if (!LF_ISSET(DB_SALVAGE))
++		return (EINVAL);
+ 
+ 	/*
+ 	 * !!!
+@@ -2126,10 +2136,8 @@ __db_salvage_leaf(dbp, vdp, pgno, h, han
+ 	int (*callback) __P((void *, const void *));
+ 	u_int32_t flags;
+ {
+-	ENV *env;
+-
+-	env = dbp->env;
+-	DB_ASSERT(env, LF_ISSET(DB_SALVAGE));
++	if (!LF_ISSET(DB_SALVAGE))
++		return (EINVAL);
+ 
+ 	/* If we got this page in the subdb pass, we can safely skip it. */
+ 	if (__db_salvage_isdone(vdp, pgno))
+@@ -2223,8 +2231,8 @@ __db_salvage_unknowns(dbp, vdp, handle,
+ 				ret = t_ret;
+ 			break;
+ 		case SALVAGE_OVERFLOW:
+-			DB_ASSERT(env, 0);	/* Shouldn't ever happen. */
+-			break;
++			EPRINT((env, DB_STR("5544", "Invalid page type to salvage.")));
++			return (EINVAL);
+ 		case SALVAGE_HASH:
+ 			if ((t_ret = __ham_salvage(dbp, vdp,
+ 			    pgno, h, handle, callback, flags)) != 0 && ret == 0)
+@@ -2237,8 +2245,8 @@ __db_salvage_unknowns(dbp, vdp, handle,
+ 			 * Shouldn't happen, but if it does, just do what the
+ 			 * nice man says.
+ 			 */
+-			DB_ASSERT(env, 0);
+-			break;
++			EPRINT((env, DB_STR("5545", "Invalid page type to salvage.")));
++			return (EINVAL);
+ 		}
+ 		if ((t_ret = __memp_fput(mpf,
+ 		    vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
+@@ -2284,8 +2292,8 @@ __db_salvage_unknowns(dbp, vdp, handle,
+ 					ret = t_ret;
+ 			break;
+ 		default:
+-			DB_ASSERT(env, 0);	/* Shouldn't ever happen. */
+-			break;
++			EPRINT((env, DB_STR("5546", "Invalid page type to salvage.")));
++			return (EINVAL);
+ 		}
+ 		if ((t_ret = __memp_fput(mpf,
+ 		    vdp->thread_info, h, dbp->priority)) != 0 && ret == 0)
+@@ -2342,7 +2350,10 @@ __db_vrfy_inpitem(dbp, h, pgno, i, is_bt
+ 
+ 	env = dbp->env;
+ 
+-	DB_ASSERT(env, himarkp != NULL);
++	if (himarkp == NULL) {
++		__db_msg(env, "Page %lu index has no end.", (u_long)pgno);
++		return (DB_VERIFY_FATAL);
++	}
+ 	inp = P_INP(dbp, h);
+ 
+ 	/*
+@@ -2755,7 +2766,11 @@ __db_salvage_subdbpg(dbp, vdp, master, h
+ 					goto err;
+ 				ovfl_bufsz = bkkey->len + 1;
+ 			}
+-			DB_ASSERT(env, subdbname != NULL);
++			if (subdbname == NULL) {
++				EPRINT((env, DB_STR("5547", "Subdatabase cannot be null.")));
++				ret = EINVAL;
++				goto err;
++			}
+ 			memcpy(subdbname, bkkey->data, bkkey->len);
+ 			subdbname[bkkey->len] = '\0';
+ 		}
+--- a/src/db/db_vrfyutil.c
++++ b/src/db/db_vrfyutil.c
+@@ -208,7 +208,8 @@ __db_vrfy_getpageinfo(vdp, pgno, pipp)
+ 	if ((ret = __db_get(pgdbp,
+ 	    vdp->thread_info, vdp->txn, &key, &data, 0)) == 0) {
+ 		/* Found it. */
+-		DB_ASSERT(env, data.size == sizeof(VRFY_PAGEINFO));
++		if (data.size != sizeof(VRFY_PAGEINFO))
++			return (DB_VERIFY_FATAL);
+ 		pip = data.data;
+ 		LIST_INSERT_HEAD(&vdp->activepips, pip, links);
+ 		goto found;
+@@ -336,7 +337,8 @@ __db_vrfy_pgset_get(dbp, ip, txn, pgno,
+ 	F_SET(&data, DB_DBT_USERMEM);
+ 
+ 	if ((ret = __db_get(dbp, ip, txn, &key, &data, 0)) == 0) {
+-		DB_ASSERT(dbp->env, data.size == sizeof(int));
++		if (data.size != sizeof(int))
++			return (EINVAL);
+ 	} else if (ret == DB_NOTFOUND)
+ 		val = 0;
+ 	else
+@@ -376,7 +378,8 @@ __db_vrfy_pgset_inc(dbp, ip, txn, pgno)
+ 	F_SET(&data, DB_DBT_USERMEM);
+ 
+ 	if ((ret = __db_get(dbp, ip, txn, &key, &data, 0)) == 0) {
+-		DB_ASSERT(dbp->env, data.size == sizeof(int));
++		if (data.size != sizeof(int))
++			return (DB_VERIFY_FATAL);
+ 	} else if (ret != DB_NOTFOUND)
+ 		return (ret);
+ 
+@@ -413,7 +416,8 @@ __db_vrfy_pgset_next(dbc, pgnop)
+ 	if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT)) != 0)
+ 		return (ret);
+ 
+-	DB_ASSERT(dbc->env, key.size == sizeof(db_pgno_t));
++	if (key.size != sizeof(db_pgno_t))
++		return (DB_VERIFY_FATAL);
+ 	*pgnop = pgno;
+ 
+ 	return (0);
+@@ -560,7 +564,8 @@ __db_vrfy_ccset(dbc, pgno, cipp)
+ 	if ((ret = __dbc_get(dbc, &key, &data, DB_SET)) != 0)
+ 		return (ret);
+ 
+-	DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO));
++	if (data.size != sizeof(VRFY_CHILDINFO))
++		return (DB_VERIFY_FATAL);
+ 	*cipp = (VRFY_CHILDINFO *)data.data;
+ 
+ 	return (0);
+@@ -588,7 +593,8 @@ __db_vrfy_ccnext(dbc, cipp)
+ 	if ((ret = __dbc_get(dbc, &key, &data, DB_NEXT_DUP)) != 0)
+ 		return (ret);
+ 
+-	DB_ASSERT(dbc->env, data.size == sizeof(VRFY_CHILDINFO));
++	if (data.size != sizeof(VRFY_CHILDINFO))
++		return (DB_VERIFY_FATAL);
+ 	*cipp = (VRFY_CHILDINFO *)data.data;
+ 
+ 	return (0);
+@@ -715,7 +721,8 @@ __db_salvage_getnext(vdp, dbcp, pgnop, p
+ 		return (ret);
+ 
+ 	while ((ret = __dbc_get(*dbcp, &key, &data, DB_NEXT)) == 0) {
+-		DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t));
++		if (data.size != sizeof(u_int32_t))
++			return (DB_VERIFY_FATAL);
+ 		memcpy(&pgtype, data.data, sizeof(pgtype));
+ 
+ 		if (skip_overflow && pgtype == SALVAGE_OVERFLOW)
+@@ -724,8 +731,9 @@ __db_salvage_getnext(vdp, dbcp, pgnop, p
+ 		if ((ret = __dbc_del(*dbcp, 0)) != 0)
+ 			return (ret);
+ 		if (pgtype != SALVAGE_IGNORE) {
+-			DB_ASSERT(dbp->env, key.size == sizeof(db_pgno_t));
+-			DB_ASSERT(dbp->env, data.size == sizeof(u_int32_t));
++			if (key.size != sizeof(db_pgno_t)
++				|| data.size != sizeof(u_int32_t))
++				return (DB_VERIFY_FATAL);
+ 
+ 			*pgnop = *(db_pgno_t *)key.data;
+ 			*pgtypep = *(u_int32_t *)data.data;
+--- a/src/db/partition.c
++++ b/src/db/partition.c
+@@ -461,9 +461,19 @@ __partition_chk_meta(dbp, ip, txn, flags
+ 		} else
+ 			part->nparts = meta->nparts;
+ 	} else if (meta->nparts != 0 && part->nparts != meta->nparts) {
++		ret = EINVAL;
+ 		__db_errx(env, DB_STR("0656",
+ 		    "Number of partitions does not match."));
++		goto err;
++	}
++	/*
++	 * There is no limit on the number of partitions, but I cannot imagine a real
++	 * database having more than 10000.
++	 */
++	if (meta->nparts > 10000) {
+ 		ret = EINVAL;
++		__db_errx(env, DB_STR_A("5553",
++			"Too many partitions %lu", "%lu"), (u_long)(meta->nparts));
+ 		goto err;
+ 	}
+ 
+@@ -1874,10 +1884,13 @@ __part_verify(dbp, vdp, fname, handle, c
+ 			memcpy(rp->data, key->data, key->size);
+ 			B_TSET(rp->type, B_KEYDATA);
+ 		}
+-vrfy:		if ((t_ret = __db_verify(*pdbp, ip, (*pdbp)->fname,
+-		    NULL, handle, callback,
+-		    lp, rp, flags | DB_VERIFY_PARTITION)) != 0 && ret == 0)
+-			ret = t_ret;
++vrfy:   if ((t_ret = __db_verify(*pdbp, ip, (*pdbp)->fname,
++	      NULL, handle, callback,
++	      lp, rp, flags | DB_VERIFY_PARTITION)) != 0 && ret == 0) {
++	        ret = t_ret;
++            if (ret == ENOENT)
++                break;
++	    }
+ 	}
+ 
+ err:	if (lp != NULL)
+--- a/src/hash/hash_page.c
++++ b/src/hash/hash_page.c
+@@ -865,7 +865,11 @@ __ham_verify_sorted_page (dbc, p)
+ 	/* Validate that next, prev pointers are OK */
+ 	n = NUM_ENT(p);
+ 	dbp = dbc->dbp;
+-	DB_ASSERT(dbp->env, n%2 == 0 );
++	if (n % 2 != 0) {
++		__db_errx(dbp->env, DB_STR_A("5549",
++		  "Odd number of entries on page: %lu", "%lu"), (u_long)(p->pgno));
++		return (DB_VERIFY_FATAL);
++	}
+ 
+ 	env = dbp->env;
+ 	t = dbp->h_internal;
+@@ -936,7 +940,12 @@ __ham_verify_sorted_page (dbc, p)
+ 			if ((ret = __db_prpage(dbp, p, DB_PR_PAGE)) != 0)
+ 				return (ret);
+ #endif
+-			DB_ASSERT(dbp->env, res < 0);
++			if (res >= 0) {
++				__db_errx(env, DB_STR_A("5550",
++					"Odd number of entries on page: %lu", "%lu"),
++					(u_long)p->pgno);
++				return (DB_VERIFY_FATAL);
++			}
+ 		}
+ 
+ 		prev = curr;
+--- a/src/hash/hash_verify.c
++++ b/src/hash/hash_verify.c
+@@ -443,7 +443,7 @@ __ham_vrfy_structure(dbp, vdp, meta_pgno
+ 				isbad = 1;
+ 			else
+ 				goto err;
+-		    }
++		}
+ 
+ 	/*
+ 	 * There may be unused hash pages corresponding to buckets
+@@ -574,7 +574,7 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, f
+ 		    "Page %lu: impossible first page in bucket %lu", "%lu %lu"),
+ 		    (u_long)pgno, (u_long)bucket));
+ 		/* Unsafe to continue. */
+-		isbad = 1;
++		ret = DB_VERIFY_FATAL;
+ 		goto err;
+ 	}
+ 
+@@ -604,7 +604,7 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, f
+ 			EPRINT((env, DB_STR_A("1116",
+ 			    "Page %lu: hash page referenced twice", "%lu"),
+ 			    (u_long)pgno));
+-			isbad = 1;
++			ret = DB_VERIFY_FATAL;
+ 			/* Unsafe to continue. */
+ 			goto err;
+ 		} else if ((ret = __db_vrfy_pgset_inc(vdp->pgset,
+@@ -1049,7 +1049,11 @@ __ham_meta2pgset(dbp, vdp, hmeta, flags,
+ 	COMPQUIET(flags, 0);
+ 	ip = vdp->thread_info;
+ 
+-	DB_ASSERT(dbp->env, pgset != NULL);
++	if (pgset == NULL) {
++		EPRINT((dbp->env, DB_STR("5548",
++			"Error, database contains no visible pages.")));
++		return (DB_VERIFY_FATAL);
++	}
+ 
+ 	mpf = dbp->mpf;
+ 	totpgs = 0;
+--- a/src/qam/qam_verify.c
++++ b/src/qam/qam_verify.c
+@@ -465,7 +465,14 @@ __qam_vrfy_walkqueue(dbp, vdp, handle, c
+ 	/* Verify/salvage each page. */
+ 	if ((ret = __db_cursor(dbp, vdp->thread_info, NULL, &dbc, 0)) != 0)
+ 		return (ret);
+-begin:	for (; i <= stop; i++) {
++begin:	if ((stop - i) > 100000) {
++		EPRINT((env, DB_STR_A("5551",
++"Warning, many possible extends files (%lu), will take a long time to verify",
++          "%lu"), (u_long)(stop - i)));
++	}
++	for (; i <= stop; i++) {
++		if (i == UINT32_MAX)
++			break;
+ 		/*
+ 		 * If DB_SALVAGE is set, we inspect our database of completed
+ 		 * pages, and skip any we've already printed in the subdb pass.
diff --git a/external/subpack/libs/db/patches/120-CVE-2019-8457.patch b/external/subpack/libs/db/patches/120-CVE-2019-8457.patch
new file mode 100644
index 0000000..658719f
--- /dev/null
+++ b/external/subpack/libs/db/patches/120-CVE-2019-8457.patch
@@ -0,0 +1,67 @@
+Description: Enhance the rtreenode function in order to avoid a heap out-of-bounds read
+Origin: https://www.sqlite.org/src/info/90acdbfce9c08858
+Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=929775
+
+--- a/lang/sql/sqlite/ext/rtree/rtree.c
++++ b/lang/sql/sqlite/ext/rtree/rtree.c
+@@ -3089,38 +3089,45 @@ static void rtreenode(sqlite3_context *c
+   RtreeNode node;
+   Rtree tree;
+   int ii;
++  int nData;
++  int errCode;
++  sqlite3_str *pOut;
+ 
+   UNUSED_PARAMETER(nArg);
+   memset(&node, 0, sizeof(RtreeNode));
+   memset(&tree, 0, sizeof(Rtree));
+   tree.nDim = sqlite3_value_int(apArg[0]);
++  if( tree.nDim<1 || tree.nDim>5 ) return;
+   tree.nBytesPerCell = 8 + 8 * tree.nDim;
+   node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
++  nData = sqlite3_value_bytes(apArg[1]);
++  if( nData<4 ) return;
++  if( nData<NCELL(&node)*tree.nBytesPerCell ) return;
+ 
++  pOut = sqlite3_str_new(0);
+   for(ii=0; ii<NCELL(&node); ii++){
+-    char zCell[512];
+-    int nCell = 0;
+     RtreeCell cell;
+     int jj;
+ 
+     nodeGetCell(&tree, &node, ii, &cell);
+-    sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid);
+-    nCell = strlen(zCell);
++    if( ii>0 ) sqlite3_str_append(pOut, " ", 1);
++    sqlite3_str_appendf(pOut, "{%lld", cell.iRowid);
+     for(jj=0; jj<tree.nDim*2; jj++){
+-      sqlite3_snprintf(512-nCell,&zCell[nCell]," %f",(double)cell.aCoord[jj].f);
+-      nCell = strlen(zCell);
++#ifndef SQLITE_RTREE_INT_ONLY
++      sqlite3_str_appendf(pOut, " %g", (double)cell.aCoord[jj].f);
++#else
++      sqlite3_str_appendf(pOut, " %d", cell.aCoord[jj].i);
++#endif
+     }
+ 
+-    if( zText ){
+-      char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell);
+-      sqlite3_free(zText);
+-      zText = zTextNew;
+-    }else{
+-      zText = sqlite3_mprintf("{%s}", zCell);
+-    }
++
++    sqlite3_str_append(pOut, "}", 1);
++
+   }
+-  
+-  sqlite3_result_text(ctx, zText, -1, sqlite3_free);
++  errCode = sqlite3_str_errcode(pOut);
++  sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free);
++  sqlite3_result_error_code(ctx, errCode);
++
+ }
+ 
+ static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
diff --git a/external/subpack/libs/db/patches/130-CVE-2017-10140-cwd-db_config.patch b/external/subpack/libs/db/patches/130-CVE-2017-10140-cwd-db_config.patch
new file mode 100644
index 0000000..e4561ab
--- /dev/null
+++ b/external/subpack/libs/db/patches/130-CVE-2017-10140-cwd-db_config.patch
@@ -0,0 +1,22 @@
+Description: CVE-2017-10140: Reads DB_CONFIG from the current working directory
+ Do not access DB_CONFIG when db_home is not set.
+Origin: vendor, https://src.fedoraproject.org/rpms/libdb/raw/8047fa8580659fcae740c25e91b490539b8453eb/f/db-5.3.28-cwd-db_config.patch
+Bug-Debian: https://bugs.debian.org/872436
+Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1464032
+Bug-SuSE: https://bugzilla.novell.com/show_bug.cgi?id=1043886
+Forwarded: no
+Author: Petr Kubat <pkubat@redhat.com>
+Reviewed-by: Salvatore Bonaccorso <carnil@debian.org>
+Last-Update: 2017-08-17
+
+--- a/src/env/env_open.c
++++ b/src/env/env_open.c
+@@ -473,7 +473,7 @@ __env_config(dbenv, db_home, flagsp, mod
+ 	env->db_mode = mode == 0 ? DB_MODE_660 : mode;
+ 
+ 	/* Read the DB_CONFIG file. */
+-	if ((ret = __env_read_db_config(env)) != 0)
++	if (env->db_home != NULL && (ret = __env_read_db_config(env)) != 0)
+ 		return (ret);
+ 
+ 	/*
diff --git a/external/subpack/libs/db/patches/140-mmap_extend-mode-requires-page-aligned-extends.patch b/external/subpack/libs/db/patches/140-mmap_extend-mode-requires-page-aligned-extends.patch
new file mode 100644
index 0000000..f6f855b
--- /dev/null
+++ b/external/subpack/libs/db/patches/140-mmap_extend-mode-requires-page-aligned-extends.patch
@@ -0,0 +1,34 @@
+From: Andy Whitcroft <apw@canonical.com>
+Subject: [PATCH] MMAP_EXTEND mode requires we extend in full system page increments
+Date: Wed, 12 Mar 2014 11:58:31 +0100
+
+When extending a mmap file we must ensure we extend by full system pages,
+otherwise there is a risk (when the filesystem page size is smaller than
+the system page size) that we will not allocate disk extents to store
+the memory and it will be lost resulting in data loss.
+
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
+
+---
+ env_file.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/src/env/env_file.c
++++ b/src/env/env_file.c
+@@ -28,6 +28,15 @@ __db_file_extend(env, fhp, size)
+ 	int ret;
+ 	char buf;
+ 
++#ifdef HAVE_MMAP_EXTEND
++	/*
++	 * We have to ensure we extend a mmap'd segment a full memory page at
++	 * a time or risk the end of the page not having any filesystem blocks
++	 * associated resulting in the data loss.
++	 */
++	size = DB_ALIGN(size, getpagesize()) - 1;
++#endif
++
+ 	buf = '\0';
+ 	/*
+ 	 * Extend the file by writing the last page.  If the region is >4Gb,
diff --git a/external/subpack/libs/db/patches/150-mutex-alignment.patch b/external/subpack/libs/db/patches/150-mutex-alignment.patch
new file mode 100644
index 0000000..88d890a
--- /dev/null
+++ b/external/subpack/libs/db/patches/150-mutex-alignment.patch
@@ -0,0 +1,15 @@
+--- a/src/dbinc/mutex_int.h
++++ b/src/dbinc/mutex_int.h
+@@ -850,7 +850,11 @@ typedef volatile unsigned char tsl_t;
+  * alignment locally.
+  */
+ #ifndef	MUTEX_ALIGN
+-#define	MUTEX_ALIGN	sizeof(unsigned int)
++# if defined(__linux__) && defined(__sparc__)
++# define	MUTEX_ALIGN	8
++# else
++# define	MUTEX_ALIGN	sizeof(unsigned int)
++# endif
+ #endif
+ 
+ /*
diff --git a/external/subpack/libs/db/patches/160-pg_crypt_size.patch b/external/subpack/libs/db/patches/160-pg_crypt_size.patch
new file mode 100644
index 0000000..0997d5f
--- /dev/null
+++ b/external/subpack/libs/db/patches/160-pg_crypt_size.patch
@@ -0,0 +1,29 @@
+--- a/src/dbinc/db_page.h
++++ b/src/dbinc/db_page.h
+@@ -256,6 +256,17 @@ typedef struct __pg_crypto {
+ 	 */
+ } PG_CRYPTO;
+ 
++/*
++ * With most compilers sizeof(PG_CRYPTO) == 38.  However some ABIs
++ * require it to be padded to 40 bytes.  The padding must be excluded
++ * from our size calculations due to the 16-byte alignment requirement
++ * for crypto.
++ *
++ * A similar problem applies to PG_CHKSUM, but it's too late to change
++ * that.
++ */
++#define SIZEOF_PG_CRYPTO 38
++
+ typedef struct _db_page {
+ 	DB_LSN	  lsn;		/* 00-07: Log sequence number. */
+ 	db_pgno_t pgno;		/* 08-11: Current page number. */
+@@ -291,7 +302,7 @@ typedef struct _db_page {
+  */
+ #define	P_INP(dbp, pg)							\
+ 	((db_indx_t *)((u_int8_t *)(pg) + SIZEOF_PAGE +			\
+-	(F_ISSET((dbp), DB_AM_ENCRYPT) ? sizeof(PG_CRYPTO) :		\
++	(F_ISSET((dbp), DB_AM_ENCRYPT) ? SIZEOF_PG_CRYPTO :		\
+ 	(F_ISSET((dbp), DB_AM_CHKSUM) ? sizeof(PG_CHKSUM) : 0))))
+ 
+ #define	P_IV(dbp, pg)							\
diff --git a/external/subpack/libs/dmx_usb_module/Makefile b/external/subpack/libs/dmx_usb_module/Makefile
new file mode 100644
index 0000000..309c6fe
--- /dev/null
+++ b/external/subpack/libs/dmx_usb_module/Makefile
@@ -0,0 +1,55 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=dmx_usb_module
+PKG_VERSION:=19.12.1
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/lowlander/dmx_usb_module/tar.gz/V$(PKG_VERSION)?
+PKG_HASH:=fabeb5500b55197338dda45d07374e5edc837bc18df3ac3114b442fe47cf1b68
+
+PKG_MAINTAINER:=Martijn Zilverschoon <martijn@friedzombie.com>
+PKG_LICENSE:=GPL-2.0-only
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/usb-serial-dmx_usb_module
+	SECTION:=kernel
+	CATEGORY:=Kernel modules
+	SUBMENU:=USB Support
+	TITLE:=Support for FTDI RS485 based DMX modules
+	URL:=http://www.erwinrol.com/open-dmx-usb-linux-driver/
+	FILES:=$(PKG_BUILD_DIR)/dmx_usb.$(LINUX_KMOD_SUFFIX)
+	AUTOLOAD:=$(call AutoProbe,dmx_usb)
+	DEPENDS+=kmod-usb-serial
+endef
+
+define KernelPackage/usb-serial-dmx_usb_module/description
+	Open DMX USB is an open USB to DMX dongle hardware design developed by Enttec.
+	The Open in Open DMX USB refers to the fact that everybody is free to use the
+	design and produce its own USB DMX Dongle without paying any licenses.
+endef
+
+DMX_MAKE_OPTS:= -C $(PKG_BUILD_DIR) \
+	PATH="$(TARGET_PATH)" \
+	ARCH="$(LINUX_KARCH)" \
+	CROSS_COMPILE="$(TARGET_CROSS)" \
+	TARGET="$(HAL_TARGET)" \
+	TOOLPREFIX="$(KERNEL_CROSS)" \
+	TOOLPATH="$(KERNEL_CROSS)" \
+	KERNELPATH="$(LINUX_DIR)" \
+	LDOPTS=" "
+
+define Build/Compile
+  $(MAKE) $(DMX_MAKE_OPTS) M=$(PKG_BUILD_DIR)
+endef
+
+$(eval $(call KernelPackage,usb-serial-dmx_usb_module))
diff --git a/external/subpack/libs/dmx_usb_module/patches/001-dmx_usb_Makefile.patch b/external/subpack/libs/dmx_usb_module/patches/001-dmx_usb_Makefile.patch
new file mode 100644
index 0000000..473e961
--- /dev/null
+++ b/external/subpack/libs/dmx_usb_module/patches/001-dmx_usb_Makefile.patch
@@ -0,0 +1,12 @@
+--- a/Makefile
++++ b/Makefile
+@@ -12,8 +12,7 @@ KDIR	:= /lib/modules/$(shell uname -r)/b
+ PWD	:= $(shell pwd)
+ 
+ default:
+-	$(MAKE) -C $(KDIR) M=$(PWD)
+-	gcc -O2 -pipe -Wall dmx_usb_test.c -o dmx_usb_test
++	$(MAKE) -C $(KERNELPATH) M=$(PWD)
+ 
+ endif
+ 
diff --git a/external/subpack/libs/dmx_usb_module/patches/100-fix-compilation-warning-wrong-cast.patch b/external/subpack/libs/dmx_usb_module/patches/100-fix-compilation-warning-wrong-cast.patch
new file mode 100644
index 0000000..9d9767d
--- /dev/null
+++ b/external/subpack/libs/dmx_usb_module/patches/100-fix-compilation-warning-wrong-cast.patch
@@ -0,0 +1,37 @@
+From eeecf40c3eb3dbdf1981c508080ab3aa61e105e2 Mon Sep 17 00:00:00 2001
+From: Erwin Rol <erwin@erwinrol.com>
+Date: Fri, 13 Jan 2023 17:57:36 +0100
+Subject: [PATCH] Fix format warnings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fix the following warning
+
+warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘size_t’ {aka ‘long unsigned int’}
+
+Signed-off-by: Erwin Rol <erwin@erwinrol.com>
+---
+ dmx_usb.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/dmx_usb.c
++++ b/dmx_usb.c
+@@ -406,7 +406,7 @@ static ssize_t dmx_usb_write (struct fil
+ 
+ 	dev = (struct dmx_usb_device *)file->private_data;
+ 
+-	dbg("%s - minor %d, count = %d", __FUNCTION__, dev->minor, count);
++	dbg("%s - minor %d, count = %zu", __FUNCTION__, dev->minor, count);
+ 
+ 	/* lock this object */
+ 	down (&dev->sem);
+@@ -500,7 +500,7 @@ static long dmx_usb_ioctl (struct file *
+ 		return -ENODEV;
+ 	}
+ 
+-	dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __FUNCTION__,
++	dbg("%s - minor %d, cmd 0x%.4x, arg %lu", __FUNCTION__,
+ 	    dev->minor, cmd, arg);
+ 
+ 	/* fill in your device specific stuff here */
diff --git a/external/subpack/libs/dmx_usb_module/patches/101-fix-kernel-6.6-builds.patch b/external/subpack/libs/dmx_usb_module/patches/101-fix-kernel-6.6-builds.patch
new file mode 100644
index 0000000..d0cd7bd
--- /dev/null
+++ b/external/subpack/libs/dmx_usb_module/patches/101-fix-kernel-6.6-builds.patch
@@ -0,0 +1,14 @@
+--- a/dmx_usb.c
++++ b/dmx_usb.c
+@@ -97,7 +97,11 @@ struct dmx_usb_device {
+ 
+ 
+ /* prevent races between open() and disconnect() */
++#if(LINUX_VERSION_CODE < KERNEL_VERSION(6,5,3))
+ 	static DEFINE_SEMAPHORE(disconnect_sem);
++#else
++	static DEFINE_SEMAPHORE(disconnect_sem, 1);
++#endif
+ 
+ /* local function prototypes */
+ static ssize_t dmx_usb_write	(struct file *file, const char *buffer, size_t count, loff_t *ppos);
diff --git a/external/subpack/libs/dtndht/Makefile b/external/subpack/libs/dtndht/Makefile
new file mode 100644
index 0000000..5846249
--- /dev/null
+++ b/external/subpack/libs/dtndht/Makefile
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2014 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:=dtndht
+PKG_VERSION:=0.2.3
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.ibr.cs.tu-bs.de/projects/ibr-dtn/releases
+PKG_HASH:=29749f6c4e1b79e6973dc7436bcc6e0aee86ce27e1786f32a60feab652af8898
+PKG_MAINTAINER:=Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
+PKG_LICENSE:=Apache-2.0
+
+PKG_INSTALL:=1
+PKG_FIXUP:=libtool
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/dtndht
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libopenssl
+  TITLE:=Library for DHT lookups for DTNs
+endef
+
+define Package/dtndht/description
+ A library with DHT functions for DTN name lookups.
+endef
+
+TARGET_CFLAGS += -std=gnu89
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)
+	$(CP) $(PKG_INSTALL_DIR)/* $(1)/
+endef
+
+define Package/dtndht/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,dtndht))
diff --git a/external/subpack/libs/dtndht/patches/001-musl_header.patch b/external/subpack/libs/dtndht/patches/001-musl_header.patch
new file mode 100644
index 0000000..32eeb6a
--- /dev/null
+++ b/external/subpack/libs/dtndht/patches/001-musl_header.patch
@@ -0,0 +1,30 @@
+--- a/dtndht/dtndht.h
++++ b/dtndht/dtndht.h
+@@ -7,6 +7,7 @@ extern "C" {
+ 
+ #include <stdio.h>
+ #include <sys/socket.h>
++#include <time.h>
+ 
+ enum dtn_dht_bind_type {
+ 	BINDNONE = 0, IPV4ONLY = 1, IPV6ONLY = 2, BINDBOTH = 3
+--- a/dtndht/blacklist.c
++++ b/dtndht/blacklist.c
+@@ -6,6 +6,7 @@
+ #include <string.h>
+ #include <stdio.h>
+ #include <arpa/inet.h>
++#include <sys/types.h>
+ #ifdef HAVE_OPENSSL_SHA_H
+ #include <openssl/sha.h>
+ #else
+--- a/dtndht/rating.h
++++ b/dtndht/rating.h
+@@ -12,6 +12,7 @@
+ #include <sys/socket.h>
+ #include <arpa/inet.h>
+ #include <string.h>
++#include <time.h>
+ #ifdef HAVE_OPENSSL_SHA_H
+ #include <openssl/sha.h>
+ #else
diff --git a/external/subpack/libs/easyloggingpp/Makefile b/external/subpack/libs/easyloggingpp/Makefile
new file mode 100644
index 0000000..f8644cb
--- /dev/null
+++ b/external/subpack/libs/easyloggingpp/Makefile
@@ -0,0 +1,34 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=easyloggingpp
+PKG_VERSION:=9.97.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/abumq/easyloggingpp/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=ebe473e17b13f1d1f16d0009689576625796947a711e14aec29530f39560c7c2
+
+PKG_MAINTAINER:=Volker Christian <me@vchrist.at>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/easyloggingpp
+  SECTION:=lib
+  CATEGORY:=Libraries
+  TITLE:=A single header C++ Logging Library
+  URL:=https://github.com/abumq/easyloggingpp
+  BUILDONLY:=1
+endef
+
+define Package/easyloggingpp/description
+  Easylogging++ is single header efficient logging library for C++
+  applications. It is extremely powerful, highly extendable and
+  configurable to user's requirements.
+endef
+
+$(eval $(call BuildPackage,easyloggingpp))
diff --git a/external/subpack/libs/efivar/Makefile b/external/subpack/libs/efivar/Makefile
new file mode 100644
index 0000000..8d7ce6e
--- /dev/null
+++ b/external/subpack/libs/efivar/Makefile
@@ -0,0 +1,68 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=efivar
+PKG_VERSION:=38
+PKG_RELEASE:=4
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://github.com/rhboot/efivar/releases/download/$(PKG_VERSION)
+PKG_HASH:=f018ed6e49c5f1c16d336d9fd7687ce87023276591921db1e49a314ad6515349
+
+PKG_LICENSE:=LGPL-2.1-only
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
+
+PKG_BUILD_FLAGS:=no-mold
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/efivar
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Tools and libraries to work with EFI variables
+  DEPENDS:=@(TARGET_x86_64||TARGET_armsr_armv8)
+  URL:=https://github.com/rhboot/efibootmgr
+endef
+
+define Package/efivar/description
+  Tools and libraries to work with EFI variables
+endef
+
+MAKE_VARS += \
+	ERRORS= \
+	HOSTCC="$(HOSTCC)" \
+	HOST_CFLAGS="$(HOST_CFLAGS)" \
+	HOST_LDFLAGS="$(HOST_LDFLAGS)" \
+	LIBDIR="/usr/lib"
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libefiboot.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libefisec.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libefivar.so* $(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/include/efivar
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/efivar/*.h $(1)/usr/include/efivar/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/efivar/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/efisecdb $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/efivar $(1)/usr/bin/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libefiboot.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libefisec.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libefivar.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,efivar))
diff --git a/external/subpack/libs/efivar/patches/002-musl-compat.patch b/external/subpack/libs/efivar/patches/002-musl-compat.patch
new file mode 100644
index 0000000..be3cfec
--- /dev/null
+++ b/external/subpack/libs/efivar/patches/002-musl-compat.patch
@@ -0,0 +1,199 @@
+From cece3ffd5be2f8641eb694513f2b73e5eb97ffd3 Mon Sep 17 00:00:00 2001
+From: Natanael Copa <ncopa@alpinelinux.org>
+Date: Fri, 28 Jan 2022 12:13:30 +0100
+Subject: [PATCH 1/2] efisecdb: fix build with musl libc
+
+Refactor code to use POSIX atexit(3) instead of the GNU specific
+on_exit(3).
+
+Resolves: #197
+Resolves: #202
+Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
+
+--- a/src/compiler.h
++++ b/src/compiler.h
+@@ -7,8 +7,6 @@
+ #ifndef COMPILER_H_
+ #define COMPILER_H_
+ 
+-#include <sys/cdefs.h>
+-
+ /* GCC version checking borrowed from glibc. */
+ #if defined(__GNUC__) && defined(__GNUC_MINOR__)
+ #  define GNUC_PREREQ(maj,min) \
+--- a/src/efisecdb.c
++++ b/src/efisecdb.c
+@@ -25,6 +25,10 @@
+ extern char *optarg;
+ extern int optind, opterr, optopt;
+ 
++static efi_secdb_t *secdb = NULL;
++static list_t infiles;
++static list_t actions;
++
+ struct hash_param {
+ 	char *name;
+ 	efi_secdb_type_t algorithm;
+@@ -187,12 +191,11 @@ add_action(list_t *list, action_type_t a
+ }
+ 
+ static void
+-free_actions(int status UNUSED, void *actionsp)
++free_actions(void)
+ {
+-	list_t *actions = (list_t *)actionsp;
+ 	list_t *pos, *tmp;
+ 
+-	for_each_action_safe(pos, tmp, actions) {
++	for_each_action_safe(pos, tmp, &actions) {
+ 		action_t *action = list_entry(pos, action_t, list);
+ 
+ 		list_del(&action->list);
+@@ -202,12 +205,11 @@ free_actions(int status UNUSED, void *ac
+ }
+ 
+ static void
+-free_infiles(int status UNUSED, void *infilesp)
++free_infiles(void)
+ {
+-	list_t *infiles = (list_t *)infilesp;
+ 	list_t *pos, *tmp;
+ 
+-	for_each_ptr_safe(pos, tmp, infiles) {
++	for_each_ptr_safe(pos, tmp, &infiles) {
+ 		ptrlist_t *entry = list_entry(pos, ptrlist_t, list);
+ 
+ 		list_del(&entry->list);
+@@ -216,27 +218,12 @@ free_infiles(int status UNUSED, void *in
+ }
+ 
+ static void
+-maybe_free_secdb(int status UNUSED, void *voidp)
++maybe_free_secdb(void)
+ {
+-	efi_secdb_t **secdbp = (efi_secdb_t **)voidp;
+-
+-	if (secdbp == NULL || *secdbp == NULL)
++	if (secdb == NULL)
+ 		return;
+ 
+-	efi_secdb_free(*secdbp);
+-}
+-
+-static void
+-maybe_do_unlink(int status, void *filep)
+-{
+-	char **file = (char **)filep;
+-
+-	if (status == 0)
+-		return;
+-	if (file == NULL || *file == NULL)
+-		return;
+-
+-	unlink(*file);
++	efi_secdb_free(secdb);
+ }
+ 
+ static void
+@@ -268,8 +255,7 @@ list_guids(void)
+  * failure.
+  */
+ static int
+-parse_input_files(list_t *infiles, char **outfile, efi_secdb_t **secdb,
+-		  bool dump)
++parse_input_files(list_t *infiles, efi_secdb_t **secdb, bool dump)
+ {
+ 	int status = 0;
+ 	list_t *pos, *tmp;
+@@ -310,8 +296,6 @@ parse_input_files(list_t *infiles, char
+ 				if (!dump)
+ 					exit(1);
+ 				status = 1;
+-				xfree(*outfile);
+-				*outfile = NULL;
+ 				break;
+ 			}
+ 		}
+@@ -323,15 +307,6 @@ parse_input_files(list_t *infiles, char
+ 	return status;
+ }
+ 
+-/*
+- * These need to be static globals so that they're not on main's stack when
+- * on_exit() fires.
+- */
+-static efi_secdb_t *secdb = NULL;
+-static list_t infiles;
+-static list_t actions;
+-static char *outfile = NULL;
+-
+ int
+ main(int argc, char *argv[])
+ {
+@@ -351,6 +326,7 @@ main(int argc, char *argv[])
+ 	bool do_sort_data = false;
+ 	bool sort_descending = false;
+ 	int status = 0;
++	char *outfile = NULL;
+ 
+ 	const char sopts[] = ":aAc:dfg:h:i:Lo:rs:t:v?";
+ 	const struct option lopts[] = {
+@@ -376,10 +352,9 @@ main(int argc, char *argv[])
+ 	INIT_LIST_HEAD(&infiles);
+ 	INIT_LIST_HEAD(&actions);
+ 
+-	on_exit(free_actions, &actions);
+-	on_exit(free_infiles, &infiles);
+-	on_exit(maybe_free_secdb, &secdb);
+-	on_exit(maybe_do_unlink, &outfile);
++	atexit(free_actions);
++	atexit(free_infiles);
++	atexit(maybe_free_secdb);
+ 
+ 	/*
+ 	 * parse the command line.
+@@ -550,7 +525,7 @@ sort_err:
+ 	efi_secdb_set_bool(secdb, EFI_SECDB_SORT_DATA, do_sort_data);
+ 	efi_secdb_set_bool(secdb, EFI_SECDB_SORT_DESCENDING, sort_descending);
+ 
+-	status = parse_input_files(&infiles, &outfile, &secdb, dump);
++	status = parse_input_files(&infiles, &secdb, dump);
+ 	if (status == 0) {
+ 		for_each_action_safe(pos, tmp, &actions) {
+ 			action_t *action = list_entry(pos, action_t, list);
+@@ -587,24 +562,30 @@ sort_err:
+ 	outfd = open(outfile, flags, 0600);
+ 	if (outfd < 0) {
+ 		char *tmpoutfile = outfile;
+-		if (errno == EEXIST)
+-			outfile = NULL;
++		if (errno != EEXIST)
++			unlink(outfile);
+ 		err(1, "could not open \"%s\"", tmpoutfile);
+ 	}
+ 
+ 	rc = ftruncate(outfd, 0);
+-	if (rc < 0)
++	if (rc < 0) {
++		unlink(outfile);
+ 		err(1, "could not truncate output file \"%s\"", outfile);
++	}
+ 
+ 	void *output;
+ 	size_t size = 0;
+ 	rc = efi_secdb_realize(secdb, &output, &size);
+-	if (rc < 0)
++	if (rc < 0) {
++		unlink(outfile);
+ 		secdb_err(1, "could not realize signature list");
++	}
+ 
+ 	rc = write(outfd, output, size);
+-	if (rc < 0)
++	if (rc < 0) {
++		unlink(outfile);
+ 		err(1, "could not write signature list");
++	}
+ 
+ 	close(outfd);
+ 	xfree(output);
diff --git a/external/subpack/libs/efivar/patches/003-Use-off_t-instead-of-off64_t.patch b/external/subpack/libs/efivar/patches/003-Use-off_t-instead-of-off64_t.patch
new file mode 100644
index 0000000..0f1ac79
--- /dev/null
+++ b/external/subpack/libs/efivar/patches/003-Use-off_t-instead-of-off64_t.patch
@@ -0,0 +1,40 @@
+From 914c686cc54b2405dab08bff77cd60827aab54b1 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Wed, 14 Dec 2022 16:55:51 -0800
+Subject: [PATCH] Use off_t instead of off64_t
+
+Pass _FILE_OFFSET_BITS=64 to ensure 64bit off_t
+
+This helps building efivar for 32bit arches on systems using musl C
+library. It works with glibc since _GNU_SOURCE defines
+_LARGEFILE64_SOURCE as well, this feature test macro enables the 64bit
+interfaces which were done as intermediate steps when transition to
+66-bit off_t was done as part olf LFS64 support.
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ src/error.c             | 2 +-
+ src/include/defaults.mk | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+--- a/src/error.c
++++ b/src/error.c
+@@ -191,7 +191,7 @@ dbglog_write(void *cookie, const char *b
+ }
+ 
+ static int
+-dbglog_seek(void *cookie UNUSED, off64_t *offset, int whence)
++dbglog_seek(void *cookie UNUSED, off_t *offset, int whence)
+ {
+ 	FILE *log = efi_errlog ? efi_errlog : stderr;
+ 	int rc;
+--- a/src/include/defaults.mk
++++ b/src/include/defaults.mk
+@@ -34,6 +34,7 @@ CPPFLAGS ?=
+ override _CPPFLAGS := $(CPPFLAGS)
+ override CPPFLAGS = $(_CPPFLAGS) -DLIBEFIVAR_VERSION=$(VERSION) \
+ 	    -D_GNU_SOURCE \
++	    -D_FILE_OFFSET_BITS=64 \
+ 	    -I$(TOPDIR)/src/include/
+ CFLAGS ?= $(OPTIMIZE) $(DEBUGINFO) $(WARNINGS) $(ERRORS)
+ CFLAGS_GCC ?= -specs=$(TOPDIR)/src/include/gcc.specs \
diff --git a/external/subpack/libs/efivar/patches/005-skip-docs.patch b/external/subpack/libs/efivar/patches/005-skip-docs.patch
new file mode 100644
index 0000000..94e20d7
--- /dev/null
+++ b/external/subpack/libs/efivar/patches/005-skip-docs.patch
@@ -0,0 +1,11 @@
+--- a/Makefile
++++ b/Makefile
+@@ -7,7 +7,7 @@ include $(TOPDIR)/src/include/defaults.m
+ include $(TOPDIR)/src/include/coverity.mk
+ include $(TOPDIR)/src/include/scan-build.mk
+ 
+-SUBDIRS := src docs
++SUBDIRS := src
+ 
+ all : | efivar.spec src/include/version.mk prep
+ all clean install prep :
diff --git a/external/subpack/libs/efivar/patches/006-build-util-c-separately-for-makeguids.patch b/external/subpack/libs/efivar/patches/006-build-util-c-separately-for-makeguids.patch
new file mode 100644
index 0000000..2305ebb
--- /dev/null
+++ b/external/subpack/libs/efivar/patches/006-build-util-c-separately-for-makeguids.patch
@@ -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))
diff --git a/external/subpack/libs/elektra/Makefile b/external/subpack/libs/elektra/Makefile
new file mode 100644
index 0000000..76df212
--- /dev/null
+++ b/external/subpack/libs/elektra/Makefile
@@ -0,0 +1,464 @@
+#
+# Copyright (C) 2006-2016 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# No copyright by Harald Geyer as filling in a template doesn't constitute
+# an original work in the sense of copyright law.
+
+include $(TOPDIR)/rules.mk
+
+PKG_MAINTAINER:=Harald Geyer <harald@ccbib.org>
+
+PKG_NAME:=elektra
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE.md
+PKG_VERSION:=0.9.14
+PKG_RELEASE:=1
+
+# Use this for official releasees
+PKG_HASH:=e4632bb6baa78f6a68c312469e41fd1ef07406571749e32f2645b1858d01a58d
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://ftp.libelektra.org/ftp/elektra/releases
+
+# Use this to test versions still under development
+#PKG_SOURCE_PROTO:=git
+#PKG_SOURCE_URL:=https://github.com/ElektraInitiative/libelektra.git
+#PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+#PKG_SOURCE_VERSION:=e97efb29a94f3a49cb952d06552fcf53708ea8c7
+#PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
+
+PKG_BUILD_DEPENDS:= lua
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libelektra/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Elektra
+  URL:=http://www.libelektra.org/
+  SUBMENU:=LibElektra
+endef
+
+define Package/libelektra/Default-description
+Elektra provides an universal and secure framework to store
+configuration parameters in a global, hierarchical key database.
+endef
+
+define Package/libelektra-core
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra core library
+  DEPENDS:=+libpthread
+endef
+
+define Package/libelektra-core/description
+$(call Package/libelektra/Default-description)
+
+This package contains the core libraries, that all other parts of
+elektra and all programs using elektra depend on, and an almost
+minimal set of plugins to be actually useful.
+endef
+
+define Package/elektra-kdb
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Elektra kdb tool
+  URL:=http://www.libelektra.org/
+  DEPENDS:=+libelektra-core +libstdcpp
+endef
+
+define Package/elektra-kdb/description
+$(call Package/libelektra/Default-description)
+
+This package contains the kdb tool, which allows to access and change
+the content of the key database from the shell.
+endef
+
+define Package/libelektra-resolvers
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra additional resolvers
+  DEPENDS:=+libelektra-core +libpthread
+endef
+
+define Package/libelektra-resolvers/description
+$(call Package/libelektra/Default-description)
+
+This package contains additional resolvers not included in the
+libelektra-core package. Usually there is no reason to install this.
+endef
+
+define Package/libelektra-plugins
+  $(call Package/libelektra/Default)
+  TITLE:=Useful elektra plugins
+  DEPENDS:=+libelektra-core $(ICONV_DEPENDS)
+endef
+
+define CONTENT_ELEKTRA_PLUGINS_TEXT
+base64 blacklist conditionals csvstorage date file filecheck glob hexcode
+hexnumber hosts iconv ipaddr keytometa line lineendings
+mathcheck macaddr mini network path profile quickdump
+range reference rgbcolor shell syslog type uname unit validation
+endef
+
+CONTENT_ELEKTRA_PLUGINS = $(strip $(CONTENT_ELEKTRA_PLUGINS_TEXT))
+
+define Package/libelektra-plugins/description
+$(call Package/libelektra/Default-description)
+
+This package contains plugins for various common configuration file
+format and optional features without heavy dependencies. Currently
+these plugins are included:
+$(CONTENT_ELEKTRA_PLUGINS_TEXT)
+endef
+
+define Package/libelektra-cpp
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra plugins depending on libstdcpp
+  DEPENDS:=+libelektra-core +libstdcpp
+endef
+
+CONTENT_ELEKTRA_CPP=ccode directoryvalue dump
+
+define Package/libelektra-cpp/description
+$(call Package/libelektra/Default-description)
+
+This package contains plugins written in C++.
+Currently these are:
+$(CONTENT_ELEKTRA_CPP)
+endef
+
+define Package/libelektra-crypto
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra crypto plugin
+  DEPENDS:=+libelektra-core +libgcrypt
+endef
+
+define Package/libelektra-crypto/description
+$(call Package/libelektra/Default-description)
+
+This package contains support for encrypting values before storage.
+endef
+
+define Package/libelektra-curlget
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra curlget plugin
+  DEPENDS:=+libelektra-core +libcurl +libopenssl
+endef
+
+define Package/libelektra-curlget/description
+$(call Package/libelektra/Default-description)
+
+This plugin can get configuration data from remote URLs before access.
+endef
+
+define Package/libelektra-dbus
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra dbus plugin
+  DEPENDS:=+libelektra-core +libdbus
+endef
+
+define Package/libelektra-dbus/description
+$(call Package/libelektra/Default-description)
+
+This package contains support for dbus notification on configuration
+changes.
+endef
+
+define Package/libelektra-ev
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra libev binding plugin
+  DEPENDS:=+libelektra-core +libev
+endef
+
+define Package/libelektra-ev/description
+$(call Package/libelektra/Default-description)
+
+This package contains support for notification on configuration
+changes via libev events.
+endef
+
+define Package/libelektra-uv
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra libuv binding plugin
+  DEPENDS:=+libelektra-core +libuv
+endef
+
+define Package/libelektra-uv/description
+$(call Package/libelektra/Default-description)
+
+This package contains support for notification on configuration
+changes via libuv events.
+endef
+
+define Package/libelektra-xerces
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra xerces based xml plugin
+  DEPENDS:=+libelektra-core +libstdcpp +libxerces-c
+endef
+
+define Package/libelektra-xerces/description
+$(call Package/libelektra/Default-description)
+
+The xerces plugin supplants the xmltool plugin
+and allows us to use XML files not following a specific schemata.
+Attributes are mapped to Elektra's metadata, multiple keys with the
+same names are mapped to arrays.
+endef
+
+define Package/libelektra-xml
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra xmltool plugin
+  DEPENDS:=+libelektra-core +libxml2
+endef
+
+define Package/libelektra-xml/description
+$(call Package/libelektra/Default-description)
+
+This package contains a plugin for storing data with xml syntax.
+endef
+
+define Package/libelektra-yajl
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra yajl (json) plugin
+  DEPENDS:=+libelektra-core +yajl
+endef
+
+define Package/libelektra-yajl/description
+$(call Package/libelektra/Default-description)
+
+This package contains support for storing the key database as json files.
+endef
+
+define Package/libelektra-yamlcpp
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra yaml plugin
+  DEPENDS:=+libelektra-core +libyaml-cpp
+endef
+
+define Package/libelektra-yamlcpp/description
+$(call Package/libelektra/Default-description)
+
+This package contains support for storing the key database as yaml files.
+endef
+
+define Package/libelektra-zmq
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra ZeroMQ transport plugins
+  DEPENDS:=+libelektra-core +libzmq
+endef
+
+define Package/libelektra-python3
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra python3 plugin
+  DEPENDS:=+libelektra-core +python3-light +libstdcpp
+endef
+
+define Package/libelektra-python3/description
+$(call Package/libelektra/Default-description)
+
+This package adds python3 support to elektra.
+endef
+
+define Package/libelektra-lua
+  $(call Package/libelektra/Default)
+  TITLE:=Elektra lua plugin
+  DEPENDS:=+libelektra-core +lua5.4 +libstdcpp
+endef
+
+define Package/libelektra-lua/description
+$(call Package/libelektra/Default-description)
+
+This package adds lua support to elektra.
+endef
+
+define Package/libelektra-extra
+  $(call Package/libelektra/Default)
+  TITLE:=Additional elektra plugins
+  DEPENDS:=+libelektra-core +libstdcpp
+endef
+
+define CONTENT_EXTRA_PLUGINS_TEXT
+blockresolver c constants counter desktop dpkg error fcrypt
+fstab logchange mozprefs passwd process rename
+timeofday tracer
+endef
+
+CONTENT_ELEKTRA_EXTRA:=$(strip $(CONTENT_EXTRA_PLUGINS_TEXT))
+
+define Package/libelektra-extra/description
+$(call Package/libelektra/Default-description)
+
+This package contains extra plugins that are only useful for debugging
+or as an example of what can be done. Also most experimental plugins
+are included in this package. Currently this includes:
+$(CONTENT_EXTRA_PLUGINS_TEXT)
+endef
+
+CMAKE_BINARY_SUBDIR=build
+
+CMAKE_OPTIONS += \
+	-DTARGET_PLUGIN_FOLDER="" \
+	-DCARGO_EXECUTABLE=OFF \
+	-DBUILD_FULL=OFF \
+	-DBUILD_STATIC=OFF \
+	-DBUILD_DOCUMENTATION=OFF \
+	-DFORCE_IN_SOURCE_BUILD=ON \
+	-DBUILD_TESTING=OFF \
+	-DKDB_DEFAULT_RESOLVER=resolver_fm_pb_b \
+	-DKDB_DEFAULT_STORAGE=toml \
+	-DENABLE_OPTIMIZATIONS=OFF \
+	-DPLUGINS="ALL;-gpgme;-multifile;-simpleini" \
+	-DBINDINGS="MAINTAINED;-intercept_env;-intercept_fs;-io_glib"
+
+define Package/libelektra-core/install
+	$(INSTALL_DIR) $(1)/etc/kdb/
+	$(INSTALL_DIR) $(1)/etc/profile.d/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(INSTALL_DATA) files/elektra.profile $(1)/etc/profile.d/elektra.sh
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-core.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-ease.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-globbing.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-highlevel.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-invoke.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-io.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-kdb.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-merge.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-meta.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-notification.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-opts.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-plugin.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-pluginprocess.so* $(1)/usr/lib/
+	#The next is only supported with glibc, so skip it.
+	#$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektraintercept-* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-resolver_fm_pb_b.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-utility.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-internalnotification.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-ni.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-spec.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-sync.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-storage.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-toml.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-resolver.so $(1)/usr/lib/
+endef
+
+define Package/elektra-kdb/install
+	$(INSTALL_DIR) $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/kdb $(1)/usr/bin
+	$(INSTALL_DIR) $(1)/usr/lib/elektra/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektratools* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/elektra/tool_exec/ $(1)/usr/lib/elektra/
+endef
+
+define Package/libelektra-resolvers/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-resolver_* $(1)/usr/lib/
+	rm -f $(1)/usr/lib/libelektra-resolver_fm_pb_b.so
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-wresolver.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-noresolver.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-plugins/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(foreach plugin,$(CONTENT_ELEKTRA_PLUGINS),$(PKG_INSTALL_DIR)/usr/lib/libelektra-$(plugin).so) $(1)/usr/lib/
+endef
+
+define Package/libelektra-cpp/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(foreach plugin,$(CONTENT_ELEKTRA_CPP),$(PKG_INSTALL_DIR)/usr/lib/libelektra-$(plugin).so) $(1)/usr/lib/
+endef
+
+define Package/libelektra-crypto/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-crypto.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-curlget/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-curlget.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-dbus/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-dbus.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-dbusrecv.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-ev/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-io-ev.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-uv/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-io-uv.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-xerces/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-xerces.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-xml/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-xmltool.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-yajl/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-yajl.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-yamlcpp/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-yamlcpp.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-zmq/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-zeromqsend.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-zeromqrecv.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-python3/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-python.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-lua/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libelektra-lua.so $(1)/usr/lib/
+endef
+
+define Package/libelektra-extra/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(foreach plugin,$(CONTENT_ELEKTRA_EXTRA),$(PKG_INSTALL_DIR)/usr/lib/libelektra-$(plugin).so) $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/elektra/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/elektra/* $(1)/usr/include/elektra/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libelektra-core))
+$(eval $(call BuildPackage,elektra-kdb))
+$(eval $(call BuildPackage,libelektra-resolvers))
+$(eval $(call BuildPackage,libelektra-plugins))
+$(eval $(call BuildPackage,libelektra-cpp))
+$(eval $(call BuildPackage,libelektra-curlget))
+$(eval $(call BuildPackage,libelektra-crypto))
+$(eval $(call BuildPackage,libelektra-dbus))
+$(eval $(call BuildPackage,libelektra-ev))
+$(eval $(call BuildPackage,libelektra-uv))
+$(eval $(call BuildPackage,libelektra-xerces))
+$(eval $(call BuildPackage,libelektra-xml))
+$(eval $(call BuildPackage,libelektra-yajl))
+$(eval $(call BuildPackage,libelektra-yamlcpp))
+$(eval $(call BuildPackage,libelektra-python3))
+$(eval $(call BuildPackage,libelektra-lua))
+$(eval $(call BuildPackage,libelektra-zmq))
+$(eval $(call BuildPackage,libelektra-extra))
diff --git a/external/subpack/libs/elektra/files/elektra.profile b/external/subpack/libs/elektra/files/elektra.profile
new file mode 100644
index 0000000..3df9be8
--- /dev/null
+++ b/external/subpack/libs/elektra/files/elektra.profile
@@ -0,0 +1 @@
+export XDG_CACHE_HOME=/tmp/
diff --git a/external/subpack/libs/elektra/patches/010-gcc13.patch b/external/subpack/libs/elektra/patches/010-gcc13.patch
new file mode 100644
index 0000000..12fbc12
--- /dev/null
+++ b/external/subpack/libs/elektra/patches/010-gcc13.patch
@@ -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>
+ 
+ #if __GNUC__ >= 12
diff --git a/external/subpack/libs/ell/Makefile b/external/subpack/libs/ell/Makefile
new file mode 100644
index 0000000..ff1ab35
--- /dev/null
+++ b/external/subpack/libs/ell/Makefile
@@ -0,0 +1,49 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ell
+PKG_VERSION:=0.69
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://git.kernel.org/pub/scm/libs/ell/ell.git
+PKG_SOURCE_VERSION:=7bed251f8020ef896043f008276f41cd13fdd43f
+PKG_MIRROR_HASH:=b462215391bf6f952b14743b4c54ac3538d4394c785f71c1bcb1623e2cb1cbc9
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=GPL-2.0-only
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+
+PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ell
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=Embedded Linux Library
+	URL:=https://patchwork.kernel.org/project/ell/
+endef
+
+define Package/ell/description
+	ELL (Embedded Linux Library) provides core, low-level functionality for system daemons.
+	It integrates with standard libc functionality and replaces some parts of it with more optimal implementations.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/ell $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libell.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/ell.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/ell/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libell.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,ell))
diff --git a/external/subpack/libs/expat/Makefile b/external/subpack/libs/expat/Makefile
new file mode 100644
index 0000000..2e80c62
--- /dev/null
+++ b/external/subpack/libs/expat/Makefile
@@ -0,0 +1,51 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=expat
+PKG_VERSION:=2.6.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/libexpat/libexpat/releases/download/R_$(subst .,_,$(PKG_VERSION))
+PKG_HASH:=17aa6cfc5c4c219c09287abfc10bc13f0c06f30bb654b28bfe6f567ca646eb79
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libexpat_project:libexpat
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libexpat
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=An XML parsing library
+  URL:=https://libexpat.github.io/
+endef
+
+define Package/libexpat/description
+ A fast, non-validating, stream-oriented XML parsing library.
+endef
+
+CMAKE_OPTIONS += \
+	-DEXPAT_BUILD_TOOLS=OFF \
+	-DEXPAT_BUILD_EXAMPLES=OFF \
+	-DEXPAT_BUILD_TESTS=OFF \
+	-DEXPAT_BUILD_DOCS=OFF \
+	-DEXPAT_DTD=OFF \
+	-DEXPAT_NS=OFF \
+	-DEXPAT_DEV_URANDOM=OFF
+
+define Package/libexpat/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libexpat.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libexpat))
diff --git a/external/subpack/libs/faad2/Makefile b/external/subpack/libs/faad2/Makefile
new file mode 100644
index 0000000..1dfc029
--- /dev/null
+++ b/external/subpack/libs/faad2/Makefile
@@ -0,0 +1,89 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=faad2
+PKG_VERSION:=2.11.1
+PKG_RELEASE:=2
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_SOURCE_URL:=https://github.com/knik0/faad2
+PKG_MIRROR_HASH:=8dfc89b418293a91c0fc0d11013205449669ce973f5e951500c1e11e3ac61970
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:audiocoding:freeware_advanced_audio_decoder_2
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/faad2/Default
+  URL:=http://www.audiocoding.com/faad2.html
+  TITLE:=Freeware Advanced Audio Decoder
+endef
+
+define Package/faad2/Default/description
+	FAAD2 is the fastest ISO AAC audio decoder available.
+	FAAD2 correctly decodes all MPEG-4 and MPEG-2 MAIN,
+	LOW, LTP, LD and ER object type AAC files.
+endef
+
+define Package/faad2
+$(call Package/faad2/Default)
+  SECTION:=sound
+  CATEGORY:=Sound
+  TITLE+=player
+  DEPENDS:=+libfaad2
+endef
+
+define Package/faad2/description
+$(call Package/faad2/Default/description)
+  This package contains a binary to play AAC or MP4 files.
+endef
+
+define Package/libfaad2
+$(call Package/faad2/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE+=library
+  MENU:=1
+endef
+
+define Package/libfaad2/description
+$(call Package/faad2/Default/description)
+  This package contains the library.
+endef
+
+TARGET_CFLAGS += \
+	$(if $(CONFIG_BUILD_PATENTED),,-DLC_ONLY_DECODER -DDISABLE_SBR) \
+	$(if $(CONFIG_SOFT_FLOAT),-DFIXED_POINT)
+
+CONFIGURE_ARGS += \
+	--without-drm \
+	--without-mpeg4ip \
+	--without-xmms
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfaad.so* $(1)/usr/lib/
+endef
+
+define Package/faad2/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/faad $(1)/usr/bin/
+endef
+
+define Package/libfaad2/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfaad.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,faad2))
+$(eval $(call BuildPackage,libfaad2))
diff --git a/external/subpack/libs/file/Makefile b/external/subpack/libs/file/Makefile
new file mode 100644
index 0000000..32da7fe
--- /dev/null
+++ b/external/subpack/libs/file/Makefile
@@ -0,0 +1,104 @@
+#
+# Copyright (C) 2007-2014 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:=file
+PKG_VERSION:=5.45
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://download.openpkg.org/components/cache/file/ \
+	ftp://ftp.astron.com/pub/file/
+PKG_HASH:=fc97f51029bb0e2c9f4e3bffefdaf678f0e039ee872b9de5c002a6d09c784d82
+
+PKG_MAINTAINER:=Marko Ratkaj <markoratkaj@gmail.com>
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/file/Default
+  TITLE:=File type determination
+  URL:=https://darwinsys.com/file/
+endef
+
+define Package/file
+$(call Package/file/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE+= utility
+  DEPENDS:=+libmagic
+endef
+
+define Package/libmagic
+$(call Package/file/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE+= library
+  DEPENDS:=+zlib +liblzma +libbz2
+endef
+
+TARGET_CFLAGS += $(FPIC)
+TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
+
+CONFIGURE_ARGS += \
+	--enable-static \
+	--enable-bzlib \
+	--enable-xzlib \
+	--enable-zlib \
+	--disable-libseccomp \
+	--disable-lzlib \
+	--disable-warnings \
+	--disable-zstdlib \
+	--without-pic
+
+MAKE_PATH := src
+
+define Build/Compile/magic
+	( cd $(PKG_BUILD_DIR)/magic/Magdir; \
+		for f in `ls`; do \
+			cat $$$${f}; \
+		done \
+	) > $(PKG_BUILD_DIR)/magic/magic
+endef
+Hooks/Compile/Post += Build/Compile/magic
+
+define Build/Install/magic
+	$(INSTALL_DIR) $(PKG_INSTALL_DIR)/usr/share/file
+	$(INSTALL_DATA) $(PKG_BUILD_DIR)/magic/magic $(PKG_INSTALL_DIR)/usr/share/file/
+endef
+Hooks/Install/Post += Build/Install/magic
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/magic.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libmagic.{a,so*} $(1)/usr/lib/
+	${INSTALL_DIR} $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) $(PKG_BUILD_DIR)/libmagic.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/file/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/file $(1)/usr/bin/
+endef
+
+define Package/libmagic/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmagic.so.* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/share/misc
+	$(SED) "/^#/d" $(PKG_INSTALL_DIR)/usr/share/file/magic
+	$(SED) "/^$$$$/d" $(PKG_INSTALL_DIR)/usr/share/file/magic
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/file/magic $(1)/usr/share/misc/
+endef
+
+$(eval $(call BuildPackage,file))
+$(eval $(call BuildPackage,libmagic))
diff --git a/external/subpack/libs/flac/Makefile b/external/subpack/libs/flac/Makefile
new file mode 100644
index 0000000..793d865
--- /dev/null
+++ b/external/subpack/libs/flac/Makefile
@@ -0,0 +1,66 @@
+#
+# Copyright (C) 2006-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:=flac
+PKG_VERSION:=1.4.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://downloads.xiph.org/releases/flac/
+PKG_HASH:=6c58e69cd22348f441b861092b825e591d0b822e106de6eb0ee4d05d27205b70
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=GFDL-1.2 GPL-2 LGPL-2.1 BSD-3-Clause
+PKG_LICENSE_FILES:=README COPYING.FDL COPYING.GPL COPYING.LGPL COPYING.Xiph
+PKG_CPE_ID:=cpe:/a:flac_project:flac
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libflac
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Free Lossless Audio Codec library
+  URL:=https://xiph.org/flac
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_SHARED_LIBS=ON \
+	-DBUILD_CXXLIBS=OFF \
+	-DBUILD_PROGRAMS=OFF \
+	-DBUILD_EXAMPLES=OFF \
+	-DBUILD_DOCS=OFF \
+	-DINSTALL_MANPAGES=OFF \
+	-DINSTALL_CMAKE_CONFIG_MODULE=OFF \
+	-DINSTALL_PKGCONFIG_MODULES=ON \
+	-DWITH_OGG=OFF \
+	-DWITH_STACK_PROTECTOR=OFF
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/FLAC \
+		$(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libFLAC.so* \
+		$(1)/usr/lib/
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* \
+		$(1)/usr/lib/pkgconfig/
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/flac.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/flac.pc
+endef
+
+define Package/libflac/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libFLAC.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libflac))
diff --git a/external/subpack/libs/freetype/Makefile b/external/subpack/libs/freetype/Makefile
new file mode 100644
index 0000000..90ad023
--- /dev/null
+++ b/external/subpack/libs/freetype/Makefile
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2006-2015 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:=freetype
+PKG_VERSION:=2.13.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@SF/freetype
+PKG_HASH:=0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289
+
+PKG_MAINTAINER:=Val Kulkov <val.kulkov@gmail.com>
+PKG_LICENSE:=FTL GPL-2.0-only MIT ZLIB GPL-3.0-or-later
+PKG_LICENSE_FILES:=docs/LICENSE.TXT docs/FTL.TXT docs/GPLv2.TXT src/bdf/README src/pcf/README src/gzip/zlib.h builds/unix/config.sub builds/unix/config.guess builds/unix/libtool 
+PKG_CPE_ID:=cpe:/a:freetype:freetype
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libfreetype
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A free, high-quality and portable font engine
+  URL:=https://www.freetype.org/
+  DEPENDS:=+zlib +libpng
+endef
+
+define Package/libfreetype/description
+ The FreeType project is a team of volunteers who develop free,
+ portable and high-quality software solutions for digital typography.
+ They specifically target embedded systems and focus on bringing small,
+ efficient and ubiquitous products.
+endef
+
+MESON_ARGS += \
+	-Dzlib=enabled \
+	-Dbzip2=disabled \
+	-Dpng=enabled \
+	-Dharfbuzz=disabled \
+	-Dbrotli=disabled \
+	-Dmmap=enabled
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/freetype2
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/freetype2/* $(1)/usr/include/freetype2/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfreetype.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/freetype2.pc $(1)/usr/lib/pkgconfig/freetype2.pc
+endef
+
+define Package/libfreetype/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfreetype.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libfreetype))
diff --git a/external/subpack/libs/gdbm/Makefile b/external/subpack/libs/gdbm/Makefile
new file mode 100644
index 0000000..7605b7b
--- /dev/null
+++ b/external/subpack/libs/gdbm/Makefile
@@ -0,0 +1,68 @@
+#
+# Copyright (C) 2006-2014 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:=gdbm
+PKG_VERSION:=1.23
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/gdbm
+PKG_HASH:=74b1081d21fff13ae4bd7c16e5d6e504a4c26f7cde1dca0d963a484174bbcacd
+
+PKG_MAINTAINER:=Marcel Denia <naoir@gmx.net>
+PKG_LICENSE:=GPL-3.0-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libgdbm
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GNU database manager
+  URL:=https://www.gnu.org/software/gdbm/
+endef
+
+define Package/libgdbm/description
+  GNU database manager library
+  GNU dbm is a set of database routines that use extendible hashing and
+  works similar to the standard UNIX dbm routines.
+endef
+
+CONFIGURE_ARGS += \
+	--enable-libgdbm-compat \
+	--enable-shared \
+	--without-readline
+
+define Build/Compile
+	+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
+		BINOWN=`id -u` \
+		BINGRP=`id -g` \
+		DESTDIR="$(PKG_INSTALL_DIR)" \
+		SUBDIRS=src \
+		all install
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/{gdbm,ndbm}.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgdbm.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgdbm_compat.so* $(1)/usr/lib/
+endef
+
+define Package/libgdbm/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgdbm.so.* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgdbm_compat.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libgdbm))
diff --git a/external/subpack/libs/getdns/Config.in b/external/subpack/libs/getdns/Config.in
new file mode 100644
index 0000000..10ee822
--- /dev/null
+++ b/external/subpack/libs/getdns/Config.in
@@ -0,0 +1,22 @@
+menu "Configuration"
+	depends on PACKAGE_getdns
+
+config GETDNS_BUILD_LIBEVENT2
+	bool "Use libevent2-based event loop"
+	default n
+	help
+		"Use libevent2 for the event loop (requires libevent2 dependency)."
+
+config GETDNS_ENABLE_STUB_ONLY
+	bool "Stub resolution mode only"
+	default y
+	help
+		getdns can be configured for stub resolution mode only (removes libunbound dependency).
+	
+config GETDNS_ENABLE_IDN_LIBIDN2
+	bool "IDN support"
+	default n
+	help
+		getdns can be configured with some IDN Support (requires libidn2 dependency).
+
+endmenu
diff --git a/external/subpack/libs/getdns/Makefile b/external/subpack/libs/getdns/Makefile
new file mode 100644
index 0000000..f982549
--- /dev/null
+++ b/external/subpack/libs/getdns/Makefile
@@ -0,0 +1,79 @@
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=getdns
+PKG_VERSION:=1.7.3
+PKG_RELEASE:=2
+
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+PKG_MAINTAINER:=
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://getdnsapi.net/dist/
+PKG_HASH:=f1404ca250f02e37a118aa00cf0ec2cbe11896e060c6d369c6761baea7d55a2c
+
+CMAKE_INSTALL:=1
+
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_GETDNS_BUILD_LIBEVENT2 \
+	CONFIG_GETDNS_ENABLE_STUB_ONLY \
+	CONFIG_GETDNS_ENABLE_IDN_LIBIDN2
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/getdns/Default
+	TITLE:=getdns
+	URL:=https://getdnsapi.net/
+endef
+
+define Package/getdns
+	$(call Package/getdns/Default)
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE+= (library)
+	DEPENDS+= +libopenssl +GETDNS_BUILD_LIBEVENT2:libevent2 +!GETDNS_ENABLE_STUB_ONLY:libunbound +GETDNS_ENABLE_IDN_LIBIDN2:libidn2
+	MENU:=1
+endef
+
+define Package/getdns/description
+	This package contains the getdns library (libgetdns).
+	This package also contains the "getdns_query" command line wrapper for getdns exposing the features of this implementation (both in the official API and the additional API functions).
+endef
+
+define Package/getdns/config
+	source "$(SOURCE)/Config.in"
+endef
+
+# CMAKE options for GetDNS are described in this document:
+# https://getdnsapi.net/quick-start/cmake-quick-start/
+CMAKE_OPTIONS += -DBUILD_LIBEV=OFF
+CMAKE_OPTIONS += -DBUILD_LIBUV=OFF
+
+CMAKE_OPTIONS += -DBUILD_LIBEVENT2=$(if $(CONFIG_GETDNS_BUILD_LIBEVENT2),ON,OFF)
+CMAKE_OPTIONS += -DENABLE_STUB_ONLY=$(if $(CONFIG_GETDNS_ENABLE_STUB_ONLY),ON,OFF)
+CMAKE_OPTIONS += -DUSE_LIBIDN2=$(if $(CONFIG_GETDNS_ENABLE_IDN_LIBIDN2),ON,OFF)
+
+# getdns will use libbsd for the functions inet_pton, inet_ntop, strlcpy if
+# present, otherwise it will use builtin code for these functions. In order to
+# force the use of the built in code and remove the libbsd dependency disable
+# the test for libbsd.
+CMAKE_OPTIONS += -DBSD_LIBRARY=OFF
+
+# Disable static linking to ensure that utility programs such as getdns_query
+# don't end up as large statically linked binaries.
+CMAKE_OPTIONS += -DENABLE_STATIC=OFF
+CMAKE_OPTIONS += -DENABLE_SHARED=ON  # This is the default
+
+define Package/getdns/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgetdns.so.* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/getdns_query $(1)/usr/sbin/getdns_query
+endef
+
+$(eval $(call BuildPackage,getdns))
diff --git a/external/subpack/libs/getdns/patches/001-openssl-deprecated.patch b/external/subpack/libs/getdns/patches/001-openssl-deprecated.patch
new file mode 100644
index 0000000..ed695ac
--- /dev/null
+++ b/external/subpack/libs/getdns/patches/001-openssl-deprecated.patch
@@ -0,0 +1,20 @@
+--- a/src/openssl/tls.c
++++ b/src/openssl/tls.c
+@@ -872,7 +872,7 @@ _getdns_tls_x509* _getdns_tls_connection
+ 	if (!conn || !conn->ssl)
+ 		return NULL;
+ 
+-	return _getdns_tls_x509_new(mfs, SSL_get_peer_certificate(conn->ssl));
++	return _getdns_tls_x509_new(mfs, SSL_get1_peer_certificate(conn->ssl));
+ }
+ 
+ getdns_return_t _getdns_tls_connection_is_session_reused(_getdns_tls_connection* conn)
+@@ -990,7 +990,7 @@ getdns_return_t _getdns_tls_connection_c
+ #if defined(USE_DANESSL)
+ 	{
+ 		getdns_return_t res = GETDNS_RETURN_GOOD;
+-		X509* peer_cert = SSL_get_peer_certificate(conn->ssl);
++		X509* peer_cert = SSL_get1_peer_certificate(conn->ssl);
+ 		if (peer_cert) {
+ 			if (conn->auth_name[0] &&
+ 			    X509_check_host(peer_cert,
diff --git a/external/subpack/libs/giflib/Makefile b/external/subpack/libs/giflib/Makefile
new file mode 100644
index 0000000..92e0ceb
--- /dev/null
+++ b/external/subpack/libs/giflib/Makefile
@@ -0,0 +1,85 @@
+#
+# Copyright (C) 2006-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:=giflib
+PKG_VERSION:=5.2.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/giflib
+PKG_HASH:=be7ffbd057cadebe2aa144542fd90c6838c6a083b5e8a9048b8ee3b66b29d5fb
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:giflib_project:giflib
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=gc-sections
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/giflib
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GIF libraries
+  URL:=https://sourceforge.net/projects/giflib
+endef
+
+define Package/giflib/description
+  giflib is a library for reading and writing gif images.
+  It is API and ABI compatible with libungif which was in wide use while
+  the LZW compression algorithm was patented.
+endef
+
+define Package/giflib-utils
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=GIF utilities
+  URL:=https://sourceforge.net/projects/giflib
+endef
+
+define Package/giflib-utils/description
+  These are the utilities that come with giflib.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+TARGET_LDFLAGS += -Wl,--as-needed
+
+MAKE_FLAGS += \
+	CFLAGS="$(TARGET_CFLAGS)" \
+	LDFLAGS="$(TARGET_LDFLAGS)" \
+	PREFIX=$(CONFIGURE_PREFIX)
+
+## Avoid 'convert' invocation during the build
+define Build/Prepare
+	$(call Build/Prepare/Default)
+	touch $(PKG_BUILD_DIR)/doc/giflib-logo.gif
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/{lib,include}
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgif.so* $(1)/usr/lib
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libgif.a $(1)/usr/lib
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include
+endef
+
+define Package/giflib/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgif.so* $(1)/usr/lib
+endef
+
+define Package/giflib-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin
+endef
+
+$(eval $(call BuildPackage,giflib))
+$(eval $(call BuildPackage,giflib-utils))
diff --git a/external/subpack/libs/glib2/Makefile b/external/subpack/libs/glib2/Makefile
new file mode 100644
index 0000000..fd30be2
--- /dev/null
+++ b/external/subpack/libs/glib2/Makefile
@@ -0,0 +1,130 @@
+#
+# Copyright (C) 2007-2019 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:=glib2
+PKG_VERSION:=2.82.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=glib-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@GNOME/glib/$(basename $(PKG_VERSION))
+PKG_HASH:=f4c82ada51366bddace49d7ba54b33b4e4d6067afa3008e4847f41cb9b5c38d3
+
+PKG_MAINTAINER:=Peter Wagner <tripolar@gmx.at>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:gnome:glib
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/glib-$(PKG_VERSION)
+PKG_CONFIG_DEPENDS:=CONFIG_BUILD_NLS
+PKG_FORTIFY_SOURCE:=0
+PKG_BUILD_FLAGS:=gc-sections
+
+HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/glib-$(PKG_VERSION)
+HOST_BUILD_DEPENDS:=pcre2/host libffi/host libiconv-full/host
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/glib2
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=$(ICONV_DEPENDS) $(INTL_DEPENDS) +zlib +libpthread +libffi +libattr +libpcre2
+  TITLE:=glib 2.0
+  URL:=http://www.gtk.org/
+endef
+
+define Package/glib2/description
+  The GLib library of C routines
+endef
+
+COMP_ARGS:=
+
+# default feature=auto see meson_options.txt
+COMP_ARGS+=-Dglib_debug=disabled
+
+# default feature=auto see meson_options.txt
+COMP_ARGS+=-Dlibmount=disabled
+
+# default feature=auto see meson_options.txt
+COMP_ARGS+=-Dselinux=disabled
+
+# default boolean=true see meson_options.txt
+COMP_ARGS+=-Dglib_assert=false
+
+# default boolean=true see meson_options.txt
+COMP_ARGS+=-Dtests=false
+
+# default feature=auto see meson_options.txt
+COMP_ARGS+=-Dintrospection=disabled
+
+# set runtime dir to /var/run
+COMP_ARGS+=-Druntime_dir=/var/run
+
+MESON_HOST_ARGS += $(COMP_ARGS) -Dxattr=false -Dnls=disabled
+MESON_ARGS += $(COMP_ARGS) -Dxattr=true -Db_lto=true -Dnls=$(if $(CONFIG_BUILD_NLS),en,dis)abled
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/bin/* \
+		$(1)/usr/bin/
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/glib-2.0 \
+		$(1)/usr/include/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/glib-2.0/include/*.h \
+		$(1)/usr/include/glib-2.0/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/gio-unix-2.0 \
+		$(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/glib-2.0 \
+		$(1)/usr/lib/
+
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/*.{so*,a} \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc \
+		$(1)/usr/lib/pkgconfig
+	$(foreach BIN,glib_genmarshal glib_mkenums,
+		$(SED) 's/^$(BIN)=$$$${bindir}\/\(.*\)/$(BIN)=$$$${prefix_hostpkg}\/bin\/\1/' $(1)/usr/lib/pkgconfig/glib-2.0.pc
+	)
+	$(foreach BIN,glib_compile_resources gdbus_codegen,
+		$(SED) 's/^$(BIN)=$$$${bindir}\/\(.*\)/$(BIN)=$$$${prefix_hostpkg}\/bin\/\1/' $(1)/usr/lib/pkgconfig/gio-2.0.pc
+	)
+
+	$(INSTALL_DIR) $(2)/share/aclocal/
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/share/aclocal/*.m4  \
+		$(2)/share/aclocal/
+
+	$(INSTALL_DIR) $(1)/usr/share/glib-2.0
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/share/glib-2.0/codegen \
+		$(1)/usr/share/glib-2.0/
+endef
+
+define Package/glib2/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,glib2))
diff --git a/external/subpack/libs/glib2/patches/003-valgrind.h-mips16-fix.patch b/external/subpack/libs/glib2/patches/003-valgrind.h-mips16-fix.patch
new file mode 100644
index 0000000..ca35972
--- /dev/null
+++ b/external/subpack/libs/glib2/patches/003-valgrind.h-mips16-fix.patch
@@ -0,0 +1,11 @@
+--- a/glib/valgrind.h
++++ b/glib/valgrind.h
+@@ -159,7 +159,7 @@
+ #  define PLAT_s390x_linux 1
+ #elif defined(__linux__) && defined(__mips__) && (__mips==64)
+ #  define PLAT_mips64_linux 1
+-#elif defined(__linux__) && defined(__mips__) && (__mips!=64)
++#elif defined(__linux__) && defined(__mips__) && (__mips!=64) && !defined(__mips16)
+ #  define PLAT_mips32_linux 1
+ #elif defined(__sun) && defined(__i386__)
+ #  define PLAT_x86_solaris 1
diff --git a/external/subpack/libs/glib2/patches/006-c99.patch b/external/subpack/libs/glib2/patches/006-c99.patch
new file mode 100644
index 0000000..98c17db
--- /dev/null
+++ b/external/subpack/libs/glib2/patches/006-c99.patch
@@ -0,0 +1,11 @@
+--- a/meson.build
++++ b/meson.build
+@@ -1189,7 +1189,7 @@ if host_system == 'windows' and (cc.get_
+   glib_conf.set('HAVE_C99_SNPRINTF', false)
+   glib_conf.set('HAVE_C99_VSNPRINTF', false)
+   glib_conf.set('HAVE_UNIX98_PRINTF', false)
+-elif not cc_can_run and host_system in ['ios', 'darwin']
++elif true
+   # All these are true when compiling natively on macOS, so we should use good
+   # defaults when building for iOS and tvOS.
+   glib_conf.set('HAVE_C99_SNPRINTF', true)
diff --git a/external/subpack/libs/gnu-efi/Makefile b/external/subpack/libs/gnu-efi/Makefile
new file mode 100644
index 0000000..a197b2d
--- /dev/null
+++ b/external/subpack/libs/gnu-efi/Makefile
@@ -0,0 +1,76 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=gnu-efi
+PKG_VERSION:=3.0.17
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/vathpela/gnu-efi.git
+PKG_SOURCE_DATE:=2023-06-11
+PKG_SOURCE_VERSION:=64027ee9864d8a8685ae187eb91ddc519d18cedb
+PKG_MIRROR_HASH:=db730ab78f501b2f324edc9a91307eab1f1c5027f9c8fe63bd72364eddaf4553
+PKG_BUILD_PARALLEL:=1
+
+PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
+PKG_LICENSE_FILES:=README.efilib
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/gnu-efi
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GNU's EFI library
+  URL:=https://github.com/vathpela/gnu-efi
+  HIDDEN:=1
+  DEPENDS:=@TARGET_x86_64
+endef
+
+define Package/gnu-efi-programs
+  SECTION:=boot
+  CATEGORY:=Boot Loaders
+  TITLE:=Various EFI programs
+  URL:=https://github.com/vathpela/gnu-efi
+  DEPENDS:=@TARGET_x86_64 +gnu-efi
+endef
+
+define Package/gnu-efi/description
+  GNU's EFI library
+endef
+
+define Package/gnu-efi-programs/description
+  Various EFI programs from GNU's EFI library
+endef
+
+TARGET_CFLAGS += -Wno-error=incompatible-pointer-types
+
+define Build/Install
+	$(MAKE_VARS) \
+	$(MAKE) -C $(PKG_BUILD_DIR)/$(MAKE_PATH) \
+		$(MAKE_INSTALL_FLAGS) \
+		INSTALLROOT=$(PKG_INSTALL_DIR) \
+		install
+endef
+
+define Package/gnu-efi/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/local/lib/{crt0-efi-*.o,elf_*.lds,libefi.a,libgnuefi.a} $(1)/usr/lib/
+endef
+
+define gnu-efi-programs/install
+	$(INSTALL_DIR) $(1)/usr/share/gnuefi/apps
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/local/lib/gnuefi/apps/*.efi $(1)/usr/share/gnuefi/apps/
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib $(1)/usr/include/efi
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/local/lib/{crt0-efi-*.o,elf_*.lds,libefi.a,libgnuefi.a} $(1)/usr/lib/
+	cp -aR $(PKG_INSTALL_DIR)/usr/local/include/efi/** $(1)/usr/include/efi/
+endef
+
+$(eval $(call BuildPackage,gnu-efi))
+$(eval $(call BuildPackage,gnu-efi-programs))
diff --git a/external/subpack/libs/gnutls/Config.in b/external/subpack/libs/gnutls/Config.in
new file mode 100644
index 0000000..88dbc7a
--- /dev/null
+++ b/external/subpack/libs/gnutls/Config.in
@@ -0,0 +1,52 @@
+# gnutls avanced configuration
+
+menu "Configuration"
+	depends on PACKAGE_libgnutls
+
+config GNUTLS_DTLS_SRTP
+	bool "enable DTLS SRTP support"
+	default y
+
+config GNUTLS_ALPN
+	bool "enable ALPN support"
+	default y
+
+config GNUTLS_OCSP
+	bool "enable ocsp support"
+	default y
+
+config GNUTLS_CRYPTODEV
+	bool "enable /dev/crypto support"
+	default n
+
+config GNUTLS_HEARTBEAT
+	bool "enable DTLS heartbeat support"
+	default y
+
+config GNUTLS_SRP
+	bool "enable SRP authentication support"
+	default n
+
+config GNUTLS_PSK
+	bool "enable PSK authentication support"
+	default y
+
+config GNUTLS_ANON
+	bool "enable anonymous authentication support"
+	default y
+
+config GNUTLS_TPM
+	bool "enable tpm support"
+	select GNUTLS_PKCS11
+	default n
+
+config GNUTLS_PKCS11
+	bool "enable smart card (PKCS11) support"
+	select GNUTLS_EXT_LIBTASN1
+	default n
+
+config GNUTLS_EXT_LIBTASN1
+	bool "use external libtasn1"
+	default n
+
+endmenu
diff --git a/external/subpack/libs/gnutls/Makefile b/external/subpack/libs/gnutls/Makefile
new file mode 100644
index 0000000..b24cc14
--- /dev/null
+++ b/external/subpack/libs/gnutls/Makefile
@@ -0,0 +1,270 @@
+# SPDX-Identifier-License: GPL-2.0-only
+#
+# Copyright (C) 2005-2016 OpenWrt.org
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=gnutls
+PKG_VERSION:=3.8.5
+PKG_RELEASE:=1
+PKG_BUILD_FLAGS:=no-mips16
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://www.gnupg.org/ftp/gcrypt/gnutls/v3.8
+PKG_HASH:=66269a2cfe0e1c2dabec87bdbbd8ab656f396edd9a40dd006978e003cfa52bfc
+
+PKG_MAINTAINER:=Nikos Mavrogiannopoulos <nmav@gnutls.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:gnu:gnutls
+
+PKG_BUILD_DEPENDS:=gettext-full/host
+PKG_BUILD_PARALLEL:=1
+PKG_FIXUP:=autoreconf gettext-version
+PKG_INSTALL:=1
+PKG_LIBTOOL_PATHS:=. lib
+
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_GNUTLS_ALPN \
+	CONFIG_GNUTLS_ANON \
+	CONFIG_GNUTLS_CRYPTODEV \
+	CONFIG_GNUTLS_DTLS_SRTP \
+	CONFIG_GNUTLS_EXT_LIBTASN1 \
+	CONFIG_GNUTLS_HEARTBEAT \
+	CONFIG_GNUTLS_OCSP \
+	CONFIG_GNUTLS_PKCS11 \
+	CONFIG_GNUTLS_PSK \
+	CONFIG_GNUTLS_SRP \
+	CONFIG_GNUTLS_TPM \
+	CONFIG_LIBNETTLE_MINI \
+	CONFIG_PACKAGE_libgnutls-dane \
+
+include $(INCLUDE_DIR)/package.mk
+
+
+define Package/gnutls/Default
+  SUBMENU:=SSL
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GNU TLS
+  URL:=http://www.gnutls.org/
+endef
+
+define Package/gnutls/Default/description
+ GnuTLS is a secure communications library implementing the SSL, TLS
+ and DTLS protocols and technologies around them. It provides a simple
+ C language application programming interface (API) to access the secure
+ communications protocols as well as APIs to parse and write X.509, PKCS12,
+ OpenPGP and other required structures. It is aimed to be portable and
+ efficient with focus on security and interoperability.
+endef
+
+
+define Package/certtool
+$(call Package/gnutls/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Encryption
+  TITLE+= (certool utility)
+  DEPENDS+= +libgnutls
+endef
+
+define Package/certtool/description
+$(call Package/gnutls/Default/description)
+ This package contains the GnuTLS certtool utility.
+endef
+
+
+define Package/gnutls-utils
+$(call Package/gnutls/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Encryption
+  TITLE+= (utilities)
+  DEPENDS+= +libgnutls +PACKAGE_libgnutls-dane:libgnutls-dane
+endef
+
+define Package/gnutls-utils/description
+$(call Package/gnutls/Default/description)
+ This package contains the GnuTLS gnutls-cli, gnutls-serv, psktool,
+ and srptool utilities.
+endef
+
+define Package/libgnutls/config
+	source "$(SOURCE)/Config.in"
+endef
+
+define Package/libgnutls
+$(call Package/gnutls/Default)
+  TITLE+= (library)
+  DEPENDS+= +libnettle +!LIBNETTLE_MINI:libgmp +GNUTLS_EXT_LIBTASN1:libtasn1 +GNUTLS_PKCS11:p11-kit +GNUTLS_CRYPTODEV:kmod-cryptodev +libatomic
+endef
+
+define Package/libgnutls-dane
+$(call Package/gnutls/Default)
+  TITLE+= (libgnutls-dane library)
+  DEPENDS:= +libgnutls +PACKAGE_libgnutls-dane:libunbound
+endef
+
+define Package/libgnutls/description
+$(call Package/gnutls/Default/description)
+ This package contains the GnuTLS shared library, needed by other programs.
+endef
+
+# We disable the configuration file (system-priority-file) because
+# the use of configuration increases the non-shared memory used by
+# the library and we don't provide an openwrt-specific configuration
+# anyway.
+CONFIGURE_ARGS+= \
+	--enable-shared \
+	--enable-static \
+	--disable-doc \
+	--disable-gcc-warnings \
+	--disable-guile \
+	--disable-rpath \
+	--disable-seccomp-tests \
+	--disable-tests \
+	--disable-valgrind-tests \
+	--disable-ssl2-support \
+	--disable-ssl3-support \
+	--enable-local-libopts \
+	--without-idn \
+	--with-default-trust-store-dir=/etc/ssl/certs/ \
+	--with-included-unistring \
+	--with-included-libunistring \
+	--with-librt-prefix="$(LIBRT_ROOT_DIR)/" \
+	--with-pic \
+	--with-system-priority-file="" \
+	--without-brotli \
+	--without-zlib \
+	--without-zstd
+
+ifneq ($(CONFIG_GNUTLS_EXT_LIBTASN1),y)
+CONFIGURE_ARGS += --with-included-libtasn1
+endif
+
+ifneq ($(CONFIG_GNUTLS_PKCS11),y)
+CONFIGURE_ARGS += --without-p11-kit
+endif
+
+ifeq ($(CONFIG_LIBNETTLE_MINI),y)
+CONFIGURE_ARGS += --with-nettle-mini
+endif
+
+ifneq ($(CONFIG_GNUTLS_DTLS_SRTP),y)
+CONFIGURE_ARGS += --disable-dtls-srtp-support
+endif
+
+ifneq ($(CONFIG_GNUTLS_ALPN),y)
+CONFIGURE_ARGS += --disable-alpn-support
+endif
+
+ifneq ($(CONFIG_GNUTLS_HEARTBEAT),y)
+CONFIGURE_ARGS += --disable-heartbeat-support
+endif
+
+ifneq ($(CONFIG_GNUTLS_SRP),y)
+CONFIGURE_ARGS += --disable-srp-authentication
+endif
+
+ifneq ($(CONFIG_GNUTLS_PSK),y)
+CONFIGURE_ARGS += --disable-psk-authentication
+endif
+
+ifneq ($(CONFIG_GNUTLS_ANON),y)
+CONFIGURE_ARGS += --disable-anon-authentication
+endif
+
+ifneq ($(CONFIG_GNUTLS_OCSP),y)
+CONFIGURE_ARGS += --disable-ocsp
+endif
+
+ifneq ($(CONFIG_GNUTLS_TPM),y)
+CONFIGURE_ARGS += --without-tpm
+endif
+
+ifeq ($(CONFIG_GNUTLS_CRYPTODEV),y)
+CONFIGURE_ARGS += --enable-cryptodev
+endif
+
+ifeq ($(CONFIG_PACKAGE_libgnutls-dane),)
+CONFIGURE_ARGS += --disable-libdane
+endif
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/gnutls \
+		$(1)/usr/include/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+
+define Package/certtool/conffiles
+/etc/gnutls/certtool.cfg
+endef
+
+define Package/certtool/install
+	$(INSTALL_DIR) $(1)/etc/gnutls
+	$(INSTALL_CONF) $(PKG_BUILD_DIR)/doc/certtool.cfg $(1)/etc/gnutls/
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/certtool $(1)/usr/bin/
+endef
+
+
+define Package/gnutls-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+ifeq ($(CONFIG_GNUTLS_OCSP),y)
+ifeq ($(CONFIG_GNUTLS_ANON),y)
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/bin/gnutls-{cli,serv} \
+		$(1)/usr/bin/
+endif
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/bin/ocsptool \
+		$(1)/usr/bin/
+endif
+ifeq ($(CONFIG_GNUTLS_SRP),y)
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/bin/srptool \
+		$(1)/usr/bin/
+endif
+ifeq ($(CONFIG_GNUTLS_PSK),y)
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/bin/psktool \
+		$(1)/usr/bin/
+endif
+ifeq ($(CONFIG_GNUTLS_PKCS11),y)
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/bin/p11tool \
+		$(1)/usr/bin/
+endif
+ifeq ($(CONFIG_GNUTLS_TPM),y)
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/bin/tpmtool \
+		$(1)/usr/bin/
+endif
+endef
+
+
+define Package/libgnutls/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgnutls.so.* $(1)/usr/lib/
+endef
+
+define Package/libgnutls-dane/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgnutls-dane.so.* $(1)/usr/lib/
+endef
+
+
+$(eval $(call BuildPackage,certtool))
+$(eval $(call BuildPackage,gnutls-utils))
+$(eval $(call BuildPackage,libgnutls))
+$(eval $(call BuildPackage,libgnutls-dane))
diff --git a/external/subpack/libs/gnutls/patches/010-m4.patch b/external/subpack/libs/gnutls/patches/010-m4.patch
new file mode 100644
index 0000000..447580f
--- /dev/null
+++ b/external/subpack/libs/gnutls/patches/010-m4.patch
@@ -0,0 +1,73 @@
+--- a/m4/stdint.m4
++++ b/m4/stdint.m4
+@@ -15,7 +15,7 @@ AC_DEFUN_ONCE([gl_STDINT_H],
+   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ 
+   AC_REQUIRE([gl_LIMITS_H])
+-  AC_REQUIRE([gt_TYPE_WINT_T])
++  AC_REQUIRE([gt_TYPE_WINT_T_GNUTLS])
+ 
+   dnl For backward compatibility. Some packages may still be testing these
+   dnl macros.
+--- a/m4/vasnprintf.m4
++++ b/m4/vasnprintf.m4
+@@ -33,7 +33,7 @@ AC_DEFUN([gl_REPLACE_VASNPRINTF],
+ AC_DEFUN([gl_PREREQ_PRINTF_ARGS],
+ [
+   AC_REQUIRE([gt_TYPE_WCHAR_T])
+-  AC_REQUIRE([gt_TYPE_WINT_T])
++  AC_REQUIRE([gt_TYPE_WINT_T_GNUTLS])
+ ])
+ 
+ # Prerequisites of lib/printf-parse.h, lib/printf-parse.c.
+@@ -41,7 +41,7 @@ AC_DEFUN([gl_PREREQ_PRINTF_PARSE],
+ [
+   AC_REQUIRE([gl_FEATURES_H])
+   AC_REQUIRE([gt_TYPE_WCHAR_T])
+-  AC_REQUIRE([gt_TYPE_WINT_T])
++  AC_REQUIRE([gt_TYPE_WINT_T_GNUTLS])
+   AC_REQUIRE([AC_TYPE_SIZE_T])
+   AC_CHECK_TYPE([ptrdiff_t], ,
+     [AC_DEFINE([ptrdiff_t], [long],
+@@ -55,7 +55,7 @@ AC_DEFUN_ONCE([gl_PREREQ_VASNPRINTF],
+ [
+   AC_REQUIRE([AC_FUNC_ALLOCA])
+   AC_REQUIRE([gt_TYPE_WCHAR_T])
+-  AC_REQUIRE([gt_TYPE_WINT_T])
++  AC_REQUIRE([gt_TYPE_WINT_T_GNUTLS])
+   AC_CHECK_FUNCS([snprintf strnlen wcslen wcsnlen mbrtowc wcrtomb])
+   dnl Use the _snprintf function only if it is declared (because on NetBSD it
+   dnl is defined as a weak alias of snprintf; we prefer to use the latter).
+--- a/m4/wchar_t.m4
++++ b/m4/wchar_t.m4
+@@ -8,7 +8,7 @@ dnl From Bruno Haible.
+ dnl Test whether <stddef.h> has the 'wchar_t' type.
+ dnl Prerequisite: AC_PROG_CC
+ 
+-AC_DEFUN([gt_TYPE_WCHAR_T],
++AC_DEFUN([gt_TYPE_WCHAR_T_GNUTLS],
+ [
+   AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t],
+     [AC_COMPILE_IFELSE(
+--- a/m4/wint_t.m4
++++ b/m4/wint_t.m4
+@@ -9,7 +9,7 @@ dnl Test whether <wchar.h> has the 'wint
+ dnl <wchar.h> or <wctype.h> would, if present, override 'wint_t'.
+ dnl Prerequisite: AC_PROG_CC
+ 
+-AC_DEFUN([gt_TYPE_WINT_T],
++AC_DEFUN([gt_TYPE_WINT_T_GNUTLS],
+ [
+   AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t],
+     [AC_COMPILE_IFELSE(
+--- a/src/gl/m4/gnulib-comp.m4
++++ b/src/gl/m4/gnulib-comp.m4
+@@ -1268,7 +1268,7 @@ changequote([, ])dnl
+   gl_UNISTD_MODULE_INDICATOR([sleep])
+   AC_CHECK_DECLS_ONCE([alarm])
+   AC_REQUIRE([gt_TYPE_WCHAR_T])
+-  AC_REQUIRE([gt_TYPE_WINT_T])
++  AC_REQUIRE([gt_TYPE_WINT_T_GNUTLS])
+   gl_FUNC_STRERROR_R
+   AS_IF([test $HAVE_DECL_STRERROR_R = 0 || test $REPLACE_STRERROR_R = 1], [
+     AC_LIBOBJ([strerror_r])
diff --git a/external/subpack/libs/gnutls/patches/020-dont-install-m4-files.patch b/external/subpack/libs/gnutls/patches/020-dont-install-m4-files.patch
new file mode 100644
index 0000000..6caeabc
--- /dev/null
+++ b/external/subpack/libs/gnutls/patches/020-dont-install-m4-files.patch
@@ -0,0 +1,25 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Eneas U de Queiroz <cote2004-github@yahoo.com>
+Date: Mon, 25 Oct 2021 08:49:21 -0300
+Subject: Do not install m4 files
+
+Do not use --install when calling aclocal.  That flag instructs aclocal to
+copy third-party files to the first -I directory.  The intention here is to
+copy files to the package build dir (m4).  However, our toolchain prepends
+the build-system's m4 dir to the list, causing the --install flag to
+install an older version to the buildsystem m4 dir, causing failures in
+other packages.
+
+Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
+
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -48,7 +48,7 @@ if ENABLE_DOC
+ SUBDIRS += doc
+ endif
+ 
+-ACLOCAL_AMFLAGS = -I m4 -I src/gl/m4 -I lib/unistring/m4 --install
++ACLOCAL_AMFLAGS = -I m4 -I src/gl/m4 -I lib/unistring/m4
+ 
+ EXTRA_DIST = cfg.mk maint.mk CONTRIBUTING.md README.md LICENSE AUTHORS NEWS \
+ 	ChangeLog THANKS INSTALL.md RELEASES.md .mailmap
diff --git a/external/subpack/libs/gnutls/patches/030-unistring-optional.patch b/external/subpack/libs/gnutls/patches/030-unistring-optional.patch
new file mode 100644
index 0000000..4e9de33
--- /dev/null
+++ b/external/subpack/libs/gnutls/patches/030-unistring-optional.patch
@@ -0,0 +1,11 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -508,6 +508,8 @@ DEFAULT_VALGRINDFLAGS='-q --error-exitco
+ 
+ gl_VALGRIND_TESTS_DEFAULT_NO
+ 
++gl_LIBUNISTRING_OPTIONAL
++
+ dnl Note that g*l_INIT are run after we check for library capabilities,
+ dnl to prevent issues from caching lib dependencies. See discussion
+ dnl in https://bugs.gentoo.org/show_bug.cgi?id=494940 and
diff --git a/external/subpack/libs/google-authenticator-libpam/Makefile b/external/subpack/libs/google-authenticator-libpam/Makefile
new file mode 100644
index 0000000..70acb1e
--- /dev/null
+++ b/external/subpack/libs/google-authenticator-libpam/Makefile
@@ -0,0 +1,51 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=google-authenticator-libpam
+PKG_VERSION:=1.09
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/google/google-authenticator-libpam/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=ab1d7983413dc2f11de2efa903e5c326af8cb9ea37765dacb39949417f7cd037
+
+PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/google-authenticator-libpam
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libpam +libqrencode
+  TITLE:=Google Authenticator PAM module
+  URL:=https://github.com/google/google-authenticator-libpam
+endef
+
+define Package/google-authenticator-libpam/description
+    Google Authenticator PAM module
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib/security
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/security/* $(1)/usr/lib/security/
+endef
+
+define Package/google-authenticator-libpam/install
+	$(INSTALL_DIR) $(1)/usr/lib/security
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/security/*.so* \
+	    $(1)/usr/lib/security/
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,google-authenticator-libpam))
diff --git a/external/subpack/libs/gost_engine/Makefile b/external/subpack/libs/gost_engine/Makefile
new file mode 100644
index 0000000..e6a8066
--- /dev/null
+++ b/external/subpack/libs/gost_engine/Makefile
@@ -0,0 +1,79 @@
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/openssl-module.mk
+
+PKG_NAME:=gost_engine
+PKG_VERSION:=3.0.3
+PKG_RELEASE:=11
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=v$(PKG_VERSION)
+PKG_SOURCE_URL:=https://github.com/gost-engine/engine
+PKG_MIRROR_HASH:=ad88b0bc4ede265bc91757f0bb9777a381f8e271faa43992a054ddd5f435ad88
+
+PKG_MAINTAINER:=Artur Petrov <github@phpchain.ru>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/gost_engine/Default
+  $(call Package/openssl/engine/Default)
+  TITLE:=GOST engine for OpenSSL
+  URL:=http://www.openssl.org/
+endef
+
+define Package/gost_engine/Default/description
+Russian GOST crypto algorithms for OpenSSL.
+endef
+
+$(eval $(call Package/openssl/add-engine,gost,libopenssl-gost_engine))
+define Package/libopenssl-gost_engine
+    $(call Package/gost_engine/Default)
+    $(call Package/openssl/engine/Default)
+    TITLE+= (library)
+    URL:=https://github.com/gost-engine/engine/
+endef
+
+define Package/libopenssl-gost_engine/description
+$(call Package/gost_engine/Default/description)
+This package contains the GOST engine library.
+
+Support ciphers:
+GOST2012-GOST8912-GOST8912
+GOST2001-GOST89-GOST89
+endef
+
+define Package/gost_engine-util
+    $(call Package/gost_engine/Default)
+    SECTION:=utils
+    CATEGORY:=Utilities
+    DEPENDS:=+libopenssl-gost_engine
+    TITLE+= (utilities)
+endef
+
+define Package/gost_engine-util/description
+$(call Package/gost_engine/Default/description)
+This package contains the GOST engine command-line utilities gostsum and gost12sum.
+endef
+
+CMAKE_OPTIONS += -DOPENSSL_ENGINES_DIR=/usr/lib/$(ENGINES_DIR)
+
+define Package/libopenssl-gost_engine/install
+	$(INSTALL_DIR) $(1)/usr/lib $(1)/usr/lib/$(ENGINES_DIR) $(1)/etc/ssl/modules.cnf.d
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libgost.so \
+			$(1)/usr/lib/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/$(ENGINES_DIR)/gost.so \
+			$(1)/usr/lib/$(ENGINES_DIR)/
+	$(INSTALL_DATA) ./files/gost.cnf $(1)/etc/ssl/modules.cnf.d/
+endef
+
+define Package/gost_engine-util/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/{gost12sum,gostsum} \
+			$(1)/usr/bin/
+endef
+
+
+$(eval $(call BuildPackage,libopenssl-gost_engine))
+$(eval $(call BuildPackage,gost_engine-util))
diff --git a/external/subpack/libs/gost_engine/files/gost.cnf b/external/subpack/libs/gost_engine/files/gost.cnf
new file mode 100644
index 0000000..8980c52
--- /dev/null
+++ b/external/subpack/libs/gost_engine/files/gost.cnf
@@ -0,0 +1,16 @@
+[gost_sect]
+default_algorithms = ALL
+# CRYPT_PARAMS: OID of default GOST 28147-89 parameters It allows the
+# user to choose between different parameter sets of symmetric cipher
+# algorithm. RFC 4357 specifies several parameters for the
+# GOST 28147-89 algorithm, but OpenSSL doesn't provide user interface
+# to choose one when encrypting. So use engine configuration parameter
+# instead.
+# Value of this parameter can be either short name, defined in OpenSSL
+# obj_dat.h header file or numeric representation of OID, defined in
+# RFC 4357.  Defaults to id-tc26-gost-28147-param-Z
+#CRYPT_PARAMS = id-tc26-gost-28147-param-Z
+
+# PBE_PARAMS: Shortname of default digest alg for PBE
+#PBE_PARAMS =
+
diff --git a/external/subpack/libs/gost_engine/patches/020-cmake-allow-cross-compile.patch b/external/subpack/libs/gost_engine/patches/020-cmake-allow-cross-compile.patch
new file mode 100644
index 0000000..e1a0e3d
--- /dev/null
+++ b/external/subpack/libs/gost_engine/patches/020-cmake-allow-cross-compile.patch
@@ -0,0 +1,59 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -64,31 +64,35 @@ else()
+  add_definitions(-DL_ENDIAN)
+ endif()
+ 
+-check_c_source_runs("
+-  #ifdef _MSC_VER
+-  # include <intrin.h>
+-  #else
+-  # include <x86intrin.h>
+-  #endif
+-  int main(void) {
+-    unsigned long long x = -1, y = 1, r;
+-    unsigned char cf;
+-    cf = _addcarry_u64(1, x, y, &r);
+-    return !(cf == 1 && r == 1);
+-  }
+-  " ADDCARRY_U64)
++if(NOT CMAKE_CROSSCOMPILING)
++  check_c_source_runs("
++    #ifdef _MSC_VER
++    # include <intrin.h>
++    #else
++    # include <x86intrin.h>
++    #endif
++    int main(void) {
++      unsigned long long x = -1, y = 1, r;
++      unsigned char cf;
++      cf = _addcarry_u64(1, x, y, &r);
++      return !(cf == 1 && r == 1);
++    }
++    " ADDCARRY_U64)
++
++  check_c_source_runs("
++    int main(void) {
++      char buf[16] = { 0, 1, 2 };
++      int *p = (int *)(buf + 1);
++      int *q = (int *)(buf + 2);
++      return (*p == *q);
++    }
++    " RELAXED_ALIGNMENT)
++endif()
++
+ if (ADDCARRY_U64)
+   add_definitions(-DHAVE_ADDCARRY_U64)
+ endif()
+ 
+-check_c_source_runs("
+-  int main(void) {
+-    char buf[16] = { 0, 1, 2 };
+-    int *p = (int *)(buf + 1);
+-    int *q = (int *)(buf + 2);
+-    return (*p == *q);
+-  }
+-  " RELAXED_ALIGNMENT)
+ if (NOT RELAXED_ALIGNMENT)
+   add_definitions(-DSTRICT_ALIGNMENT)
+ endif()
diff --git a/external/subpack/libs/gost_engine/patches/030-dont-build-provider.patch b/external/subpack/libs/gost_engine/patches/030-dont-build-provider.patch
new file mode 100644
index 0000000..59ff87e
--- /dev/null
+++ b/external/subpack/libs/gost_engine/patches/030-dont-build-provider.patch
@@ -0,0 +1,56 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -367,9 +367,11 @@ set_target_properties(lib_gost_engine PR
+   COMPILE_DEFINITIONS "BUILDING_ENGINE_AS_LIBRARY"
+   PUBLIC_HEADER gost-engine.h
+   OUTPUT_NAME "gost")
+-target_link_libraries(lib_gost_engine PRIVATE gost_core gost_err)
++#target_link_libraries(lib_gost_engine PRIVATE gost_core gost_err)
++target_link_libraries(lib_gost_engine PRIVATE gost_core)
+ endif()
+ 
++if (0)
+ # The GOST provider uses this
+ add_subdirectory(libprov)
+ 
+@@ -394,6 +396,7 @@ set_target_properties(lib_gost_prov PROP
+   )
+ target_link_libraries(lib_gost_prov PRIVATE gost_core libprov)
+ endif()
++endif()
+ 
+ set(GOST_SUM_SOURCE_FILES
+         gostsum.c
+@@ -434,15 +437,15 @@ install(FILES gostsum.1 gost12sum.1 DEST
+ install(TARGETS gost_engine EXPORT GostEngineConfig
+         LIBRARY  DESTINATION ${OPENSSL_ENGINES_DIR}
+         RUNTIME  DESTINATION ${OPENSSL_ENGINES_DIR})
+-install(TARGETS gost_prov EXPORT GostProviderConfig
+-        LIBRARY  DESTINATION ${OPENSSL_MODULES_DIR}
+-        RUNTIME  DESTINATION ${OPENSSL_MODULES_DIR})
++#install(TARGETS gost_prov EXPORT GostProviderConfig
++#        LIBRARY  DESTINATION ${OPENSSL_MODULES_DIR}
++#        RUNTIME  DESTINATION ${OPENSSL_MODULES_DIR})
+ if (NOT MSVC)
+ # install engine and provider in library form
+ install(TARGETS lib_gost_engine EXPORT GostEngineConfig
+         LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
+-install(TARGETS lib_gost_prov EXPORT GostProviderConfig
+-        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
++#install(TARGETS lib_gost_prov EXPORT GostProviderConfig
++#        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
+ endif()
+ 
+ if (MSVC)
+@@ -450,8 +453,8 @@ if (MSVC)
+     EXPORT GostEngineConfig DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL)
+   install(FILES $<TARGET_PDB_FILE:gost_engine>
+     EXPORT GostEngineConfig DESTINATION ${OPENSSL_ENGINES_DIR} OPTIONAL)
+-  install(FILES $<TARGET_PDB_FILE:gost_prov>
+-    EXPORT GostProviderConfig DESTINATION ${OPENSSL_MODULES_DIR} OPTIONAL)
++#  install(FILES $<TARGET_PDB_FILE:gost_prov>
++#    EXPORT GostProviderConfig DESTINATION ${OPENSSL_MODULES_DIR} OPTIONAL)
+ endif()
+ install(EXPORT GostEngineConfig DESTINATION share/cmake/GostEngine)
+-install(EXPORT GostProviderConfig DESTINATION share/cmake/GostProvider)
++#install(EXPORT GostProviderConfig DESTINATION share/cmake/GostProvider)
diff --git a/external/subpack/libs/gost_engine/patches/040-dont-build-tests.patch b/external/subpack/libs/gost_engine/patches/040-dont-build-tests.patch
new file mode 100644
index 0000000..08c7b76
--- /dev/null
+++ b/external/subpack/libs/gost_engine/patches/040-dont-build-tests.patch
@@ -0,0 +1,141 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -213,138 +213,6 @@ set(GOST_PROV_SOURCE_FILES
+         gost_prov_mac.c
+         )
+ 
+-set(TEST_ENVIRONMENT_COMMON
+-        CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
+-        PERL5LIB=${CMAKE_CURRENT_SOURCE_DIR}/test
+-        OPENSSL_PROGRAM=${OPENSSL_PROGRAM}
+-        OPENSSL_CRYPTO_LIBRARY=${OPENSSL_CRYPTO_LIBRARY}
+-        )
+-
+-set(TEST_ENVIRONMENT_ENGINE
+-        ${TEST_ENVIRONMENT_COMMON}
+-        OPENSSL_ENGINES=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+-        OPENSSL_CONF=${CMAKE_CURRENT_SOURCE_DIR}/test/engine.cnf
+-        )
+-
+-set(TEST_ENVIRONMENT_PROVIDER
+-        ${TEST_ENVIRONMENT_COMMON}
+-        OPENSSL_MODULES=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
+-        OPENSSL_CONF=${CMAKE_CURRENT_SOURCE_DIR}/test/provider.cnf
+-        )
+-
+-add_executable(test_digest test_digest.c)
+-target_link_libraries(test_digest OpenSSL::Crypto)
+-add_test(NAME digest-with-engine COMMAND test_digest)
+-set_tests_properties(digest-with-engine
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}")
+-add_test(NAME digest-with-provider COMMAND test_digest)
+-set_tests_properties(digest-with-provider
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}")
+-
+-add_executable(test_ciphers test_ciphers.c)
+-target_link_libraries(test_ciphers OpenSSL::Crypto)
+-add_test(NAME ciphers-with-engine COMMAND test_ciphers)
+-set_tests_properties(ciphers-with-engine
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}")
+-add_test(NAME ciphers-with-provider COMMAND test_ciphers)
+-set_tests_properties(ciphers-with-provider
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}")
+-
+-# test_curves is an internals testing program, it doesn't need a test env
+-add_executable(test_curves test_curves.c)
+-target_link_libraries(test_curves gost_core gost_err)
+-add_test(NAME curves COMMAND test_curves)
+-
+-add_executable(test_params test_params.c)
+-target_link_libraries(test_params OpenSSL::Crypto)
+-add_test(NAME parameters-with-engine COMMAND test_params)
+-set_tests_properties(parameters-with-engine
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}")
+-
+-add_executable(test_derive test_derive.c)
+-target_link_libraries(test_derive OpenSSL::Crypto)
+-add_test(NAME derive-with-engine COMMAND test_derive)
+-set_tests_properties(derive-with-engine
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}")
+-
+-add_executable(test_sign test_sign.c)
+-target_link_libraries(test_sign OpenSSL::Crypto)
+-add_test(NAME sign/verify-with-engine COMMAND test_sign)
+-set_tests_properties(sign/verify-with-engine
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}")
+-
+-add_executable(test_tls test_tls.c)
+-target_link_libraries(test_tls OpenSSL::SSL)
+-add_test(NAME TLS-with-engine COMMAND test_tls)
+-set_tests_properties(TLS-with-engine
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}")
+-
+-add_executable(test_context test_context.c)
+-target_link_libraries(test_context OpenSSL::Crypto)
+-add_test(NAME context-with-engine COMMAND test_context)
+-set_tests_properties(context-with-engine
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}")
+-add_test(NAME context-with-provider COMMAND test_context)
+-set_tests_properties(context-with-provider
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}")
+-
+-# test_keyexpimp is an internals testing program, it doesn't need a test env
+-add_executable(test_keyexpimp test_keyexpimp.c)
+-#target_compile_definitions(test_keyexpimp PUBLIC -DOPENSSL_LOAD_CONF)
+-target_link_libraries(test_keyexpimp gost_core gost_err)
+-add_test(NAME keyexpimp COMMAND test_keyexpimp)
+-
+-# test_gost89 is an internals testing program, it doesn't need a test env
+-add_executable(test_gost89 test_gost89.c)
+-target_link_libraries(test_gost89 gost_core gost_err)
+-add_test(NAME gost89 COMMAND test_gost89)
+-
+-add_executable(test_mgm test_mgm.c)
+-target_link_libraries(test_mgm OpenSSL::Crypto)
+-add_test(NAME mgm-with-engine COMMAND test_mgm)
+-set_tests_properties(mgm-with-engine
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}")
+-add_test(NAME mgm-with-provider COMMAND test_mgm)
+-set_tests_properties(mgm-with-provider
+-  PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}")
+-
+-if(NOT SKIP_PERL_TESTS)
+-    execute_process(COMMAND perl -MTest2::V0 -e ""
+-       ERROR_QUIET RESULT_VARIABLE MISSING_TEST2_V0)
+-    find_program(HAVE_PROVE NAMES prove)
+-    if(NOT MISSING_TEST2_V0 AND HAVE_PROVE)
+-	add_test(NAME engine
+-	    COMMAND prove --merge -PWrapOpenSSL ${CMAKE_CURRENT_SOURCE_DIR}/test :: engine)
+-	set_tests_properties(engine PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_ENGINE}")
+-	add_test(NAME provider
+-	    COMMAND prove --merge -PWrapOpenSSL ${CMAKE_CURRENT_SOURCE_DIR}/test :: provider)
+-	set_tests_properties(provider PROPERTIES ENVIRONMENT "${TEST_ENVIRONMENT_PROVIDER}")
+-    else()
+-        message(STATUS "No Test2::V0 perl module (engine and provider tests skipped)")
+-    endif()
+-endif()
+-
+-if(NOT MSVC)
+-  add_executable(sign benchmark/sign.c)
+-  target_link_libraries(sign gost_core gost_err ${CLOCK_GETTIME_LIB})
+-endif()
+-
+-# All that may need to load just built engine will have path to it defined.
+-set(BINARY_TESTS_TARGETS
+-        test_digest
+-        test_ciphers
+-        test_curves
+-        test_params
+-        test_derive
+-        test_sign
+-        test_context
+-        test_keyexpimp
+-        test_gost89
+-        test_tls
+-        test_mgm
+-        )
+-set_property(TARGET ${BINARY_TESTS_TARGETS} APPEND PROPERTY COMPILE_DEFINITIONS ENGINE_DIR="${OUTPUT_DIRECTORY}")
+-
+ add_library(gost_core STATIC ${GOST_LIB_SOURCE_FILES})
+ set_target_properties(gost_core PROPERTIES POSITION_INDEPENDENT_CODE ON)
+ target_link_libraries(gost_core PRIVATE OpenSSL::Crypto)
diff --git a/external/subpack/libs/gost_engine/test.sh b/external/subpack/libs/gost_engine/test.sh
new file mode 100644
index 0000000..b2cef4b
--- /dev/null
+++ b/external/subpack/libs/gost_engine/test.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+# shellcheck disable=SC2059
+
+run_md_test () {
+	[ $# -ge 3 ] || {
+		echo "Error: insufficient args to run_md_test()" >&2
+		exit 1
+	}
+	DGST="$1";  shift
+	INP="$1"; shift
+	EXP="$1"; shift
+	printf "Testing digest %s: " "$DGST" >&2
+	OUT="$(printf "$INP" | openssl dgst -"$DGST" "$@")" || exit 1
+	[ -z "${OUT%%*"$EXP"}" ] || {
+		printf "Failure: expected: '%s', got '%s'\n" "$EXP" "$OUT" >&2
+		exit 1
+	}
+	echo OK >&2 || true
+}
+
+run_cipher_test() {
+	[ $# -ge 5 ] || {
+		echo "Error: insufficient args to run_cipher_test()" >&2
+		exit 1
+	}
+	ALG="$1"; shift
+	KEY="$1"; shift
+	IV="$1"; shift
+	CLEAR_TEXT="$1"; shift
+	CIPHER_TEXT="$1"; shift
+	printf "Testing %s encryption: " "$ALG" >&2
+	OUT="$(printf "$CLEAR_TEXT" | openssl enc -e -"$ALG" -K "$KEY" -iv "$IV" "$@" -a -A)" || exit 1
+	[ -z "${OUT%"$CIPHER_TEXT"}" ] || {
+		printf "Encryption failure: expected: '%s', got '%s'\n" "$CIPHER_TEXT" "$OUT" >&2
+		exit 1
+	}
+	echo OK >&2
+	printf "Testing %s decryption: " "$ALG" >&2
+	OUT="$(printf "$CIPHER_TEXT" | openssl enc -d -"$ALG" -K "$KEY" -iv "$IV" "$@" -a -A)" || exit 1
+	[ -z "${OUT%"$(printf "$CLEAR_TEXT")"}" ] || {
+		echo "Decryption failure!" >&2
+		echo "----------- expected hexdump -------------" >&2
+		printf "$CLEAR_TEXT" | hexdump -C
+		echo "------------ result hexdump --------------" >&2
+		echo "$OUT" | hexdump -C >&2
+		exit 1
+	}
+	echo OK >&2 || true
+}
+
+case "$1" in
+	libopenssl-gost_engine)
+		opkg install openssl-util
+		run_md_test \
+			md_gost12_256 \
+			012345678901234567890123456789012345678901234567890123456789012 \
+			9d151eefd8590b89daa6ba6cb74af9275dd051026bb149a452fd84e5e57b5500
+		export CRYPT_PARAMS="1.2.643.2.2.31.1"
+		run_cipher_test \
+			gost89 \
+			0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF \
+			0000000000000000 \
+			"The quick brown fox jumps over the lazy dog\n" \
+			"B/QQLGGFxKCeZ24mm/pLycXfZXWRa4eb0TqJOiKF7maQEHze73oxXS61S/o="
+		;;
+	gost_engine-util)
+		printf "Testing gost12sum: "
+		EXP=9d151eefd8590b89daa6ba6cb74af9275dd051026bb149a452fd84e5e57b5500
+		OUT=$(printf 012345678901234567890123456789012345678901234567890123456789012 | gost12sum)
+		[ -z "${OUT##"$EXP"*}" ] || {
+			printf "Failure: expected: '%s', got '%s'\n" "$EXP" "$OUT" >&2
+			exit 1
+		}
+		echo OK >&2 || true
+		;;
+	*)
+		echo "Unexpected package '$1'" >&2
+		exit 1
+		;;
+esac
diff --git a/external/subpack/libs/gperftools/Makefile b/external/subpack/libs/gperftools/Makefile
new file mode 100644
index 0000000..92e7e61
--- /dev/null
+++ b/external/subpack/libs/gperftools/Makefile
@@ -0,0 +1,70 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=gperftools
+PKG_VERSION:=2.16
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/gperftools/gperftools/tar.gz/$(PKG_NAME)-$(PKG_VERSION)?
+PKG_HASH:=737be182b4e42f5c7f595da2a7aa59ce0489a73d336d0d16847f2aa52d5221b4
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_MAINTAINER:=John Audia <therealgraysky@proton.me>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_FLAGS:=no-mips16
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/gperftools-headers
+  CATEGORY:=Libraries
+  SECTION:=libs
+  TITLE:=Gperftools Headers
+  URL:=https://github.com/gperftools/gperftools
+  DEPENDS:= @!(mips||mips64||mipsel||powerpc)
+endef
+
+define Package/gperftools-runtime
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Gperftools Runtime
+  URL:=https://github.com/gperftools/gperftools
+  DEPENDS:= +libunwind +libstdcpp @!(mips||mips64||mipsel||powerpc)
+endef
+
+define Package/gperftools-headers/description
+  Gperftools is a collection of a high-performance multi-threaded malloc() implementation, plus some pretty nifty performance analysis tools.
+  This package contains the headers.
+endef
+
+define Package/gperftools-runtime/description
+  Gperftools is a collection of a high-performance multi-threaded malloc() implementation, plus some pretty nifty performance analysis tools.
+  This package contains the shared objects and bins.
+endef
+
+CONFIGURE_ARGS += \
+	--enable-frame-pointers \
+	--enable-libunwind \
+	--disable-deprecated-pprof
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtcmalloc.so* $(1)/usr/lib/
+endef
+
+define Package/gperftools-headers/install
+	$(INSTALL_DIR) $(1)/usr/include/gperftools
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/gperftools/tcmalloc.h $(1)/usr/include/gperftools
+endef
+
+define Package/gperftools-runtime/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtcmalloc.so* $(1)/usr/lib/
+endef
+$(eval $(call BuildPackage,gperftools-headers))
+$(eval $(call BuildPackage,gperftools-runtime))
diff --git a/external/subpack/libs/gpgme/Makefile b/external/subpack/libs/gpgme/Makefile
new file mode 100644
index 0000000..c4fa317
--- /dev/null
+++ b/external/subpack/libs/gpgme/Makefile
@@ -0,0 +1,113 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=gpgme
+PKG_VERSION:=1.21.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://gnupg.org/ftp/gcrypt/$(PKG_NAME)
+PKG_HASH:=416e174e165734d84806253f8c96bda2993fd07f258c3aad5f053a6efd463e88
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:gnu:gpgme
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libgpgme
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GnuPG Made Easy (GPGME) library
+  URL:=https://gnupg.org/software/gpgme/index.html
+  DEPENDS:=+libassuan +libgpg-error
+endef
+
+define Package/libgpgmepp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GnuPG Made Easy (GPGME) library (C++)
+  URL:=https://gnupg.org/software/gpgme/index.html
+  DEPENDS:=+libgpgme +libstdcpp
+endef
+
+define Package/libgpgme/description
+GnuPG Made Easy (GPGME) is a library designed to make access to GnuPG
+easier for applications. It provides a High-Level Crypto API for
+encryption, decryption, signing, signature verification and key
+management. Currently it uses GnuPG's OpenPGP backend as the default,
+but the API isn't restricted to this engine. We have, in fact, already
+developed a backend for CMS (S/MIME).
+endef
+
+CONFIGURE_ARGS += \
+	--with-libassuan-prefix="$(STAGING_DIR)/usr/" \
+	--with-gpg-error-prefix="$(STAGING_DIR)/usr/" \
+	--disable-gpgconf-test \
+	--disable-gpg-test \
+	--disable-gpgsm-test \
+	--disable-g13-test \
+	--enable-languages="cpp"
+
+ifneq ($(CONFIG_USE_MUSL),)
+  TARGET_CFLAGS += -D_LARGEFILE64_SOURCE
+endif
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/gpgme++
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/include/gpgme.h \
+		$(1)/usr/include/
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/include/gpgme++/*.h \
+		$(1)/usr/include/gpgme++/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libgpgme.{la,so*} \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/share/aclocal
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/share/aclocal/gpgme.m4 \
+		$(1)/usr/share/aclocal/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/gpgme.pc \
+		$(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/gpgme-glib.pc \
+		$(1)/usr/lib/pkgconfig
+
+	$(INSTALL_DIR) $(1)/usr/lib/cmake/Gpgmepp
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/cmake/Gpgmepp/*.cmake \
+		$(1)/usr/lib/cmake/Gpgmepp
+
+	$(INSTALL_DIR) $(2)/bin $(1)/usr/bin
+	$(INSTALL_BIN) \
+		$(PKG_INSTALL_DIR)/usr/bin/gpgme-config \
+		$(2)/bin/
+	$(SED) \
+		's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \
+		$(2)/bin/gpgme-config
+	$(LN) -sf $(STAGING_DIR)/host/bin/gpgme-config $(1)/usr/bin/gpgme-config
+endef
+
+define Package/libgpgme/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgpgme.so.* $(1)/usr/lib/
+endef
+
+define Package/libgpgmepp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgpgmepp.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libgpgme))
+$(eval $(call BuildPackage,libgpgmepp))
diff --git a/external/subpack/libs/hidapi/Makefile b/external/subpack/libs/hidapi/Makefile
new file mode 100644
index 0000000..4f0698c
--- /dev/null
+++ b/external/subpack/libs/hidapi/Makefile
@@ -0,0 +1,61 @@
+#
+# Copyright (C) 2015 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:=hidapi
+PKG_VERSION:=0.14.0
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/libusb/hidapi
+PKG_SOURCE_VERSION:=hidapi-$(PKG_VERSION)
+PKG_MIRROR_HASH:=01aae0df35dd8b166378557d783b8a92ab05b725c35ee19eb7f5fa0b2ee03595
+
+PKG_MAINTAINER:=Paul Fertser <fercerpav@gmail.com>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE-bsd.txt
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/hidapi
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libusb-1.0 +libudev $(ICONV_DEPENDS)
+  TITLE:=Library to talk to HID devices
+  URL:=https://github.com/libusb/hidapi
+endef
+
+define Package/hidapi/description
+HIDAPI is a multi-platform library which allows an application to interface
+with USB and Bluetooth HID-Class devices on Windows, Linux, FreeBSD, and Mac
+OS X.  HIDAPI can be either built as a shared library (.so or .dll) or
+can be embedded directly into a target application by adding a single source
+file (per platform) and a single header.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/hidapi
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/hidapi/hidapi.h $(1)/usr/include/hidapi/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/hidapi/hidapi_libusb.h $(1)/usr/include/hidapi/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libhidapi-hidraw.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libhidapi-libusb.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/hidapi-libusb.pc $(1)/usr/lib/pkgconfig/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/hidapi-hidraw.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/hidapi/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libhidapi-hidraw.so.* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libhidapi-libusb.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,hidapi))
diff --git a/external/subpack/libs/hiredis/Makefile b/external/subpack/libs/hiredis/Makefile
new file mode 100644
index 0000000..f046768
--- /dev/null
+++ b/external/subpack/libs/hiredis/Makefile
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2010-2015 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:=hiredis
+PKG_VERSION:=1.2.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/redis/hiredis/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=82ad632d31ee05da13b537c124f819eb88e18851d9cb0c30ae0552084811588c
+
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:redis:hiredis
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+PKG_BUILD_PARALLEL:=1
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libhiredis
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=Minimalistic C client for Redis
+	URL:=https://github.com/redis/hiredis
+endef
+
+define Package/libhiredis/description
+	Hiredis is a minimalistic C client library for the Redis database.
+endef
+
+define Package/libhiredis/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libhiredis.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libhiredis))
diff --git a/external/subpack/libs/hwloc/Makefile b/external/subpack/libs/hwloc/Makefile
new file mode 100644
index 0000000..570f5fb
--- /dev/null
+++ b/external/subpack/libs/hwloc/Makefile
@@ -0,0 +1,98 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=hwloc
+PKG_VERSION:=2.10.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://download.open-mpi.org/release/$(PKG_NAME)/v2.10
+PKG_HASH:=0305dd60c9de2fbe6519fe2a4e8fdc6d3db8de574a0ca7812b92e80c05ae1392
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/hwloc/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Portable Hardware Locality
+  URL:=https://www.open-mpi.org/projects/hwloc/
+endef
+
+define Package/hwloc/Default/description
+  The Portable Hardware Locality (hwloc) software package provides a
+  portable abstraction (across OS, versions, architectures, ...) of the
+  hierarchical topology of modern architectures, including NUMA memory
+  nodes, sockets, shared caches, cores and simultaneous multithreading. It
+  also gathers various system attributes such as cache and memory
+  information as well as the locality of I/O devices such as network
+  interfaces, InfiniBand HCAs or GPUs.
+endef
+
+define Package/hwloc-utils
+$(call Package/hwloc/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE+= utilities
+  DEPENDS+= +libhwloc +libncurses
+endef
+
+define Package/hwloc-utils/description
+$(call Package/hwloc/Default/description)
+  This package contains the hwloc utilities.
+endef
+
+define Package/libhwloc
+$(call Package/hwloc/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE+= libraries
+  DEPENDS+=+libpciaccess
+endef
+
+define Package/libhwloc/description
+$(call Package/hwloc/Default/description)
+  This package contains the hwloc libraries.
+endef
+
+CONFIGURE_ARGS += \
+	--disable-libxml2 \
+	--disable-libudev
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/hwloc.h $(STAGING_DIR)/usr/include/
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/include/hwloc
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/hwloc/*.h $(STAGING_DIR)/usr/include/hwloc/
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/include/hwloc/autogen
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/hwloc/autogen/*.h $(STAGING_DIR)/usr/include/hwloc/autogen/
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib* $(STAGING_DIR)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc \
+		$(1)/usr/lib/pkgconfig
+endef
+
+define Package/hwloc-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+define Package/libhwloc/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,hwloc-utils))
+$(eval $(call BuildPackage,libhwloc))
diff --git a/external/subpack/libs/hyperscan/Makefile b/external/subpack/libs/hyperscan/Makefile
new file mode 100644
index 0000000..ed33cae
--- /dev/null
+++ b/external/subpack/libs/hyperscan/Makefile
@@ -0,0 +1,82 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=hyperscan
+PKG_VERSION:=5.4.2
+PKG_RELEASE:=3
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/intel/hyperscan/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=32b0f24b3113bbc46b6bfaa05cf7cf45840b6b59333d078cc1f624e4c40b2b99
+
+PKG_MAINTAINER:=John Audia <therealgraysky@proton.me>
+PKG_LICENSE:=BSD-3-Clause BSD-2-Clause BSL-1.0
+PKG_LICENSE_FILES:=LICENSE
+PKG_BUILD_DEPENDS:=ragel/host python3/host boost/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+# A minimum of SSSE3 support is required to use hyperscan
+# We need to define the C(XX)FLAGS to avoid -march=native being
+# used as this is hardcoded by upstream, see:
+# https://github.com/intel/hyperscan/blob/master/doc/dev-reference/getting_started.rst
+CMAKE_OPTIONS += \
+	-DCMAKE_INSTALL_PREFIX=/usr \
+	-DCMAKE_INSTALL_LIBDIR=lib \
+	-DBUILD_SHARED_LIBS=ON \
+	-DCMAKE_C_FLAGS="-march=x86-64-v2" \
+	-DCMAKE_CXX_FLAGS="-march=x86-64-v2" \
+	-Wno-dev
+
+define Package/hyperscan-headers
+  CATEGORY:=Libraries
+  SECTION:=libs
+  TITLE:=Hyperscan Headers
+  URL:=https://github.com/intel/hyperscan
+  DEPENDS:=@TARGET_x86_64
+endef
+
+define Package/hyperscan-runtime
+  CATEGORY:=Libraries
+  SECTION:=libs
+  TITLE:=Hyperscan Runtime
+  URL:=https://github.com/intel/hyperscan
+  DEPENDS:=@TARGET_x86_64 +libstdcpp
+endef
+
+define Package/hyperscan-headers/description
+  This package contains the headers for Hyperscan.
+endef
+
+define Package/hyperscan-runtime/description
+  This package contains the shared objects for Hyperscan.
+endef
+
+# This installs files into ./staging_dir/. so that you can cross compile from the host
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/hs
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/hs/* $(1)/usr/include/hs/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libhs* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) $(PKG_BUILD_DIR)/libhs.pc $(1)/usr/lib/pkgconfig/libhs.pc
+endef
+
+# These install files on the target.  Compare with Build/InstallDev
+define Package/hyperscan-headers/install
+	$(INSTALL_DIR) $(1)/usr/include/hs
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/hs/*.h $(1)/usr/include/hs/
+endef
+
+define Package/hyperscan-runtime/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libhs* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,hyperscan-headers))
+$(eval $(call BuildPackage,hyperscan-runtime))
diff --git a/external/subpack/libs/hyperscan/patches/0001-CMakeLists.txt-hack-for-our-build-system.patch b/external/subpack/libs/hyperscan/patches/0001-CMakeLists.txt-hack-for-our-build-system.patch
new file mode 100644
index 0000000..450af73
--- /dev/null
+++ b/external/subpack/libs/hyperscan/patches/0001-CMakeLists.txt-hack-for-our-build-system.patch
@@ -0,0 +1,56 @@
+From c5a983652a2bbbc029961affd2996459e45b5336 Mon Sep 17 00:00:00 2001
+From: John Audia <therealgraysky@proton.me>
+Date: Sat, 20 Apr 2024 13:29:49 -0400
+Subject: [PATCH] CMakeLists.txt: hack for our build system
+
+If building with the project external toolchain, the gcc check
+fails to set the correct value for TUNE_FLAG to allow the min
+supported SSSE3 compiler support test to pass.  This patch hacks
+the file to set to the correct value.
+
+Links to upstream bug reports:
+https://github.com/openwrt/openwrt/issues/15216
+https://github.com/intel/hyperscan/issues/431
+
+---
+ CMakeLists.txt | 29 +----------------------------
+ 1 file changed, 1 insertion(+), 28 deletions(-)
+
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -183,34 +183,7 @@ else()
+     endforeach ()
+ 
+     if (CMAKE_COMPILER_IS_GNUCC)
+-        message(STATUS "gcc version ${CMAKE_C_COMPILER_VERSION}")
+-        # If gcc doesn't recognise the host cpu, then mtune=native becomes
+-        # generic, which isn't very good in some cases. march=native looks at
+-        # cpuid info and then chooses the best microarch it can (and replaces
+-        # the flag), so use that for tune.
+-
+-        # arg1 might exist if using ccache
+-        string (STRIP "${CMAKE_C_COMPILER_ARG1}" CC_ARG1)
+-        set (EXEC_ARGS ${CC_ARG1} -c -Q --help=target -march=native -mtune=native)
+-        execute_process(COMMAND ${CMAKE_C_COMPILER} ${EXEC_ARGS}
+-            OUTPUT_VARIABLE _GCC_OUTPUT)
+-        string(FIND "${_GCC_OUTPUT}" "march" POS)
+-        string(SUBSTRING "${_GCC_OUTPUT}" ${POS} -1 _GCC_OUTPUT)
+-        string(REGEX REPLACE "march=[ \t]*([^ \n]*)[ \n].*" "\\1"
+-            GNUCC_ARCH "${_GCC_OUTPUT}")
+-
+-        # test the parsed flag
+-        set (EXEC_ARGS ${CC_ARG1} -E - -mtune=${GNUCC_ARCH})
+-        execute_process(COMMAND ${CMAKE_C_COMPILER} ${EXEC_ARGS}
+-            OUTPUT_QUIET ERROR_QUIET
+-            INPUT_FILE /dev/null
+-            RESULT_VARIABLE GNUCC_TUNE_TEST)
+-        if (NOT GNUCC_TUNE_TEST EQUAL 0)
+-            message(SEND_ERROR "Something went wrong determining gcc tune: -mtune=${GNUCC_ARCH} not valid")
+-        endif()
+-        set(TUNE_FLAG ${GNUCC_ARCH})
+-    else ()
+-        set(TUNE_FLAG native)
++        set(TUNE_FLAG x86-64-v2)
+     endif()
+ 
+     # compiler version checks TODO: test more compilers
diff --git a/external/subpack/libs/ibrcommon/Makefile b/external/subpack/libs/ibrcommon/Makefile
new file mode 100644
index 0000000..2b6f4c2
--- /dev/null
+++ b/external/subpack/libs/ibrcommon/Makefile
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2015 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:=ibrcommon
+PKG_VERSION:=1.0.1
+PKG_RELEASE:=10
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.ibr.cs.tu-bs.de/projects/ibr-dtn/releases
+PKG_HASH:=9c457c1ebc01e6216524636628c647bef34ab11bd96f0e0788be8749374fdc20
+PKG_MAINTAINER:=Johannes Morgenroth <jm@m-network.de>
+PKG_LICENSE:=Apache-2.0
+
+PKG_INSTALL:=1
+PKG_FIXUP:=libtool
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ibrcommon
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libstdcpp +librt +libnl +libopenssl
+  TITLE:=IBR Common C++ Library
+endef
+
+CONFIGURE_ARGS += \
+	--with-openssl
+
+TARGET_CXXFLAGS += -std=c++11
+
+define Package/ibrcommon/description
+ A library with common functions for C++.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)
+	$(CP) $(PKG_INSTALL_DIR)/* $(1)/
+endef
+
+define Package/ibrcommon/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,ibrcommon))
diff --git a/external/subpack/libs/ibrcommon/patches/001-fix-build-with-musl.patch b/external/subpack/libs/ibrcommon/patches/001-fix-build-with-musl.patch
new file mode 100644
index 0000000..bee392d
--- /dev/null
+++ b/external/subpack/libs/ibrcommon/patches/001-fix-build-with-musl.patch
@@ -0,0 +1,33 @@
+--- a/ibrcommon/data/File.cpp
++++ b/ibrcommon/data/File.cpp
+@@ -35,10 +35,6 @@
+ #include <cerrno>
+ #include <fstream>
+ 
+-#if !defined(HAVE_FEATURES_H) || defined(ANDROID)
+-#include <libgen.h>
+-#endif
+-
+ #ifdef __WIN32__
+ #include <io.h>
+ #define FILE_DELIMITER_CHAR '\\'
+@@ -225,14 +221,11 @@ namespace ibrcommon
+ 
+ 	std::string File::getBasename() const
+ 	{
+-#if !defined(ANDROID) && defined(HAVE_FEATURES_H)
+-		return std::string(basename(_path.c_str()));
+-#else
+-		char path[_path.length()+1];
+-		::memcpy(&path, _path.c_str(), _path.length()+1);
+-
+-		return std::string(basename(path));
+-#endif
++		size_t found = _path.find_last_of('/');
++		if (found != std::string::npos)
++			return _path.substr(found + 1);
++		else
++			return _path;
+ 	}
+ 
+ 	File File::get(const std::string &filename) const
diff --git a/external/subpack/libs/ibrcommon/patches/010-build-with-openssl-1.1.patch b/external/subpack/libs/ibrcommon/patches/010-build-with-openssl-1.1.patch
new file mode 100644
index 0000000..559d17a
--- /dev/null
+++ b/external/subpack/libs/ibrcommon/patches/010-build-with-openssl-1.1.patch
@@ -0,0 +1,337 @@
+From fe7ae129b8be052e5178b07e76e19ede21b13261 Mon Sep 17 00:00:00 2001
+From: Eneas U de Queiroz <cote2004-github@yahoo.com>
+Date: Tue, 22 May 2018 16:40:20 -0300
+Subject: [PATCH] ibrcommon: added openssl 1.1 compatibility
+
+This patch adds compatibility to openssl 1.1.0.
+
+Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
+---
+ ibrcommon/ssl/HMacStream.cpp      | 11 ++++----
+ ibrcommon/ssl/HMacStream.h        |  2 +-
+ ibrcommon/ssl/RSASHA256Stream.cpp | 28 +++++++++---------
+ ibrcommon/ssl/RSASHA256Stream.h   |  2 +-
+ ibrcommon/ssl/iostreamBIO.cpp     | 44 ++++++++++++++++++++++-------
+ ibrcommon/ssl/openssl_compat.h    | 38 +++++++++++++++++++++++++
+ 6 files changed, 95 insertions(+), 30 deletions(-)
+ create mode 100644 ibrcommon/ssl/openssl_compat.h
+
+--- a/ibrcommon/ssl/HMacStream.cpp
++++ b/ibrcommon/ssl/HMacStream.cpp
+@@ -20,29 +20,30 @@
+  */
+ 
+ #include "ibrcommon/ssl/HMacStream.h"
++#include "openssl_compat.h"
+ 
+ namespace ibrcommon
+ {
+ 	HMacStream::HMacStream(const unsigned char * const key, const int key_size)
+ 	 : HashStream(EVP_MAX_MD_SIZE, BUFF_SIZE), key_(key), key_size_(key_size)
+ 	{
+-		HMAC_CTX_init(&ctx_);
+-		HMAC_Init_ex(&ctx_, key_, key_size_, EVP_sha1(), NULL);
++		ctx_ = HMAC_CTX_new();
++		HMAC_Init_ex(ctx_, key_, key_size_, EVP_sha1(), NULL);
+ 	}
+ 
+ 	HMacStream::~HMacStream()
+ 	{
+-		HMAC_CTX_cleanup(&ctx_);
++		HMAC_CTX_free(ctx_);
+ 	}
+ 
+ 	void HMacStream::update(char *buf, const size_t size)
+ 	{
+ 		// hashing
+-		HMAC_Update(&ctx_, (unsigned char*)buf, size);
++		HMAC_Update(ctx_, (unsigned char*)buf, size);
+ 	}
+ 
+ 	void HMacStream::finalize(char * hash, unsigned int &size)
+ 	{
+-		HMAC_Final(&ctx_, (unsigned char*)hash, &size);
++		HMAC_Final(ctx_, (unsigned char*)hash, &size);
+ 	}
+ }
+--- a/ibrcommon/ssl/HMacStream.h
++++ b/ibrcommon/ssl/HMacStream.h
+@@ -44,7 +44,7 @@ namespace ibrcommon
+ 		const unsigned char * const key_;
+ 		const int key_size_;
+ 
+-		HMAC_CTX ctx_;
++		HMAC_CTX* ctx_;
+ 	};
+ }
+ 
+--- a/ibrcommon/ssl/RSASHA256Stream.cpp
++++ b/ibrcommon/ssl/RSASHA256Stream.cpp
+@@ -21,6 +21,7 @@
+ 
+ #include "ibrcommon/ssl/RSASHA256Stream.h"
+ #include "ibrcommon/Logger.h"
++#include "openssl_compat.h"
+ #include <openssl/err.h>
+ 
+ namespace ibrcommon
+@@ -30,11 +31,11 @@ namespace ibrcommon
+ 	{
+ 		// Initialize get pointer.  This should be zero so that underflow is called upon first read.
+ 		setp(&out_buf_[0], &out_buf_[BUFF_SIZE - 1]);
+-		EVP_MD_CTX_init(&_ctx);
++		_ctx = EVP_MD_CTX_new();
+ 
+ 		if (!_verify)
+ 		{
+-			if (!EVP_SignInit_ex(&_ctx, EVP_sha256(), NULL))
++			if (!EVP_SignInit_ex(_ctx, EVP_sha256(), NULL))
+ 			{
+ 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to initialize the signature function" << IBRCOMMON_LOGGER_ENDL;
+ 				ERR_print_errors_fp(stderr);
+@@ -42,7 +43,7 @@ namespace ibrcommon
+ 		}
+ 		else
+ 		{
+-			if (!EVP_VerifyInit_ex(&_ctx, EVP_sha256(), NULL))
++			if (!EVP_VerifyInit_ex(_ctx, EVP_sha256(), NULL))
+ 			{
+ 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to initialize the verification function" << IBRCOMMON_LOGGER_ENDL;
+ 				ERR_print_errors_fp(stderr);
+@@ -52,18 +53,19 @@ namespace ibrcommon
+ 
+ 	RSASHA256Stream::~RSASHA256Stream()
+ 	{
+-		EVP_MD_CTX_cleanup(&_ctx);
++		EVP_MD_CTX_free(_ctx);
+ 	}
+ 
+ 	void RSASHA256Stream::reset()
+ 	{
+-		EVP_MD_CTX_cleanup(&_ctx);
+-
+-		EVP_MD_CTX_init(&_ctx);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++		EVP_MD_CTX_cleanup(_ctx);
++#endif
++		EVP_MD_CTX_init(_ctx);
+ 
+ 		if (!_verify)
+ 		{
+-			if (!EVP_SignInit_ex(&_ctx, EVP_sha256(), NULL))
++			if (!EVP_SignInit_ex(_ctx, EVP_sha256(), NULL))
+ 			{
+ 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to initialize the signature function" << IBRCOMMON_LOGGER_ENDL;
+ 				ERR_print_errors_fp(stderr);
+@@ -71,7 +73,7 @@ namespace ibrcommon
+ 		}
+ 		else
+ 		{
+-			if (!EVP_VerifyInit_ex(&_ctx, EVP_sha256(), NULL))
++			if (!EVP_VerifyInit_ex(_ctx, EVP_sha256(), NULL))
+ 			{
+ 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to initialize the verfication function" << IBRCOMMON_LOGGER_ENDL;
+ 				ERR_print_errors_fp(stderr);
+@@ -91,7 +93,7 @@ namespace ibrcommon
+ 			std::vector<unsigned char> sign(EVP_PKEY_size(_pkey));
+ 			unsigned int size = EVP_PKEY_size(_pkey);
+ 
+-			_return_code = EVP_SignFinal(&_ctx, &sign[0], &size, _pkey);
++			_return_code = EVP_SignFinal(_ctx, &sign[0], &size, _pkey);
+ 
+ 			_sign = std::string((const char*)&sign[0], size);
+ 
+@@ -107,7 +109,7 @@ namespace ibrcommon
+ 		if (!_sign_valid)
+ 		{
+ 			sync();
+-			_return_code = EVP_VerifyFinal(&_ctx, reinterpret_cast<const unsigned char *>(their_sign.c_str()), static_cast<unsigned int>(their_sign.size()), _pkey);
++			_return_code = EVP_VerifyFinal(_ctx, reinterpret_cast<const unsigned char *>(their_sign.c_str()), static_cast<unsigned int>(their_sign.size()), _pkey);
+ 			_sign_valid = true;
+ 		}
+ 		return _return_code;
+@@ -145,7 +147,7 @@ namespace ibrcommon
+ 		if (!_verify)
+ 			// hashing
+ 		{
+-			if (!EVP_SignUpdate(&_ctx, &out_buf_[0], iend - ibegin))
++			if (!EVP_SignUpdate(_ctx, &out_buf_[0], iend - ibegin))
+ 			{
+ 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to feed data into the signature function" << IBRCOMMON_LOGGER_ENDL;
+ 				ERR_print_errors_fp(stderr);
+@@ -153,7 +155,7 @@ namespace ibrcommon
+ 		}
+ 		else
+ 		{
+-			if (!EVP_VerifyUpdate(&_ctx, &out_buf_[0], iend - ibegin))
++			if (!EVP_VerifyUpdate(_ctx, &out_buf_[0], iend - ibegin))
+ 			{
+ 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to feed data into the verification function" << IBRCOMMON_LOGGER_ENDL;
+ 				ERR_print_errors_fp(stderr);
+--- a/ibrcommon/ssl/RSASHA256Stream.h
++++ b/ibrcommon/ssl/RSASHA256Stream.h
+@@ -106,7 +106,7 @@ namespace ibrcommon
+ 
+ 		/** the context in which the streamed data will be feed into for
+ 		calculation of the hash/signature */
+-		EVP_MD_CTX _ctx;
++		EVP_MD_CTX * _ctx;
+ 
+ 		/** tells if the context needs to be finalized to get a valid signature or
+ 		verification */
+--- a/ibrcommon/ssl/iostreamBIO.cpp
++++ b/ibrcommon/ssl/iostreamBIO.cpp
+@@ -23,6 +23,7 @@
+ 
+ #include "ibrcommon/Logger.h"
+ 
++#include "openssl_compat.h"
+ #include <openssl/err.h>
+ 
+ namespace ibrcommon
+@@ -42,7 +43,20 @@ static int create(BIO *bio);
+ //static int destroy(BIO *bio);
+ //static long (*callback_ctrl)(BIO *, int, bio_info_cb *);
+ 
+-
++#if OPENSSL_VERSION_NUMBER >= 0x10100000L
++BIO_METHOD * BIO_iostream_method()
++{
++	static BIO_METHOD *iostream_method = NULL;
++	if (iostream_method) {
++		iostream_method = BIO_meth_new(iostreamBIO::type, iostreamBIO::name);
++		BIO_meth_set_write(iostream_method, bwrite);
++		BIO_meth_set_read(iostream_method, bread);
++		BIO_meth_set_ctrl(iostream_method, ctrl);
++		BIO_meth_set_create(iostream_method, create);
++	}
++	return iostream_method;
++}
++#else
+ static BIO_METHOD iostream_method =
+ {
+ 		iostreamBIO::type,
+@@ -56,12 +70,17 @@ static BIO_METHOD iostream_method =
+ 		NULL,//destroy,
+ 		NULL//callback_ctrl
+ };
++BIO_METHOD * BIO_iostream_method()
++{
++	return &iostream_method;
++}
++#endif
+ 
+ iostreamBIO::iostreamBIO(iostream *stream)
+ 	:	_stream(stream)
+ {
+ 	/* create BIO */
+-	_bio = BIO_new(&iostream_method);
++	_bio = BIO_new(BIO_iostream_method());
+ 	if(!_bio){
+ 		/* creation failed, throw exception */
+ 		char err_buf[ERR_BUF_SIZE];
+@@ -72,7 +91,7 @@ iostreamBIO::iostreamBIO(iostream *strea
+ 	}
+ 
+ 	/* save the iostream in the bio object */
+-	_bio->ptr = stream;
++	BIO_set_data(_bio, (void *) stream);
+ }
+ 
+ BIO * iostreamBIO::getBIO(){
+@@ -81,10 +100,10 @@ BIO * iostreamBIO::getBIO(){
+ 
+ static int create(BIO *bio)
+ {
+-	bio->ptr = NULL;
+-	/* (from openssl memory bio) */
+-	bio->shutdown=1;
+-	bio->init=1;
++	BIO_set_data(bio, NULL);
++	BIO_set_shutdown(bio, 1);
++	BIO_set_init(bio, 1);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ 	/* from bss_mem.c (openssl):
+ 	 * bio->num is used to hold the value to return on 'empty', if it is
+ 	 * 0, should_retry is not set
+@@ -93,6 +112,7 @@ static int create(BIO *bio)
+ 	 * it is set to 0 since the underlying stream is blocking
+ 	 */
+ 	bio->num= 0;
++#endif
+ 
+ 	return 1;
+ }
+@@ -102,7 +122,7 @@ static int create(BIO *bio)
+ static long ctrl(BIO *bio, int cmd, long  num, void *)
+ {
+ 	long ret;
+-	iostream *stream = reinterpret_cast<iostream*>(bio->ptr);
++	iostream *stream = reinterpret_cast<iostream*>(BIO_get_data(bio));
+ 
+ 	IBRCOMMON_LOGGER_DEBUG_TAG("iostreamBIO", 90) << "ctrl called, cmd: " << cmd << ", num: " << num << "." << IBRCOMMON_LOGGER_ENDL;
+ 
+@@ -147,8 +167,12 @@ static long ctrl(BIO *bio, int cmd, long
+ 
+ static int bread(BIO *bio, char *buf, int len)
+ {
+-	iostream *stream = reinterpret_cast<iostream*>(bio->ptr);
++	iostream *stream = reinterpret_cast<iostream*>(BIO_get_data(bio));
++#if OPENSSL_VERSION_NUMBER >= 0x10100000L
++	int num_bytes = 0;
++#else
+ 	int num_bytes = bio->num;
++#endif
+ 
+ 	try{
+ 		/* make sure to read at least 1 byte and then read as much as we can */
+@@ -170,7 +194,7 @@ static int bwrite(BIO *bio, const char *
+ 	if(len == 0){
+ 		return 0;
+ 	}
+-	iostream *stream = reinterpret_cast<iostream*>(bio->ptr);
++	iostream *stream = reinterpret_cast<iostream*>(BIO_get_data(bio));
+ 
+ 	/* write the data */
+ 	try{
+--- /dev/null
++++ b/ibrcommon/ssl/openssl_compat.h
+@@ -0,0 +1,38 @@
++#ifndef OPENSSL_COMPAT_H
++#define OPENSSL_COMPAT_H
++
++#include <openssl/crypto.h>
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++
++#include <openssl/evp.h>
++#include <openssl/hmac.h>
++
++static inline EVP_MD_CTX * EVP_MD_CTX_new()
++{
++	EVP_MD_CTX *ctx;
++
++	ctx = (EVP_MD_CTX *) OPENSSL_malloc(sizeof(EVP_MD_CTX));
++	EVP_MD_CTX_init(ctx);
++        return ctx;
++}
++#define EVP_MD_CTX_free(c) if (c != NULL) OPENSSL_free(c)
++
++static inline HMAC_CTX * HMAC_CTX_new()
++{
++        HMAC_CTX *ctx;
++
++        ctx = (HMAC_CTX *) OPENSSL_malloc(sizeof(HMAC_CTX));
++        HMAC_CTX_init(ctx);
++        return ctx;
++}
++#define HMAC_CTX_free(c) if (c != NULL) OPENSSL_free(c)
++
++#define BIO_get_data(b) b->ptr
++#define BIO_set_data(b, v) b->ptr=v
++#define BIO_set_shutdown(b, v) b->shutdown=v
++#define BIO_set_init(b, v) b->init=v
++
++#endif /* OPENSSL_VERSION_NUMBER */
++
++#endif /* OPENSSL_COMPAT_H */
++
diff --git a/external/subpack/libs/ibrcommon/patches/020-openssl-deprecated.patch b/external/subpack/libs/ibrcommon/patches/020-openssl-deprecated.patch
new file mode 100644
index 0000000..e69a82f
--- /dev/null
+++ b/external/subpack/libs/ibrcommon/patches/020-openssl-deprecated.patch
@@ -0,0 +1,25 @@
+--- a/ibrcommon/ssl/TLSStream.cpp
++++ b/ibrcommon/ssl/TLSStream.cpp
+@@ -259,16 +259,22 @@ namespace ibrcommon
+ 		/* openssl initialization */
+ 		/* the if block is needed because SSL_library_init() is not reentrant */
+ 		if(!_SSL_initialized){
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ 			SSL_load_error_strings();
+ 			SSL_library_init();
+ 			ERR_load_BIO_strings();
+ 			ERR_load_SSL_strings();
++#endif
+ 			_SSL_initialized = true;
+ 		}
+ 
+ 
+ 		/* create ssl context and throw exception if it fails */
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ 		_ssl_ctx = SSL_CTX_new(TLSv1_method());
++#else
++		_ssl_ctx = SSL_CTX_new(TLS_method());
++#endif
+ 		if(!_ssl_ctx){
+ 			char err_buf[ERR_BUF_SIZE];
+ 			ERR_error_string_n(ERR_get_error(), err_buf, ERR_BUF_SIZE);
diff --git a/external/subpack/libs/ibrdtn/Makefile b/external/subpack/libs/ibrdtn/Makefile
new file mode 100644
index 0000000..a318084
--- /dev/null
+++ b/external/subpack/libs/ibrdtn/Makefile
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 2015 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:=ibrdtn
+PKG_VERSION:=1.0.1
+PKG_RELEASE:=4
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.ibr.cs.tu-bs.de/projects/ibr-dtn/releases
+PKG_HASH:=288b14ccbaefb5e3234065c2778c247797ccb3c7afbb6746bb37dc12c620d360
+PKG_MAINTAINER:=Johannes Morgenroth <jm@m-network.de>
+PKG_LICENSE:=Apache-2.0
+
+PKG_INSTALL:=1
+PKG_FIXUP:=libtool
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ibrdtn
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+ibrcommon +zlib
+  TITLE:=IBR-DTN Library
+endef
+
+define Package/ibrdtn/description
+ Base library for IBR-DTN daemon and tools.
+endef
+
+CONFIGURE_ARGS += \
+	--with-compression \
+	--without-glib
+
+TARGET_CXXFLAGS +=-std=c++11
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)
+	$(CP) $(PKG_INSTALL_DIR)/* $(1)/
+endef
+
+define Package/ibrdtn/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,ibrdtn))
diff --git a/external/subpack/libs/icu/Makefile b/external/subpack/libs/icu/Makefile
new file mode 100644
index 0000000..6ffa83c
--- /dev/null
+++ b/external/subpack/libs/icu/Makefile
@@ -0,0 +1,176 @@
+#
+# Copyright (C) 2006-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:=icu4c
+MAJOR_VERSION:=75
+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:=cb968df3e4d2e87e8b11c49a5d01c787bd13b9545280fc6642f826527618caef
+
+PKG_LICENSE:=ICU
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:icu-project:international_components_for_unicode
+
+PKG_MAINTAINER:=Hirokazu MORIKAWA <morikw2@gmail.com>
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+HOST_BUILD_PARALLEL:=1
+
+PKG_BUILD_DEPENDS:=icu/host
+HOST_BUILD_DEPENDS:=python3/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+TAR_OPTIONS+= icu/source --strip-components 2
+TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS)
+
+define Package/icu
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=International Components for Unicode
+  URL:=http://icu-project.org
+  DEPENDS:=+libstdcpp +libpthread
+  ABI_VERSION:=$(MAJOR_VERSION)
+endef
+
+define Package/icu/description
+  ICU is a mature, widely used set of C/C++ and Java libraries providing Unicode and Globalization support for software applications. ICU is widely portable and gives applications the same results on all platforms and between C/C++ and Java software.
+  This package supports C/C++.
+endef
+
+define Package/icu-full-data
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Full ICU Data
+  URL:=http://icu-project.org
+  DEPENDS:=+icu
+  ABI_VERSION:=$(MAJOR_VERSION)
+endef
+
+define Package/icu-full-data/description
+  ICU makes use of a wide variety of data tables to provide many of its services. Examples include converter mapping tables, collation rules, transliteration rules, break iterator rules and dictionaries, and other locale data.
+  This package contains the complete data library provided by ICU.
+  A custom data library can be generated at http://apps.icu-project.org/datacustom/
+endef
+
+define Package/icu-data-tools
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=ICU Data manipulation tools
+  URL:=http://icu-project.org
+  DEPENDS:=+icu
+endef
+
+define Package/icu-data-tools/description
+ This package provides tools for manipulating ICU data.
+endef
+
+CONFIGURE_CMD:= ./runConfigureICU
+CONFIGURE_ARGS:= \
+	Linux/gcc \
+	CC="$(TARGET_CC_NOCACHE)" \
+	CXX="$(TARGET_CXX_NOCACHE)" \
+	--target=$(GNU_TARGET_NAME) \
+	--host=$(GNU_TARGET_NAME) \
+	--build=$(GNU_HOST_NAME) \
+	--disable-debug \
+	--enable-release \
+	--enable-shared \
+	--enable-static \
+	--enable-draft \
+	--enable-renaming \
+	--disable-tracing \
+	--disable-extras \
+	--enable-dyload \
+	--with-data-packaging=archive \
+	--disable-tests \
+	--disable-samples \
+	--with-cross-build="$(STAGING_DIR_HOSTPKG)/share/icu/$(PKG_VERSION)" \
+	--prefix=/usr
+
+HOST_CONFIGURE_CMD:= ./runConfigureICU
+HOST_CONFIGURE_VARS:=
+ifeq ($(HOST_OS),Darwin)
+HOST_CONFIGURE_ARGS:= MacOSX
+else
+HOST_CONFIGURE_ARGS:= Linux/gcc
+endif
+HOST_CONFIGURE_ARGS+= \
+	--disable-debug \
+	--enable-release \
+	--enable-shared \
+	--enable-static \
+	--enable-draft \
+	--enable-renaming \
+	--disable-tracing \
+	--disable-extras \
+	--enable-dyload \
+	--prefix=$(STAGING_DIR_HOSTPKG)
+
+define Build/Prepare
+	$(call Build/Prepare/Default)
+	mkdir -p $(PKG_BUILD_DIR)/data/out
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_DIR) $(2)/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/icu-config $(1)/usr/bin/
+	$(SED) 's,^\(prefix\|execprefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(1)/usr/bin/icu-config
+	$(LN) $(STAGING_DIR)/usr/bin/icu-config $(2)/bin/
+endef
+
+define Host/Install
+	$(INSTALL_DIR)  $(STAGING_DIR_HOSTPKG)/share/icu/$(PKG_VERSION)/config
+	$(INSTALL_DIR)  $(STAGING_DIR_HOSTPKG)/share/icu/$(PKG_VERSION)/bin
+	$(INSTALL_DIR)  $(STAGING_DIR_HOSTPKG)/share/icu/$(PKG_VERSION)/lib
+	$(INSTALL_DATA) $(HOST_BUILD_DIR)/config/icucross.* $(STAGING_DIR_HOSTPKG)/share/icu/$(PKG_VERSION)/config/
+	$(INSTALL_BIN)  $(HOST_BUILD_DIR)/bin/icupkg $(STAGING_DIR_HOSTPKG)/share/icu/$(PKG_VERSION)/bin/
+	$(INSTALL_BIN)  $(HOST_BUILD_DIR)/bin/pkgdata $(STAGING_DIR_HOSTPKG)/share/icu/$(PKG_VERSION)/bin/
+ifeq ($(HOST_OS),Darwin)
+	$(CP)           $(HOST_BUILD_DIR)/lib/*.dylib* $(STAGING_DIR_HOSTPKG)/share/icu/$(PKG_VERSION)/lib/
+else
+	$(CP)           $(HOST_BUILD_DIR)/lib/*.so* $(STAGING_DIR_HOSTPKG)/share/icu/$(PKG_VERSION)/lib/
+endif
+	$(RM)           $(STAGING_DIR_HOSTPKG)/share/icu/current
+	(cd $(STAGING_DIR_HOSTPKG)/share/icu;$(LN) $(PKG_VERSION) current)
+endef
+
+define Package/icu/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+define Package/icu-full-data/install
+	$(INSTALL_DIR)  $(1)/usr/share/icu/$(PKG_VERSION)
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/icu/$(PKG_VERSION)/icudt*.dat \
+		$(1)/usr/share/icu/$(PKG_VERSION)/
+endef
+
+define Package/icu-data-tools/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/* $(1)/usr/sbin/
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,icu))
+$(eval $(call BuildPackage,icu-full-data))
+$(eval $(call BuildPackage,icu-data-tools))
diff --git a/external/subpack/libs/icu/patches/000-dont-cpy-files-from-topdirs.patch b/external/subpack/libs/icu/patches/000-dont-cpy-files-from-topdirs.patch
new file mode 100644
index 0000000..c77db6e
--- /dev/null
+++ b/external/subpack/libs/icu/patches/000-dont-cpy-files-from-topdirs.patch
@@ -0,0 +1,10 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -190,7 +190,6 @@ install-icu: $(INSTALLED_BUILT_FILES)
+ 	$(INSTALL_SCRIPT) $(top_srcdir)/install-sh $(DESTDIR)$(pkgdatadir)/install-sh
+ 	@$(MKINSTALLDIRS) $(DESTDIR)$(libdir)/pkgconfig
+ 	$(INSTALL_DATA) $(ALL_PKGCONFIG_FILES) $(DESTDIR)$(libdir)/pkgconfig/
+-	$(INSTALL_DATA) $(top_srcdir)/../LICENSE $(DESTDIR)$(pkgdatadir)/LICENSE
+ ifeq ($(INSTALL_ICU_CONFIG),true)
+ 	$(INSTALL_SCRIPT) $(top_builddir)/config/icu-config $(DESTDIR)$(bindir)/icu-config
+ endif
diff --git a/external/subpack/libs/icu/patches/001-change_optimization_option.patch b/external/subpack/libs/icu/patches/001-change_optimization_option.patch
new file mode 100644
index 0000000..4c088ef
--- /dev/null
+++ b/external/subpack/libs/icu/patches/001-change_optimization_option.patch
@@ -0,0 +1,13 @@
+--- a/runConfigureICU
++++ b/runConfigureICU
+@@ -255,8 +255,8 @@ case $platform in
+         THE_COMP="the GNU C++"
+         CC=gcc; export CC
+         CXX=g++; export CXX
+-        RELEASE_CFLAGS='-O3'
+-        RELEASE_CXXFLAGS='-O3'
++        RELEASE_CFLAGS=' '
++        RELEASE_CXXFLAGS=' '
+         DEBUG_CFLAGS='-g'
+         DEBUG_CXXFLAGS='-g'
+         ;;
diff --git a/external/subpack/libs/icu/patches/002-Disable-LDFLAGSICUDT-for-Linux.patch b/external/subpack/libs/icu/patches/002-Disable-LDFLAGSICUDT-for-Linux.patch
new file mode 100644
index 0000000..fd4767d
--- /dev/null
+++ b/external/subpack/libs/icu/patches/002-Disable-LDFLAGSICUDT-for-Linux.patch
@@ -0,0 +1,23 @@
+From 0c82d6aa02c08e41b13c83b14782bd7024e25d59 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sat, 15 Feb 2014 21:06:42 +0000
+Subject: [PATCH] Disable LDFLAGSICUDT for Linux
+
+Upstream-Status: Inappropriate [ OE Configuration ]
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ source/config/mh-linux |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/config/mh-linux
++++ b/config/mh-linux
+@@ -23,7 +23,7 @@ LD_RPATH= -Wl,-zorigin,-rpath,'$$'ORIGIN
+ LD_RPATH_PRE = -Wl,-rpath,
+ 
+ ## These are the library specific LDFLAGS
+-LDFLAGSICUDT=-nodefaultlibs -nostdlib
++# LDFLAGSICUDT=-nodefaultlibs -nostdlib
+ 
+ ## Compiler switch to embed a library name
+ # The initial tab in the next line is to prevent icu-config from reading it.
diff --git a/external/subpack/libs/icu/patches/010-max_align_t.patch b/external/subpack/libs/icu/patches/010-max_align_t.patch
new file mode 100644
index 0000000..5dcf568
--- /dev/null
+++ b/external/subpack/libs/icu/patches/010-max_align_t.patch
@@ -0,0 +1,60 @@
+--- a/common/uarrsort.cpp
++++ b/common/uarrsort.cpp
+@@ -37,7 +37,7 @@ enum {
+ };
+ 
+ static constexpr int32_t sizeInMaxAlignTs(int32_t sizeInBytes) {
+-    return (sizeInBytes + sizeof(std::max_align_t) - 1) / sizeof(std::max_align_t);
++    return (sizeInBytes + sizeof(max_align_t) - 1) / sizeof(max_align_t);
+ }
+ 
+ /* UComparator convenience implementations ---------------------------------- */
+@@ -141,7 +141,7 @@ static void
+ insertionSort(char *array, int32_t length, int32_t itemSize,
+               UComparator *cmp, const void *context, UErrorCode *pErrorCode) {
+ 
+-    icu::MaybeStackArray<std::max_align_t, sizeInMaxAlignTs(STACK_ITEM_SIZE)> v;
++    icu::MaybeStackArray<max_align_t, sizeInMaxAlignTs(STACK_ITEM_SIZE)> v;
+     if (sizeInMaxAlignTs(itemSize) > v.getCapacity() &&
+             v.resize(sizeInMaxAlignTs(itemSize)) == nullptr) {
+         *pErrorCode = U_MEMORY_ALLOCATION_ERROR;
+@@ -235,7 +235,7 @@ static void
+ quickSort(char *array, int32_t length, int32_t itemSize,
+             UComparator *cmp, const void *context, UErrorCode *pErrorCode) {
+     /* allocate two intermediate item variables (x and w) */
+-    icu::MaybeStackArray<std::max_align_t, sizeInMaxAlignTs(STACK_ITEM_SIZE) * 2> xw;
++    icu::MaybeStackArray<max_align_t, sizeInMaxAlignTs(STACK_ITEM_SIZE) * 2> xw;
+     if(sizeInMaxAlignTs(itemSize)*2 > xw.getCapacity() &&
+             xw.resize(sizeInMaxAlignTs(itemSize) * 2) == nullptr) {
+         *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+--- a/common/utext.cpp
++++ b/common/utext.cpp
+@@ -572,7 +572,7 @@ enum {
+ 
+ struct ExtendedUText {
+     UText               ut;
+-    std::max_align_t    extension;
++    max_align_t    extension;
+ };
+ 
+ static const UText emptyText = UTEXT_INITIALIZER;
+@@ -587,7 +587,7 @@ utext_setup(UText *ut, int32_t extraSpac
+         // We need to heap-allocate storage for the new UText
+         int32_t spaceRequired = sizeof(UText);
+         if (extraSpace > 0) {
+-            spaceRequired = sizeof(ExtendedUText) + extraSpace - sizeof(std::max_align_t);
++            spaceRequired = sizeof(ExtendedUText) + extraSpace - sizeof(max_align_t);
+         }
+         ut = (UText *)uprv_malloc(spaceRequired);
+         if (ut == nullptr) {
+--- a/tools/toolutil/toolutil.cpp
++++ b/tools/toolutil/toolutil.cpp
+@@ -267,7 +267,7 @@ struct UToolMemory {
+     char name[64];
+     int32_t capacity, maxCapacity, size, idx;
+     void *array;
+-    alignas(std::max_align_t) char staticArray[1];
++    alignas(max_align_t) char staticArray[1];
+ };
+ 
+ U_CAPI UToolMemory * U_EXPORT2
diff --git a/external/subpack/libs/inih/Makefile b/external/subpack/libs/inih/Makefile
new file mode 100644
index 0000000..2146619
--- /dev/null
+++ b/external/subpack/libs/inih/Makefile
@@ -0,0 +1,76 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=inih
+PKG_VERSION:=58
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/benhoyt/inih
+PKG_SOURCE_VERSION:=r$(PKG_VERSION)
+PKG_MIRROR_HASH:=3dcf4cfd05e5cb0228a19896635fac40d7752c4eac05578c6aaf696d387eaeb7
+
+PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE.txt
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libinih/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=https://github.com/benhoyt/inih
+endef
+
+define Package/libinih
+  $(call Package/libinih/Default)
+  TITLE:=Simple .INI file parser in C
+endef
+
+define Package/libinireader
+  $(call Package/libinih/Default)
+  TITLE:=C++ library and API for inih
+  DEPENDS:=+libinih +libstdcpp
+endef
+
+define Package/libinih/description
+  inih (INI Not Invented Here) is a simple .INI file parser written
+  in C. It's only a couple of pages of code, and it was designed to
+  be small and simple, so it's good for embedded systems. It's also
+  more or less compatible with Python's ConfigParser style of .INI
+  files, including RFC 822-style multi-line syntax and name: value
+  entries.
+endef
+
+Package/libinireader/description = $(Package/libinih/description)
+
+MESON_ARGS += \
+	-Ddefault_library=both \
+	-Ddistro_install=true \
+	-Dwith_INIReader=true \
+	-Dmulti-line_entries=true \
+	-Dutf-8_bom=true \
+	-Dinline_comments=true \
+	-Duse_heap=false
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/{ini,INIReader}.h $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/{inih,INIReader}.pc $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib{inih,INIReader}.a $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib{inih,INIReader}.so* $(1)/usr/lib/
+endef
+
+define Package/libinih/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libinih.so* $(1)/usr/lib/
+endef
+
+define Package/libinireader/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libINIReader.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libinih))
+$(eval $(call BuildPackage,libinireader))
diff --git a/external/subpack/libs/intltool/Makefile b/external/subpack/libs/intltool/Makefile
new file mode 100644
index 0000000..244f599
--- /dev/null
+++ b/external/subpack/libs/intltool/Makefile
@@ -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:=intltool
+PKG_VERSION:=0.51.0
+PKG_RELEASE:=3
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://launchpad.net/intltool/trunk/$(PKG_VERSION)/+download
+PKG_HASH:=67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+
+
+HOST_BUILD_DEPENDS:=perl/host
+PKG_HOST_ONLY:=1
+HOST_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+HOST_CONFIGURE_VARS+= \
+        PATH="$(STAGING_DIR_HOSTPKG)/bin:$(STAGING_DIR_HOSTPKG)/usr/bin:$(PATH)"
+
+define Package/intltool
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=set of tools to centralize translation using GNU gettext
+  URL:=https://www.freedesktop.org/wiki/Software/intltool
+  BUILDONLY:=1
+endef
+
+define Package/intltool/description
+  intltool is a set of tools to centralize translation of many different
+  file formats using GNU gettext-compatible PO files.
+endef
+
+$(eval $(call BuildPackage,intltool))
+$(eval $(call HostBuild))
diff --git a/external/subpack/libs/intltool/patches/100-optional-perl-xml-parser.patch b/external/subpack/libs/intltool/patches/100-optional-perl-xml-parser.patch
new file mode 100644
index 0000000..32474ba
--- /dev/null
+++ b/external/subpack/libs/intltool/patches/100-optional-perl-xml-parser.patch
@@ -0,0 +1,22 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -27,7 +27,7 @@ AC_MSG_CHECKING([for XML::Parser])
+ if `$PERL -e "require XML::Parser" 2>/dev/null`; then
+    AC_MSG_RESULT([ok])
+ else
+-   AC_MSG_ERROR([XML::Parser perl module is required for intltool])
++   AC_MSG_RESULT([XML::Parser perl module is required for intltool])
+ fi
+ AC_PATH_PROG(BZR, bzr)
+ 
+--- a/intltool.m4
++++ b/intltool.m4
+@@ -148,7 +148,7 @@ if test "x$2" != "xno-xml"; then
+    if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then
+        AC_MSG_RESULT([ok])
+    else
+-       AC_MSG_ERROR([XML::Parser perl module is required for intltool])
++       AC_MSG_RESULT([XML::Parser perl module is required for intltool])
+    fi
+ fi
+ 
diff --git a/external/subpack/libs/intltool/patches/200-intltool-0.51.0-perl-5.22.patch b/external/subpack/libs/intltool/patches/200-intltool-0.51.0-perl-5.22.patch
new file mode 100644
index 0000000..097c511
--- /dev/null
+++ b/external/subpack/libs/intltool/patches/200-intltool-0.51.0-perl-5.22.patch
@@ -0,0 +1,48 @@
+https://bugs.launchpad.net/intltool/+bug/1490906
+
+fix warnings w/newer perl:
+Unescaped left brace in regex is deprecated, passed through in regex; marked by <-- HERE in m/^(.*)\${ <-- HERE ?([A-Z_]+)}?(.*)$/ at /usr/bin/intltool-update line 1065.
+
+--- a/intltool-update.in
++++ b/intltool-update.in
+@@ -1062,7 +1062,7 @@
+ 	}
+     }
+ 
+-    if ($str =~ /^(.*)\${?([A-Z_]+)}?(.*)$/)
++    if ($str =~ /^(.*)\$\{?([A-Z_]+)}?(.*)$/)
+     {
+ 	my $rest = $3;
+ 	my $untouched = $1;
+@@ -1190,10 +1190,10 @@
+ 	$name    =~ s/\(+$//g;
+ 	$version =~ s/\(+$//g;
+ 
+-	$varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/);
+-	$varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/);
+-	$varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/);
+-	$varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/);
++	$varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\$\{?AC_PACKAGE_NAME}?/);
++	$varhash{"PACKAGE"} = $name if (not $name =~ /\$\{?PACKAGE}?/);
++	$varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\$\{?AC_PACKAGE_VERSION}?/);
++	$varhash{"VERSION"} = $version if (not $name =~ /\$\{?VERSION}?/);
+     }
+ 
+     if ($conf_source =~ /^AC_INIT\(([^,\)]+),([^,\)]+)[,]?([^,\)]+)?/m)
+@@ -1219,11 +1219,11 @@
+ 	$version =~ s/\(+$//g;
+         $bugurl  =~ s/\(+$//g if (defined $bugurl);
+ 
+-	$varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/);
+-	$varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/);
+-	$varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/);
+-	$varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/);
+-        $varhash{"PACKAGE_BUGREPORT"} = $bugurl if (defined $bugurl and not $bugurl =~ /\${?\w+}?/);
++	$varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\$\{?AC_PACKAGE_NAME}?/);
++	$varhash{"PACKAGE"} = $name if (not $name =~ /\$\{?PACKAGE}?/);
++	$varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\$\{?AC_PACKAGE_VERSION}?/);
++	$varhash{"VERSION"} = $version if (not $name =~ /\$\{?VERSION}?/);
++        $varhash{"PACKAGE_BUGREPORT"} = $bugurl if (defined $bugurl and not $bugurl =~ /\$\{?\w+}?/);
+     }
+ 
+     # \s makes this not work, why?
diff --git a/external/subpack/libs/jose/Makefile b/external/subpack/libs/jose/Makefile
new file mode 100644
index 0000000..4195197
--- /dev/null
+++ b/external/subpack/libs/jose/Makefile
@@ -0,0 +1,72 @@
+#
+# Author: Tibor Dudlák
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=jose
+PKG_VERSION:=11
+PKG_RELEASE:=6
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/latchset/$(PKG_NAME)/releases/download/v$(PKG_VERSION)/
+PKG_HASH:=e272afe7717e22790c383f3164480627a567c714ccb80c1ee96f62c9929d8225
+
+PKG_MAINTAINER:=Tibor Dudlák <tibor.dudlak@gmail.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libjose
+  SECTION:=libs
+  TITLE:=Provides a full crypto stack including key generation, signing and encryption.
+  DEPENDS:=+zlib +jansson +libopenssl +libpthread
+  URL:=https://github.com/latchset/jose
+endef
+
+define Package/jose
+  SECTION:=utils
+  TITLE:=Provides a full crypto stack including key generation, signing and encryption.
+  DEPENDS:=+libjose
+  URL:=https://github.com/latchset/jose
+endef
+
+define Package/jose/description
+	jose is a command line utility for performing various tasks on JSON
+	Object Signing and Encryption (JOSE) objects. José provides a full
+	crypto stack including key generation, signing and encryption.
+endef
+
+define Package/libjose/description
+	libjose is a library for performing various tasks on JSON
+	Object Signing and Encryption (JOSE) objects. José provides a full
+	crypto stack including key generation, signing and encryption.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR)	$(1)/usr/lib
+	$(INSTALL_DIR)  $(1)/usr/include
+	$(INSTALL_DIR)	$(1)/usr/include/$(PKG_NAME)
+	$(INSTALL_DIR)	$(1)/usr/lib/pkgconfig
+	$(CP)	$(PKG_INSTALL_DIR)/usr/lib/lib$(PKG_NAME).so*	$(1)/usr/lib
+	$(CP)	$(PKG_INSTALL_DIR)/usr/include/$(PKG_NAME)/*.h	$(1)/usr/include/$(PKG_NAME)
+	$(CP)	$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc	$(1)/usr/lib/pkgconfig
+endef
+
+define Package/libjose/install
+	$(INSTALL_DIR)	$(1)/usr/lib
+	$(CP)		$(PKG_INSTALL_DIR)/usr/lib/lib$(PKG_NAME).so*	$(1)/usr/lib/
+endef
+
+define Package/jose/install
+	$(INSTALL_DIR)  $(1)/usr/bin
+	$(INSTALL_BIN)  $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME)          $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libjose))
+$(eval $(call BuildPackage,jose))
diff --git a/external/subpack/libs/json-glib/Makefile b/external/subpack/libs/json-glib/Makefile
new file mode 100644
index 0000000..1b5aac8
--- /dev/null
+++ b/external/subpack/libs/json-glib/Makefile
@@ -0,0 +1,78 @@
+#
+# Copyright (C) 2020 Sebastian Kemper <sebastian_ml@gmx.net>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=json-glib
+PKG_VERSION:=1.8.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@GNOME/json-glib/$(basename $(PKG_VERSION))
+PKG_HASH:=97ef5eb92ca811039ad50a65f06633f1aae64792789307be7170795d8b319454
+
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Sebastian Kemper <sebastian_ml@gmx.net>
+
+PKG_BUILD_DEPENDS:=glib2/host
+
+OPENWRT_VERBOSE:=c
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/json-glib
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=JSON GLib Library
+  URL:=https://wiki.gnome.org/Projects/JsonGlib
+  DEPENDS:=+glib2
+  ABI_VERSION:=0
+endef
+
+define Package/json-glib/description
+JSON-GLib is a library providing serialization and deserialization
+support for the JavaScript Object Notation (JSON) format described by
+RFC 4627.
+endef
+
+MESON_ARGS += \
+	-Dgtk_doc=disabled \
+	-Dintrospection=disabled \
+	-Dtests=false
+
+define Build/Prepare
+	$(call Build/Prepare/Default)
+ifeq ($(QUILT),)
+	$(SED) '/error=format=2/d' $(PKG_BUILD_DIR)/meson.build
+endif
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/json-glib-1.0/json-glib
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/include/json-glib-1.0/json-glib/*.h \
+				$(1)/usr/include/json-glib-1.0/json-glib
+	
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libjson-glib-1.0.so* \
+						$(1)/usr/lib
+	
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/json-glib-1.0.pc \
+					$(1)/usr/lib/pkgconfig
+endef
+
+define Package/json-glib/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libjson-glib-1.0.so.$(ABI_VERSION)* \
+						$(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,json-glib))
diff --git a/external/subpack/libs/jsoncpp/Makefile b/external/subpack/libs/jsoncpp/Makefile
new file mode 100644
index 0000000..28aedac
--- /dev/null
+++ b/external/subpack/libs/jsoncpp/Makefile
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2019 Daniel Engberg <daniel.engberg.lists@pyret.net>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=jsoncpp
+PKG_VERSION:=1.9.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/open-source-parsers/jsoncpp/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=f409856e5920c18d0c2fb85276e24ee607d2a09b5e7d5f0a371368903c275da2
+
+PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec1@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:jsoncpp_project:jsoncpp
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/jsoncpp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=jsoncpp
+  URL:=https://github.com/open-source-parsers/jsoncpp
+  DEPENDS:=+libstdcpp
+endef
+
+define Package/jsoncpp/description
+  JsonCpp is a C++ library that allows manipulating
+  JSON values, including serialization and
+  deserialization to and from strings. It can also
+  preserve existing comment in
+  unserialization/serialization steps, making it a
+  convenient format to store user input files.
+endef
+
+MESON_ARGS += \
+	-Db_lto=true \
+	-Dtests=false
+
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/json $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libjsoncpp.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/jsoncpp.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/jsoncpp/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libjsoncpp.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,jsoncpp))
diff --git a/external/subpack/libs/ldns/Makefile b/external/subpack/libs/ldns/Makefile
new file mode 100644
index 0000000..3711b31
--- /dev/null
+++ b/external/subpack/libs/ldns/Makefile
@@ -0,0 +1,133 @@
+#
+# Copyright (C) 2011-2015 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:=ldns
+PKG_VERSION:=1.8.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.nlnetlabs.nl/downloads/ldns
+PKG_HASH:=c3f72dd1036b2907e3a56e6acf9dfb2e551256b3c1bbd9787942deeeb70e7860
+
+PKG_MAINTAINER:=Eric Luehrsen <ericluehrsen@gmail.com>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:nlnetlabs:ldns
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libldns/Default
+  URL:=http://www.nlnetlabs.nl/projects/ldns/
+  DEPENDS:=+libopenssl
+endef
+
+define Package/libldns
+  $(call Package/libldns/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A library to simplify DNS programming
+endef
+
+define Package/libldns/description
+  The goal of ldns is to simplify DNS programming, it supports recent RFCs like
+  the DNSSEC documents, and allows developers to easily create software
+  conforming to current RFCs, and experimental software for current Internet
+  Drafts.
+endef
+
+define Package/drill
+  $(call Package/libldns/Default)
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=IP Addresses and Names
+  TITLE:=DNS(SEC) information tool
+  DEPENDS+= +libldns
+endef
+
+define Package/drill/description
+  ldns includes the drill tool, which is much like dig from BIND. It was
+  designed with DNSSEC in mind and should be a useful debugging/query tool
+  for DNSSEC.
+endef
+
+define Package/ldns-examples
+  $(call Package/libldns/Default)
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=IP Addresses and Names
+  TITLE:=Example programs from NLNetLabs ldns library
+  DEPENDS+= +libldns +libpcap +drill
+endef
+
+define Package/ldns-examples/description
+  A few example programs are included in the source of ldns. They include tools
+  which can create DNSSEC keys and DNSSEC zone files.
+endef
+
+CONFIGURE_ARGS += \
+	--disable-dsa \
+	--disable-gost \
+	--enable-ecdsa \
+	--with-drill \
+	--with-examples \
+	--with-ssl="$(STAGING_DIR)/usr"
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/ldns $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libldns.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_BUILD_DIR)/packaging/libldns.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/libldns/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libldns.so.* $(1)/usr/lib/
+endef
+
+define Package/drill/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/drill $(1)/usr/bin/
+endef
+
+define Package/ldns-examples/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-chaos $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-compare-zones $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-dane $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-dpa $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-gen-zone $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-key2ds $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-keyfetcher $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-keygen $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-mx $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-notify $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-nsec3-hash $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-read-zone $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-revoke $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-rrsig $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-signzone $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-test-edns $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-testns $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-update $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-verify-zone $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-version $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-walk $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-zcat $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldns-zsplit $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libldns))
+$(eval $(call BuildPackage,drill))
+$(eval $(call BuildPackage,ldns-examples))
diff --git a/external/subpack/libs/leptonica/Makefile b/external/subpack/libs/leptonica/Makefile
new file mode 100644
index 0000000..ac33d81
--- /dev/null
+++ b/external/subpack/libs/leptonica/Makefile
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2019 Valentín Kivachuk <vk18496@gmail.com>
+#
+# This is free software, licensed under the GNU General Public License v3.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=leptonica
+PKG_VERSION:=1.84.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.leptonica.org/source/
+PKG_HASH:=2b3e1254b1cca381e77c819b59ca99774ff43530209b9aeb511e1d46588a64f6
+
+PKG_MAINTAINER:=Valentín Kivachuk <vk18496@gmail.com>
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=leptonica-license.txt
+PKG_CPE_ID:=cpe:/a:leptonica:leptonica
+
+CMAKE_BINARY_SUBDIR:=openwrt-build
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libleptonica
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A library for efficient image processing and image analysis operations
+  URL:=http://www.leptonica.org/
+  DEPENDS:=+giflib +libjpeg +libpng +libtiff +libwebp +zlib
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_SHARED_LIBS=ON \
+	-DENABLE_OPENJPEG=OFF \
+	-DWEBPMUX_INCLUDE_DIR=$(STAGING_DIR)/usr/include
+
+TARGET_CFLAGS:=$(filter-out -O%,$(TARGET_CFLAGS)) -O3
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/leptonica
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/leptonica/*.h $(1)/usr/include/leptonica/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libleptonica.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/cmake
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/cmake/leptonica/*.cmake $(1)/usr/lib/cmake/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/lept_Release.pc $(1)/usr/lib/pkgconfig/lept.pc
+endef
+
+define Package/libleptonica/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libleptonica.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libleptonica))
diff --git a/external/subpack/libs/libaio/Makefile b/external/subpack/libs/libaio/Makefile
new file mode 100644
index 0000000..4415393
--- /dev/null
+++ b/external/subpack/libs/libaio/Makefile
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2007-2014 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:=libaio
+PKG_VERSION:=0.3.113
+PKG_RELEASE:=3
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://releases.pagure.org/libaio
+PKG_HASH:=2c44d1c5fd0d43752287c9ae1eb9c023f04ef848ea8d4aafa46e9aedb678200b
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=LGPL-2.1-only
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libaio_project:libaio
+
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=no-mips16 no-lto
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libaio
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Linux kernel AIO interface access library
+  URL:=http://lse.sourceforge.net/io/aio.html
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libaio.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libaio.{a,so*} $(1)/usr/lib/
+endef
+
+define Package/libaio/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libaio.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libaio))
diff --git a/external/subpack/libs/libaio/patches/001_arches.patch b/external/subpack/libs/libaio/patches/001_arches.patch
new file mode 100644
index 0000000..569c9a1
--- /dev/null
+++ b/external/subpack/libs/libaio/patches/001_arches.patch
@@ -0,0 +1,135 @@
+Description: Add/fix support for m68k, mips, paris, sparc
+Author: Guillem Jover <guillem@debian.org>
+Origin: vendor
+Forwarded: no
+Last-Update: 2014-10-09
+
+
+---
+ harness/main.c       |   10 +++++++++
+ src/libaio.h         |    1 
+ src/syscall-m68k.h   |    5 ++++
+ src/syscall-mips.h   |   54 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/syscall-parisc.h |    6 +++++
+ src/syscall.h        |    6 +++++
+ 6 files changed, 82 insertions(+)
+
+--- /dev/null
++++ b/src/syscall-m68k.h
+@@ -0,0 +1,5 @@
++#define __NR_io_setup		241
++#define __NR_io_destroy		242
++#define __NR_io_getevents	243
++#define __NR_io_submit		244
++#define __NR_io_cancel		245
+--- a/src/syscall.h
++++ b/src/syscall.h
+@@ -27,6 +27,12 @@
+ #include "syscall-arm.h"
+ #elif defined(__sparc__)
+ #include "syscall-sparc.h"
++#elif defined(__m68k__)
++#include "syscall-m68k.h"
++#elif defined(__hppa__)
++#include "syscall-parisc.h"
++#elif defined(__mips__)
++#include "syscall-mips.h"
+ #elif defined(__aarch64__) || defined(__loongarch__) || defined(__riscv)
+ #include "syscall-generic.h"
+ #else
+--- /dev/null
++++ b/src/syscall-mips.h
+@@ -0,0 +1,54 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
++ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
++ */
++
++#ifndef _MIPS_SIM_ABI32
++#define _MIPS_SIM_ABI32			1
++#define _MIPS_SIM_NABI32		2
++#define _MIPS_SIM_ABI64			3
++#endif
++
++#if _MIPS_SIM == _MIPS_SIM_ABI32
++
++/*
++ * Linux o32 style syscalls are in the range from 4000 to 4999.
++ */
++#define __NR_Linux			4000
++#define __NR_io_setup			(__NR_Linux + 241)
++#define __NR_io_destroy			(__NR_Linux + 242)
++#define __NR_io_getevents		(__NR_Linux + 243)
++#define __NR_io_submit			(__NR_Linux + 244)
++#define __NR_io_cancel			(__NR_Linux + 245)
++
++#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
++
++#if _MIPS_SIM == _MIPS_SIM_ABI64
++
++/*
++ * Linux 64-bit syscalls are in the range from 5000 to 5999.
++ */
++#define __NR_Linux			5000
++#define __NR_io_setup			(__NR_Linux + 200)
++#define __NR_io_destroy			(__NR_Linux + 201)
++#define __NR_io_getevents		(__NR_Linux + 202)
++#define __NR_io_submit			(__NR_Linux + 203)
++#define __NR_io_cancel			(__NR_Linux + 204)
++#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
++
++#if _MIPS_SIM == _MIPS_SIM_NABI32
++
++/*
++ * Linux N32 syscalls are in the range from 6000 to 6999.
++ */
++#define __NR_Linux			6000
++#define __NR_io_setup			(__NR_Linux + 200)
++#define __NR_io_destroy			(__NR_Linux + 201)
++#define __NR_io_getevents		(__NR_Linux + 202)
++#define __NR_io_submit			(__NR_Linux + 203)
++#define __NR_io_cancel			(__NR_Linux + 204)
++#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
+--- a/src/libaio.h
++++ b/src/libaio.h
+@@ -74,6 +74,7 @@ typedef enum io_iocb_cmd {
+ 
+ /* big endian, 64 bits */
+ #elif defined(__powerpc64__) || defined(__s390x__) || \
++      (defined(__hppa__) && defined(__arch64__)) || \
+       (defined(__sparc__) && defined(__arch64__)) || \
+       (defined(__aarch64__) && defined(__AARCH64EB__)) || \
+       (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
+--- /dev/null
++++ b/src/syscall-parisc.h
+@@ -0,0 +1,6 @@
++#define __NR_Linux                0
++#define __NR_io_setup           (__NR_Linux + 215)
++#define __NR_io_destroy         (__NR_Linux + 216)
++#define __NR_io_getevents       (__NR_Linux + 217)
++#define __NR_io_submit          (__NR_Linux + 218)
++#define __NR_io_cancel          (__NR_Linux + 219)
+--- a/harness/main.c
++++ b/harness/main.c
+@@ -12,7 +12,17 @@
+ #include <libaio.h>
+ 
+ #if __LP64__ == 0
++#if defined(__i386__) || defined(__powerpc__) || defined(__mips__)
+ #define KERNEL_RW_POINTER	((void *)0xc0010000)
++#elif defined(__arm__) || defined(__m68k__) || defined(__s390__)
++#define KERNEL_RW_POINTER	((void *)0x00010000)
++#elif defined(__hppa__)
++#define KERNEL_RW_POINTER	((void *)0x10100000)
++#elif defined(__sparc__)
++#define KERNEL_RW_POINTER	((void *)0xf0010000)
++#else
++#error Unknown kernel memory address.
++#endif
+ #else
+ //#warning Not really sure where kernel memory is.  Guessing.
+ #define KERNEL_RW_POINTER	((void *)0xffffffff81000000)
diff --git a/external/subpack/libs/libaio/patches/002_arches_sh.patch b/external/subpack/libs/libaio/patches/002_arches_sh.patch
new file mode 100644
index 0000000..db6abea
--- /dev/null
+++ b/external/subpack/libs/libaio/patches/002_arches_sh.patch
@@ -0,0 +1,66 @@
+Author: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+Description: Add SH supprt
+ The test-suite logs can be found at:
+ .
+ <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=535288>
+
+
+---
+ harness/main.c   |    2 +-
+ src/libaio.h     |    4 +++-
+ src/syscall-sh.h |    6 ++++++
+ src/syscall.h    |    2 ++
+ 4 files changed, 12 insertions(+), 2 deletions(-)
+
+
+--- a/harness/main.c
++++ b/harness/main.c
+@@ -14,7 +14,7 @@
+ #if __LP64__ == 0
+ #if defined(__i386__) || defined(__powerpc__) || defined(__mips__)
+ #define KERNEL_RW_POINTER	((void *)0xc0010000)
+-#elif defined(__arm__) || defined(__m68k__) || defined(__s390__)
++#elif defined(__arm__) || defined(__m68k__) || defined(__s390__) || defined(__sh__)
+ #define KERNEL_RW_POINTER	((void *)0x00010000)
+ #elif defined(__hppa__)
+ #define KERNEL_RW_POINTER	((void *)0x10100000)
+--- a/src/libaio.h
++++ b/src/libaio.h
+@@ -52,7 +52,8 @@ typedef enum io_iocb_cmd {
+ 
+ /* little endian, 32 bits */
+ #if defined(__i386__) || (defined(__arm__) && !defined(__ARMEB__)) || \
+-    defined(__sh__) || defined(__bfin__) || defined(__MIPSEL__) || \
++    (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \
++    defined(__bfin__) || defined(__MIPSEL__) || \
+     defined(__cris__) || defined(__loongarch32) || \
+     (defined(__riscv) && __riscv_xlen == 32) || \
+     (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
+@@ -86,6 +87,7 @@ typedef enum io_iocb_cmd {
+ /* big endian, 32 bits */
+ #elif defined(__PPC__) || defined(__s390__) || \
+       (defined(__arm__) && defined(__ARMEB__)) || \
++      (defined(__sh__) && defined (__BIG_ENDIAN__)) || \
+       defined(__sparc__) || defined(__MIPSEB__) || defined(__m68k__) || \
+       defined(__hppa__) || defined(__frv__) || defined(__avr32__) || \
+       (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
+--- /dev/null
++++ b/src/syscall-sh.h
+@@ -0,0 +1,6 @@
++/* Copy from ./arch/sh/include/asm/unistd_32.h */
++#define __NR_io_setup       245
++#define __NR_io_destroy     246
++#define __NR_io_getevents   247
++#define __NR_io_submit      248
++#define __NR_io_cancel      249
+--- a/src/syscall.h
++++ b/src/syscall.h
+@@ -33,6 +33,8 @@
+ #include "syscall-parisc.h"
+ #elif defined(__mips__)
+ #include "syscall-mips.h"
++#elif defined(__sh__)
++#include "syscall-sh.h"
+ #elif defined(__aarch64__) || defined(__loongarch__) || defined(__riscv)
+ #include "syscall-generic.h"
+ #else
diff --git a/external/subpack/libs/libaio/patches/003_arches_mips_fix_padding.patch b/external/subpack/libs/libaio/patches/003_arches_mips_fix_padding.patch
new file mode 100644
index 0000000..539d236
--- /dev/null
+++ b/external/subpack/libs/libaio/patches/003_arches_mips_fix_padding.patch
@@ -0,0 +1,38 @@
+Description: Fix structure padding for mips64
+Author: Guillem Jover <guillem@debian.org>
+Forwarded: no
+Last-Update: 2014-07-23
+
+
+---
+ src/libaio.h |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/src/libaio.h
++++ b/src/libaio.h
+@@ -53,7 +53,8 @@ typedef enum io_iocb_cmd {
+ /* little endian, 32 bits */
+ #if defined(__i386__) || (defined(__arm__) && !defined(__ARMEB__)) || \
+     (defined(__sh__) && defined(__LITTLE_ENDIAN__)) || \
+-    defined(__bfin__) || defined(__MIPSEL__) || \
++    defined(__bfin__) || \
++    (defined(__MIPSEL__) && !defined(__mips64)) || \
+     defined(__cris__) || defined(__loongarch32) || \
+     (defined(__riscv) && __riscv_xlen == 32) || \
+     (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
+@@ -64,6 +65,7 @@ typedef enum io_iocb_cmd {
+ 
+ /* little endian, 64 bits */
+ #elif defined(__ia64__) || defined(__x86_64__) || defined(__alpha__) || \
++      (defined(__mips64) && defined(__MIPSEL__)) || \
+       (defined(__aarch64__) && defined(__AARCH64EL__)) || \
+       defined(__loongarch64) || \
+       (defined(__riscv) && __riscv_xlen == 64) || \
+@@ -77,6 +79,7 @@ typedef enum io_iocb_cmd {
+ #elif defined(__powerpc64__) || defined(__s390x__) || \
+       (defined(__hppa__) && defined(__arch64__)) || \
+       (defined(__sparc__) && defined(__arch64__)) || \
++      (defined(__mips64) && defined(__MIPSEB__)) || \
+       (defined(__aarch64__) && defined(__AARCH64EB__)) || \
+       (defined(__GNUC__) && defined(__BYTE_ORDER__) && \
+            __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_LONG__ == 8)
diff --git a/external/subpack/libs/libaio/patches/004_arches_x32.patch b/external/subpack/libs/libaio/patches/004_arches_x32.patch
new file mode 100644
index 0000000..22d3d9b
--- /dev/null
+++ b/external/subpack/libs/libaio/patches/004_arches_x32.patch
@@ -0,0 +1,43 @@
+Description: Add support for x32 (from the Yocto project)
+Author: Daniel Schepler <dschepler@gmail.com>
+Origin: vendor
+Forwarded: no
+Bug-Debian: 702183
+Last-Update: 2013-05-06
+
+
+---
+ harness/main.c       |    2 +-
+ src/syscall-x86_64.h |   10 ++++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+--- a/src/syscall-x86_64.h
++++ b/src/syscall-x86_64.h
+@@ -1,6 +1,16 @@
++#ifndef __NR_io_setup
+ #define __NR_io_setup		206
++#endif
++#ifndef __NR_io_destroy
+ #define __NR_io_destroy		207
++#endif
++#ifndef __NR_io_getevents
+ #define __NR_io_getevents	208
++#endif
++#ifndef __NR_io_submit
+ #define __NR_io_submit		209
++#endif
++#ifndef __NR_io_cancel
+ #define __NR_io_cancel		210
++#endif
+ #define __NR_io_pgetevents	333
+--- a/harness/main.c
++++ b/harness/main.c
+@@ -14,7 +14,7 @@
+ #if __LP64__ == 0
+ #if defined(__i386__) || defined(__powerpc__) || defined(__mips__)
+ #define KERNEL_RW_POINTER	((void *)0xc0010000)
+-#elif defined(__arm__) || defined(__m68k__) || defined(__s390__) || defined(__sh__)
++#elif defined(__arm__) || defined(__m68k__) || defined(__s390__) || defined(__sh__) || defined(__x86_64__)
+ #define KERNEL_RW_POINTER	((void *)0x00010000)
+ #elif defined(__hppa__)
+ #define KERNEL_RW_POINTER	((void *)0x10100000)
diff --git a/external/subpack/libs/libantlr3c/Makefile b/external/subpack/libs/libantlr3c/Makefile
new file mode 100644
index 0000000..c7a52e7
--- /dev/null
+++ b/external/subpack/libs/libantlr3c/Makefile
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2006-2014 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:=libantlr3c
+PKG_VERSION:=3.4
+PKG_RELEASE:=1
+PKG_HASH:=ca914a97f1a2d2f2c8e1fca12d3df65310ff0286d35c48b7ae5f11dcc8b2eb52
+
+PKG_SOURCE_URL:=https://www.antlr3.org/download/C
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+PKG_MAINTAINER:=Espen Jürgensen <espenjurgensen+openwrt@gmail.com>
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libantlr3c
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libantlr3c
+  URL:=https://www.antlr3.org/
+endef
+
+define Package/libantlr3c/description
+  ANother Tool for Language Recognition, is a language tool that provides a framework for constructing recognizers,
+  interpreters, compilers, and translators from grammatical descriptions containing actions in a variety of target languages.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libantlr3c.{a,so} $(1)/usr/lib/
+endef
+
+define Package/libantlr3c/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libantlr3c.so  $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libantlr3c))
diff --git a/external/subpack/libs/libao/Makefile b/external/subpack/libs/libao/Makefile
new file mode 100644
index 0000000..1f0e3cc
--- /dev/null
+++ b/external/subpack/libs/libao/Makefile
@@ -0,0 +1,68 @@
+#
+# Copyright (C) 2006-2014 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:=libao
+PKG_VERSION:=1.2.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://downloads.xiph.org/releases/ao/
+PKG_HASH:=03ad231ad1f9d64b52474392d63c31197b0bc7bd416e58b1c10a329a5ed89caf
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:xiph:libao
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libao
+  SECTION:=libs
+  DEPENDS:=+alsa-lib
+  CATEGORY:=Libraries
+  TITLE:=A cross platform audio library
+  URL:=http://www.xiph.org/ao/
+endef
+
+define Package/libao/description
+	Libao is a cross-platform audio library that allows programs to
+	output audio using a simple API on a wide variety of platforms.
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--disable-esd \
+	--disable-arts \
+	--disable-nas \
+	--disable-pulse
+
+TARGET_CFLAGS += $(FPIC)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/ao $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libao.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/ao.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libao/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libao.so.* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/ao/plugins-4
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/ao/plugins-4/lib*.so $(1)/usr/lib/ao/plugins-4/
+endef
+
+$(eval $(call BuildPackage,libao))
diff --git a/external/subpack/libs/libao/patches/010-CVE-2017-11548.patch b/external/subpack/libs/libao/patches/010-CVE-2017-11548.patch
new file mode 100644
index 0000000..e376e0c
--- /dev/null
+++ b/external/subpack/libs/libao/patches/010-CVE-2017-11548.patch
@@ -0,0 +1,184 @@
+From d5221655dfd1a2156aa6be83b5aadea7c1e0f5bd Mon Sep 17 00:00:00 2001
+From: Ron <ron@debian.org>
+Date: Sat, 13 Jan 2018 20:19:20 +1030
+Subject: [PATCH] Check memory allocations for success
+
+Adds some missing checks spotted by eye in a visual review while looking
+into the details of https://bugs.debian.org/870608
+---
+ src/audio_out.c                | 58 +++++++++++++++++++++++++---------
+ src/plugins/macosx/ao_macosx.c |  2 +-
+ src/plugins/sndio/ao_sndio.c   |  3 ++
+ 3 files changed, 47 insertions(+), 16 deletions(-)
+
+--- a/src/audio_out.c
++++ b/src/audio_out.c
+@@ -634,6 +634,10 @@ static char *_sanitize_matrix(int maxcha
+     char *ret = calloc(strlen(matrix)+1,1); /* can only get smaller */
+     char *p=matrix;
+     int count=0;
++
++    if(!ret)
++      return NULL;
++
+     while(count<maxchannels){
+       char *h,*t;
+       int m=0;
+@@ -707,6 +711,15 @@ static int _find_channel(int needle, cha
+   return -1;
+ }
+ 
++static void _free_map(char **m){
++  char **in=m;
++  while(m && *m){
++    free(*m);
++    m++;
++  }
++  if(in)free(in);
++}
++
+ static char **_tokenize_matrix(char *matrix){
+   char **ret=NULL;
+   char *p=matrix;
+@@ -731,6 +744,8 @@ static char **_tokenize_matrix(char *mat
+   }
+ 
+   ret = calloc(count+1,sizeof(*ret));
++  if(!ret)
++    return NULL;
+ 
+   p=matrix;
+   count=0;
+@@ -749,6 +764,10 @@ static char **_tokenize_matrix(char *mat
+     while(t>p && isspace(*(t-1)))t--;
+ 
+     ret[count] = calloc(t-p+1,1);
++    if(!ret[count]){
++      _free_map(ret);
++      return NULL;
++    }
+     memcpy(ret[count],p,t-p);
+     count++;
+     if(!*h)break;
+@@ -756,16 +775,6 @@ static char **_tokenize_matrix(char *mat
+   }
+ 
+   return ret;
+-
+-}
+-
+-static void _free_map(char **m){
+-  char **in=m;
+-  while(m && *m){
+-    free(*m);
+-    m++;
+-  }
+-  if(in)free(in);
+ }
+ 
+ static unsigned int _matrix_to_channelmask(int ch, char *matrix, char *premap, int **mout){
+@@ -773,7 +782,14 @@ static unsigned int _matrix_to_channelma
+   char *p=matrix;
+   int *perm=(*mout=malloc(ch*sizeof(*mout)));
+   int i;
+-  char **map = _tokenize_matrix(premap);
++  char **map;
++
++  if(!perm)
++    return 0;
++
++  map = _tokenize_matrix(premap);
++  if(!map)
++    return 0;
+ 
+   for(i=0;i<ch;i++) perm[i] = -1;
+   i=0;
+@@ -811,6 +827,9 @@ static char *_channelmask_to_matrix(unsi
+   char buffer[257]={0};
+   char **map = _tokenize_matrix(premap);
+ 
++  if(!map)
++    return NULL;
++
+   while(map[m]){
+     if(mask & (1<<m)){
+       if(count)
+@@ -850,6 +869,9 @@ static char *_matrix_intersect(char *mat
+   int count=0;
+   char **map = _tokenize_matrix(premap);
+ 
++  if(!map)
++    return NULL;
++
+   while(1){
+     char *h=p;
+     int m=0;
+@@ -1040,7 +1062,7 @@ static ao_device* _open_device(int drive
+                                                          device->output_matrix,
+                                                          &device->input_map);
+               int channels = _channelmask_bits(mask);
+-              if(channels<0){
++              if(channels<=0){
+                 aerror("Unable to map any channels from input matrix to output");
+                 errno = AO_EBADFORMAT;
+                 goto error;
+@@ -1061,7 +1083,7 @@ static ao_device* _open_device(int drive
+                                                          device->output_matrix,
+                                                          &device->input_map);
+               int channels = _channelmask_bits(mask);
+-              if(channels<0){
++              if(channels<=0){
+                 aerror("Unable to map any channels from input matrix to output");
+                 errno = AO_EBADFORMAT;
+                 goto error;
+@@ -1112,6 +1134,10 @@ static ao_device* _open_device(int drive
+             int count=0;
+             device->inter_permute = calloc(device->output_channels,sizeof(int));
+ 
++            if (!device->inter_permute) {
++              errno = AO_EFAIL;
++              goto error;
++            }
+             adebug("\n");
+ 
+             while(count<device->output_channels){
+@@ -1158,8 +1184,10 @@ static ao_device* _open_device(int drive
+                 for(i=0;i<device->output_channels;i++)
+                   if(device->inter_permute[i]==j)break;
+                 if(i==device->output_channels){
+-                  adebug("input %d (%s)\t -> none\n",
+-                         j,inch[j]);
++                  if(inch){
++                    adebug("input %d (%s)\t -> none\n",
++                           j,inch[j]);
++                  }
+                   unflag=1;
+                 }
+               }
+--- a/src/plugins/macosx/ao_macosx.c
++++ b/src/plugins/macosx/ao_macosx.c
+@@ -592,11 +592,11 @@ int ao_plugin_open(ao_device *device, ao
+   internal->firstValidByteOffset = 0;
+   internal->validByteCount = 0;
+   internal->buffer = malloc(internal->bufferByteCount);
+-  memset(internal->buffer, 0, internal->bufferByteCount);
+   if (!internal->buffer) {
+     aerror("Unable to allocate queue buffer.\n");
+     return 0;
+   }
++  memset(internal->buffer, 0, internal->bufferByteCount);
+ 
+   /* limited to stereo for now */
+   //if(!device->output_matrix)
+--- a/src/plugins/sndio/ao_sndio.c
++++ b/src/plugins/sndio/ao_sndio.c
+@@ -67,6 +67,9 @@ int ao_plugin_device_init(ao_device *dev
+ {
+   ao_sndio_internal *internal;
+   internal = (ao_sndio_internal *) calloc(1,sizeof(*internal));
++  if (internal == NULL)
++    return 0;
++
+   internal->id=-1;
+   device->internal = internal;
+   device->output_matrix_order = AO_OUTPUT_MATRIX_FIXED;
diff --git a/external/subpack/libs/libarchive/Makefile b/external/subpack/libs/libarchive/Makefile
new file mode 100644
index 0000000..a0a82a0
--- /dev/null
+++ b/external/subpack/libs/libarchive/Makefile
@@ -0,0 +1,130 @@
+#
+# Copyright (C) 2014 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:=libarchive
+PKG_VERSION:=3.7.4
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://www.libarchive.org/downloads
+PKG_HASH:=f887755c434a736a609cbd28d87ddbfbe9d6a3bb5b703c22c02f6af80a802735
+
+PKG_MAINTAINER:=Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libarchive:libarchive
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libarchive/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+zlib +liblzma +libbz2 +libexpat
+  TITLE:=Multi-format archive and compression library
+  URL:=https://www.libarchive.org/
+endef
+
+define Package/libarchive
+  $(call Package/libarchive/Default)
+  DEPENDS += +libopenssl
+  CONFLICTS:=libarchive-noopenssl
+endef
+
+define Package/libarchive-noopenssl
+  $(call Package/libarchive/Default)
+  TITLE += (without OpenSSL dependency)
+  VARIANT:=noopenssl
+endef
+
+define Package/bsdtar/Default
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Compression
+  TITLE:=tar BSD variant
+  URL:=https://www.libarchive.org/
+endef
+
+define Package/bsdtar
+  $(call Package/bsdtar/Default)
+  DEPENDS:= +libarchive
+  CONFLICTS:=bsdtar-noopenssl
+endef
+
+define Package/bsdtar-noopenssl
+  $(call Package/bsdtar/Default)
+  TITLE += (without OpenSSL dependency)
+  DEPENDS:= +libarchive-noopenssl
+  VARIANT:=noopenssl
+endef
+
+define Package/bsdtar/description
+  Reads a variety of formats including tar, pax, zip, xar, lha, ar,
+  cab, mtree, rar, warc, 7z and ISO images. Writes tar, pax, zip,
+  xar, ar, ISO, mtree and shar archives. Automatically handles
+  archives compressed with gzip, bzip2, lzip, xz, lzma or compress.
+endef
+
+CMAKE_OPTIONS += \
+	-DENABLE_LIBB2=OFF \
+	-DENABLE_LZ4=OFF \
+	\
+	-DENABLE_ZSTD=OFF \
+	-DENABLE_LIBXML2=OFF \
+	-DENABLE_PCREPOSIX=OFF \
+	-DENABLE_PCRE2POSIX=OFF \
+	-DENABLE_LibGCC=OFF \
+	-DENABLE_CNG=OFF \
+	\
+	-DENABLE_TAR_SHARED=ON \
+	-DENABLE_CPIO=OFF \
+	-DENABLE_CAT=OFF \
+	-DENABLE_XATTR=OFF \
+	-DENABLE_ACL=OFF \
+	-DENABLE_ICONV=OFF \
+	-DENABLE_TEST=OFF
+
+ifeq ($(BUILD_VARIANT),noopenssl)
+	CMAKE_OPTIONS += -DENABLE_OPENSSL=OFF
+else
+	CMAKE_OPTIONS += -DENABLE_OPENSSL=ON
+endif
+
+EXTRA_CFLAGS += "-I$(PKG_BUILD_DIR)/extra-includes"
+
+define Build/Configure
+	$(INSTALL_DIR) $(PKG_BUILD_DIR)/extra-includes/
+	$(CP) -R $(STAGING_DIR_HOST)/include/ext2fs $(PKG_BUILD_DIR)/extra-includes/
+	$(Build/Configure/Default)
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+endef
+
+define Package/libarchive/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so.* $(1)/usr/lib/
+endef
+
+define Package/bsdtar/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/bsdtar $(1)/usr/bin
+endef
+
+Package/libarchive-noopenssl/install = $(Package/libarchive/install)
+Package/bsdtar-noopenssl/install = $(Package/bsdtar/install)
+
+$(eval $(call BuildPackage,libarchive))
+$(eval $(call BuildPackage,libarchive-noopenssl))
+$(eval $(call BuildPackage,bsdtar))
+$(eval $(call BuildPackage,bsdtar-noopenssl))
diff --git a/external/subpack/libs/libassuan/Makefile b/external/subpack/libs/libassuan/Makefile
new file mode 100644
index 0000000..48245e2
--- /dev/null
+++ b/external/subpack/libs/libassuan/Makefile
@@ -0,0 +1,73 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libassuan
+PKG_VERSION:=2.5.6
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://gnupg.org/ftp/gcrypt/$(PKG_NAME)
+PKG_HASH:=e9fd27218d5394904e4e39788f9b1742711c3e6b41689a31aa3380bd5aa4f426
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING COPYING.LIB
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libassuan
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GnuPG IPC library
+  URL:=https://gnupg.org/software/libassuan/index.html
+  DEPENDS:=+libgpg-error
+endef
+
+define Package/libassuan/description
+Libassuan is a small library implementing the so-called Assuan
+protocol. This protocol is used for IPC between most newer GnuPG
+components. Both, server and client side functions are provided. 
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(2)/bin $(1)/usr/bin
+	$(INSTALL_BIN) \
+		$(PKG_INSTALL_DIR)/usr/bin/libassuan-config \
+		$(2)/bin/
+	$(SED) \
+		's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \
+		$(2)/bin/libassuan-config
+	ln -sf $(STAGING_DIR)/host/bin/libassuan-config $(1)/usr/bin/libassuan-config
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/include/assuan.h \
+		$(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libassuan.{la,so*} \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/share/aclocal
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/share/aclocal/libassuan.m4 \
+		$(1)/usr/share/aclocal/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libassuan.pc \
+		$(1)/usr/lib/pkgconfig
+endef
+
+define Package/libassuan/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libassuan.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libassuan))
diff --git a/external/subpack/libs/libatasmart/Makefile b/external/subpack/libs/libatasmart/Makefile
new file mode 100644
index 0000000..6f7db46
--- /dev/null
+++ b/external/subpack/libs/libatasmart/Makefile
@@ -0,0 +1,98 @@
+#
+# Copyright (C) 2021 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See https://www.gnu.org/licenses/gpl-2.0.txt for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libatasmart
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://git.0pointer.net/libatasmart.git
+PKG_SOURCE_DATE:=2012-05-21
+PKG_SOURCE_VERSION:=de6258940960443038b4c1651dfda3620075e870
+PKG_MIRROR_HASH:=666884b9fe8b6648a596be42d55c41b29a4095e2d70ced5aba67b06241c728e1
+
+PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
+PKG_LICENSE:=LGPL-2.1
+PKG_LICENSE_FILES:=LGPL
+
+PKG_REMOVE_FILES:=autogen.sh
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_DEPENDS:=libatasmart/host
+
+# Do not do autoconf FIXUP for host.
+# We only need Host Compiled strpool binary.
+HOST_FIXUP:=
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+define Package/libatasmart
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=S.M.A.R.T. Reading and Parsing Library
+  URL:=https://git.0pointer.net/libatasmart.git
+  DEPENDS:= +libudev
+endef
+
+define Package/libatasmart/description
+  This library is supposed to be lean and small and thus
+  supports only a subset of the S.M.A.R.T. functionality.
+  However, I claim that it implements the relevant part of it.
+  If you need full control over all S.M.A.R.T. functionality of
+  your hardware please refer to smartmontools.
+endef
+
+define Host/Configure
+endef
+
+define Host/Compile
+	$(RM) -rf $(HOST_BUILD_DIR)/strpool
+	$(HOSTCC) $(HOST_CFLAGS) $(HOST_LDFLAGS) \
+		-o $(HOST_BUILD_DIR)/strpool \
+		$(HOST_BUILD_DIR)/strpool.c
+endef
+
+define Host/Install
+	$(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/bin
+	$(INSTALL_BIN) $(HOST_BUILD_DIR)/strpool $(STAGING_DIR_HOSTPKG)/bin
+endef
+
+define Build/Configure
+	$(RM) -rf $(PKG_BUILD_DIR)/strpool
+	$(RM) $(PKG_BUILD_DIR)/strpool.c
+	$(Build/Configure/Default)
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.la \
+		$(1)/usr/lib
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h \
+		$(1)/usr/include
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libatasmart/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,libatasmart))
diff --git a/external/subpack/libs/libatasmart/patches/001-fix-cross-compile.patch b/external/subpack/libs/libatasmart/patches/001-fix-cross-compile.patch
new file mode 100644
index 0000000..93d8633
--- /dev/null
+++ b/external/subpack/libs/libatasmart/patches/001-fix-cross-compile.patch
@@ -0,0 +1,43 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -114,7 +114,6 @@ dnl###################################
+ 
+ AC_CONFIG_FILES([
+ Makefile
+-strpool/Makefile
+ libatasmart.pc
+ ])
+ AC_OUTPUT
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -22,7 +22,6 @@ AM_LDFLAGS = $(GCLDFLAGS)
+ dist_doc_DATA = README
+ 
+ EXTRA_DIST = \
+-	autogen.sh \
+ 	LGPL \
+ 	README \
+ 	atasmart.c \
+@@ -47,9 +46,6 @@ EXTRA_DIST = \
+ 	blob-examples/WDC_WD5000AAKS--00TMA0-12.01C01 \
+ 	vala/atasmart.vapi
+ 
+-# build the strpool tool first
+-SUBDIRS = strpool .
+-
+ CLEANFILES = atasmart.strpool.c
+ 
+ MAINTAINERCLEANFILES =
+@@ -94,10 +90,7 @@ libatasmart_la_CFLAGS = \
+ BUILT_SOURCES = \
+ 	atasmart.strpool.c
+ 
+-strpool/strpool:
+-	$(MAKE) -C strpool strpool
+-
+-atasmart.strpool.c: atasmart.c strpool/strpool
+-	$(top_builddir)/strpool/strpool $< $@
++atasmart.strpool.c: atasmart.c
++	$(STAGING_DIR_HOSTPKG)/bin/strpool $< $@
+ 
+ ACLOCAL_AMFLAGS = -I m4
diff --git a/external/subpack/libs/libatasmart/src/atasmart.strpool.c b/external/subpack/libs/libatasmart/src/atasmart.strpool.c
new file mode 100644
index 0000000..990cf24
--- /dev/null
+++ b/external/subpack/libs/libatasmart/src/atasmart.strpool.c
@@ -0,0 +1,3235 @@
+/* Saved 149 relocations, saved 7 strings (90 b) due to suffix compression. */
+static const char _strpool_[] =
+	"16 Byte SCSI ATA SAT Passthru\0"
+	"12 Byte SCSI ATA SAT Passthru\0"
+	"Native Linux IDE\0"
+	"Sunplus SCSI ATA Passthru\0"
+	"JMicron SCSI ATA Passthru\0"
+	"Blob\0"
+	"Automatic\0"
+	"None\0"
+	"sat16\0"
+	"sat12\0"
+	"linux-ide\0"
+	"sunplus\0"
+	"jmicron\0"
+	"none\0"
+	"auto\0"
+	"Off-line data collection activity was never started.\0"
+	"Off-line data collection activity was completed without error.\0"
+	"Off-line activity in progress.\0"
+	"Off-line data collection activity was suspended by an interrupting command from host.\0"
+	"Off-line data collection activity was aborted by an interrupting command from host.\0"
+	"Off-line data collection activity was aborted by the device with a fatal error.\0"
+	"Unknown status\0"
+	"The previous self-test routine completed without error or no self-test has ever been run.\0"
+	"The self-test routine was aborted by the host.\0"
+	"The self-test routine was interrupted by the host with a hardware or software reset.\0"
+	"A fatal error or unknown test error occurred while the device was executing its self-test routine and the device was unable to complete the self-test routine.\0"
+	"The previous self-test completed having a test element that failed and the test element that failed.\0"
+	"The previous self-test completed having the electrical element of the test failed.\0"
+	"The previous self-test completed having the servo (and/or seek) test element of the test failed.\0"
+	"The previous self-test completed having the read element of the test failed.\0"
+	"The previous self-test completed having a test element that failed and the device is suspected of having handling damage.\0"
+	"Self-test routine in progress\0"
+	"raw-read-error-rate\0"
+	"throughput-performance\0"
+	/*** Suppressed due to suffix: 
+	"spin-up-time\0" ***/
+	/*** Suppressed due to suffix: 
+	"start-stop-count\0" ***/
+	"reallocated-sector-count\0"
+	"read-channel-margin\0"
+	"seek-error-rate\0"
+	"seek-time-performance\0"
+	"power-on-hours\0"
+	"spin-retry-count\0"
+	"calibration-retry-count\0"
+	"power-cycle-count\0"
+	"read-soft-error-rate\0"
+	/*** Suppressed due to suffix: 
+	"available-reserved-space\0" ***/
+	"program-fail-count\0"
+	"erase-fail-count\0"
+	"program-fail-count-chip\0"
+	"erase-fail-count-chip\0"
+	"wear-leveling-count\0"
+	"used-reserved-blocks-chip\0"
+	"used-reserved-blocks-total\0"
+	"unused-reserved-blocks\0"
+	"program-fail-count-total\0"
+	"erase-fail-count-total\0"
+	"runtime-bad-block-total\0"
+	"end-to-end-error\0"
+	"reported-uncorrect\0"
+	"command-timeout\0"
+	"high-fly-writes\0"
+	"airflow-temperature-celsius\0"
+	"g-sense-error-rate\0"
+	"power-off-retract-count\0"
+	"load-cycle-count\0"
+	"temperature-celsius-2\0"
+	"hardware-ecc-recovered\0"
+	"reallocated-event-count\0"
+	"current-pending-sector\0"
+	"offline-uncorrectable\0"
+	"udma-crc-error-count\0"
+	"multi-zone-error-rate\0"
+	"soft-read-error-rate\0"
+	"ta-increase-count\0"
+	"run-out-cancel\0"
+	"shock-count-write-open\0"
+	"shock-rate-write-open\0"
+	"flying-height\0"
+	"spin-high-current\0"
+	"spin-buzz\0"
+	"offline-seek-performance\0"
+	"disk-shift\0"
+	"g-sense-error-rate-2\0"
+	"loaded-hours\0"
+	"load-retry-count\0"
+	"load-friction\0"
+	"load-cycle-count-2\0"
+	"load-in-time\0"
+	"torq-amp-count\0"
+	"power-off-retract-count-2\0"
+	"head-amplitude\0"
+	/*** Suppressed due to suffix: 
+	"temperature-celsius\0" ***/
+	"endurance-remaining\0"
+	"power-on-seconds-2\0"
+	"uncorrectable-ecc-count\0"
+	"good-block-rate\0"
+	"head-flying-hours\0"
+	/*** Suppressed due to suffix: 
+	"total-lbas-written\0" ***/
+	"total-lbas-read\0"
+	"read-error-retry-rate\0"
+	"9_POWERONMINUTES\0"
+	"9_POWERONSECONDS\0"
+	"9_POWERONHALFMINUTES\0"
+	"192_EMERGENCYRETRACTCYCLECT\0"
+	"193_LOADUNLOAD\0"
+	"194_10XCELSIUS\0"
+	"194_UNKNOWN\0"
+	"200_WRITEERRORCOUNT\0"
+	"201_DETECTEDTACOUNT\0"
+	"5_UNKNOWN\0"
+	"9_UNKNOWN\0"
+	"197_UNKNOWN\0"
+	"198_UNKNOWN\0"
+	"190_UNKNOWN\0"
+	"232_AVAILABLERESERVEDSPACE\0"
+	"233_MEDIAWEAROUTINDICATOR\0"
+	"225_TOTALLBASWRITTEN\0"
+	"4_UNUSED\0"
+	"226_TIMEWORKLOADMEDIAWEAR\0"
+	"227_TIMEWORKLOADHOSTREADS\0"
+	"228_WORKLOADTIMER\0"
+	"3_UNUSED\0"
+	"spin-up-time\0"
+	"start-stop-count\0"
+	"power-on-minutes\0"
+	"power-on-seconds\0"
+	"power-on-half-minutes\0"
+	"emergency-retract-cycle-count\0"
+	"temperature-centi-celsius\0"
+	"write-error-count\0"
+	"detected-ta-count\0"
+	"total-lbas-written\0"
+	"timed-workload-media-wear\0"
+	"timed-workload-host-reads\0"
+	"workload-timer\0"
+	"available-reserved-space\0"
+	"media-wearout-indicator\0"
+	/*** Suppressed due to suffix: 
+	"\0" ***/
+	"ms\0"
+	"sectors\0"
+	"mK\0"
+	/*** Suppressed due to suffix: 
+	"%\0" ***/
+	"%\0"
+	"MB\0"
+	"GOOD\0"
+	"BAD_ATTRIBUTE_IN_THE_PAST\0"
+	"BAD_SECTOR\0"
+	"BAD_ATTRIBUTE_NOW\0"
+	"BAD_SECTOR_MANY\0"
+	"BAD_STATUS\0";
+#ifndef STRPOOL
+#define STRPOOL
+#endif
+#ifndef _P
+#define _P(x) (_strpool_ + ((x) - (const char*) 1))
+#endif
+
+#line 1 "atasmart.c"
+/*-*- Mode: C; c-basic-offset: 8 -*-*/
+
+/***
+    This file is part of libatasmart.
+
+    Copyright 2008 Lennart Poettering
+
+    libatasmart is free software; you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as
+    published by the Free Software Foundation, either version 2.1 of the
+    License, or (at your option) any later version.
+
+    libatasmart is distributed in the hope that it will be useful, but
+    WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with libatasmart. If not, If not, see
+    <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <alloca.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <scsi/scsi.h>
+#include <scsi/sg.h>
+#include <scsi/scsi_ioctl.h>
+#include <linux/hdreg.h>
+#include <linux/fs.h>
+#include <sys/types.h>
+#include <regex.h>
+#include <sys/param.h>
+#include <libudev.h>
+
+#include "atasmart.h"
+
+#ifndef STRPOOL
+#define _P(x) x
+#endif
+
+#define SK_TIMEOUT 2000
+
+typedef enum SkDirection {
+        SK_DIRECTION_NONE,
+        SK_DIRECTION_IN,
+        SK_DIRECTION_OUT,
+        _SK_DIRECTION_MAX
+} SkDirection;
+
+typedef enum SkDiskType {
+        /* These three will be autotested for: */
+        SK_DISK_TYPE_ATA_PASSTHROUGH_12, /* ATA passthrough over SCSI transport, 12-byte version */
+        SK_DISK_TYPE_ATA_PASSTHROUGH_16, /* ATA passthrough over SCSI transport, 16-byte version */
+        SK_DISK_TYPE_LINUX_IDE,          /* Classic Linux /dev/hda ioctls */
+
+        /* These three will not be autotested for */
+        SK_DISK_TYPE_SUNPLUS,            /* SunPlus USB/ATA bridges */
+        SK_DISK_TYPE_JMICRON,            /* JMicron USB/ATA bridges */
+        SK_DISK_TYPE_BLOB,               /* From a file */
+        SK_DISK_TYPE_NONE,               /* No access method */
+        SK_DISK_TYPE_AUTO,               /* We don't know yet */
+        _SK_DISK_TYPE_MAX,
+        _SK_DISK_TYPE_TEST_MAX = SK_DISK_TYPE_SUNPLUS /* only auto test until here */
+} SkDiskType;
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define MAKE_TAG(a,b,c,d)                        \
+        (((uint32_t) d << 24) |                  \
+         ((uint32_t) c << 16) |                  \
+         ((uint32_t) b << 8) |                   \
+         ((uint32_t) a))
+#else
+#define MAKE_TAG(a,b,c,d)                        \
+        (((uint32_t) a << 24) |                  \
+         ((uint32_t) b << 16) |                  \
+         ((uint32_t) c << 8) |                   \
+         ((uint32_t) d))
+#endif
+
+typedef enum SkBlobTag {
+        SK_BLOB_TAG_IDENTIFY = MAKE_TAG('I', 'D', 'F', 'Y'),
+        SK_BLOB_TAG_SMART_STATUS = MAKE_TAG('S', 'M', 'S', 'T'),
+        SK_BLOB_TAG_SMART_DATA = MAKE_TAG('S', 'M', 'D', 'T'),
+        SK_BLOB_TAG_SMART_THRESHOLDS = MAKE_TAG('S', 'M', 'T', 'H')
+} SkBlobTag;
+
+struct SkDisk {
+        char *name;
+        int fd;
+        SkDiskType type;
+
+        uint64_t size;
+
+        uint8_t identify[512];
+        uint8_t smart_data[512];
+        uint8_t smart_thresholds[512];
+
+        SkBool smart_initialized:1;
+
+        SkBool identify_valid:1;
+        SkBool smart_data_valid:1;
+        SkBool smart_thresholds_valid:1;
+
+        SkBool blob_smart_status:1;
+        SkBool blob_smart_status_valid:1;
+
+        SkBool attribute_verification_bad:1;
+
+        SkIdentifyParsedData identify_parsed_data;
+        SkSmartParsedData smart_parsed_data;
+
+        /* cache for commonly used attributes */
+        SkBool attribute_cache_valid:1;
+        SkBool bad_attribute_now:1;
+        SkBool bad_attribute_in_the_past:1;
+        SkBool reallocated_sector_count_found:1;
+        SkBool current_pending_sector_found:1;
+        uint64_t reallocated_sector_count;
+        uint64_t current_pending_sector;
+
+        void *blob;
+};
+
+/* ATA commands */
+typedef enum SkAtaCommand {
+        SK_ATA_COMMAND_IDENTIFY_DEVICE = 0xEC,
+        SK_ATA_COMMAND_IDENTIFY_PACKET_DEVICE = 0xA1,
+        SK_ATA_COMMAND_SMART = 0xB0,
+        SK_ATA_COMMAND_CHECK_POWER_MODE = 0xE5
+} SkAtaCommand;
+
+/* ATA SMART subcommands (ATA8 7.52.1) */
+typedef enum SkSmartCommand {
+        SK_SMART_COMMAND_READ_DATA = 0xD0,
+        SK_SMART_COMMAND_READ_THRESHOLDS = 0xD1,
+        SK_SMART_COMMAND_EXECUTE_OFFLINE_IMMEDIATE = 0xD4,
+        SK_SMART_COMMAND_ENABLE_OPERATIONS = 0xD8,
+        SK_SMART_COMMAND_DISABLE_OPERATIONS = 0xD9,
+        SK_SMART_COMMAND_RETURN_STATUS = 0xDA
+} SkSmartCommand;
+
+/* Hmm, if the data we parse is out of a certain range just consider it misparsed */
+#define SK_MKELVIN_VALID_MIN ((uint64_t) ((-15LL*1000LL) + 273150LL))
+#define SK_MKELVIN_VALID_MAX ((uint64_t) ((100LL*1000LL) + 273150LL))
+
+#define SK_MSECOND_VALID_MIN 1ULL
+#define SK_MSECOND_VALID_SHORT_MAX (60ULL * 60ULL * 1000ULL)
+#define SK_MSECOND_VALID_LONG_MAX (30ULL * 365ULL * 24ULL * 60ULL * 60ULL * 1000ULL)
+
+static int init_smart(SkDisk *d);
+
+static const char *disk_type_to_human_string(SkDiskType type) {
+
+        /* %STRINGPOOLSTART% */
+        static const char* const map[_SK_DISK_TYPE_MAX] = {
+                [SK_DISK_TYPE_ATA_PASSTHROUGH_16] = ((const char*) 1),
+                [SK_DISK_TYPE_ATA_PASSTHROUGH_12] = ((const char*) 31),
+                [SK_DISK_TYPE_LINUX_IDE] = ((const char*) 61),
+                [SK_DISK_TYPE_SUNPLUS] = ((const char*) 78),
+                [SK_DISK_TYPE_JMICRON] = ((const char*) 104),
+                [SK_DISK_TYPE_BLOB] = ((const char*) 130),
+                [SK_DISK_TYPE_AUTO] = ((const char*) 135),
+                [SK_DISK_TYPE_NONE] = ((const char*) 145)
+        };
+        /* %STRINGPOOLSTOP% */
+
+        if (type >= _SK_DISK_TYPE_MAX)
+                return NULL;
+
+        return _P(map[type]);
+}
+
+static const char *disk_type_to_prefix_string(SkDiskType type) {
+
+        /* %STRINGPOOLSTART% */
+        static const char* const map[_SK_DISK_TYPE_MAX] = {
+                [SK_DISK_TYPE_ATA_PASSTHROUGH_16] = ((const char*) 150),
+                [SK_DISK_TYPE_ATA_PASSTHROUGH_12] = ((const char*) 156),
+                [SK_DISK_TYPE_LINUX_IDE] = ((const char*) 162),
+                [SK_DISK_TYPE_SUNPLUS] = ((const char*) 172),
+                [SK_DISK_TYPE_JMICRON] = ((const char*) 180),
+                [SK_DISK_TYPE_NONE] = ((const char*) 188),
+                [SK_DISK_TYPE_AUTO] = ((const char*) 193),
+        };
+        /* %STRINGPOOLSTOP% */
+
+        if (type >= _SK_DISK_TYPE_MAX)
+                return NULL;
+
+        return _P(map[type]);
+}
+
+static const char *disk_type_from_string(const char *s, SkDiskType *type) {
+        unsigned u;
+
+        assert(s);
+        assert(type);
+
+        for (u = 0; u < _SK_DISK_TYPE_MAX; u++) {
+                const char *t;
+                size_t l;
+
+                if (!(t = disk_type_to_prefix_string(u)))
+                        continue;
+
+                l = strlen(t);
+
+                if (strncmp(s, t, l))
+                        continue;
+
+                if (s[l] != ':')
+                        continue;
+
+                *type = u;
+
+                return s + l + 1;
+        }
+
+        return NULL;
+}
+
+static SkBool disk_smart_is_available(SkDisk *d) {
+        return d->identify_valid && !!(d->identify[164] & 1);
+}
+
+static SkBool disk_smart_is_enabled(SkDisk *d) {
+        return d->identify_valid && !!(d->identify[170] & 1);
+}
+
+static SkBool disk_smart_is_conveyance_test_available(SkDisk *d) {
+        assert(d->smart_data_valid);
+
+        return !!(d->smart_data[367] & 32);
+}
+static SkBool disk_smart_is_short_and_extended_test_available(SkDisk *d) {
+        assert(d->smart_data_valid);
+
+        return !!(d->smart_data[367] & 16);
+}
+
+static SkBool disk_smart_is_start_test_available(SkDisk *d) {
+        assert(d->smart_data_valid);
+
+        return !!(d->smart_data[367] & 1);
+}
+
+static SkBool disk_smart_is_abort_test_available(SkDisk *d) {
+        assert(d->smart_data_valid);
+
+        return !!(d->smart_data[367] & 41);
+}
+
+static int disk_linux_ide_command(SkDisk *d, SkAtaCommand command, SkDirection direction, void* cmd_data, void* data, size_t *len) {
+        uint8_t *bytes = cmd_data;
+        int ret;
+
+        assert(d->type == SK_DISK_TYPE_LINUX_IDE);
+
+        switch (direction) {
+
+                case SK_DIRECTION_OUT:
+
+                        /* We could use HDIO_DRIVE_TASKFILE here, but
+                         * that's a deprecated ioctl(), hence we don't
+                         * do it. And we don't need writing anyway. */
+
+                        errno = ENOTSUP;
+                        return -1;
+
+                case SK_DIRECTION_IN: {
+                        uint8_t *ioctl_data;
+
+                        /* We have HDIO_DRIVE_CMD which can only read, but not write,
+                         * and cannot do LBA. We use it for all read commands. */
+
+                        ioctl_data = alloca(4 + *len);
+                        memset(ioctl_data, 0, 4 + *len);
+
+                        ioctl_data[0] = (uint8_t) command;  /* COMMAND */
+                        ioctl_data[1] = ioctl_data[0] == WIN_SMART ? bytes[9] : bytes[3];  /* SECTOR/NSECTOR */
+                        ioctl_data[2] = bytes[1];          /* FEATURE */
+                        ioctl_data[3] = bytes[3];          /* NSECTOR */
+
+                        if ((ret = ioctl(d->fd, HDIO_DRIVE_CMD, ioctl_data)) < 0)
+                                return ret;
+
+                        memset(bytes, 0, 12);
+                        bytes[11] = ioctl_data[0];
+                        bytes[1] = ioctl_data[1];
+                        bytes[3] = ioctl_data[2];
+
+                        memcpy(data, ioctl_data+4, *len);
+
+                        return ret;
+                }
+
+                case SK_DIRECTION_NONE: {
+                        uint8_t ioctl_data[7];
+
+                        /* We have HDIO_DRIVE_TASK which can neither read nor
+                         * write, but can do LBA. We use it for all commands that
+                         * do neither read nor write */
+
+                        memset(ioctl_data, 0, sizeof(ioctl_data));
+
+                        ioctl_data[0] = (uint8_t) command;  /* COMMAND */
+                        ioctl_data[1] = bytes[1];         /* FEATURE */
+                        ioctl_data[2] = bytes[3];         /* NSECTOR */
+
+                        ioctl_data[3] = bytes[9];         /* LBA LOW */
+                        ioctl_data[4] = bytes[8];         /* LBA MID */
+                        ioctl_data[5] = bytes[7];         /* LBA HIGH */
+                        ioctl_data[6] = bytes[10];        /* SELECT */
+
+                        if ((ret = ioctl(d->fd, HDIO_DRIVE_TASK, ioctl_data)))
+                                return ret;
+
+                        memset(bytes, 0, 12);
+                        bytes[11] = ioctl_data[0];
+                        bytes[1] = ioctl_data[1];
+                        bytes[3] = ioctl_data[2];
+
+                        bytes[9] = ioctl_data[3];
+                        bytes[8] = ioctl_data[4];
+                        bytes[7] = ioctl_data[5];
+
+                        bytes[10] = ioctl_data[6];
+
+                        return ret;
+                }
+
+                default:
+                        assert(FALSE);
+                        return -1;
+        }
+}
+
+/* Sends a SCSI command block */
+static int sg_io(int fd, int direction,
+                 const void *cdb, size_t cdb_len,
+                 void *data, size_t data_len,
+                 void *sense, size_t sense_len) {
+
+        struct sg_io_hdr io_hdr;
+
+        memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
+
+        io_hdr.interface_id = 'S';
+        io_hdr.cmdp = (unsigned char*) cdb;
+        io_hdr.cmd_len = cdb_len;
+        io_hdr.dxferp = data;
+        io_hdr.dxfer_len = data_len;
+        io_hdr.sbp = sense;
+        io_hdr.mx_sb_len = sense_len;
+        io_hdr.dxfer_direction = direction;
+        io_hdr.timeout = SK_TIMEOUT;
+
+        return ioctl(fd, SG_IO, &io_hdr);
+}
+
+static int disk_passthrough_16_command(SkDisk *d, SkAtaCommand command, SkDirection direction, void* cmd_data, void* data, size_t *len) {
+        uint8_t *bytes = cmd_data;
+        uint8_t cdb[16];
+        uint8_t sense[32];
+        uint8_t *desc = sense+8;
+        int ret;
+
+        static const int direction_map[] = {
+                [SK_DIRECTION_NONE] = SG_DXFER_NONE,
+                [SK_DIRECTION_IN] = SG_DXFER_FROM_DEV,
+                [SK_DIRECTION_OUT] = SG_DXFER_TO_DEV
+        };
+
+        assert(d->type == SK_DISK_TYPE_ATA_PASSTHROUGH_16);
+
+        /* ATA Pass-Through 16 byte command, as described in "T10 04-262r8
+         * ATA Command Pass-Through":
+         * http://www.t10.org/ftp/t10/document.04/04-262r8.pdf */
+
+        memset(cdb, 0, sizeof(cdb));
+
+        cdb[0] = 0x85; /* OPERATION CODE: 16 byte pass through */
+
+        if (direction == SK_DIRECTION_NONE) {
+                cdb[1] = 3 << 1;   /* PROTOCOL: Non-Data */
+                cdb[2] = 0x20;     /* OFF_LINE=0, CK_COND=1, T_DIR=0, BYT_BLOK=0, T_LENGTH=0 */
+
+        } else if (direction == SK_DIRECTION_IN) {
+                cdb[1] = 4 << 1;   /* PROTOCOL: PIO Data-in */
+                cdb[2] = 0x2e;     /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
+
+        } else if (direction == SK_DIRECTION_OUT) {
+                cdb[1] = 5 << 1;   /* PROTOCOL: PIO Data-Out */
+                cdb[2] = 0x26;     /* OFF_LINE=0, CK_COND=1, T_DIR=0, BYT_BLOK=1, T_LENGTH=2 */
+        }
+
+        cdb[3] = bytes[0]; /* FEATURES */
+        cdb[4] = bytes[1];
+
+        cdb[5] = bytes[2]; /* SECTORS */
+        cdb[6] = bytes[3];
+
+        cdb[8] = bytes[9]; /* LBA LOW */
+        cdb[10] = bytes[8]; /* LBA MID */
+        cdb[12] = bytes[7]; /* LBA HIGH */
+
+        cdb[13] = bytes[10] & 0x4F; /* SELECT */
+        cdb[14] = (uint8_t) command;
+
+        memset(sense, 0, sizeof(sense));
+
+        if ((ret = sg_io(d->fd, direction_map[direction], cdb, sizeof(cdb), data, len ? *len : 0, sense, sizeof(sense))) < 0)
+                return ret;
+
+        if (sense[0] != 0x72 || desc[0] != 0x9 || desc[1] != 0x0c) {
+                errno = EIO;
+                return -1;
+        }
+
+        memset(bytes, 0, 12);
+
+        bytes[1] = desc[3];
+        bytes[2] = desc[4];
+        bytes[3] = desc[5];
+        bytes[9] = desc[7];
+        bytes[8] = desc[9];
+        bytes[7] = desc[11];
+        bytes[10] = desc[12];
+        bytes[11] = desc[13];
+
+        return ret;
+}
+
+static int disk_passthrough_12_command(SkDisk *d, SkAtaCommand command, SkDirection direction, void* cmd_data, void* data, size_t *len) {
+        uint8_t *bytes = cmd_data;
+        uint8_t cdb[12];
+        uint8_t sense[32];
+        uint8_t *desc = sense+8;
+        int ret;
+
+        static const int direction_map[] = {
+                [SK_DIRECTION_NONE] = SG_DXFER_NONE,
+                [SK_DIRECTION_IN] = SG_DXFER_FROM_DEV,
+                [SK_DIRECTION_OUT] = SG_DXFER_TO_DEV
+        };
+
+        assert(d->type == SK_DISK_TYPE_ATA_PASSTHROUGH_12);
+
+        /* ATA Pass-Through 12 byte command, as described in "T10 04-262r8
+         * ATA Command Pass-Through":
+         * http://www.t10.org/ftp/t10/document.04/04-262r8.pdf */
+
+        memset(cdb, 0, sizeof(cdb));
+
+        cdb[0] = 0xa1; /* OPERATION CODE: 12 byte pass through */
+
+        if (direction == SK_DIRECTION_NONE) {
+                cdb[1] = 3 << 1;   /* PROTOCOL: Non-Data */
+                cdb[2] = 0x20;     /* OFF_LINE=0, CK_COND=1, T_DIR=0, BYT_BLOK=0, T_LENGTH=0 */
+
+        } else if (direction == SK_DIRECTION_IN) {
+                cdb[1] = 4 << 1;   /* PROTOCOL: PIO Data-in */
+                cdb[2] = 0x2e;     /* OFF_LINE=0, CK_COND=1, T_DIR=1, BYT_BLOK=1, T_LENGTH=2 */
+
+        } else if (direction == SK_DIRECTION_OUT) {
+                cdb[1] = 5 << 1;   /* PROTOCOL: PIO Data-Out */
+                cdb[2] = 0x26;     /* OFF_LINE=0, CK_COND=1, T_DIR=0, BYT_BLOK=1, T_LENGTH=2 */
+        }
+
+        cdb[3] = bytes[1]; /* FEATURES */
+        cdb[4] = bytes[3]; /* SECTORS */
+
+        cdb[5] = bytes[9]; /* LBA LOW */
+        cdb[6] = bytes[8]; /* LBA MID */
+        cdb[7] = bytes[7]; /* LBA HIGH */
+
+        cdb[8] = bytes[10] & 0x4F; /* SELECT */
+        cdb[9] = (uint8_t) command;
+
+        memset(sense, 0, sizeof(sense));
+
+        if ((ret = sg_io(d->fd, direction_map[direction], cdb, sizeof(cdb), data, len ? *len : 0, sense, sizeof(sense))) < 0)
+                return ret;
+
+        if (sense[0] != 0x72 || desc[0] != 0x9 || desc[1] != 0x0c) {
+                errno = EIO;
+                return -1;
+        }
+
+        memset(bytes, 0, 12);
+
+        bytes[1] = desc[3]; /* FEATURES */
+        bytes[2] = desc[4]; /* STATUS */
+        bytes[3] = desc[5]; /* SECTORS */
+        bytes[9] = desc[7]; /* LBA LOW */
+        bytes[8] = desc[9]; /* LBA MID */
+        bytes[7] = desc[11]; /* LBA HIGH */
+        bytes[10] = desc[12]; /* SELECT */
+        bytes[11] = desc[13]; /* ERROR */
+
+        return ret;
+}
+
+static int disk_sunplus_command(SkDisk *d, SkAtaCommand command, SkDirection direction, void* cmd_data, void* data, size_t *len) {
+        uint8_t *bytes = cmd_data;
+        uint8_t cdb[12];
+        uint8_t sense[32], buf[8];
+        int ret;
+        static const int direction_map[] = {
+                [SK_DIRECTION_NONE] = SG_DXFER_NONE,
+                [SK_DIRECTION_IN] = SG_DXFER_FROM_DEV,
+                [SK_DIRECTION_OUT] = SG_DXFER_TO_DEV
+        };
+
+        assert(d->type == SK_DISK_TYPE_SUNPLUS);
+
+        /* SunplusIT specific SCSI ATA pass-thru. Inspired by smartmonutils' support for these bridges */
+
+        memset(cdb, 0, sizeof(cdb));
+
+        cdb[0] = 0xF8; /* OPERATION CODE: Sunplus specific */
+        cdb[1] = 0x00; /* Subcommand: Pass-thru */
+        cdb[2] = 0x22;
+
+        if (direction == SK_DIRECTION_NONE)
+                cdb[3] = 0x00; /* protocol */
+        else if (direction == SK_DIRECTION_IN)
+                cdb[3] = 0x10; /* protocol */
+        else if (direction == SK_DIRECTION_OUT)
+                cdb[3] = 0x11; /* protocol */
+
+        cdb[4] = bytes[3]; /* size? */
+        cdb[5] = bytes[1]; /* FEATURES */
+        cdb[6] = bytes[3]; /* SECTORS */
+        cdb[7] = bytes[9]; /* LBA LOW */
+        cdb[8] = bytes[8]; /* LBA MID */
+        cdb[9] = bytes[7]; /* LBA HIGH */
+        cdb[10] = bytes[10] | 0xA0; /* SELECT */
+        cdb[11] = (uint8_t) command;
+
+        memset(sense, 0, sizeof(sense));
+
+        /* Issue request */
+        if ((ret = sg_io(d->fd, direction_map[direction], cdb, sizeof(cdb), data, len ? *len : 0, sense, sizeof(sense))) < 0)
+                return ret;
+
+        memset(cdb, 0, sizeof(cdb));
+
+        cdb[0] = 0xF8;
+        cdb[1] = 0x00;
+        cdb[2] = 0x21;
+
+        memset(buf, 0, sizeof(buf));
+
+        /* Ask for response */
+        if ((ret = sg_io(d->fd, SG_DXFER_FROM_DEV, cdb, sizeof(cdb), buf, sizeof(buf), sense, sizeof(sense))) < 0)
+                return ret;
+
+        memset(bytes, 0, 12);
+
+        bytes[2] = buf[1]; /* ERROR */
+        bytes[3] = buf[2]; /* SECTORS */
+        bytes[9] = buf[3]; /* LBA LOW */
+        bytes[8] = buf[4]; /* LBA MID */
+        bytes[7] = buf[5]; /* LBA HIGH */
+        bytes[10] = buf[6]; /* SELECT */
+        bytes[11] = buf[7]; /* STATUS */
+
+        return ret;
+}
+
+static int disk_jmicron_command(SkDisk *d, SkAtaCommand command, SkDirection direction, void* cmd_data, void* _data, size_t *_len) {
+        uint8_t *bytes = cmd_data;
+        uint8_t cdb[12];
+        uint8_t sense[32];
+        uint8_t port;
+        int ret;
+        SkBool is_smart_status = FALSE;
+        void *data = _data;
+        size_t len = _len ? *_len : 0;
+        uint8_t smart_status = 0;
+
+        static const int direction_map[] = {
+                [SK_DIRECTION_NONE] = SG_DXFER_NONE,
+                [SK_DIRECTION_IN] = SG_DXFER_FROM_DEV,
+                [SK_DIRECTION_OUT] = SG_DXFER_TO_DEV
+        };
+
+        assert(d->type == SK_DISK_TYPE_JMICRON);
+
+        /* JMicron specific SCSI ATA pass-thru. Inspired by smartmonutils' support for these bridges */
+
+        memset(cdb, 0, sizeof(cdb));
+
+        cdb[0] = 0xdf; /* operation code */
+        cdb[1] = 0x10;
+        cdb[2] = 0x00;
+        cdb[3] = 0x00; /* size HI */
+        cdb[4] = sizeof(port); /* size LO */
+        cdb[5] = 0x00;
+        cdb[6] = 0x72; /* register address HI */
+        cdb[7] = 0x0f; /* register address LO */
+        cdb[8] = 0x00;
+        cdb[9] = 0x00;
+        cdb[10] = 0x00;
+        cdb[11] = 0xfd;
+
+        memset(sense, 0, sizeof(sense));
+
+        if ((ret = sg_io(d->fd, SG_DXFER_FROM_DEV, cdb, sizeof(cdb), &port, sizeof(port), sense, sizeof(sense))) < 0)
+                return ret;
+
+        /* Port & 0x04 is port #0, Port & 0x40 is port #1 */
+        if (!(port & 0x44))
+                return -EIO;
+
+        cdb[0] = 0xdf; /* OPERATION CODE: 12 byte pass through */
+
+        if (command == SK_ATA_COMMAND_SMART && bytes[1] == SK_SMART_COMMAND_RETURN_STATUS) {
+                /* We need to rewrite the SMART status request */
+                is_smart_status = TRUE;
+                direction = SK_DIRECTION_IN;
+                data = &smart_status;
+                len = sizeof(smart_status);
+                cdb[1] = 0x10;
+        } else if (direction == SK_DIRECTION_NONE)
+                cdb[1] = 0x10;
+        else if (direction == SK_DIRECTION_IN)
+                cdb[1] = 0x10;
+        else if (direction == SK_DIRECTION_OUT)
+                cdb[1] = 0x00;
+
+        cdb[2] = 0x00;
+
+        cdb[3] = (uint8_t) (len >> 8);
+        cdb[4] = (uint8_t) (len & 0xFF);
+
+        cdb[5] = bytes[1]; /* FEATURES */
+        cdb[6] = bytes[3]; /* SECTORS */
+
+        cdb[7] = bytes[9]; /* LBA LOW */
+        cdb[8] = bytes[8]; /* LBA MID */
+        cdb[9] = bytes[7]; /* LBA HIGH */
+
+        cdb[10] = bytes[10] | ((port & 0x04) ? 0xA0 : 0xB0); /* SELECT */
+        cdb[11] = (uint8_t) command;
+
+        memset(sense, 0, sizeof(sense));
+
+        if ((ret = sg_io(d->fd, direction_map[direction], cdb, sizeof(cdb), data, len, sense, sizeof(sense))) < 0)
+                return ret;
+
+        memset(bytes, 0, 12);
+
+        if (is_smart_status) {
+                if (smart_status == 0x01 || smart_status == 0xc2) {
+                        bytes[7] = 0xc2; /* LBA HIGH */
+                        bytes[8] = 0x4f; /* LBA MID */
+                } else if (smart_status == 0x00 || smart_status == 0x2c) {
+                        bytes[7] = 0x2c; /* LBA HIGH */
+                        bytes[8] = 0xf4; /* LBA MID */
+                } else
+                        return -EIO;
+        } else {
+                uint8_t regbuf[16];
+
+                cdb[0] = 0xdf; /* operation code */
+                cdb[1] = 0x10;
+                cdb[2] = 0x00;
+                cdb[3] = 0x00; /* size HI */
+                cdb[4] = sizeof(regbuf); /* size LO */
+                cdb[5] = 0x00;
+                cdb[6] = (port & 0x04) ? 0x80 : 0x90; /* register address HI */
+                cdb[7] = 0x00; /* register address LO */
+                cdb[8] = 0x00;
+                cdb[9] = 0x00;
+                cdb[10] = 0x00;
+                cdb[11] = 0xfd;
+
+                if ((ret = sg_io(d->fd, SG_DXFER_FROM_DEV, cdb, sizeof(cdb), regbuf, sizeof(regbuf), sense, sizeof(sense))) < 0)
+                        return ret;
+
+                bytes[2] = regbuf[14]; /* STATUS */
+                bytes[3] = regbuf[0]; /* SECTORS */
+                bytes[9] = regbuf[6]; /* LBA LOW */
+                bytes[8] = regbuf[4]; /* LBA MID */
+                bytes[7] = regbuf[10]; /* LBA HIGH */
+                bytes[10] = regbuf[9]; /* SELECT */
+                bytes[11] = regbuf[13]; /* ERROR */
+        }
+
+        return ret;
+}
+
+static int disk_command(SkDisk *d, SkAtaCommand command, SkDirection direction, void* cmd_data, void* data, size_t *len) {
+
+        static int (* const disk_command_table[_SK_DISK_TYPE_MAX]) (SkDisk *d, SkAtaCommand command, SkDirection direction, void* cmd_data, void* data, size_t *len) = {
+                [SK_DISK_TYPE_LINUX_IDE] = disk_linux_ide_command,
+                [SK_DISK_TYPE_ATA_PASSTHROUGH_12] = disk_passthrough_12_command,
+                [SK_DISK_TYPE_ATA_PASSTHROUGH_16] = disk_passthrough_16_command,
+                [SK_DISK_TYPE_SUNPLUS] = disk_sunplus_command,
+                [SK_DISK_TYPE_JMICRON] = disk_jmicron_command,
+                [SK_DISK_TYPE_BLOB] = NULL,
+                [SK_DISK_TYPE_AUTO] = NULL,
+                [SK_DISK_TYPE_NONE] = NULL
+        };
+
+        assert(d);
+        assert(d->type <= _SK_DISK_TYPE_MAX);
+        assert(direction <= _SK_DIRECTION_MAX);
+
+        assert(direction == SK_DIRECTION_NONE || (data && len && *len > 0));
+        assert(direction != SK_DIRECTION_NONE || (!data && !len));
+
+        if (!disk_command_table[d->type]) {
+                errno = -ENOTSUP;
+                return -1;
+        }
+
+        return disk_command_table[d->type](d, command, direction, cmd_data, data, len);
+}
+
+static int disk_identify_device(SkDisk *d) {
+        uint16_t cmd[6];
+        int ret;
+        size_t len = 512;
+        const uint8_t *p;
+
+        if (d->type == SK_DISK_TYPE_BLOB)
+                return 0;
+
+        memset(d->identify, 0, len);
+        memset(cmd, 0, sizeof(cmd));
+
+        cmd[1] = htons(1);
+
+        if ((ret = disk_command(d, SK_ATA_COMMAND_IDENTIFY_DEVICE, SK_DIRECTION_IN, cmd, d->identify, &len)) < 0)
+                return ret;
+
+        if (len != 512) {
+                errno = EIO;
+                return -1;
+        }
+
+        /* Check if IDENTIFY data is all NULs */
+        for (p = d->identify; p < (const uint8_t*) d->identify+len; p++)
+                if (*p) {
+                        p = NULL;
+                        break;
+                }
+
+        if (p) {
+                errno = EIO;
+                return -1;
+        }
+
+        d->identify_valid = TRUE;
+
+        return 0;
+}
+
+int sk_disk_check_sleep_mode(SkDisk *d, SkBool *awake) {
+        int ret;
+        uint16_t cmd[6];
+        uint8_t status;
+
+        if (!d->identify_valid) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        if (d->type == SK_DISK_TYPE_BLOB) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        memset(cmd, 0, sizeof(cmd));
+
+        if ((ret = disk_command(d, SK_ATA_COMMAND_CHECK_POWER_MODE, SK_DIRECTION_NONE, cmd, NULL, 0)) < 0)
+                return ret;
+
+        if (cmd[0] != 0 || (ntohs(cmd[5]) & 1) != 0) {
+                errno = EIO;
+                return -1;
+        }
+
+        status = ntohs(cmd[1]) & 0xFF;
+        *awake = status == 0xFF || status == 0x80; /* idle and active/idle is considered awake */
+
+        return 0;
+}
+
+static int disk_smart_enable(SkDisk *d, SkBool b) {
+        uint16_t cmd[6];
+
+        if (!disk_smart_is_available(d)) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        if (d->type == SK_DISK_TYPE_BLOB) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        memset(cmd, 0, sizeof(cmd));
+
+        cmd[0] = htons(b ? SK_SMART_COMMAND_ENABLE_OPERATIONS : SK_SMART_COMMAND_DISABLE_OPERATIONS);
+        cmd[2] = htons(0x0000U);
+        cmd[3] = htons(0x00C2U);
+        cmd[4] = htons(0x4F00U);
+
+        return disk_command(d, SK_ATA_COMMAND_SMART, SK_DIRECTION_NONE, cmd, NULL, 0);
+}
+
+int sk_disk_smart_read_data(SkDisk *d) {
+        uint16_t cmd[6];
+        int ret;
+        size_t len = 512;
+
+        if (init_smart(d) < 0)
+                return -1;
+
+        if (!disk_smart_is_available(d)) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        if (d->type == SK_DISK_TYPE_BLOB)
+                return 0;
+
+        memset(cmd, 0, sizeof(cmd));
+
+        cmd[0] = htons(SK_SMART_COMMAND_READ_DATA);
+        cmd[1] = htons(1);
+        cmd[2] = htons(0x0000U);
+        cmd[3] = htons(0x00C2U);
+        cmd[4] = htons(0x4F00U);
+
+        if ((ret = disk_command(d, SK_ATA_COMMAND_SMART, SK_DIRECTION_IN, cmd, d->smart_data, &len)) < 0)
+                return ret;
+
+        d->smart_data_valid = TRUE;
+
+        return ret;
+}
+
+static int disk_smart_read_thresholds(SkDisk *d) {
+        uint16_t cmd[6];
+        int ret;
+        size_t len = 512;
+
+        if (!disk_smart_is_available(d)) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        if (d->type == SK_DISK_TYPE_BLOB)
+                return 0;
+
+        memset(cmd, 0, sizeof(cmd));
+
+        cmd[0] = htons(SK_SMART_COMMAND_READ_THRESHOLDS);
+        cmd[1] = htons(1);
+        cmd[2] = htons(0x0000U);
+        cmd[3] = htons(0x00C2U);
+        cmd[4] = htons(0x4F00U);
+
+        if ((ret = disk_command(d, SK_ATA_COMMAND_SMART, SK_DIRECTION_IN, cmd, d->smart_thresholds, &len)) < 0)
+                return ret;
+
+        d->smart_thresholds_valid = TRUE;
+
+        return ret;
+}
+
+int sk_disk_smart_status(SkDisk *d, SkBool *good) {
+        uint16_t cmd[6];
+        int ret;
+
+        if (init_smart(d) < 0)
+                return -1;
+
+        if (!disk_smart_is_available(d)) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        if (d->type == SK_DISK_TYPE_BLOB) {
+
+                if (d->blob_smart_status_valid) {
+                        *good = d->blob_smart_status;
+                        return 0;
+                }
+
+                errno = ENXIO;
+                return -1;
+        }
+
+        memset(cmd, 0, sizeof(cmd));
+
+        cmd[0] = htons(SK_SMART_COMMAND_RETURN_STATUS);
+        cmd[1] = htons(0x0000U);
+        cmd[3] = htons(0x00C2U);
+        cmd[4] = htons(0x4F00U);
+
+        if ((ret = disk_command(d, SK_ATA_COMMAND_SMART, SK_DIRECTION_NONE, cmd, NULL, 0)) < 0)
+                return ret;
+
+        /* SAT/USB bridges truncate packets, so we only check for 4F,
+         * not for 2C on those */
+        if ((d->type == SK_DISK_TYPE_ATA_PASSTHROUGH_12 || cmd[3] == htons(0x00C2U)) &&
+            cmd[4] == htons(0x4F00U))
+                *good = TRUE;
+        else if ((d->type == SK_DISK_TYPE_ATA_PASSTHROUGH_12 || cmd[3] == htons(0x002CU)) &&
+                 cmd[4] == htons(0xF400U))
+                *good = FALSE;
+        else {
+                errno = EIO;
+                return -1;
+        }
+
+        return ret;
+}
+
+int sk_disk_smart_self_test(SkDisk *d, SkSmartSelfTest test) {
+        uint16_t cmd[6];
+        int ret;
+
+        if (init_smart(d) < 0)
+                return -1;
+
+        if (!disk_smart_is_available(d)) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        if (d->type == SK_DISK_TYPE_BLOB) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        if (!d->smart_data_valid)
+                if ((ret = sk_disk_smart_read_data(d)) < 0)
+                        return -1;
+
+        assert(d->smart_data_valid);
+
+        if (test != SK_SMART_SELF_TEST_SHORT &&
+            test != SK_SMART_SELF_TEST_EXTENDED &&
+            test != SK_SMART_SELF_TEST_CONVEYANCE &&
+            test != SK_SMART_SELF_TEST_ABORT) {
+                errno = EINVAL;
+                return -1;
+        }
+
+        if (!disk_smart_is_start_test_available(d)
+            || (test == SK_SMART_SELF_TEST_ABORT && !disk_smart_is_abort_test_available(d))
+            || ((test == SK_SMART_SELF_TEST_SHORT || test == SK_SMART_SELF_TEST_EXTENDED) && !disk_smart_is_short_and_extended_test_available(d))
+            || (test == SK_SMART_SELF_TEST_CONVEYANCE && !disk_smart_is_conveyance_test_available(d))) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        if (test == SK_SMART_SELF_TEST_ABORT &&
+            !disk_smart_is_abort_test_available(d)) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        memset(cmd, 0, sizeof(cmd));
+
+        cmd[0] = htons(SK_SMART_COMMAND_EXECUTE_OFFLINE_IMMEDIATE);
+        cmd[2] = htons(0x0000U);
+        cmd[3] = htons(0x00C2U);
+        cmd[4] = htons(0x4F00U | (uint16_t) test);
+
+        return disk_command(d, SK_ATA_COMMAND_SMART, SK_DIRECTION_NONE, cmd, NULL, NULL);
+}
+
+static void swap_strings(char *s, size_t len) {
+        assert((len & 1) == 0);
+
+        for (; len > 0; s += 2, len -= 2) {
+                char t;
+                t = s[0];
+                s[0] = s[1];
+                s[1] = t;
+        }
+}
+
+static void clean_strings(char *s) {
+        char *e;
+
+        for (e = s; *e; e++)
+                if (*e < ' ' || *e >= 127)
+                        *e = ' ';
+}
+
+static void drop_spaces(char *s) {
+        char *d = s;
+        SkBool prev_space = FALSE;
+
+        s += strspn(s, " ");
+
+        for (;*s; s++) {
+
+                if (prev_space) {
+                        if (*s != ' ') {
+                                prev_space = FALSE;
+                                *(d++) = ' ';
+                                *(d++) = *s;
+                        }
+                } else {
+                        if (*s == ' ')
+                                prev_space = TRUE;
+                        else
+                                *(d++) = *s;
+                }
+        }
+
+        *d = 0;
+}
+
+static void read_string(char *d, uint8_t *s, size_t len) {
+        memcpy(d, s, len);
+        d[len] = 0;
+        swap_strings(d, len);
+        clean_strings(d);
+        drop_spaces(d);
+}
+
+int sk_disk_identify_parse(SkDisk *d, const SkIdentifyParsedData **ipd) {
+        assert(d);
+        assert(ipd);
+
+        if (!d->identify_valid) {
+                errno = ENOENT;
+                return -1;
+        }
+
+        read_string(d->identify_parsed_data.serial, d->identify+20, 20);
+        read_string(d->identify_parsed_data.firmware, d->identify+46, 8);
+        read_string(d->identify_parsed_data.model, d->identify+54, 40);
+
+        *ipd = &d->identify_parsed_data;
+
+        return 0;
+}
+
+int sk_disk_smart_is_available(SkDisk *d, SkBool *b) {
+        assert(d);
+        assert(b);
+
+        if (!d->identify_valid) {
+                errno = ENOTSUP;
+                return -1;
+        }
+
+        *b = disk_smart_is_available(d);
+        return 0;
+}
+
+int sk_disk_identify_is_available(SkDisk *d, SkBool *b) {
+        assert(d);
+        assert(b);
+
+        *b = d->identify_valid;
+        return 0;
+}
+
+const char *sk_smart_offline_data_collection_status_to_string(SkSmartOfflineDataCollectionStatus status) {
+
+        /* %STRINGPOOLSTART% */
+        static const char* const map[] = {
+                [SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_NEVER] = ((const char*) 198),
+                [SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_SUCCESS] = ((const char*) 251),
+                [SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_INPROGRESS] = ((const char*) 314),
+                [SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_SUSPENDED] = ((const char*) 345),
+                [SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_ABORTED] = ((const char*) 431),
+                [SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_FATAL] = ((const char*) 515),
+                [SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_UNKNOWN] = ((const char*) 595)
+        };
+        /* %STRINGPOOLSTOP% */
+
+        if (status >= _SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_MAX)
+                return NULL;
+
+        return _P(map[status]);
+}
+
+const char *sk_smart_self_test_execution_status_to_string(SkSmartSelfTestExecutionStatus status) {
+
+        /* %STRINGPOOLSTART% */
+        static const char* const map[] = {
+                [SK_SMART_SELF_TEST_EXECUTION_STATUS_SUCCESS_OR_NEVER] = ((const char*) 610),
+                [SK_SMART_SELF_TEST_EXECUTION_STATUS_ABORTED] = ((const char*) 700),
+                [SK_SMART_SELF_TEST_EXECUTION_STATUS_INTERRUPTED] = ((const char*) 747),
+                [SK_SMART_SELF_TEST_EXECUTION_STATUS_FATAL] = ((const char*) 832),
+                [SK_SMART_SELF_TEST_EXECUTION_STATUS_ERROR_UNKNOWN] = ((const char*) 991),
+                [SK_SMART_SELF_TEST_EXECUTION_STATUS_ERROR_ELECTRICAL] = ((const char*) 1092),
+                [SK_SMART_SELF_TEST_EXECUTION_STATUS_ERROR_SERVO] = ((const char*) 1175),
+                [SK_SMART_SELF_TEST_EXECUTION_STATUS_ERROR_READ] = ((const char*) 1272),
+                [SK_SMART_SELF_TEST_EXECUTION_STATUS_ERROR_HANDLING] = ((const char*) 1349),
+                [SK_SMART_SELF_TEST_EXECUTION_STATUS_INPROGRESS] = ((const char*) 1471)
+        };
+        /* %STRINGPOOLSTOP% */
+
+        if (status >= _SK_SMART_SELF_TEST_EXECUTION_STATUS_MAX)
+                return NULL;
+
+        return _P(map[status]);
+}
+
+const char* sk_smart_self_test_to_string(SkSmartSelfTest test) {
+
+        switch (test) {
+                case SK_SMART_SELF_TEST_SHORT:
+                        return "short";
+                case SK_SMART_SELF_TEST_EXTENDED:
+                        return "extended";
+                case SK_SMART_SELF_TEST_CONVEYANCE:
+                        return "conveyance";
+                case SK_SMART_SELF_TEST_ABORT:
+                        return "abort";
+        }
+
+        return NULL;
+}
+
+SkBool sk_smart_self_test_available(const SkSmartParsedData *d, SkSmartSelfTest test) {
+        assert(d);
+
+        if (!d->start_test_available)
+                return FALSE;
+
+        switch (test) {
+                case SK_SMART_SELF_TEST_SHORT:
+                case SK_SMART_SELF_TEST_EXTENDED:
+                        return d->short_and_extended_test_available;
+                case SK_SMART_SELF_TEST_CONVEYANCE:
+                        return d->conveyance_test_available;
+                case SK_SMART_SELF_TEST_ABORT:
+                        return d->abort_test_available;
+                default:
+                        return FALSE;
+        }
+}
+
+unsigned sk_smart_self_test_polling_minutes(const SkSmartParsedData *d, SkSmartSelfTest test) {
+        assert(d);
+
+        if (!sk_smart_self_test_available(d, test))
+                return 0;
+
+        switch (test) {
+                case SK_SMART_SELF_TEST_SHORT:
+                        return d->short_test_polling_minutes;
+                case SK_SMART_SELF_TEST_EXTENDED:
+                        return d->extended_test_polling_minutes;
+                case SK_SMART_SELF_TEST_CONVEYANCE:
+                        return d->conveyance_test_polling_minutes;
+                default:
+                        return 0;
+        }
+}
+
+static void make_pretty(SkSmartAttributeParsedData *a) {
+        uint64_t fourtyeight;
+
+        if (!a->name)
+                return;
+
+        if (a->pretty_unit == SK_SMART_ATTRIBUTE_UNIT_UNKNOWN)
+                return;
+
+        fourtyeight =
+                ((uint64_t) a->raw[0]) |
+                (((uint64_t) a->raw[1]) << 8) |
+                (((uint64_t) a->raw[2]) << 16) |
+                (((uint64_t) a->raw[3]) << 24) |
+                (((uint64_t) a->raw[4]) << 32) |
+                (((uint64_t) a->raw[5]) << 40);
+
+        if (!strcmp(a->name, "spin-up-time"))
+                a->pretty_value = fourtyeight & 0xFFFF;
+        else if (!strcmp(a->name, "airflow-temperature-celsius") ||
+                 !strcmp(a->name, "temperature-celsius") ||
+                 !strcmp(a->name, "temperature-celsius-2"))
+                a->pretty_value = (fourtyeight & 0xFFFF)*1000 + 273150;
+        else if (!strcmp(a->name, "temperature-centi-celsius"))
+                a->pretty_value = (fourtyeight & 0xFFFF)*100 + 273150;
+        else if (!strcmp(a->name, "power-on-minutes"))
+                a->pretty_value = fourtyeight * 60 * 1000;
+        else if (!strcmp(a->name, "power-on-seconds") ||
+                 !strcmp(a->name, "power-on-seconds-2"))
+                a->pretty_value = fourtyeight * 1000;
+        else if (!strcmp(a->name, "power-on-half-minutes"))
+                a->pretty_value = fourtyeight * 30 * 1000;
+        else if (!strcmp(a->name, "power-on-hours") ||
+                 !strcmp(a->name, "loaded-hours") ||
+                 !strcmp(a->name, "head-flying-hours"))
+                a->pretty_value = (fourtyeight & 0xFFFFFFFFU) * 60 * 60 * 1000;
+        else if (!strcmp(a->name, "reallocated-sector-count") ||
+                 !strcmp(a->name, "current-pending-sector"))
+                a->pretty_value = fourtyeight & 0xFFFFFFFFU;
+        else if (!strcmp(a->name, "endurance-remaining") ||
+                 !strcmp(a->name, "available-reserved-space"))
+                a->pretty_value = a->current_value;
+        else if (!strcmp(a->name, "total-lbas-written") ||
+                 !strcmp(a->name, "total-lbas-read"))
+                a->pretty_value = fourtyeight * 65536LLU * 512LLU / 1000000LLU;
+        else if (!strcmp(a->name, "timed-workload-media-wear") ||
+                 !strcmp(a->name, "timed-workload-host-reads"))
+                a->pretty_value = (double)fourtyeight / 1024LLU;
+        else if (!strcmp(a->name, "workload-timer"))
+                a->pretty_value = fourtyeight * 60 * 1000;
+        else
+                a->pretty_value = fourtyeight;
+}
+
+typedef void (*SkSmartAttributeVerify)(SkDisk *d, SkSmartAttributeParsedData *a);
+
+typedef struct SkSmartAttributeInfo {
+        const char *name;
+        SkSmartAttributeUnit unit;
+        SkSmartAttributeVerify verify;
+} SkSmartAttributeInfo;
+
+static void verify_temperature(SkDisk *d, SkSmartAttributeParsedData *a) {
+        assert(a);
+        assert(a->pretty_unit == SK_SMART_ATTRIBUTE_UNIT_MKELVIN);
+
+        if (a->pretty_value < SK_MKELVIN_VALID_MIN ||
+            a->pretty_value > SK_MKELVIN_VALID_MAX) {
+                a->pretty_unit = SK_SMART_ATTRIBUTE_UNIT_UNKNOWN;
+                d->attribute_verification_bad = TRUE;
+        }
+}
+
+static void verify_short_time(SkDisk *d, SkSmartAttributeParsedData *a) {
+        assert(a);
+        assert(a->pretty_unit == SK_SMART_ATTRIBUTE_UNIT_MSECONDS);
+
+        if (a->pretty_value < SK_MSECOND_VALID_MIN ||
+            a->pretty_value > SK_MSECOND_VALID_SHORT_MAX) {
+                a->pretty_unit = SK_SMART_ATTRIBUTE_UNIT_UNKNOWN;
+                d->attribute_verification_bad = TRUE;
+        }
+}
+
+static void verify_long_time(SkDisk *d, SkSmartAttributeParsedData *a) {
+        assert(a);
+        assert(a->pretty_unit == SK_SMART_ATTRIBUTE_UNIT_MSECONDS);
+
+        if (a->pretty_value < SK_MSECOND_VALID_MIN ||
+            a->pretty_value > SK_MSECOND_VALID_LONG_MAX) {
+                a->pretty_unit = SK_SMART_ATTRIBUTE_UNIT_UNKNOWN;
+                d->attribute_verification_bad = TRUE;
+        }
+}
+
+static void verify_sectors(SkDisk *d, SkSmartAttributeParsedData *a) {
+        uint64_t max_sectors;
+
+        assert(d);
+        assert(a);
+        assert(a->pretty_unit == SK_SMART_ATTRIBUTE_UNIT_SECTORS);
+
+        max_sectors = d->size / 512ULL;
+
+        if (a->pretty_value == 0xffffffffULL ||
+            a->pretty_value == 0xffffffffffffULL ||
+            (max_sectors > 0 && a->pretty_value > max_sectors)) {
+                a->pretty_value = SK_SMART_ATTRIBUTE_UNIT_UNKNOWN;
+                d->attribute_verification_bad = TRUE;
+        } else {
+                if ((!strcmp(a->name, "reallocated-sector-count") ||
+                     !strcmp(a->name, "current-pending-sector")) &&
+                    a->pretty_value > 0)
+                        a->warn = TRUE;
+        }
+}
+
+/* This data is stolen from smartmontools */
+
+/* %STRINGPOOLSTART% */
+static const SkSmartAttributeInfo const attribute_info[256] = {
+        [1]   = { ((const char*) 1501),         SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [2]   = { ((const char*) 1521),      SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [3]   = { ((const char*) 3133),                SK_SMART_ATTRIBUTE_UNIT_MSECONDS, verify_short_time },
+        [4]   = { ((const char*) 3146),            SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [5]   = { ((const char*) 1544),    SK_SMART_ATTRIBUTE_UNIT_SECTORS,  verify_sectors },
+        [6]   = { ((const char*) 1569),         SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [7]   = { ((const char*) 1589),             SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [8]   = { ((const char*) 1605),       SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [9]   = { ((const char*) 1627),              SK_SMART_ATTRIBUTE_UNIT_MSECONDS, verify_long_time },
+        [10]  = { ((const char*) 1642),            SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [11]  = { ((const char*) 1659),     SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [12]  = { ((const char*) 1683),           SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [13]  = { ((const char*) 1701),        SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [170] = { ((const char*) 3397),    SK_SMART_ATTRIBUTE_UNIT_PERCENT,  NULL },
+        [171] = { ((const char*) 1722),          SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [172] = { ((const char*) 1741),            SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [175] = { ((const char*) 1758),     SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [176] = { ((const char*) 1782),       SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [177] = { ((const char*) 1804),         SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [178] = { ((const char*) 1824),   SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [179] = { ((const char*) 1850),  SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [180] = { ((const char*) 1877),      SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [181] = { ((const char*) 1900),    SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [182] = { ((const char*) 1925),      SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [183] = { ((const char*) 1948),     SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [184] = { ((const char*) 1972),            SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [187] = { ((const char*) 1989),          SK_SMART_ATTRIBUTE_UNIT_SECTORS,  verify_sectors },
+        [188] = { ((const char*) 2008),             SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [189] = { ((const char*) 2024),             SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [190] = { ((const char*) 2040), SK_SMART_ATTRIBUTE_UNIT_MKELVIN,  verify_temperature },
+        [191] = { ((const char*) 2068),          SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [192] = { ((const char*) 2087),     SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [193] = { ((const char*) 2111),            SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [194] = { ((const char*) 2128),       SK_SMART_ATTRIBUTE_UNIT_MKELVIN,  verify_temperature },
+        [195] = { ((const char*) 2150),      SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [196] = { ((const char*) 2173),     SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [197] = { ((const char*) 2197),      SK_SMART_ATTRIBUTE_UNIT_SECTORS,  verify_sectors },
+        [198] = { ((const char*) 2220),       SK_SMART_ATTRIBUTE_UNIT_SECTORS,  verify_sectors },
+        [199] = { ((const char*) 2242),        SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [200] = { ((const char*) 2263),       SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [201] = { ((const char*) 2285),        SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [202] = { ((const char*) 2306),           SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [203] = { ((const char*) 2324),              SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [204] = { ((const char*) 2339),      SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [205] = { ((const char*) 2362),       SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [206] = { ((const char*) 2384),               SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [207] = { ((const char*) 2398),           SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [208] = { ((const char*) 2416),                   SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [209] = { ((const char*) 2426),    SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [220] = { ((const char*) 2451),                  SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [221] = { ((const char*) 2462),        SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [222] = { ((const char*) 2483),                SK_SMART_ATTRIBUTE_UNIT_MSECONDS, verify_long_time },
+        [223] = { ((const char*) 2496),            SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [224] = { ((const char*) 2513),               SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [225] = { ((const char*) 2527),          SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [226] = { ((const char*) 2546),                SK_SMART_ATTRIBUTE_UNIT_MSECONDS, verify_short_time },
+        [227] = { ((const char*) 2559),              SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [228] = { ((const char*) 2574),   SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL },
+        [230] = { ((const char*) 2600),              SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [231] = { ((const char*) 2048),         SK_SMART_ATTRIBUTE_UNIT_MKELVIN,  verify_temperature },
+
+        /* http://www.adtron.com/pdf/SMART_for_XceedLite_SATA_RevA.pdf */
+        [232] = { ((const char*) 2615),         SK_SMART_ATTRIBUTE_UNIT_PERCENT,  NULL },
+        [233] = { ((const char*) 2635),          SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+        [234] = { ((const char*) 2654),     SK_SMART_ATTRIBUTE_UNIT_SECTORS,  NULL },
+        [235] = { ((const char*) 2678),             SK_SMART_ATTRIBUTE_UNIT_UNKNOWN,  NULL },
+
+        [240] = { ((const char*) 2694),           SK_SMART_ATTRIBUTE_UNIT_MSECONDS, verify_long_time },
+        [241] = { ((const char*) 3311),          SK_SMART_ATTRIBUTE_UNIT_MB,  NULL },
+        [242] = { ((const char*) 2712),             SK_SMART_ATTRIBUTE_UNIT_MB,  NULL },
+        [250] = { ((const char*) 2728),       SK_SMART_ATTRIBUTE_UNIT_NONE,     NULL }
+};
+/* %STRINGPOOLSTOP% */
+
+typedef enum SkSmartQuirk {
+        SK_SMART_QUIRK_9_POWERONMINUTES            = 0x000001,
+        SK_SMART_QUIRK_9_POWERONSECONDS            = 0x000002,
+        SK_SMART_QUIRK_9_POWERONHALFMINUTES        = 0x000004,
+        SK_SMART_QUIRK_192_EMERGENCYRETRACTCYCLECT = 0x000008,
+        SK_SMART_QUIRK_193_LOADUNLOAD              = 0x000010,
+        SK_SMART_QUIRK_194_10XCELSIUS              = 0x000020,
+        SK_SMART_QUIRK_194_UNKNOWN                 = 0x000040,
+        SK_SMART_QUIRK_200_WRITEERRORCOUNT         = 0x000080,
+        SK_SMART_QUIRK_201_DETECTEDTACOUNT         = 0x000100,
+        SK_SMART_QUIRK_5_UNKNOWN                   = 0x000200,
+        SK_SMART_QUIRK_9_UNKNOWN                   = 0x000400,
+        SK_SMART_QUIRK_197_UNKNOWN                 = 0x000800,
+        SK_SMART_QUIRK_198_UNKNOWN                 = 0x001000,
+        SK_SMART_QUIRK_190_UNKNOWN                 = 0x002000,
+        SK_SMART_QUIRK_232_AVAILABLERESERVEDSPACE  = 0x004000,
+        SK_SMART_QUIRK_233_MEDIAWEAROUTINDICATOR   = 0x008000,
+        SK_SMART_QUIRK_225_TOTALLBASWRITTEN        = 0x010000,
+        SK_SMART_QUIRK_4_UNUSED                    = 0x020000,
+        SK_SMART_QUIRK_226_TIMEWORKLOADMEDIAWEAR   = 0x040000,
+        SK_SMART_QUIRK_227_TIMEWORKLOADHOSTREADS   = 0x080000,
+        SK_SMART_QUIRK_228_WORKLOADTIMER           = 0x100000,
+        SK_SMART_QUIRK_3_UNUSED                    = 0x200000
+} SkSmartQuirk;
+
+/* %STRINGPOOLSTART% */
+static const char *quirk_name[] = {
+        ((const char*) 2750),
+        ((const char*) 2767),
+        ((const char*) 2784),
+        ((const char*) 2805),
+        ((const char*) 2833),
+        ((const char*) 2848),
+        ((const char*) 2863),
+        ((const char*) 2875),
+        ((const char*) 2895),
+        ((const char*) 2915),
+        ((const char*) 2925),
+        ((const char*) 2935),
+        ((const char*) 2947),
+        ((const char*) 2959),
+        ((const char*) 2971),
+        ((const char*) 2998),
+        ((const char*) 3024),
+        ((const char*) 3045),
+        ((const char*) 3054),
+        ((const char*) 3080),
+        ((const char*) 3106),
+        ((const char*) 3124),
+        NULL
+};
+/* %STRINGPOOLSTOP% */
+
+typedef struct SkSmartQuirkDatabase {
+        const char *model;
+        const char *firmware;
+        SkSmartQuirk quirk;
+} SkSmartQuirkDatabase;
+
+static const SkSmartQuirkDatabase quirk_database[] = { {
+
+        /*** Fujitsu */
+                "^("
+                "FUJITSU MHY2120BH|"
+                "FUJITSU MHY2250BH"
+                ")$",
+                "^0085000B$", /* seems to be specific to this firmware */
+                SK_SMART_QUIRK_9_POWERONMINUTES|
+                SK_SMART_QUIRK_197_UNKNOWN|
+                SK_SMART_QUIRK_198_UNKNOWN
+        }, {
+                "^FUJITSU MHR2040AT$",
+                NULL,
+                SK_SMART_QUIRK_9_POWERONSECONDS|
+                SK_SMART_QUIRK_192_EMERGENCYRETRACTCYCLECT|
+                SK_SMART_QUIRK_200_WRITEERRORCOUNT
+        }, {
+                "^FUJITSU MHS20[6432]0AT(  .)?$",
+                NULL,
+                SK_SMART_QUIRK_9_POWERONSECONDS|
+                SK_SMART_QUIRK_192_EMERGENCYRETRACTCYCLECT|
+                SK_SMART_QUIRK_200_WRITEERRORCOUNT|
+                SK_SMART_QUIRK_201_DETECTEDTACOUNT
+        }, {
+                "^("
+                "FUJITSU M1623TAU|"
+                "FUJITSU MHG2...ATU?.*|"
+                "FUJITSU MHH2...ATU?.*|"
+                "FUJITSU MHJ2...ATU?.*|"
+                "FUJITSU MHK2...ATU?.*|"
+                "FUJITSU MHL2300AT|"
+                "FUJITSU MHM2(20|15|10|06)0AT|"
+                "FUJITSU MHN2...AT|"
+                "FUJITSU MHR2020AT|"
+                "FUJITSU MHT2...(AH|AS|AT|BH)U?.*|"
+                "FUJITSU MHU2...ATU?.*|"
+                "FUJITSU MHV2...(AH|AS|AT|BH|BS|BT).*|"
+                "FUJITSU MP[A-G]3...A[HTEV]U?.*"
+                ")$",
+                NULL,
+                SK_SMART_QUIRK_9_POWERONSECONDS
+        }, {
+
+        /*** Samsung ***/
+                "^("
+                "SAMSUNG SV4012H|"
+                "SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]"
+                ")$",
+                NULL,
+                SK_SMART_QUIRK_9_POWERONHALFMINUTES
+        }, {
+                "^("
+                "SAMSUNG SV0412H|"
+                "SAMSUNG SV1204H"
+                ")$",
+                NULL,
+                SK_SMART_QUIRK_9_POWERONHALFMINUTES|
+                SK_SMART_QUIRK_194_10XCELSIUS
+        }, {
+                "^SAMSUNG SP40A2H$",
+                "^RR100-07$",
+                SK_SMART_QUIRK_9_POWERONHALFMINUTES
+        }, {
+                "^SAMSUNG SP80A4H$",
+                "^RT100-06$",
+                SK_SMART_QUIRK_9_POWERONHALFMINUTES
+        }, {
+                "^SAMSUNG SP8004H$",
+                "^QW100-61$",
+                SK_SMART_QUIRK_9_POWERONHALFMINUTES
+        }, {
+
+        /*** Maxtor */
+                "^("
+                "Maxtor 2B0(0[468]|1[05]|20)H1|"
+                "Maxtor 4G(120J6|160J[68])|"
+                "Maxtor 4D0(20H1|40H2|60H3|80H4)"
+                ")$",
+                NULL,
+                SK_SMART_QUIRK_9_POWERONMINUTES|
+                SK_SMART_QUIRK_194_UNKNOWN
+        }, {
+                "^("
+                "Maxtor 2F0[234]0[JL]0|"
+                "Maxtor 8(1280A2|2160A4|2560A4|3840A6|4000A6|5120A8)|"
+                "Maxtor 8(2160D2|3228D3|3240D3|4320D4|6480D6|8400D8|8455D8)|"
+                "Maxtor 9(0510D4|0576D4|0648D5|0720D5|0840D6|0845D6|0864D6|1008D7|1080D8|1152D8)|"
+                "Maxtor 9(1(360|350|202)D8|1190D7|10[12]0D6|0840D5|06[48]0D4|0510D3|1(350|202)E8|1010E6|0840E5|0640E4)|"
+                "Maxtor 9(0512D2|0680D3|0750D3|0913D4|1024D4|1360D6|1536D6|1792D7|2048D8)|"
+                "Maxtor 9(2732U8|2390U7|204[09]U6|1707U5|1366U4|1024U3|0845U3|0683U2)|"
+                "Maxtor 4(R0[68]0[JL]0|R1[26]0L0|A160J0|R120L4)|"
+                "Maxtor (91728D8|91512D7|91303D6|91080D5|90845D4|90645D3|90648D[34]|90432D2)|"
+                "Maxtor 9(0431U1|0641U2|0871U2|1301U3|1741U4)|"
+                "Maxtor (94091U8|93071U6|92561U5|92041U4|91731U4|91531U3|91361U3|91021U2|90841U2|90651U2)|"
+                "Maxtor (33073U4|32049U3|31536U2|30768U1|33073H4|32305H3|31536H2|30768H1)|"
+                "Maxtor (93652U8|92739U6|91826U4|91369U3|90913U2|90845U2|90435U1)|"
+                "Maxtor 9(0684U2|1024U2|1362U3|1536U3|2049U4|2562U5|3073U6|4098U8)|"
+                "Maxtor (54098[UH]8|53073[UH]6|52732[UH]6|52049[UH]4|51536[UH]3|51369[UH]3|51024[UH]2)|"
+                "Maxtor 3(1024H1|1535H2|2049H2|3073H3|4098H4)( B)?|"
+                "Maxtor 5(4610H6|4098H6|3073H4|2049H3|1536H2|1369H2|1023H2)|"
+                "Maxtor 9(1023U2|1536U2|2049U3|2305U3|3073U4|4610U6|6147U8)|"
+                "Maxtor 9(1023H2|1536H2|2049H3|2305H3|3073H4|4098H6|4610H6|6147H8)|"
+                "Maxtor 5T0(60H6|40H4|30H3|20H2|10H1)|"
+                "Maxtor (98196H8|96147H6)|"
+                "Maxtor 4W(100H6|080H6|060H4|040H3|030H2)|"
+                "Maxtor 6(E0[234]|K04)0L0|"
+                "Maxtor 6(B(30|25|20|16|12|10|08)0[MPRS]|L(080[MLP]|(100|120)[MP]|160[MP]|200[MPRS]|250[RS]|300[RS]))0|"
+                "Maxtor 6Y((060|080|120|160)L0|(060|080|120|160|200|250)P0|(060|080|120|160|200|250)M0)|"
+                "Maxtor 7Y250[PM]0|"
+                "Maxtor [45]A(25|30|32)0[JN]0|"
+                "Maxtor 7L(25|30)0[SR]0"
+                ")$",
+                NULL,
+                SK_SMART_QUIRK_9_POWERONMINUTES
+        }, {
+
+
+        /*** Hitachi */
+                "^("
+                "HITACHI_DK14FA-20B|"
+                "HITACHI_DK23..-..B?|"
+                "HITACHI_DK23FA-20J|HTA422020F9AT[JN]0|"
+                "HE[JN]4230[23]0F9AT00|"
+                "HTC4260[23]0G5CE00|HTC4260[56]0G8CE00"
+                ")$",
+                NULL,
+                SK_SMART_QUIRK_9_POWERONMINUTES|
+                SK_SMART_QUIRK_193_LOADUNLOAD
+        }, {
+                "^HTS541010G9SA00$",
+                "^MBZOC60P$",
+                SK_SMART_QUIRK_5_UNKNOWN
+        }, {
+
+        /*** Apple SSD (?) http://bugs.freedesktop.org/show_bug.cgi?id=24700
+	                   https://bugs.launchpad.net/ubuntu/+source/gnome-disk-utility/+bug/438136/comments/4 */
+                "^MCCOE64GEMPP$",
+                "^2.9.0[3-9]$",
+                SK_SMART_QUIRK_5_UNKNOWN|
+                SK_SMART_QUIRK_190_UNKNOWN
+        }, {
+
+        /*** Intel */
+                "^INTEL SSDSA2(CT|BT|CW|BW)[0-9]{3}G3.*$", /* 320 Series */
+                NULL,
+                SK_SMART_QUIRK_3_UNUSED|
+                SK_SMART_QUIRK_4_UNUSED|
+                SK_SMART_QUIRK_225_TOTALLBASWRITTEN|
+                SK_SMART_QUIRK_226_TIMEWORKLOADMEDIAWEAR|
+                SK_SMART_QUIRK_227_TIMEWORKLOADHOSTREADS|
+                SK_SMART_QUIRK_228_WORKLOADTIMER|
+                SK_SMART_QUIRK_232_AVAILABLERESERVEDSPACE|
+                SK_SMART_QUIRK_233_MEDIAWEAROUTINDICATOR
+        }, {
+                NULL,
+                NULL,
+                0
+        }
+};
+
+static int match(const char*regex, const char *s, SkBool *result) {
+        int k;
+        regex_t re;
+
+        *result = FALSE;
+
+        if (regcomp(&re, regex, REG_EXTENDED|REG_NOSUB) != 0) {
+                errno = EINVAL;
+                return -1;
+        }
+
+        if ((k = regexec(&re, s, 0, NULL, 0)) != 0) {
+
+                if (k != REG_NOMATCH) {
+                        regfree(&re);
+                        errno = EINVAL;
+                        return -1;
+                }
+
+        } else
+                *result = TRUE;
+
+        regfree(&re);
+
+        return 0;
+}
+
+static int lookup_quirks(const char *model, const char *firmware, SkSmartQuirk *quirk) {
+        int k;
+        const SkSmartQuirkDatabase *db;
+
+        *quirk = 0;
+
+        for (db = quirk_database; db->model || db->firmware; db++) {
+
+                if (db->model) {
+                        SkBool matching = FALSE;
+
+                        if ((k = match(db->model, model, &matching)) < 0)
+                                return k;
+
+                        if (!matching)
+                                continue;
+                }
+
+                if (db->firmware) {
+                        SkBool matching = FALSE;
+
+                        if ((k = match(db->firmware, firmware, &matching)) < 0)
+                                return k;
+
+                        if (!matching)
+                                continue;
+                }
+
+                *quirk = db->quirk;
+                return 0;
+        }
+
+        return 0;
+}
+
+static const SkSmartAttributeInfo *lookup_attribute(SkDisk *d, uint8_t id) {
+        const SkIdentifyParsedData *ipd;
+        SkSmartQuirk quirk = 0;
+
+        /* These are the complex ones */
+        if (sk_disk_identify_parse(d, &ipd) < 0)
+                return NULL;
+
+        if (lookup_quirks(ipd->model, ipd->firmware, &quirk) < 0)
+                return NULL;
+
+        if (quirk) {
+                switch (id) {
+                        case 3:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_3_UNUSED) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3133), SK_SMART_ATTRIBUTE_UNIT_UNKNOWN, NULL
+                                        };
+                                        return &a;
+                                }
+                                /* %STRINGPOOLSTOP% */
+
+                                break;
+
+                        case 4:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_4_UNUSED) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3146), SK_SMART_ATTRIBUTE_UNIT_UNKNOWN, NULL
+                                        };
+                                        return &a;
+                                }
+                                /* %STRINGPOOLSTOP% */
+
+                                break;
+
+                        case 5:
+                                if (quirk & SK_SMART_QUIRK_5_UNKNOWN)
+                                        return NULL;
+
+                                break;
+
+                        case 9:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_9_POWERONMINUTES) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3163), SK_SMART_ATTRIBUTE_UNIT_MSECONDS, verify_long_time
+                                        };
+                                        return &a;
+
+                                } else if (quirk & SK_SMART_QUIRK_9_POWERONSECONDS) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3180), SK_SMART_ATTRIBUTE_UNIT_MSECONDS, verify_long_time
+                                        };
+                                        return &a;
+
+                                } else if (quirk & SK_SMART_QUIRK_9_POWERONHALFMINUTES) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3197), SK_SMART_ATTRIBUTE_UNIT_MSECONDS, verify_long_time
+                                        };
+                                        return &a;
+                                } else if (quirk & SK_SMART_QUIRK_9_UNKNOWN)
+                                        return NULL;
+                                /* %STRINGPOOLSTOP% */
+
+                                break;
+
+                        case 190:
+                                if (quirk & SK_SMART_QUIRK_190_UNKNOWN)
+                                        return NULL;
+
+                                break;
+
+                        case 192:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_192_EMERGENCYRETRACTCYCLECT) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3219), SK_SMART_ATTRIBUTE_UNIT_NONE, NULL
+                                        };
+                                        return &a;
+                                }
+                                /* %STRINGPOOLSTOP% */
+
+                                break;
+
+                        case 194:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_194_10XCELSIUS) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3249), SK_SMART_ATTRIBUTE_UNIT_MKELVIN, verify_temperature
+                                        };
+                                        return &a;
+                                } else if (quirk & SK_SMART_QUIRK_194_UNKNOWN)
+                                        return NULL;
+                                /* %STRINGPOOLSTOP% */
+
+                                break;
+
+                        case 197:
+                                if (quirk & SK_SMART_QUIRK_197_UNKNOWN)
+                                        return NULL;
+
+                                break;
+
+                        case 198:
+                                if (quirk & SK_SMART_QUIRK_198_UNKNOWN)
+                                        return NULL;
+
+                                break;
+
+                        case 200:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_200_WRITEERRORCOUNT) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3275), SK_SMART_ATTRIBUTE_UNIT_NONE, NULL
+                                        };
+                                        return &a;
+                                }
+                                /* %STRINGPOOLSTOP% */
+
+                                break;
+
+                        case 201:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_201_DETECTEDTACOUNT) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3293), SK_SMART_ATTRIBUTE_UNIT_NONE, NULL
+                                        };
+                                        return &a;
+                                }
+                                /* %STRINGPOOLSTOP% */
+
+                                break;
+
+                        case 225:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_225_TOTALLBASWRITTEN) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3311), SK_SMART_ATTRIBUTE_UNIT_MB, NULL
+                                        };
+                                        return &a;
+                                }
+                                /* %STRINGPOOLSTOP% */
+
+                                break;
+
+                        case 226:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_226_TIMEWORKLOADMEDIAWEAR) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3330), SK_SMART_ATTRIBUTE_UNIT_SMALL_PERCENT, NULL
+                                        };
+                                        return &a;
+                                }
+                                /* %STRINGPOOLSTOP% */
+
+                                break;
+
+                        case 227:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_227_TIMEWORKLOADHOSTREADS) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3356), SK_SMART_ATTRIBUTE_UNIT_SMALL_PERCENT, NULL
+                                        };
+                                        return &a;
+                                }
+                                /* %STRINGPOOLSTOP% */
+
+                                break;
+
+                        case 228:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_228_WORKLOADTIMER) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3382), SK_SMART_ATTRIBUTE_UNIT_MSECONDS, NULL
+                                        };
+                                        return &a;
+                                }
+                                /* %STRINGPOOLSTOP% */
+
+                                break;
+
+                        case 232:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_232_AVAILABLERESERVEDSPACE) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3397), SK_SMART_ATTRIBUTE_UNIT_PERCENT, NULL
+                                        };
+                                        return &a;
+                                }
+                                /* %STRINGPOOLSTOP% */
+                                break;
+
+                        case 233:
+                                /* %STRINGPOOLSTART% */
+                                if (quirk & SK_SMART_QUIRK_233_MEDIAWEAROUTINDICATOR) {
+                                        static const SkSmartAttributeInfo a = {
+                                                ((const char*) 3422), SK_SMART_ATTRIBUTE_UNIT_PERCENT, NULL
+                                        };
+                                        return &a;
+                                }
+                                /* %STRINGPOOLSTOP% */
+                                break;
+
+                }
+        }
+
+        /* These are the simple cases */
+        if (attribute_info[id].name)
+                return &attribute_info[id];
+
+        return NULL;
+}
+
+int sk_disk_smart_parse(SkDisk *d, const SkSmartParsedData **spd) {
+
+        if (!d->smart_data_valid) {
+                errno = ENOENT;
+                return -1;
+        }
+
+        switch (d->smart_data[362]) {
+                case 0x00:
+                case 0x80:
+                        d->smart_parsed_data.offline_data_collection_status = SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_NEVER;
+                        break;
+
+                case 0x02:
+                case 0x82:
+                        d->smart_parsed_data.offline_data_collection_status = SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_SUCCESS;
+                        break;
+
+                case 0x03:
+                        d->smart_parsed_data.offline_data_collection_status = SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_INPROGRESS;
+                        break;
+
+                case 0x04:
+                case 0x84:
+                        d->smart_parsed_data.offline_data_collection_status = SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_SUSPENDED;
+                        break;
+
+                case 0x05:
+                case 0x85:
+                        d->smart_parsed_data.offline_data_collection_status = SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_ABORTED;
+                        break;
+
+                case 0x06:
+                case 0x86:
+                        d->smart_parsed_data.offline_data_collection_status = SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_FATAL;
+                        break;
+
+                default:
+                        d->smart_parsed_data.offline_data_collection_status = SK_SMART_OFFLINE_DATA_COLLECTION_STATUS_UNKNOWN;
+                        break;
+        }
+
+        d->smart_parsed_data.self_test_execution_percent_remaining = 10*(d->smart_data[363] & 0xF);
+        d->smart_parsed_data.self_test_execution_status = (d->smart_data[363] >> 4) & 0xF;
+
+        d->smart_parsed_data.total_offline_data_collection_seconds = (uint16_t) d->smart_data[364] | ((uint16_t) d->smart_data[365] << 8);
+
+        d->smart_parsed_data.conveyance_test_available = disk_smart_is_conveyance_test_available(d);
+        d->smart_parsed_data.short_and_extended_test_available = disk_smart_is_short_and_extended_test_available(d);
+        d->smart_parsed_data.start_test_available = disk_smart_is_start_test_available(d);
+        d->smart_parsed_data.abort_test_available = disk_smart_is_abort_test_available(d);
+
+        d->smart_parsed_data.short_test_polling_minutes = d->smart_data[372];
+        d->smart_parsed_data.extended_test_polling_minutes = d->smart_data[373] != 0xFF ? d->smart_data[373] : ((uint16_t) d->smart_data[376] << 8 | (uint16_t) d->smart_data[375]);
+        d->smart_parsed_data.conveyance_test_polling_minutes = d->smart_data[374];
+
+        *spd = &d->smart_parsed_data;
+
+        return 0;
+}
+
+static void find_threshold(SkDisk *d, SkSmartAttributeParsedData *a) {
+        uint8_t *p;
+        unsigned n;
+
+        if (!d->smart_thresholds_valid)
+                goto fail;
+
+        for (n = 0, p = d->smart_thresholds+2; n < 30; n++, p+=12)
+                if (p[0] == a->id)
+                        break;
+
+        if (n >= 30)
+                goto fail;
+
+        a->threshold = p[1];
+        a->threshold_valid = p[1] != 0xFE;
+
+        a->good_now_valid = FALSE;
+        a->good_now = TRUE;
+        a->good_in_the_past_valid = FALSE;
+        a->good_in_the_past = TRUE;
+
+        /* Always-Fail and Always-Passing thresholds are not relevant
+         * for our assessment. */
+        if (p[1] >= 1 && p[1] <= 0xFD) {
+
+                if (a->worst_value_valid) {
+                        a->good_in_the_past = a->good_in_the_past && (a->worst_value > a->threshold);
+                        a->good_in_the_past_valid = TRUE;
+                }
+
+                if (a->current_value_valid) {
+                        a->good_now = a->good_now && (a->current_value > a->threshold);
+                        a->good_now_valid = TRUE;
+                }
+        }
+
+        a->warn =
+                (a->good_now_valid && !a->good_now) ||
+                (a->good_in_the_past_valid && !a->good_in_the_past);
+
+        return;
+
+fail:
+        a->threshold_valid = FALSE;
+        a->good_now_valid = FALSE;
+        a->good_in_the_past_valid = FALSE;
+        a->warn = FALSE;
+}
+
+int sk_disk_smart_parse_attributes(SkDisk *d, SkSmartAttributeParseCallback cb, void* userdata) {
+        uint8_t *p;
+        unsigned n;
+
+        if (!d->smart_data_valid) {
+                errno = ENOENT;
+                return -1;
+        }
+
+        for (n = 0, p = d->smart_data + 2; n < 30; n++, p+=12) {
+                SkSmartAttributeParsedData a;
+                const SkSmartAttributeInfo *i;
+                char *an = NULL;
+
+                if (p[0] == 0)
+                        continue;
+
+                memset(&a, 0, sizeof(a));
+                a.id = p[0];
+                a.current_value = p[3];
+                a.current_value_valid = p[3] >= 1 && p[3] <= 0xFD;
+                a.worst_value = p[4];
+                a.worst_value_valid = p[4] >= 1 && p[4] <= 0xFD;
+
+                a.flags = ((uint16_t) p[2] << 8) | p[1];
+                a.prefailure = !!(p[1] & 1);
+                a.online = !!(p[1] & 2);
+
+                memcpy(a.raw, p+5, 6);
+
+                if ((i = lookup_attribute(d, p[0]))) {
+                        a.name = _P(i->name);
+                        a.pretty_unit = i->unit;
+                } else {
+                        if (asprintf(&an, "attribute-%u", a.id) < 0) {
+                                errno = ENOMEM;
+                                return -1;
+                        }
+
+                        a.name = an;
+                        a.pretty_unit = SK_SMART_ATTRIBUTE_UNIT_UNKNOWN;
+                }
+
+                make_pretty(&a);
+
+                find_threshold(d, &a);
+
+                if (i && i->verify)
+                        i->verify(d, &a);
+
+                cb(d, &a, userdata);
+                free(an);
+        }
+
+        return 0;
+}
+
+static const char *yes_no(SkBool b) {
+        return  b ? "yes" : "no";
+}
+
+const char* sk_smart_attribute_unit_to_string(SkSmartAttributeUnit unit) {
+
+        /* %STRINGPOOLSTART% */
+        const char * const map[] = {
+                [SK_SMART_ATTRIBUTE_UNIT_UNKNOWN] = NULL,
+                [SK_SMART_ATTRIBUTE_UNIT_NONE] = ((const char*) 30),
+                [SK_SMART_ATTRIBUTE_UNIT_MSECONDS] = ((const char*) 3446),
+                [SK_SMART_ATTRIBUTE_UNIT_SECTORS] = ((const char*) 3449),
+                [SK_SMART_ATTRIBUTE_UNIT_MKELVIN] = ((const char*) 3457),
+                [SK_SMART_ATTRIBUTE_UNIT_PERCENT] = ((const char*) 3460),
+                [SK_SMART_ATTRIBUTE_UNIT_SMALL_PERCENT] = ((const char*) 3460),
+                [SK_SMART_ATTRIBUTE_UNIT_MB] = ((const char*) 3462)
+        };
+        /* %STRINGPOOLSTOP% */
+
+        if (unit >= _SK_SMART_ATTRIBUTE_UNIT_MAX)
+                return NULL;
+
+        return _P(map[unit]);
+}
+
+struct attr_helper {
+        uint64_t *value;
+        SkBool found;
+};
+
+static void temperature_cb(SkDisk *d, const SkSmartAttributeParsedData *a, struct attr_helper *ah) {
+
+        if (a->pretty_unit != SK_SMART_ATTRIBUTE_UNIT_MKELVIN)
+                return;
+
+        if (!strcmp(a->name, "temperature-centi-celsius") ||
+            !strcmp(a->name, "temperature-celsius") ||
+            !strcmp(a->name, "temperature-celsius-2") ||
+            !strcmp(a->name, "airflow-temperature-celsius")) {
+
+                if (!ah->found || a->pretty_value > *ah->value)
+                        *ah->value = a->pretty_value;
+
+                ah->found = TRUE;
+        }
+}
+
+int sk_disk_smart_get_temperature(SkDisk *d, uint64_t *kelvin) {
+        struct attr_helper ah;
+
+        assert(d);
+        assert(kelvin);
+
+        ah.found = FALSE;
+        ah.value = kelvin;
+
+        if (sk_disk_smart_parse_attributes(d, (SkSmartAttributeParseCallback) temperature_cb, &ah) < 0)
+                return -1;
+
+        if (!ah.found) {
+                errno = ENOENT;
+                return -1;
+        }
+
+        return 0;
+}
+
+static void power_on_cb(SkDisk *d, const SkSmartAttributeParsedData *a, struct attr_helper *ah) {
+
+        if (a->pretty_unit != SK_SMART_ATTRIBUTE_UNIT_MSECONDS)
+                return;
+
+        if (!strcmp(a->name, "power-on-minutes") ||
+            !strcmp(a->name, "power-on-seconds") ||
+            !strcmp(a->name, "power-on-seconds-2") ||
+            !strcmp(a->name, "power-on-half-minutes") ||
+            !strcmp(a->name, "power-on-hours")) {
+
+                if (!ah->found || a->pretty_value > *ah->value)
+                        *ah->value = a->pretty_value;
+
+                ah->found = TRUE;
+        }
+}
+
+int sk_disk_smart_get_power_on(SkDisk *d, uint64_t *mseconds) {
+        struct attr_helper ah;
+
+        assert(d);
+        assert(mseconds);
+
+        ah.found = FALSE;
+        ah.value = mseconds;
+
+        if (sk_disk_smart_parse_attributes(d, (SkSmartAttributeParseCallback) power_on_cb, &ah) < 0)
+                return -1;
+
+        if (!ah.found) {
+                errno = ENOENT;
+                return -1;
+        }
+
+        return 0;
+}
+
+static void power_cycle_cb(SkDisk *d, const SkSmartAttributeParsedData *a, struct attr_helper *ah) {
+
+        if (a->pretty_unit != SK_SMART_ATTRIBUTE_UNIT_NONE)
+                return;
+
+        if (!strcmp(a->name, "power-cycle-count")) {
+
+                if (!ah->found || a->pretty_value > *ah->value)
+                        *ah->value = a->pretty_value;
+
+                ah->found = TRUE;
+        }
+}
+
+int sk_disk_smart_get_power_cycle(SkDisk *d, uint64_t *count) {
+        struct attr_helper ah;
+
+        assert(d);
+        assert(count);
+
+        ah.found = FALSE;
+        ah.value = count;
+
+        if (sk_disk_smart_parse_attributes(d, (SkSmartAttributeParseCallback) power_cycle_cb, &ah) < 0)
+                return -1;
+
+        if (!ah.found) {
+                errno = ENOENT;
+                return -1;
+        }
+
+        return 0;
+}
+
+static void fill_cache_cb(SkDisk *d, const SkSmartAttributeParsedData *a, void* userdata) {
+
+        if (a->prefailure) {
+                if (a->good_now_valid && !a->good_now)
+                    d->bad_attribute_now = TRUE;
+
+                if (a->good_in_the_past_valid && !a->good_in_the_past)
+                    d->bad_attribute_in_the_past = TRUE;
+        }
+
+        if (a->pretty_unit != SK_SMART_ATTRIBUTE_UNIT_SECTORS)
+                return;
+
+        if (!strcmp(a->name, "reallocated-sector-count")) {
+                if (a->pretty_value > d->reallocated_sector_count)
+                        d->reallocated_sector_count = a->pretty_value;
+                d->reallocated_sector_count_found = TRUE;
+        }
+
+        if (!strcmp(a->name, "current-pending-sector")) {
+                if (a->pretty_value > d->current_pending_sector)
+                        d->current_pending_sector = a->pretty_value;
+                d->current_pending_sector_found = TRUE;
+        }
+}
+
+static int fill_cache(SkDisk *d) {
+        if (d->attribute_cache_valid)
+                return 0;
+
+        if (sk_disk_smart_parse_attributes(d, (SkSmartAttributeParseCallback) fill_cache_cb, NULL) >= 0) {
+                d->attribute_cache_valid = TRUE;
+                return 0;
+        } else
+                return -1;
+}
+
+int sk_disk_smart_get_bad(SkDisk *d, uint64_t *sectors) {
+        assert(d);
+        assert(sectors);
+
+        if (fill_cache (d) < 0)
+                return -1;
+
+        if (!d->reallocated_sector_count_found && !d->current_pending_sector_found) {
+                errno = ENOENT;
+                return -1;
+        }
+
+        if (d->reallocated_sector_count_found && d->current_pending_sector_found)
+                *sectors = d->reallocated_sector_count + d->current_pending_sector;
+        else if (d->reallocated_sector_count_found)
+                *sectors = d->reallocated_sector_count;
+        else
+                *sectors = d->current_pending_sector;
+
+        return 0;
+}
+
+const char* sk_smart_overall_to_string(SkSmartOverall overall) {
+
+        /* %STRINGPOOLSTART% */
+        const char * const map[] = {
+                [SK_SMART_OVERALL_GOOD] = ((const char*) 3465),
+                [SK_SMART_OVERALL_BAD_ATTRIBUTE_IN_THE_PAST] = ((const char*) 3470),
+                [SK_SMART_OVERALL_BAD_SECTOR] = ((const char*) 3496),
+                [SK_SMART_OVERALL_BAD_ATTRIBUTE_NOW] = ((const char*) 3507),
+                [SK_SMART_OVERALL_BAD_SECTOR_MANY] = ((const char*) 3525),
+                [SK_SMART_OVERALL_BAD_STATUS] = ((const char*) 3541),
+        };
+        /* %STRINGPOOLSTOP% */
+
+        if (overall >= _SK_SMART_OVERALL_MAX)
+                return NULL;
+
+        return _P(map[overall]);
+}
+
+static uint64_t u64log2(uint64_t n) {
+        unsigned r;
+
+        if (n <= 1)
+                return 0;
+
+        r = 0;
+        for (;;) {
+                n = n >> 1;
+                if (!n)
+                        return r;
+                r++;
+        }
+}
+
+int sk_disk_smart_get_overall(SkDisk *d, SkSmartOverall *overall) {
+        SkBool good;
+        uint64_t sectors, sector_threshold;
+
+        assert(d);
+        assert(overall);
+
+        /* First, check SMART self-assesment */
+        if (sk_disk_smart_status(d, &good) < 0)
+                return -1;
+
+        if (!good) {
+                *overall = SK_SMART_OVERALL_BAD_STATUS;
+                return 0;
+        }
+
+        /* Second, check if the number of bad sectors is greater than
+         * a certain threshold */
+        if (sk_disk_smart_get_bad(d, &sectors) < 0) {
+                if (errno != ENOENT)
+                        return -1;
+                sectors = 0;
+        } else {
+
+                /* We use log2(n_sectors)*1024 as a threshold here. We
+                 * had to pick something, and this makes a bit of
+                 * sense, or doesn't it? */
+                sector_threshold = u64log2(d->size/512) * 1024;
+
+                if (sectors >= sector_threshold) {
+                        *overall = SK_SMART_OVERALL_BAD_SECTOR_MANY;
+                        return 0;
+                }
+        }
+
+        /* Third, check if any of the SMART attributes is bad */
+        if (fill_cache (d) < 0)
+                return -1;
+
+        if (d->bad_attribute_now) {
+                *overall = SK_SMART_OVERALL_BAD_ATTRIBUTE_NOW;
+                return 0;
+        }
+
+        /* Fourth, check if there are any bad sectors at all */
+        if (sectors > 0) {
+                *overall = SK_SMART_OVERALL_BAD_SECTOR;
+                return 0;
+        }
+
+        /* Fifth, check if any of the SMART attributes ever was bad */
+        if (d->bad_attribute_in_the_past) {
+                *overall = SK_SMART_OVERALL_BAD_ATTRIBUTE_IN_THE_PAST;
+                return 0;
+        }
+
+        /* Sixth, there's really nothing to complain about, so give it a pass */
+        *overall = SK_SMART_OVERALL_GOOD;
+        return 0;
+}
+
+static char* print_name(char *s, size_t len, uint8_t id, const char *k) {
+
+        if (k)
+                strncpy(s, k, len);
+        else
+                snprintf(s, len, "%u", id);
+
+        s[len-1] = 0;
+
+        return s;
+}
+
+static char *print_value(char *s, size_t len, uint64_t pretty_value, SkSmartAttributeUnit pretty_unit) {
+
+        switch (pretty_unit) {
+                case SK_SMART_ATTRIBUTE_UNIT_MSECONDS:
+
+                        if (pretty_value >= 1000LLU*60LLU*60LLU*24LLU*365LLU)
+                                snprintf(s, len, "%0.1f years", ((double) pretty_value)/(1000.0*60*60*24*365));
+                        else if (pretty_value >= 1000LLU*60LLU*60LLU*24LLU*30LLU)
+                                snprintf(s, len, "%0.1f months", ((double) pretty_value)/(1000.0*60*60*24*30));
+                        else if (pretty_value >= 1000LLU*60LLU*60LLU*24LLU)
+                                snprintf(s, len, "%0.1f days", ((double) pretty_value)/(1000.0*60*60*24));
+                        else if (pretty_value >= 1000LLU*60LLU*60LLU)
+                                snprintf(s, len, "%0.1f h", ((double) pretty_value)/(1000.0*60*60));
+                        else if (pretty_value >= 1000LLU*60LLU)
+                                snprintf(s, len, "%0.1f min", ((double) pretty_value)/(1000.0*60));
+                        else if (pretty_value >= 1000LLU)
+                                snprintf(s, len, "%0.1f s", ((double) pretty_value)/(1000.0));
+                        else
+                                snprintf(s, len, "%llu ms", (unsigned long long) pretty_value);
+
+                        break;
+
+                case SK_SMART_ATTRIBUTE_UNIT_MKELVIN:
+                        snprintf(s, len, "%0.1f C", ((double) pretty_value - 273150) / 1000);
+                        break;
+
+                case SK_SMART_ATTRIBUTE_UNIT_SECTORS:
+                        snprintf(s, len, "%llu sectors", (unsigned long long) pretty_value);
+                        break;
+
+                case SK_SMART_ATTRIBUTE_UNIT_PERCENT:
+                        snprintf(s, len, "%llu%%", (unsigned long long) pretty_value);
+                        break;
+
+                case SK_SMART_ATTRIBUTE_UNIT_SMALL_PERCENT:
+                        snprintf(s, len, "%0.3f%%", (double) pretty_value);
+                        break;
+
+                case SK_SMART_ATTRIBUTE_UNIT_MB:
+                        if (pretty_value >= 1000000LLU)
+                          snprintf(s, len, "%0.3f TB",  (double) pretty_value / 1000000LLU);
+                        else if (pretty_value >= 1000LLU)
+                          snprintf(s, len, "%0.3f GB",  (double) pretty_value / 1000LLU);
+                        else
+                          snprintf(s, len, "%llu MB", (unsigned long long) pretty_value);
+                        break;
+
+                case SK_SMART_ATTRIBUTE_UNIT_NONE:
+                        snprintf(s, len, "%llu", (unsigned long long) pretty_value);
+                        break;
+
+                case SK_SMART_ATTRIBUTE_UNIT_UNKNOWN:
+                        snprintf(s, len, "n/a");
+                        break;
+
+                case _SK_SMART_ATTRIBUTE_UNIT_MAX:
+                        assert(FALSE);
+        }
+
+        s[len-1] = 0;
+
+        return s;
+}
+
+#define HIGHLIGHT "\x1B[1m"
+#define ENDHIGHLIGHT "\x1B[0m"
+
+static void disk_dump_attributes(SkDisk *d, const SkSmartAttributeParsedData *a, void* userdata) {
+        char name[32];
+        char pretty[32];
+        char tt[32], tw[32], tc[32];
+        SkBool highlight;
+
+        snprintf(tt, sizeof(tt), "%3u", a->threshold);
+        tt[sizeof(tt)-1] = 0;
+        snprintf(tw, sizeof(tw), "%3u", a->worst_value);
+        tw[sizeof(tw)-1] = 0;
+        snprintf(tc, sizeof(tc), "%3u", a->current_value);
+        tc[sizeof(tc)-1] = 0;
+
+        highlight = a->warn && isatty(1);
+
+        if (highlight)
+                fprintf(stderr, HIGHLIGHT);
+
+        printf("%3u %-27s %-3s   %-3s   %-3s   %-11s 0x%02x%02x%02x%02x%02x%02x %-7s %-7s %-4s %-4s\n",
+               a->id,
+               print_name(name, sizeof(name), a->id, a->name),
+               a->current_value_valid ? tc : "n/a",
+               a->worst_value_valid ? tw : "n/a",
+               a->threshold_valid ? tt : "n/a",
+               print_value(pretty, sizeof(pretty), a->pretty_value, a->pretty_unit),
+               a->raw[0], a->raw[1], a->raw[2], a->raw[3], a->raw[4], a->raw[5],
+               a->prefailure ? "prefail" : "old-age",
+               a->online ? "online" : "offline",
+               a->good_now_valid ? yes_no(a->good_now) : "n/a",
+               a->good_in_the_past_valid ? yes_no(a->good_in_the_past) : "n/a");
+
+        if (highlight)
+                fprintf(stderr, ENDHIGHLIGHT);
+}
+
+int sk_disk_dump(SkDisk *d) {
+        int ret;
+        SkBool awake = FALSE;
+        uint64_t size;
+
+        assert(d);
+
+        printf("Device: %s%s%s\n"
+               "Type: %s\n",
+               d->name ? disk_type_to_prefix_string(d->type) : "",
+               d->name ? ":" : "",
+               d->name ? d->name : "n/a",
+               disk_type_to_human_string(d->type));
+
+        ret = sk_disk_get_size(d, &size);
+        if (ret >= 0)
+                printf("Size: %lu MiB\n", (unsigned long) (d->size/1024/1024));
+        else
+                printf("Size: %s\n", strerror(errno));
+
+        if (d->identify_valid) {
+                const SkIdentifyParsedData *ipd;
+                SkSmartQuirk quirk = 0;
+                unsigned i;
+
+                if ((ret = sk_disk_identify_parse(d, &ipd)) < 0)
+                        return ret;
+
+                printf("Model: [%s]\n"
+                       "Serial: [%s]\n"
+                       "Firmware: [%s]\n"
+                       "SMART Available: %s\n",
+                       ipd->model,
+                       ipd->serial,
+                       ipd->firmware,
+                       yes_no(disk_smart_is_available(d)));
+
+                if ((ret = lookup_quirks(ipd->model, ipd->firmware, &quirk)))
+                        return ret;
+
+                printf("Quirks:");
+
+                for (i = 0; quirk_name[i]; i++)
+                        if (quirk & (1<<i))
+                                printf(" %s", _P(quirk_name[i]));
+
+                printf("\n");
+        }
+
+        ret = sk_disk_check_sleep_mode(d, &awake);
+        printf("Awake: %s\n",
+               ret >= 0 ? yes_no(awake) : strerror(errno));
+
+        if (disk_smart_is_available(d)) {
+                SkSmartOverall overall;
+                const SkSmartParsedData *spd;
+                SkBool good;
+                char pretty[32];
+                uint64_t value, power_on;
+
+                ret = sk_disk_smart_status(d, &good);
+                printf("%sSMART Disk Health Good: %s%s\n",
+                       ret >= 0 && !good ? HIGHLIGHT : "",
+                       ret >= 0 ? yes_no(good) : strerror(errno),
+                       ret >= 0 && !good ? ENDHIGHLIGHT : "");
+                if ((ret = sk_disk_smart_read_data(d)) < 0)
+                        return ret;
+
+                if ((ret = sk_disk_smart_parse(d, &spd)) < 0)
+                        return ret;
+
+                printf("Off-line Data Collection Status: [%s]\n"
+                       "Total Time To Complete Off-Line Data Collection: %u s\n"
+                       "Self-Test Execution Status: [%s]\n"
+                       "Percent Self-Test Remaining: %u%%\n"
+                       "Conveyance Self-Test Available: %s\n"
+                       "Short/Extended Self-Test Available: %s\n"
+                       "Start Self-Test Available: %s\n"
+                       "Abort Self-Test Available: %s\n"
+                       "Short Self-Test Polling Time: %u min\n"
+                       "Extended Self-Test Polling Time: %u min\n"
+                       "Conveyance Self-Test Polling Time: %u min\n",
+                       sk_smart_offline_data_collection_status_to_string(spd->offline_data_collection_status),
+                       spd->total_offline_data_collection_seconds,
+                       sk_smart_self_test_execution_status_to_string(spd->self_test_execution_status),
+                       spd->self_test_execution_percent_remaining,
+                       yes_no(spd->conveyance_test_available),
+                       yes_no(spd->short_and_extended_test_available),
+                       yes_no(spd->start_test_available),
+                       yes_no(spd->abort_test_available),
+                       spd->short_test_polling_minutes,
+                       spd->extended_test_polling_minutes,
+                       spd->conveyance_test_polling_minutes);
+
+                if (sk_disk_smart_get_bad(d, &value) < 0)
+                        printf("Bad Sectors: %s\n", strerror(errno));
+                else
+                        printf("%sBad Sectors: %s%s\n",
+                               value > 0 ? HIGHLIGHT : "",
+                               print_value(pretty, sizeof(pretty), value, SK_SMART_ATTRIBUTE_UNIT_SECTORS),
+                               value > 0 ? ENDHIGHLIGHT : "");
+
+                if (sk_disk_smart_get_power_on(d, &power_on) < 0) {
+                        printf("Powered On: %s\n", strerror(errno));
+                        power_on = 0;
+                } else
+                        printf("Powered On: %s\n", print_value(pretty, sizeof(pretty), power_on, SK_SMART_ATTRIBUTE_UNIT_MSECONDS));
+
+                if (sk_disk_smart_get_power_cycle(d, &value) < 0)
+                        printf("Power Cycles: %s\n", strerror(errno));
+                else {
+                        printf("Power Cycles: %llu\n", (unsigned long long) value);
+
+                        if (value > 0 && power_on > 0)
+                                printf("Average Powered On Per Power Cycle: %s\n", print_value(pretty, sizeof(pretty), power_on/value, SK_SMART_ATTRIBUTE_UNIT_MSECONDS));
+                }
+
+                if (sk_disk_smart_get_temperature(d, &value) < 0)
+                        printf("Temperature: %s\n", strerror(errno));
+                else
+                        printf("Temperature: %s\n", print_value(pretty, sizeof(pretty), value, SK_SMART_ATTRIBUTE_UNIT_MKELVIN));
+
+                printf("Attribute Parsing Verification: %s\n",
+                       d->attribute_verification_bad ? "Bad" : "Good");
+
+                if (sk_disk_smart_get_overall(d, &overall) < 0)
+                        printf("Overall Status: %s\n", strerror(errno));
+                else
+                        printf("%sOverall Status: %s%s\n",
+                               overall != SK_SMART_OVERALL_GOOD ? HIGHLIGHT : "",
+                               sk_smart_overall_to_string(overall),
+                               overall != SK_SMART_OVERALL_GOOD ? ENDHIGHLIGHT : "");
+
+                printf("%3s %-27s %5s %5s %5s %-11s %-14s %-7s %-7s %-4s %-4s\n",
+                       "ID#",
+                       "Name",
+                       "Value",
+                       "Worst",
+                       "Thres",
+                       "Pretty",
+                       "Raw",
+                       "Type",
+                       "Updates",
+                       "Good",
+                       "Good/Past");
+
+                if ((ret = sk_disk_smart_parse_attributes(d, disk_dump_attributes, NULL)) < 0)
+                        return ret;
+        } else
+                printf("ATA SMART not supported.\n");
+
+        return 0;
+}
+
+int sk_disk_get_size(SkDisk *d, uint64_t *bytes) {
+        assert(d);
+        assert(bytes);
+
+        if (d->size == (uint64_t) -1) {
+                errno = ENODATA;
+                return -1;
+        }
+
+        *bytes = d->size;
+        return 0;
+}
+
+static int disk_find_type(SkDisk *d, dev_t devnum) {
+        struct udev *udev;
+        struct udev_device *dev = NULL, *usb;
+        int r = -1;
+        const char *a;
+
+        assert(d);
+
+        if (!(udev = udev_new())) {
+                errno = ENXIO;
+                goto finish;
+        }
+
+        if (!(dev = udev_device_new_from_devnum(udev, 'b', devnum))) {
+                errno = ENODEV;
+                goto finish;
+        }
+
+        if ((a = udev_device_get_property_value(dev, "ID_ATA_SMART_ACCESS"))) {
+                unsigned u;
+
+                for (u = 0; u < _SK_DISK_TYPE_MAX; u++) {
+                        const char *t;
+
+                        if (!(t = disk_type_to_prefix_string(u)))
+                                continue;
+
+                        if (!strcmp(a, t)) {
+                                d->type = u;
+                                r = 0;
+                                goto finish;
+                        }
+                }
+
+                d->type = SK_DISK_TYPE_NONE;
+                r = 0;
+                goto finish;
+        }
+
+        if ((usb = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"))) {
+                const char *product, *vendor;
+                uint32_t pid, vid;
+
+                if (!(product = udev_device_get_sysattr_value(usb, "idProduct")) ||
+                    sscanf(product, "%04x", &pid) != 1) {
+                        errno = ENODEV;
+                        goto finish;
+                }
+
+                if (!(vendor = udev_device_get_sysattr_value(usb, "idVendor")) ||
+                    sscanf(vendor, "%04x", &vid) != 1) {
+                        errno = ENODEV;
+                        goto finish;
+                }
+
+                if ((vid == 0x0928 && pid == 0x0000))
+                        /* This Oxford Semiconductor bridge seems to
+                         * choke on SAT commands. Let's explicitly
+                         * black list it here.
+                         *
+                         * http://bugs.freedesktop.org/show_bug.cgi?id=24951 */
+                        d->type = SK_DISK_TYPE_NONE;
+                else if ((vid == 0x152d && pid == 0x2329) ||
+                         (vid == 0x152d && pid == 0x2338) ||
+                         (vid == 0x152d && pid == 0x2339))
+                        /* Some JMicron bridges seem to choke on SMART
+                         * commands, so let's explicitly black list
+                         * them here.
+                         *
+                         * https://bugzilla.redhat.com/show_bug.cgi?id=515881
+                         *
+                         * At least some of the JMicron bridges with
+                         * these vids/pids choke on the jmicron access
+                         * mode. To make sure we don't break things
+                         * for people we now disable this by
+                         * default. */
+                        d->type = SK_DISK_TYPE_NONE;
+                else if ((vid == 0x152d && pid == 0x2336))
+                        /* This JMicron bridge seems to always work
+                         * with SMART commands send with the jmicron
+                         * access mode. */
+                        d->type = SK_DISK_TYPE_JMICRON;
+                else if ((vid == 0x0c0b && pid == 0xb159) ||
+                    (vid == 0x04fc && pid == 0x0c25) ||
+                    (vid == 0x04fc && pid == 0x0c15))
+                        d->type = SK_DISK_TYPE_SUNPLUS;
+                else
+                        d->type = SK_DISK_TYPE_ATA_PASSTHROUGH_12;
+
+        } else if (udev_device_get_parent_with_subsystem_devtype(dev, "ide", NULL))
+                d->type = SK_DISK_TYPE_LINUX_IDE;
+        else if (udev_device_get_parent_with_subsystem_devtype(dev, "scsi", NULL))
+                d->type = SK_DISK_TYPE_ATA_PASSTHROUGH_16;
+        else
+                d->type = SK_DISK_TYPE_AUTO;
+
+        r = 0;
+
+finish:
+        if (dev)
+                udev_device_unref(dev);
+
+        if (udev)
+                udev_unref(udev);
+
+        return r;
+}
+
+static int init_smart(SkDisk *d) {
+        /* We don't do the SMART initialization right-away, since some
+         * drivers spin up when we do that */
+
+        int ret;
+
+        if (d->smart_initialized)
+                return 0;
+
+        d->smart_initialized = TRUE;
+
+        /* Check if driver can do SMART, and enable if necessary */
+        if (!disk_smart_is_available(d))
+                return 0;
+
+        if (!disk_smart_is_enabled(d)) {
+                if ((ret = disk_smart_enable(d, TRUE)) < 0)
+                        goto fail;
+
+                if ((ret = disk_identify_device(d)) < 0)
+                        goto fail;
+
+                if (!disk_smart_is_enabled(d)) {
+                        errno = EIO;
+                        ret = -1;
+                        goto fail;
+                }
+        }
+
+        disk_smart_read_thresholds(d);
+        ret = 0;
+
+fail:
+        return ret;
+}
+
+int sk_disk_open(const char *name, SkDisk **_d) {
+        SkDisk *d;
+        int ret = -1;
+        struct stat st;
+
+        assert(_d);
+
+        if (!(d = calloc(1, sizeof(SkDisk)))) {
+                errno = ENOMEM;
+                goto fail;
+        }
+
+        d->fd = -1;
+        d->size = (uint64_t) -1;
+
+        if (!name)
+                d->type = SK_DISK_TYPE_BLOB;
+        else {
+                const char *dn;
+
+                d->type = SK_DISK_TYPE_AUTO;
+
+                if (!(dn = disk_type_from_string(name, &d->type)))
+                        dn = name;
+
+                if (!(d->name = strdup(dn))) {
+                        errno = ENOMEM;
+                        goto fail;
+                }
+
+                if ((d->fd = open(d->name,
+                                  O_RDONLY|O_NOCTTY|O_NONBLOCK
+#ifdef O_CLOEXEC
+                                  |O_CLOEXEC
+#endif
+
+                     )) < 0) {
+                        ret = d->fd;
+                        goto fail;
+                }
+
+                if ((ret = fstat(d->fd, &st)) < 0)
+                        goto fail;
+
+                if (!S_ISBLK(st.st_mode)) {
+                        errno = ENODEV;
+                        ret = -1;
+                        goto fail;
+                }
+
+                /* So, it's a block device. Let's make sure the ioctls work */
+                if ((ret = ioctl(d->fd, BLKGETSIZE64, &d->size)) < 0)
+                        goto fail;
+
+                if (d->size <= 0 || d->size == (uint64_t) -1) {
+                        errno = EIO;
+                        ret = -1;
+                        goto fail;
+                }
+
+                /* OK, it's a real block device with a size. Now let's find the suitable API */
+                if (d->type == SK_DISK_TYPE_AUTO)
+                        if ((ret = disk_find_type(d, st.st_rdev)) < 0)
+                                goto fail;
+
+                if (d->type == SK_DISK_TYPE_AUTO) {
+                        /* We have no clue, so let's autotest for a working API */
+                        for (d->type = 0; d->type < _SK_DISK_TYPE_TEST_MAX; d->type++)
+                                if (disk_identify_device(d) >= 0)
+                                        break;
+                        if (d->type >= _SK_DISK_TYPE_TEST_MAX)
+                                d->type = SK_DISK_TYPE_NONE;
+                } else
+                        disk_identify_device(d);
+        }
+
+        *_d = d;
+
+        return 0;
+
+fail:
+
+        if (d)
+                sk_disk_free(d);
+
+        return ret;
+}
+
+void sk_disk_free(SkDisk *d) {
+        assert(d);
+
+        if (d->fd >= 0)
+                close(d->fd);
+
+        free(d->name);
+        free(d->blob);
+        free(d);
+}
+
+int sk_disk_get_blob(SkDisk *d, const void **blob, size_t *rsize) {
+        size_t size;
+        SkBool good, have_good = FALSE;
+        uint32_t *p;
+
+        assert(d);
+        assert(blob);
+        assert(rsize);
+
+        size =
+                (d->identify_valid ? 8 + sizeof(d->identify) : 0) +
+                (d->smart_data_valid ? 8 + sizeof(d->smart_data) : 0) +
+                (d->smart_thresholds_valid ? 8 + sizeof(d->smart_thresholds) : 0);
+
+        if (sk_disk_smart_status(d, &good) >= 0) {
+                size += 12;
+                have_good = TRUE;
+        }
+
+        if (size <= 0) {
+                errno = ENODATA;
+                return -1;
+        }
+
+        free(d->blob);
+        if (!(d->blob = malloc(size))) {
+                errno = ENOMEM;
+                return -1;
+        }
+
+        p = d->blob;
+
+        /* These memory accesses are only OK as long as all our
+         * objects are sensibly aligned, which they are... */
+
+        if (d->identify_valid) {
+                p[0] = SK_BLOB_TAG_IDENTIFY;
+                p[1] = htonl(sizeof(d->identify));
+                p += 2;
+
+                memcpy(p, d->identify, sizeof(d->identify));
+                p = (uint32_t*) ((uint8_t*) p + sizeof(d->identify));
+        }
+
+        if (have_good) {
+                p[0] = SK_BLOB_TAG_SMART_STATUS;
+                p[1] = htonl(4);
+                p[2] = htonl(!!good);
+                p += 3;
+        }
+
+        if (d->smart_data_valid) {
+                p[0] = SK_BLOB_TAG_SMART_DATA;
+                p[1] = htonl(sizeof(d->smart_data));
+                p += 2;
+
+                memcpy(p, d->smart_data, sizeof(d->smart_data));
+                p = (uint32_t*) ((uint8_t*) p + sizeof(d->smart_data));
+        }
+
+        if (d->smart_thresholds_valid) {
+                p[0] = SK_BLOB_TAG_SMART_THRESHOLDS;
+                p[1] = htonl(sizeof(d->smart_thresholds));
+                p += 2;
+
+                memcpy(p, d->smart_thresholds, sizeof(d->smart_thresholds));
+                p = (uint32_t*) ((uint8_t*) p + sizeof(d->smart_thresholds));
+        }
+
+        assert((size_t) ((uint8_t*) p - (uint8_t*) d->blob) == size);
+
+        *blob = d->blob;
+        *rsize = size;
+
+        return 0;
+}
+
+int sk_disk_set_blob(SkDisk *d, const void *blob, size_t size) {
+        const uint32_t *p;
+        size_t left;
+        SkBool idv = FALSE, sdv = FALSE, stv = FALSE, bssv = FALSE;
+
+        assert(d);
+        assert(blob);
+
+        if (d->type != SK_DISK_TYPE_BLOB) {
+                errno = ENODEV;
+                return -1;
+        }
+
+        if (size <= 0) {
+                errno = EINVAL;
+                return -1;
+        }
+
+        /* First run, verify if everything makes sense */
+        p = blob;
+        left = size;
+        while (left > 0) {
+                uint32_t tag, tsize;
+
+                if (left < 8) {
+                        errno = EINVAL;
+                        return -1;
+                }
+
+                memcpy(&tag, p, 4);
+                memcpy(&tsize, p+1, 4);
+                p += 2;
+                left -= 8;
+
+                if (left < ntohl(tsize)) {
+                        errno = EINVAL;
+                        return -1;
+                }
+
+                switch (tag) {
+
+                        case SK_BLOB_TAG_IDENTIFY:
+                                if (ntohl(tsize) != sizeof(d->identify) || idv) {
+                                        errno = EINVAL;
+                                        return -1;
+                                }
+                                idv = TRUE;
+                                break;
+
+                        case SK_BLOB_TAG_SMART_STATUS:
+                                if (ntohl(tsize) != 4 || bssv) {
+                                        errno = EINVAL;
+                                        return -1;
+                                }
+                                bssv = TRUE;
+                                break;
+
+                        case SK_BLOB_TAG_SMART_DATA:
+                                if (ntohl(tsize) != sizeof(d->smart_data) || sdv) {
+                                        errno = EINVAL;
+                                        return -1;
+                                }
+                                sdv = TRUE;
+                                break;
+
+                        case SK_BLOB_TAG_SMART_THRESHOLDS:
+                                if (ntohl(tsize) != sizeof(d->smart_thresholds) || stv) {
+                                        errno = EINVAL;
+                                        return -1;
+                                }
+                                stv = TRUE;
+                                break;
+                }
+
+                p = (uint32_t*) ((uint8_t*) p + ntohl(tsize));
+                left -= ntohl(tsize);
+        }
+
+        if (!idv) {
+                errno = -ENODATA;
+                return -1;
+        }
+
+        d->identify_valid = idv;
+        d->smart_data_valid = sdv;
+        d->smart_thresholds_valid = stv;
+        d->blob_smart_status_valid = bssv;
+
+        /* Second run, actually copy things in */
+        p = blob;
+        left = size;
+        while (left > 0) {
+                uint32_t tag, tsize;
+
+                assert(left >= 8);
+                memcpy(&tag, p, 4);
+                memcpy(&tsize, p+1, 4);
+                p += 2;
+                left -= 8;
+
+                assert(left >= ntohl(tsize));
+
+                switch (tag) {
+
+                        case SK_BLOB_TAG_IDENTIFY:
+                                assert(ntohl(tsize) == sizeof(d->identify));
+                                memcpy(d->identify, p, sizeof(d->identify));
+                                break;
+
+                        case SK_BLOB_TAG_SMART_STATUS: {
+                                uint32_t ok;
+                                assert(ntohl(tsize) == 4);
+                                memcpy(&ok, p, 4);
+                                d->blob_smart_status = !!ok;
+                                break;
+                        }
+
+                        case SK_BLOB_TAG_SMART_DATA:
+                                assert(ntohl(tsize) == sizeof(d->smart_data));
+                                memcpy(d->smart_data, p, sizeof(d->smart_data));
+                                break;
+
+                        case SK_BLOB_TAG_SMART_THRESHOLDS:
+                                assert(ntohl(tsize) == sizeof(d->smart_thresholds));
+                                memcpy(d->smart_thresholds, p, sizeof(d->smart_thresholds));
+                                break;
+                }
+
+                p = (uint32_t*) ((uint8_t*) p + ntohl(tsize));
+                left -= ntohl(tsize);
+        }
+
+        return 0;
+}
diff --git a/external/subpack/libs/libb64/Makefile b/external/subpack/libs/libb64/Makefile
new file mode 100644
index 0000000..284ca3a
--- /dev/null
+++ b/external/subpack/libs/libb64/Makefile
@@ -0,0 +1,34 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libb64
+PKG_VERSION:=2.0.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/libb64/libb64/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=28c43c47674409fc50e7145d4c2d26dc1f3d200889c41205e7812c2b67f26382
+
+PKG_LICENSE:=Public-Domain
+PKG_LICENSE_FILES:=LICENSE.md
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+MAKE_FLAGS+=all_src
+
+define Package/libb64
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Base64 Encoding/Decoding Routines
+  URL:=https://github.com/libb64/libb64
+  BUILDONLY:=1
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/b64 $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/include/b64/*.h $(1)/usr/include/b64
+	$(CP) $(PKG_BUILD_DIR)/src/*.a $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libb64))
diff --git a/external/subpack/libs/libb64/patches/100-no-Werror.patch b/external/subpack/libs/libb64/patches/100-no-Werror.patch
new file mode 100644
index 0000000..5485999
--- /dev/null
+++ b/external/subpack/libs/libb64/patches/100-no-Werror.patch
@@ -0,0 +1,11 @@
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -15,7 +15,7 @@ TARGETS = $(LIBRARIES)
+ 
+ LINK.o = gcc
+ 
+-CFLAGS += -Werror -pedantic
++CFLAGS += -pedantic
+ CFLAGS += -I../include
+ 
+ vpath %.h ../include/b64
diff --git a/external/subpack/libs/libcap-ng/Makefile b/external/subpack/libs/libcap-ng/Makefile
new file mode 100644
index 0000000..fc0e960
--- /dev/null
+++ b/external/subpack/libs/libcap-ng/Makefile
@@ -0,0 +1,91 @@
+#
+# Copyright (C) 2020 Lucian Cristian
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libcap-ng
+PKG_VERSION:=0.8.4
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://people.redhat.com/sgrubb/libcap-ng
+PKG_HASH:=68581d3b38e7553cb6f6ddf7813b1fc99e52856f21421f7b477ce5abd2605a8a
+
+PKG_MAINTAINER:=Lucian CRISTIAN <lucian.cristian@gmail.com>
+PKG_LICENSE:=GPL-2.0-or-later LGPL-2.1-or-later
+PKG_LICENSE_FILES:=License
+PKG_CPE_ID:=cpe:/a:libcap-ng_project:libcap-ng
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_FIXUP:=autoreconf
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libcap-ng/Default
+  TITLE:=POSIX capabilities library
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=https://people.redhat.com/sgrubb/libcap-ng/index.html
+endef
+
+define Package/libcap-ng/description/Default
+  POSIX capabilities library
+endef
+
+define Package/libcap-ng
+  $(call Package/libcap-ng/Default)
+  TITLE += library
+endef
+
+define Package/libcap-ng-bin
+  $(call Package/libcap-ng/Default)
+  TITLE += binaries
+  DEPENDS += libcap-ng
+endef
+
+define Package/libcap-ng-bin/description
+  $(call Package/libcap-ng/description/Default)
+  .
+  This package contains the libcap-ng utilities.
+endef
+
+TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed $(FPIC)
+
+CONFIGURE_VARS += \
+    ac_cv_prog_swig_found=no
+
+CONFIGURE_ARGS += \
+    --prefix=/usr \
+    --without-python \
+    --without-python3
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcap-ng.{so*,a} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libcap-ng.pc $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DIR) $(1)/usr/share/aclocal
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/aclocal/cap-ng.m4\
+	 $(1)/usr/share/aclocal
+endef
+
+define Package/libcap-ng/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcap-ng.so* $(1)/usr/lib/
+endef
+
+define Package/libcap-ng-bin/install
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,libcap-ng))
+$(eval $(call BuildPackage,libcap-ng-bin))
diff --git a/external/subpack/libs/libcbor/Makefile b/external/subpack/libs/libcbor/Makefile
new file mode 100644
index 0000000..7247f55
--- /dev/null
+++ b/external/subpack/libs/libcbor/Makefile
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2020 Linos Giannopoulos
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libcbor
+PKG_VERSION:=0.11.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/PJK/libcbor/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=89e0a83d16993ce50651a7501355453f5250e8729dfc8d4a251a78ea23bb26d7
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Linos Giannopoulos <linosgian00+openwrt@gmail.com>
+
+CMAKE_OPTIONS += \
+        -DBUILD_SHARED_LIBS=ON
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libcbor
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libcbor
+  URL:=https://github.com/PJK/libcbor
+  ABI_VERSION:=0
+endef
+
+define Package/libcbor/description
+ libcbor is a C library for parsing and generating CBOR, the general-purpose schema-less binary data format.
+endef
+
+
+define Package/libcbor/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcbor.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libcbor))
diff --git a/external/subpack/libs/libcgroup/Makefile b/external/subpack/libs/libcgroup/Makefile
new file mode 100644
index 0000000..7b42ebf
--- /dev/null
+++ b/external/subpack/libs/libcgroup/Makefile
@@ -0,0 +1,67 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libcgroup
+PKG_VERSION:=2.0.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/libcgroup/libcgroup/releases/download/v$(PKG_VERSION)
+PKG_HASH:=b29b5704de3d0fadf199fe4e17eeeaecba7f0dd1b85569c96eec37c7672e3026
+
+PKG_MAINTAINER:=Daniel Danzberger <daniel@dd-wrt.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libcgroup_project:libcgroup
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libcgroup
+  TITLE:=CGroup config and exec library
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+USE_MUSL:musl-fts +@KERNEL_CGROUPS
+endef
+
+define Package/cgroup-tools
+  TITLE:=CGroup config and exec tools
+  DEPENDS:=+libcgroup
+  CATEGORY:=Utilities
+endef
+
+define Package/libcgroup/description
+  Helpers utils for working with cgroups.
+endef
+
+CONFIGURE_ARGS += \
+	--enable-tools \
+	--enable-shared \
+	--disable-daemon \
+	--disable-pam
+
+TARGET_LDFLAGS += $(if $(CONFIG_USE_MUSL),-lfts)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libcgroup.h $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libcgroup $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcgroup.so* $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libcgroup.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libcgroup/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcgroup.so* $(1)/usr/lib
+endef
+
+define Package/cgroup-tools/install
+	$(INSTALL_DIR) $(1)/usr/bin $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/* $(1)/usr/sbin
+endef
+
+$(eval $(call BuildPackage,libcgroup))
+$(eval $(call BuildPackage,cgroup-tools))
diff --git a/external/subpack/libs/libcgroup/patches/010-strerror.patch b/external/subpack/libs/libcgroup/patches/010-strerror.patch
new file mode 100644
index 0000000..051165e
--- /dev/null
+++ b/external/subpack/libs/libcgroup/patches/010-strerror.patch
@@ -0,0 +1,51 @@
+From 942ef655237b90909edf53eafd121842cdc07ce1 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Fri, 13 Jan 2023 12:44:07 -0700
+Subject: [PATCH] api: Use GNU strerror_r when available
+
+GNU strerror_r is only available in glibc, musl impelents the XSI
+version which is slightly different, therefore check if GNU version is
+available before using it, otherwise use the XSI compliant version.
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Signed-off-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
+Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
+TJH: Minor formatting change so that the line doesn't exceed 100 chars
+---
+ configure.ac | 5 +++++
+ src/api.c    | 9 +++++++--
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -186,6 +186,11 @@ AC_FUNC_REALLOC
+ AC_FUNC_STAT
+ AC_CHECK_FUNCS([getmntent hasmntopt memset mkdir rmdir strdup])
+ 
++orig_CFLAGS="$CFLAGS"
++CFLAGS="$CFLAGS -D_GNU_SOURCE"
++AC_FUNC_STRERROR_R
++CFLAGS="$orig_CFLAGS"
++
+ AC_SEARCH_LIBS(
+ 	[fts_open],
+ 	[fts],
+--- a/src/api.c
++++ b/src/api.c
+@@ -4598,9 +4598,14 @@ const char *cgroup_strerror(int code)
+ {
+ 	int idx = code % ECGROUPNOTCOMPILED;
+ 
+-	if (code == ECGOTHER)
++	if (code == ECGOTHER) {
++#ifdef STRERROR_R_CHAR_P
+ 		return strerror_r(cgroup_get_last_errno(), errtext, MAXLEN);
+-
++#else
++		return strerror_r(cgroup_get_last_errno(), errtext, sizeof (errtext)) ?
++			"unknown error" : errtext;
++#endif
++	}
+ 	if (idx >= sizeof(cgroup_strerror_codes)/sizeof(cgroup_strerror_codes[0]))
+ 		return "Invalid error code";
+ 
diff --git a/external/subpack/libs/libcli/Makefile b/external/subpack/libs/libcli/Makefile
new file mode 100644
index 0000000..7b50623
--- /dev/null
+++ b/external/subpack/libs/libcli/Makefile
@@ -0,0 +1,56 @@
+# Copyright (C) 2022 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libcli
+PKG_VERSION:=1.10.7
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=V$(PKG_VERSION)
+PKG_SOURCE_URL=https://github.com/dparrish/libcli
+PKG_MIRROR_HASH:=a9842266ae80f78b838f71c98bbfeed6c7082fadedd2d9a301aedc3e47a88af7
+
+PKG_MAINTAINER:=Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+PKG_LICENSE:=LGPL-2.1
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libcli
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libcli
+  URL:=https://dparrish.com/link/libcli
+endef
+
+define Package/libcli/description
+  Libcli provides a shared library for including a Cisco-like
+  command-line interface into other software.
+endef
+
+define Build/Compile
+	$(MAKE) -C $(PKG_BUILD_DIR) \
+		CC="$(TARGET_CC)" \
+		LDFLAGS="$(TARGET_LDFLAGS)" \
+		DESTDIR="$(PKG_INSTALL_DIR)" \
+		TESTS=0 \
+		all install
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/local/include/libcli.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/local/lib/libcli.so* $(1)/usr/lib/
+endef
+
+define Package/libcli/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/local/lib/libcli.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libcli))
diff --git a/external/subpack/libs/libcli/patches/010-gcc14.patch b/external/subpack/libs/libcli/patches/010-gcc14.patch
new file mode 100644
index 0000000..e48e136
--- /dev/null
+++ b/external/subpack/libs/libcli/patches/010-gcc14.patch
@@ -0,0 +1,96 @@
+--- a/libcli.c
++++ b/libcli.c
+@@ -427,7 +427,7 @@ struct cli_command *cli_register_command
+   struct cli_command *c;
+ 
+   if (!command) return NULL;
+-  if (!(c = calloc(sizeof(struct cli_command), 1))) return NULL;
++  if (!(c = calloc(1, sizeof(struct cli_command)))) return NULL;
+   c->command_type = CLI_REGULAR_COMMAND;
+   c->callback = callback;
+   c->next = NULL;
+@@ -597,10 +597,10 @@ struct cli_def *cli_init() {
+   struct cli_def *cli;
+   struct cli_command *c;
+ 
+-  if (!(cli = calloc(sizeof(struct cli_def), 1))) return 0;
++  if (!(cli = calloc(1, sizeof(struct cli_def)))) return 0;
+ 
+   cli->buf_size = 1024;
+-  if (!(cli->buffer = calloc(cli->buf_size, 1))) {
++  if (!(cli->buffer = calloc(1, cli->buf_size))) {
+     cli_done(cli);
+     return 0;
+   }
+@@ -778,7 +778,7 @@ static char *cli_int_return_newword(cons
+ 
+   // allocate space (including terminal NULL, then go through and deal with escaping characters as we copy them
+ 
+-  if (!(newword = calloc(len + 1, 1))) return 0;
++  if (!(newword = calloc(1, len + 1))) return 0;
+   to = newword;
+   while (start != end) {
+     if (*start == '\\')
+@@ -1940,7 +1940,7 @@ int cli_match_filter_init(struct cli_def
+   char *search_flags = cli_get_optarg_value(cli, "search_flags", NULL);
+ 
+   filt->filter = cli_match_filter;
+-  filt->data = state = calloc(sizeof(struct cli_match_filter_state), 1);
++  filt->data = state = calloc(1, sizeof(struct cli_match_filter_state));
+   if (!state) return CLI_ERROR;
+ 
+   if (!strcmp(cli->pipeline->current_stage->words[0], "include")) {
+@@ -2033,7 +2033,7 @@ int cli_range_filter_init(struct cli_def
+   //    from the command line processing and continue
+ 
+   filt->filter = cli_range_filter;
+-  filt->data = state = calloc(sizeof(struct cli_range_filter_state), 1);
++  filt->data = state = calloc(1, sizeof(struct cli_range_filter_state));
+   if (state) {
+     state->from = from;
+     state->to = to;
+@@ -2070,7 +2070,7 @@ int cli_count_filter_init(struct cli_def
+   }
+ 
+   filt->filter = cli_count_filter;
+-  if (!(filt->data = calloc(sizeof(int), 1))) return CLI_ERROR;
++  if (!(filt->data = calloc(1, sizeof(int)))) return CLI_ERROR;
+ 
+   return CLI_OK;
+ }
+@@ -2127,7 +2127,7 @@ struct cli_command *cli_register_filter(
+   struct cli_command *c;
+ 
+   if (!command) return NULL;
+-  if (!(c = calloc(sizeof(struct cli_command), 1))) return NULL;
++  if (!(c = calloc(1, sizeof(struct cli_command)))) return NULL;
+ 
+   c->command_type = CLI_FILTER_COMMAND;
+   c->init = init;
+@@ -2239,7 +2239,7 @@ struct cli_optarg *cli_register_optarg(s
+       goto CLEANUP;
+     }
+   }
+-  if (!(optarg = calloc(sizeof(struct cli_optarg), 1))) goto CLEANUP;
++  if (!(optarg = calloc(1, sizeof(struct cli_optarg)))) goto CLEANUP;
+   if (!(optarg->name = strdup(name))) goto CLEANUP;
+   if (help && !(optarg->help = strdup(help))) goto CLEANUP;
+ 
+@@ -2505,7 +2505,7 @@ struct cli_command *cli_int_register_bui
+   struct cli_command *c;
+ 
+   if (!command) return NULL;
+-  if (!(c = calloc(sizeof(struct cli_command), 1))) return NULL;
++  if (!(c = calloc(1, sizeof(struct cli_command)))) return NULL;
+ 
+   c->flags = flags;
+   c->callback = callback;
+@@ -3068,7 +3068,7 @@ int cli_int_execute_pipeline(struct cli_
+     struct cli_pipeline_stage *stage = &pipeline->stage[stage_num];
+     pipeline->current_stage = stage;
+     cli->found_optargs = stage->found_optargs;
+-    *filt = calloc(sizeof(struct cli_filter), 1);
++    *filt = calloc(1, sizeof(struct cli_filter));
+     if (*filt) {
+       if ((rc = stage->command->init(cli, stage->num_words, stage->words, *filt) != CLI_OK)) {
+         break;
diff --git a/external/subpack/libs/libcoap/Makefile b/external/subpack/libs/libcoap/Makefile
new file mode 100644
index 0000000..a1fcdbf
--- /dev/null
+++ b/external/subpack/libs/libcoap/Makefile
@@ -0,0 +1,99 @@
+#
+# Copyright (C) 2015 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:=libcoap
+PKG_VERSION:=4.3.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/obgm/libcoap/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=1a195adacd6188d3b71c476e7b21706fef7f3663ab1fb138652e8da49a9ec556
+
+PKG_MAINTAINER:=Anton Glukhov <anton.a.glukhov@gmail.com>
+PKG_LICENSE:=GPL-2.0-or-later BSD-2-Clause
+PKG_LICENSE_FILES:=COPYING LICENSE.GPL LICENSE.BSD
+PKG_CPE_ID:=cpe:/a:libcoap:libcoap
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libcoap
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=CoAP (RFC 7252) library
+  URL:=https://libcoap.net/
+  ABI_VERSION:=3
+endef
+
+define Package/libcoap/description
+  Constrained Application Protocol (RFC 7252) library
+endef
+
+define Package/coap-client
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libcoap
+  TITLE:=CoAP (RFC 7252) client tool
+endef
+
+define Package/coap-client/description
+  Constrained Application Protocol (RFC7252) client tool
+endef
+
+define Package/coap-server
+  SECTION:=net
+  CATEGORY:=Network
+  DEPENDS:=+libcoap
+  TITLE:=CoAP (RFC 7252) server programs
+endef
+
+define Package/coap-server/description
+  Constrained Application Protocol (RFC 7252) server and resource directory server
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+	--enable-examples \
+	--disable-documentation \
+	--disable-doxygen \
+	--disable-dtls \
+	--disable-gcov \
+	--disable-tests
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+endef
+
+define Package/libcoap/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcoap-$(ABI_VERSION)*.so* $(1)/usr/lib/
+endef
+
+define Package/coap-client/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/coap-client $(1)/usr/bin/
+endef
+
+define Package/coap-server/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/coap-server $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/coap-rd $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libcoap))
+$(eval $(call BuildPackage,coap-client))
+$(eval $(call BuildPackage,coap-server))
diff --git a/external/subpack/libs/libconfig/Makefile b/external/subpack/libs/libconfig/Makefile
new file mode 100644
index 0000000..b2b91df
--- /dev/null
+++ b/external/subpack/libs/libconfig/Makefile
@@ -0,0 +1,61 @@
+#
+# Copyright (C) 2008-2012 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:=libconfig
+PKG_VERSION:=1.7.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://hyperrealm.github.io/libconfig/dist/
+PKG_HASH:=545166d6cac037744381d1e9cc5a5405094e7bfad16a411699bcff40bbb31ee7
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LIB
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libconfig
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Configuration File Library
+  URL:=https://hyperrealm.github.io/libconfig/
+  ABI_VERSION:=11
+endef
+
+define Package/libconfig/description
+ Libconfig is a simple library for manipulating structured configuration
+ files. This file format is more compact and more readable than XML. And
+ unlike XML, it is type-aware, so it is not necessary to do string
+ parsing in application code.
+
+ Libconfig is very compact -- just 38K for the stripped C shared
+ library (less than one-fourth the size of the expat XML parser library)
+ and 66K for the stripped C++ shared library. This makes it well-suited
+ for memory-constrained systems like handheld devices.
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--disable-static \
+	--disable-cxx
+
+define Build/InstallDev
+	$(CP) $(PKG_INSTALL_DIR)/* $(1)/
+endef
+
+define Package/libconfig/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libconfig.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libconfig))
diff --git a/external/subpack/libs/libcups/Makefile b/external/subpack/libs/libcups/Makefile
new file mode 100644
index 0000000..39b5c8e
--- /dev/null
+++ b/external/subpack/libs/libcups/Makefile
@@ -0,0 +1,96 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+# Copyright (C) 2017-2018 Luiz Angelo Daros de Luca <luizluca@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:=cups
+PKG_VERSION:=2.2.12
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-source.tar.gz
+PKG_SOURCE_URL:=https://github.com/apple/cups/releases/download/v$(PKG_VERSION)/
+PKG_HASH:=0f61ab449e4748a24c6ab355b481ff7691247a140d327b2b7526fce34b7f9aa8
+PKG_MAINTAINER:=Luiz Angelo Daros de Luca <luizluca@gmail.com>
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=LICENSE.txt
+PKG_CPE_ID:=cpe:/a:apple:cups
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libcups/Default
+  URL:=http://www.cups.org/
+  SUBMENU:=Printing
+endef
+
+define Package/libcups
+$(call Package/cups/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+zlib +libpthread +libpng +libjpeg +libusb-1.0
+  TITLE:=Common UNIX Printing System - Core library
+  BUILDONLY:=1
+endef
+
+define Package/libcups/description
+	Common UNIX Printing System - Core library
+endef
+
+CONFIGURE_ARGS+=--with-cups-user="nobody" \
+		--with-cups-group="nogroup" \
+		--with-components="core" \
+		--with-pdftops="none" \
+		--without-perl \
+		--without-python \
+		--without-php \
+		--enable-shared \
+		--enable-image \
+		--enable-libusb \
+		--disable-acl \
+		--disable-dbus \
+		--disable-dnssd \
+		--disable-launchd \
+		--disable-ldap \
+		--disable-pam \
+		--disable-slp \
+		--disable-gnutls \
+		--disable-openssl \
+		--disable-cdsassl \
+		--disable-ssl \
+		--disable-gssapi \
+		--disable-tiff \
+		UNAME="Linux" \
+		LIBS="$(TARGET_LDFLAGS) -lz -lpng -ljpeg"
+
+define Build/Compile
+	$(MAKE) -C $(PKG_BUILD_DIR)/cups \
+		$(TARGET_CONFIGURE_OPTS) \
+		DSTROOT="$(PKG_INSTALL_DIR)" \
+		STRIP="/bin/true" \
+		libcups.so.2 install-libs install-headers
+	$(MAKE) -C $(PKG_BUILD_DIR)/filter \
+		$(TARGET_CONFIGURE_OPTS) \
+		DSTROOT="$(PKG_INSTALL_DIR)" \
+		STRIP="/bin/true" \
+		libcupsimage.so.2 install-libs install-headers
+	$(INSTALL_DIR) $(PKG_INSTALL_DIR)/usr/bin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/cups-config $(PKG_INSTALL_DIR)/usr/bin
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/cups-config $(1)/usr/bin/
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) $(STAGING_DIR)/usr/bin/cups-config $(2)/bin
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/cups $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib*/libcups*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libcups))
diff --git a/external/subpack/libs/libdaemon/Makefile b/external/subpack/libs/libdaemon/Makefile
new file mode 100644
index 0000000..2dc618b
--- /dev/null
+++ b/external/subpack/libs/libdaemon/Makefile
@@ -0,0 +1,73 @@
+#
+# Copyright (C) 2006-2014 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:=libdaemon
+PKG_VERSION:=0.14
+PKG_RELEASE:=5
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://0pointer.de/lennart/projects/libdaemon/
+PKG_HASH:=fd23eb5f6f986dcc7e708307355ba3289abe03cc381fc47a80bca4a50aa6b834
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_CPE_ID:=cpe:/a:libdaemon_project:libdaemon
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdaemon
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A lightweight C library that eases the writing of UNIX daemons
+  URL:=http://0pointer.de/lennart/projects/libdaemon/
+endef
+
+define Package/libdaemon/description
+	libdaemon is a lightweight C library that eases the writing of UNIX daemons.
+	It consists of the following parts:
+	- A wrapper around fork() which does the correct daemonization procedure of a process
+	- A wrapper around syslog() for simpler and compatible log output to Syslog or STDERR
+	- An API for writing PID files
+	- An API for serializing UNIX signals into a pipe for usage with select() or poll()
+	- An API for running subprocesses with STDOUT and STDERR redirected to syslog
+
+	APIs like these are used in most daemon software available. It is not that
+	simple to get it done right and code duplication is not a goal.
+endef
+
+define Build/Configure
+	$(call Build/Configure/Default, \
+		--enable-shared \
+		--enable-static \
+		--disable-lynx \
+		--disable-examples \
+		, \
+		ac_cv_func_setpgrp_void=yes \
+	)
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libdaemon $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdaemon.a $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdaemon.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libdaemon.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libdaemon/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdaemon.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libdaemon))
diff --git a/external/subpack/libs/libdaemon/patches/001-daemon_set_verbosity.patch b/external/subpack/libs/libdaemon/patches/001-daemon_set_verbosity.patch
new file mode 100644
index 0000000..bbe8f97
--- /dev/null
+++ b/external/subpack/libs/libdaemon/patches/001-daemon_set_verbosity.patch
@@ -0,0 +1,25 @@
+From 013963ba35e8fe8897211c0acf5ee98f9a871fc1 Mon Sep 17 00:00:00 2001
+From: Michael Heimpold <mhei@heimpold.de>
+Date: Fri, 10 Jan 2014 19:38:51 +0100
+Subject: [PATCH] daemon_set_verbosity: fix erroneous error message
+
+When calling this function with a value other than LOG_DEBUG
+the error message was triggered erroneously.
+
+Signed-off-by: Michael Heimpold <mhei@heimpold.de>
+---
+
+ libdaemon/dlog.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/libdaemon/dlog.c
++++ b/libdaemon/dlog.c
+@@ -37,7 +37,7 @@ static int daemon_verbosity_level = LOG_
+ void daemon_set_verbosity(int verbosity_prio) {
+ 
+     /* Allow using negative verbosity levels to hide _all_ messages */
+-    if (verbosity_prio > 0 && (verbosity_prio & LOG_PRIMASK) != LOG_PRIMASK)
++    if (verbosity_prio > 0 && (verbosity_prio & LOG_PRIMASK) != verbosity_prio)
+         daemon_log(LOG_ERR, "The value %d is not a valid priority value", verbosity_prio);
+ 
+     daemon_verbosity_level = verbosity_prio & LOG_PRIMASK;
diff --git a/external/subpack/libs/libdaq3/Makefile b/external/subpack/libs/libdaq3/Makefile
new file mode 100644
index 0000000..c643ad1
--- /dev/null
+++ b/external/subpack/libs/libdaq3/Makefile
@@ -0,0 +1,68 @@
+#
+# Copyright (C) 2012-2015 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:=libdaq3
+PKG_VERSION:=3.0.15
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+
+PKG_LICENSE:=GPL-2.0-only
+PKG_LICENSE_FILES:=COPYING LICENSE
+
+PKG_SOURCE:=libdaq-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/snort3/libdaq/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=174c639d59f7bda84d71bda50257febbb2646138aa7bbf948bb4d4a8be60f2d8
+PKG_BUILD_DIR:=$(BUILD_DIR)/libdaq-$(PKG_VERSION)
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdaq3
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=DAQ library
+  URL:=$(PKG_SOURCE_URL)
+  DEPENDS:=+libdnet +libpcap +libstdcpp +libmnl +libnetfilter-queue
+endef
+
+define Package/libdaq3/description
+ Data Acquisition library for packet I/O.
+endef
+
+CONFIGURE_ARGS+= \
+	--disable-static \
+	--enable-nfq-module \
+	--with-dnet-includes="$(STAGING_DIR)/usr/include" \
+	--with-dnet-libraries="$(STAGING_DIR)/usr/lib" \
+	--with-libpcap-includes="$(STAGING_DIR)/usr/include" \
+	--with-libpcap-libraries="$(STAGING_DIR)/usr/lib" \
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/include/daq3
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/. $(STAGING_DIR)/usr/include/daq3/
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/lib/daq3
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib* $(STAGING_DIR)/usr/lib/daq3/
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/lib/daq3/daq
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/daq/* $(STAGING_DIR)/usr/lib/daq3/daq/
+endef
+
+define Package/libdaq3/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/daq
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/daq/*.so* $(1)/usr/lib/daq/
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libdaq3))
diff --git a/external/subpack/libs/libdbi-drivers/Makefile b/external/subpack/libs/libdbi-drivers/Makefile
new file mode 100644
index 0000000..1dc57a9
--- /dev/null
+++ b/external/subpack/libs/libdbi-drivers/Makefile
@@ -0,0 +1,105 @@
+#
+# Copyright (C) 2009-2014 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:=libdbi-drivers
+PKG_VERSION:=0.9.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/libdbi-drivers
+PKG_HASH:=43d2eacd573a4faff296fa925dd97fbf2aedbf1ae35c6263478210c61004c854
+
+PKG_LICENSE:=LGPL-2.1
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdbi-drivers/default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=http://libdbi-drivers.sourceforge.net/
+endef
+
+define Package/libdbi-drivers
+$(call Package/libdbi-drivers/default)
+  DEPENDS:=libdbi +libdbd-mysql +libdbd-pgsql +libdbd-sqlite3
+  TITLE:=Database drivers for libdbi
+endef
+
+define Package/libdbd-mysql
+$(call Package/libdbi-drivers/default)
+  DEPENDS:=libdbi +libmysqlclient
+  TITLE:=MySQL database server driver for libdbi
+endef
+
+define Package/libdbd-pgsql
+$(call Package/libdbi-drivers/default)
+  DEPENDS:=libdbi +libpq
+  TITLE:=PostgreSQL database server driver for libdbi
+endef
+
+define Package/libdbd-sqlite3
+$(call Package/libdbi-drivers/default)
+  DEPENDS:=libdbi +libsqlite3
+  TITLE:=SQLite3 database driver for libdbi
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--disable-static \
+	--disable-rpath \
+	--disable-docs \
+	--with-dbi-incdir=$(STAGING_DIR)/usr/include \
+	--with-dbi-libdir=$(STAGING_DIR)/usr/lib
+
+ifneq ($(CONFIG_PACKAGE_libdbd-mysql),)
+	CONFIGURE_ARGS += \
+		--with-mysql \
+		--with-mysql-incdir=$(STAGING_DIR)/usr/include/mysql \
+		--with-mysql-libdir=$(STAGING_DIR)/usr/lib/mysql
+	TARGET_LDFLAGS += \
+		-L$(STAGING_DIR)/usr/lib/mysql/
+else
+	CONFIGURE_ARGS += --without-mysql
+endif
+
+ifneq ($(SDK)$(CONFIG_PACKAGE_libdbd-pgsql),)
+	CONFIGURE_ARGS += \
+		--with-pgsql \
+		--with-pgsql-incdir=$(STAGING_DIR)/usr/include \
+		--with-pgsql-libdir=$(STAGING_DIR)/usr/lib
+else
+	CONFIGURE_ARGS += --without-pgsql
+endif
+
+ifneq ($(SDK)$(CONFIG_PACKAGE_libdbd-sqlite3),)
+	CONFIGURE_ARGS += \
+		--with-sqlite3 \
+		--with-sqlite3-incdir=$(STAGING_DIR)/usr/include \
+		--with-sqlite3-libdir=$(STAGING_DIR)/usr/lib
+else
+	CONFIGURE_ARGS += --without-sqlite3
+endif
+
+define BuildPlugin
+  define Package/libdbd-$(1)/install
+	$(INSTALL_DIR) $$(1)/usr/lib/dbd
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/dbd/libdbd$(1).so $$(1)/usr/lib/dbd/
+  endef
+  $$(eval $$(call BuildPackage,libdbd-$(1)))
+endef
+
+#$(eval $(call BuildPackage,libdbi-drivers))
+$(eval $(call BuildPlugin,mysql))
+$(eval $(call BuildPlugin,pgsql))
+$(eval $(call BuildPlugin,sqlite3))
diff --git a/external/subpack/libs/libdbi-drivers/patches/001_libsqlite3_fix.patch b/external/subpack/libs/libdbi-drivers/patches/001_libsqlite3_fix.patch
new file mode 100644
index 0000000..5ded953
--- /dev/null
+++ b/external/subpack/libs/libdbi-drivers/patches/001_libsqlite3_fix.patch
@@ -0,0 +1,11 @@
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -310,7 +310,7 @@ if test "$ac_sqlite3" = "yes"; then
+ 		AC_SEARCH_LIBS_VAR([sqlite3_exec], sqlite3, , , , SQLITE3_LIBS)
+ 		SQLITE3_LDFLAGS=""
+ 	else
+-		SQLITE3_LIBS=-lsqlite
++		SQLITE3_LIBS=-lsqlite3
+ 		SQLITE3_LDFLAGS=-L$ac_sqlite3_libdir
+ 	fi
+ 
diff --git a/external/subpack/libs/libdbi-drivers/patches/100-remove-date-to-fix-reproducible-builds.patch b/external/subpack/libs/libdbi-drivers/patches/100-remove-date-to-fix-reproducible-builds.patch
new file mode 100644
index 0000000..ac662b2
--- /dev/null
+++ b/external/subpack/libs/libdbi-drivers/patches/100-remove-date-to-fix-reproducible-builds.patch
@@ -0,0 +1,120 @@
+--- a/drivers/db2/dbd_db2.c
++++ b/drivers/db2/dbd_db2.c
+@@ -57,8 +57,7 @@ static const dbi_info_t driver_info = {
+   "IBM DB2 database support (using DB2 Call Level Interface)",
+   "João Henrique F. Freitas <joaohf@users.sourceforge.net>",
+   "http://libdbi-drivers.sourceforge.net",
+-  "dbd_db2 v" VERSION,
+-  __DATE__
++  "dbd_db2 v" VERSION
+ };
+ 
+ static const char *custom_functions[] = {NULL}; // TODO
+--- a/drivers/firebird/dbd_firebird.c
++++ b/drivers/firebird/dbd_firebird.c
+@@ -67,8 +67,7 @@ static const dbi_info_t driver_info = {
+ 	"Firebird/Interbase database support",
+ 	"Christian M. Stamgren <cms@cention.se>",
+ 	"http://libdbi-drivers.sourceforge.net",
+-	"dbd_firebird v" VERSION,
+-	__DATE__
++	"dbd_firebird v" VERSION
+ };
+ 
+ 
+--- a/drivers/freetds/dbd_freetds.c
++++ b/drivers/freetds/dbd_freetds.c
+@@ -63,8 +63,7 @@ static const dbi_info_t driver_info = {
+     "MS SQL and Sybase databases support (using libct)",
+     "Vadym Kononenko <konan_v@users.sourceforge.net>",
+     "http://libdbi.sourceforge.net",
+-    "dbd_freetds v" VERSION,
+-    __DATE__
++    "dbd_freetds v" VERSION
+ };
+ 
+ static const char APP_NAME[] = "libdbi-freetds-driver";
+--- a/drivers/ingres/dbd_ingres.c
++++ b/drivers/ingres/dbd_ingres.c
+@@ -44,8 +44,7 @@ static const dbi_info_t driver_info = {
+ 	"Ingres database support",
+ 	"Toby Thain <qu1j0t3@sourceforge.net>",
+ 	"http://libdbi-drivers.sourceforge.net",
+-	"dbd_ingres v" VERSION,
+-	__DATE__
++	"dbd_ingres v" VERSION
+ };
+ 
+ static const char *custom_functions[] = {NULL};
+--- a/drivers/msql/dbd_msql.c
++++ b/drivers/msql/dbd_msql.c
+@@ -57,8 +57,7 @@ static const dbi_info_t driver_info = {
+ 	"Mini SQL (mSQL) database support",
+ 	"Christian M. Stamgren <christian@centiongroup.com>",
+ 	"libdbi-drivers.sourceforge.net", 
+-	"dbd_msql v" VERSION,
+-	__DATE__
++	"dbd_msql v" VERSION
+ };
+ 
+ static const char *custom_functions[] = {NULL}; 
+--- a/drivers/mysql/dbd_mysql.c
++++ b/drivers/mysql/dbd_mysql.c
+@@ -59,8 +59,7 @@ static const dbi_info_t driver_info = {
+ 	"MySQL database support (using libmysqlclient)",
+ 	"Mark M. Tobenkin <mark@brentwoodradio.com>",
+ 	"http://libdbi-drivers.sourceforge.net",
+-	"dbd_mysql v" VERSION,
+-	__DATE__
++	"dbd_mysql v" VERSION
+ };
+ 
+ static const char *custom_functions[] = MYSQL_CUSTOM_FUNCTIONS;
+--- a/drivers/oracle/dbd_oracle.c
++++ b/drivers/oracle/dbd_oracle.c
+@@ -54,8 +54,7 @@ static const dbi_info_t driver_info = {
+ 	"Oracle database support (using Oracle Call Interface)",
+ 	"Ashish Ranjan <ashishwave@yahoo.com>", 
+ 	"http://libdbi-drivers.sourceforge.net",
+-	"dbd_Oracle v" VERSION,
+-	__DATE__
++	"dbd_Oracle v" VERSION
+ };
+ 
+ static const char *custom_functions[] = {NULL}; 
+--- a/drivers/pgsql/dbd_pgsql.c
++++ b/drivers/pgsql/dbd_pgsql.c
+@@ -61,8 +61,7 @@ static const dbi_info_t driver_info = {
+ 	"PostgreSQL database support (using libpq)",
+ 	"David A. Parker <david@neongoat.com>",
+ 	"http://libdbi-drivers.sourceforge.net",
+-	"dbd_pgsql v" VERSION,
+-	__DATE__
++	"dbd_pgsql v" VERSION
+ };
+ 
+ static const char *custom_functions[] = PGSQL_CUSTOM_FUNCTIONS;
+--- a/drivers/sqlite/dbd_sqlite.c
++++ b/drivers/sqlite/dbd_sqlite.c
+@@ -65,8 +65,7 @@ static const dbi_info_t driver_info = {
+   "SQLite database support (using libsqlite)",
+   "Markus Hoenicka <mhoenicka@users.sourceforge.net>",
+   "http://libdbi-drivers.sourceforge.net",
+-  "dbd_sqlite v" VERSION,
+-  __DATE__
++  "dbd_sqlite v" VERSION
+ };
+ 
+ static const char *custom_functions[] = SQLITE_CUSTOM_FUNCTIONS;
+--- a/drivers/sqlite3/dbd_sqlite3.c
++++ b/drivers/sqlite3/dbd_sqlite3.c
+@@ -65,8 +65,7 @@ static const dbi_info_t driver_info = {
+   "SQLite3 database support (using libsqlite3)",
+   "Markus Hoenicka <mhoenicka@users.sourceforge.net>",
+   "http://libdbi-drivers.sourceforge.net",
+-  "dbd_sqlite3 v" VERSION,
+-  __DATE__
++  "dbd_sqlite3 v" VERSION
+ };
+ 
+ static const char *custom_functions[] = SQLITE3_CUSTOM_FUNCTIONS;
diff --git a/external/subpack/libs/libdbi/Makefile b/external/subpack/libs/libdbi/Makefile
new file mode 100644
index 0000000..53af4ba
--- /dev/null
+++ b/external/subpack/libs/libdbi/Makefile
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2009-2014 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:=libdbi
+PKG_VERSION:=0.9.0
+PKG_RELEASE:=5
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/libdbi
+PKG_HASH:=dafb6cdca524c628df832b6dd0bf8fabceb103248edb21762c02d3068fca4503
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdbi
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Database Independent Abstraction Layer library
+  URL:=http://libdbi.sourceforge.net/
+endef
+
+define Package/libdbi/description
+ This package provides a database-independent abstraction layer library in C.
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--disable-docs
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/dbi $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdbi.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/dbi.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libdbi/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdbi.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libdbi))
diff --git a/external/subpack/libs/libdcwproto/Makefile b/external/subpack/libs/libdcwproto/Makefile
new file mode 100644
index 0000000..4ac94d7
--- /dev/null
+++ b/external/subpack/libs/libdcwproto/Makefile
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2019 EWSI
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libdcwproto
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=b3d12f2533eafbb293bbf27608ff39520508d955a084f33894c594f39d2f7c8e
+
+PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=gc-sections lto
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdcwproto
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=Networking
+  TITLE:=Dual-Channel WiFi messaging library
+  URL:=https://www.edgewaterwireless.com
+  DEPENDS:=+kmod-macremapper
+endef
+
+define Package/libdcwproto/description
+  Platform-independent C library for marshaling and serializing DCW messages
+endef
+
+TARGET_LDFLAGS += -Wl,--as-needed
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
+endef
+
+define Package/libdcwproto/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	# Note: $(INSTALL_BIN) does not keep symlinks, so use $(CP)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libdcwproto))
diff --git a/external/subpack/libs/libdcwsocket/Makefile b/external/subpack/libs/libdcwsocket/Makefile
new file mode 100644
index 0000000..6024192
--- /dev/null
+++ b/external/subpack/libs/libdcwsocket/Makefile
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2019 EWSI
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libdcwsocket
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ewsi/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_HASH:=71383c4d8c5f58c1299a3717d7de9a8b5dabfd51a2dcf9993248f2709908d23a
+
+PKG_MAINTAINER:=Carey Sonsino <careys@edgewaterwireless.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=gc-sections lto
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdcwsocket
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=Networking
+  TITLE:=Dual-Channel socket library
+  URL:=https://www.edgewaterwireless.com
+endef
+
+define Package/libdcwsocket/description
+  User-land C library for sending and receiving DCW "EtherType"d messages
+endef
+
+TARGET_CFLAGS += -std=c89
+TARGET_LDFLAGS += -Wl,--as-needed
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
+endef
+
+define Package/libdcwsocket/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	# Note: $(INSTALL_BIN) does not keep symlinks, so use $(CP)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/$(PKG_NAME)*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libdcwsocket))
diff --git a/external/subpack/libs/libdcwsocket/patches/010-glibc.patch b/external/subpack/libs/libdcwsocket/patches/010-glibc.patch
new file mode 100644
index 0000000..24cb24b
--- /dev/null
+++ b/external/subpack/libs/libdcwsocket/patches/010-glibc.patch
@@ -0,0 +1,12 @@
+--- a/src/dcwsocket.c.linux
++++ b/src/dcwsocket.c.linux
+@@ -36,6 +36,9 @@
+ #include <linux/filter.h>
+ #include <arpa/inet.h>
+ 
++#ifndef SO_ATTACH_FILTER
++#define SO_ATTACH_FILTER  26
++#endif
+ 
+ #define ETHER_HEADERSIZE  14
+ #define CL3_HEADERSIZE    4
diff --git a/external/subpack/libs/libdcwsocket/patches/02_fix_storage_size_error.patch b/external/subpack/libs/libdcwsocket/patches/02_fix_storage_size_error.patch
new file mode 100644
index 0000000..431b093
--- /dev/null
+++ b/external/subpack/libs/libdcwsocket/patches/02_fix_storage_size_error.patch
@@ -0,0 +1,10 @@
+--- a/src/dcwsocket.c.linux
++++ b/src/dcwsocket.c.linux
+@@ -31,6 +31,7 @@
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <net/if.h>
++#include <linux/if.h>
+ #include <linux/if_packet.h>
+ #include <linux/if_ether.h>
+ #include <linux/filter.h>
diff --git a/external/subpack/libs/libdeflate/Makefile b/external/subpack/libs/libdeflate/Makefile
new file mode 100644
index 0000000..d754ff2
--- /dev/null
+++ b/external/subpack/libs/libdeflate/Makefile
@@ -0,0 +1,38 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libdeflate
+PKG_VERSION:=1.22
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/ebiggers/libdeflate/releases/download/v$(PKG_VERSION)
+PKG_HASH:=7834d9adbc9a809e0fb0d7b486060a9ae5f7819eb7f55bb8c22b10d7b3bed8da
+
+PKG_LICENSE:=COPYING
+PKG_LICENSE_FILES:=MIT
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libdeflate
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=library for fast, whole-buffer DEFLATE-based compression and decompression
+  URL:=https://github.com/ebiggers/libdeflate
+endef
+
+define Package/libdeflate/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdeflate.so* $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libdeflate.pc $(1)/usr/lib/pkgconfig/
+endef
+
+$(eval $(call BuildPackage,libdeflate))
diff --git a/external/subpack/libs/libdht/Makefile b/external/subpack/libs/libdht/Makefile
new file mode 100644
index 0000000..46217cb
--- /dev/null
+++ b/external/subpack/libs/libdht/Makefile
@@ -0,0 +1,41 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libdht
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/jech/dht
+PKG_SOURCE_DATE:=2022-04-27
+PKG_SOURCE_VERSION:=111230894416d400c9a1e038a033586bfeaafc93
+PKG_MIRROR_HASH:=05805aaaa2c8a5f1eb5534a2f3a55c7727a1fa15f8e05e7bf6f117aaa91ce65c
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdht
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Kademlia Distributed Hash Table (DHT) library
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/dht $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/dht.h $(1)/usr/include/dht
+	$(CP) $(PKG_BUILD_DIR)/libdht.so $(1)/usr/lib/
+endef
+
+define Package/libdht/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/libdht.so $(1)/usr/lib/
+endef
+
+define Build/Compile
+	$(TARGET_CC) $(FPIC) -Wall -c -o $(PKG_BUILD_DIR)/dht.o $(PKG_BUILD_DIR)/dht.c
+	$(TARGET_CC) -shared -lcrypt -o $(PKG_BUILD_DIR)/libdht.so $(PKG_BUILD_DIR)/dht.o
+endef
+
+$(eval $(call BuildPackage,libdht))
diff --git a/external/subpack/libs/libdmapsharing/Makefile b/external/subpack/libs/libdmapsharing/Makefile
new file mode 100644
index 0000000..5d506aa
--- /dev/null
+++ b/external/subpack/libs/libdmapsharing/Makefile
@@ -0,0 +1,71 @@
+#
+# Copyright (C) 2009-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# This Makefile is a skeleton
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libdmapsharing
+PKG_VERSION:=3.9.13
+PKG_RELEASE:=1
+
+PKG_SOURCE:=libdmapsharing-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://www.flyn.org/projects/libdmapsharing/
+PKG_HASH:=3659f63f29e11d6d6ae78b53d7cc6be3f3adeff9c00c67cc50ad19c6af699f7a
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_DEPENDS:=glib2/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libdmapsharing
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libsoup3 +mdnsresponder +gstreamer1-plugins-base +gst1-mod-app
+  TITLE:=libdmapsharing
+  URL:=https://www.flyn.org/projects/libdmapsharing/
+endef
+
+define Package/libdmapsharing/decription
+  Libdmapsharing is a DMAP library implementation in C
+endef
+
+CONFIGURE_ARGS += \
+	--disable-tests \
+	--disable-gtk-doc \
+	--disable-introspection
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/libdmapsharing-4.0/ \
+		$(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libdmapsharing/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libdmapsharing))
diff --git a/external/subpack/libs/libdmapsharing/patches/001-disable_pixbuf.patch b/external/subpack/libs/libdmapsharing/patches/001-disable_pixbuf.patch
new file mode 100644
index 0000000..e0f0fd8
--- /dev/null
+++ b/external/subpack/libs/libdmapsharing/patches/001-disable_pixbuf.patch
@@ -0,0 +1,19 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -124,15 +124,7 @@ fi
+ AC_SUBST(GOBJECT_CFLAGS)
+ AC_SUBST(GOBJECT_LIBS)
+ 
+-# Have gdkpixbuf?
+-PKG_CHECK_MODULES(GDKPIXBUF, gdk-pixbuf-2.0, HAVE_GDKPIXBUF=yes, HAVE_GDKPIXBUF=no)
+-if test x"$HAVE_GDKPIXBUF" = "xyes"; then
+-	AC_DEFINE(HAVE_GDKPIXBUF, 1, [Define if gdk-pixbuf support is enabled])
+-else
+-	AC_MSG_WARN([Gdk-pixbuf library not present; now-playing artwork might be affected])
+-fi
+-
+-AM_CONDITIONAL(USE_GDKPIXBUF, test x"$HAVE_GDKPIXBUF" = "xyes")
++HAVE_GDKPIXBUF=no
+ 
+ AC_SUBST(GDKPIXBUF_CFLAGS)
+ AC_SUBST(GDKPIXBUF_LIBS)
diff --git a/external/subpack/libs/libdnet/Makefile b/external/subpack/libs/libdnet/Makefile
new file mode 100644
index 0000000..f0f0bbc
--- /dev/null
+++ b/external/subpack/libs/libdnet/Makefile
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2006-2015 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:=libdnet
+PKG_VERSION:=1.16.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/ofalk/libdnet/tar.gz/$(PKG_NAME)-$(PKG_VERSION)?
+PKG_HASH:=b151c4913758ef80daf4558361b4f2680a37b01d59272625bb78c77183062c63
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Luka Perkov <luka@openwrt.org>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdnet
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Low-level network library
+  URL:=https://github.com/ofalk/libdnet
+endef
+
+define Package/libdnet/description
+ libdnet is a library of simplified, portable interface to several low-level
+ networking routines.
+endef
+
+CONFIGURE_ARGS += \
+	--without-check \
+	--without-python \
+	--without-wpdpack
+
+CONFIGURE_VARS += \
+	ac_cv_dnet_bsd_bpf=no \
+	ac_cv_dnet_linux_pf_packet=yes
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/dnet-config $(1)/usr/bin/
+	$(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(1)/usr/bin/dnet-config
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/dnet-config $(2)/bin/
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DATA)\
+		$(PKG_INSTALL_DIR)/usr/include/dnet.h \
+		$(1)/usr/include/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/dnet \
+		$(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libdnet.{la,a,so*} \
+		$(1)/usr/lib/
+endef
+
+define Package/libdnet/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libdnet.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libdnet))
diff --git a/external/subpack/libs/libdrm/Config.in b/external/subpack/libs/libdrm/Config.in
new file mode 100644
index 0000000..b2e7d4f
--- /dev/null
+++ b/external/subpack/libs/libdrm/Config.in
@@ -0,0 +1,25 @@
+menu "Select libdrm build options"
+		depends on PACKAGE_libdrm
+
+config LIBDRM_INTEL
+	bool "Intel support"
+	default y
+	depends on x86_64 || i386
+	help
+		Installs the Intel driver.
+
+config LIBDRM_NOUVEAU
+	bool "Nouveau support"
+	default y
+	depends on x86_64 || i386 || TARGET_tegra
+	help
+		Installs the Nouveau driver.
+
+config LIBDRM_RADEON
+	bool "Radeon support"
+	default y
+	depends on x86_64 || i386
+	help
+		Installs the Radeon driver.
+
+endmenu
diff --git a/external/subpack/libs/libdrm/Makefile b/external/subpack/libs/libdrm/Makefile
new file mode 100644
index 0000000..5df4abc
--- /dev/null
+++ b/external/subpack/libs/libdrm/Makefile
@@ -0,0 +1,78 @@
+# Copyright (C) 2007-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:=libdrm
+PKG_VERSION:=2.4.120
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://dri.freedesktop.org/libdrm
+PKG_HASH:=3bf55363f76c7250946441ab51d3a6cc0ae518055c0ff017324ab76cdefb327a
+
+PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
+PKG_LICENSE:=BSD-3-Clause
+
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_LIBDRM_INTEL \
+	CONFIG_LIBDRM_NOUVEAU \
+	CONFIG_LIBDRM_RADEON
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libdrm
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+LIBDRM_INTEL:libpciaccess
+  TITLE:=libdrm
+  URL:=https://dri.freedesktop.org/
+endef
+
+define Package/libdrm/description
+  LIBDRM is the cross-driver middleware which allows user-space applications
+  (such as Mesa and 2D drivers) to communicate with the Kernel by the means
+  of the DRI protocol.
+endef
+
+define Package/libdrm/config
+	source "$(SOURCE)/Config.in"
+endef
+
+MESON_ARGS += \
+	-Dintel=$(if $(CONFIG_LIBDRM_INTEL),en,dis)abled \
+	-Dradeon=$(if $(CONFIG_LIBDRM_RADEON),en,dis)abled \
+	-Damdgpu=disabled \
+	-Dnouveau=$(if $(CONFIG_LIBDRM_NOUVEAU),en,dis)abled \
+	-Dvmwgfx=disabled \
+	-Domap=disabled \
+	-Dexynos=disabled \
+	-Dfreedreno=disabled \
+	-Dtegra=disabled \
+	-Dvc4=disabled \
+	-Detnaviv=disabled \
+	-Dcairo-tests=disabled \
+	-Dman-pages=disabled \
+	-Dvalgrind=disabled \
+	-Dfreedreno-kgsl=false \
+	-Dinstall-test-programs=false \
+	-Dudev=false
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib*.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/libdrm/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libdrm))
diff --git a/external/subpack/libs/libdrm/patches/010-64bit.patch b/external/subpack/libs/libdrm/patches/010-64bit.patch
new file mode 100644
index 0000000..b02a2b5
--- /dev/null
+++ b/external/subpack/libs/libdrm/patches/010-64bit.patch
@@ -0,0 +1,12 @@
+--- a/include/drm/drm.h
++++ b/include/drm/drm.h
+@@ -37,6 +37,9 @@
+ 
+ #if   defined(__linux__)
+ 
++#ifndef __SANE_USERSPACE_TYPES__
++#define __SANE_USERSPACE_TYPES__	/* For PPC64, to get LL64 types */
++#endif
+ #include <linux/types.h>
+ #include <asm/ioctl.h>
+ typedef unsigned int drm_handle_t;
diff --git a/external/subpack/libs/libdvbcsa/Config.in b/external/subpack/libs/libdvbcsa/Config.in
new file mode 100644
index 0000000..4630d73
--- /dev/null
+++ b/external/subpack/libs/libdvbcsa/Config.in
@@ -0,0 +1,23 @@
+config LIBDVBCSA_DEBUG
+	bool "Enable debugging"
+	default n
+
+config LIBDVBCSA_MMX
+	bool "Use MMX for bitslice"
+	depends on (!LIBDVBCSA_SSE2 && (x86_64 || i386))
+	default n
+
+config LIBDVBCSA_SSE2
+	bool "Use SSE2 for bitslice"
+	depends on (x86_64 || i386)
+	default y
+
+config LIBDVBCSA_ALTIVEC
+	bool "Use AltiVec for bitslice"
+	depends on (BROKEN && (powerpc || powerpc64))
+	default y
+
+config LIBDVBCSA_NEON
+	bool "Use ARM NEON for bitslice"
+	depends on (arm || aarch64)
+	default y if aarch64
diff --git a/external/subpack/libs/libdvbcsa/Makefile b/external/subpack/libs/libdvbcsa/Makefile
new file mode 100644
index 0000000..62a89e9
--- /dev/null
+++ b/external/subpack/libs/libdvbcsa/Makefile
@@ -0,0 +1,69 @@
+#
+# Copyright (C) 2020 Rafał Dzięgiel <rafostar.github@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:=libdvbcsa
+PKG_RELEASE:=2
+
+PKG_SOURCE_VERSION:=bc6c0b164a87ce05e9925785cc6fb3f54c02b026
+PKG_HASH:=2d761c9e094642f2c9aa7e66534c6147a59d0d0bc709ec0f2fdbb34bf020d8ec
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
+PKG_SOURCE_URL:=https://code.videolan.org/videolan/libdvbcsa/-/archive/$(PKG_SOURCE_VERSION)
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION)
+
+PKG_MAINTAINER:=Rafał Dzięgiel <rafostar.github@gmail.com>
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libdvbcsa
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=DVB Common Scrambling Algorithm Library
+  URL:=https://www.videolan.org/developers/libdvbcsa.html
+  DEPENDS:=@BUILD_PATENTED
+endef
+
+define Package/libdvbcsa/description
+ Libdvbcsa is a free implementation of the DVB Common Scrambling
+ Algorithm DVB/CSA - with encryption and decryption capabilities.
+endef
+
+define Package/libdvbcsa/config
+  menu "Configuration"
+  depends on PACKAGE_libdvbcsa
+  source "$(SOURCE)/Config.in"
+  endmenu
+endef
+
+CONFIGURE_ARGS += \
+	--$(if $(CONFIG_LIBDVBCSA_DEBUG),en,dis)able-debug \
+	--$(if $(CONFIG_LIBDVBCSA_MMX),en,dis)able-mmx \
+	--$(if $(CONFIG_LIBDVBCSA_SSE2),en,dis)able-sse2 \
+	--$(if $(CONFIG_LIBDVBCSA_ALTIVEC),en,dis)able-altivec \
+	--$(if $(CONFIG_LIBDVBCSA_NEON),en,dis)able-neon
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/dvbcsa
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/dvbcsa/*.h $(1)/usr/include/dvbcsa/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+define Package/libdvbcsa/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libdvbcsa.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libdvbcsa))
diff --git a/external/subpack/libs/libesmtp/Makefile b/external/subpack/libs/libesmtp/Makefile
new file mode 100644
index 0000000..d4b6f6c
--- /dev/null
+++ b/external/subpack/libs/libesmtp/Makefile
@@ -0,0 +1,58 @@
+#
+# Copyright (C) 2008-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:=libesmtp
+PKG_VERSION:=1.1.0
+PKG_RELEASE:=2
+
+PKG_MAINTAINER:=Othmar Truniger <github@truniger.ch>
+PKG_LICENSE:=LGPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/libesmtp/libESMTP/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=32bc3614ca12d21c7d933f32d43410e8744b6f91fdca7732da9877a385e4e6c3
+PKG_BUILD_DIR:=$(BUILD_DIR)/libESMTP-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libesmtp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A Library for Posting Electronic Mail
+  URL:=https://libesmtp.github.io/
+  DEPENDS:=+libpthread +libopenssl
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libesmtp.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/esmtp-plugins-6.2.0
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/esmtp-plugins-6.2.0/sasl-crammd5.so $(1)/usr/lib/esmtp-plugins-6.2.0
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/esmtp-plugins-6.2.0/sasl-login.so $(1)/usr/lib/esmtp-plugins-6.2.0
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/esmtp-plugins-6.2.0/sasl-ntlm.so $(1)/usr/lib/esmtp-plugins-6.2.0
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/esmtp-plugins-6.2.0/sasl-plain.so $(1)/usr/lib/esmtp-plugins-6.2.0
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libesmtp-1.0.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/libesmtp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libesmtp.so.* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/esmtp-plugins-6.2.0
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/esmtp-plugins-6.2.0/sasl-crammd5.so $(1)/usr/lib/esmtp-plugins-6.2.0
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/esmtp-plugins-6.2.0/sasl-login.so $(1)/usr/lib/esmtp-plugins-6.2.0
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/esmtp-plugins-6.2.0/sasl-ntlm.so $(1)/usr/lib/esmtp-plugins-6.2.0
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/esmtp-plugins-6.2.0/sasl-plain.so $(1)/usr/lib/esmtp-plugins-6.2.0
+endef
+
+$(eval $(call BuildPackage,libesmtp))
diff --git a/external/subpack/libs/libestr/Makefile b/external/subpack/libs/libestr/Makefile
new file mode 100644
index 0000000..dd4f671
--- /dev/null
+++ b/external/subpack/libs/libestr/Makefile
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2015 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:=libestr
+PKG_VERSION:=0.1.11
+PKG_RELEASE:=3
+
+PKG_SOURCE_URL:=http://libestr.adiscon.com/files/download/
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_HASH:=46632b2785ff4a231dcf241eeb0dcb5fc0c7d4da8ee49cf5687722cdbe8b2024
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:adiscon:libestr
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libestr
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=String handling library
+  URL:=http://libestr.adiscon.com/
+endef
+
+define Package/libestr/description
+  libestr - some essentials for string handling (and a bit more)
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+endef
+
+define Package/libestr/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libestr.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libestr))
diff --git a/external/subpack/libs/libevdev/Makefile b/external/subpack/libs/libevdev/Makefile
new file mode 100644
index 0000000..df92371
--- /dev/null
+++ b/external/subpack/libs/libevdev/Makefile
@@ -0,0 +1,57 @@
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libevdev
+PKG_VERSION:=1.13.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://www.freedesktop.org/software/libevdev/
+PKG_HASH:=06a77bf2ac5c993305882bc1641017f5bec1592d6d1b64787bad492ab34f2f36
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libevdev
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=a wrapper library for evdev devices
+  URL:=https://www.freedesktop.org/wiki/Software/libevdev/
+endef
+
+define Package/libevdev/description
+  libevdev is a wrapper library for evdev devices. it moves the common
+  tasks when dealing with evdev devices into a library and provides a
+  library interface to the callers, thus avoiding erroneous ioctls, etc.
+
+  The eventual goal is that libevdev wraps all ioctls available to
+  evdev devices, thus making direct access unnecessary.
+endef
+
+MESON_ARGS += \
+	-Dtests=disabled \
+	-Ddocumentation=disabled \
+	-Dcoverity=false
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/libevdev-1.0/libevdev
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libevdev-1.0/libevdev/*.h $(1)/usr/include/libevdev-1.0/libevdev
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libevdev.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libevdev.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libevdev/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libevdev.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libevdev))
diff --git a/external/subpack/libs/libexif/Makefile b/external/subpack/libs/libexif/Makefile
new file mode 100644
index 0000000..3d53a6c
--- /dev/null
+++ b/external/subpack/libs/libexif/Makefile
@@ -0,0 +1,66 @@
+#
+# Copyright (C) 2006-2014 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:=libexif
+PKG_VERSION:=0.6.24
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://github.com/libexif/libexif/releases/download/v$(PKG_VERSION)
+PKG_HASH:=d47564c433b733d83b6704c70477e0a4067811d184ec565258ac563d8223f6ae
+
+PK_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libexif:libexif
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libexif
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=library for jpeg files with exif tags
+  URL:=https://libexif.github.io/
+endef
+
+define Package/libexif/description
+  libexif is a library for parsing, editing, and saving EXIF data. It is
+  intended to replace lots of redundant implementations in command-line
+  utilities and programs with GUIs.
+endef
+
+CONFIGURE_ARGS+= \
+	--enable-shared \
+	--enable-static \
+	--disable-rpath \
+	--disable-nls \
+	--without-libiconv-prefix \
+	--without-libintl-prefix \
+
+TARGET_CFLAGS += $(FPIC)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libexif $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libexif*.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libexif.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libexif/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libexif*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libexif))
diff --git a/external/subpack/libs/libexif/patches/100-no_doc.patch b/external/subpack/libs/libexif/patches/100-no_doc.patch
new file mode 100644
index 0000000..a67f79d
--- /dev/null
+++ b/external/subpack/libs/libexif/patches/100-no_doc.patch
@@ -0,0 +1,11 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -406,7 +406,7 @@ target_alias = @target_alias@
+ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+-SUBDIRS = m4m po libexif test doc binary-dist contrib
++SUBDIRS = m4m po libexif test binary-dist contrib
+ EXTRA_DIST = @PACKAGE_TARNAME@.spec README-Win32.txt libexif.pc.in \
+ 	libexif-uninstalled.pc.in SECURITY.md
+ pkgconfigdir = $(libdir)/pkgconfig
diff --git a/external/subpack/libs/libextractor/Makefile b/external/subpack/libs/libextractor/Makefile
new file mode 100644
index 0000000..c298c0d
--- /dev/null
+++ b/external/subpack/libs/libextractor/Makefile
@@ -0,0 +1,140 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libextractor
+PKG_VERSION:=1.13
+PKG_RELEASE:=1
+
+# ToDo:
+# - package missing optional dependencies: libexiv2, gsf, librpm, smf, tidy
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
+PKG_HASH:=bb8f312c51d202572243f113c6b62d8210301ab30cbaee604f9837d878cdf755
+
+PKG_LICENSE:=GPL-3.0-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_PACKAGE_libextractor-plugin-gstreamer
+
+PLUGINS:= \
+	archive:+libarchive-noopenssl \
+	deb \
+	dvi \
+	flac:+libflac \
+	gif:+giflib \
+	gstreamer:+libgstreamer1:+gstreamer1-plugins-base:+libgst1app:+libgst1pbutils:+libgst1tag \
+	it \
+	jpeg:+libjpeg-turbo \
+	man \
+	mime:+libmagic \
+	mpeg:+libmpeg2 \
+	nsf \
+	nsfe \
+	odf \
+	ogg:+libvorbis \
+	png \
+	ps \
+	riff \
+	s3m \
+	sid \
+	tiff:+libtiff \
+	wav \
+	xm \
+	zip
+
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+CONFIGURE_ARGS += \
+	--disable-glibtest \
+	--disable-gsf \
+	--disable-rpath \
+	--with$(if $(CONFIG_PACKAGE_libextractor-plugin-gstreamer),,out)-gstreamer
+
+define Package/libextractor
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=GNU Libextractor
+	URL:=https://www.gnu.org/software/libextractor/
+	DEPENDS:=+libbz2 +libltdl +librt +zlib $(ICONV_DEPENDS) $(INTL_DEPENDS)
+	MENU:=1
+endef
+
+define Package/libextractor/description
+  GNU Libextractor is a library used to extract meta data from files.
+  The goal is to provide developers of file-sharing networks, browsers or
+  WWW-indexing bots with a universal library to obtain simple keywords and meta
+  data to match against queries and to show to users instead of only relying on
+  filenames.
+endef
+
+define PluginGen
+define Package/libextractor-plugin-$(subst _,-,$(firstword $(subst :, ,$(1))))
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=GNU Libextractor ($(firstword $(subst :, ,$(1))) plugin)
+	URL:=https://www.gnu.org/software/libextractor/
+	DEPENDS:=libextractor $(wordlist 2,$(words $(subst :, ,$(1))),$(subst :, ,$(1)))
+endef
+endef
+
+$(foreach file,$(PLUGINS),$(eval $(call PluginGen,$(file))))
+
+define Package/extract
+	SECTION:=utils
+	CATEGORY:=Utilities
+	TITLE:=extract util from GNU Libextractor
+	URL:=https://www.gnu.org/software/libextractor/
+	DEPENDS:=+libextractor
+endef
+
+define Package/extract/description
+  libextractor contains the shell command extract that, similar to the
+  well-known file command, can extract meta data from a file an print the results
+  to stdout.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.{so*,a,la} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libextractor/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+define PluginInstall
+define Package/libextractor-plugin-$(subst _,-,$(firstword $(subst :, ,$(1))))/install
+	$(INSTALL_DIR) $$(1)/usr/lib/libextractor
+	$(INSTALL_BIN) \
+		$(PKG_INSTALL_DIR)/usr/lib/libextractor/libextractor_$(firstword $(subst :, ,$(1))).so \
+		$$(1)/usr/lib/libextractor
+endef
+endef
+
+define Package/extract/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+$(foreach file,$(PLUGINS),$(eval $(call PluginInstall,$(file))))
+
+$(eval $(call BuildPackage,libextractor))
+$(foreach file,$(PLUGINS),$(eval $(call BuildPackage,libextractor-plugin-$(subst _,-,$(firstword $(subst :, ,$(file)))))))
+$(eval $(call BuildPackage,extract))
diff --git a/external/subpack/libs/libextractor/patches/010-musl.patch b/external/subpack/libs/libextractor/patches/010-musl.patch
new file mode 100644
index 0000000..fe9562f
--- /dev/null
+++ b/external/subpack/libs/libextractor/patches/010-musl.patch
@@ -0,0 +1,11 @@
+--- a/src/common/le_architecture.h
++++ b/src/common/le_architecture.h
+@@ -26,6 +26,8 @@
+ 

+ #if WINDOWS

+ #include <sys/param.h>          /* #define BYTE_ORDER */

++#else

++#include <byteswap.h>

+ #endif

+ 

+ /* This is copied directly from GNUnet headers */

diff --git a/external/subpack/libs/libfastjson/Makefile b/external/subpack/libs/libfastjson/Makefile
new file mode 100644
index 0000000..9cbcc00
--- /dev/null
+++ b/external/subpack/libs/libfastjson/Makefile
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2015 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:=libfastjson
+PKG_VERSION:=1.2304.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://download.rsyslog.com/libfastjson
+PKG_HASH:=ef30d1e57a18ec770f90056aaac77300270c6203bbe476f4181cc83a2d5dc80c
+
+PKG_MAINTAINER:=Dov Murik <dmurik@us.ibm.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:rsyslog:libfastjson
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libfastjson
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A fast JSON library for C
+  URL:=https://github.com/rsyslog/libfastjson
+endef
+
+define Package/libfastjson/description
+  libfastjson - A fast JSON library for C
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+endef
+
+define Package/libfastjson/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfastjson.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libfastjson))
diff --git a/external/subpack/libs/libffi/Makefile b/external/subpack/libs/libffi/Makefile
new file mode 100644
index 0000000..aba83e2
--- /dev/null
+++ b/external/subpack/libs/libffi/Makefile
@@ -0,0 +1,89 @@
+#
+# Copyright (C) 2009-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:=libffi
+PKG_VERSION:=3.4.6
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/libffi/libffi/releases/download/v$(PKG_VERSION)
+PKG_HASH:=b0dea9df23c863a7a50e825440f3ebffabd65df1497108e5d437747843895a4e
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:libffi_project:libffi
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=no-mips16
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+define Package/libffi
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Foreign Function Interface (FFI) library
+  URL:=https://sourceware.org/libffi/
+  MAINTAINER:=Peter Wagner <tripolar@gmx.at>
+endef
+
+define Package/libffi/description
+The libffi library provides a portable, high level programming interface to
+various calling conventions. This allows a programmer to call any function
+specified by a call interface description at run-time.
+
+FFI stands for Foreign Function Interface. A foreign function interface is the
+popular name for the interface that allows code written in one language to call
+code written in another language. The libffi library really only provides the
+lowest, machine dependent layer of a fully featured foreign function interface.
+A layer must exist above libffi that handles type conversions for values passed
+between the two languages.
+endef
+
+HOST_CONFIGURE_ARGS += \
+	--disable-shared \
+	--disable-docs \
+	--disable-multi-os-directory \
+	--disable-raw-api \
+	--disable-structs \
+	--with-pic
+
+CONFIGURE_ARGS += \
+	--disable-docs \
+	--disable-multi-os-directory \
+	--disable-raw-api \
+	--disable-structs
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libffi.{so*,a,la} \
+		$(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* \
+		$(1)/usr/lib/pkgconfig/
+	$(SED) 's,includedir=.*,includedir=$$$${prefix}/include,' $(1)/usr/lib/pkgconfig/libffi.pc
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/*.h \
+		$(1)/usr/include/
+endef
+
+define Package/libffi/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libffi.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,libffi))
diff --git a/external/subpack/libs/libfido2/Makefile b/external/subpack/libs/libfido2/Makefile
new file mode 100644
index 0000000..9780cc7
--- /dev/null
+++ b/external/subpack/libs/libfido2/Makefile
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2020 Linos Giannopoulos
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libfido2
+PKG_VERSION:=1.14.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/Yubico/libfido2/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=3601792e320032d428002c4cce8499a4c7b803319051a25a0c9f1f138ffee45a
+
+PKG_MAINTAINER:=Linos Giannopoulos <linosgian00+openwrt@gmail.com>
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FORTIFY_SOURCE:=0
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libfido2
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=FIDO2 Library
+  URL:=https://github.com/Yubico/libfido2
+  ABI_VERSION:=1
+  DEPENDS += +libcbor +libopenssl +libudev +zlib
+endef
+
+define Package/libfido2/description
+ libfido2 provides library functionality and command-line tools to communicate with a FIDO device over USB, and to verify attestation and assertion signatures.
+
+ libfido2 supports the FIDO U2F (CTAP 1) and FIDO 2.0 (CTAP 2) protocols.
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_EXAMPLES=OFF \
+	-DBUILD_MANPAGES=OFF \
+	-DBUILD_STATIC_LIBS=OFF \
+	-DBUILD_TOOLS=OFF
+
+define Package/libfido2/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfido2.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libfido2))
diff --git a/external/subpack/libs/libfmt/Makefile b/external/subpack/libs/libfmt/Makefile
new file mode 100644
index 0000000..a1fcd2d
--- /dev/null
+++ b/external/subpack/libs/libfmt/Makefile
@@ -0,0 +1,58 @@
+#
+# Copyright (C) 2018 Othmar Truniger
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libfmt
+PKG_VERSION:=11.0.2
+PKG_RELEASE:=1
+
+PKG_SOURCE_NAME:=fmt
+PKG_SOURCE:=$(PKG_SOURCE_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/fmtlib/$(PKG_SOURCE_NAME)/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=6cb1e6d37bdcb756dbbe59be438790db409cdb4868c66e888d5df9f13f7c027f
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_NAME)-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Othmar Truniger <github@truniger.ch>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE.rst
+PKG_CPE_ID:=cpe:/a:fmt:fmt
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_OPTIONS += -DBUILD_SHARED_LIBS=ON
+CMAKE_OPTIONS += -DFMT_DOC=OFF
+CMAKE_OPTIONS += -DFMT_TEST=OFF
+
+define Package/libfmt
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Small, safe and fast formatting library
+  URL:=https://github.com/fmtlib/fmt
+  DEPENDS:=+libstdcpp
+endef
+
+define Package/libfmt/description
+  fmt is an open-source formatting library for C++.
+  It can be used as a safe alternative to printf or as a fast alternative to IOStreams.
+endef
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/fmt.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/fmt.pc
+endef
+
+define Package/libfmt/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfmt.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libfmt))
diff --git a/external/subpack/libs/libfstrm/Makefile b/external/subpack/libs/libfstrm/Makefile
new file mode 100644
index 0000000..7d26043
--- /dev/null
+++ b/external/subpack/libs/libfstrm/Makefile
@@ -0,0 +1,61 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libfstrm
+PKG_VERSION:=0.6.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=fstrm-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://dl.farsightsecurity.com/dist/fstrm/
+PKG_HASH:=bca4ac1e982a2d923ccd24cce2c98f4ceeed5009694430f73fc0dcebca8f098f
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/fstrm-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Peter van Dijk <peter.van.dijk@powerdns.com>, Remi Gacogne <remi.gacogne@powerdns.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libfstrm
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=C implementation of the Frame Streams data transport protocol
+  URL:=https://github.com/farsightsec/fstrm
+endef
+
+define Package/libfstrm/description
+fstrm is an optimized C implementation of Frame Streams that includes a fast,
+  lockless circular queue implementation and exposes library interfaces for
+  setting up a dedicated Frame Streams I/O thread and asynchronously submitting
+  data frames for transport from worker threads. It was originally written to
+  facilitate the addition of high speed binary logging to DNS servers written
+  in C using the dnstap log format.
+endef
+
+CONFIGURE_ARGS+= \
+	--disable-programs
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/include/fstrm
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/fstrm/*.h $(1)/usr/include/fstrm/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfstrm.{a,so*} $(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libfstrm.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libfstrm/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfstrm.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libfstrm))
diff --git a/external/subpack/libs/libftdi/Makefile b/external/subpack/libs/libftdi/Makefile
new file mode 100644
index 0000000..7e5dccb
--- /dev/null
+++ b/external/subpack/libs/libftdi/Makefile
@@ -0,0 +1,66 @@
+#
+# Copyright (C) 2011-2015 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:=libftdi
+PKG_VERSION:=0.20
+PKG_RELEASE:=7
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.intra2net.com/en/developer/libftdi/download/
+PKG_HASH:=3176d5b5986438f33f5208e690a8bfe90941be501cc0a72118ce3d338d4b838e
+
+PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
+PKG_LICENSE:=LGPL-2.0
+PKG_LICENSE_FILES:=COPYING.LIB
+
+CMAKE_INSTALL:=1
+PKG_BUILD_FLAGS:=no-mips16
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libftdi
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libusb-compat
+  TITLE:=Library to talk to FTDI chips
+  URL:=http://www.intra2net.com/en/developer/libftdi/
+endef
+
+define Package/libftdi/description
+  libFTDI - FTDI USB driver with bitbang mode
+  libFTDI is an open source library to talk to FTDI chips: FT232BM, FT245BM, FT2232C, FT2232H, FT4232H, FT2232D and FT245R, including the popular bitbang mode. 
+  The library is linked with your program in userspace, no kernel driver required.
+endef
+
+CMAKE_OPTIONS += \
+	-DBoost_NO_BOOST_CMAKE=ON \
+	-DEXAMPLES=OFF
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/bin,/usr,g' $(1)/usr/lib/pkgconfig/libftdi.pc
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libftdi.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libftdi.pc
+	$(SED) 's,/usr/bin,/usr,g' $(1)/usr/lib/pkgconfig/libftdipp.pc
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libftdipp.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libftdipp.pc
+	$(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(1)/usr/bin/libftdi-config
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/libftdi-config $(2)/bin/libftdi-config
+endef
+
+define Package/libftdi/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libftdi-config $(1)/usr/bin/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libftdi.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libftdi))
diff --git a/external/subpack/libs/libftdi/patches/100-fix-x86_64-build.patch b/external/subpack/libs/libftdi/patches/100-fix-x86_64-build.patch
new file mode 100644
index 0000000..2460cb1
--- /dev/null
+++ b/external/subpack/libs/libftdi/patches/100-fix-x86_64-build.patch
@@ -0,0 +1,11 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -44,7 +44,7 @@ IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
+     SET(LIB_SUFFIX "")
+     SET(PACK_ARCH "")
+   ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8)
+-    SET(LIB_SUFFIX 64)
++    SET(LIB_SUFFIX "")
+     SET(PACK_ARCH .x86_64)
+ endif(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ 
diff --git a/external/subpack/libs/libftdi/patches/101-fix-cmake-version-packagekit.patch b/external/subpack/libs/libftdi/patches/101-fix-cmake-version-packagekit.patch
new file mode 100644
index 0000000..e6861dc
--- /dev/null
+++ b/external/subpack/libs/libftdi/patches/101-fix-cmake-version-packagekit.patch
@@ -0,0 +1,29 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1,9 +1,12 @@
+ # Project
+ project(libftdi)
++set(PACKAGE libftdi)
+ set(MAJOR_VERSION 0)
+ set(MINOR_VERSION 20)
++set(VERSION ${VERSION_STRING})
+ set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION})
+-SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}")
++set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}")
++set(top_srcdir ${CMAKE_SOURCE_DIR})
+ 
+ # CMake
+ if("${CMAKE_BUILD_TYPE}" STREQUAL "")
+@@ -98,12 +101,6 @@ option(DOCUMENTATION "Generate API docum
+ 
+ find_package(Doxygen)
+ if(DOCUMENTATION AND DOXYGEN_FOUND)
+-
+-   # Set variables
+-   set(PACKAGE libftdi)
+-   set(VERSION ${VERSION_STRING})
+-   set(top_srcdir ${CMAKE_SOURCE_DIR})
+-
+    # Find doxy config
+    message(STATUS "Doxygen found.")
+    set(DOXY_DIR "${CMAKE_SOURCE_DIR}/doc")
diff --git a/external/subpack/libs/libftdi/patches/102-fix-cmake-include-examples.patch b/external/subpack/libs/libftdi/patches/102-fix-cmake-include-examples.patch
new file mode 100644
index 0000000..b37a968
--- /dev/null
+++ b/external/subpack/libs/libftdi/patches/102-fix-cmake-include-examples.patch
@@ -0,0 +1,11 @@
+--- a/examples/CMakeLists.txt
++++ b/examples/CMakeLists.txt
+@@ -2,7 +2,7 @@ option(EXAMPLES "Build example programs"
+ 
+ if (EXAMPLES)
+     # Includes
+-    include( ${CMAKE_CURRENT_SOURCE_DIR}
++    include_directories( ${CMAKE_CURRENT_SOURCE_DIR}
+             ${CMAKE_CURRENT_BINARY_DIR}
+             )
+ 
diff --git a/external/subpack/libs/libftdi1/Makefile b/external/subpack/libs/libftdi1/Makefile
new file mode 100644
index 0000000..60985f1
--- /dev/null
+++ b/external/subpack/libs/libftdi1/Makefile
@@ -0,0 +1,92 @@
+#
+# Copyright (C) 2014-2017 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:=libftdi1
+PKG_VERSION:=1.5
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://www.intra2net.com/en/developer/libftdi/download/
+PKG_HASH:=7c7091e9c86196148bd41177b4590dccb1510bfe6cea5bf7407ff194482eb049
+
+PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
+PKG_LICENSE:=LGPL-2.1-only
+PKG_LICENSE_FILES:=COPYING.LIB
+
+CMAKE_INSTALL:=1
+PKG_BUILD_FLAGS:=no-mips16
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libftdi1
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libusb-1.0
+  TITLE:=Library to talk to FTDI chips
+  URL:=http://www.intra2net.com/en/developer/libftdi/
+endef
+
+define Package/libftdi1/description
+  libFTDI - FTDI USB driver with bitbang mode
+  libFTDI is an open source library to talk to FTDI chips: FT232BM, FT245BM, FT2232C, FT2232H, FT4232H, FT2232D and FT245R, including the popular bitbang mode. 
+  The library is linked with your program in userspace, no kernel driver required.
+endef
+
+define Package/ftdi_eeprom
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+confuse +libftdi1
+  TITLE:=Tool for reading/erasing/flashing FTDI USB chip eeproms
+  URL:=http://www.intra2net.com/en/developer/libftdi/
+endef
+
+define Package/ftdi_eeprom/description
+  ftdi_eeprom is a small tool for reading/erasing/flashing FTDI USB chip
+  eeproms. It uses libftdi to access the chip, so you will need to have
+  the required permissions on the device.
+
+  The ftdi_sio module should not be loaded.
+
+  You have to unplug and replug your device to get the new values to be
+  read. Otherwise, you will still get the old values.
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_TESTS=OFF \
+	-DDOCUMENTATION=OFF \
+	-DEXAMPLES=OFF
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/bin,/usr,g' $(1)/usr/lib/pkgconfig/libftdi1.pc
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libftdi1.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libftdi1.pc
+	$(SED) 's,/usr/bin,/usr,g' $(1)/usr/lib/pkgconfig/libftdipp1.pc
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libftdipp1.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libftdipp1.pc
+	$(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(1)/usr/bin/libftdi1-config
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/libftdi1-config $(2)/bin/libftdi1-config
+endef
+
+define Package/libftdi1/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libftdi1-config $(1)/usr/bin/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libftdi1.so.* $(1)/usr/lib/
+endef
+
+define Package/ftdi_eeprom/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ftdi_eeprom $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libftdi1))
+$(eval $(call BuildPackage,ftdi_eeprom))
diff --git a/external/subpack/libs/libftdi1/patches/100-fix-x86_64-build.patch b/external/subpack/libs/libftdi1/patches/100-fix-x86_64-build.patch
new file mode 100644
index 0000000..12861d9
--- /dev/null
+++ b/external/subpack/libs/libftdi1/patches/100-fix-x86_64-build.patch
@@ -0,0 +1,11 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -57,7 +57,7 @@ if ( NOT DEFINED LIB_SUFFIX )
+       AND NOT EXISTS "/etc/debian_version"
+       AND NOT EXISTS "/etc/arch-release" )
+     if ( "${CMAKE_SIZEOF_VOID_P}" EQUAL "8" )
+-      set ( LIB_SUFFIX 64 )
++      set ( LIB_SUFFIX "" )
+     endif ()
+   endif ()
+ endif ()
diff --git a/external/subpack/libs/libgabe/Makefile b/external/subpack/libs/libgabe/Makefile
new file mode 100644
index 0000000..9c74881
--- /dev/null
+++ b/external/subpack/libs/libgabe/Makefile
@@ -0,0 +1,47 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libgabe
+PKG_VERSION:=1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/schanzen/libgabe/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=2a8c151a90c9ad8eaad073c8ad1482d66875e3433b0b4fd1e08424c0fc89e877
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=GPLv2
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libgabe
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+glib2 +libgcrypt +libgmp +libpbc
+  TITLE:=Ciphertext-Policy Attribute-Based Encryption
+  URL:=https://github.com/schanzen/libgabe
+endef
+
+define Package/libgabe/description
+  This is a fork of the libbswabe library by John Bethencourt
+  (http://hms.isi.jhu.edu/acsc/cpabe/) replacing openssl with libgcrypt
+  and fixing some bugs.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+define Package/libgabe/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libgabe))
diff --git a/external/subpack/libs/libgabe/patches/010-shared-library.patch b/external/subpack/libs/libgabe/patches/010-shared-library.patch
new file mode 100644
index 0000000..5bdc73e
--- /dev/null
+++ b/external/subpack/libs/libgabe/patches/010-shared-library.patch
@@ -0,0 +1,46 @@
+From 9a0e73c5f6cbcf825eced89d26273a24f7266522 Mon Sep 17 00:00:00 2001
+From: "Schanzenbach, Martin" <martin.schanzenbach@aisec.fraunhofer.de>
+Date: Sun, 30 Sep 2018 20:38:37 +0200
+Subject: [PATCH] shared library
+
+---
+ Makefile.in | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -18,13 +18,12 @@ LDFLAGS = @LDFLAGS@ \
+ 
+ DISTNAME = @PACKAGE_TARNAME@-@PACKAGE_VERSION@
+ 
+-all: libgabe.a TAGS
++all: libgabe.so TAGS
+ 
+ # compilation and library making
+ 
+-libgabe.a: core.o misc.o
+-	rm -f $@
+-	ar rc $@ $^
++libgabe.so: core.o misc.o
++	$(CC) -shared -o $@ $^
+ 
+ # test: test.o libgabe.a
+ # 	$(CC) -o $@ $(LDFLAGS) $^
+@@ -44,14 +43,14 @@ dist: AUTHORS COPYING INSTALL NEWS READM
+ 	tar zc $(DISTNAME) > $(DISTNAME).tar.gz
+ 	rm -rf $(DISTNAME)
+ 
+-install: libgabe.a gabe.h
++install: libgabe.so gabe.h
+ 	$(top_srcdir)/mkinstalldirs -m 755 $(DESTDIR)$(libdir)
+ 	$(top_srcdir)/mkinstalldirs -m 755 $(DESTDIR)$(includedir)
+-	$(top_srcdir)/install-sh -m 755 libgabe.a $(DESTDIR)$(libdir)
++	$(top_srcdir)/install-sh -m 755 libgabe.so $(DESTDIR)$(libdir)
+ 	$(top_srcdir)/install-sh -m 644 gabe.h $(DESTDIR)$(includedir)
+ 
+ uninstall:
+-	/bin/rm -f $(DESTDIR)$(libdir)/libgabe.a
++	/bin/rm -f $(DESTDIR)$(libdir)/libgabe.so
+ 	/bin/rm -f $(DESTDIR)$(includedir)/gabe.h
+ 
+ # development and meta stuff
diff --git a/external/subpack/libs/libgcrypt/Makefile b/external/subpack/libs/libgcrypt/Makefile
new file mode 100644
index 0000000..bde8880
--- /dev/null
+++ b/external/subpack/libs/libgcrypt/Makefile
@@ -0,0 +1,71 @@
+#
+# Copyright (C) 2005-2011 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:=libgcrypt
+PKG_VERSION:=1.10.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://www.gnupg.org/ftp/gcrypt/libgcrypt/
+PKG_HASH:=8b0870897ac5ac67ded568dcfadf45969cfa8a6beb0fd60af2a9eadc2a3272aa
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_CPE_ID:=cpe:/a:gnupg:libgcrypt
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libgcrypt
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libgpg-error
+  TITLE:=GNU crypto library
+  URL:=https://www.gnupg.org/related_software/libgcrypt/
+  LICENSE:=LGPL-2.1-or-later
+  LICENSE_FILES:=COPYING.LIB
+endef
+
+define Package/libgcrypt/description
+ This is a general purpose cryptographic library based on the code from
+ GnuPG. It provides functions for all cryptograhic building blocks:
+ symmetric ciphers (AES, DES, Arcfour, CAST5), hash algorithms (MD5, SHA-1,
+ RIPE-MD160, SHA-224/256, SHA-384/512), MACs (HMAC for all hash
+ algorithms), public key algorithms (RSA, DSA), large integer functions,
+ random numbers and a lot of supporting functions. Some algorithms have
+ been disabled to reduce size (Blowfish, Twofish, Serpent,
+ RC2, SEED, Camellia, CRC, MD4, TIGER-192, Whirlpool, ElGamal, ECC).
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--disable-asm \
+	--disable-doc \
+	--with-gpg-error-prefix="$(STAGING_DIR)/usr"
+
+TARGET_CFLAGS += $(FPIC)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin $(2)/bin $(1)/usr/include $(1)/usr/lib $(1)/usr/share/aclocal
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libgcrypt-config $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/gcrypt*.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgcrypt.{la,a,so*} $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/share/aclocal/libgcrypt.m4 $(1)/usr/share/aclocal/
+	$(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(1)/usr/bin/libgcrypt-config
+	$(LN) ../../usr/bin/libgcrypt-config $(2)/bin/libgcrypt-config
+endef
+
+define Package/libgcrypt/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgcrypt.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libgcrypt))
diff --git a/external/subpack/libs/libgd/Makefile b/external/subpack/libs/libgd/Makefile
new file mode 100644
index 0000000..f1bc84f
--- /dev/null
+++ b/external/subpack/libs/libgd/Makefile
@@ -0,0 +1,128 @@
+#
+# Copyright (C) 2006-2015 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:=libgd
+PKG_VERSION:=2.3.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/$(PKG_NAME)/$(PKG_NAME)/releases/download/gd-$(PKG_VERSION)/
+PKG_HASH:=3fe822ece20796060af63b7c60acb151e5844204d289da0ce08f8fdf131e5a61
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
+PKG_LICENSE:=GD
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libgd:libgd
+
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libgd/default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libjpeg +libpng +libwebp
+  TITLE:=The GD graphics library
+  URL:=https://libgd.github.io/
+endef
+
+define Package/libgd
+  $(call Package/libgd/default)
+  MENU:=1
+  DEPENDS+=+LIBGD_TIFF:libtiff +LIBGD_FREETYPE:libfreetype
+  VARIANT:=default
+  CONFLICTS:=libgd-full
+endef
+
+define Package/libgd-full
+  $(call Package/libgd/default)
+  DEPENDS+=+libtiff +libfreetype
+  TITLE+=(full)
+  VARIANT:=full
+  PROVIDES:=libgd
+endef
+
+define Package/libgd/description/default
+  GD is an open source code library for the dynamic creation of images by
+  programmers. GD creates PNG, JPEG and GIF images, among other formats.
+endef
+
+Package/libgd/description=$(Package/libgd/description/default)
+
+define Package/libgd-full/description
+  $(call Package/libgd/description/default)
+  .
+  This variant of the libgd package is compiled will all features enabled.
+endef
+
+define Package/libgd/config
+	if PACKAGE_libgd
+		config LIBGD_TIFF
+			bool "TIFF image support"
+			default n
+			help
+				Enable TIFF image support through libtiff
+	endif
+	if PACKAGE_libgd
+		config LIBGD_FREETYPE
+			bool "Freetype 2.x library support"
+			default n
+			help
+				Enable Freetype 2.x font engine support through libfreetype
+	endif
+endef
+
+TARGET_CFLAGS += $(FPIC) -ffunction-sections -fdata-sections
+
+CMAKE_OPTIONS += \
+	-DENABLE_FONTCONFIG=OFF \
+	-DENABLE_ICONV=OFF \
+	-DENABLE_JPEG=ON \
+	-DENABLE_LIQ=OFF \
+	-DENABLE_PNG=ON \
+	-DENABLE_TIFF=$(if $(CONFIG_LIBGD_TIFF),ON,OFF) \
+	-DENABLE_WEBP=ON \
+	-DENABLE_XPM=OFF \
+	-DZLIB_INCLUDE_DIR="$(STAGING_DIR)/usr"
+
+ifeq ($(BUILD_VARIANT),full)
+	CMAKE_OPTIONS += \
+		-DENABLE_TIFF=ON \
+		-DFREETYPE_INCLUDE_DIRS=$(STAGING_DIR)/usr/include/freetype2/ \
+		-DENABLE_FREETYPE=ON
+
+else
+
+ifdef CONFIG_LIBGD_FREETYPE
+	CMAKE_OPTIONS += \
+		-DFREETYPE_INCLUDE_DIRS=$(STAGING_DIR)/usr/include/freetype2/ \
+		-DENABLE_FREETYPE=ON
+else
+	CMAKE_OPTIONS += \
+		-DENABLE_FREETYPE=OFF
+endif
+
+endif
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/lib,$(STAGING_DIR)/usr/lib,g' $(1)/usr/lib/pkgconfig/gdlib.pc
+	$(SED) 's,/usr/include,$(STAGING_DIR)/include,g' $(1)/usr/lib/pkgconfig/gdlib.pc
+endef
+
+define Package/libgd/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgd.so* $(1)/usr/lib/
+endef
+
+Package/libgd-full/install=$(Package/libgd/install)
+
+$(eval $(call BuildPackage,libgd))
+$(eval $(call BuildPackage,libgd-full))
diff --git a/external/subpack/libs/libgd/patches/010-webp.patch b/external/subpack/libs/libgd/patches/010-webp.patch
new file mode 100644
index 0000000..2b21bab
--- /dev/null
+++ b/external/subpack/libs/libgd/patches/010-webp.patch
@@ -0,0 +1,25 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -134,7 +134,7 @@ else (USE_EXT_GD)
+ 	endif (ENABLE_ICONV)
+ 
+ 	IF (ENABLE_WEBP)
+-		FIND_PACKAGE(WEBP REQUIRED)
++		FIND_PACKAGE(WebP REQUIRED)
+ 	ENDIF (ENABLE_WEBP)
+ 
+ 	IF (ENABLE_HEIF)
+@@ -195,10 +195,10 @@ else (USE_EXT_GD)
+ 		LIST(APPEND PKG_REQUIRES_PRIVATES zlib)
+ 	ENDIF(ZLIB_FOUND)
+ 
+-	IF(WEBP_FOUND)
+-		INCLUDE_DIRECTORIES(${WEBP_INCLUDE_DIR})
++	IF(WebP_FOUND)
++		INCLUDE_DIRECTORIES(${WebP_INCLUDE_DIR})
+ 		SET(HAVE_LIBWEBP 1)
+-	ENDIF(WEBP_FOUND)
++	ENDIF(WebP_FOUND)
+ 
+ 	IF(HEIF_FOUND)
+ 		INCLUDE_DIRECTORIES(${HEIF_INCLUDE_DIR})
diff --git a/external/subpack/libs/libgd/patches/100-no-cxx.patch b/external/subpack/libs/libgd/patches/100-no-cxx.patch
new file mode 100644
index 0000000..63c733a
--- /dev/null
+++ b/external/subpack/libs/libgd/patches/100-no-cxx.patch
@@ -0,0 +1,26 @@
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -18,7 +18,6 @@ SET (LIBGD_SRC_FILES
+ 	gd_io_dp.c
+ 	gd_io_file.c
+ 	gd_io_ss.c
+-	gd_io_stream.cxx
+ 	gd_jpeg.c
+ 	gd_matrix.c
+ 	gd_nnquant.c
+@@ -44,7 +43,6 @@ SET (LIBGD_SRC_FILES
+ 	gdfx.c
+ 	gdhelpers.c
+ 	gdkanji.c
+-	gdpp.cxx
+ 	gdtables.c
+ 	gdxpm.c
+ 	wbmp.c
+@@ -193,7 +191,6 @@ install(FILES
+ 	gdfonts.h
+ 	gdfontt.h
+ 	gdfx.h
+-	gdpp.h
+ 	DESTINATION include)
+ 
+ CONFIGURE_FILE(../config/gdlib.pc.cmake gdlib.pc @ONLY)
diff --git a/external/subpack/libs/libgee/Makefile b/external/subpack/libs/libgee/Makefile
new file mode 100644
index 0000000..965b49d
--- /dev/null
+++ b/external/subpack/libs/libgee/Makefile
@@ -0,0 +1,74 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libgee
+PKG_VERSION:=0.20.6
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@GNOME/libgee/$(basename $(PKG_VERSION))
+PKG_HASH:=1bf834f5e10d60cc6124d74ed3c1dd38da646787fbf7872220b8b4068e476d4d
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:gnome:libgee
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_DEPENDS:=vala/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libgee
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+glib2
+  TITLE:=libgee
+  URL:=https://wiki.gnome.org/Libgee
+endef
+
+define Package/libgee/decription
+  Libgee is an utility library providing GObject-based interfaces and classes
+endef
+
+CONFIGURE_ARGS += \
+	--disable-benchmark \
+	--disable-coverage \
+	--disable-doc \
+	--disable-internal-asserts \
+	--disable-introspection \
+	--disable-vala-fatal-warnings
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/gee-0.8/ \
+		$(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc \
+		$(1)/usr/lib/pkgconfig/
+	$(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/share/vala-`$(STAGING_DIR_HOSTPKG)/bin/valac --api-version`/vapi/
+	$(INSTALL_DATA) \
+                $(PKG_INSTALL_DIR)/usr/share/vala/vapi/* \
+                $(STAGING_DIR_HOSTPKG)/share/vala-`$(STAGING_DIR_HOSTPKG)/bin/valac --api-version`/vapi
+endef
+
+define Package/libgee/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libgee))
diff --git a/external/subpack/libs/libgpg-error/Makefile b/external/subpack/libs/libgpg-error/Makefile
new file mode 100644
index 0000000..d2e8ecb
--- /dev/null
+++ b/external/subpack/libs/libgpg-error/Makefile
@@ -0,0 +1,109 @@
+#
+# Copyright (C) 2005-2011 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:=libgpg-error
+PKG_VERSION:=1.49
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://mirrors.dotsrc.org/gcrypt/libgpg-error \
+		http://ring.ksc.gr.jp/archives/net/gnupg/libgpg-error \
+		https://www.gnupg.org/ftp/gcrypt/libgpg-error
+PKG_HASH:=8b79d54639dbf4abc08b5406fb2f37e669a2dec091dd024fb87dd367131c63a9
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:gnupg:libgpg-error
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libgpg-error
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GnuPG error handling helper library
+  URL:=https://www.gnupg.org/related_software/libgpg-error/
+endef
+
+define Package/libgpg-error/description
+	An helper library for common error codes and descriptions.
+	This is a library that defines common error values for all GnuPG
+	components. Among these are GPG, GPGSM, GPGME, GPG-Agent, libgcrypt,
+	Libksba, DirMngr, Pinentry, SmartCard Daemon and possibly more in the
+	future.
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--enable-install-gpg-error-config \
+	--disable-doc \
+	--disable-languages \
+	--disable-rpath \
+	--disable-tests
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(2)/bin $(1)/usr/bin
+	$(INSTALL_BIN) \
+		$(PKG_INSTALL_DIR)/usr/bin/gpg-error-config \
+		$(2)/bin/
+	$(SED) \
+		's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \
+		$(2)/bin/gpg-error-config
+	$(LN) $(STAGING_DIR)/host/bin/gpg-error-config $(1)/usr/bin/gpg-error-config
+
+	$(INSTALL_BIN) \
+		$(PKG_INSTALL_DIR)/usr/bin/gpgrt-config \
+		$(2)/bin/
+	$(SED) \
+		's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \
+		$(2)/bin/gpgrt-config
+	$(LN) $(STAGING_DIR)/host/bin/gpgrt-config $(1)/usr/bin/gpgrt-config
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/include/gpg-error.h \
+		$(1)/usr/include/
+
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/include/gpgrt.h \
+		$(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libgpg-error.{la,a,so*} \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/share/aclocal
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/share/aclocal/gpg-error.m4 \
+		$(1)/usr/share/aclocal/
+
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/share/aclocal/gpgrt.m4 \
+		$(1)/usr/share/aclocal/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/gpg-error.pc \
+		$(1)/usr/lib/pkgconfig
+endef
+
+define Package/libgpg-error/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libgpg-error.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libgpg-error))
diff --git a/external/subpack/libs/libgpg-error/patches/001-cross-compile-fix.patch b/external/subpack/libs/libgpg-error/patches/001-cross-compile-fix.patch
new file mode 100644
index 0000000..606cdd3
--- /dev/null
+++ b/external/subpack/libs/libgpg-error/patches/001-cross-compile-fix.patch
@@ -0,0 +1,24 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -74,6 +74,21 @@ AM_SILENT_RULES
+ AC_CANONICAL_HOST
+ AB_INIT
+ 
++case "${host}" in
++    x86_64-openwrt-linux-gnu|i?86-openwrt-linux-gnu)
++        host=$(echo $host | sed 's/openwrt/pc/g')
++        ;;
++    arm-openwrt-linux-gnu|armeb-openwrt-linux-gnu)
++        host=arm-unknown-linux-gnueabi
++        ;;
++    mips64-openwrt-linux-gnu)
++        host=mips64el-unknown-linux-gnuabi64
++        ;;
++    *)
++        host=$(echo $host | sed 's/openwrt/unknown/g')
++        ;;
++esac
++
+ # Checks for programs.
+ AC_PROG_CC
+ AM_PROG_CC_C_O
diff --git a/external/subpack/libs/libgpg-error/patches/010-add-arc-support.patch b/external/subpack/libs/libgpg-error/patches/010-add-arc-support.patch
new file mode 100644
index 0000000..03387f8
--- /dev/null
+++ b/external/subpack/libs/libgpg-error/patches/010-add-arc-support.patch
@@ -0,0 +1,64 @@
+From: Mylene Josserand <mylene.josserand at bootlin.com>
+
+DesignWare ARC Processors are a family of 32-bit CPUs from Synopsys.
+This change allows us to build for and use libgpg-error on ARC cores.
+
+These values were obtained from a test application executed on ARC
+in simulation this way:
+
+1. Instructions for cross-compilation used are here:
+   http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgpg-error.git;a=blob;f=README
+
+2. Commands used on host:
+   # build="$(build-aux/config.guess)"
+   # ./configure --prefix=build/tmp-uclibc/sysroots/nsimhs/usr/ --host=arc-oe-linux-uclibc --build=$build
+   # cd src
+   # make gen-posix-lock-obj
+
+3. Commands used on target:
+   # ./gen-posix-lock-obj
+
+Signed-off-by: Mylene Josserand <mylene.josserand at bootlin.com>
+Signed-off-by: Alexey Brodkin <abrodkin at synopsys.com>
+---
+ src/Makefile.am                               |  1 +
+ .../lock-obj-pub.arc-unknown-linux-gnu.h      | 23 +++++++++++++++++++
+ 2 files changed, 24 insertions(+)
+ create mode 100644 src/syscfg/lock-obj-pub.arc-unknown-linux-gnu.h
+
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -40,6 +40,7 @@ lock_obj_pub = \
+         syscfg/lock-obj-pub.aarch64-unknown-linux-gnu_ilp32.h \
+ 	syscfg/lock-obj-pub.aarch64-apple-darwin.h          \
+         syscfg/lock-obj-pub.alpha-unknown-linux-gnu.h       \
++        syscfg/lock-obj-pub.arc-unknown-linux-gnu.h         \
+         syscfg/lock-obj-pub.arm-unknown-linux-androideabi.h \
+         syscfg/lock-obj-pub.arm-unknown-linux-gnueabi.h     \
+ 	syscfg/lock-obj-pub.arm-apple-darwin.h              \
+--- /dev/null
++++ b/src/syscfg/lock-obj-pub.arc-unknown-linux-gnu.h
+@@ -0,0 +1,23 @@
++## lock-obj-pub.arc-oe-linux-uclibc.h
++## File created by gen-posix-lock-obj - DO NOT EDIT
++## To be included by mkheader into gpg-error.h
++
++typedef struct
++{
++  long _vers;
++  union {
++    volatile char _priv[24];
++    long _x_align;
++    long *_xp_align;
++  } u;
++} gpgrt_lock_t;
++
++#define GPGRT_LOCK_INITIALIZER {1,{{0,0,0,0,0,0,0,0, \
++                                    0,0,0,0,0,0,0,0, \
++                                    0,0,0,0,0,0,0,0}}}
++##
++## Local Variables:
++## mode: c
++## buffer-read-only: t
++## End:
++##
diff --git a/external/subpack/libs/libgphoto2/Makefile b/external/subpack/libs/libgphoto2/Makefile
new file mode 100644
index 0000000..91a27f0
--- /dev/null
+++ b/external/subpack/libs/libgphoto2/Makefile
@@ -0,0 +1,868 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+# Copyright (C) 2017-2019 Leonardo Medici
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libgphoto2
+PKG_VERSION:=2.5.30
+PKG_RELEASE:=1
+PORT_VERSION:=0.12.1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@SF/gphoto
+PKG_HASH:=ee61a1dac6ad5cf711d114e06b90a6d431961a6e7ec59f4b757a7cd77b1c0fb4
+
+PKG_MAINTAINER:=Leonardo Medici <leonardo_medici@me.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_LIBTOOL_PATHS:=. libgphoto2_port
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libgphoto2/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=http://www.gphoto.org/
+endef
+
+define Package/libgphoto2
+  $(call Package/libgphoto2/Default)
+  DEPENDS:=+libpthread +libltdl +libusb-compat +libusb-1.0 $(ICONV_DEPENDS) $(INTL_DEPENDS)
+  TITLE:=The basic library of the gphoto2 program, version $(PKG_VERSION).
+  MENU:=1
+endef
+
+define Package/libgphoto2-port
+  $(call Package/libgphoto2/Default)
+  DEPENDS:=libgphoto2 +libusb-1.0 +libusb-compat
+  TITLE:=Gphoto2 drivers for connect cameras
+endef
+
+define Package/libgphoto2-drivers-adc65
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for adc65 cameras
+endef
+
+define Package/libgphoto2-drivers-agfa_cl20
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for agfa_cl20 cameras
+endef
+
+define Package/libgphoto2-drivers-aox
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for aox cameras
+endef
+
+define Package/libgphoto2-drivers-ax203
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for ax203 cameras
+endef
+
+define Package/libgphoto2-drivers-barbie
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for barbie cameras
+endef
+
+define Package/libgphoto2-drivers-canon
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for canon cameras
+endef
+
+define Package/libgphoto2-drivers-casio_qv
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for casio_qv cameras
+endef
+
+define Package/libgphoto2-drivers-clicksmart310
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for clicksmart310 cameras
+endef
+
+define Package/libgphoto2-drivers-digigr8
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for digigr8 cameras
+endef
+
+define Package/libgphoto2-drivers-digita
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for digita cameras
+endef
+
+define Package/libgphoto2-drivers-dimera3500
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for dimera3500 cameras
+endef
+
+define Package/libgphoto2-drivers-directory
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for directory cameras
+endef
+
+define Package/libgphoto2-drivers-enigma13
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for enigma13 cameras
+endef
+
+define Package/libgphoto2-drivers-fuji
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for fuji cameras
+endef
+
+define Package/libgphoto2-drivers-gsmart300
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for gsmart300 cameras
+endef
+
+define Package/libgphoto2-drivers-hp215
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for hp215 cameras
+endef
+
+define Package/libgphoto2-drivers-iclick
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for iclick cameras
+endef
+
+define Package/libgphoto2-drivers-jamcam
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for jamcam cameras
+endef
+
+define Package/libgphoto2-drivers-jd11
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for jd11 cameras
+endef
+
+define Package/libgphoto2-drivers-jl2005a
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for jl2005a cameras
+endef
+
+define Package/libgphoto2-drivers-jl2005c
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for jl2005c cameras
+endef
+
+define Package/libgphoto2-drivers-kodak_dc120
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for kodak_dc120 cameras
+endef
+
+define Package/libgphoto2-drivers-kodak_dc210
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for kodak_dc210 cameras
+endef
+
+define Package/libgphoto2-drivers-kodak_dc240
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for kodak_dc240 cameras
+endef
+
+define Package/libgphoto2-drivers-kodak_dc3200
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for kodak_dc3200 cameras
+endef
+
+define Package/libgphoto2-drivers-kodak_ez200
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for kodak_ez200 cameras
+endef
+
+define Package/libgphoto2-drivers-konica
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for konica cameras
+endef
+
+define Package/libgphoto2-drivers-konica_qm150
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for konica_qm150 cameras
+endef
+
+define Package/libgphoto2-drivers-largan
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for largan cameras
+endef
+
+define Package/libgphoto2-drivers-lg_gsm
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for lg_gsm cameras
+endef
+
+define Package/libgphoto2-drivers-mars
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for mars cameras
+endef
+
+define Package/libgphoto2-drivers-dimagev
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for dimagev cameras
+endef
+
+define Package/libgphoto2-drivers-mustek
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for mustek cameras
+endef
+
+define Package/libgphoto2-drivers-panasonic_coolshot
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for panasonic_coolshot cameras
+endef
+
+define Package/libgphoto2-drivers-panasonic_l859
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for panasonic_l859 cameras
+endef
+
+define Package/libgphoto2-drivers-panasonic_dc1000
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for panasonic_dc1000 cameras
+endef
+
+define Package/libgphoto2-drivers-panasonic_dc1580
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for panasonic_dc1580 cameras
+endef
+
+define Package/libgphoto2-drivers-pccam300
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for pccam300 cameras
+endef
+
+define Package/libgphoto2-drivers-pccam600
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for pccam600 cameras
+endef
+
+define Package/libgphoto2-drivers-pentax
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for pentax cameras
+endef
+
+define Package/libgphoto2-drivers-polaroid_pdc320
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for polaroid_pdc320 cameras
+endef
+
+define Package/libgphoto2-drivers-polaroid_pdc640
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for polaroid_pdc640 cameras
+endef
+
+define Package/libgphoto2-drivers-polaroid_pdc700
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for polaroid_pdc700 cameras
+endef
+
+define Package/libgphoto2-drivers-ptp2
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for ptp2 cameras
+endef
+
+define Package/libgphoto2-drivers-ricoh
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for ricoh cameras
+endef
+
+define Package/libgphoto2-drivers-ricoh_g3
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for ricoh_g3 cameras
+endef
+
+define Package/libgphoto2-drivers-samsung
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for samsung cameras
+endef
+
+define Package/libgphoto2-drivers-sierra
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for sierra cameras
+endef
+
+define Package/libgphoto2-drivers-sipix_blink2
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for sipix_blink2 cameras
+endef
+
+define Package/libgphoto2-drivers-sipix_web2
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for sipix_web2 cameras
+endef
+
+define Package/libgphoto2-drivers-smal
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for smal cameras
+endef
+
+define Package/libgphoto2-drivers-sonix
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for sonix cameras
+endef
+
+define Package/libgphoto2-drivers-sony_dscf1
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for sony_dscf1 cameras
+endef
+
+define Package/libgphoto2-drivers-sony_dscf55
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for sony_dscf55 cameras
+endef
+
+define Package/libgphoto2-drivers-soundvision
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for soundvision cameras
+endef
+
+define Package/libgphoto2-drivers-spca50x
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for spca50x cameras
+endef
+
+define Package/libgphoto2-drivers-sq905
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for sq905 cameras
+endef
+
+define Package/libgphoto2-drivers-st2205
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for st2205 cameras
+endef
+
+define Package/libgphoto2-drivers-stv0674
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for stv0674 cameras
+endef
+
+define Package/libgphoto2-drivers-stv0680
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for stv0680 cameras
+endef
+
+define Package/libgphoto2-drivers-sx330z
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for sx330z cameras
+endef
+
+define Package/libgphoto2-drivers-topfield
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for topfield cameras
+endef
+
+define Package/libgphoto2-drivers-toshiba_pdrm11
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for toshiba_pdrm11 cameras
+endef
+
+define Package/libgphoto2-drivers-tp6801
+	$(call Package/libgphoto2/Default)
+	DEPENDS:=+libgphoto2-port
+	TITLE:=Gphoto2 drivers for tp6801 cameras
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--disable-rpath \
+	--with-camlibs="standard,outdated" \
+	--with-gdlib=no \
+	--with-libexif=no \
+	--with-libusb=no \
+	--with-libusb-1.0=auto \
+	--with-libxml-2.0=no \
+	--without-included-ltdl \
+	--without-jpeg \
+	--without-libiconv-prefix \
+	--without-libintl-prefix \
+	--with-pic
+
+TARGET_LDFLAGS += $(if $(INTL_FULL),-lintl) -lltdl
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/gphoto2{,-port}-config $(1)/usr/bin/
+	$(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(1)/usr/bin/gphoto2{,-port}-config
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/gphoto2 $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2{,_port}.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libgphoto2{,_port}.pc $(1)/usr/lib/pkgconfig/
+	# remove annoying recursive symlink
+	rm -f $(1)/usr/include/gphoto2/gphoto2
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/gphoto2-config $(2)/bin/gphoto2-config
+	$(LN) ../../usr/bin/gphoto2-port-config $(2)/bin/gphoto2-port-config
+endef
+
+define Package/libgphoto2/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2{,_port}.so.* $(1)/usr/lib/
+	$(LN) libgphoto2_port.so.12 $(1)/usr/lib/libgphoto2_port.so.10
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/print-camera-list $(1)/usr/lib/libgphoto2/print-camera-list
+endef
+
+define Package/libgphoto2-port/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2_port/$(PORT_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2_port/$(PORT_VERSION)/*.so $(1)/usr/lib/libgphoto2_port/$(PORT_VERSION)
+endef
+
+define Package/libgphoto2-drivers-adc65/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/adc65.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-agfa_cl20/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/agfa_cl20.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-aox/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/aox.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-ax203/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/ax203.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-barbie/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/barbie.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-canon/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/canon.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-casio_qv/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/casio_qv.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-clicksmart310/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/clicksmart310.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-digigr8/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/digigr8.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-digita/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/digita.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-dimera3500/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/dimera3500.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-directory/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/directory.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-enigma13/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/enigma13.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-fuji/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/fuji.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-gsmart300/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/gsmart300.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-hp215/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/hp215.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-iclick/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/iclick.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-jamcam/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/jamcam.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-jd11/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/jd11.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-jl2005a/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/jl2005a.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-jl2005c/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/jl2005c.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-kodak_dc120/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/kodak_dc120.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-kodak_dc210/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/kodak_dc210.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-kodak_dc240/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/kodak_dc240.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-kodak_dc3200/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/kodak_dc3200.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-kodak_ez200/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/kodak_ez200.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-konica/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/konica.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-konica_qm150/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/konica_qm150.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-largan/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/largan.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-lg_gsm/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/lg_gsm.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-mars/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/mars.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-dimagev/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/dimagev.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-mustek/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/mustek.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-panasonic_coolshot/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/panasonic_coolshot.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-panasonic_l859/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/panasonic_l859.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-panasonic_dc1000/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/panasonic_dc1000.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-panasonic_dc1580/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/panasonic_dc1580.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-pccam300/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/pccam300.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-pccam600/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/pccam600.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-pentax/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/pentax.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-polaroid_pdc320/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/polaroid_pdc320.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-polaroid_pdc640/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/polaroid_pdc640.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-polaroid_pdc700/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/polaroid_pdc700.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-ptp2/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/ptp2.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-ricoh/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/ricoh.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-ricoh_g3/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/ricoh_g3.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-samsung/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/samsung.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-sierra/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/sierra.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-sipix_blink2/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/sipix_blink2.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-sipix_web2/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/sipix_web2.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-smal/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/smal.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-sonix/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/sonix.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-sony_dscf1/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/sony_dscf1.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-sony_dscf55/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/sony_dscf55.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-soundvision/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/soundvision.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-spca50x/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/spca50x.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-sq905/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/sq905.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-st2205/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/st2205.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-stv0674/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/stv0674.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-stv0680/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/stv0680.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-sx330z/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/sx330z.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-topfield/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/topfield.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-toshiba_pdrm11/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/toshiba_pdrm11.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+define Package/libgphoto2-drivers-tp6801/install
+	$(INSTALL_DIR) $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgphoto2/$(PKG_VERSION)/tp6801.so $(1)/usr/lib/libgphoto2/$(PKG_VERSION)
+endef
+
+$(eval $(call BuildPackage,libgphoto2))
+$(eval $(call BuildPackage,libgphoto2-port))
+$(eval $(call BuildPackage,libgphoto2-drivers-adc65))
+$(eval $(call BuildPackage,libgphoto2-drivers-agfa_cl20))
+$(eval $(call BuildPackage,libgphoto2-drivers-aox))
+$(eval $(call BuildPackage,libgphoto2-drivers-ax203))
+$(eval $(call BuildPackage,libgphoto2-drivers-barbie))
+$(eval $(call BuildPackage,libgphoto2-drivers-canon))
+$(eval $(call BuildPackage,libgphoto2-drivers-casio_qv))
+$(eval $(call BuildPackage,libgphoto2-drivers-clicksmart310))
+$(eval $(call BuildPackage,libgphoto2-drivers-digigr8))
+$(eval $(call BuildPackage,libgphoto2-drivers-digita))
+$(eval $(call BuildPackage,libgphoto2-drivers-dimera3500))
+$(eval $(call BuildPackage,libgphoto2-drivers-directory))
+$(eval $(call BuildPackage,libgphoto2-drivers-enigma13))
+$(eval $(call BuildPackage,libgphoto2-drivers-fuji))
+$(eval $(call BuildPackage,libgphoto2-drivers-gsmart300))
+$(eval $(call BuildPackage,libgphoto2-drivers-hp215))
+$(eval $(call BuildPackage,libgphoto2-drivers-iclick))
+$(eval $(call BuildPackage,libgphoto2-drivers-jamcam))
+$(eval $(call BuildPackage,libgphoto2-drivers-jd11))
+$(eval $(call BuildPackage,libgphoto2-drivers-jl2005a))
+$(eval $(call BuildPackage,libgphoto2-drivers-jl2005c))
+$(eval $(call BuildPackage,libgphoto2-drivers-kodak_dc120))
+$(eval $(call BuildPackage,libgphoto2-drivers-kodak_dc210))
+$(eval $(call BuildPackage,libgphoto2-drivers-kodak_dc240))
+$(eval $(call BuildPackage,libgphoto2-drivers-kodak_dc3200))
+$(eval $(call BuildPackage,libgphoto2-drivers-kodak_ez200))
+$(eval $(call BuildPackage,libgphoto2-drivers-konica))
+$(eval $(call BuildPackage,libgphoto2-drivers-konica_qm150))
+$(eval $(call BuildPackage,libgphoto2-drivers-largan))
+$(eval $(call BuildPackage,libgphoto2-drivers-lg_gsm))
+$(eval $(call BuildPackage,libgphoto2-drivers-mars))
+$(eval $(call BuildPackage,libgphoto2-drivers-dimagev))
+$(eval $(call BuildPackage,libgphoto2-drivers-mustek))
+$(eval $(call BuildPackage,libgphoto2-drivers-panasonic_coolshot))
+$(eval $(call BuildPackage,libgphoto2-drivers-panasonic_l859))
+$(eval $(call BuildPackage,libgphoto2-drivers-panasonic_dc1000))
+$(eval $(call BuildPackage,libgphoto2-drivers-panasonic_dc1580))
+$(eval $(call BuildPackage,libgphoto2-drivers-pccam300))
+$(eval $(call BuildPackage,libgphoto2-drivers-pccam600))
+$(eval $(call BuildPackage,libgphoto2-drivers-pentax))
+$(eval $(call BuildPackage,libgphoto2-drivers-polaroid_pdc320))
+$(eval $(call BuildPackage,libgphoto2-drivers-polaroid_pdc640))
+$(eval $(call BuildPackage,libgphoto2-drivers-polaroid_pdc700))
+$(eval $(call BuildPackage,libgphoto2-drivers-ptp2))
+$(eval $(call BuildPackage,libgphoto2-drivers-ricoh))
+$(eval $(call BuildPackage,libgphoto2-drivers-ricoh_g3))
+$(eval $(call BuildPackage,libgphoto2-drivers-samsung))
+$(eval $(call BuildPackage,libgphoto2-drivers-sierra))
+$(eval $(call BuildPackage,libgphoto2-drivers-sipix_blink2))
+$(eval $(call BuildPackage,libgphoto2-drivers-sipix_web2))
+$(eval $(call BuildPackage,libgphoto2-drivers-smal))
+$(eval $(call BuildPackage,libgphoto2-drivers-sonix))
+$(eval $(call BuildPackage,libgphoto2-drivers-sony_dscf1))
+$(eval $(call BuildPackage,libgphoto2-drivers-sony_dscf55))
+$(eval $(call BuildPackage,libgphoto2-drivers-soundvision))
+$(eval $(call BuildPackage,libgphoto2-drivers-spca50x))
+$(eval $(call BuildPackage,libgphoto2-drivers-sq905))
+$(eval $(call BuildPackage,libgphoto2-drivers-st2205))
+$(eval $(call BuildPackage,libgphoto2-drivers-stv0674))
+$(eval $(call BuildPackage,libgphoto2-drivers-stv0680))
+$(eval $(call BuildPackage,libgphoto2-drivers-sx330z))
+$(eval $(call BuildPackage,libgphoto2-drivers-topfield))
+$(eval $(call BuildPackage,libgphoto2-drivers-toshiba_pdrm11))
+$(eval $(call BuildPackage,libgphoto2-drivers-tp6801))
diff --git a/external/subpack/libs/libgpiod/Makefile b/external/subpack/libs/libgpiod/Makefile
new file mode 100644
index 0000000..77bee54
--- /dev/null
+++ b/external/subpack/libs/libgpiod/Makefile
@@ -0,0 +1,170 @@
+#
+# Copyright (C) 2018-2019 Michael Heimpold <mhei@heimpold.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libgpiod
+PKG_VERSION:=2.1.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@KERNEL/software/libs/libgpiod/
+PKG_HASH:=2be4c0b03e995d236c0e476e14aeb475d7b431dd1439609b6d65c540f91eaf58
+
+PKG_MAINTAINER:=Michael Heimpold <mhei@heimpold.de>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PYTHON3_PKG_BUILD:=0
+
+include $(INCLUDE_DIR)/package.mk
+include ../../lang/python/python3-package.mk
+
+ifneq ($(CONFIG_PACKAGE_libgpiodcxx),)
+CONFIGURE_ARGS += --enable-bindings-cxx
+else
+CONFIGURE_ARGS += --disable-bindings-cxx
+endif
+
+ifneq ($(CONFIG_PACKAGE_gpiod-tools),)
+CONFIGURE_ARGS += --enable-tools
+endif
+
+PYTHON3_PKG_WHEEL_NAME:=gpiod
+PYTHON3_PKG_WHEEL_VERSION:=2.0.1
+
+PYTHON3_PKG_SETUP_DIR:=bindings/python
+PYTHON3_PKG_SETUP_VARS += LINK_SYSTEM_LIBGPIOD=1
+
+TARGET_CPPFLAGS += -I$(PKG_BUILD_DIR)/include
+TARGET_LDFLAGS += -L$(PKG_BUILD_DIR)/lib/.libs
+
+define Package/libgpiod
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git
+  TITLE:=Library for interacting with Linux's GPIO character device
+  KCONFIG:= \
+    CONFIG_GPIO_CDEV=y
+  DEPENDS:=@GPIO_SUPPORT
+endef
+
+define Package/libgpiod/description
+  C library for interacting with the linux GPIO character device
+  (gpiod stands for GPIO device).
+endef
+
+define Package/gpiod-tools
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Tools for interacting with GPIO pins
+  DEPENDS:=+libgpiod
+endef
+
+define Package/gpiod-tools/description
+  Tools for interacting with the linux GPIO character device
+  (gpiod stands for GPIO device).
+endef
+
+define Package/libgpiodcxx
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git
+  TITLE:=C++ binding for libgpiod
+  DEPENDS:=+libstdcpp +libgpiod
+endef
+
+define Package/libgpiodcxx/description
+  This package contains the C++ binding for libgpiod.
+endef
+
+define Package/python3-gpiod
+  SECTION:=lang
+  CATEGORY:=Languages
+  SUBMENU:=Python
+  TITLE:=Python bindings for libgpiod
+  URL:=https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git
+  DEPENDS:=+python3-light +libgpiod
+endef
+
+define Package/python3-gpiod/description
+  This package contains the Python bindings for libgpiod.
+endef
+
+define Build/Configure
+	$(call Build/Configure/Default)
+    ifneq ($(CONFIG_PACKAGE_python3-gpiod),)
+	$(call Py3Build/Configure)
+    endif
+endef
+
+define Build/Compile
+	$(call Build/Compile/Default)
+    ifneq ($(CONFIG_PACKAGE_python3-gpiod),)
+	$(call Py3Build/Compile)
+    endif
+endef
+
+define Build/Install
+	$(call Build/Install/Default)
+    ifneq ($(CONFIG_PACKAGE_python3-gpiod),)
+	$(call Py3Build/Install/Default)
+    endif
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/gpiod.h $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgpiod.{so*,a} $(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libgpiod.pc $(1)/usr/lib/pkgconfig/
+
+    ifneq ($(CONFIG_PACKAGE_libgpiodcxx),)
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/gpiodcxx $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/gpiod.hpp $(1)/usr/include/
+
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgpiodcxx.{so*,a} $(1)/usr/lib/
+
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libgpiodcxx.pc $(1)/usr/lib/pkgconfig/
+    endif
+
+    ifneq ($(CONFIG_PACKAGE_python3-gpiod),)
+	$(INSTALL_DIR) $(1)$(PYTHON3_PKG_DIR)
+	$(CP) $(PKG_INSTALL_DIR)$(PYTHON3_PKG_DIR)/* $(1)$(PYTHON3_PKG_DIR)
+    endif
+endef
+
+define Package/libgpiod/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgpiod.so.* $(1)/usr/lib/
+endef
+
+define Package/libgpiodcxx/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libgpiodcxx.so.* $(1)/usr/lib/
+endef
+
+define Package/gpiod-tools/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+define Py3Package/python3-gpiod/install
+	# this empty define prevent installing tools from /usr/bin
+endef
+
+$(eval $(call BuildPackage,libgpiod))
+$(eval $(call BuildPackage,libgpiodcxx))
+$(eval $(call BuildPackage,gpiod-tools))
+$(eval $(call Py3Package,python3-gpiod))
+$(eval $(call BuildPackage,python3-gpiod))
+$(eval $(call BuildPackage,python3-gpiod-src))
diff --git a/external/subpack/libs/libhttp-parser/Makefile b/external/subpack/libs/libhttp-parser/Makefile
new file mode 100644
index 0000000..4af400b
--- /dev/null
+++ b/external/subpack/libs/libhttp-parser/Makefile
@@ -0,0 +1,59 @@
+#
+# 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:=libhttp-parser
+PKG_VERSION:=2.9.4
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/nodejs/http-parser/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=467b9e30fd0979ee301065e70f637d525c28193449e1b13fbcb1b1fab3ad224f
+PKG_BUILD_DIR:=$(BUILD_DIR)/http-parser-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Ramanathan Sivagurunathan <ramzthecoder@gmail.com>, Hirokazu MORIKAWA <morikw2@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE-MIT
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libhttp-parser
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A library to parse http request and response
+  URL:=https://github.com/nodejs/http-parser
+endef
+
+define Package/libhttp-parser/description
+  A parser for HTTP messages written in C. It parses both requests and responses.
+  The parser is designed to be used in performance HTTP applications.
+  It does not make any syscalls nor allocations, it does not buffer data,
+  it can be interrupted at anytime. Depending on your architecture,
+  it only requires about 40 bytes of data per message stream
+  (in a web server that is per connection).
+endef
+
+MAKE_FLAGS+=library \
+	PREFIX=/usr
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/http_parser.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttp_parser.so* $(1)/usr/lib/
+endef
+
+define Package/libhttp-parser/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttp_parser.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libhttp-parser))
diff --git a/external/subpack/libs/libhttp-parser/patches/000-fix_darwin_error.patch b/external/subpack/libs/libhttp-parser/patches/000-fix_darwin_error.patch
new file mode 100644
index 0000000..55684a6
--- /dev/null
+++ b/external/subpack/libs/libhttp-parser/patches/000-fix_darwin_error.patch
@@ -0,0 +1,51 @@
+--- a/Makefile
++++ b/Makefile
+@@ -25,11 +25,7 @@ SOLIBNAME = libhttp_parser
+ SOMAJOR = 2
+ SOMINOR = 9
+ SOREV   = 4
+-ifeq (darwin,$(PLATFORM))
+-SOEXT ?= dylib
+-SONAME ?= $(SOLIBNAME).$(SOMAJOR).$(SOMINOR).$(SOEXT)
+-LIBNAME ?= $(SOLIBNAME).$(SOMAJOR).$(SOMINOR).$(SOREV).$(SOEXT)
+-else ifeq (wine,$(PLATFORM))
++ifeq (wine,$(PLATFORM))
+ CC = winegcc
+ BINEXT = .exe.so
+ HELPER = wine
+@@ -65,12 +61,8 @@ PREFIX ?= /usr/local
+ LIBDIR = $(PREFIX)/lib
+ INCLUDEDIR = $(PREFIX)/include
+ 
+-ifeq (darwin,$(PLATFORM))
+-LDFLAGS_LIB += -Wl,-install_name,$(LIBDIR)/$(SONAME)
+-else
+ # TODO(bnoordhuis) The native SunOS linker expects -h rather than -soname...
+ LDFLAGS_LIB += -Wl,-soname=$(SONAME)
+-endif
+ 
+ test: test_g test_fast
+ 	$(HELPER) ./test_g$(BINEXT)
+@@ -131,14 +123,18 @@ tags: http_parser.c http_parser.h test.c
+ 	ctags $^
+ 
+ install: library
+-	$(INSTALL) -D  http_parser.h $(DESTDIR)$(INCLUDEDIR)/http_parser.h
+-	$(INSTALL) -D $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME)
++	$(INSTALL) -d $(DESTDIR)$(INCLUDEDIR)
++	$(INSTALL) -d $(DESTDIR)$(LIBDIR)
++	$(INSTALL)    http_parser.h $(DESTDIR)$(INCLUDEDIR)/http_parser.h
++	$(INSTALL)    $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME)
+ 	ln -sf $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SONAME)
+ 	ln -sf $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SOLIBNAME).$(SOEXT)
+ 
+ install-strip: library
+-	$(INSTALL) -D  http_parser.h $(DESTDIR)$(INCLUDEDIR)/http_parser.h
+-	$(INSTALL) -D -s $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME)
++	$(INSTALL) -d $(DESTDIR)$(INCLUDEDIR)
++	$(INSTALL) -d $(DESTDIR)$(LIBDIR)
++	$(INSTALL)    http_parser.h $(DESTDIR)$(INCLUDEDIR)/http_parser.h
++	$(INSTALL) -s $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(LIBNAME)
+ 	ln -sf $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SONAME)
+ 	ln -sf $(LIBNAME) $(DESTDIR)$(LIBDIR)/$(SOLIBNAME).$(SOEXT)
+ 
diff --git a/external/subpack/libs/libical/Makefile b/external/subpack/libs/libical/Makefile
new file mode 100644
index 0000000..bbc83d9
--- /dev/null
+++ b/external/subpack/libs/libical/Makefile
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2009-2015 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:=libical
+PKG_VERSION:=3.0.9
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_HASH:=bd26d98b7fcb2eb0cd5461747bbb02024ebe38e293ca53a7dfdcb2505265a728
+PKG_SOURCE_URL:=https://github.com/libical/libical/releases/download/v$(PKG_VERSION)/
+
+PKG_MAINTAINER:=Jose Zapater <jzapater@gmail.com>
+PKG_LICENSE:=LGPL-2.1-or-later MPL-2.0
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libical_project:libical
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libical
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=An implementation of iCalendar protocols and data formats
+  URL:=http://libical.github.io/libical/
+  DEPENDS:=+libpthread
+endef
+
+define Package/libical/description
+ Libical is an Open Source implementation of the iCalendar protocols and protocol
+ data units. The iCalendar specification describes how calendar clients can
+ communicate with calendar servers so users can store their calendar data and
+ arrange meetings with other users.
+ Libical implements RFC2445, RFC2446 and some of RFC2447.
+endef
+
+CMAKE_OPTIONS += -DWITH_CXX_BINDINGS=false -DICAL_BUILD_DOCS=false -DICAL_GLIB=false
+
+define Package/libical/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libical{,ss,vcal}.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libical))
diff --git a/external/subpack/libs/libical/patches/001-disable-icu-and-bdb-support.patch b/external/subpack/libs/libical/patches/001-disable-icu-and-bdb-support.patch
new file mode 100644
index 0000000..204ed3d
--- /dev/null
+++ b/external/subpack/libs/libical/patches/001-disable-icu-and-bdb-support.patch
@@ -0,0 +1,18 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -192,7 +192,6 @@ endif()
+ # libicu is highly recommended for RSCALE support
+ #  libicu can be found at http://www.icu-project.org
+ #  RSCALE info at https://tools.ietf.org/html/rfc7529
+-find_package(ICU)
+ set_package_properties(ICU PROPERTIES
+   TYPE RECOMMENDED
+   PURPOSE "For RSCALE (RFC7529) support"
+@@ -216,7 +215,6 @@ if(ICU_I18N_FOUND)
+ endif()
+ 
+ # compile in Berkeley DB support
+-find_package(BDB)
+ set_package_properties(BDB PROPERTIES
+   TYPE OPTIONAL
+   PURPOSE "For Berkeley DB storage support"
diff --git a/external/subpack/libs/libid3tag/Makefile b/external/subpack/libs/libid3tag/Makefile
new file mode 100644
index 0000000..e7d3e07
--- /dev/null
+++ b/external/subpack/libs/libid3tag/Makefile
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2006-2014 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:=libid3tag
+PKG_VERSION:=0.16.3
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://codeberg.org/tenacityteam/libid3tag.git
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_MIRROR_HASH:=b373a3015ace3e9d5db83d0987b1dad8cd02945fd223294365396ec54901b8a5
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+
+PKG_LICENSE:=GPL-2
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:media-libs:libid3tag
+
+CMAKE_BINARY_SUBDIR:=openwrt-build
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libid3tag
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+zlib
+  TITLE:=An ID3 tag manipulation library
+  URL:=https://codeberg.org/tenacityteam/libid3tag
+endef
+
+define Package/libid3tag/description
+	libid3tag is a library for reading and (eventually) writing ID3 tags, both
+	ID3v1 and the various versions of ID3v2.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/id3tag.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libid3tag.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/id3tag.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libid3tag/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libid3tag.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libid3tag))
diff --git a/external/subpack/libs/libideviceactivation/Makefile b/external/subpack/libs/libideviceactivation/Makefile
new file mode 100644
index 0000000..b73daf5
--- /dev/null
+++ b/external/subpack/libs/libideviceactivation/Makefile
@@ -0,0 +1,96 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libideviceactivation
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/libimobiledevice/libideviceactivation.git
+PKG_SOURCE_DATE:=2024-04-16
+PKG_SOURCE_VERSION:=6925d58ef7994168fb9585aa6f48421149982329
+PKG_MIRROR_HASH:=671a4feef00d6cc1b81df1e8f305a2e7a26752848b23c8ab60432940f307fe57
+
+PKG_MAINTAINER:=Rosen Penev <rosenp@gmail.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LESSER
+PKG_CPE_ID:=cpe:/a:libimobiledevice:libideviceactivation
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libideviceactivation/Default
+  TITLE:=Manage the activation of Apple iOS devices
+  URL:=https://www.libimobiledevice.org/
+  SUBMENU:=libimobiledevice
+endef
+
+define Package/libideviceactivation/Default/description
+  A library to manage the activation process of Apple iOS devices.
+  This project provides an interface to activate and deactivate iOS devices
+  by talking to Apple's webservice alongside a command-line utility named
+  ideviceactivation.
+  - Status: Implements complete activation and deactivation process
+  - Compatibility: Supports legacy and latest activation webservice APIs
+  - Utility: Provides ideviceactivation utility for command-line usage
+  - Interactive: Requests user input if the activation process uses forms
+  - Cross-Platform: Tested on Linux, macOS, Windows and Android platforms
+endef
+
+define Package/libideviceactivation
+  $(call Package/libideviceactivation/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libcurl +libimobiledevice +usbmuxd
+  LICENSE:=LGPL-2.1-or-later
+  LICENSE_FILES:=COPYING.LESSER
+endef
+
+define Package/libideviceactivation/description
+  $(call Package/libideviceactivation/Default/description)
+endef
+
+define Package/libideviceactivation-utils
+  $(call Package/libideviceactivation/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libideviceactivation
+  LICENSE:=GPL-3.0-or-later
+  ICENSE_FILES:=COPYING
+endef
+
+define Package/libideviceactivation-utils/description
+  $(call Package/libideviceactivation/Default/description)
+  This package contains the libideviceactivation utilities.
+endef
+
+CONFIGURE_ARGS += \
+	PACKAGE_VERSION=$(PKG_VERSION)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libideviceactivation.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libideviceactivation-1.0.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libideviceactivation-1.0.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libideviceactivation/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libideviceactivation-1.0.so.* $(1)/usr/lib/
+endef
+
+define Package/libideviceactivation-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ideviceactivation $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libideviceactivation))
+$(eval $(call BuildPackage,libideviceactivation-utils))
diff --git a/external/subpack/libs/libidn/Makefile b/external/subpack/libs/libidn/Makefile
new file mode 100644
index 0000000..a8135a0
--- /dev/null
+++ b/external/subpack/libs/libidn/Makefile
@@ -0,0 +1,94 @@
+#
+# Copyright (C) 2009-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:=libidn
+PKG_VERSION:=1.42
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/libidn
+PKG_HASH:=d6c199dcd806e4fe279360cb4b08349a0d39560ed548ffd1ccadda8cdecb4723
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=GPL-2.0-or-later GPL-3.0-or-later LGPL-2.1-or-later LGPL-3.0-or-later Apache-2.0
+PKG_LICENSE_FILES:=COPYING COPYINGv2 COPYINGv3 COPYING.LESSERv2 COPYING.LESSERv3 java/LICENSE-2.0.txt
+PKG_CPE_ID:=cpe:/a:gnu:libidn
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/idn/Default
+  SECTION:=net
+  CATEGORY:=Network
+  URL:=http://www.gnu.org/software/libidn/
+endef
+
+define Package/idn/Default/description
+  GNU Libidn is a fully documented implementation of the Stringprep,
+  Punycode and IDNA specifications. Libidn's purpose is to encode and
+  decode internationalized domain names.
+endef
+
+define Package/idn
+  $(call Package/idn/Default)
+  SUBMENU:=IP Addresses and Names
+  TITLE:=GNU IDN (Internationalized Domain Name) tool
+  DEPENDS:=+libidn
+endef
+
+define Package/idn/description
+$(call Package/idn/Default/description)
+
+  Command line tool using libidn
+
+endef
+
+define Package/libidn
+  $(call Package/idn/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Stringprep, Punycode and IDNA implementation
+endef
+
+define Package/libidn/description
+$(call Package/idn/Default/description)
+
+  Library only package
+
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+        --disable-rpath \
+        --disable-doc
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libidn.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libidn.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/idn/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+define Package/libidn/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libidn.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,idn))
+$(eval $(call BuildPackage,libidn))
diff --git a/external/subpack/libs/libidn/patches/010-fix-idn-error-usage.patch b/external/subpack/libs/libidn/patches/010-fix-idn-error-usage.patch
new file mode 100644
index 0000000..4f42242
--- /dev/null
+++ b/external/subpack/libs/libidn/patches/010-fix-idn-error-usage.patch
@@ -0,0 +1,119 @@
+--- a/src/idn.c
++++ b/src/idn.c
+@@ -169,7 +169,7 @@ main (int argc, char *argv[])
+       (args_info.idna_to_unicode_given ? 1 : 0) +
+       (args_info.nfkc_given ? 1 : 0) != 1)
+     {
+-      error (0, 0,
++      error (0, 0, "%s",
+ 	     _("only one of -s, -e, -d, -a, -u or -n can be specified"));
+       usage (EXIT_FAILURE);
+     }
+@@ -183,7 +183,7 @@ main (int argc, char *argv[])
+ 
+   if (!args_info.quiet_given
+       && args_info.inputs_num == 0 && isatty (fileno (stdin)))
+-    fprintf (stderr, _("Type each input string on a line by itself, "
++    fprintf (stderr, "%s", _("Type each input string on a line by itself, "
+ 		       "terminated by a newline character.\n"));
+ 
+   do
+@@ -199,7 +199,7 @@ main (int argc, char *argv[])
+ 	  if (feof (stdin))
+ 	    break;
+ 
+-	  error (EXIT_FAILURE, errno, _("input error"));
++	  error (EXIT_FAILURE, errno, "%s", _("input error"));
+ 	}
+ 
+       if (strlen (line) > 0)
+@@ -217,7 +217,7 @@ main (int argc, char *argv[])
+ 	  if (!q)
+ 	    {
+ 	      free (p);
+-	      error (EXIT_FAILURE, 0,
++	      error (EXIT_FAILURE, 0, "%s",
+ 		     _("could not convert from UTF-8 to UCS-4"));
+ 	    }
+ 
+@@ -242,7 +242,7 @@ main (int argc, char *argv[])
+ 	  if (!q)
+ 	    {
+ 	      free (r);
+-	      error (EXIT_FAILURE, 0,
++	      error (EXIT_FAILURE, 0, "%s",
+ 		     _("could not convert from UTF-8 to UCS-4"));
+ 	    }
+ 
+@@ -279,7 +279,7 @@ main (int argc, char *argv[])
+ 	  q = stringprep_utf8_to_ucs4 (p, -1, &len);
+ 	  free (p);
+ 	  if (!q)
+-	    error (EXIT_FAILURE, 0,
++	    error (EXIT_FAILURE, 0, "%s",
+ 		   _("could not convert from UTF-8 to UCS-4"));
+ 
+ 	  if (args_info.debug_given)
+@@ -338,7 +338,7 @@ main (int argc, char *argv[])
+ 	  r = stringprep_ucs4_to_utf8 (q, -1, NULL, NULL);
+ 	  free (q);
+ 	  if (!r)
+-	    error (EXIT_FAILURE, 0,
++	    error (EXIT_FAILURE, 0, "%s",
+ 		   _("could not convert from UCS-4 to UTF-8"));
+ 
+ 	  p = stringprep_utf8_to_locale (r);
+@@ -362,7 +362,7 @@ main (int argc, char *argv[])
+ 	  q = stringprep_utf8_to_ucs4 (p, -1, NULL);
+ 	  free (p);
+ 	  if (!q)
+-	    error (EXIT_FAILURE, 0,
++	    error (EXIT_FAILURE, 0, "%s",
+ 		   _("could not convert from UCS-4 to UTF-8"));
+ 
+ 	  if (args_info.debug_given)
+@@ -440,7 +440,7 @@ main (int argc, char *argv[])
+ 	  if (!q)
+ 	    {
+ 	      free (p);
+-	      error (EXIT_FAILURE, 0,
++	      error (EXIT_FAILURE, 0, "%s",
+ 		     _("could not convert from UCS-4 to UTF-8"));
+ 	    }
+ 
+@@ -496,7 +496,7 @@ main (int argc, char *argv[])
+ 	  r = stringprep_ucs4_to_utf8 (q, -1, NULL, NULL);
+ 	  free (q);
+ 	  if (!r)
+-	    error (EXIT_FAILURE, 0,
++	    error (EXIT_FAILURE, 0, "%s",
+ 		   _("could not convert from UTF-8 to UCS-4"));
+ 
+ 	  p = stringprep_utf8_to_locale (r);
+@@ -525,7 +525,7 @@ main (int argc, char *argv[])
+ 	      if (!q)
+ 		{
+ 		  free (p);
+-		  error (EXIT_FAILURE, 0,
++		  error (EXIT_FAILURE, 0, "%s",
+ 			 _("could not convert from UTF-8 to UCS-4"));
+ 		}
+ 
+@@ -539,7 +539,7 @@ main (int argc, char *argv[])
+ 	  r = stringprep_utf8_nfkc_normalize (p, -1);
+ 	  free (p);
+ 	  if (!r)
+-	    error (EXIT_FAILURE, 0, _("could not do NFKC normalization"));
++	    error (EXIT_FAILURE, 0, "%s", _("could not do NFKC normalization"));
+ 
+ 	  if (args_info.debug_given)
+ 	    {
+@@ -549,7 +549,7 @@ main (int argc, char *argv[])
+ 	      if (!q)
+ 		{
+ 		  free (r);
+-		  error (EXIT_FAILURE, 0,
++		  error (EXIT_FAILURE, 0, "%s",
+ 			 _("could not convert from UTF-8 to UCS-4"));
+ 		}
+ 
diff --git a/external/subpack/libs/libidn2/Makefile b/external/subpack/libs/libidn2/Makefile
new file mode 100644
index 0000000..d8919c0
--- /dev/null
+++ b/external/subpack/libs/libidn2/Makefile
@@ -0,0 +1,98 @@
+#
+# Copyright (C) 2017-2018 Daniel Engberg <daniel.engberg.lists@pyret.net>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libidn2
+PKG_VERSION:=2.3.7
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=@GNU/libidn
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_HASH:=4c21a791b610b9519b9d0e12b8097bf2f359b12f8dd92647611a929e6bfd7d64
+
+PKG_MAINTAINER:=
+PKG_CPE_ID:=cpe:/a:gnu:libidn2
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/idn2/Default
+  SECTION:=net
+  CATEGORY:=Network
+  URL:=http://www.gnu.org/software/libidn/
+endef
+
+define Package/idn2/Default/description
+  Libidn2 is a free software implementation of IDNA2008,
+  Punycode and TR46 in library form. It contains
+  functionality to convert internationalized domain
+  names to and from ASCII Compatible Encoding (ACE),
+  following the IDNA2008 and TR46 standards.
+endef
+
+define Package/idn2
+  $(call Package/idn2/Default)
+  SUBMENU:=IP Addresses and Names
+  TITLE:=GNU IDN2 (Internationalized Domain Name) tool
+  DEPENDS:=+libidn2
+  LICENSE:=GPL-2.0-or-later
+  LICENSE_FILES:=COPYINGv2
+endef
+
+define Package/idn2/description
+$(call Package/idn2/Default/description)
+
+  Command line tool using libidn2
+
+endef
+
+define Package/libidn2
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libunistring $(ICONV_DEPENDS) $(INTL_DEPENDS)
+  TITLE:=International domain name library (IDNA2008, Punycode and TR46)
+  URL:=https://www.gnu.org/software/libidn/#libidn2
+  LICENSE:=LGPL-3.0-or-later
+  LICENSE_FILES:=COPYING.LESSERv3
+endef
+
+define Package/libidn2/description
+$(call Package/idn2/Default/description)
+
+  Library only package
+
+endef
+
+CONFIGURE_ARGS += \
+	--disable-rpath \
+	--disable-doc
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/idn2.h $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.{la,so}* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libidn2.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/idn2/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+define Package/libidn2/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,idn2))
+$(eval $(call BuildPackage,libidn2))
diff --git a/external/subpack/libs/libiio/Makefile b/external/subpack/libs/libiio/Makefile
new file mode 100644
index 0000000..ba78a68
--- /dev/null
+++ b/external/subpack/libs/libiio/Makefile
@@ -0,0 +1,154 @@
+#
+# Copyright (C) 2017-2018 Michael Heimpold <mhei@heimpold.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libiio
+PKG_VERSION:=0.25
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/analogdevicesinc/libiio/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=21972599a3c143ab1f98002ad2b3f28f4aff927fde5f677478311cd4e517730c
+
+PKG_LICENSE:=LGPL-2.1
+PKG_LICENSE_FILES:=COPYING.txt
+
+PKG_MAINTAINER:=Michael Heimpold <mhei@heimpold.de>
+
+CMAKE_INSTALL:=1
+
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_IPV6 \
+	CONFIG_LIBIIO_LOCAL_BACKEND \
+	CONFIG_LIBIIO_NETWORK_BACKEND \
+	CONFIG_LIBIIO_USB_BACKEND \
+	CONFIG_LIBIIO_XML_BACKEND
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_OPTIONS += -DWITH_DOC=OFF
+CMAKE_OPTIONS += -DENABLE_IPV6=$(if $(CONFIG_IPV6),ON,OFF)
+CMAKE_OPTIONS += -DWITH_AIO=OFF
+CMAKE_OPTIONS += -DWITH_LOCAL_BACKEND=$(if $(CONFIG_LIBIIO_LOCAL_BACKEND),ON,OFF)
+CMAKE_OPTIONS += -DWITH_LOCAL_CONFIG=OFF
+CMAKE_OPTIONS += -DWITH_NETWORK_BACKEND=$(if $(CONFIG_LIBIIO_NETWORK_BACKEND),ON,OFF)
+# serial backend requires libserial which is not packaged yet
+CMAKE_OPTIONS += -DWITH_SERIAL_BACKEND=OFF
+CMAKE_OPTIONS += -DWITH_USB_BACKEND=$(if $(CONFIG_LIBIIO_USB_BACKEND),ON,OFF)
+CMAKE_OPTIONS += -DWITH_XML_BACKEND=$(if $(CONFIG_LIBIIO_XML_BACKEND),ON,OFF)
+
+define Package/libiio
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Library for interfacing with Linux IIO devices
+  URL:=https://github.com/analogdevicesinc/libiio
+  DEPENDS:=\
+           +zlib \
+           +LIBIIO_USB_BACKEND:libusb-1.0 \
+           +LIBIIO_NETWORK_BACKEND:libavahi-client \
+           +LIBIIO_XML_BACKEND:libxml2 \
+           $(ICONV_DEPENDS)
+  MENU:=1
+endef
+
+define Package/libiio/config
+config LIBIIO_LOCAL_BACKEND
+	bool "Enable local backend"
+	depends on PACKAGE_libiio
+	default y
+
+config LIBIIO_NETWORK_BACKEND
+	bool "Enable network backend"
+	depends on PACKAGE_libiio
+	select LIBIIO_XML_BACKEND
+	default y
+
+config LIBIIO_USB_BACKEND
+	bool "Enable USB backend"
+	depends on PACKAGE_libiio
+	select LIBIIO_XML_BACKEND
+	default n
+
+config LIBIIO_XML_BACKEND
+	bool
+	depends on PACKAGE_libiio
+	default y
+endef
+
+define Package/libiio/description
+  libiio is used to interface to the Linux Industrial Input/Output (IIO) Subsystem.
+  The Linux IIO subsystem is intended to provide support for devices that in some
+  sense are analog to digital or digital to analog converters (ADCs, DACs). This
+  includes, but is not limited to ADCs, Accelerometers, Gyros, IMUs, Capacitance
+  to Digital Converters (CDCs), Pressure Sensors, Color, Light and Proximity Sensors,
+  Temperature Sensors, Magnetometers, DACs, DDS (Direct Digital Synthesis),
+  PLLs (Phase Locked Loops), Variable/Programmable Gain Amplifiers (VGA, PGA),
+  and RF transceivers. You can use libiio natively on an embedded Linux
+  target (local mode), or use libiio to communicate remotely to that same target
+  from a host Linux, Windows or MAC over USB or Ethernet or Serial.
+endef
+
+define Package/iiod
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=Linux IIO daemon
+  URL:=https://github.com/analogdevicesinc/libiio
+  DEPENDS:=+libiio
+endef
+
+define Package/iiod/description
+  Daemon to access IIO devices via network.
+endef
+
+define Package/iio-utils
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Linux IIO tools
+  URL:=https://github.com/analogdevicesinc/libiio
+  DEPENDS:=+libiio
+endef
+
+define Package/iio-utils/description
+  Command line tools for IIO devices.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/iio.h $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libiio.so* $(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libiio.pc $(1)/usr/lib/pkgconfig/
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libiio.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libiio.pc
+endef
+
+define Package/libiio/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libiio.so.* $(1)/usr/lib/
+endef
+
+define Package/iiod/install
+	$(INSTALL_DIR) $(1)/etc/init.d
+	$(INSTALL_BIN) ./files/iiod.init $(1)/etc/init.d/iiod
+	$(INSTALL_DIR) $(1)/usr/sbin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/iiod $(1)/usr/sbin/
+endef
+
+define Package/iio-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libiio))
+$(eval $(call BuildPackage,iiod))
+$(eval $(call BuildPackage,iio-utils))
diff --git a/external/subpack/libs/libiio/files/iiod.init b/external/subpack/libs/libiio/files/iiod.init
new file mode 100644
index 0000000..1ac62f3
--- /dev/null
+++ b/external/subpack/libs/libiio/files/iiod.init
@@ -0,0 +1,12 @@
+#!/bin/sh /etc/rc.common
+
+START=90
+USE_PROCD=1
+PROG=/usr/sbin/iiod
+
+start_service() {
+	procd_open_instance
+	procd_set_param command $PROG
+	procd_set_param respawn
+	procd_close_instance
+}
diff --git a/external/subpack/libs/libiio/patches/0001-xml-Fix-compatibility-with-libxml-2.12.patch b/external/subpack/libs/libiio/patches/0001-xml-Fix-compatibility-with-libxml-2.12.patch
new file mode 100644
index 0000000..1f3c7f9
--- /dev/null
+++ b/external/subpack/libs/libiio/patches/0001-xml-Fix-compatibility-with-libxml-2.12.patch
@@ -0,0 +1,27 @@
+From bb688d04294dda45e68dfaf13e3bc1187841e52a Mon Sep 17 00:00:00 2001
+From: Jan Tojnar <jtojnar@gmail.com>
+Date: Sun, 10 Dec 2023 21:52:05 +0100
+Subject: [PATCH] xml: Fix compatibility with libxml 2.12
+
+libxml 2.12.0 reorganized includes, resulting in the following no longer being in scope:
+
+- XML_PARSE_DTDVALID
+- xmlReadMemory
+- xmlReadFile
+- xmlCleanupParser
+
+Signed-off-by: Jan Tojnar <jtojnar@gmail.com>
+---
+ xml.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/xml.c
++++ b/xml.c
+@@ -10,6 +10,7 @@
+ #include "iio-private.h"
+ 
+ #include <errno.h>
++#include <libxml/parser.h>
+ #include <libxml/tree.h>
+ #include <string.h>
+ 
diff --git a/external/subpack/libs/libimobiledevice-glue/Makefile b/external/subpack/libs/libimobiledevice-glue/Makefile
new file mode 100644
index 0000000..39066f1
--- /dev/null
+++ b/external/subpack/libs/libimobiledevice-glue/Makefile
@@ -0,0 +1,67 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libimobiledevice-glue
+PKG_VERSION:=1.2.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://github.com/libimobiledevice/libimobiledevice-glue/releases/download/$(PKG_VERSION)
+PKG_HASH:=ff9cbc240c9780edfa43914a057b86362054053721b65fb04f54a25023b92b62
+
+PKG_MAINTAINER:=Rosen Penev <rosenp@gmail.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libimobiledevice-glue/Default
+  TITLE:=Common code used by libimobiledevice.
+  URL:=https://www.libimobiledevice.org/
+  SUBMENU:=libimobiledevice
+endef
+
+define Package/libimobiledevice-glue/Default/description
+  libimobiledevice-glue is a library with common code used by the
+  libraries and tools around the libimobiledevice project.
+endef
+
+define Package/libimobiledevice-glue
+  $(call Package/libimobiledevice-glue/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libplist
+  LICENSE:=LGPL-2.1-or-later
+  LICENSE_FILES:=COPYING
+endef
+
+define Package/libimobiledevice-glue/description
+  $(call Package/libimobiledevice-glue/Default/description)
+endef
+
+CONFIGURE_ARGS += \
+	--disable-static \
+	--without-cython
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libimobiledevice-glue $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libimobiledevice-glue-1.0.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libimobiledevice-glue-1.0.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libimobiledevice-glue/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libimobiledevice-glue-1.0.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libimobiledevice-glue))
diff --git a/external/subpack/libs/libimobiledevice/Makefile b/external/subpack/libs/libimobiledevice/Makefile
new file mode 100644
index 0000000..f8a1afd
--- /dev/null
+++ b/external/subpack/libs/libimobiledevice/Makefile
@@ -0,0 +1,92 @@
+#
+# Copyright (C) 2012-2014 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:=libimobiledevice
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/libimobiledevice/libimobiledevice.git
+PKG_SOURCE_DATE:=2024-05-20
+PKG_SOURCE_VERSION:=9ccc52222c287b35e41625cc282fb882544676c6
+PKG_MIRROR_HASH:=9d272d40515c5ba6be5fa22eb897724d8940a505163918120c005bbeed352475
+
+PKG_MAINTAINER:=Rosen Penev <rosenp@gmail.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LESSER
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libimobiledevice/Default
+  TITLE:=A library that talks to Apple devices.
+  URL:=https://www.libimobiledevice.org/
+  SUBMENU:=libimobiledevice
+endef
+
+define Package/libimobiledevice/Default/description
+  libimobiledevice is a software library that talks the protocols to support
+  iPhone®, iPod Touch®, iPad® and Apple TV® devices.
+endef
+
+define Package/libimobiledevice
+  $(call Package/libimobiledevice/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libplist +libimobiledevice-glue +libusbmuxd +libopenssl
+  LICENSE:=LGPL-2.1-or-later
+  LICENSE_FILES:=COPYING.LESSER
+endef
+
+define Package/libimobiledevice/description
+  $(call Package/libimobiledevice/Default/description)
+endef
+
+define Package/libimobiledevice-utils
+  $(call Package/libimobiledevice/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libimobiledevice
+  LICENSE:=GPL-2.0-or-later
+  ICENSE_FILES:=COPYING
+endef
+
+define Package/libimobiledevice-utils/description
+  $(call Package/libimobiledevice/Default/description)
+  This package contains the libimobiledevice utilities.
+endef
+
+CONFIGURE_ARGS += \
+	--disable-static \
+	--without-cython \
+	PACKAGE_VERSION=$(PKG_VERSION)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libimobiledevice $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libimobiledevice-1.0.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libimobiledevice-1.0.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libimobiledevice/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libimobiledevice-1.0.so.* $(1)/usr/lib/
+endef
+
+define Package/libimobiledevice-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/idevice* $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libimobiledevice))
+$(eval $(call BuildPackage,libimobiledevice-utils))
diff --git a/external/subpack/libs/libimobiledevice/patches/010-gcc14.patch b/external/subpack/libs/libimobiledevice/patches/010-gcc14.patch
new file mode 100644
index 0000000..0913865
--- /dev/null
+++ b/external/subpack/libs/libimobiledevice/patches/010-gcc14.patch
@@ -0,0 +1,10 @@
+--- a/tools/afcclient.c
++++ b/tools/afcclient.c
+@@ -37,6 +37,7 @@
+ #include <ctype.h>
+ #include <unistd.h>
+ #include <dirent.h>
++#include <time.h>
+ 
+ #ifdef WIN32
+ #include <windows.h>
diff --git a/external/subpack/libs/libimobiledevice/patches/020-config.patch b/external/subpack/libs/libimobiledevice/patches/020-config.patch
new file mode 100644
index 0000000..2df33f6
--- /dev/null
+++ b/external/subpack/libs/libimobiledevice/patches/020-config.patch
@@ -0,0 +1,11 @@
+--- a/common/userpref.c
++++ b/common/userpref.c
+@@ -173,7 +173,7 @@ const char *userpref_get_config_dir()
+ #ifdef __APPLE__
+ 	base_config_dir = strdup("/var/db");
+ #else
+-	base_config_dir = strdup("/var/lib");
++	base_config_dir = strdup("/etc");
+ #endif
+ #endif
+ 	__config_dir = string_concat(base_config_dir, DIR_SEP_S, USERPREF_CONFIG_DIR, NULL);
diff --git a/external/subpack/libs/libinput/Makefile b/external/subpack/libs/libinput/Makefile
new file mode 100644
index 0000000..2541223
--- /dev/null
+++ b/external/subpack/libs/libinput/Makefile
@@ -0,0 +1,67 @@
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libinput
+PKG_VERSION:=1.25.0
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://gitlab.freedesktop.org/libinput/libinput.git
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_MIRROR_HASH:=e2c4a46292a17d2e037ba4eb439c135e9834041993ac641e23c71fd5ddfceb72
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:freedesktop:libinput
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libinput
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=a library to handle input devices
+  URL:=https://freedesktop.org/wiki/Software/libinput/
+  DEPENDS:=+libevdev +mtdev +libudev
+endef
+
+define Package/libinput/description
+  libinput is a library to handle input devices in Wayland compositors
+  and to provide a generic X.Org input driver. It provides device
+  detection, device handling, input device event processing and
+  abstraction so minimize the amount of custom input code compositors
+  need to provide the common set of functionality that users expect.
+endef
+
+MESON_ARGS += \
+	-Depoll-dir=no \
+	-Dlibwacom=false \
+	-Ddebug-gui=false \
+	-Dtests=false \
+	-Dzshcompletiondir=no
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libinput.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libinput.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libinput.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libinput/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/{udev,libinput.so.*} $(1)/usr/lib
+	$(INSTALL_DIR) $(1)/usr/libexec/libinput
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/libexec/libinput/* $(1)/usr/libexec/libinput
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libinput $(1)/usr/bin
+	$(INSTALL_DIR) $(1)/usr/share/libinput
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/libinput/* $(1)/usr/share/libinput
+endef
+
+$(eval $(call BuildPackage,libinput))
diff --git a/external/subpack/libs/libirecovery/Makefile b/external/subpack/libs/libirecovery/Makefile
new file mode 100644
index 0000000..cd12b79
--- /dev/null
+++ b/external/subpack/libs/libirecovery/Makefile
@@ -0,0 +1,84 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libirecovery
+PKG_VERSION:=1.2.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://github.com/libimobiledevice/libirecovery/releases/download/$(PKG_VERSION)
+PKG_HASH:=74448348f8a68b654015fe1952fdc4e0781db20dcf4e1d85ec97d6f91e95eb14
+
+PKG_MAINTAINER:=Rosen Penev <rosenp@gmail.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libirecovery/Default
+  URL:=https://github.com/libimobiledevice/libirecovery
+  SUBMENU:=libimobiledevice
+endef
+
+define Package/libirecovery/Default/description
+  libirecovery is a cross-platform library which implements communication
+  to iBoot/iBSS found on Apple's iOS devices via USB.
+endef
+
+define Package/libirecovery
+  $(call Package/libirecovery/Default)
+  TITLE:=A library that talks to Apple iBoot/iBSS
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libimobiledevice-glue +libreadline +libusb-1.0
+endef
+
+define Package/libirecovery/description
+  $(call Package/libirecovery/Default/description)
+endef
+
+define Package/irecovery
+  $(call Package/libirecovery/Default)
+  TITLE:=A utility that talks to Apple iBoot/iBSS
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libirecovery
+endef
+
+define Package/irecovery/description
+  $(call Package/libirecovery/Default/description)
+  This package contains the libirecovery utilities.
+endef
+
+CONFIGURE_ARGS += \
+	--disable-static \
+	--without-udev
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libirecovery.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libirecovery-1.0.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libirecovery-1.0.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libirecovery/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libirecovery-1.0.so.* $(1)/usr/lib/
+endef
+
+define Package/irecovery/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/irecovery $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libirecovery))
+$(eval $(call BuildPackage,irecovery))
diff --git a/external/subpack/libs/libjaylink/Makefile b/external/subpack/libs/libjaylink/Makefile
new file mode 100644
index 0000000..2ed5753
--- /dev/null
+++ b/external/subpack/libs/libjaylink/Makefile
@@ -0,0 +1,48 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libjaylink
+PKG_VERSION:=0.3.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://gitlab.zapb.de/libjaylink/libjaylink/-/archive/$(PKG_VERSION)
+PKG_HASH:=a2d98c1aa13dcf41c6c681767a43cdefc42b6f71af9362937555051007514cd9
+
+PKG_MAINTAINER:=Paul Fertser <fercerpav@gmail.com>
+PKG_LICENSE:=GPL-2.0+
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libjaylink
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libusb-1.0
+  TITLE:=Library to access SEGGER J-Link and compatible devices
+  URL:=https://gitlab.zapb.de/libjaylink/libjaylink.git
+endef
+
+define Package/libjaylink/description
+libjaylink is a shared library written in C to access SEGGER J-Link and
+compatible devices.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/libjaylink
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libjaylink/*.h $(1)/usr/include/libjaylink/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libjaylink.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libjaylink.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libjaylink/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libjaylink.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libjaylink))
diff --git a/external/subpack/libs/libjcat/Config.in b/external/subpack/libs/libjcat/Config.in
new file mode 100644
index 0000000..db1528d
--- /dev/null
+++ b/external/subpack/libs/libjcat/Config.in
@@ -0,0 +1,22 @@
+menu "Select libjcat options"
+	depends on PACKAGE_libjcat
+
+config LIBJCAT_GPG
+	bool "GPG"
+	default y
+	help
+	  Compile libjcat with GPG support
+
+config LIBJCAT_PKCS7
+	bool "PKCS #7"
+	default y
+	help
+	  Compile libjcat with PKCS #7 support
+
+config LIBJCAT_ED25519
+	bool "ed25519"
+	default n
+	help
+	  Compile libjcat with ed25519 support
+
+endmenu
diff --git a/external/subpack/libs/libjcat/Makefile b/external/subpack/libs/libjcat/Makefile
new file mode 100644
index 0000000..daece53
--- /dev/null
+++ b/external/subpack/libs/libjcat/Makefile
@@ -0,0 +1,83 @@
+#
+# Copyright (C) 2024 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See https://www.gnu.org/licenses/gpl-2.0.txt for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libjcat
+PKG_VERSION:=0.2.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/hughsie/libjcat/releases/download/$(PKG_VERSION)
+PKG_HASH:=a6232aeca3c3fab6dbb3bed06ec3832088b49a4b278a7119558d72be60ce921f
+
+PKG_MAINTAINER:=Lukas Voegl <lvoegl@tdt.de>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_DEPENDS:=glib2/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libjcat
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libjcat
+  URL:=https://github.com/hughsie/libjcat
+  DEPENDS:= \
+	+glib2 \
+	+json-glib \
+	+LIBJCAT_GPG:libgpgme \
+	+LIBJCAT_GPG:libgpg-error \
+	+LIBJCAT_PKCS7:libgnutls \
+	+LIBJCAT_ED25519:libgnutls \
+	+LIBJCAT_ED25519:libnettle
+endef
+
+define Package/libjcat/description
+  libjcat allows reading and writing gzip-compressed JSON catalog files,
+  which can be used to store GPG, PKCS-7 and SHA-256 checksums for each file.
+endef
+
+define Package/libjcat/config
+	source "$(SOURCE)/Config.in"
+endef
+
+MESON_ARGS += \
+	-Db_lto=true \
+	-Dgtkdoc=false \
+	-Dintrospection=false \
+	-Dvapi=false \
+	-Dtests=false \
+	-Dman=false \
+	-Dcli=false \
+	-Dgpg=$(if $(CONFIG_LIBJCAT_GPG),true,false) \
+	-Dpkcs7=$(if $(CONFIG_LIBJCAT_PKCS7),true,false) \
+	-Ded25519=$(if $(CONFIG_LIBJCAT_ED25519),true,false)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/libjcat-1
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libjcat-1/jcat.h $(1)/usr/include/libjcat-1/jcat.h
+
+	$(INSTALL_DIR) $(1)/usr/include/libjcat-1/libjcat
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libjcat-1/libjcat/*.h $(1)/usr/include/libjcat-1/libjcat
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libjcat.so* $(1)/usr/lib
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/jcat.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/libjcat/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libjcat.so* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libjcat))
diff --git a/external/subpack/libs/libjpeg-turbo/Makefile b/external/subpack/libs/libjpeg-turbo/Makefile
new file mode 100644
index 0000000..de0e557
--- /dev/null
+++ b/external/subpack/libs/libjpeg-turbo/Makefile
@@ -0,0 +1,90 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libjpeg-turbo
+PKG_VERSION:=3.0.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$(PKG_VERSION)
+PKG_HASH:=343e789069fc7afbcdfe44dbba7dbbf45afa98a15150e079a38e60e44578865d
+
+PKG_MAINTAINER:=Rosen Penev <rosenp@gmail.com>
+PKG_LICENSE:=BSD-3-Clause IJG zlib
+PKG_LICENSE_FILES:=LICENSE.md
+PKG_CPE_ID:=cpe:/a:libjpeg-turbo:libjpeg-turbo
+
+# Allows ASM compilation for speed
+PKG_BUILD_FLAGS:=no-mips16
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libjpeg-turbo/Default
+  TITLE:=libjpeg-turbo
+  URL:=https://www.libjpeg-turbo.org/
+endef
+
+define Package/libjpeg-turbo
+  $(call Package/libjpeg-turbo/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE+= runtime library
+  PROVIDES:=libjpeg
+endef
+
+define Package/libjpeg-turbo-utils
+  $(call Package/libjpeg-turbo/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Image Manipulation
+  DEPENDS:=+libjpeg-turbo
+  TITLE+= manipulation tools
+  PROVIDES:=jpeg-tools
+endef
+
+define Package/libjpeg-turbo/description
+	libjpeg-turbo is a speed focused fork of libjpeg.
+endef
+
+define Package/libjpeg-turbo-utils/description
+	These are the JPEG utilities that come with libjpeg-turbo.
+endef
+
+CMAKE_OPTIONS += \
+	-DWITH_SIMD=O$(if $(findstring mips,$(CONFIG_ARCH)),FF,N) \
+	-DWITH_TURBOJPEG=OFF
+
+ifneq ($(findstring arm,$(CONFIG_ARCH)),)
+ifeq ($(findstring neon,$(CONFIG_CPU_TYPE)),)
+	CMAKE_OPTIONS += -DWITH_SIMD=OFF
+endif
+endif
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libjpeg.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libjpeg.a $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc $(1)/usr/lib/pkgconfig/
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libjpeg.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libjpeg.pc
+endef
+
+define Package/libjpeg-turbo/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libjpeg.so* $(1)/usr/lib
+endef
+
+define Package/libjpeg-turbo-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/rdjpgcom $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wrjpgcom $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/cjpeg $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/djpeg $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/jpegtran $(1)/usr/bin
+endef
+
+$(eval $(call BuildPackage,libjpeg-turbo))
+$(eval $(call BuildPackage,libjpeg-turbo-utils))
diff --git a/external/subpack/libs/libjwt/Makefile b/external/subpack/libs/libjwt/Makefile
new file mode 100644
index 0000000..a3cfa8a
--- /dev/null
+++ b/external/subpack/libs/libjwt/Makefile
@@ -0,0 +1,43 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libjwt
+PKG_VERSION:=1.17.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/benmcollins/libjwt/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=568cb5c272622e6ae045708594f1eded64fbfc101112d20de51875fce7653c83
+
+PKG_LICENSE:=MPL-2.0
+PKG_LICENSE_FILES:=LICENSE
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+CMAKE_OPTIONS += \
+        -DBUILD_SHARED_LIBS=ON
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libjwt
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libjwt
+  URL:=https://github.com/benmcollins/libjwt
+  DEPENDS:=+libopenssl +jansson
+  ABI_VERSION:=0
+endef
+
+define Package/libjwt/description
+ JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
+ libjwt seems to be the most popular implementation written in C.
+endef
+
+
+define Package/libjwt/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libjwt.so $(1)/usr/lib/libjwt.so.0
+	$(LN) libjwt.so.0 $(1)/usr/lib/libjwt.so
+endef
+
+$(eval $(call BuildPackage,libjwt))
diff --git a/external/subpack/libs/libksba/Makefile b/external/subpack/libs/libksba/Makefile
new file mode 100644
index 0000000..17bd33b
--- /dev/null
+++ b/external/subpack/libs/libksba/Makefile
@@ -0,0 +1,72 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libksba
+PKG_VERSION:=1.6.4
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://gnupg.org/ftp/gcrypt/$(PKG_NAME)
+PKG_HASH:=bbb43f032b9164d86c781ffe42213a83bf4f2fee91455edfa4654521b8b03b6b
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=LGPL-3.0-or-later GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING.GPLv2 COPYING.GPLv3 COPYING.LGPLv3
+PKG_CPE_ID:=cpe:/a:gnupg:libksba
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libksba
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GnuPG X.509 library
+  URL:=https://gnupg.org/software/libksba/index.html
+  DEPENDS:=+libgpg-error
+endef
+
+define Package/libksba/description
+Libksba is a library to make the tasks of working with X.509 certificates, CMS data and related objects more easy. 
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(2)/bin $(1)/usr/bin
+	$(INSTALL_BIN) \
+		$(PKG_INSTALL_DIR)/usr/bin/ksba-config \
+		$(2)/bin/
+	$(SED) \
+		's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \
+		$(2)/bin/ksba-config
+	ln -sf $(STAGING_DIR)/host/bin/ksba-config $(1)/usr/bin/ksba-config
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/include/ksba.h \
+		$(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libksba.{la,so*} \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/share/aclocal
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/share/aclocal/ksba.m4 \
+		$(1)/usr/share/aclocal/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/ksba.pc \
+		$(1)/usr/lib/pkgconfig
+endef
+
+define Package/libksba/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libksba.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libksba))
diff --git a/external/subpack/libs/liblo/Makefile b/external/subpack/libs/liblo/Makefile
new file mode 100644
index 0000000..2b44ecf
--- /dev/null
+++ b/external/subpack/libs/liblo/Makefile
@@ -0,0 +1,69 @@
+#
+# Copyright (C) 2010-2014 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:=liblo
+PKG_VERSION:=0.31
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/liblo
+PKG_HASH:=2b4f446e1220dcd624ecd8405248b08b7601e9a0d87a0b94730c2907dbccc750
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+CMAKE_INSTALL:=1
+CMAKE_SOURCE_SUBDIR:=cmake
+PKG_CONFIG_DEPENDS:=CONFIG_PACKAGE_liblo-utils
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/liblo/Default
+  TITLE:=Lightweight Open Sound Control (OSC)
+  URL:=http://liblo.sourceforge.net/
+endef
+
+define Package/liblo
+$(call Package/liblo/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=Sound
+  TITLE+= library
+  DEPENDS:= +libpthread
+endef
+
+define Package/liblo-utils
+$(call Package/liblo/Default)
+  CATEGORY:=Sound
+  TITLE+= utilities
+  DEPENDS:= +liblo
+endef
+
+CMAKE_OPTIONS += \
+	-DWITH_TOOLS=O$(if $(CONFIG_PACKAGE_liblo-utils),N,FF) \
+	-DWITH_TESTS=OFF \
+	-DWITH_EXAMPLES=OFF \
+	-DWITH_CPP_TESTS=OFF \
+	-DWITH_STATIC=OFF \
+	-DTHREADING=ON
+
+define Package/liblo/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liblo.so.* $(1)/usr/lib/
+endef
+
+define Package/liblo-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/osc{dump,send} $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,liblo))
+$(eval $(call BuildPackage,liblo-utils))
diff --git a/external/subpack/libs/liblo/patches/010-index.patch b/external/subpack/libs/liblo/patches/010-index.patch
new file mode 100644
index 0000000..160ed3a
--- /dev/null
+++ b/external/subpack/libs/liblo/patches/010-index.patch
@@ -0,0 +1,15 @@
+--- a/src/server.c
++++ b/src/server.c
+@@ -2013,11 +2013,8 @@ static void dispatch_method(lo_server s,
+ 
+                     tmp = (char*) malloc(strlen(it->path + len) + 1);
+                     strcpy(tmp, it->path + len);
+-#if defined(WIN32) || defined(_MSC_VER)
+                     sec = strchr(tmp, '/');
+-#else
+-                    sec = index(tmp, '/');
+-#endif
++
+                     if (sec)
+                         *sec = '\0';
+                     slend = sl;
diff --git a/external/subpack/libs/liblo/patches/020-usleep.patch b/external/subpack/libs/liblo/patches/020-usleep.patch
new file mode 100644
index 0000000..2b138f6
--- /dev/null
+++ b/external/subpack/libs/liblo/patches/020-usleep.patch
@@ -0,0 +1,20 @@
+--- a/src/tools/oscsendfile.c
++++ b/src/tools/oscsendfile.c
+@@ -354,7 +354,7 @@ int send_file(lo_address target, double
+             lo_timetag_now(&tt_now);
+             double wait_time = timetag_diff(*tt_last, tt_now);
+             if (wait_time > 0.) {
+-                usleep(wait_time * 1000000);
++                sleep(wait_time);
+             }
+             if (b) {
+                 ret = lo_send_bundle(target, b);
+@@ -376,7 +376,7 @@ int send_file(lo_address target, double
+         lo_timetag_now(&tt_now);
+         double wait_time = timetag_diff(*tt_last, tt_now);
+         if (wait_time > 0.) {
+-            usleep(wait_time * 1000000);
++            sleep(wait_time);
+         }
+         lo_send_bundle(target, b);
+     }
diff --git a/external/subpack/libs/liblz4/Config.in b/external/subpack/libs/liblz4/Config.in
new file mode 100644
index 0000000..d66fb7d
--- /dev/null
+++ b/external/subpack/libs/liblz4/Config.in
@@ -0,0 +1,7 @@
+config LZ4_OPTIMIZE_SPEED
+	bool "Optimize for speed"
+	depends on PACKAGE_liblz4
+	help
+		This enables additional optimization and
+		increases performance considerably at
+		the expense of binary size.
diff --git a/external/subpack/libs/liblz4/Makefile b/external/subpack/libs/liblz4/Makefile
new file mode 100644
index 0000000..1690014
--- /dev/null
+++ b/external/subpack/libs/liblz4/Makefile
@@ -0,0 +1,101 @@
+#
+# Copyright (C) 2015 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:=lz4
+PKG_VERSION:=1.10.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/lz4/lz4/releases/download/v$(PKG_VERSION)
+PKG_HASH:=537512904744b35e232912055ccf8ec66d768639ff3abe5788d90d792ec5f48b
+
+PKG_MAINTAINER:=Darik Horn <dajhorn@vanadac.com>
+PKG_CPE_ID:=cpe:/a:lz4_project:lz4
+
+PKG_CONFIG_DEPENDS:=CONFIG_PACKAGE_lz4
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+MESON_BUILD_DIR:=$(PKG_BUILD_DIR)/build/meson/openwrt-build
+
+define Package/lz4/Default
+  SUBMENU:=Compression
+  URL:=https://www.lz4.org/
+endef
+
+define Package/liblz4
+$(call Package/lz4/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Extremely fast compression
+  LICENSE:=BSD-2-Clause
+  LICENSE_FILES:=LICENSE lib/LICENSE
+  ABI_VERSION:=$(firstword $(subst .,$(space),$(PKG_VERSION)))
+  MENU:=1
+endef
+
+define Package/liblz4/description
+  LZ4 is a compression codec that features a very fast encoder and an
+  even faster decoder. This package provides the liblz4 shared library.
+endef
+
+define Package/liblz4/config
+	source "$(SOURCE)/Config.in"
+endef
+
+define Package/lz4
+$(call Package/lz4/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Extremely fast compression
+  LICENSE:=GPL-2.0-or-later
+  LICENSE_FILES:=LICENSE programs/COPYING
+  DEPENDS:=+liblz4
+endef
+
+define Package/lz4/description
+  LZ4 - Fast real-time compression algorithm.
+  This package provides the lz4 binaries.
+endef
+
+MESON_ARGS += \
+	-Ddebug-level=0 \
+	-Dunstable=false \
+	-Dprograms=$(if $(CONFIG_PACKAGE_lz4),true,false) \
+	-Dtests=false \
+	-Dcontrib=false \
+	-Dexamples=false \
+	-Db_lto=false
+
+ifeq ($(CONFIG_LZ4_OPTIMIZE_SPEED),y)
+	TARGET_CFLAGS := $(filter-out -O%,$(TARGET_CFLAGS)) -O3
+endif
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liblz4.so* $(1)/usr/lib
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/liblz4.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/liblz4/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liblz4.so.$(ABI_VERSION)* $(1)/usr/lib/
+endef
+
+define Package/lz4/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/{lz4,lz4c,lz4cat,unlz4} $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,liblz4))
+$(eval $(call BuildPackage,lz4))
diff --git a/external/subpack/libs/libmad/Makefile b/external/subpack/libs/libmad/Makefile
new file mode 100644
index 0000000..bdd5360
--- /dev/null
+++ b/external/subpack/libs/libmad/Makefile
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2006-2014 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:=libmad
+PKG_VERSION:=0.16.4
+PKG_RELEASE:=3
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_SOURCE_URL:=https://codeberg.org/tenacityteam/libmad
+PKG_MIRROR_HASH:=6a9cca07873ed6e7ace90652cc681d825260bd2866f2f92673b39dcd99523c3c
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:underbit:mad_libmad
+
+CMAKE_INSTALL:=1
+PKG_BUILD_FLAGS:=no-mips16
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libmad
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=An high-quality MPEG audio decoding library
+  URL:=http://www.underbit.com/products/mad/
+endef
+
+define Package/libmad/description
+	MAD is a high-quality MPEG audio decoder. It currently supports
+	MPEG-1 and the MPEG-2 extension to lower sampling frequencies,
+	as well as the de facto MPEG 2.5 format. All three audio layers -
+	Layer I, Layer II, and Layer III (i.e. MP3) - are fully implemented.
+endef
+
+CMAKE_OPTIONS += \
+	-DOPTIMIZE=SPEED
+
+TARGET_CFLAGS:= $(filter-out -O%,$(TARGET_CFLAGS)) -O2
+
+define Package/libmad/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmad.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libmad))
diff --git a/external/subpack/libs/libmad/patches/010-format.patch b/external/subpack/libs/libmad/patches/010-format.patch
new file mode 100644
index 0000000..c1d0562
--- /dev/null
+++ b/external/subpack/libs/libmad/patches/010-format.patch
@@ -0,0 +1,29 @@
+From cb1e56cb691e0f9ebcad595632ef484389830431 Mon Sep 17 00:00:00 2001
+From: Mangix <mangixjohn@icloud.com>
+Date: Thu, 27 Jun 2024 20:13:07 +0000
+Subject: [PATCH] minimad: fix format under 32-bit
+
+This is pointer subtraction. Use proper macro for this. 32-bit needs to be %d.
+---
+ minimad.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/minimad.c
++++ b/minimad.c
+@@ -19,6 +19,7 @@
+  * $Id: minimad.c,v 1.4 2004/01/23 09:41:32 rob Exp $
+  */
+ 
++# include <inttypes.h>
+ # include <stdio.h>
+ # include <unistd.h>
+ # include <sys/stat.h>
+@@ -174,7 +175,7 @@ enum mad_flow error(void *data,
+ {
+   struct buffer *buffer = data;
+ 
+-  fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %u\n",
++  fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %" PRIdPTR "\n",
+ 	  stream->error, mad_stream_errorstr(stream),
+ 	  stream->this_frame - buffer->start);
+ 
diff --git a/external/subpack/libs/libmariadb/Makefile b/external/subpack/libs/libmariadb/Makefile
new file mode 100644
index 0000000..32a7bef
--- /dev/null
+++ b/external/subpack/libs/libmariadb/Makefile
@@ -0,0 +1,176 @@
+#
+# Copyright (C) 2019 Sebastian Kemper <sebastian_ml@gmx.net>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libmariadb
+PKG_VERSION:=3.4.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=mariadb-connector-c-$(PKG_VERSION)-src.tar.gz
+PKG_SOURCE_URL:=\
+	https://mirror.netcologne.de/mariadb/connector-c-$(PKG_VERSION) \
+	https://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/connector-c-$(PKG_VERSION) \
+	https://dlm.mariadb.com/3907132/Connectors/c/connector-c-$(PKG_VERSION)
+PKG_HASH:=0a7f2522a44a7369c1dda89676e43485037596a7b1534898448175178aedeb4d
+PKG_BUILD_DIR:=$(BUILD_DIR)/mariadb-connector-c-$(PKG_VERSION)-src
+
+PKG_MAINTAINER:=Michal Hrusecky <Michal@Hrusecky.net>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LIB
+PKG_CPE_ID:=cpe:/a:mariadb:mariadb
+
+MARIADB_CONF_DIR:=/etc/mysql
+MARIADB_PLUGIN_DIR:=/usr/lib/mariadb/plugin
+
+MARIADB_PORT=3306
+MARIADB_SOCKET=/var/run/mysql/mysql.sock
+
+MARIADB_CLIENT_PLUGINS := \
+	auth_gssapi_client \
+	remote_io
+
+PKG_BUILD_DEPENDS:=curl USE_MUSL:libucontext
+
+PKG_CONFIG_DEPENDS := \
+	$(patsubst %,CONFIG_PACKAGE_$(PKG_NAME)-plugin-%,$(subst _,-,$(MARIADB_CLIENT_PLUGINS)))
+
+plugin-auth_gssapi_client       := CLIENT_PLUGIN_AUTH_GSSAPI_CLIENT
+plugin-remote_io                := CLIENT_PLUGIN_REMOTE_IO
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+# Pass CPPFLAGS in the CFLAGS as otherwise the build system will ignore them.
+TARGET_CFLAGS+=$(TARGET_CPPFLAGS)
+
+define Package/$(PKG_NAME)/install/plugin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)$(MARIADB_PLUGIN_DIR)/$(2).so $(1)$(MARIADB_PLUGIN_DIR)
+endef
+
+define Package/$(PKG_NAME)/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=https://mariadb.org/
+  SUBMENU:=Database
+endef
+
+define Package/$(PKG_NAME)/description/Default
+MariaDB is a very fast and robust SQL database server.
+endef
+
+define Package/$(PKG_NAME)
+  $(call Package/$(PKG_NAME)/Default)
+  DEPENDS:= \
+	  $(ICONV_DEPENDS) \
+	  +libopenssl \
+	  +zlib
+  TITLE:=MariaDB database client library
+  MENU:=1
+  PROVIDES:=libmariadbclient libmysqlclient libmysqlclient-r
+  ABI_VERSION:=3
+endef
+
+define Package/$(PKG_NAME)/description
+$(call Package/$(PKG_NAME)/description/Default)
+
+This package includes the client library.
+
+endef
+
+# We won't need unit tests
+CMAKE_OPTIONS += -DWITH_UNIT_TESTS=0
+
+CMAKE_OPTIONS += \
+	-DDEFAULT_CHARSET=utf8 \
+	-DDEFAULT_COLLATION=utf8_general_ci \
+	-DINSTALL_INCLUDEDIR=include/mysql \
+	-DINSTALL_LIBDIR=lib \
+	-DINSTALL_PLUGINDIR=lib/mariadb/plugin \
+	-DMARIADB_UNIX_ADDR=$(MARIADB_SOCKET) \
+	-DWITH_EXTERNAL_ZLIB=YES \
+	-DWITH_MYSQLCOMPAT=ON \
+	-DWITH_SSL=OPENSSL
+
+# Help MariaDB find the correct libiconv.
+# nls.mk sets it up so that with CONFIG_BUILD_NLS libiconv-full would be used,
+# otherwise libiconv-stub (independent of the selected libc). MariaDB needs a
+# leg up to find/pick the right lib.
+CMAKE_OPTIONS += \
+	-DICONV_INCLUDE_DIR=$(ICONV_PREFIX)/include \
+	-DICONV_LIBRARIES=$(ICONV_PREFIX)/lib/libiconv.$(if $(CONFIG_BUILD_NLS),so,a)
+
+CMAKE_OPTIONS += \
+	$(foreach p,$(MARIADB_CLIENT_PLUGINS),-D$(plugin-$(p))=$(if $(CONFIG_PACKAGE_$(PKG_NAME)-plugin-$(subst _,-,$(p))),DYNAMIC,OFF))
+
+# LIBICONV_PLUG is used in GNU's libiconv for redefinition of exports [e.g.
+# from libiconv_open() to iconv_open()]. But in OpenWrt this variable is not set
+# when building libiconv-full. So when MariaDB sets LIBICONV_PLUG it expects
+# iconv_open() to be available for example, which is not the case - only
+# libiconv_open() is. To address this prevent the variable from being set.
+# libiconv-stub does not use this variable, so there is no harm in always doing
+# this.
+
+define Build/Prepare
+	$(call Build/Prepare/Default)
+	$(SED) '/ADD_DEFINITIONS(-DLIBICONV_PLUG)/d' $(PKG_BUILD_DIR)/CMakeLists.txt
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin $(1)/usr/include $(1)/usr/lib/mysql $(1)/usr/lib/pkgconfig $(2)/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/mysql $(1)/usr/include
+	cd $(1)/usr/include/mysql; $(LN) mariadb_version.h mysql_version.h
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib{mariadb,mysqlclient}*.so* $(1)/usr/lib
+	cd $(1)/usr/lib/mysql; $(LN) ../lib{mariadb,mysqlclient}*.so* .
+	$(INSTALL_BIN) files/mysql_config $(1)/usr/bin
+	$(LN) $(STAGING_DIR)/usr/bin/mysql_config $(2)/bin
+	$(SED) 's/PORT/$(MARIADB_PORT)/' $(1)/usr/bin/mysql_config
+	$(SED) 's|PLUGIN_DIR|$(MARIADB_PLUGIN_DIR)|' $(1)/usr/bin/mysql_config
+	$(SED) 's|SOCKET|$(MARIADB_SOCKET)|' $(1)/usr/bin/mysql_config
+	cd "$(PKG_BUILD_DIR)/mariadb_config"; \
+		CLIENT_VERSION=`sed -n 's|^#define[[:blank:]]*VERSION[[:blank:]]*"\([0-9.]*\)"|\1|p' mariadb_config.c`; \
+		$(SED) "s/VERSION/$$$${CLIENT_VERSION}/" $(1)/usr/bin/mysql_config
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libmariadb.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/$(PKG_NAME)/install
+	$(INSTALL_DIR) $(1)$(MARIADB_CONF_DIR)/conf.d
+	$(INSTALL_DIR) $(1)$(MARIADB_PLUGIN_DIR)
+	$(INSTALL_BIN) \
+		$(PKG_INSTALL_DIR)$(MARIADB_PLUGIN_DIR)/caching_sha2_password.so \
+		$(PKG_INSTALL_DIR)$(MARIADB_PLUGIN_DIR)/client_ed25519.so \
+		$(PKG_INSTALL_DIR)$(MARIADB_PLUGIN_DIR)/dialog.so \
+		$(PKG_INSTALL_DIR)$(MARIADB_PLUGIN_DIR)/mysql_clear_password.so \
+		$(PKG_INSTALL_DIR)$(MARIADB_PLUGIN_DIR)/sha256_password.so \
+		$(1)$(MARIADB_PLUGIN_DIR)
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/libmariadb.so.$(ABI_VERSION) $(1)/usr/lib
+endef
+
+define BuildPlugin
+  define Package/$(PKG_NAME)-plugin-$(subst _,-,$(1))
+    $(call Package/$(PKG_NAME)/Default)
+    TITLE:=$(PKG_NAME) plugin
+    DEPENDS:=$(PKG_NAME) $(patsubst +%,+PACKAGE_$(PKG_NAME)-plugin-$(subst _,-,$(1)):%,$(2))
+  endef
+  define Package/$(PKG_NAME)-plugin-$(subst _,-,$(1))/description
+    $(call Package/$(PKG_NAME)/description/Default)
+
+This package provides the $(1) plugin.
+
+  endef
+  define Package/$(PKG_NAME)-plugin-$(subst _,-,$(1))/install
+	  $(INSTALL_DIR) $$(1)$(MARIADB_PLUGIN_DIR)
+	  $(call Package/$(PKG_NAME)/install/plugin,$$(1),$(1))
+  endef
+  $$(eval $$(call BuildPackage,$(PKG_NAME)-plugin-$(subst _,-,$(1))))
+endef
+
+$(eval $(call BuildPackage,$(PKG_NAME)))
+
+$(eval $(call BuildPlugin,auth_gssapi_client,+krb5-libs))
+$(eval $(call BuildPlugin,remote_io,+libcurl))
diff --git a/external/subpack/libs/libmariadb/files/mysql_config b/external/subpack/libs/libmariadb/files/mysql_config
new file mode 100755
index 0000000..5c4dfbd
--- /dev/null
+++ b/external/subpack/libs/libmariadb/files/mysql_config
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+PCFILE=libmariadb
+
+command -v pkg-config > /dev/null 2>&1
+ret="$?"
+if [ "$ret" -ne 0 ]; then
+        echo pkg-config not found >&2
+        exit 1
+fi
+
+pkg-config $PCFILE > /dev/null 2>&1
+ret="$?"
+if [ "$ret" -ne 0 ]; then
+        echo $PCFILE pkg-config file missing >&2
+        exit 1
+fi
+
+cflags=$(pkg-config $PCFILE --cflags)
+include=$(pkg-config $PCFILE --cflags)
+libs=$(pkg-config $PCFILE --libs)
+plugindir=PLUGIN_DIR
+socket=SOCKET
+port=PORT
+version=VERSION
+
+usage () {
+        cat <<EOF
+Usage: $0 [OPTIONS]
+Options:
+        --cflags         [$cflags]
+        --include        [$include]
+        --libs           [$libs]
+        --libs_r         [$libs]
+        --plugindir      [$plugindir]
+        --socket         [$socket]
+        --port           [$port]
+        --version        [$version]
+EOF
+  exit "$1"
+}
+
+if test $# -le 0; then usage 0 ; fi
+
+while test $# -gt 0; do
+        case $1 in
+        --cflags)  echo "$cflags" ;;
+        --include) echo "$include" ;;
+        --libs)    echo "$libs" ;;
+        --libs_r)  echo "$libs" ;;
+        --plugindir) echo "$plugindir" ;;
+        --socket)  echo "$socket" ;;
+        --port)    echo "$port" ;;
+        --version) echo "$version" ;;
+        *) usage 1 >&2 ;;
+        esac
+
+        shift
+done
+
+exit 0
diff --git a/external/subpack/libs/libmariadb/patches/010-link-to-libucontext.patch b/external/subpack/libs/libmariadb/patches/010-link-to-libucontext.patch
new file mode 100644
index 0000000..ebde0c1
--- /dev/null
+++ b/external/subpack/libs/libmariadb/patches/010-link-to-libucontext.patch
@@ -0,0 +1,61 @@
+libmariadb: Fix async api by linking to libucontext
+The asynchronous API of libmariadb uses cooperative multi threading
+by using the system calls
+  * makecontext
+  * swapcontext
+  * getcontext
+  * setcontext
+of the ucontext.h C-API.
+
+Thus additionally link libmariadb to libucontext which is a library
+providing these system calls on platforms not supporting them out of
+the box - like musl based platforms.
+--- a/libmariadb/CMakeLists.txt
++++ b/libmariadb/CMakeLists.txt
+@@ -458,7 +458,7 @@ ELSE()
+   SET_TARGET_PROPERTIES(libmariadb PROPERTIES LINKER_LANGUAGE C)
+ ENDIF()
+ 
+-TARGET_LINK_LIBRARIES(libmariadb LINK_PRIVATE ${SYSTEM_LIBS} ${CRYPTO_LIBS})
++TARGET_LINK_LIBRARIES(libmariadb LINK_PRIVATE ${SYSTEM_LIBS} ${CRYPTO_LIBS} ${LIBUCONTEXT_POSIX} ${LIBUCONTEXT})
+ 
+ SIGN_TARGET(libmariadb)
+ 
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -251,6 +251,14 @@ IF(UNIX)
+   SEARCH_LIBRARY(LIBPTHREAD pthread_getspecific "pthread;pthreads")
+   SEARCH_LIBRARY(LIBNSL gethostbyname_r "nsl_r;nsl")
+   SEARCH_LIBRARY(LIBSOCKET setsockopt socket)
++  SEARCH_LIBRARY(LIBUCONTEXT libucontext_swapcontext libucontext.a)
++  SEARCH_LIBRARY(LIBUCONTEXT_POSIX swapcontext libucontext_posix.a)
++  IF (NOT HAVE_LIBUCONTEXT_POSIX OR NOT HAVE_LIBUCONTEXT)
++    UNSET(HAVE_LIBUCONTEXT)
++    UNSET(LIBUCONTEXT)
++    UNSET(HAVE_LIBUCONTEXT_POSIX)
++    UNSET(LIBUCONTEXT_POSIX)
++  ENDIF()
+   FIND_PACKAGE(Threads)
+   SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${LIBNSL} ${LIBBIND} ${LIBICONV} ${ZLIB_LIBRARY} 
+       ${LIBSOCKET} ${CMAKE_DL_LIBS} ${LIBM} ${LIBPTHREAD})
+--- a/include/ma_config.h.in
++++ b/include/ma_config.h.in
+@@ -28,6 +28,7 @@
+ #cmakedefine HAVE_SYS_UN_H 1
+ #cmakedefine HAVE_UNISTD_H 1
+ #cmakedefine HAVE_UCONTEXT_H 1
++#cmakedefine HAVE_LIBUCONTEXT_POSIX 1
+ 
+ /*
+  * function definitions - processed in LibmysqlFunctions.txt 
+--- a/include/ma_context.h
++++ b/include/ma_context.h
+@@ -32,7 +32,7 @@
+ #define MY_CONTEXT_USE_X86_64_GCC_ASM
+ #elif defined(__GNUC__) && __GNUC__ >= 3 && defined(__i386__)
+ #define MY_CONTEXT_USE_I386_GCC_ASM
+-#elif defined(HAVE_UCONTEXT_H)
++#elif defined(HAVE_UCONTEXT_H) || defined(HAVE_LIBUCONTEXT_POSIX)
+ #define MY_CONTEXT_USE_UCONTEXT
+ #else
+ #define MY_CONTEXT_DISABLE
diff --git a/external/subpack/libs/libmariadb/patches/020-fix-ucontext-maybe-uninitialized.patch b/external/subpack/libs/libmariadb/patches/020-fix-ucontext-maybe-uninitialized.patch
new file mode 100644
index 0000000..d350e7a
--- /dev/null
+++ b/external/subpack/libs/libmariadb/patches/020-fix-ucontext-maybe-uninitialized.patch
@@ -0,0 +1,12 @@
+--- a/libmariadb/ma_context.c
++++ b/libmariadb/ma_context.c
+@@ -92,6 +92,9 @@ my_context_spawn(struct my_context *c, v
+ {
+   int err;
+   union pass_void_ptr_as_2_int u;
++  // Avoid 'may be used uninitialized' error on 32-bit systems
++  // upstream issue: https://jira.mariadb.org/browse/CONC-725
++  u.a[1] = 0;
+ 
+   err= getcontext(&c->spawned_context);
+   if (err)
diff --git a/external/subpack/libs/libmaxminddb/Makefile b/external/subpack/libs/libmaxminddb/Makefile
new file mode 100644
index 0000000..f5c3e22
--- /dev/null
+++ b/external/subpack/libs/libmaxminddb/Makefile
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://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:=libmaxminddb
+PKG_VERSION:=1.11.0
+PKG_RELEASE=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/maxmind/libmaxminddb/releases/download/$(PKG_VERSION)
+PKG_HASH:=b2eea79a96fed77ad4d6c39ec34fed83d45fcb75a31c58956813d58dcf30b19f
+
+PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec1@gmail.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:maxmind:libmaxminddb
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libmaxminddb
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A library for working with MaxMind DB files
+  URL:=https://maxmind.github.io/libmaxminddb/
+endef
+
+define Package/libmaxminddb/description
+ The libmaxminddb library provides functions for working MaxMind DB files.
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_SHARED_LIBS=ON \
+	-DBUILD_TESTING=OFF
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmaxminddb.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libmaxminddb.pc $(1)/usr/lib/pkgconfig
+	$(SED) 's,libdir=lib,libdir=$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libmaxminddb.pc
+	$(SED) 's,includedir=include,includedir=$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libmaxminddb.pc
+endef
+
+define Package/libmaxminddb/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mmdblookup $(1)/usr/bin/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmaxminddb.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libmaxminddb))
diff --git a/external/subpack/libs/libmbim/Makefile b/external/subpack/libs/libmbim/Makefile
new file mode 100644
index 0000000..c6ba427
--- /dev/null
+++ b/external/subpack/libs/libmbim/Makefile
@@ -0,0 +1,97 @@
+#
+# Copyright (C) 2016 Velocloud Inc.
+# Copyright (C) 2016 Aleksander Morgado <aleksander@aleksander.es>
+#
+# This is free software, licensed under the GNU General Public License v2.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libmbim
+PKG_VERSION:=1.30.0
+PKG_RELEASE:=2
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libmbim.git
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_MIRROR_HASH:=0ff9212138eb68c2e33ad9220aa64df2e9a0da86f03dd02bf6d4cf02bcd95a68
+
+PKG_BUILD_FLAGS:=gc-sections
+
+PKG_MAINTAINER:=Nicholas Smith <nicholas@nbembedded.com>
+PKG_CPE_ID:=cpe:/a:freedesktop:libmbim
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+TARGET_CFLAGS += -fno-merge-all-constants -fmerge-constants
+
+MESON_ARGS += \
+	-Dintrospection=false \
+	-Dman=false \
+	-Dbash_completion=false \
+	-Db_lto=true
+
+define Package/libmbim
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+glib2
+  TITLE:=Helper library and utils to talk to MBIM enabled modems
+  URL:=https://www.freedesktop.org/wiki/Software/libmbim
+  LICENSE:=LGPL-2.0-or-later
+  LICENSE_FILES:=COPYING.LIB
+endef
+
+define Package/libmbim/description
+  Helper library to talk to MBIM enabled modems.
+  Add mbim-utils for extra utilities.
+endef
+
+define Package/mbim-utils
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libmbim
+  TITLE:=Utilities to talk to MBIM enabled modems
+  URL:=https://www.freedesktop.org/wiki/Software/libmbim
+  LICENSE:=GPL-2.0-or-later
+  LICENSE_FILES:=COPYING
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/libmbim-glib \
+		$(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libmbim*.so* \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/mbim-glib.pc \
+		$(1)/usr/lib/pkgconfig
+endef
+
+define Package/libmbim/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib \
+		$(1)/usr/libexec
+
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libmbim*.so.* \
+		$(1)/usr/lib/
+
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/libexec/mbim-proxy $(1)/usr/libexec/
+endef
+
+define Package/mbim-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mbimcli $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mbim-network $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libmbim))
+$(eval $(call BuildPackage,mbim-utils))
diff --git a/external/subpack/libs/libmcrypt/Makefile b/external/subpack/libs/libmcrypt/Makefile
new file mode 100644
index 0000000..ef70444
--- /dev/null
+++ b/external/subpack/libs/libmcrypt/Makefile
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2006-2010 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:=libmcrypt
+PKG_VERSION:=2.5.8
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@SF/mcrypt
+PKG_HASH:=bf2f1671f44af88e66477db0982d5ecb5116a5c767b0a0d68acb34499d41b793
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LIB
+PKG_CPE_ID:=cpe:/a:mcrypt:libmcrypt
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libmcrypt
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Cryptographic library
+  URL:=http://mcrypt.sourceforge.net/
+endef
+
+define Package/libmcrypt/description
+	libmcrypt is a cryptographic library that conveniently brings
+	together a variety of ciphers for convenient use.
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static
+
+TARGET_CFLAGS += $(FPIC)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmcrypt.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/libmcrypt-config $(1)/usr/bin/
+	$(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(1)/usr/bin/libmcrypt-config
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/libmcrypt-config $(2)/bin/libmcrypt-config
+endef
+
+define Package/libmcrypt/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmcrypt.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libmcrypt))
diff --git a/external/subpack/libs/libmicrohttpd/Makefile b/external/subpack/libs/libmicrohttpd/Makefile
new file mode 100644
index 0000000..76acb47
--- /dev/null
+++ b/external/subpack/libs/libmicrohttpd/Makefile
@@ -0,0 +1,95 @@
+#
+# Copyright (C) 2010-2014 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:=libmicrohttpd
+PKG_VERSION:=1.0.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/libmicrohttpd
+PKG_HASH:=a89e09fc9b4de34dde19f4fcb4faaa1ce10299b9908db1132bbfa1de47882b94
+
+PKG_MAINTAINER:=Alexander Couzens <lynxis@fe80.eu>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:gnu:libmicrohttpd
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libmicrohttpd/default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=https://www.gnu.org/software/libmicrohttpd/
+endef
+
+define Package/libmicrohttpd-no-ssl
+$(call Package/libmicrohttpd/default)
+  TITLE:=GNU libmicrohttpd is an embbeded HTTP server library
+  VARIANT:=nossl
+  DEFAULT_VARIANT:=1
+  PROVIDES:=libmicrohttpd
+endef
+
+define Package/libmicrohttpd-ssl
+$(call Package/libmicrohttpd/default)
+  TITLE:=GNU libmicrohttpd is an embbeded HTTP and HTTPS server library
+  VARIANT:=ssl
+  DEPENDS:=+libgnutls
+  PROVIDES:=libmicrohttpd
+endef
+
+define Package/libmicrohttpd/description
+  GNU libmicrohttpd is a small C library that is supposed to make it easy
+  to run an HTTP server as part of another application.
+endef
+
+CONFIGURE_ARGS += \
+	--disable-curl \
+	--disable-rpath \
+	--disable-doc \
+	--disable-examples \
+	--enable-epoll \
+	--with-pic
+
+ifeq ($(BUILD_VARIANT),ssl)
+CONFIGURE_ARGS += \
+	--enable-https \
+	--with-gnutls \
+	--enable-md5=tlslib \
+	--enable-sha256=tlslib
+else
+CONFIGURE_ARGS += \
+	--disable-https \
+	--without-gnutls
+endif
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/microhttpd.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmicrohttpd.{so*,a,la} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libmicrohttpd.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libmicrohttpd-no-ssl/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmicrohttpd.so* $(1)/usr/lib/
+endef
+
+define Package/libmicrohttpd-ssl/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmicrohttpd.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libmicrohttpd-no-ssl))
+$(eval $(call BuildPackage,libmicrohttpd-ssl))
diff --git a/external/subpack/libs/libmms/Makefile b/external/subpack/libs/libmms/Makefile
new file mode 100644
index 0000000..49000a6
--- /dev/null
+++ b/external/subpack/libs/libmms/Makefile
@@ -0,0 +1,58 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libmms
+PKG_VERSION:=0.6.4
+PKG_RELEASE:=4
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/libmms
+PKG_HASH:=3c05e05aebcbfcc044d9e8c2d4646cd8359be39a3f0ba8ce4e72a9094bee704f
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+
+PKG_LICENSE:=LGPLv2.1
+PKG_LICENSE_FILES:=COPYING.LIB
+PKG_CPE_ID:=cpe:/a:libmms_project:libmms
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libmms
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=MMS stream protocol library
+  URL:=http://libmms.sourceforge.net
+endef
+
+define Package/libmms/description
+	LibMMS is a common library for parsing mms:// and mmsh:// type network streams.
+	These are commonly used to stream Windows Media Video content over the web.
+	LibMMS itself is only for receiving MMS stream,
+	it doesn't handle sending at all.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libmms $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmms.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc \
+		$(1)/usr/lib/pkgconfig
+endef
+
+define Package/libmms/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmms.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libmms))
diff --git a/external/subpack/libs/libmms/patches/010-remove_glib_from_pkgconfig.patch b/external/subpack/libs/libmms/patches/010-remove_glib_from_pkgconfig.patch
new file mode 100644
index 0000000..a551cc6
--- /dev/null
+++ b/external/subpack/libs/libmms/patches/010-remove_glib_from_pkgconfig.patch
@@ -0,0 +1,10 @@
+--- a/pkgconfig/libmms.pc.in
++++ b/pkgconfig/libmms.pc.in
+@@ -5,7 +5,6 @@ includedir=@includedir@/
+ 
+ Name: libmms
+ Description: Library implementing the MMS protocol 
+-Requires: glib-2.0
+ Version: @VERSION@
+ Libs: -L${libdir} -lmms -lm
+ Cflags: -I${includedir}
diff --git a/external/subpack/libs/libmodbus/Makefile b/external/subpack/libs/libmodbus/Makefile
new file mode 100644
index 0000000..70acb00
--- /dev/null
+++ b/external/subpack/libs/libmodbus/Makefile
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2006-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:=libmodbus
+PKG_VERSION:=3.1.8
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/stephane/libmodbus/releases/download/v$(PKG_VERSION)/
+PKG_HASH:=b122f2bc29f749702a22c0a760a7ca2182d541f5fa26bf25e3431f907b606f3c
+
+PKG_MAINTAINER:=Michael Heimpold <mhei@heimpold.de>
+
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LESSER
+PKG_CPE_ID:=cpe:/a:libmodbus:libmodbus
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libmodbus
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=http://www.libmodbus.org
+  TITLE:=libmodbus
+endef
+
+define Package/libmodbus/description
+  A Modbus library for Linux, Mac OS X, FreeBSD, QNX and Win32.
+endef
+
+CONFIGURE_ARGS += --disable-tests
+TARGET_CFLAGS += $(FPIC)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/modbus $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmodbus.{so*,la} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libmodbus.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libmodbus/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmodbus.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libmodbus))
diff --git a/external/subpack/libs/libmpc/Makefile b/external/subpack/libs/libmpc/Makefile
new file mode 100644
index 0000000..2a5e3d1
--- /dev/null
+++ b/external/subpack/libs/libmpc/Makefile
@@ -0,0 +1,57 @@
+#
+# 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:=mpc
+PKG_VERSION:=1.3.1
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=@GNU/mpc/
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_HASH:=ab642492f5cf882b74aa0cb730cd410a81edcdbec895183ce930e706c1c759b8
+
+PKG_LICENSE:=LGPL-3.0-or-later
+PKG_LICENSE_FILES:=COPYING.LESSER
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_PARALLEL:=1
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libmpc
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GNU MPC library
+  URL:=https://www.multiprecision.org/mpc/
+  DEPENDS:=+libgmp +libmpfr
+  ABI_VERSION:=3
+endef
+
+define Package/libmpc/description
+GNU MPC is a portable library written in C for arbitrary precision
+arithmetic on complex numbers providing correct rounding. It implements
+a multiprecision equivalent of the C99 standard. It builds upon the GNU
+MP and the GNU MPFR libraries.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/mpc* $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmpc.{a,so*} $(1)/usr/lib/
+endef
+
+define Package/libmpc/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmpc.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libmpc))
diff --git a/external/subpack/libs/libmpc/patches/001-only-src.patch b/external/subpack/libs/libmpc/patches/001-only-src.patch
new file mode 100644
index 0000000..8201ec7
--- /dev/null
+++ b/external/subpack/libs/libmpc/patches/001-only-src.patch
@@ -0,0 +1,22 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -23,7 +23,7 @@ ACLOCAL_AMFLAGS = -I m4
+ # VERSION = @VERSION@@GITVERSION@ # for development version
+ VERSION = @VERSION@
+ 
+-SUBDIRS = src tests doc tools
++SUBDIRS = src
+ 
+ EXTRA_HEADERS = src/mpc-log.h
+ include_HEADERS = src/mpc.h @MPC_LOG_H@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -376,7 +376,7 @@ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+ ACLOCAL_AMFLAGS = -I m4
+-SUBDIRS = src tests doc tools
++SUBDIRS = src
+ EXTRA_HEADERS = src/mpc-log.h
+ include_HEADERS = src/mpc.h @MPC_LOG_H@
+ EXTRA_DIST = doc/fdl-1.3.texi src/mpc-log.h
diff --git a/external/subpack/libs/libmpdclient/Makefile b/external/subpack/libs/libmpdclient/Makefile
new file mode 100644
index 0000000..7d4e9f4
--- /dev/null
+++ b/external/subpack/libs/libmpdclient/Makefile
@@ -0,0 +1,60 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libmpdclient
+PKG_VERSION:=2.22
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://www.musicpd.org/download/libmpdclient/2
+PKG_HASH:=eac15b82b5ba5ed0648af580221eb74657394f7fe768e966d9e9ebb27435429f
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libmpdclient
+    TITLE:=libmpdclient
+    SECTION:=libs
+    CATEGORY:=Libraries
+    URL:=https://musicpd.org/libs/libmpdclient/
+endef
+
+define Package/libmpdclient/description
+    A stable, documented, asynchronous API library for interfacing MPD in the C, C++ & Objective C languages.
+endef
+
+MESON_ARGS+=-Ddocumentation=false
+
+define Build/InstallDev
+	$(INSTALL_DIR) \
+		$(1)/usr/include \
+		$(1)/usr/lib \
+		$(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/* \
+		$(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/* \
+		$(1)/usr/include/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig \
+		$(1)/usr/lib/
+endef
+
+define Package/libmpdclient/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libmpdclient.so* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libmpdclient))
diff --git a/external/subpack/libs/libmpeg2/Makefile b/external/subpack/libs/libmpeg2/Makefile
new file mode 100644
index 0000000..a0c1c44
--- /dev/null
+++ b/external/subpack/libs/libmpeg2/Makefile
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2011 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:=libmpeg2
+PKG_VERSION:=0.5.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=libmpeg2-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://libmpeg2.sourceforge.net/files/
+PKG_HASH:=dee22e893cb5fc2b2b6ebd60b88478ab8556cb3b93f9a0d7ce8f3b61851871d4
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libmpeg2
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=MPEG-1 & -2 decoding library
+  URL:=http://libmpeg2.sourceforge.net/
+  MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+endef
+
+define Package/libmpeg2/decription
+  Libmpeg2 is a library for decoding MPEG-1 and MPEG-2 video streams
+endef
+
+CONFIGURE_ARGS += \
+	--disable-sdl \
+	--without-x \
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/mpeg2dec \
+		$(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libmpeg2{,convert}.{a,so*} \
+		$(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libmpeg2{,convert}.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libmpeg2/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libmpeg2{,convert}.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libmpeg2))
diff --git a/external/subpack/libs/libmpeg2/patches/101-ppc_no_altivec.patch b/external/subpack/libs/libmpeg2/patches/101-ppc_no_altivec.patch
new file mode 100644
index 0000000..49251a0
--- /dev/null
+++ b/external/subpack/libs/libmpeg2/patches/101-ppc_no_altivec.patch
@@ -0,0 +1,66 @@
+--- a/libmpeg2/motion_comp_altivec.c
++++ b/libmpeg2/motion_comp_altivec.c
+@@ -25,6 +25,8 @@
+ 
+ #ifdef ARCH_PPC
+ 
++#ifdef __I_WANT_ALTIVEC__
++
+ #ifdef HAVE_ALTIVEC_H
+ #include <altivec.h>
+ #endif
+@@ -1007,4 +1009,6 @@ static void MC_avg_xy_8_altivec (uint8_t
+ 
+ MPEG2_MC_EXTERN (altivec)
+ 
++#endif /* __I_WANT_ALTIVEC__ */
++
+ #endif
+--- a/libmpeg2/idct_altivec.c
++++ b/libmpeg2/idct_altivec.c
+@@ -25,6 +25,8 @@
+ 
+ #ifdef ARCH_PPC
+ 
++#ifdef __I_WANT_ALTIVEC__
++
+ #ifdef HAVE_ALTIVEC_H
+ #include <altivec.h>
+ #endif
+@@ -283,4 +285,6 @@ void mpeg2_idct_altivec_init (void)
+     }
+ }
+ 
++#endif /* __I_WANT_ALTIVEC__ */
++
+ #endif
+--- a/libmpeg2/idct.c
++++ b/libmpeg2/idct.c
+@@ -251,11 +251,13 @@ void mpeg2_idct_init (uint32_t accel)
+     } else
+ #endif
+ #ifdef ARCH_PPC
++#ifdef __I_WANT_ALTIVEC__
+     if (accel & MPEG2_ACCEL_PPC_ALTIVEC) {
+ 	mpeg2_idct_copy = mpeg2_idct_copy_altivec;
+ 	mpeg2_idct_add = mpeg2_idct_add_altivec;
+ 	mpeg2_idct_altivec_init ();
+     } else
++#endif /* __I_WANT_ALTIVEC__ */
+ #endif
+ #ifdef ARCH_ALPHA
+     if (accel & MPEG2_ACCEL_ALPHA_MVI) {
+--- a/libmpeg2/motion_comp.c
++++ b/libmpeg2/motion_comp.c
+@@ -43,9 +43,11 @@ void mpeg2_mc_init (uint32_t accel)
+     else
+ #endif
+ #ifdef ARCH_PPC
++#ifdef __I_WANT_ALTIVEC__
+     if (accel & MPEG2_ACCEL_PPC_ALTIVEC)
+ 	mpeg2_mc = mpeg2_mc_altivec;
+     else
++#endif /* __I_WANT_ALTIVEC__ */
+ #endif
+ #ifdef ARCH_ALPHA
+     if (accel & MPEG2_ACCEL_ALPHA)
diff --git a/external/subpack/libs/libmpeg2/patches/102-arm_data_preload_check.patch b/external/subpack/libs/libmpeg2/patches/102-arm_data_preload_check.patch
new file mode 100644
index 0000000..7351b62
--- /dev/null
+++ b/external/subpack/libs/libmpeg2/patches/102-arm_data_preload_check.patch
@@ -0,0 +1,18 @@
+--- a/libmpeg2/motion_comp_arm_s.S
++++ b/libmpeg2/motion_comp_arm_s.S
+@@ -19,6 +19,15 @@
+ @ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ 
+ 
++@ Data preload is supported only by ARM V5TE and above
++
++#if (defined (__ARM_ARCH_2__) || defined (__ARM_ARCH_3__) \
++     || defined (__ARM_ARCH_3M__) || defined (__ARM_ARCH_4__) \
++     || defined (__ARM_ARCH_4T__) || defined (__ARM_ARCH_5__) \
++     || defined (__ARM_ARCH_5T__))
++.macro pld reg
++.endm
++#endif
+ 	.text
+ 
+ @ ----------------------------------------------------------------
diff --git a/external/subpack/libs/libmraa/Makefile b/external/subpack/libs/libmraa/Makefile
new file mode 100644
index 0000000..2f18f93
--- /dev/null
+++ b/external/subpack/libs/libmraa/Makefile
@@ -0,0 +1,92 @@
+#
+# Copyright (C) 2015-2018 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:=libmraa
+PKG_VERSION:=2.2.0
+PKG_RELEASE:=3
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/eclipse/mraa/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=076669bee8423ffef3065735b293a329020be86630fea457174dbfcc67a0554a
+PKG_BUILD_DIR:=$(BUILD_DIR)/mraa-$(PKG_VERSION)
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>, Hirokazu MORIKAWA <morikw2@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_DEPENDS:=swig/host
+CMAKE_INSTALL:=1
+PKG_BUILD_FLAGS:=no-mips16
+PYTHON3_PKG_BUILD:=0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+include ../../lang/python/python3-package.mk
+
+CMAKE_OPTIONS += \
+	-DENABLEEXAMPLES=0 \
+	-DBUILDSWIGNODE=OFF \
+	-DBUILDTESTS=OFF \
+	-DFIRMATA=ON
+
+define Package/libmraa/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=IoT
+  TITLE:=Eclipse MRAA lowlevel IO library
+  URL:=https://projects.eclipse.org/projects/iot.mraa
+endef
+
+define Package/libmraa/Default/description
+  Libmraa is a C/C++ library with bindings to Java, Python and JavaScript to interface
+with the IO on Galileo, Edison & other platforms, with a structured and sane API where
+port names/numbering matches the board that you are on. Use of libmraa does not tie you
+to specific hardware with board detection done at runtime you can create portable code
+that will work across the supported platforms.
+endef
+
+define Package/libmraa
+  $(call Package/libmraa/Default)
+  TITLE:=Eclipse MRAA lowlevel IO C/C++ library
+  DEPENDS:=+libstdcpp +libjson-c @!arc @!armeb @!powerpc @!riscv64
+endef
+
+define Package/libmraa/description
+$(call Package/libmraa/Default/description)
+
+This package contains the C/C++ libraries.
+endef
+
+define Package/libmraa-python3
+  $(call Package/libmraa/Default)
+  TITLE:=Eclipse MRAA lowlevel IO Python3 library
+  DEPENDS:=+libmraa +python3-light
+endef
+
+define Package/libmraa-python3/description
+$(call Package/libmraa/Default/description)
+
+This package contains the Python3 libraries.
+endef
+
+define Package/libmraa/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmraa.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mraa-* $(1)/usr/bin/
+endef
+
+define Package/libmraa-python3/install
+	$(INSTALL_DIR) $(1)/usr/lib/python$(PYTHON3_VERSION)/site-packages
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/python$(PYTHON3_VERSION)/site-packages/* \
+		$(1)/usr/lib/python$(PYTHON3_VERSION)/site-packages/
+endef
+
+$(eval $(call BuildPackage,libmraa))
+$(eval $(call BuildPackage,libmraa-python3))
diff --git a/external/subpack/libs/libmraa/patches/001-mraa-Use-posix-basename.patch b/external/subpack/libs/libmraa/patches/001-mraa-Use-posix-basename.patch
new file mode 100644
index 0000000..97af156
--- /dev/null
+++ b/external/subpack/libs/libmraa/patches/001-mraa-Use-posix-basename.patch
@@ -0,0 +1,40 @@
+From 47c3850cddd63cebd9dc48e411963314449118f1 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Sun, 31 Dec 2023 19:16:35 -0800
+Subject: [PATCH] mraa: Use posix basename
+
+Musl has removed the declaration from string.h [1] which exposes the
+problem especially with clang-17+ compiler where implicit function
+declaration is flagged as error. Use posix basename and make a copy of
+string to operate on to emulate GNU basename behaviour.
+
+[1] https://git.musl-libc.org/cgit/musl/commit/?id=725e17ed6dff4d0cd22487bb64470881e86a92e7
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ src/mraa.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/src/mraa.c
++++ b/src/mraa.c
+@@ -12,6 +12,7 @@
+ #endif
+ 
+ #include <dlfcn.h>
++#include <libgen.h>
+ #include <pwd.h>
+ #include <sched.h>
+ #include <stddef.h>
+@@ -338,9 +339,11 @@ static int
+ mraa_count_iio_devices(const char* path, const struct stat* sb, int flag, struct FTW* ftwb)
+ {
+     // we are only interested in files with specific names
+-    if (fnmatch(IIO_DEVICE_WILDCARD, basename(path), 0) == 0) {
++    char* tmp = strdup(path);
++    if (fnmatch(IIO_DEVICE_WILDCARD, basename(tmp), 0) == 0) {
+         num_iio_devices++;
+     }
++    free(tmp);
+     return 0;
+ }
+ 
diff --git a/external/subpack/libs/libmraa/patches/010-version.patch b/external/subpack/libs/libmraa/patches/010-version.patch
new file mode 100644
index 0000000..4f9cd11
--- /dev/null
+++ b/external/subpack/libs/libmraa/patches/010-version.patch
@@ -0,0 +1,16 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -113,12 +113,7 @@ endif()
+ set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})
+ 
+ # Make a version file containing the current version from git.
+-include (GetGitRevisionDescription)
+-git_describe (VERSION "--tags")
+-if ("x_${VERSION}" STREQUAL "x_GIT-NOTFOUND" OR "x_${VERSION}" STREQUAL "x_HEAD-HASH-NOTFOUND" OR "x_${VERSION}" STREQUAL "x_-128-NOTFOUND")
+-  message (WARNING " - Install git to compile a production libmraa!")
+-  set (VERSION "v2.2.0")
+-endif ()
++set (VERSION "v2.2.0")
+ 
+ message (STATUS "INFO - libmraa Version ${VERSION}")
+ message (STATUS "INFO - cmake Version ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}")
diff --git a/external/subpack/libs/libmraa/patches/020-support_v12.patch b/external/subpack/libs/libmraa/patches/020-support_v12.patch
new file mode 100644
index 0000000..0ac0013
--- /dev/null
+++ b/external/subpack/libs/libmraa/patches/020-support_v12.patch
@@ -0,0 +1,14 @@
+--- a/api/mraa/gpio.hpp
++++ b/api/mraa/gpio.hpp
+@@ -175,7 +175,11 @@ class Gpio
+         v8::Local<v8::Value> argv[] = { SWIGV8_INTEGER_NEW(-1) };
+ #if NODE_MODULE_VERSION >= 0x000D
+         v8::Local<v8::Function> f = v8::Local<v8::Function>::New(v8::Isolate::GetCurrent(), This->m_v8isr);
++#if NODE_MODULE_VERSION >= 72
++        f->Call(SWIGV8_CURRENT_CONTEXT(), SWIGV8_CURRENT_CONTEXT()->Global(), argc, argv);
++#else
+         f->Call(SWIGV8_CURRENT_CONTEXT()->Global(), argc, argv);
++#endif
+ #else
+         This->m_v8isr->Call(SWIGV8_CURRENT_CONTEXT()->Global(), argc, argv);
+ #endif
diff --git a/external/subpack/libs/libmraa/patches/030-gcc10.patch b/external/subpack/libs/libmraa/patches/030-gcc10.patch
new file mode 100644
index 0000000..dad1249
--- /dev/null
+++ b/external/subpack/libs/libmraa/patches/030-gcc10.patch
@@ -0,0 +1,13 @@
+--- a/include/version.h
++++ b/include/version.h
+@@ -11,8 +11,8 @@
+ extern "C" {
+ #endif
+ 
+-const char* gVERSION;
+-const char* gVERSION_SHORT;
++extern const char* gVERSION;
++extern const char* gVERSION_SHORT;
+ 
+ #ifdef __cplusplus
+ }
diff --git a/external/subpack/libs/libmspack/Makefile b/external/subpack/libs/libmspack/Makefile
new file mode 100644
index 0000000..0f8a68f
--- /dev/null
+++ b/external/subpack/libs/libmspack/Makefile
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2021 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See https://www.gnu.org/licenses/gpl-2.0.txt for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libmspack
+PKG_REALVERSION:=0.11alpha
+PKG_VERSION:=0.11_alpha
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_REALVERSION).tar.gz
+PKG_SOURCE_URL:=https://www.cabextract.org.uk/$(PKG_NAME)
+PKG_HASH:=70dd1fb2f0aecc36791b71a1e1840e62173079eadaa081192d1c323a0eeea21b
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_REALVERSION)
+
+PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LIB
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libmspack
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Compressors and decompressors for Microsoft formats
+  DEPENDS:=@TARGET_x86
+  URL:=https://github.com/kyz/libmspack
+endef
+
+define Package/libmspack/description
+  The purpose of libmspack is to provide compressors and decompressors,
+  archivers and dearchivers for Microsoft compression formats: CAB, CHM, WIM,
+  LIT, HLP, KWAJ and SZDD. It is also designed to be easily embeddable,
+  stable, robust and resource-efficient.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/mspack.h \
+		$(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc \
+		$(1)/usr/lib/pkgconfig
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib
+endef
+
+define Package/libmspack/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libmspack))
diff --git a/external/subpack/libs/libnatpmp/Makefile b/external/subpack/libs/libnatpmp/Makefile
new file mode 100644
index 0000000..008f21b
--- /dev/null
+++ b/external/subpack/libs/libnatpmp/Makefile
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2011-2012 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:=libnatpmp
+PKG_VERSION:=20230423
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://miniupnp.tuxfamily.org/files
+PKG_HASH:=0684ed2c8406437e7519a1bd20ea83780db871b3a3a5d752311ba3e889dbfc70
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libnatpmp/Default
+  TITLE:=NAT Port Mapping Protocol (NAT-PMP)
+  URL:=https://miniupnp.tuxfamily.org/libnatpmp.html
+endef
+
+define Package/libnatpmp/Default/description
+  libnatpmp is an attempt to make a portable and fully compliant implementation
+  of the protocol for the client side. It is based on non blocking sockets and
+  all calls of the API are asynchronous. It is therefore very easy to integrate
+  the NAT-PMP code to any event driven code.
+endef
+
+define Package/libnatpmp
+  $(call Package/libnatpmp/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE+= library
+  ABI_VERSION:=1
+endef
+
+define Package/libnatpmp/description
+  $(call Package/libnatpmp/Default/description)
+  This package contains the shared library.
+endef
+
+define Package/natpmpc
+  $(call Package/libnatpmp/Default)
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=Firewall
+  TITLE+= client
+  DEPENDS:=+libnatpmp
+endef
+
+define Package/natpmpc/description
+  $(call Package/libnatpmp/Default/description)
+  This package contains the natpmp client.
+endef
+
+define Package/libnatpmp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnatpmp.so.* $(1)/usr/lib/
+endef
+
+define Package/natpmpc/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/natpmpc $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libnatpmp))
+$(eval $(call BuildPackage,natpmpc))
diff --git a/external/subpack/libs/libnatpmp/patches/010-cmake.patch b/external/subpack/libs/libnatpmp/patches/010-cmake.patch
new file mode 100644
index 0000000..0f71290
--- /dev/null
+++ b/external/subpack/libs/libnatpmp/patches/010-cmake.patch
@@ -0,0 +1,50 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -4,7 +4,10 @@ if(POLICY CMP0048)
+ 	cmake_policy(SET CMP0048 NEW)
+ endif()
+ 
+-project(natpmp)
++project(natpmp C)
++
++set (NATPMP_VERSION 20230423)
++set (NATPMP_API_VERSION 1)
+ 
+ set (NATPMP_SOURCES
+         natpmp.c
+@@ -16,20 +19,33 @@ if (WIN32)
+ endif (WIN32)
+ 
+ # Library itself
+-add_library(natpmp STATIC ${NATPMP_SOURCES})
+-target_include_directories(natpmp PUBLIC ${CMAKE_CURRENT_LIST_DIR})
++add_library(natpmp SHARED ${NATPMP_SOURCES})
++set_target_properties (natpmp PROPERTIES OUTPUT_NAME "natpmp")
++set_target_properties (natpmp PROPERTIES VERSION ${NATPMP_VERSION})
++set_target_properties (natpmp PROPERTIES SOVERSION ${NATPMP_API_VERSION})
+ target_compile_definitions(natpmp PRIVATE -DENABLE_STRNATPMPERR)
++target_include_directories(natpmp PUBLIC ${CMAKE_CURRENT_LIST_DIR})
+ 
+ if (WIN32)
+ 	target_link_libraries(natpmp PUBLIC ws2_32 Iphlpapi)
+ 	target_compile_definitions(natpmp PUBLIC -DNATPMP_STATICLIB)
+ endif (WIN32)
+ 
++install(TARGETS natpmp
++	RUNTIME DESTINATION bin
++	LIBRARY DESTINATION lib${LIB_SUFFIX}
++	ARCHIVE DESTINATION lib${LIB_SUFFIX})
++
+ # Executables
+ add_executable(natpmpc natpmpc.c)
+ target_link_libraries(natpmpc natpmp)
+ 
++install(FILES ${CMAKE_CURRENT_BINARY_DIR}/natpmpc DESTINATION bin)
++
+ add_executable(testgetgateway
+ 	testgetgateway.c
+ 	getgateway.c)
+ target_link_libraries(testgetgateway natpmp)
++
++install(FILES natpmp.h DESTINATION include)
++install(FILES natpmp_declspec.h DESTINATION include)
diff --git a/external/subpack/libs/libndpi/Makefile b/external/subpack/libs/libndpi/Makefile
new file mode 100644
index 0000000..66dfc36
--- /dev/null
+++ b/external/subpack/libs/libndpi/Makefile
@@ -0,0 +1,122 @@
+#
+# Copyright (C) 2017 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:=libndpi
+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:=8f6235ba672d4ac8e4cbebb5611bc712a74587d9d53a649f483e4bcca5b80e58
+PKG_BUILD_DIR:=$(BUILD_DIR)/nDPI-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Banglang Huang <banglang.huang@foxmail.com>, Toni Uhlig <matzeton@googlemail.com>
+PKG_LICENSE:=LGPL-3.0-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_REMOVE_FILES:=autogen.sh
+PKG_BUILD_DEPENDS:=libpcap
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+ifeq ($(LIBNDPI_NDPIREADER),)
+CONFIGURE_ARGS += --with-only-libndpi
+endif
+
+ifneq ($(CONFIG_LIBNDPI_GCRYPT),)
+CONFIGURE_ARGS += --with-local-libgcrypt
+endif
+
+ifneq ($(CONFIG_LIBNDPI_PCRE),)
+CONFIGURE_ARGS += --with-pcre2
+endif
+
+ifneq ($(CONFIG_LIBNDPI_MAXMINDDB),)
+CONFIGURE_ARGS += --with-maxminddb
+endif
+
+define Package/libndpi
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Library for deep-packet inspection
+  URL:=https://github.com/ntop/nDPI
+  DEPENDS:=+LIBNDPI_GCRYPT:libgcrypt +LIBNDPI_PCRE:libpcre2 +LIBNDPI_MAXMINDDB:libmaxminddb +LIBNDPI_NDPIREADER:libpcap
+endef
+
+define Package/libndpi/description
+  nDPI is an open source LGPLv3 library for deep-packet inspection.
+  Based on OpenDPI it includes ntop extensions.
+endef
+
+define Package/libndpi/config
+config LIBNDPI_NDPIREADER
+	bool "Enable ndpiReader"
+	depends on PACKAGE_libndpi
+	default n
+	help
+	  This option builds and installs ndpiReader,
+	  an example application that show some nDPI features.
+
+config LIBNDPI_GCRYPT
+	bool "Use host GCrypt"
+	depends on PACKAGE_libndpi
+	default n
+	help
+	  This option enables the use of libgcrypt to decrypt QUIC client hello's.
+	  If disabled, nDPI will use a builtin lightweight libgcrypt version to
+	  decrypt QUIC client hello's.
+	  Disabled by default.
+
+config LIBNDPI_PCRE
+	bool "pcre support"
+	depends on PACKAGE_libndpi
+	default n
+	help
+	  This option enables the use of regular expressions.
+	  Used by nDPI to detect RCE injection.
+	  Disabled by default.
+
+config LIBNDPI_MAXMINDDB
+	bool "Maxmind GeoIP support"
+	depends on PACKAGE_libndpi
+	default n
+	help
+	  This options enables geographical information processing
+	  and serialization based on IP addresses.
+	  Disabled by default.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/ndpi
+	$(CP) $(PKG_BUILD_DIR)/src/include/*.h \
+		$(1)/usr/include/ndpi/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/src/lib/libndpi.so* \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_BUILD_DIR)/libndpi.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libndpi/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_BUILD_DIR)/src/lib/libndpi.so* \
+		$(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/bin/
+ifneq ($(LIBNDPI_NDPIREADER),)
+	$(CP) $(PKG_BUILD_DIR)/example/ndpiReader \
+		$(1)/usr/bin/
+endif
+endef
+
+$(eval $(call BuildPackage,libndpi))
diff --git a/external/subpack/libs/libndpi/patches/001-Move-from-PCRE-to-PCRE2.patch b/external/subpack/libs/libndpi/patches/001-Move-from-PCRE-to-PCRE2.patch
new file mode 100644
index 0000000..731d1b2
--- /dev/null
+++ b/external/subpack/libs/libndpi/patches/001-Move-from-PCRE-to-PCRE2.patch
@@ -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
diff --git a/external/subpack/libs/libnet-1.2.x/Makefile b/external/subpack/libs/libnet-1.2.x/Makefile
new file mode 100644
index 0000000..7318d5e
--- /dev/null
+++ b/external/subpack/libs/libnet-1.2.x/Makefile
@@ -0,0 +1,66 @@
+#
+# Copyright (C) 2015 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:=libnet
+PKG_VERSION:=1.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/libnet/libnet/releases/download/v$(PKG_VERSION)
+PKG_HASH:=ad1e2dd9b500c58ee462acd839d0a0ea9a2b9248a1287840bc601e774fb6b28f
+
+PKG_MAINTAINER:=Mislav Novakovic <mislav.novakovic@sartura.hr>
+PKG_LICENSE:=GPL-2.0
+PKG_CPE_ID:=cpe:/a:libnet_project:libnet
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libnet-1.2.x
+ SECTION:=libs
+ CATEGORY:=Libraries
+ DEPENDS:=+libpcap
+ TITLE:=Low-level packet creation library
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--with-pic
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/libnet-config $(STAGING_DIR)/usr/bin
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/libnet-config $(2)/bin/
+
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libnet.h $(STAGING_DIR)/usr/include
+
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/include/libnet
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libnet/*.h $(STAGING_DIR)/usr/include/libnet
+
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/include/libnet
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libnet/libnet-*.h $(STAGING_DIR)/usr/include/libnet
+
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnet.{a,la,so*} $(STAGING_DIR)/usr/lib
+
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnet.pc $(STAGING_DIR)/usr/lib/pkgconfig
+endef
+
+define Package/libnet-1.2.x/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnet.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libnet-1.2.x))
diff --git a/external/subpack/libs/libnetconf2/Makefile b/external/subpack/libs/libnetconf2/Makefile
new file mode 100644
index 0000000..2b201f2
--- /dev/null
+++ b/external/subpack/libs/libnetconf2/Makefile
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2017 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:=libnetconf2
+PKG_VERSION:=2.0.24
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/CESNET/libnetconf2/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=78ffa0bd85823abd321a1dbb09c1ead36612f2a12049638a14bb081567f86ade
+
+PKG_MAINTAINER:=Jakov Smolic <jakov.smolic@sartura.hr>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libnetconf2
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=NETCONF library
+  URL:=https://github.com/CESNET/libnetconf2
+  DEPENDS:= +libyang +libssh +libopenssl +libpthread
+endef
+
+define Package/libnetconf2/description
+ libnetconf2 is the NETCONF library in C intended for building NETCONF clients and servers.
+
+ libnetconf2 provides basic functions to connect NETCONF client and server to each other via
+ SSH, to send and receive NETCONF messages. NETCONF datastore implementation is not included.
+endef
+
+define Package/libnetconf2/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnetconf2.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libnetconf2))
diff --git a/external/subpack/libs/libnetconf2/patches/001-cmake_not_updated.patch b/external/subpack/libs/libnetconf2/patches/001-cmake_not_updated.patch
new file mode 100644
index 0000000..08f5343
--- /dev/null
+++ b/external/subpack/libs/libnetconf2/patches/001-cmake_not_updated.patch
@@ -0,0 +1,11 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -235,7 +235,7 @@ endif()
+ # dependencies - libssh
+ if(ENABLE_SSH)
+     find_package(LibSSH 0.7.1 REQUIRED)
+-    if(LIBSSH_VERSION VERSION_EQUAL 0.9.3 OR LIBSSH_VERSION VERSION_EQUAL 0.9.4)
++    if(LIBSSH_VERSION VERSION_EQUAL 0.9.x)
+         message(FATAL_ERROR "LibSSH ${LIBSSH_VERSION} includes regression bugs and libnetconf2 will NOT work properly, try to use another version")
+     endif()
+ 
diff --git a/external/subpack/libs/libnetfilter-acct/Makefile b/external/subpack/libs/libnetfilter-acct/Makefile
new file mode 100644
index 0000000..272295e
--- /dev/null
+++ b/external/subpack/libs/libnetfilter-acct/Makefile
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2009-2015 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:=libnetfilter_acct
+PKG_VERSION:=1.0.3
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://netfilter.org/projects/libnetfilter_acct/files
+PKG_HASH:=4250ceef3efe2034f4ac05906c3ee427db31b9b0a2df41b2744f4bf79a959a1a
+
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Nicolas Thill <nico@openwrt.org>
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libnetfilter-acct
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=API to extended accounting infrastructure
+  URL:=http://www.netfilter.org/projects/libnetfilter_acct/
+  DEPENDS:=+libmnl
+endef
+
+define Package/libnetfilter-acct/description
+ libnetfilter_acct is a userspace library providing a programming interface
+ (API) to the extended accounting infrastructure.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+	--enable-static \
+	--enable-shared \
+
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/libnetfilter_acct \
+		$(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libnetfilter_acct*.{so*,a,la} \
+		$(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnetfilter_acct.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libnetfilter-acct/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnetfilter_acct.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libnetfilter-acct))
diff --git a/external/subpack/libs/libnetfilter-cthelper/Makefile b/external/subpack/libs/libnetfilter-cthelper/Makefile
new file mode 100644
index 0000000..934afba
--- /dev/null
+++ b/external/subpack/libs/libnetfilter-cthelper/Makefile
@@ -0,0 +1,73 @@
+#
+# Copyright (C) 2009-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:=libnetfilter_cthelper
+PKG_VERSION:=1.0.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:= \
+	http://www.netfilter.org/projects/libnetfilter_cthelper/files/ \
+	ftp://ftp.netfilter.org/pub/libnetfilter_cthelper/
+PKG_HASH:=07618e71c4d9a6b6b3dc1986540486ee310a9838ba754926c7d14a17d8fccf3d
+
+PKG_FIXUP:=autoreconf
+PKG_LICENSE:=GPL-2.0+
+PKG_CPE_ID:=cpe:/a:netfilter:libnetfilter_cthelper
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libnetfilter-cthelper
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libmnl
+  TITLE:=API to the in-kernel connection tracking helper infrastructure
+  URL:=http://www.netfilter.org/projects/libnetfilter_cthelper/
+  ABI_VERSION:=0
+endef
+
+define Package/libnetfilter-cthelper/description
+ libnetfilter_cthelper is a userspace library providing a programming
+ interface (API) to the in-kernel connection tracking helpers. 
+ This library is currently used by conntrack-tools.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+	--enable-static \
+	--enable-shared \
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/libnetfilter_cthelper
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/libnetfilter_cthelper/*.h \
+		$(1)/usr/include/libnetfilter_cthelper/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libnetfilter_cthelper.{so*,a,la} \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnetfilter_cthelper.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libnetfilter-cthelper/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libnetfilter_cthelper.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libnetfilter-cthelper))
diff --git a/external/subpack/libs/libnetfilter-cttimeout/Makefile b/external/subpack/libs/libnetfilter-cttimeout/Makefile
new file mode 100644
index 0000000..8a4b59b
--- /dev/null
+++ b/external/subpack/libs/libnetfilter-cttimeout/Makefile
@@ -0,0 +1,73 @@
+#
+# Copyright (C) 2009-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:=libnetfilter_cttimeout
+PKG_VERSION:=1.0.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:= \
+	http://www.netfilter.org/projects/libnetfilter_cttimeout/files/ \
+	ftp://ftp.netfilter.org/pub/libnetfilter_cttimeout/
+PKG_HASH:=aeab12754f557cba3ce2950a2029963d817490df7edb49880008b34d7ff8feba
+
+PKG_FIXUP:=autoreconf
+PKG_LICENSE:=GPL-2.0+
+PKG_CPE_ID:=cpe:/a:netfilter:libnetfilter_cttimeout
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libnetfilter-cttimeout
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libmnl
+  TITLE:=API to the in-kernel connection tracking timeout infrastructure
+  URL:=http://www.netfilter.org/projects/libnetfilter_cttimeout/
+  ABI_VERSION:=1
+endef
+
+define Package/libnetfilter-cttimeout/description
+ libnetfilter_cttimeout is a userspace library providing a programming
+ interface (API) to the in-kernel connection tracking timeout handling.
+ This library is currently used by conntrack-tools.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+	--enable-static \
+	--enable-shared \
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/libnetfilter_cttimeout
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/libnetfilter_cttimeout/*.h \
+		$(1)/usr/include/libnetfilter_cttimeout/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libnetfilter_cttimeout.{so*,a,la} \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnetfilter_cttimeout.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libnetfilter-cttimeout/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libnetfilter_cttimeout.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libnetfilter-cttimeout))
diff --git a/external/subpack/libs/libnetfilter-log/Makefile b/external/subpack/libs/libnetfilter-log/Makefile
new file mode 100644
index 0000000..f29e3cc
--- /dev/null
+++ b/external/subpack/libs/libnetfilter-log/Makefile
@@ -0,0 +1,75 @@
+#
+# Copyright (C) 2014 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:=libnetfilter_log
+PKG_VERSION:=1.0.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:= \
+	http://www.netfilter.org/projects/libnetfilter_log/files/ \
+	ftp://ftp.netfilter.org/pub/libnetfilter_log/
+PKG_HASH:=e3f408575614d849e4726b45e90c7ebb0e6744b04859555a9ce6ec40744ffeea
+PKG_MAINTAINER:=Yousong Zhou <yszhou4tech@gmail.com>
+
+PKG_FIXUP:=autoreconf
+PKG_LICENSE:=GPL-2.0+
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libnetfilter-log
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libnfnetlink +kmod-nfnetlink-log +libmnl
+  TITLE:=API to receive to-be-logged packets from the kernel nfnetlink_log subsystem
+  URL:=http://www.netfilter.org/projects/libnetfilter_log/
+  ABI_VERSION:=1
+endef
+
+define Package/libnetfilter-log/description
+ libnetfilter_log is a userspace library providing interface to packets that
+ have been logged by the kernel packet filter. It is is part of a system that
+ deprecates the old syslog/dmesg based packet logging. This library has been
+ previously known as libnfnetlink_log.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+	--enable-static \
+	--enable-shared \
+	--without-ipulog \
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/libnetfilter_log
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/libnetfilter_log/*.h \
+		$(1)/usr/include/libnetfilter_log/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libnetfilter_log.{so*,a,la} \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnetfilter_log.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libnetfilter-log/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libnetfilter_log.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libnetfilter-log))
diff --git a/external/subpack/libs/libnetfilter-queue/Makefile b/external/subpack/libs/libnetfilter-queue/Makefile
new file mode 100644
index 0000000..5027532
--- /dev/null
+++ b/external/subpack/libs/libnetfilter-queue/Makefile
@@ -0,0 +1,73 @@
+#
+# Copyright (C) 2009-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:=libnetfilter_queue
+PKG_VERSION:=1.0.5
+PKG_RELEASE:=4
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://www.netfilter.org/projects/libnetfilter_queue/files
+PKG_HASH:=f9ff3c11305d6e03d81405957bdc11aea18e0d315c3e3f48da53a24ba251b9f5
+
+PKG_FIXUP:=autoreconf
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:netfilter:libnetfilter_queue
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libnetfilter-queue
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libmnl +libnfnetlink
+  TITLE:=Userspace API to packets queued by kernel packet filter
+  URL:=https://www.netfilter.org/projects/libnetfilter_queue/
+  ABI_VERSION:=1
+endef
+
+define Package/libnetfilter-queue/description
+ libnetfilter_queue is a userspace library providing a programming
+ interface (API) to packets that have been queued by the kernel
+ packet filter.
+endef
+
+TARGET_CFLAGS += $(FPIC) -D_GNU_SOURCE=1
+
+CONFIGURE_ARGS += \
+	--enable-static \
+	--enable-shared \
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/libnetfilter_queue
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/libnetfilter_queue/*.h \
+		$(1)/usr/include/libnetfilter_queue/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libnetfilter_queue.{so*,a,la} \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnetfilter_queue.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libnetfilter-queue/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libnetfilter_queue.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libnetfilter-queue))
diff --git a/external/subpack/libs/libnetfilter-queue/patches/0001-src-add-pkt_buff-function-for-ICMP.patch b/external/subpack/libs/libnetfilter-queue/patches/0001-src-add-pkt_buff-function-for-ICMP.patch
new file mode 100644
index 0000000..7d8346c
--- /dev/null
+++ b/external/subpack/libs/libnetfilter-queue/patches/0001-src-add-pkt_buff-function-for-ICMP.patch
@@ -0,0 +1,100 @@
+From 662c8f44d53492d2e0ebd430dadef12d580ec330 Mon Sep 17 00:00:00 2001
+From: Etan Kissling <etan_kissling@apple.com>
+Date: Tue, 19 Jan 2021 16:05:39 +0100
+Subject: [PATCH] src: add pkt_buff function for ICMP
+
+Add support for processing ICMP packets using pkt_buff, similar to
+existing library support for TCP and UDP.
+
+Signed-off-by: Etan Kissling <etan_kissling@apple.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ include/libnetfilter_queue/Makefile.am        |  1 +
+ .../libnetfilter_queue_icmp.h                 |  8 ++++
+ src/Makefile.am                               |  1 +
+ src/extra/icmp.c                              | 48 +++++++++++++++++++
+ 4 files changed, 58 insertions(+)
+ create mode 100644 include/libnetfilter_queue/libnetfilter_queue_icmp.h
+ create mode 100644 src/extra/icmp.c
+
+--- a/include/libnetfilter_queue/Makefile.am
++++ b/include/libnetfilter_queue/Makefile.am
+@@ -1,5 +1,6 @@
+ pkginclude_HEADERS = libnetfilter_queue.h	\
+ 		     linux_nfnetlink_queue.h	\
++		     libnetfilter_queue_icmp.h	\
+ 		     libnetfilter_queue_ipv4.h	\
+ 		     libnetfilter_queue_ipv6.h	\
+ 		     libnetfilter_queue_tcp.h	\
+--- /dev/null
++++ b/include/libnetfilter_queue/libnetfilter_queue_icmp.h
+@@ -0,0 +1,8 @@
++#ifndef _LIBNFQUEUE_ICMP_H_
++#define _LIBNFQUEUE_ICMP_H_
++
++struct pkt_buff;
++
++struct icmphdr *nfq_icmp_get_hdr(struct pkt_buff *pktb);
++
++#endif
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -31,6 +31,7 @@ libnetfilter_queue_la_LDFLAGS = -Wc,-nos
+ libnetfilter_queue_la_SOURCES = libnetfilter_queue.c	\
+ 				nlmsg.c			\
+ 				extra/checksum.c	\
++				extra/icmp.c		\
+ 				extra/ipv6.c		\
+ 				extra/tcp.c		\
+ 				extra/ipv4.c		\
+--- /dev/null
++++ b/src/extra/icmp.c
+@@ -0,0 +1,48 @@
++/*
++ * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.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 Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
++ */
++
++#include <stdio.h>
++#define _GNU_SOURCE
++#include <netinet/ip_icmp.h>
++
++#include <libnetfilter_queue/libnetfilter_queue_icmp.h>
++
++#include "internal.h"
++
++/**
++ * \defgroup icmp ICMP helper functions
++ * @{
++ */
++
++/**
++ * nfq_icmp_get_hdr - get the ICMP header.
++ * \param pktb: pointer to user-space network packet buffer
++ * \returns validated pointer to the ICMP header or NULL if the ICMP header was
++ * not set or if a minimal length check fails.
++ * \note You have to call nfq_ip_set_transport_header() or
++ * nfq_ip6_set_transport_header() first to set the ICMP header.
++ */
++EXPORT_SYMBOL
++struct icmphdr *nfq_icmp_get_hdr(struct pkt_buff *pktb)
++{
++	if (pktb->transport_header == NULL)
++		return NULL;
++
++	/* No room for the ICMP header. */
++	if (pktb_tail(pktb) - pktb->transport_header < sizeof(struct icmphdr))
++		return NULL;
++
++	return (struct icmphdr *)pktb->transport_header;
++}
++
++/**
++ * @}
++ */
diff --git a/external/subpack/libs/libnetfilter-queue/patches/0002-src-fix-IPv6-header-handling.patch b/external/subpack/libs/libnetfilter-queue/patches/0002-src-fix-IPv6-header-handling.patch
new file mode 100644
index 0000000..83713f3
--- /dev/null
+++ b/external/subpack/libs/libnetfilter-queue/patches/0002-src-fix-IPv6-header-handling.patch
@@ -0,0 +1,52 @@
+From 51f25df304aeaa6c1b02ef7456a61278ee70c102 Mon Sep 17 00:00:00 2001
+From: Etan Kissling <etan_kissling@apple.com>
+Date: Tue, 9 Feb 2021 23:51:33 +0100
+Subject: [PATCH] src: fix IPv6 header handling
+
+This corrects issues in IPv6 header handling that sometimes resulted
+in an endless loop.
+
+Signed-off-by: Etan Kissling <etan_kissling@apple.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ src/extra/ipv6.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/src/extra/ipv6.c
++++ b/src/extra/ipv6.c
+@@ -67,10 +67,19 @@ int nfq_ip6_set_transport_header(struct
+ 	uint8_t nexthdr = ip6h->ip6_nxt;
+ 	uint8_t *cur = (uint8_t *)ip6h + sizeof(struct ip6_hdr);
+ 
+-	while (nexthdr != target) {
++	while (nexthdr == IPPROTO_HOPOPTS ||
++	       nexthdr == IPPROTO_ROUTING ||
++	       nexthdr == IPPROTO_FRAGMENT ||
++	       nexthdr == IPPROTO_AH ||
++	       nexthdr == IPPROTO_NONE ||
++	       nexthdr == IPPROTO_DSTOPTS) {
+ 		struct ip6_ext *ip6_ext;
+ 		uint32_t hdrlen;
+ 
++		/* Extension header was requested, we're done. */
++		if (nexthdr == target)
++			break;
++
+ 		/* No more extensions, we're done. */
+ 		if (nexthdr == IPPROTO_NONE) {
+ 			cur = NULL;
+@@ -107,11 +116,13 @@ int nfq_ip6_set_transport_header(struct
+ 		} else if (nexthdr == IPPROTO_AH)
+ 			hdrlen = (ip6_ext->ip6e_len + 2) << 2;
+ 		else
+-			hdrlen = ip6_ext->ip6e_len;
++			hdrlen = (ip6_ext->ip6e_len + 1) << 3;
+ 
+ 		nexthdr = ip6_ext->ip6e_nxt;
+ 		cur += hdrlen;
+ 	}
++	if (nexthdr != target)
++		cur = NULL;
+ 	pktb->transport_header = cur;
+ 	return cur ? 1 : 0;
+ }
diff --git a/external/subpack/libs/libnopoll/Makefile b/external/subpack/libs/libnopoll/Makefile
new file mode 100644
index 0000000..84c92ce
--- /dev/null
+++ b/external/subpack/libs/libnopoll/Makefile
@@ -0,0 +1,58 @@
+#
+# libnopoll - Makefile for noPoll C WebSocket library
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nopoll
+PKG_VERSION:=0.4.6
+PKG_RELEASE:=2
+
+PKG_SOURCE_URL:=https://codeload.github.com/ASPLes/nopoll/tar.gz/$(PKG_VERSION)?
+PKG_SOURCE:=nopoll-$(PKG_VERSION).tar.gz
+PKG_HASH:=16eae3885d572495ba1f22d85fa9032139c761fb21ef1d80205039acd3143f5a
+PKG_BUILD_DIR:=$(BUILD_DIR)/nopoll-$(PKG_VERSION)
+
+PKG_MAINTAINER:=John Clark <inindev@gmail.com>
+PKG_LICENSE:=LGPL-2.1
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libnopoll
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libopenssl
+  TITLE:=noPoll C WebSocket Library
+  URL:=https://www.aspl.es/nopoll
+endef
+
+define Package/libnopoll/description
+  This package contains the noPoll C WebSocket library.
+endef
+
+TARGET_LDFLAGS += -lcrypto -lpthread
+
+CONFIGURE_ARGS += \
+	--enable-nopoll-log=no \
+	--enable-nopoll-doc=no
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/{lib,include}
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnopoll.{a,so*} $(1)/usr/lib/
+endef
+
+define Package/libnopoll/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnopoll.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libnopoll))
diff --git a/external/subpack/libs/libnopoll/patches/010-openssl-deprecated.patch b/external/subpack/libs/libnopoll/patches/010-openssl-deprecated.patch
new file mode 100644
index 0000000..c4c640d
--- /dev/null
+++ b/external/subpack/libs/libnopoll/patches/010-openssl-deprecated.patch
@@ -0,0 +1,81 @@
+--- a/src/nopoll.c
++++ b/src/nopoll.c
+@@ -868,9 +868,11 @@ void nopoll_cleanup_library (void)
+ {
+ 	
+ 	if (__nopoll_tls_was_init) {
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ 		EVP_cleanup ();
+ 		CRYPTO_cleanup_all_ex_data ();
+ 		ERR_free_strings ();
++#endif
+ 
+ 		/* notify the library isn't initialized */
+ 		__nopoll_tls_was_init = nopoll_false;
+--- a/src/nopoll_conn.c
++++ b/src/nopoll_conn.c
+@@ -1380,7 +1380,9 @@ noPollConn * nopoll_conn_tls_new (noPoll
+ 	/* init ssl ciphers and engines */
+ 	if (! __nopoll_tls_was_init) {
+ 		__nopoll_tls_was_init = nopoll_true;
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ 		SSL_library_init ();
++#endif
+ 	} /* end if */
+ 
+ 	/* call common implementation */
+@@ -1426,7 +1428,9 @@ noPollConn * nopoll_conn_tls_new6 (noPol
+ 	/* init ssl ciphers and engines */
+ 	if (! __nopoll_tls_was_init) {
+ 		__nopoll_tls_was_init = nopoll_true;
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ 		SSL_library_init ();
++#endif
+ 	} /* end if */
+ 
+ 	/* call common implementation */
+@@ -1495,7 +1499,9 @@ noPollConn * nopoll_conn_tls_new_with_so
+ 	/* init ssl ciphers and engines */
+ 	if (! __nopoll_tls_was_init) {
+ 		__nopoll_tls_was_init = nopoll_true;
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ 		SSL_library_init ();
++#endif
+ 	} /* end if */
+ 
+ 	/* call common implementation */
+@@ -4755,7 +4761,9 @@ nopoll_bool __nopoll_conn_accept_complet
+ 		/* init ssl ciphers and engines */
+ 		if (! __nopoll_tls_was_init) {
+ 			__nopoll_tls_was_init = nopoll_true;
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
+ 			SSL_library_init ();
++#endif
+ 		} /* end if */
+ 
+ 		/* now configure chainCertificate */
+--- a/src/nopoll_decl.h
++++ b/src/nopoll_decl.h
+@@ -511,20 +511,18 @@ typedef enum {
+ 	 * established with this method will only understand this
+ 	 * method.
+ 	 */
+-	NOPOLL_METHOD_TLSV1_1     = 5
++	NOPOLL_METHOD_TLSV1_1     = 5,
+ #endif
+ #if defined(NOPOLL_HAVE_TLSv12_ENABLED)
+-	,
+ 	/** 
+ 	 * @brief Allows to define TLSv1.2 as SSL protocol used by the
+ 	 * client or server connection. A connection/listener
+ 	 * established with this method will only understand this
+ 	 * method.
+ 	 */
+-	NOPOLL_METHOD_TLSV1_2     = 6
++	NOPOLL_METHOD_TLSV1_2     = 6,
+ #endif
+ #if defined(NOPOLL_HAVE_TLS_FLEXIBLE_ENABLED)
+-	,
+ 	/** 
+ 	 * @brief Allows to define TLS flexible negotiation where the
+ 	 * highest version available will be negotiated by both
diff --git a/external/subpack/libs/libnpupnp/Makefile b/external/subpack/libs/libnpupnp/Makefile
new file mode 100644
index 0000000..85dc686
--- /dev/null
+++ b/external/subpack/libs/libnpupnp/Makefile
@@ -0,0 +1,51 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libnpupnp
+PKG_VERSION:=6.1.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://www.lesbonscomptes.com/upmpdcli/downloads
+PKG_HASH:=80c3d5adc388e59057be52c4c33d7708efe05318487c09e342e7a1f4a83aa792
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_DEPENDS:=libmicrohttpd
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libnpupnp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libstdcpp +libexpat +libcurl +libmicrohttpd
+  TITLE:=A C++ base UPnP library
+  URL:=https://framagit.org/medoc92/npupnp
+endef
+
+define Package/libnpupnp/description
+npupnp (new pupnp or not pupnp ?) is an UPnP library derived from the
+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/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnpupnp.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnpupnp.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libnpupnp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnpupnp.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libnpupnp))
diff --git a/external/subpack/libs/libnvme/Makefile b/external/subpack/libs/libnvme/Makefile
new file mode 100644
index 0000000..50a6aeb
--- /dev/null
+++ b/external/subpack/libs/libnvme/Makefile
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2023 Luca Barbato
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libnvme
+PKG_VERSION:=1.9
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/linux-nvme/libnvme/archive/refs/tags/v$(PKG_VERSION)
+PKG_HASH:=455867060d2b7563eab59fe21779dff469d98465028997178c7efbe4b8763206
+
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=LICENSE
+PKG_MAINTAINER:=Luca Barbato <lu_zero@luminem.org>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libnvme
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=C Library for NVM Express on Linux
+  URL:=https://github.com/linux-nvme/libnvme
+  DEPENDS:=+libjson-c
+endef
+
+define Package/libnvme/description
+  This is the libnvme development C library. libnvme provides type
+  definitions for NVMe specification structures, enumerations, and
+  bit fields, helper functions to construct, dispatch, and decode
+  commands and payloads, and utilities to connect, scan, and manage
+  nvme devices on a Linux system.
+endef
+
+MESON_ARGS += \
+	-Dopenssl=disabled -Dpython=disabled -Dkeyutils=disabled
+
+define Package/libnvme/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnvme*.so* $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/nvme
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/nvme/*.h $(1)/usr/include/nvme
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnvme*.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnvme*.pc $(1)/usr/lib/pkgconfig/
+endef
+
+$(eval $(call BuildPackage,libnvme))
diff --git a/external/subpack/libs/libogg/Makefile b/external/subpack/libs/libogg/Makefile
new file mode 100644
index 0000000..93b502a
--- /dev/null
+++ b/external/subpack/libs/libogg/Makefile
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2008-2014 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:=libogg
+PKG_VERSION:=1.3.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://downloads.xiph.org/releases/ogg/
+PKG_HASH:=c4d91be36fc8e54deae7575241e03f4211eb102afb3fc0775fbbc1b740016705
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libogg
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libogg
+  URL:=https://xiph.org/ogg/
+  ABI_VERSION:=0
+endef
+
+define Package/libogg/description
+Ogg project codecs use the Ogg bitstream format to arrange the raw,
+compressed bitstream into a more robust, useful form.  For example,
+the Ogg bitstream makes seeking, time stamping and error recovery
+possible, as well as mixing several sepearate, concurrent media
+streams into a single physical bitstream.
+endef
+
+TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/ogg/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/ogg/* $(1)/usr/include/ogg/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.{so*,a,la} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DIR) $(1)/usr/share/aclocal/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/aclocal/* $(1)/usr/share/aclocal/
+endef
+
+define Package/libogg/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libogg.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libogg))
diff --git a/external/subpack/libs/liboil/Makefile b/external/subpack/libs/liboil/Makefile
new file mode 100644
index 0000000..a8ef2c4
--- /dev/null
+++ b/external/subpack/libs/liboil/Makefile
@@ -0,0 +1,70 @@
+# 
+# Copyright (C) 2007-2014 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:=liboil
+PKG_VERSION:=0.3.17
+PKG_RELEASE:=3
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://liboil.freedesktop.org/download/
+PKG_HASH:=105f02079b0b50034c759db34b473ecb5704ffa20a5486b60a8b7698128bfc69
+
+PKG_LICENSE:=FREE
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/liboil
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=simple functions optimized for various CPUs
+  URL:=http://liboil.freedesktop.org/wiki/
+  MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+  DEPENDS:=+librt
+endef
+
+define Package/liboil/description
+  Liboil is a library of simple functions that are optimized for various CPUs.
+  These functions are generally loops implementing simple algorithms, such as
+  converting an array of N integers to floating-point numbers or multiplying
+  and summing an array of N numbers. Such functions are candidates for significant
+  optimization using various techniques, especially by using extended instructions
+  provided by modern CPUs (Altivec, MMX, SSE, etc.).
+endef
+
+CONFIGURE_ARGS += \
+	--with-pic \
+	--enable-shared \
+	--enable-static \
+	--disable-glib
+
+# XXX: VFP_CFLAGS is set to '-mfpu=vfp' on arm by configure, but that breaks 
+# final linking stages, so override it until we find why
+MAKE_FLAGS += \
+	VFP_CFLAGS="" \
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/liboil-0.3/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liboil-0.3.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/liboil-0.3.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/liboil/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liboil-0.3.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,liboil))
diff --git a/external/subpack/libs/libopen62541/Config.in b/external/subpack/libs/libopen62541/Config.in
new file mode 100644
index 0000000..83539a4
--- /dev/null
+++ b/external/subpack/libs/libopen62541/Config.in
@@ -0,0 +1,118 @@
+menu "Configuration"
+        depends on PACKAGE_libopen62541
+
+config LIBOPEN62541_UA_ENABLE_SUBSCRIPTIONS
+	bool "Enable subscriptions support"
+	default y
+
+config LIBOPEN62541_UA_ENABLE_SUBSCRIPTIONS_EVENTS
+        bool "Use events for subscriptions (EXPERIMENTAL)"
+	depends on LIBOPEN62541_UA_ENABLE_SUBSCRIPTIONS && (LIBOPEN62541_NAMESPACEZERO_FULL || LIBOPEN62541_NAMESPACEZERO_REDUCED)
+
+config LIBOPEN62541_UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS
+        bool "Use alarms and conditions for subscriptions (EXPERIMENTAL)"
+        depends on LIBOPEN62541_UA_ENABLE_SUBSCRIPTIONS_EVENTS && LIBOPEN62541_NAMESPACEZERO_FULL
+
+config LIBOPEN62541_UA_ENABLE_METHODCALLS
+	bool "Enable the Method service set"
+	default y
+
+config LIBOPEN62541_UA_ENABLE_PARSING
+	bool "Enable parsing human readable formats of builtin data types"
+	default y
+
+config LIBOPEN62541_UA_ENABLE_NODEMANAGEMENT
+        bool "Enable dynamic addition and removal of nodes at runtime"
+        default y
+
+config LIBOPEN62541_UA_ENABLE_IMMUTABLE_NODES
+        bool "Enable immutable nodes"
+        default y
+
+config LIBOPEN62541_UA_ENABLE_DISCOVERY
+        bool "Enable Discovery Service (LDS)"
+        default y
+
+config LIBOPEN62541_UA_ENABLE_DISCOVERY_MULTICAST
+        bool "Enable Discovery Service with multicast support (LDS-ME)"
+        default y
+	depends on LIBOPEN62541_UA_ENABLE_DISCOVERY
+
+config LIBOPEN62541_UA_ENABLE_DISCOVERY_SEMAPHORE
+        bool "Enable Discovery Semaphore support"
+        default y
+	depends on LIBOPEN62541_UA_ENABLE_DISCOVERY
+
+choice
+        prompt "Encryption library"
+        default LIBOPEN62541_NOENCRYPTION
+
+        config LIBOPEN62541_NOENCRYPTION
+                bool "No encryption"
+
+        config LIBOPEN62541_MBDEDTLS
+                bool "Encryption support using mbed TLS"
+
+        config LIBOPEN62541_OPENSSL
+                bool "Encryption support using OpenSSL"
+endchoice
+
+config LIBOPEN62541_UA_ENABLE_ENCRYPTION_TPM2
+	bool "Enable TPM support"
+	depends on LIBOPEN62541_UA_ENABLE_PUBSUB_ENCRYPTION
+
+choice
+	prompt "Namespace zero definition"
+
+	default LIBOPEN62541_NAMESPACEZERO_FULL
+
+	config LIBOPEN62541_NAMESPACEZERO_FULL
+		bool "Full namespace zero"
+
+	config LIBOPEN62541_NAMESPACEZERO_REDUCED
+		bool "Small namespace zero still passing CTT"
+
+	config LIBOPEN62541_NAMESPACEZERO_MINIMAL
+		bool "Barebones namespace zero"
+
+endchoice
+
+config LIBOPEN62541_UA_ENABLE_TYPEDESCRIPTION
+        bool "Add the type and member names to the UA_DataType structure"
+        default y
+
+config LIBOPEN62541_UA_ENABLE_STATUSCODE_DESCRIPTIONS
+        bool "Compile the human-readable name of the StatusCodes into the binary"
+        default y
+
+config LIBOPEN62541_UA_ENABLE_HISTORIZING
+	bool "Enable historical access"
+
+config LIBOPEN62541_UA_ENABLE_PUBSUB
+        bool "Enable OPC UA PubSub support (EXPERIMENTAL)"
+
+config LIBOPEN62541_UA_ENABLE_PUBSUB_DELTAFRAMES
+        bool "PubSub messages differentiate between keyframe and deltaframe messages"
+	depends on LIBOPEN62541_UA_ENABLE_PUBSUB
+
+config LIBOPEN62541_UA_ENABLE_PUBSUB_FILE_CONFIG
+        bool "Enable loading OPC UA PubSub configuration from File/ByteString"
+	depends on LIBOPEN62541_UA_ENABLE_PUBSUB
+
+config LIBOPEN62541_UA_ENABLE_PUBSUB_INFORMATIONMODEL
+        bool "Enable the information model representation of the PubSub configuration"
+	depends on LIBOPEN62541_UA_ENABLE_PUBSUB && (LIBOPEN62541_NAMESPACEZERO_FULL || LIBOPEN62541_NAMESPACEZERO_REDUCED)
+
+config LIBOPEN62541_UA_ENABLE_PUBSUB_MONITORING
+        bool "Enable the experimental PubSub monitoring"
+	depends on LIBOPEN62541_UA_ENABLE_PUBSUB
+
+config LIBOPEN62541_UA_ENABLE_PUBSUB_ETH_UADP
+        bool "Enable the OPC UA Ethernet PubSub support to transport UADP NetworkMessages as payload of Ethernet II frame without IP or UDP headers"
+	depends on LIBOPEN62541_UA_ENABLE_PUBSUB
+
+config LIBOPEN62541_UA_ENABLE_PUBSUB_ENCRYPTION
+        bool "Enable PubSub encryption"
+        depends on LIBOPEN62541_UA_ENABLE_PUBSUB
+
+endmenu
diff --git a/external/subpack/libs/libopen62541/Makefile b/external/subpack/libs/libopen62541/Makefile
new file mode 100644
index 0000000..0182e3a
--- /dev/null
+++ b/external/subpack/libs/libopen62541/Makefile
@@ -0,0 +1,108 @@
+#
+# Copyright (C) 2023 Michele Primavera
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libopen62541
+PKG_VERSION:=1.3.6
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/open62541/open62541.git
+PKG_SOURCE_VERSION:=v$(PKG_VERSION)
+PKG_MIRROR_HASH:=4e1513dfea70c2be52cc9c096386063e9e20ef757912a197f78e669a7e9dfb3d
+
+PKG_LICENSE:=MPL-2.0
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:open62541:open62541
+PKG_MAINTAINER:=Michele Primavera <primavera@elmod.it>
+
+CMAKE_INSTALL:=1
+
+define Package/libopen62541/config
+        source "$(SOURCE)/Config.in"
+endef
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+ifeq ($(CONFIG_HAS_MIPS16),y)
+  TARGET_CFLAGS += -fstack-check=generic
+endif
+
+define Package/libopen62541
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=An OPC UA library
+  URL:=https://open62541.org/
+  DEPENDS:=+librt +zlib +libstdcpp +libpthread +libatomic \
+		+LIBOPEN62541_MBDEDTLS:libmbedtls +LIBOPEN62541_OPENSSL:libopenssl
+endef
+
+define Package/libopen62541/description
+ open62541 (http://open62541.org) is an open source and free implementation of
+ OPC UA (OPC Unified Architecture) written in the common subset of the C99 and
+ C++98 languages. The library is usable with all major compilers and provides
+ the necessary tools to implement dedicated OPC UA clients and servers, or to
+ integrate OPC UA-based communication into existing applications. open62541
+ library is platform independent.
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_SHARED_LIBS=ON \
+	-DUA_LOGLEVEL=500 \
+	-DUA_ENABLE_AMALGAMATION=OFF \
+	-DCMAKE_BUILD_TYPE=MinSizeRel \
+	-DUA_ARCHITECTURE=posix \
+	-DUA_BUILD_EXAMPLES=OFF \
+	-DUA_BUILD_TOOLS=OFF \
+	-DUA_BUILD_UNIT_TESTS=OFF \
+	-DOPEN62541_VERSION=v$(PKG_VERSION) \
+	-DUA_ENABLE_SUBSCRIPTIONS=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_SUBSCRIPTIONS),ON,OFF) \
+	-DUA_ENABLE_SUBSCRIPTIONS_EVENTS=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_SUBSCRIPTIONS_EVENTS),ON,OFF) \
+	-DUA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_SUBSCRIPTIONS_ALARMS_CONDITIONS),ON,OFF) \
+	-DUA_ENABLE_METHODCALLS=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_METHODCALLS),ON,OFF) \
+	-DUA_ENABLE_PARSING=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_PARSING),ON,OFF) \
+	-DUA_ENABLE_NODEMANAGEMENT=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_NODEMANAGEMENT),ON,OFF) \
+	-DUA_ENABLE_IMMUTABLE_NODES=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_IMMUTABLE_NODES),ON,OFF) \
+	-DUA_ENABLE_DISCOVERY=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_DISCOVERY),ON,OFF) \
+	-DUA_ENABLE_DISCOVERY_MULTICAST=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_DISCOVERY_MULTICAST),ON,OFF) \
+	-DUA_ENABLE_DISCOVERY_SEMAPHORE=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_DISCOVERY_SEMAPHORE),ON,OFF) \
+	-DUA_ENABLE_ENCRYPTION_TPM2=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_ENCRYPTION_TPM2),ON,OFF) \
+	-DUA_ENABLE_TYPEDESCRIPTION=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_TYPEDESCRIPTION),ON,OFF) \
+	-DUA_ENABLE_STATUSCODE_DESCRIPTIONS=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_STATUSCODE_DESCRIPTIONS),ON,OFF) \
+	-DUA_ENABLE_PUBSUB=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_PUBSUB),ON,OFF) \
+	-DUA_ENABLE_PUBSUB_DELTAFRAMES=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_PUBSUB_DELTAFRAMES),ON,OFF) \
+	-DUA_ENABLE_PUBSUB_FILE_CONFIG=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_PUBSUB_FILE_CONFIG),ON,OFF) \
+	-DUA_ENABLE_PUBSUB_INFORMATIONMODEL=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_PUBSUB_INFORMATIONMODEL),ON,OFF) \
+	-DUA_ENABLE_PUBSUB_MONITORING=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_PUBSUB_MONITORING),ON,OFF) \
+	-DUA_ENABLE_PUBSUB_ETH_UADP=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_PUBSUB_ETH_UADP),ON,OFF) \
+	-DUA_ENABLE_PUBSUB_ENCRYPTION=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_PUBSUB_ENCRYPTION),ON,OFF) \
+	-DUA_ENABLE_HISTORIZING=$(if $(CONFIG_LIBOPEN62541_UA_ENABLE_HISTORIZING),ON,OFF)
+
+ifeq ($(CONFIG_LIBOPEN62541_MBDEDTLS),y)
+	CMAKE_OPTIONS += -DUA_ENABLE_ENCRYPTION=MBEDTLS
+else ifeq ($(CONFIG_LIBOPEN62541_OPENSSL),y)
+	CMAKE_OPTIONS += -DUA_ENABLE_ENCRYPTION=OPENSSL
+else
+	CMAKE_OPTIONS += -DUA_ENABLE_ENCRYPTION=OFF
+endif
+
+ifeq ($(CONFIG_LIBOPEN62541_NAMESPACEZERO_REDUCED),y)
+	CMAKE_OPTIONS += -DUA_NAMESPACE_ZERO=REDUCED
+else ifeq ($(CONFIG_LIBOPEN62541_NAMESPACEZERO_MINIMAL),y)
+	CMAKE_OPTIONS += -DUA_NAMESPACE_ZERO=MINIMAL
+else
+	CMAKE_OPTIONS += -DUA_NAMESPACE_ZERO=FULL
+endif
+
+define Package/libopen62541/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/libopen62541.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libopen62541))
diff --git a/external/subpack/libs/liboping/Makefile b/external/subpack/libs/liboping/Makefile
new file mode 100644
index 0000000..dc5013d
--- /dev/null
+++ b/external/subpack/libs/liboping/Makefile
@@ -0,0 +1,90 @@
+#
+# Copyright (C) 2009-2014 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:=liboping
+PKG_VERSION:=1.10.0
+PKG_RELEASE:=3
+PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_CPE_ID:=cpe:/a:noping:liboping
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://noping.cc/files
+PKG_HASH:=eb38aa93f93e8ab282d97e2582fbaea88b3f889a08cbc9dbf20059c3779d5cd8
+
+PKG_FIXUP:=autoreconf
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/liboping/Default
+  URL:=https://noping.cc
+endef
+
+define Package/liboping
+$(call Package/liboping/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=C library to generate ICMP echo requests.
+endef
+
+define Package/oping
+$(call Package/liboping/Default)
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=Send ICMP echo request to network hosts
+  DEPENDS+= +liboping
+endef
+
+define Package/noping
+$(call Package/liboping/Default)
+  SECTION:=net
+  CATEGORY:=Network
+  TITLE:=Ncurses application to send ICMP echo request to network hosts
+  DEPENDS+= +liboping +libncurses
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+	--without-perl-bindings \
+	--enable-shared \
+	--enable-static
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/oping.h $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liboping.{a,so*} $(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/liboping.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/liboping/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liboping.so.* $(1)/usr/lib/
+endef
+
+define Package/oping/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/oping $(1)/usr/bin/
+endef
+
+define Package/noping/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/noping $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,liboping))
+$(eval $(call BuildPackage,oping))
+$(eval $(call BuildPackage,noping))
diff --git a/external/subpack/libs/liboping/patches/01-no-werror.patch b/external/subpack/libs/liboping/patches/01-no-werror.patch
new file mode 100644
index 0000000..8589284
--- /dev/null
+++ b/external/subpack/libs/liboping/patches/01-no-werror.patch
@@ -0,0 +1,11 @@
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS = foreign no-dependenci
+ SUBDIRS = mans
+ 
+ if COMPILER_IS_GCC
+-AM_CFLAGS = -Wall -Werror
++AM_CFLAGS = -Wall
+ endif
+ 
+ include_HEADERS = oping.h
diff --git a/external/subpack/libs/liboping/patches/05-fix-format-arguments-ncurses63.patch b/external/subpack/libs/liboping/patches/05-fix-format-arguments-ncurses63.patch
new file mode 100644
index 0000000..66b9657
--- /dev/null
+++ b/external/subpack/libs/liboping/patches/05-fix-format-arguments-ncurses63.patch
@@ -0,0 +1,30 @@
+--- a/src/oping.c
++++ b/src/oping.c
+@@ -1125,7 +1125,7 @@ static int update_graph_prettyping (ping
+ 			wattron (ctx->window, COLOR_PAIR(color));
+ 
+ 		if (has_utf8())
+-			mvwprintw (ctx->window, /* y = */ 3, /* x = */ x + 2, symbol);
++			mvwprintw (ctx->window, /* y = */ 3, /* x = */ x + 2, "%s", symbol);
+ 		else
+ 			mvwaddch (ctx->window, /* y = */ 3, /* x = */ x + 2, symbolc);
+ 
+@@ -1223,7 +1223,7 @@ static int update_graph_histogram (ping_
+ 			mvwaddch (ctx->window, /* y = */ 3, /* x = */ x + 2, ' ');
+ 		else if (has_utf8 ())
+ 			mvwprintw (ctx->window, /* y = */ 3, /* x = */ x + 2,
+-					hist_symbols_utf8[index]);
++					"%s", hist_symbols_utf8[index]);
+ 		else
+ 			mvwaddch (ctx->window, /* y = */ 3, /* x = */ x + 2,
+ 					hist_symbols_acs[index] | A_ALTCHARSET);
+@@ -1600,8 +1600,7 @@ static void update_host_hook (pingobj_it
+ 
+ 			HOST_PRINTF ("%zu bytes from %s (%s): icmp_seq=%u ttl=%i ",
+ 					data_len, context->host, context->addr,
+-					sequence, recv_ttl,
+-					format_qos (recv_qos, recv_qos_str, sizeof (recv_qos_str)));
++					sequence, recv_ttl);
+ 			if ((recv_qos != 0) || (opt_send_qos != 0))
+ 			{
+ 				HOST_PRINTF ("qos=%s ",
diff --git a/external/subpack/libs/libopusenc/Makefile b/external/subpack/libs/libopusenc/Makefile
new file mode 100644
index 0000000..3f0dba5
--- /dev/null
+++ b/external/subpack/libs/libopusenc/Makefile
@@ -0,0 +1,51 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libopusenc
+PKG_VERSION:=0.2.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://archive.mozilla.org/pub/opus
+PKG_HASH:=8298db61a8d3d63e41c1a80705baa8ce9ff3f50452ea7ec1c19a564fe106cbb9
+
+PKG_MAINTAINER:=Eduardo Abinader <eduardoabinader@gmail.com>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libopusenc
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libopus
+  TITLE:=OPUS Audio stream files
+  URL:=https://opus-codec.org
+endef
+
+define Package/libopusenc/descriptiion
+ Libopusenc provides a high-level API for creating .opus files and streams.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libopusenc.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libopusenc/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libopusenc))
diff --git a/external/subpack/libs/libopusenc/patches/0001-Fix-ope_encoder_drain-assertion-failure.patch b/external/subpack/libs/libopusenc/patches/0001-Fix-ope_encoder_drain-assertion-failure.patch
new file mode 100644
index 0000000..7c0ba06
--- /dev/null
+++ b/external/subpack/libs/libopusenc/patches/0001-Fix-ope_encoder_drain-assertion-failure.patch
@@ -0,0 +1,27 @@
+From 205552370e058d99452fd34983942e10f2db6dff Mon Sep 17 00:00:00 2001
+From: Mark Harris <mark.hsj@gmail.com>
+Date: Mon, 28 Dec 2020 12:58:17 -0800
+Subject: [PATCH] Fix ope_encoder_drain() assertion failure
+
+If the stream is drained without writing any audio and the frame size is
+smaller than the encoder latency, the assertion (enc->streams == NULL)
+would fail because pad_samples was computed using an incorrect value of
+enc->global_granule_offset before it was set in init_stream(), causing
+the padding to be insufficient to drain the stream.
+---
+ src/opusenc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/src/opusenc.c
++++ b/src/opusenc.c
+@@ -808,9 +808,9 @@ int ope_encoder_drain(OggOpusEnc *enc) {
+   if (enc->unrecoverable) return enc->unrecoverable;
+   /* Check if it's already been drained. */
+   if (enc->streams == NULL) return OPE_TOO_LATE;
++  if (!enc->streams->stream_is_init) init_stream(enc);
+   if (enc->re) resampler_drain = speex_resampler_get_output_latency(enc->re);
+   pad_samples = MAX(LPC_PADDING, enc->global_granule_offset + enc->frame_size + resampler_drain + 1);
+-  if (!enc->streams->stream_is_init) init_stream(enc);
+   shift_buffer(enc);
+   assert(enc->buffer_end + pad_samples <= BUFFER_SAMPLES);
+   memset(&enc->buffer[enc->channels*enc->buffer_end], 0, pad_samples*enc->channels*sizeof(enc->buffer[0]));
diff --git a/external/subpack/libs/libopusenc/patches/0002-Fix-use-of-uninitialized-fields.patch b/external/subpack/libs/libopusenc/patches/0002-Fix-use-of-uninitialized-fields.patch
new file mode 100644
index 0000000..8642e2f
--- /dev/null
+++ b/external/subpack/libs/libopusenc/patches/0002-Fix-use-of-uninitialized-fields.patch
@@ -0,0 +1,78 @@
+From 6d46f2d7f7617852bab7cbb2f7cae8350b99204e Mon Sep 17 00:00:00 2001
+From: Mark Harris <mark.hsj@gmail.com>
+Date: Mon, 28 Dec 2020 17:01:39 -0800
+Subject: [PATCH] Fix use of uninitialized fields
+
+enc->streams->end_granule used uninitialized in encode_buffer() if the
+stream contains no audio (opusenc_example /dev/null out.opus).
+
+enc->frame_size_request used uninitialized in encode_buffer() if the
+frame size was not explicitly set.
+
+enc->callbacks used uninitialized if the encoder is created with
+ope_encoder_create_callbacks() and callbacks is NULL.
+---
+ src/opusenc.c | 23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+--- a/src/opusenc.c
++++ b/src/opusenc.c
+@@ -361,8 +361,7 @@ static void stream_destroy(EncStream *st
+   free(stream);
+ }
+ 
+-/* Create a new OggOpus file (callback-based). */
+-OggOpusEnc *ope_encoder_create_callbacks(const OpusEncCallbacks *callbacks, void *user_data,
++static OggOpusEnc *ope_encoder_create_callbacks_impl(const OpusEncCallbacks *callbacks, void *user_data,
+     OggOpusComments *comments, opus_int32 rate, int channels, int family, int *error) {
+   OggOpusEnc *enc=NULL;
+   int ret;
+@@ -395,11 +394,11 @@ OggOpusEnc *ope_encoder_create_callbacks
+   enc->oggp = NULL;
+   /* Not initializing anything is an unrecoverable error. */
+   enc->unrecoverable = family == -1 ? OPE_TOO_LATE : 0;
+-  enc->pull_api = 0;
+   enc->packet_callback = NULL;
+   enc->rate = rate;
+   enc->channels = channels;
+   enc->frame_size = 960;
++  enc->frame_size_request = OPUS_FRAMESIZE_20_MS;
+   enc->decision_delay = 96000;
+   enc->max_ogg_delay = 48000;
+   enc->chaining_keyframe = NULL;
+@@ -447,8 +446,12 @@ OggOpusEnc *ope_encoder_create_callbacks
+   if (callbacks != NULL)
+   {
+     enc->callbacks = *callbacks;
++    enc->pull_api = 0;
++  } else {
++    enc->pull_api = 1;
+   }
+   enc->streams->user_data = user_data;
++  enc->streams->end_granule = 0;
+   if (error) *error = OPE_OK;
+   return enc;
+ fail:
+@@ -462,11 +465,19 @@ fail:
+   return NULL;
+ }
+ 
++/* Create a new OggOpus stream (callback-based). */
++OggOpusEnc *ope_encoder_create_callbacks(const OpusEncCallbacks *callbacks, void *user_data,
++    OggOpusComments *comments, opus_int32 rate, int channels, int family, int *error) {
++  if (callbacks == NULL) {
++    if (error) *error = OPE_BAD_ARG;
++    return NULL;
++  }
++  return ope_encoder_create_callbacks_impl(callbacks, user_data, comments, rate, channels, family, error);
++}
++
+ /* Create a new OggOpus stream, pulling one page at a time. */
+ OggOpusEnc *ope_encoder_create_pull(OggOpusComments *comments, opus_int32 rate, int channels, int family, int *error) {
+-  OggOpusEnc *enc = ope_encoder_create_callbacks(NULL, NULL, comments, rate, channels, family, error);
+-  if (enc) enc->pull_api = 1;
+-  return enc;
++  return ope_encoder_create_callbacks_impl(NULL, NULL, comments, rate, channels, family, error);
+ }
+ 
+ int ope_encoder_deferred_init_with_mapping(OggOpusEnc *enc, int family, int streams,
diff --git a/external/subpack/libs/libopusenc/patches/0003-Fix-use-of-uninitialized-serialno.patch b/external/subpack/libs/libopusenc/patches/0003-Fix-use-of-uninitialized-serialno.patch
new file mode 100644
index 0000000..cf5cf56
--- /dev/null
+++ b/external/subpack/libs/libopusenc/patches/0003-Fix-use-of-uninitialized-serialno.patch
@@ -0,0 +1,47 @@
+From 427d61131a1af5eed48d5428e723ab4602b56cc1 Mon Sep 17 00:00:00 2001
+From: Mark Harris <mark.hsj@gmail.com>
+Date: Tue, 29 Dec 2020 01:43:37 -0800
+Subject: [PATCH] Fix use of uninitialized serialno
+
+Also do not crash if OPE_GET_SERIALNO_REQUEST is used after draining.
+---
+ src/opusenc.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+--- a/src/opusenc.c
++++ b/src/opusenc.c
+@@ -356,6 +356,11 @@ fail:
+   return NULL;
+ }
+ 
++static void stream_generate_serialno(EncStream *stream) {
++  stream->serialno = rand();
++  stream->serialno_is_set = 1;
++}
++
+ static void stream_destroy(EncStream *stream) {
+   if (stream->comment) free(stream->comment);
+   free(stream);
+@@ -512,9 +517,7 @@ int ope_encoder_deferred_init_with_mappi
+ 
+ static void init_stream(OggOpusEnc *enc) {
+   assert(!enc->streams->stream_is_init);
+-  if (!enc->streams->serialno_is_set) {
+-    enc->streams->serialno = rand();
+-  }
++  if (!enc->streams->serialno_is_set) stream_generate_serialno(enc->streams);
+ 
+   if (enc->oggp != NULL) oggp_chain(enc->oggp, enc->streams->serialno);
+   else {
+@@ -1071,6 +1074,11 @@ int ope_encoder_ctl(OggOpusEnc *enc, int
+     case OPE_GET_SERIALNO_REQUEST:
+     {
+       opus_int32 *value = va_arg(ap, opus_int32*);
++      if (!enc->last_stream) {
++        ret = OPE_TOO_LATE;
++        break;
++      }
++      if (!enc->last_stream->serialno_is_set) stream_generate_serialno(enc->last_stream);
+       *value = enc->last_stream->serialno;
+     }
+     break;
diff --git a/external/subpack/libs/liborcania/Makefile b/external/subpack/libs/liborcania/Makefile
new file mode 100644
index 0000000..7591b46
--- /dev/null
+++ b/external/subpack/libs/liborcania/Makefile
@@ -0,0 +1,38 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=liborcania
+PKG_VERSION:=2.3.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/babelouest/orcania/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=b1b5550523164eca0f59099e843177684c5017c6088284123880cffd4c6dbbde
+
+PKG_MAINTAINER:=Toni Uhlig <matzeton@googlemail.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/orcania-$(PKG_VERSION)
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/liborcania
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Functionality required by libulfius.
+  URL:=https://github.com/babelouest/orcania
+  PROVIDES:=liborcania
+endef
+
+define Package/liborcania/description
+  Potluck with different functions for different purposes that can be shared among C programs.
+endef
+
+$(eval $(call BuildPackage,liborcania))
diff --git a/external/subpack/libs/libowfat/Makefile b/external/subpack/libs/libowfat/Makefile
new file mode 100644
index 0000000..94f1777
--- /dev/null
+++ b/external/subpack/libs/libowfat/Makefile
@@ -0,0 +1,75 @@
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libowfat
+PKG_VERSION:=0.33
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://www.fefe.de/libowfat
+PKG_HASH:=311ec8b3f4b72bb442e323fb013a98f956fa745547f2bc9456287b20d027cd7d
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_DEPENDS += libowfat/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+# set to 1 to enable debugging
+DEBUG=
+
+define Package/libowfat
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=reimplemented libdjb under GPL
+  URL:=https://www.fefe.de/libowfat/
+  BUILDONLY:=1
+endef
+
+define Build/Configure
+endef
+
+TARGET_CFLAGS += $(FPIC)
+LOWFAT_MAKEOPTS = $(TARGET_CONFIGURE_OPTS) \
+	AR="ar" \
+	CFLAGS="$(TARGET_CFLAGS) -I$(PKG_BUILD_DIR) -I$(STAGING_DIR)/usr/include" \
+	CCC="$(TARGET_CC)" \
+	CROSS="$(TARGET_CROSS)" \
+	DEBUG="$(DEBUG)" \
+	VERSION="$(PKG_VERSION)" \
+	OS="Linux"
+
+LOWFAT_HOST_MAKEOPTS = $(HOST_CONFIGURE_OPTS) \
+	CFLAGS="$(HOST_CFLAGS) -I$(HOST_BUILD_DIR) -I$(STAGING_DIR_HOSTPKG)/include" \
+	DEBUG="$(DEBUG)" \
+	VERSION="$(PKG_VERSION)" \
+	OS="Linux"
+
+define Build/Compile
+	$(MAKE) -C $(PKG_BUILD_DIR) $(LOWFAT_MAKEOPTS)
+endef
+
+define Host/Compile
+	$(LN) . $(HOST_BUILD_DIR)/libowfat
+	$(MAKE) -C $(HOST_BUILD_DIR) $(LOWFAT_HOST_MAKEOPTS) ent
+endef
+
+define Host/Install
+	$(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/bin
+	$(CP) $(HOST_BUILD_DIR)/ent $(STAGING_DIR_HOSTPKG)/bin/libowfat-ent
+endef
+
+define Build/InstallDev
+	mkdir -p $(1)/usr/include/libowfat
+	$(CP) $(PKG_BUILD_DIR)/*.h $(1)/usr/include/libowfat
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/*.a $(1)/usr/lib
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,libowfat))
diff --git a/external/subpack/libs/libowfat/patches/001-fixbuild.patch b/external/subpack/libs/libowfat/patches/001-fixbuild.patch
new file mode 100644
index 0000000..ebd9aca
--- /dev/null
+++ b/external/subpack/libs/libowfat/patches/001-fixbuild.patch
@@ -0,0 +1,20 @@
+--- a/GNUmakefile
++++ b/GNUmakefile
+@@ -368,6 +368,8 @@ socket_accept4.o socket_accept6.o socket
+ socket_local6.o socket_recv4.o socket_recv6.o socket_remote4.o \
+ socket_remote6.o socket_accept4_flags.o socket_accept6_flags.o: havesl.h
+ 
++socket_remote4.o: havescope.h
++
+ dns_nd6.o fmt_xlong.o scan_xlong.o fmt_ip6_flat.o $(TEXTCODE_OBJS): haveinline.h
+ 
+ iob_send.o scan_ip6if.o: havealloca.h
+@@ -397,7 +399,7 @@ update:
+ 	dl -n http://www.w3.org/TR/html5/entities.json
+ 
+ entities.h: entities.json ent
+-	./ent
++	libowfat-ent
+ 
+ scan_html.o: entities.h
+ 
diff --git a/external/subpack/libs/libowfat/patches/020-cflags.patch b/external/subpack/libs/libowfat/patches/020-cflags.patch
new file mode 100644
index 0000000..54555f7
--- /dev/null
+++ b/external/subpack/libs/libowfat/patches/020-cflags.patch
@@ -0,0 +1,13 @@
+--- a/Makefile
++++ b/Makefile
+@@ -42,8 +42,8 @@ OPT_PLUS=-O3 $(NATIVE)
+ 
+ DEFINE=-D_REENTRANT
+ 
+-CFLAGS=-pipe $(WARN) $(DEFINE) $(OPT_REG)
+-CFLAGS_OPT=-pipe $(WARN) $(DEFINE) $(OPT_PLUS)
++CFLAGS+=-pipe $(WARN) $(DEFINE) $(OPT_REG)
++CFLAGS_OPT+=-pipe $(WARN) $(DEFINE) $(OPT_PLUS)
+ 
+ #CFLAGS=-pipe -Os -march=pentiumpro -mcpu=pentiumpro -fomit-frame-pointer -fschedule-insns2 -Wall
+ 
diff --git a/external/subpack/libs/libp11/Makefile b/external/subpack/libs/libp11/Makefile
new file mode 100644
index 0000000..2380db8
--- /dev/null
+++ b/external/subpack/libs/libp11/Makefile
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2011-2014 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:=libp11
+PKG_VERSION:=0.4.12
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=https://github.com/OpenSC/libp11/releases/download/$(PKG_NAME)-$(PKG_VERSION)/
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_HASH:=1e1a2533b3fcc45fde4da64c9c00261b1047f14c3f911377ebd1b147b3321cfd
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_PARALLEL:=1
+PKG_FIXUP:=libtool
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libp11
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=PKCS#11 wrapper library
+  URL:=https://www.opensc-project.org/opensc/wiki/libp11
+  DEPENDS:=+libopenssl +@OPENSSL_ENGINE
+  CONFLICTS:=engine_pkcs11
+endef
+
+define Package/libp11/description
+  Libp11 is a library implementing a small layer on top of PKCS#11 API
+  to make using PKCS#11 implementations easier.
+endef
+
+CONFIGURE_ARGS += --with-enginesdir=/usr/lib/engines
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libp11.{a,so} $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libp11.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libp11.pc $(1)/usr/lib/pkgconfig/libp11.pc
+endef
+
+define Package/libp11/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libp11.so.* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/engines
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/engines/*.so* $(1)/usr/lib/engines
+	$(LN) pkcs11.so $(1)/usr/lib/engines/libpkcs11.so
+endef
+
+$(eval $(call BuildPackage,libp11))
diff --git a/external/subpack/libs/libp11/patches/001-fix-install.patch b/external/subpack/libs/libp11/patches/001-fix-install.patch
new file mode 100644
index 0000000..302b7e3
--- /dev/null
+++ b/external/subpack/libs/libp11/patches/001-fix-install.patch
@@ -0,0 +1,53 @@
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -49,13 +49,6 @@ pkcs11_la_LIBADD = $(libp11_la_OBJECTS)
+ pkcs11_la_LDFLAGS = $(AM_LDFLAGS) -module -shared -shrext $(SHARED_EXT) \
+ 	-avoid-version -export-symbols "$(srcdir)/pkcs11.exports"
+ 
+-# OpenSSL older than 1.1.0 expected libpkcs11.so instead of pkcs11.so
+-check-local: $(LTLIBRARIES)
+-	cd .libs && $(LN_S) -f pkcs11$(SHARED_EXT) libpkcs11$(SHARED_EXT)
+-
+-install-exec-hook:
+-	cd '$(DESTDIR)$(enginesexecdir)' && $(LN_S) -f pkcs11$(SHARED_EXT) libpkcs11$(SHARED_EXT)
+-
+ if WIN32
+ # def file required for MS users to build library
+ mylibdir=$(libdir)
+--- a/src/Makefile.in
++++ b/src/Makefile.in
+@@ -911,7 +911,7 @@ distdir-am: $(DISTFILES)
+ 	  fi; \
+ 	done
+ check-am: all-am
+-	$(MAKE) $(AM_MAKEFLAGS) check-local
++	$(MAKE) $(AM_MAKEFLAGS)
+ check: check-am
+ all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) config.h
+ installdirs:
+@@ -1000,7 +1000,7 @@ install-dvi-am:
+ 
+ install-exec-am: install-enginesexecLTLIBRARIES install-libLTLIBRARIES
+ 	@$(NORMAL_INSTALL)
+-	$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
++	$(MAKE) $(AM_MAKEFLAGS)
+ install-html: install-html-am
+ 
+ install-html-am:
+@@ -1063,14 +1063,14 @@ uninstall-am: uninstall-enginesexecLTLIB
+ .MAKE: all check-am install-am install-exec-am install-strip
+ 
+ .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am \
+-	check-local clean clean-enginesexecLTLIBRARIES clean-generic \
++	clean clean-enginesexecLTLIBRARIES clean-generic \
+ 	clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
+ 	ctags-am distclean distclean-compile distclean-generic \
+ 	distclean-hdr distclean-libtool distclean-tags distdir dvi \
+ 	dvi-am html html-am info info-am install install-am \
+ 	install-data install-data-am install-dvi install-dvi-am \
+ 	install-enginesexecLTLIBRARIES install-exec install-exec-am \
+-	install-exec-hook install-html install-html-am \
++	install-html install-html-am \
+ 	install-includeHEADERS install-info install-info-am \
+ 	install-libLTLIBRARIES install-man install-mylibDATA \
+ 	install-pdf install-pdf-am install-pkgconfigDATA install-ps \
diff --git a/external/subpack/libs/libpbc/Makefile b/external/subpack/libs/libpbc/Makefile
new file mode 100644
index 0000000..77e04db
--- /dev/null
+++ b/external/subpack/libs/libpbc/Makefile
@@ -0,0 +1,52 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libpbc
+PKG_VERSION:=0.5.14
+PKG_RELEASE:=2
+
+PKG_SOURCE:=pbc-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://crypto.stanford.edu/pbc/files/
+PKG_HASH:=772527404117587560080241cedaf441e5cac3269009cdde4c588a1dce4c23d2
+PKG_BUILD_DIR:=$(BUILD_DIR)/pbc-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=LGPL-3.0-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libpbc
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=The Pairing-Based Cryptography Library
+  URL:=https://crypto.stanford.edu/pbc/
+  DEPENDS:=+libgmp
+endef
+
+define Package/libpbc/description
+  Pairing-based cryptography is a relatively young area of cryptography
+  that revolves around a certain function with special properties.
+
+  The PBC (Pairing-Based Cryptography) library is a free C library
+  (released under the GNU Lesser General Public License) built on the GMP
+  library that performs the mathematical operations underlying
+  pairing-based cryptosystems.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/pbc
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/pbc/*.h $(1)/usr/include/pbc
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpbc* $(1)/usr/lib/
+endef
+
+define Package/libpbc/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpbc.so.*  $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libpbc))
diff --git a/external/subpack/libs/libpbc/patches/010-pass-cflags.patch b/external/subpack/libs/libpbc/patches/010-pass-cflags.patch
new file mode 100644
index 0000000..078ff83
--- /dev/null
+++ b/external/subpack/libs/libpbc/patches/010-pass-cflags.patch
@@ -0,0 +1,10 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -10,7 +10,6 @@ AC_CONFIG_SRCDIR([./])
+ LT_INIT
+ #AC_CANONICAL_HOST
+ 
+-CFLAGS=
+ default_fink_path=/sw
+ case $host_os in
+      darwin*) 
diff --git a/external/subpack/libs/libpciaccess/Makefile b/external/subpack/libs/libpciaccess/Makefile
new file mode 100644
index 0000000..a651b08
--- /dev/null
+++ b/external/subpack/libs/libpciaccess/Makefile
@@ -0,0 +1,58 @@
+# Copyright (C) 2019 Lucian Cristian <lucian.cristian@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:=libpciaccess
+PKG_VERSION:=0.18.1
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=https://www.x.org/releases/individual/lib/
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_HASH:=4af43444b38adb5545d0ed1c2ce46d9608cc47b31c2387fc5181656765a6fa76
+
+PKG_MAINTAINER:= Lucian Cristian <lucian.cristian@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libpciaccess
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Generic PCI access library
+  URL:=https://gitlab.freedesktop.org/xorg/lib/libpciaccess
+endef
+
+MESON_ARGS += -Dzlib=disabled
+
+define Build/InstallDev
+	$(INSTALL_DIR) \
+	  $(1)/usr/include \
+	  $(1)/usr/lib
+
+	$(CP) \
+	  $(PKG_INSTALL_DIR)/usr/include/* \
+	  $(1)/usr/include/
+
+	$(CP) \
+	  $(PKG_INSTALL_DIR)/usr/lib/{pkgconfig,*.so*} \
+	  $(1)/usr/lib/
+endef
+
+define Package/libpciaccess/install
+	$(INSTALL_DIR) \
+	  $(1)/usr/lib
+
+	$(CP) \
+	  $(PKG_INSTALL_DIR)/usr/lib/*.so* \
+	  $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libpciaccess))
diff --git a/external/subpack/libs/libpfring/Makefile b/external/subpack/libs/libpfring/Makefile
new file mode 100644
index 0000000..969d27f
--- /dev/null
+++ b/external/subpack/libs/libpfring/Makefile
@@ -0,0 +1,90 @@
+#
+# Copyright (C) 2017 Banglang Huang
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=libpfring
+PKG_VERSION:=8.6.1
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_SOURCE_URL:=https://github.com/ntop/PF_RING
+PKG_MIRROR_HASH:=2c4623e4a3cd601a94cfdaf748e0cd7aa93e8ec850d3cd4c2ec5d33419e45fbb
+
+PKG_MAINTAINER:=Banglang Huang <banglang.huang@foxmail.com>
+
+PKG_FIXUP:=patch-libtool
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+CONFIGURE_PATH:=userland
+MAKE_PATH:=userland/lib
+
+define Package/libpfring
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Library for PR_RING (package process framework)
+  URL:=https://github.com/ntop/pf_ring
+  DEPENDS:=+kmod-pf-ring +libpcap +libpthread
+  LICENSE:=LGPL-2.1-or-later
+  LICENSE_FILES:=LICENSE
+endef
+
+define Package/libpfring/description
+  PF_RING is a high speed packet capture library that turns a commodity PC into an efficient and cheap
+  network measurement box suitable for both packet and active traffic analysis and manipulation.
+  Moreover, PF_RING opens totally new markets as it enables the creation of efficient application such as
+  traffic balancers or packet filters in a matter of lines of codes.
+endef
+
+define KernelPackage/pf-ring
+  SUBMENU:=Network Support
+  TITLE:=PF_RING Kernel driver
+  FILES:=$(PKG_BUILD_DIR)/kernel/pf_ring.ko
+  AUTOLOAD:=$(call AutoLoad,90,pf_ring,1)
+  LICENSE:=GPL-2.0-or-later
+endef
+
+define KernelPackage/pf-ring/description
+  Kernel module for libpf-ring package
+endef
+
+CONFIGURE_VARS += \
+	MACHINE="$(ARCH)" \
+	ac_cv_lib_nl_3_nl_socket_alloc=no
+
+define Build/Compile
+	$(MAKE) -C "$(LINUX_DIR)" \
+		KERNEL_DIR="$(LINUX_DIR)" \
+		ARCH="$(LINUX_KARCH)" \
+		CROSS_COMPILE="$(TARGET_CROSS)" \
+		M="$(PKG_BUILD_DIR)/kernel" \
+		EXTRA_CFLAGS="$(EXTRA_CFLAGS) -I$(PKG_BUILD_DIR)/kernel" \
+		modules
+	$(call Build/Compile/Default)
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpfring.so* $(1)/usr/lib/
+endef
+
+define Package/libpfring/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpfring.so* $(1)/usr/lib/
+	$(LN) libpfring.so $(1)/usr/lib/libpfring.so.1
+endef
+
+$(eval $(call BuildPackage,libpfring))
+$(eval $(call KernelPackage,pf-ring))
diff --git a/external/subpack/libs/libpfring/patches/0001-fix-cross-compiling.patch b/external/subpack/libs/libpfring/patches/0001-fix-cross-compiling.patch
new file mode 100644
index 0000000..1b9d455
--- /dev/null
+++ b/external/subpack/libs/libpfring/patches/0001-fix-cross-compiling.patch
@@ -0,0 +1,32 @@
+--- a/userland/configure
++++ b/userland/configure
+@@ -3873,12 +3873,6 @@ $as_echo "no" >&6; }
+         if test "$IS_FREEBSD" != "1" && test "$cross_compiling" != "yes" ; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking if r/w locks are supported" >&5
+ $as_echo_n "checking if r/w locks are supported... " >&6; }
+-      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
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h.  */
+ 
+@@ -3891,7 +3885,7 @@ else
+ 
+ 
+ _ACEOF
+-if ac_fn_c_try_run "$LINENO"; then :
++if ac_fn_c_try_compile "$LINENO"; then :
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ $as_echo "yes" >&6; }
+ cat >>confdefs.h <<_ACEOF
+@@ -3905,7 +3899,6 @@ $as_echo "no" >&6; }
+ fi
+ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+   conftest.$ac_objext conftest.beam conftest.$ac_ext
+-fi
+ 
+     fi
+ 
diff --git a/external/subpack/libs/libpfring/patches/010-gcc14.patch b/external/subpack/libs/libpfring/patches/010-gcc14.patch
new file mode 100644
index 0000000..c17dc85
--- /dev/null
+++ b/external/subpack/libs/libpfring/patches/010-gcc14.patch
@@ -0,0 +1,24 @@
+--- a/kernel/pf_ring.c
++++ b/kernel/pf_ring.c
+@@ -4713,8 +4713,8 @@ void reserve_memory(unsigned long base,
+ {
+   struct page *page, *page_end;
+ 
+-  page_end = virt_to_page(base + mem_len - 1);
+-  for(page = virt_to_page(base); page <= page_end; page++)
++  page_end = virt_to_page((void*)base + mem_len - 1);
++  for(page = virt_to_page((void*)base); page <= page_end; page++)
+     SetPageReserved(page);
+ }
+ 
+@@ -4722,8 +4722,8 @@ void unreserve_memory(unsigned long base
+ {
+   struct page *page, *page_end;
+ 
+-  page_end = virt_to_page(base + mem_len - 1);
+-  for(page = virt_to_page(base); page <= page_end; page++)
++  page_end = virt_to_page((void*)base + mem_len - 1);
++  for(page = virt_to_page((void*)base); page <= page_end; page++)
+     ClearPageReserved(page);
+ }
+ 
diff --git a/external/subpack/libs/libpfring/patches/100-fix-compilation-warning.patch b/external/subpack/libs/libpfring/patches/100-fix-compilation-warning.patch
new file mode 100644
index 0000000..85393a2
--- /dev/null
+++ b/external/subpack/libs/libpfring/patches/100-fix-compilation-warning.patch
@@ -0,0 +1,11 @@
+--- a/kernel/pf_ring.c
++++ b/kernel/pf_ring.c
+@@ -3903,7 +3903,7 @@ static int hash_pkt_cluster(ring_cluster
+       break;
+     }
+     /* else, fall through, because it's like 2-tuple for non-TCP packets */
+-
++    fallthrough;
+   case cluster_per_flow_2_tuple:
+   case cluster_per_inner_flow_2_tuple:
+     flags |= mask_2_tuple;
diff --git a/external/subpack/libs/libpfring/patches/101-kernel-pf_ring-better-define-sa_data-size.patch b/external/subpack/libs/libpfring/patches/101-kernel-pf_ring-better-define-sa_data-size.patch
new file mode 100644
index 0000000..3045818
--- /dev/null
+++ b/external/subpack/libs/libpfring/patches/101-kernel-pf_ring-better-define-sa_data-size.patch
@@ -0,0 +1,72 @@
+From 1b7780e9ecb46c6a5bbc8a831778a683f8ae80d8 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Mon, 18 Mar 2024 10:03:43 +0100
+Subject: [PATCH] kernel: pf_ring: better define sa_data size
+
+pfring_mod_bind() needs to specify the interface
+name using struct sockaddr that is defined as
+
+struct sockaddr { ushort sa_family; char sa_data[14]; };
+
+so the total interface name length is 13 chars (plus \0 trailer).
+
+Since sa_data size is arbitrary, define a more precise size for
+PF_RING socket use.
+
+This fix some compilation error with fortify string and makes the array
+handling more deterministic.
+
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+---
+ kernel/pf_ring.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+--- a/kernel/pf_ring.c
++++ b/kernel/pf_ring.c
+@@ -158,6 +158,18 @@
+ #endif
+ #endif
+ 
++/*
++  pfring_mod_bind() needs to specify the interface
++	name using struct sockaddr that is defined as
++
++  struct sockaddr { ushort sa_family; char sa_data[14]; };
++
++  so the total interface name length is 13 chars (plus \0 trailer).
++  Since sa_data size is arbitrary, define a more precise size for
++  PF_RING socket use.
++*/
++#define RING_SA_DATA_LEN 14
++
+ /* ************************************************* */
+ 
+ #if(LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
+@@ -1032,7 +1044,7 @@ pf_ring_device *pf_ring_device_name_look
+           so the total interface name length is 13 chars (plus \0 trailer).
+           The check below is to trap this case.
+          */
+-        || ((l >= 13) && (strncmp(dev_ptr->device_name, name, 13) == 0)))
++        || ((l >= RING_SA_DATA_LEN - 1) && (strncmp(dev_ptr->device_name, name, RING_SA_DATA_LEN - 1) == 0)))
+        && device_net_eq(dev_ptr, net))
+       return dev_ptr;
+   }
+@@ -5605,15 +5617,15 @@ static int ring_bind(struct socket *sock
+ #ifndef RING_USE_SOCKADDR_LL
+   } else if (addr_len == sizeof(struct sockaddr)) { /* Deprecated */
+ 
+-    char name[sizeof(sa->sa_data)+1];
++    char name[RING_SA_DATA_LEN];
+ 
+     if (sa->sa_family != PF_RING)
+       return(-EINVAL);
+ 
+-    memcpy(name, sa->sa_data, sizeof(sa->sa_data));
++    memcpy(name, sa->sa_data, RING_SA_DATA_LEN - 1);
+ 
+     /* Add trailing zero if missing */
+-    name[sizeof(name)-1] = '\0';
++    name[RING_SA_DATA_LEN-1] = '\0';
+ 
+     debug_printk(2, "searching device %s\n", name);
+ 
diff --git a/external/subpack/libs/libpfring/patches/102-remove-sendpage.patch b/external/subpack/libs/libpfring/patches/102-remove-sendpage.patch
new file mode 100644
index 0000000..a5ca509
--- /dev/null
+++ b/external/subpack/libs/libpfring/patches/102-remove-sendpage.patch
@@ -0,0 +1,22 @@
+From 5557b6ffe8d4eeb93532d043649b40eb10120bf7 Mon Sep 17 00:00:00 2001
+From: Gavin <gavin.bravery@jagsiacs.co.uk>
+Date: Wed, 25 Oct 2023 11:40:50 +0100
+Subject: [PATCH] Update pf_ring.c
+
+Change to remove .sendpage assignment, as that attribute seems to have gone away in 6.5.3 kernel.
+---
+ kernel/pf_ring.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/kernel/pf_ring.c
++++ b/kernel/pf_ring.c
+@@ -8470,7 +8470,9 @@ static struct proto_ops ring_ops = {
+   .getname = sock_no_getname,
+   .listen = sock_no_listen,
+   .shutdown = sock_no_shutdown,
++  #if(LINUX_VERSION_CODE < KERNEL_VERSION(6,5,3))
+   .sendpage = sock_no_sendpage,
++  #endif
+ 
+   /* Now the operations that really occur. */
+   .release = ring_release,
diff --git a/external/subpack/libs/libplist/Makefile b/external/subpack/libs/libplist/Makefile
new file mode 100644
index 0000000..7c8b959
--- /dev/null
+++ b/external/subpack/libs/libplist/Makefile
@@ -0,0 +1,93 @@
+#
+# Copyright (C) 2012-2014 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:=libplist
+PKG_VERSION:=2.4.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://github.com/libimobiledevice/libplist/releases/download/$(PKG_VERSION)
+PKG_HASH:=3f5868ae15b117320c1ff5e71be53d29469d4696c4085f89db1975705781a7cd
+
+PKG_MAINTAINER:=Rosen Penev <rosenp@gmail.com>
+PKG_CPE_ID:=cpe:/a:libimobiledevice:libplist
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libplist/Default
+  TITLE:=Apple property list
+  URL:=https://www.libimobiledevice.org/
+  SUBMENU:=libimobiledevice
+endef
+
+define Package/libplist/Default/description
+  A library to handle Apple Property List format whereas it's binary or XML
+endef
+
+define Package/libplist
+  $(call Package/libplist/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libxml2
+  TITLE+= library
+  PKG_LICENSE:=LGPL-2.1-or-later
+  PKG_LICENSE_FILES:=COPYING.LESSER
+endef
+
+define Package/libplist/description
+  $(call Package/libplist/Default/description)
+endef
+
+define Package/plistutil
+  $(call Package/libplist/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libplist
+  TITLE+= converter
+  LICENSE:=GPL-2.0-or-later
+  LICENSE_FILES:=COPYING
+endef
+
+define Package/plistutil/description
+  $(call Package/libplist/Default/description)
+  This package contains the libplist utilities.
+endef
+
+CONFIGURE_ARGS += \
+	--disable-static \
+	--without-cython
+
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/plist $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libplist-2.0*.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libplist-2.0.pc $(1)/usr/lib/pkgconfig/
+	$(LN) libplist-2.0.pc $(1)/usr/lib/pkgconfig/libplist.pc
+endef
+
+define Package/libplist/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libplist-2.0.so.* $(1)/usr/lib/
+endef
+
+define Package/plistutil/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/plistutil $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libplist))
+$(eval $(call BuildPackage,plistutil))
diff --git a/external/subpack/libs/libpng/Makefile b/external/subpack/libs/libpng/Makefile
new file mode 100644
index 0000000..748752f
--- /dev/null
+++ b/external/subpack/libs/libpng/Makefile
@@ -0,0 +1,66 @@
+#
+# Copyright (C) 2006-2015 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:=libpng
+PKG_VERSION:=1.6.44
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@SF/libpng
+PKG_HASH:=60c4da1d5b7f0aa8d158da48e8f8afa9773c1c8baa5d21974df61f1886b8ce8e
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
+PKG_LICENSE:=Libpng GPL-2.0-or-later BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE contrib/gregbook/COPYING contrib/gregbook/LICENSE
+PKG_CPE_ID:=cpe:/a:libpng:libpng
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libpng
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+zlib
+  TITLE:=A PNG format files handling library
+  URL:=http://www.libpng.org/pub/png/libpng.html
+endef
+
+CMAKE_OPTIONS += \
+	-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
+	-DPNG_TOOLS=OFF \
+	-DPNG_TESTS=OFF \
+	-DPNG_FRAMEWORK=OFF \
+	-DPNG_HARDWARE_OPTIMIZATIONS=ON \
+	-DPNG_ARM_NEON=$(if $(or $(findstring aarch64,$(CONFIG_ARCH)),$(findstring neon,$(CONFIG_CPU_TYPE))),on,off) \
+	-DPNG_LOONGARCH_LSX=off \
+	-DPNG_MIPS_MMI=off \
+	-DPNG_MIPS_MSA=off \
+	-DPNG_POWERPC_VSX=off \
+	-Dld-version-script=OFF
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(1)/usr/bin/libpng{,16}-config
+	$(SED) '/^includedir=/s|/usr|$$$${prefix}|' $(1)/usr/bin/libpng{,16}-config
+	$(SED) '/^libdir=/s|/usr|$$$${prefix}|' $(1)/usr/bin/libpng{,16}-config
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libpng16.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libpng16.pc
+	$(INSTALL_DIR) $(2)/bin
+	for f in libpng{,16}-config; do \
+		$(LN) ../../usr/bin/$$$$f $(2)/bin/ ; \
+	done
+endef
+
+define Package/libpng/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpng16.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpng.so $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libpng))
diff --git a/external/subpack/libs/libpng/patches/100-config_fix.patch b/external/subpack/libs/libpng/patches/100-config_fix.patch
new file mode 100644
index 0000000..3cb6d8a
--- /dev/null
+++ b/external/subpack/libs/libpng/patches/100-config_fix.patch
@@ -0,0 +1,10 @@
+--- a/scripts/libpng-config-body.in
++++ b/scripts/libpng-config-body.in
+@@ -83,6 +83,7 @@ while test $# -gt 0; do
+ 
+     --static)
+         R_opts=""
++        libs=${all_libs}
+         ;;
+ 
+     *)
diff --git a/external/subpack/libs/libpng/patches/200-ccache.patch b/external/subpack/libs/libpng/patches/200-ccache.patch
new file mode 100644
index 0000000..a08dcd1
--- /dev/null
+++ b/external/subpack/libs/libpng/patches/200-ccache.patch
@@ -0,0 +1,19 @@
+--- a/scripts/cmake/genout.cmake.in
++++ b/scripts/cmake/genout.cmake.in
+@@ -18,6 +18,7 @@ set(BINDIR "@CMAKE_CURRENT_BINARY_DIR@")
+ 
+ set(AWK "@AWK@")
+ set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@")
++set(CMAKE_C_COMPILER_ARG1 "@CMAKE_C_COMPILER_ARG1@")
+ set(CMAKE_C_FLAGS @CMAKE_C_FLAGS@)
+ set(CMAKE_SYSROOT @CMAKE_SYSROOT@)
+ set(INCDIR "@CMAKE_CURRENT_BINARY_DIR@")
+@@ -67,7 +68,7 @@ if(INPUTEXT STREQUAL ".c" AND OUTPUTEXT
+     set(PNG_PREFIX_DEF "-DPNG_PREFIX=${PNG_PREFIX}")
+   endif()
+ 
+-  execute_process(COMMAND "${CMAKE_C_COMPILER}" "-E"
++  execute_process(COMMAND "${CMAKE_C_COMPILER}" ${CMAKE_C_COMPILER_ARG1} "-E"
+                           ${CMAKE_C_FLAGS}
+                           ${PLATFORM_C_FLAGS}
+                           "-I${SRCDIR}"
diff --git a/external/subpack/libs/libpqxx/Config.in b/external/subpack/libs/libpqxx/Config.in
new file mode 100644
index 0000000..c8407d8
--- /dev/null
+++ b/external/subpack/libs/libpqxx/Config.in
@@ -0,0 +1,26 @@
+menu "Options"
+	 depends on PACKAGE_libpqxx
+
+config LIBPQXX_STATIC
+    bool "Build static library"
+	default y
+	help
+		Build static (.a) library
+
+config LIBPQXX_SHARED
+    bool "Build and install shared library"
+	default n
+	help
+		Build and install shared (.so) library
+
+config LIBPQXX_INSTALL_TEST
+    bool "Build and install test suite"
+	default n
+	depends on LIBPQXX_STATIC || LIBPQXX_SHARED
+	help
+		Build and install a test suite against a real server.
+		One can run this suite on a target platform to ensure
+		that the library is built the way it should and operating
+		correctly.
+
+endmenu
diff --git a/external/subpack/libs/libpqxx/Makefile b/external/subpack/libs/libpqxx/Makefile
new file mode 100644
index 0000000..72f3dd2
--- /dev/null
+++ b/external/subpack/libs/libpqxx/Makefile
@@ -0,0 +1,50 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libpqxx
+PKG_VERSION:=7.9.2
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/jtv/libpqxx
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_MIRROR_HASH:=3bc0572b06b6030d046aa1f11b64d644e78a688f58febbc2b4597f07672b22a8
+
+CMAKE_INSTALL:=1
+
+PKG_MAINTAINER:=Igor Bezzubchenko <garikello@gmail.com>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libpqxx
+	SECTION:=libs
+	CATEGORY:=Libraries
+	DEPENDS:=+libpq +libstdcpp
+	TITLE:=PostgreSQL client library (C++ interface)
+	URL:=http://pqxx.org/development/libpqxx
+	SUBMENU:=Database
+endef
+
+define Package/libpqxx/config
+	source "$(SOURCE)/Config.in"
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_DOC=OFF \
+	-DBUILD_STATIC_LIBS=O$(if $(CONFIG_LIBPQXX_STATIC),N,FF) \
+	-DBUILD_SHARED_LIBS=O$(if $(CONFIG_LIBPQXX_SHARED),N,FF) \
+	$(if $(CONFIG_LIBPQXX_INSTALL_TEST),\
+		-DINSTALL_TEST=ON  -DSKIP_BUILD_TEST=OFF, \
+		-DINSTALL_TEST=OFF -DSKIP_BUILD_TEST=ON \
+	)
+
+define Package/libpqxx/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(if $(CONFIG_LIBPQXX_SHARED), \
+		$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpqxx*.so $(1)/usr/lib/)
+	$(if $(CONFIG_LIBPQXX_INSTALL_TEST), \
+		$(CP) $(PKG_INSTALL_DIR)/usr/bin/libpqxx* $(1)/usr/bin/)
+endef
+
+$(eval $(call BuildPackage,libpqxx))
diff --git a/external/subpack/libs/libpsl/Makefile b/external/subpack/libs/libpsl/Makefile
new file mode 100644
index 0000000..e554c00
--- /dev/null
+++ b/external/subpack/libs/libpsl/Makefile
@@ -0,0 +1,49 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libpsl
+PKG_VERSION:=0.21.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/rockdaboot/libpsl/releases/download/$(PKG_VERSION)
+PKG_HASH:=1dcc9ceae8b128f3c0b3f654decd0e1e891afc6ff81098f227ef260449dae208
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libpsl
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=C library to handle the Public Suffix List
+  URL:=https://github.com/rockdaboot/libpsl
+  DEPENDS:=+libidn2 +libunistring $(INTL_DEPENDS)
+  ABI_VERSION:=5
+endef
+
+define Package/libpsl/description
+  C library to handle the Public Suffix List
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libpsl.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpsl.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libpsl.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libpsl/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpsl.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libpsl))
diff --git a/external/subpack/libs/libqmi/Config.in b/external/subpack/libs/libqmi/Config.in
new file mode 100644
index 0000000..46f3611
--- /dev/null
+++ b/external/subpack/libs/libqmi/Config.in
@@ -0,0 +1,33 @@
+menu "Configuration"
+	depends on PACKAGE_libqmi
+
+config LIBQMI_WITH_MBIM_QMUX
+	bool "Include MBIM QMUX service support"
+	default y
+	help
+	  Compile libqmi with QMI-over-MBIM support
+
+config LIBQMI_WITH_QRTR_GLIB
+	bool "Include QRTR support"
+	default y
+	help
+	  Compile libqmi with QRTR support
+
+choice
+	prompt "Select QMI message collection to build"
+	default LIBQMI_COLLECTION_BASIC
+
+	config LIBQMI_COLLECTION_MINIMAL
+		depends on !MODEMMANAGER_WITH_QMI
+		depends on !FWUPD_PLUGIN_MODEMMANAGER
+		bool "minimal"
+
+	config LIBQMI_COLLECTION_BASIC
+		depends on !FWUPD_PLUGIN_MODEMMANAGER
+		bool "basic (default)"
+
+	config LIBQMI_COLLECTION_FULL
+		bool "full"
+endchoice
+
+endmenu
diff --git a/external/subpack/libs/libqmi/Makefile b/external/subpack/libs/libqmi/Makefile
new file mode 100644
index 0000000..f743052
--- /dev/null
+++ b/external/subpack/libs/libqmi/Makefile
@@ -0,0 +1,119 @@
+#
+# Copyright (C) 2016 Velocloud Inc.
+# Copyright (C) 2016 Aleksander Morgado <aleksander@aleksander.es>
+#
+# This is free software, licensed under the GNU General Public License v2.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libqmi
+PKG_VERSION:=1.34.0
+PKG_RELEASE:=2
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libqmi.git
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_MIRROR_HASH:=65ee91b81c6f68d908cc94a0b5d670eefa29d550ecf8ef94cb836981fbfa4c2a
+
+PKG_BUILD_FLAGS:=gc-sections
+
+PKG_MAINTAINER:=Nicholas Smith <nicholas@nbembedded.com>
+PKG_CPE_ID:=cpe:/a:libqmi_project:libqmi
+
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_LIBQMI_COLLECTION_FULL \
+	CONFIG_LIBQMI_COLLECTION_BASIC \
+	CONFIG_LIBQMI_COLLECTION_MINIMAL
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+TARGET_CFLAGS += -fno-merge-all-constants -fmerge-constants
+
+define Package/libqmi/config
+  source "$(SOURCE)/Config.in"
+endef
+
+define Package/libqmi
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:= \
+    +glib2 \
+    +LIBQMI_WITH_MBIM_QMUX:libmbim \
+    +LIBQMI_WITH_QRTR_GLIB:libqrtr-glib
+  TITLE:=Helper library to talk to QMI enabled modems
+  URL:=https://www.freedesktop.org/wiki/Software/libqmi
+  LICENSE:=LGPL-2.0-or-later
+  LICENSE_FILES:=COPYING.LIB
+endef
+
+define Package/libqmi/description
+  Helper library talk to QMI enabled modems.
+  Add qmi-utils for extra utilities.
+endef
+
+define Package/qmi-utils
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libqmi
+  TITLE:=Utilities to talk to QMI enabled modems
+  URL:=https://www.freedesktop.org/wiki/Software/libqmi
+  LICENSE:=GPL-2.0-or-later
+  LICENSE_FILES:=COPYING
+endef
+
+define Package/libqmi-utils/description
+  Utils to talk to QMI enabled modems
+endef
+
+MESON_ARGS += \
+	-Dudev=false \
+	-Dintrospection=false \
+	-Dman=false \
+	-Dbash_completion=false \
+	-Db_lto=true \
+	-Dmbim_qmux=$(if $(CONFIG_LIBQMI_WITH_MBIM_QMUX),true,false) \
+	-Dqrtr=$(if $(CONFIG_LIBQMI_WITH_QRTR_GLIB),true,false) \
+	-Dcollection=$(if $(CONFIG_LIBQMI_COLLECTION_MINIMAL),minimal\
+		    ,$(if $(CONFIG_LIBQMI_COLLECTION_BASIC),basic,full))
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/libqmi-glib \
+		$(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libqmi*.so* \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/qmi-glib.pc \
+		$(1)/usr/lib/pkgconfig
+endef
+
+define Package/libqmi/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib \
+		$(1)/usr/libexec
+
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libqmi*.so.* \
+		$(1)/usr/lib/
+
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/libexec/qmi-proxy $(1)/usr/libexec/
+endef
+
+define Package/qmi-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/qmicli $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/qmi-network $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/qmi-firmware-update $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libqmi))
+$(eval $(call BuildPackage,qmi-utils))
diff --git a/external/subpack/libs/libqrtr-glib/Makefile b/external/subpack/libs/libqrtr-glib/Makefile
new file mode 100644
index 0000000..9e8e288
--- /dev/null
+++ b/external/subpack/libs/libqrtr-glib/Makefile
@@ -0,0 +1,72 @@
+#
+# Copyright (C) 2016 Velocloud Inc.
+# Copyright (C) 2016 Aleksander Morgado <aleksander@aleksander.es>
+#
+# This is free software, licensed under the GNU General Public License v2.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libqrtr-glib
+PKG_VERSION:=1.2.2
+PKG_RELEASE:=3
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libqrtr-glib.git
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_MIRROR_HASH:=483e17daa7ad17928d53a11fa3bed6201f3a94ce16cfd0b5bff39941de14d115
+
+PKG_BUILD_FLAGS:=gc-sections
+
+PKG_MAINTAINER:=Nicholas Smith <nicholas.smith@telcoantennas.com.au>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+TARGET_CFLAGS += -fno-merge-all-constants -fmerge-constants
+
+define Package/libqrtr-glib
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+glib2
+  TITLE:=Helper library to talk to QRTR enabled modems
+  URL:=https://gitlab.freedesktop.org/mobile-broadband/libqrtr-glib
+  LICENSE:=LGPL-2.1-or-later
+  LICENSE_FILES:=COPYING.LIB
+endef
+
+define Package/libqrtr-glib/description
+  Helper library talk to QRTR enabled modems.
+endef
+
+MESON_ARGS += \
+	-Dintrospection=false \
+	-Dgtk_doc=false \
+	-Db_lto=true
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/libqrtr-glib \
+		$(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libqrtr-glib*.so* \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/qrtr-glib.pc \
+		$(1)/usr/lib/pkgconfig
+endef
+
+define Package/libqrtr-glib/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libqrtr-glib*.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libqrtr-glib))
diff --git a/external/subpack/libs/libradcli/Config.in b/external/subpack/libs/libradcli/Config.in
new file mode 100644
index 0000000..35c3a22
--- /dev/null
+++ b/external/subpack/libs/libradcli/Config.in
@@ -0,0 +1,10 @@
+# radcli avanced configuration
+
+menu "Configuration"
+	depends on PACKAGE_libradcli
+
+config RADCLI_TLS
+	bool "enable TLS support"
+	default y
+
+endmenu
diff --git a/external/subpack/libs/libradcli/Makefile b/external/subpack/libs/libradcli/Makefile
new file mode 100644
index 0000000..f3a7dc0
--- /dev/null
+++ b/external/subpack/libs/libradcli/Makefile
@@ -0,0 +1,76 @@
+#
+# Copyright (C) 2015 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:=libradcli
+PKG_VERSION:=1.3.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=radcli-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/radcli/radcli/releases/download/$(PKG_VERSION)
+PKG_HASH:=20ddc8429d5912dfa2e71fafc93881844ce98e898c041b1dd7f757b9ddc8fcfd
+PKG_BUILD_DIR:=$(BUILD_DIR)/radcli-$(PKG_VERSION)
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libradcli
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A library for radius clients
+  URL:=https://radcli.github.io/radcli
+  MAINTAINER:=Nikos Mavrogiannopoulos <nmav@gnutls.org>
+  DEPENDS:= +RADCLI_TLS:libgnutls +libnettle
+endef
+
+define Package/libradcli/decription
+  The radcli library is a library for writing RADIUS Clients. The library's
+  approach is to allow writing RADIUS-aware application in less than 50 lines
+  of C code. It was based originally on freeradius-client and is source 
+  compatible with it.
+endef
+
+CONFIGURE_ARGS+= \
+	--enable-legacy-compat
+
+ifneq ($(CONFIG_RADCLI_TLS),y)
+CONFIGURE_ARGS += --without-tls
+endif
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/radcli
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/radcli/radcli.h \
+		$(PKG_INSTALL_DIR)/usr/include/radcli/version.h \
+		$(1)/usr/include/radcli
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/freeradius-client.h \
+		$(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libradcli.so* \
+		$(PKG_INSTALL_DIR)/usr/lib/libfreeradius-client.so \
+		$(1)/usr/lib/
+endef
+
+define Package/libradcli/conffiles
+/etc/radcli/radiusclient.conf
+endef
+
+define Package/libradcli/install
+	$(INSTALL_DIR) $(1)/etc/radcli
+	$(INSTALL_CONF) $(PKG_BUILD_DIR)/etc/radiusclient.conf $(1)/etc/radcli/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libradcli.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libradcli))
diff --git a/external/subpack/libs/libradiotap/Makefile b/external/subpack/libs/libradiotap/Makefile
new file mode 100644
index 0000000..0ba095a
--- /dev/null
+++ b/external/subpack/libs/libradiotap/Makefile
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2016 Bruno Randolf (br1@einfach.org)
+#               2019 Nick Hainke (vincent@systemli.org)
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libradiotap
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/radiotap/radiotap-library
+PKG_SOURCE_DATE:=2023-10-09
+PKG_SOURCE_VERSION:=ee71d224e0faeb9ec4e198d587d4e5aac60d4afe
+PKG_MIRROR_HASH:=c829fcbaaef8ab15467b241fca331d484825bb8de1bf3a59bf29727345ec88d3
+
+PKG_MAINTAINER:=Nick Hainke <vincent@systemli.org>
+PKG_LICENSE:=ISC
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libradiotap
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=Radiotap Parser Library
+	URL:=https://www.radiotap.org/
+endef
+
+define Package/libradiotap/description
+	Library that supplies additional information about frames from the driver to userspace applications.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/radiotap* $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libradiotap.so* $(1)/usr/lib/
+endef
+
+define Package/libradiotap/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libradiotap.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libradiotap))
diff --git a/external/subpack/libs/libre2/Makefile b/external/subpack/libs/libre2/Makefile
new file mode 100644
index 0000000..c43c9ae
--- /dev/null
+++ b/external/subpack/libs/libre2/Makefile
@@ -0,0 +1,53 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=re2
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/google/re2
+PKG_SOURCE_DATE:=2023-02-01
+PKG_SOURCE_VERSION:=b025c6a3ae05995660e3b882eb3277f4399ced1a
+PKG_MIRROR_HASH:=b473f4fd10d9f0afd65d409cf11dd1fd7b4010cfa4e07cfc99d33e382390baef
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/re2
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libstdcpp
+  TITLE:=RE2 - C++ regular expression library
+  URL:=https://github.com/google/re2
+  ABI_VERSION:=10
+endef
+
+define Package/re2/description
+  RE2 is a fast, safe, thread-friendly alternative to backtracking regular
+  expression engines like those used in PCRE, Perl, and Python.
+  It is a C++ library.
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_SHARED_LIBS=ON
+
+TARGET_LDFLAGS += \
+	-Wl,--as-needed,--gc-sections
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/re2.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/re2.pc
+endef
+
+define Package/re2/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libre2.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,re2))
diff --git a/external/subpack/libs/libredblack/Makefile b/external/subpack/libs/libredblack/Makefile
new file mode 100644
index 0000000..5f1bcc7
--- /dev/null
+++ b/external/subpack/libs/libredblack/Makefile
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2017 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:=libredblack
+PKG_VERSION:=1.3
+PKG_RELEASE:=4
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/libredblack
+PKG_HASH:=a0ecc59b0aae2df01558a6950532c711a782a099277b439a51d270003092f44f
+
+PKG_MAINTAINER:=Mislav Novakovic <mislav.novakovic@sartura.hr>
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+define Package/libredblack
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=RedBlack tree library
+  URL:=http://libredblack.sourceforge.net/
+endef
+
+define Package/libredblack/description
+ RedBlack Balanced Tree Searching and Sorting Library.
+endef
+
+CONFIGURE_ARGS += --without-rbgen
+CONFIGURE_VARS += lt_cv_prog_cc_pic="$(FPIC)"
+MAKE_FLAGS += CFLAGS="$(TARGET_CFLAGS)"
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libredblack.{so*,a,la} $(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/redblack.h $(1)/usr/include/
+endef
+
+define Package/libredblack/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libredblack.so* $(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/include/redblack.h $(1)/usr/include
+endef
+
+$(eval $(call BuildPackage,libredblack))
diff --git a/external/subpack/libs/librouteros/Makefile b/external/subpack/libs/librouteros/Makefile
new file mode 100644
index 0000000..1d5a6b4
--- /dev/null
+++ b/external/subpack/libs/librouteros/Makefile
@@ -0,0 +1,54 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=librouteros
+PKG_SOURCE_DATE:=2018-07-19
+PKG_SOURCE_VERSION:=c485c777ffbbbd87c3d72d843af36ba016803cae
+PKG_RELEASE:=2
+
+PKG_MAINTAINER:=Sven Roederer <devel-sven@geroedel.de>
+PKG_LICENSE:=ISC
+PKG_LICENSE_FILES:=COPYING
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/octo/librouteros/tar.gz/$(PKG_SOURCE_VERSION)?
+PKG_HASH:=427e071fe270ff6c08e32a10e5beff2add4205e6c864b142f950efdb8d2245a4
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION)
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/librouteros
+  TITLE:=A library that talks to MikroTik devices.
+  URL:=https://octo.github.io/librouteros/
+  SECTION:=libs
+  CATEGORY:=Libraries
+endef
+
+define Package/librouteros/description
+  librouteros is a library to communicate with RouterOS, the operating system of MikroTik's RouterBoards.
+  It uses the API port provided by those systems to connect and talk to the devices. librouteros is a
+  low-level library in that it abstracts the network protocol used but has next to no knowledge about the
+  commands and responses available
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/routeros_*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/librouteros.{a,la,so*} $(1)/usr/lib/
+endef
+
+define Package/librouteros/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/librouteros.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,librouteros))
diff --git a/external/subpack/libs/librouteros/patches/010-no-doc.patch b/external/subpack/libs/librouteros/patches/010-no-doc.patch
new file mode 100644
index 0000000..8a07e30
--- /dev/null
+++ b/external/subpack/libs/librouteros/patches/010-no-doc.patch
@@ -0,0 +1,7 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,3 +1,3 @@
+-SUBDIRS = src doc
++SUBDIRS = src
+ 
+ README:	README.md
diff --git a/external/subpack/libs/libroxml/Makefile b/external/subpack/libs/libroxml/Makefile
new file mode 100644
index 0000000..29bf986
--- /dev/null
+++ b/external/subpack/libs/libroxml/Makefile
@@ -0,0 +1,47 @@
+#
+# Copyright (C) 2014 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:=libroxml
+PKG_VERSION:=3.0.2
+PKG_RELEASE:=3
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://download.libroxml.net/pool/v3.x
+PKG_HASH:=ed6d68d1bceabf98e5e76907411e2e4d93b2dbd48479ab41dede851f59dad6a3
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=License.txt
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libroxml
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Minimum, easy-to-use, C implementation for xml file parsing
+  URL:=http://www.libroxml.net/
+  ABI_VERSION:=2
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_TESTING=OFF \
+	-DCONFIG_XML_FILE=OFF \
+	-DCONFIG_XML_EDIT=OFF \
+	-DCONFIG_XML_COMMIT=OFF \
+	-DCONFIG_XML_XPATH=OFF
+
+define Package/libroxml/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libroxml.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libroxml))
diff --git a/external/subpack/libs/libroxml/patches/010-gcc10.patch b/external/subpack/libs/libroxml/patches/010-gcc10.patch
new file mode 100644
index 0000000..3c4fee6
--- /dev/null
+++ b/external/subpack/libs/libroxml/patches/010-gcc10.patch
@@ -0,0 +1,11 @@
+--- a/src/roxml_mem.h
++++ b/src/roxml_mem.h
+@@ -14,7 +14,7 @@
+ 
+ #include "roxml_internal.h"
+ 
+-memory_cell_t head_cell;
++extern memory_cell_t head_cell;
+ 
+ /** \brief alloc memory function
+  *
diff --git a/external/subpack/libs/libroxml/patches/020-gcc14.patch b/external/subpack/libs/libroxml/patches/020-gcc14.patch
new file mode 100644
index 0000000..e20d75c
--- /dev/null
+++ b/external/subpack/libs/libroxml/patches/020-gcc14.patch
@@ -0,0 +1,31 @@
+--- a/src/roxml_mem.c
++++ b/src/roxml_mem.c
+@@ -20,7 +20,7 @@ ROXML_STATIC ROXML_INT inline void roxml
+ 	memory_cell_t *ptr = &head_cell;
+ 	memory_cell_t *to_delete = NULL;
+ 
+-	while ((ptr->prev != NULL) && (ptr->prev->id != pthread_self()))
++	while ((ptr->prev != NULL) && (ptr->prev->id != (unsigned long int)pthread_self()))
+ 		ptr = ptr->prev;
+ 
+ 	if (ptr->prev == NULL)
+@@ -135,7 +135,7 @@ ROXML_INT void *roxml_malloc(int size, i
+ 	cell->next->prev = cell;
+ 	cell = cell->next;
+ 	cell->type = type;
+-	cell->id = pthread_self();
++	cell->id = (unsigned long int)pthread_self();
+ 	cell->occ = size;
+ 	cell->ptr = calloc(num, size);
+ 	head_cell.prev = cell;
+--- a/src/roxml_utils.h
++++ b/src/roxml_utils.h
+@@ -48,7 +48,7 @@ ROXML_STATIC_INLINE ROXML_INT int roxml_
+ #else /* CONFIG_XML_THREAD_SAFE==1 */
+ ROXML_STATIC_INLINE ROXML_INT unsigned long int roxml_thread_id(node_t *n)
+ {
+-	return pthread_self();
++	return (unsigned long int)pthread_self();
+ }
+ 
+ ROXML_STATIC_INLINE ROXML_INT int roxml_lock_init(node_t *n)
diff --git a/external/subpack/libs/libsamplerate/Makefile b/external/subpack/libs/libsamplerate/Makefile
new file mode 100644
index 0000000..147b4b1
--- /dev/null
+++ b/external/subpack/libs/libsamplerate/Makefile
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2007-2014 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:=libsamplerate
+PKG_VERSION:=0.2.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/libsndfile/libsamplerate/releases/download/$(PKG_VERSION)
+PKG_HASH:=3258da280511d24b49d6b08615bbe824d0cacc9842b0e4caf11c52cf2b043893
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libsamplerate_project:libsamplerate
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libsamplerate
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libsndfile
+  TITLE:=Sample Rate Converter
+  URL:=https://libsndfile.github.io/libsamplerate/
+endef
+
+define Package/libsamplerate/description
+ Secret Rabbit Code (aka libsamplerate) is a Sample Rate
+ Converter for audio.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+	--disable-fftw \
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)
+	$(CP) $(PKG_INSTALL_DIR)/* $(1)/
+endef
+
+define Package/libsamplerate/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsamplerate.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libsamplerate))
diff --git a/external/subpack/libs/libseccomp/Makefile b/external/subpack/libs/libseccomp/Makefile
new file mode 100644
index 0000000..df26514
--- /dev/null
+++ b/external/subpack/libs/libseccomp/Makefile
@@ -0,0 +1,96 @@
+#
+# Copyright (C) 2014-2015 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:=libseccomp
+PKG_VERSION:=2.5.5
+PKG_RELEASE:=1
+PKG_BUILD_FLAGS:=no-mips16
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/seccomp/libseccomp/releases/download/v$(PKG_VERSION)/
+PKG_HASH:=248a2c8a4d9b9858aa6baf52712c34afefcf9c9e94b76dce02c1c9aa25fb3375
+
+PKG_MAINTAINER:=Nikos Mavrogiannopoulos <nmav@gnutls.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:libseccomp_project:libseccomp
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_DEPENDS:=gperf/host
+PKG_LIBTOOL_PATHS:=. lib
+
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_KERNEL_SECCOMP
+
+include $(INCLUDE_DIR)/package.mk
+
+# This is done instead of DEPENDS:=@!arc to avoid a recursive dependency when
+# the library is conditionally selected by util/lxc.
+define Package/libseccomp/config
+  depends on !arc
+endef
+
+define Package/libseccomp/Default
+  SUBMENU:=
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=seccomp
+  URL:=https://github.com/seccomp/libseccomp/wiki
+endef
+
+define Package/libseccomp/Default/description
+ The libseccomp library provides an easy to use, platform independent, interface
+ to the Linux Kernel's syscall filtering mechanism.  The libseccomp API is
+ designed to abstract away the underlying BPF based syscall filter language and
+ present a more conventional function-call based filtering interface that should
+ be familiar to, and easily adopted by, application developers.
+endef
+
+define Package/libseccomp
+$(call Package/libseccomp/Default)
+  TITLE+= (library)
+endef
+
+define Package/scmp_sys_resolver
+$(call Package/libseccomp/Default)
+  TITLE+= scmp_sys_resolver
+  DEPENDS+= libseccomp
+endef
+
+define Package/libseccomp/description
+ This package contains the seccomp library.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib/pkgconfig
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/seccomp*.h \
+		$(1)/usr/include/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libseccomp.{a,so*} \
+		$(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libseccomp.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libseccomp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libseccomp.so.* $(1)/usr/lib/
+endef
+
+define Package/scmp_sys_resolver/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/scmp_sys_resolver $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libseccomp))
+$(eval $(call BuildPackage,scmp_sys_resolver))
diff --git a/external/subpack/libs/libseccomp/patches/010-no-code-coverage.patch b/external/subpack/libs/libseccomp/patches/010-no-code-coverage.patch
new file mode 100644
index 0000000..093bace
--- /dev/null
+++ b/external/subpack/libs/libseccomp/patches/010-no-code-coverage.patch
@@ -0,0 +1,10 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -16,7 +16,6 @@
+ # along with this library; if not, see <http://www.gnu.org/licenses>.
+ #
+ 
+-@CODE_COVERAGE_RULES@
+ 
+ CODE_COVERAGE_OUTPUT_FILE = libseccomp.lcov.info
+ CODE_COVERAGE_OUTPUT_DIRECTORY = libseccomp.lcov.html.d
diff --git a/external/subpack/libs/libshout/Makefile b/external/subpack/libs/libshout/Makefile
new file mode 100644
index 0000000..9cd11e4
--- /dev/null
+++ b/external/subpack/libs/libshout/Makefile
@@ -0,0 +1,119 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libshout
+PKG_VERSION:=2.4.6
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://downloads.us.xiph.org/releases/libshout/
+PKG_HASH:=39cbd4f0efdfddc9755d88217e47f8f2d7108fa767f9d58a2ba26a16d8f7c910
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libshout:libshout
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libshout/default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Shoutcast client library
+  URL:=http://www.icecast.org
+  DEPENDS:= +libvorbisidec +libpthread
+endef
+
+define Package/libshout
+  $(call Package/libshout/default)
+  TITLE+= (no theora)
+  DEPENDS+= +libopenssl
+  VARIANT:=notheora
+endef
+
+define Package/libshout-nossl
+  $(call Package/libshout/default)
+  TITLE+= (no ssl/theora)
+  VARIANT:=nossl
+endef
+
+define Package/libshout-full
+  $(call Package/libshout/default)
+  TITLE+=(full)
+  DEPENDS+= +libtheora +libopenssl
+  VARIANT:=full
+endef
+
+define Package/libshout/description/default
+ libshout allows applications to easily communicate and broadcast
+ to an Icecast streaming media server. It handles the socket connections,
+ metadata communication, and data streaming for the calling application,
+ and lets developers focus on feature sets instead of implementation
+ details.
+endef
+
+define Package/libshout/description
+  $(call Package/libshout/description/default)
+  .
+  This package does not have Theora support.
+endef
+
+define Package/libshout-nossl/description
+  $(call Package/libshout/description/default)
+  .
+  This package does not have OpenSSL or Theora support.
+endef
+
+Package/libshout-full/description=$(Package/libshout/description/default)
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--disable-speex \
+	--without-pic
+
+ifeq ($(BUILD_VARIANT),notheora)
+  CONFIGURE_ARGS += --disable-theora
+endif
+
+ifeq ($(BUILD_VARIANT),nossl)
+  CONFIGURE_ARGS += --disable-theora --without-openssl
+endif
+
+CONFIGURE_VARS += \
+	VORBIS_CFLAGS="-I$(STAGING_DIR)/usr/include/tremor/" \
+	VORBIS_LIBS="$(TARGET_LDFLAGS) -lvorbisidec" \
+
+TARGET_CFLAGS += $(FPIC)
+
+PACKAGE_CONFIG_FILE=shout$(if $(findstring $(BUILD_VARIANT),full),-full).pc
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/shout $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libshout.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/shout.pc $(1)/usr/lib/pkgconfig/$(PACKAGE_CONFIG_FILE)
+	$(SED) 's| -I/usr/include||' $(1)/usr/lib/pkgconfig/$(PACKAGE_CONFIG_FILE)
+endef
+
+define Package/libshout/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libshout.so.* $(1)/usr/lib/
+endef
+
+Package/libshout-full/install=$(Package/libshout/install)
+Package/libshout-nossl/install=$(Package/libshout/install)
+
+$(eval $(call BuildPackage,libshout))
+$(eval $(call BuildPackage,libshout-nossl))
+$(eval $(call BuildPackage,libshout-full))
diff --git a/external/subpack/libs/libshout/patches/010-gcc14.patch b/external/subpack/libs/libshout/patches/010-gcc14.patch
new file mode 100644
index 0000000..0ff6839
--- /dev/null
+++ b/external/subpack/libs/libshout/patches/010-gcc14.patch
@@ -0,0 +1,11 @@
+--- a/src/shout_private.h
++++ b/src/shout_private.h
+@@ -33,6 +33,8 @@
+ #include <common/timing/timing.h>
+ #include "util.h"
+ 
++#include <stdio.h>
++#include <stdlib.h>
+ #include <sys/types.h>
+ 
+ #ifdef HAVE_STDINT_H
diff --git a/external/subpack/libs/libshout/patches/100-add_with-openssl_option.patch b/external/subpack/libs/libshout/patches/100-add_with-openssl_option.patch
new file mode 100644
index 0000000..7319e29
--- /dev/null
+++ b/external/subpack/libs/libshout/patches/100-add_with-openssl_option.patch
@@ -0,0 +1,27 @@
+--- a/m4/xiph_openssl.m4
++++ b/m4/xiph_openssl.m4
+@@ -29,14 +29,16 @@ else
+     fi
+ fi
+ 
+-# Now try linking to openssl
+-xt_save_CFLAGS="$CFLAGS"
+-xt_save_LIBS="$LIBS"
+-CFLAGS="$CFLAGS $OPENSSL_CFLAGS"
+-LIBS="$OPENSSL_LIBS $LIBS"
+-AC_TRY_LINK([#include <openssl/ssl.h>], [void *a = SSL_new], [openssl_ok='yes'])
+-CFLAGS="$xt_save_CFLAGS"
+-LIBS="$xt_save_LIBS"
++if test "x$openssl_prefix" != "xno"; then
++    # Now try linking to openssl
++    xt_save_CFLAGS="$CFLAGS"
++    xt_save_LIBS="$LIBS"
++    CFLAGS="$CFLAGS $OPENSSL_CFLAGS"
++    LIBS="$OPENSSL_LIBS $LIBS"
++    AC_TRY_LINK([#include <openssl/ssl.h>], [void *a = SSL_new], [openssl_ok='yes'])
++    CFLAGS="$xt_save_CFLAGS"
++    LIBS="$xt_save_LIBS"
++fi
+ 
+ if test "$openssl_ok" = "yes"; then
+     AC_DEFINE(HAVE_OPENSSL, 1, [Define if you have libopenssl.])
diff --git a/external/subpack/libs/libshout/patches/120-vorbis-c.patch b/external/subpack/libs/libshout/patches/120-vorbis-c.patch
new file mode 100644
index 0000000..d7886b7
--- /dev/null
+++ b/external/subpack/libs/libshout/patches/120-vorbis-c.patch
@@ -0,0 +1,11 @@
+--- a/src/codec_vorbis.c
++++ b/src/codec_vorbis.c
+@@ -29,7 +29,7 @@
+ #endif
+ #include <stdlib.h>
+ 
+-#include <vorbis/codec.h>
++#include <tremor/ivorbiscodec.h>
+ 
+ #include "shout_private.h"
+ #include "format_ogg.h"
diff --git a/external/subpack/libs/libslirp/Makefile b/external/subpack/libs/libslirp/Makefile
new file mode 100644
index 0000000..a4c2039
--- /dev/null
+++ b/external/subpack/libs/libslirp/Makefile
@@ -0,0 +1,49 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libslirp
+PKG_VERSION:=4.7.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-v$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://gitlab.freedesktop.org/slirp/$(PKG_NAME)/-/archive/v$(PKG_VERSION)
+PKG_HASH:=9398f0ec5a581d4e1cd6856b88ae83927e458d643788c3391a39e61b75db3d3b
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-v$(PKG_VERSION)
+
+PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmailcom>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libslirp_project:libslirp
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libslirp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=Networking
+  TITLE:=user-mode networking library for virtual environments
+  DEPENDS:=+glib2
+  URL:=https://gitlab.freedesktop.org/slirp/libslirp
+endef
+
+define Package/libslirp/description
+  libslirp is a user-mode networking library used by virtual machines,
+  containers or various tools.
+endef
+
+define Package/libslirp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libslirp.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libslirp.so.* $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib $(1)/usr/include/slirp $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libslirp.so $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libslirp.so.* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/slirp/** $(1)/usr/include/slirp/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/** $(1)/usr/lib/pkgconfig/
+endef
+
+$(eval $(call BuildPackage,libslirp))
diff --git a/external/subpack/libs/libsndfile/Makefile b/external/subpack/libs/libsndfile/Makefile
new file mode 100644
index 0000000..f600431
--- /dev/null
+++ b/external/subpack/libs/libsndfile/Makefile
@@ -0,0 +1,58 @@
+#
+# Copyright (C) 2007-2019 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:=libsndfile
+PKG_VERSION:=1.2.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/libsndfile/libsndfile/releases/download/$(PKG_VERSION)
+PKG_HASH:=3799ca9924d3125038880367bf1468e53a1b7e3686a934f098b7e1d286cdb80e
+
+PKG_MAINTAINER:=Peter Wagner <tripolar@gmx.at>
+PKG_LICENSE:=LGPLv2.1
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libsndfile_project:libsndfile
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libsndfile
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Library for reading/writing audio files
+  URL:=https://libsndfile.github.io/libsndfile/
+  DEPENDS:=+lame-lib +libmpg123
+endef
+
+define Package/libsndfile/description
+ libsndfile is a library of C routines for reading and writing files
+ containing sampled audio data.
+endef
+
+CMAKE_OPTIONS += \
+	-DENABLE_MPEG=ON \
+	-DBUILD_SHARED_LIBS=ON \
+	-DENABLE_EXTERNAL_LIBS=OFF
+
+TARGET_CFLAGS += $(FPIC)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)
+	$(CP) $(PKG_INSTALL_DIR)/* $(1)/
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/sndfile.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/sndfile.pc
+endef
+
+define Package/libsndfile/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsndfile.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libsndfile))
diff --git a/external/subpack/libs/libsoc/Makefile b/external/subpack/libs/libsoc/Makefile
new file mode 100644
index 0000000..1dbf0b1
--- /dev/null
+++ b/external/subpack/libs/libsoc/Makefile
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2017 Yegor Yefremov <yegorslists@googlemail.com>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libsoc
+PKG_RELEASE:=2
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/jackmitch/libsoc.git
+PKG_MIRROR_HASH:=6aefbd76922fd6b606b9fcbda555dfe079f3afe445a6180d8be0fbb8fd27f424
+PKG_SOURCE_DATE:=2016-12-22
+PKG_SOURCE_VERSION:=5b788d4d558a78c52e6cfe97325e4564b307a3a0
+
+PKG_MAINTAINER:=Yegor Yefremov <yegorslists@googlemail.com>
+PKG_LICENSE:=LGPL-2.1
+PKG_LICENSE_FILES:=LICENCE
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libsoc
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libpthread
+  TITLE:=SoC Library
+  URL:=https://github.com/jackmitch/libsoc
+endef
+
+define Package/libsoc/description
+  libsoc: C library for interfacing with common SoC peripherals through
+  generic kernel interfaces
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--disable-cxx
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libsoc_board.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libsoc_conffile.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libsoc_debug.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libsoc_gpio.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libsoc_i2c.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libsoc_pwm.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libsoc_spi.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsoc.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libsoc.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/libsoc/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsoc.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libsoc))
diff --git a/external/subpack/libs/libsocketcan/Makefile b/external/subpack/libs/libsocketcan/Makefile
new file mode 100644
index 0000000..67ba3a9
--- /dev/null
+++ b/external/subpack/libs/libsocketcan/Makefile
@@ -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))
diff --git a/external/subpack/libs/libsodium/Makefile b/external/subpack/libs/libsodium/Makefile
new file mode 100644
index 0000000..9c207f8
--- /dev/null
+++ b/external/subpack/libs/libsodium/Makefile
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2009-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:=libsodium
+PKG_VERSION:=1.0.19
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://download.libsodium.org/libsodium/releases \
+		https://github.com/jedisct1/libsodium/releases/download/$(PKG_VERSION)
+PKG_HASH:=018d79fe0a045cca07331d37bd0cb57b2e838c51bc48fd837a1472e50068bbea
+
+PKG_MAINTAINER:=Damiano Renfer <x9w2n7xnu@relay.firefox.com>
+PKG_LICENSE:=ISC
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_FLAGS:=no-mips16
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+TAR_OPTIONS+= --strip-components 1
+TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS)
+
+define Package/libsodium
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=P(ortable|ackageable) NaCl-based crypto library
+  URL:=https://github.com/jedisct1/libsodium
+endef
+
+define Package/libsodium/description
+  NaCl (pronounced "salt") is a new easy-to-use high-speed software library for network communication, encryption, decryption, signatures, etc.
+  NaCl's goal is to provide all of the core operations needed to build higher-level cryptographic tools.
+  Sodium is a portable, cross-compilable, installable, packageable fork of NaCl (based on the latest released upstream version nacl-20110221), with a compatible API.
+  The design choices, particularly in regard to the Curve25519 Diffie-Hellman function, emphasize security (whereas NIST curves emphasize "performance" at the cost of security), and "magic constants" in NaCl/Sodium have clear rationales.
+  The same cannot be said of NIST curves, where the specific origins of certain constants are not described by the standards.
+  And despite the emphasis on higher security, primitives are faster across-the-board than most implementations of the NIST standards.
+endef
+
+define Package/libsodium/config
+menu "Configuration"
+	depends on PACKAGE_libsodium
+	config LIBSODIUM_MINIMAL
+		bool "Compile only what is required for the high-level API (no aes128ctr), should be fine in most cases."
+		default y
+endmenu
+endef
+
+CONFIGURE_ARGS+= \
+	--disable-ssp \
+	$(if $(CONFIG_LIBSODIUM_MINIMAL),--enable,--disable)-minimal
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/sodium
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/sodium.h $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/sodium/*.h $(1)/usr/include/sodium
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsodium.{a,so*} $(1)/usr/lib
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libsodium.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libsodium/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsodium.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libsodium))
diff --git a/external/subpack/libs/libsodium/patches/001-revert-f5076db5f8ef27.patch b/external/subpack/libs/libsodium/patches/001-revert-f5076db5f8ef27.patch
new file mode 100644
index 0000000..c88ef10
--- /dev/null
+++ b/external/subpack/libs/libsodium/patches/001-revert-f5076db5f8ef27.patch
@@ -0,0 +1,36 @@
+--- a/src/libsodium/Makefile.am
++++ b/src/libsodium/Makefile.am
+@@ -73,6 +73,7 @@ libsodium_la_SOURCES = \
+ 	crypto_scalarmult/curve25519/ref10/x25519_ref10.h \
+ 	crypto_scalarmult/curve25519/scalarmult_curve25519.c \
+ 	crypto_scalarmult/curve25519/scalarmult_curve25519.h \
++	crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c \
+ 	crypto_secretbox/crypto_secretbox.c \
+ 	crypto_secretbox/crypto_secretbox_easy.c \
+ 	crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c \
+@@ -173,7 +174,6 @@ libsodium_la_SOURCES += \
+ 	crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h \
+ 	crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c \
+ 	crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c \
+-	crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c \
+ 	crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c \
+ 	crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c \
+ 	crypto_shorthash/siphash24/shorthash_siphashx24.c \
+--- a/src/libsodium/include/sodium.h
++++ b/src/libsodium/include/sodium.h
+@@ -39,6 +39,7 @@
+ #include "sodium/crypto_pwhash_argon2i.h"
+ #include "sodium/crypto_scalarmult.h"
+ #include "sodium/crypto_scalarmult_curve25519.h"
++#include "sodium/crypto_scalarmult_ed25519.h"
+ #include "sodium/crypto_secretbox.h"
+ #include "sodium/crypto_secretbox_xsalsa20poly1305.h"
+ #include "sodium/crypto_secretstream_xchacha20poly1305.h"
+@@ -64,7 +65,6 @@
+ #include "sodium/crypto_core_ed25519.h"
+ #include "sodium/crypto_core_ristretto255.h"
+ #include "sodium/crypto_pwhash_scryptsalsa208sha256.h"
+-#include "sodium/crypto_scalarmult_ed25519.h"
+ #include "sodium/crypto_scalarmult_ristretto255.h"
+ #include "sodium/crypto_secretbox_xchacha20poly1305.h"
+ #include "sodium/crypto_stream_salsa2012.h"
diff --git a/external/subpack/libs/libsodium/patches/100-minimal-build-with-ed25519-core.patch b/external/subpack/libs/libsodium/patches/100-minimal-build-with-ed25519-core.patch
new file mode 100644
index 0000000..7e92ffe
--- /dev/null
+++ b/external/subpack/libs/libsodium/patches/100-minimal-build-with-ed25519-core.patch
@@ -0,0 +1,36 @@
+--- a/src/libsodium/Makefile.am
++++ b/src/libsodium/Makefile.am
+@@ -23,6 +23,7 @@ libsodium_la_SOURCES = \
+ 	crypto_box/crypto_box_easy.c \
+ 	crypto_box/crypto_box_seal.c \
+ 	crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c \
++	crypto_core/ed25519/core_ed25519.c \
+ 	crypto_core/ed25519/ref10/ed25519_ref10.c \
+ 	crypto_core/hchacha20/core_hchacha20.c \
+ 	crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c \
+@@ -165,7 +166,6 @@ if !MINIMAL
+ libsodium_la_SOURCES += \
+ 	crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c \
+ 	crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c \
+-	crypto_core/ed25519/core_ed25519.c \
+ 	crypto_core/ed25519/core_ristretto255.c \
+ 	crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c \
+ 	crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h \
+--- a/src/libsodium/include/sodium.h
++++ b/src/libsodium/include/sodium.h
+@@ -16,6 +16,7 @@
+ #include "sodium/crypto_auth_hmacsha512256.h"
+ #include "sodium/crypto_box.h"
+ #include "sodium/crypto_box_curve25519xsalsa20poly1305.h"
++#include "sodium/crypto_core_ed25519.h"
+ #include "sodium/crypto_core_hchacha20.h"
+ #include "sodium/crypto_core_hsalsa20.h"
+ #include "sodium/crypto_core_salsa20.h"
+@@ -62,7 +63,6 @@
+ 
+ #ifndef SODIUM_LIBRARY_MINIMAL
+ #include "sodium/crypto_box_curve25519xchacha20poly1305.h"
+-#include "sodium/crypto_core_ed25519.h"
+ #include "sodium/crypto_core_ristretto255.h"
+ #include "sodium/crypto_pwhash_scryptsalsa208sha256.h"
+ #include "sodium/crypto_scalarmult_ristretto255.h"
diff --git a/external/subpack/libs/libsoup3/Makefile b/external/subpack/libs/libsoup3/Makefile
new file mode 100644
index 0000000..067903c
--- /dev/null
+++ b/external/subpack/libs/libsoup3/Makefile
@@ -0,0 +1,74 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libsoup3
+PKG_VERSION:=3.4.4
+PKG_RELEASE:=1
+
+PKG_SOURCE:=libsoup-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@GNOME/libsoup/$(basename $(PKG_VERSION))
+PKG_HASH:=291c67725f36ed90ea43efff25064b69c5a2d1981488477c05c481a3b4b0c5aa
+PKG_BUILD_DIR:=$(BUILD_DIR)/libsoup-$(PKG_VERSION)
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:gnome:libsoup
+
+PKG_BUILD_DEPENDS:=glib2/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libsoup3
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libsoup3
+  URL:=https://wiki.gnome.org/Projects/libsoup
+  DEPENDS:=+glib2 +libxml2 +libgnutls +libsqlite3 +libpsl +libnghttp2
+endef
+
+MESON_ARGS += \
+	-Dgssapi=disabled \
+	-Dntlm=disabled \
+	-Dbrotli=disabled \
+	-Dtls_check=false \
+	-Dintrospection=disabled \
+	-Dvapi=disabled \
+	-Dtests=false \
+	-Dinstalled_tests=false \
+	-Dsysprof=disabled
+
+define package/libsoup3/decription
+Libsoup is an HTTP library implementation in C
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/{lib/pkgconfig,include/libsoup-3.0/libsoup}
+
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libsoup-3.0.so* \
+		$(1)/usr/lib/
+
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* \
+		$(1)/usr/lib/pkgconfig/
+
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/include/libsoup-3.0/libsoup/*.h \
+		$(1)/usr/include/libsoup-3.0/libsoup/
+endef
+
+define Package/libsoup3/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libsoup-3.0.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libsoup3))
diff --git a/external/subpack/libs/libsoxr/Makefile b/external/subpack/libs/libsoxr/Makefile
new file mode 100644
index 0000000..b1b20f3
--- /dev/null
+++ b/external/subpack/libs/libsoxr/Makefile
@@ -0,0 +1,53 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+# updated to work with latest source from abrasive
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libsoxr
+PKG_VERSION:=0.1.3
+PKG_RELEASE:=2
+
+PKG_SOURCE_URL:=@SF/project/soxr/
+PKG_SOURCE:=soxr-$(PKG_VERSION)-Source.tar.xz
+PKG_HASH:=b111c15fdc8c029989330ff559184198c161100a59312f5dc19ddeb9b5a15889
+PKG_BUILD_DIR:=$(BUILD_DIR)/soxr-$(PKG_VERSION)-Source
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>, \
+		Mike Brady <mikebrady@eircom.net>
+PKG_LICENSE:=LGPL-2.1
+PKG_LICENSE_FILES:=LICENCE
+PKG_CPE_ID:=cpe:/a:sox:sox
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libsoxr
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=The SoX Resampler library
+  URL:=https://sourceforge.net/projects/soxr/
+  DEPENDS:= +libpthread
+endef
+
+define Package/libsoxr/description
+  The SoX Resampler library
+  High quality, one-dimensional sample-rate conversion library
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_TESTS=0 \
+	-DBUILD_EXAMPLES=0 \
+	-DWITH_OPENMP=0 \
+	-DHAVE_WORDS_BIGENDIAN_EXITCODE=$(if $(CONFIG_BIG_ENDIAN),0,1)
+
+define Package/libsoxr/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsoxr.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libsoxr))
diff --git a/external/subpack/libs/libsoxr/patches/010-Remove_automatic_avutil_inclusion.patch b/external/subpack/libs/libsoxr/patches/010-Remove_automatic_avutil_inclusion.patch
new file mode 100644
index 0000000..db66a14
--- /dev/null
+++ b/external/subpack/libs/libsoxr/patches/010-Remove_automatic_avutil_inclusion.patch
@@ -0,0 +1,11 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -134,7 +134,7 @@ if (WITH_AVFFT)
+   endif ()
+ endif ()
+ 
+-if (WITH_AVFFT OR (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" AND SIMD32_FOUND AND WITH_CR32))
++if (WITH_AVFFT)
+   find_package (LibAVUtil)
+   if (AVUTIL_FOUND)
+     include_directories (${AVUTIL_INCLUDE_DIRS})
diff --git a/external/subpack/libs/libsoxr/patches/020-pkgconfig.patch b/external/subpack/libs/libsoxr/patches/020-pkgconfig.patch
new file mode 100644
index 0000000..cf44255
--- /dev/null
+++ b/external/subpack/libs/libsoxr/patches/020-pkgconfig.patch
@@ -0,0 +1,56 @@
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -88,7 +88,7 @@ if (BUILD_FRAMEWORK)
+   set_target_properties (${PROJECT_NAME} PROPERTIES FRAMEWORK TRUE)
+ elseif (NOT WIN32)
+   set (TARGET_PCS ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc)
+-  configure_file (${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc.in ${TARGET_PCS})
++  configure_file (${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc.in ${TARGET_PCS} @ONLY)
+   install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+ endif ()
+ 
+@@ -112,7 +112,7 @@ if (WITH_LSR_BINDINGS)
+     set_target_properties (${LSR} PROPERTIES FRAMEWORK TRUE)
+   elseif (NOT WIN32)
+     set (TARGET_PCS "${TARGET_PCS} ${CMAKE_CURRENT_BINARY_DIR}/${LSR}.pc")
+-    configure_file (${CMAKE_CURRENT_SOURCE_DIR}/${LSR}.pc.in ${CMAKE_CURRENT_BINARY_DIR}/${LSR}.pc)
++    configure_file (${CMAKE_CURRENT_SOURCE_DIR}/${LSR}.pc.in ${CMAKE_CURRENT_BINARY_DIR}/${LSR}.pc @ONLY)
+     install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${LSR}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+   endif ()
+ endif ()
+--- a/src/soxr-lsr.pc.in
++++ b/src/soxr-lsr.pc.in
+@@ -1,5 +1,10 @@
+-Name: ${LSR}
+-Description: ${DESCRIPTION_SUMMARY} (with libsamplerate-like bindings)
+-Version: ${PROJECT_VERSION}
+-Libs: -L${LIB_INSTALL_DIR} -l${LSR}
+-Cflags: -I${INCLUDE_INSTALL_DIR}
++prefix=@CMAKE_INSTALL_PREFIX@
++exec_prefix=@CMAKE_INSTALL_PREFIX@
++libdir=${exec_prefix}/lib
++includedir=${prefix}/include
++
++Name: @LSR@
++Description: @DESCRIPTION_SUMMARY@ (with libsamplerate-like bindings)
++Version: @PROJECT_VERSION@
++Libs: -L${libdir} -l@LSR@
++Cflags: -I${includedir}
+--- a/src/soxr.pc.in
++++ b/src/soxr.pc.in
+@@ -1,5 +1,10 @@
+-Name: ${PROJECT_NAME}
+-Description: ${DESCRIPTION_SUMMARY}
+-Version: ${PROJECT_VERSION}
+-Libs: -L${LIB_INSTALL_DIR} -l${PROJECT_NAME}
+-Cflags: -I${INCLUDE_INSTALL_DIR}
++prefix=@CMAKE_INSTALL_PREFIX@
++exec_prefix=@CMAKE_INSTALL_PREFIX@
++libdir=${exec_prefix}/lib
++includedir=${prefix}/include
++
++Name: @PROJECT_NAME@
++Description: @DESCRIPTION_SUMMARY@
++Version: @PROJECT_VERSION@
++Libs: -L${libdir} -l@PROJECT_NAME@
++Cflags: -I${includedir}
diff --git a/external/subpack/libs/libssh/Makefile b/external/subpack/libs/libssh/Makefile
new file mode 100644
index 0000000..1f51a98
--- /dev/null
+++ b/external/subpack/libs/libssh/Makefile
@@ -0,0 +1,75 @@
+#
+# Copyright (C) 2017 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:=libssh
+PKG_VERSION:=0.10.6
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://www.libssh.org/files/0.10/
+PKG_HASH:=1861d498f5b6f1741b6abc73e608478491edcf9c9d4b6630eef6e74596de9dc1
+
+PKG_MAINTAINER:=Mislav Novakovic <mislav.novakovic@sartura.hr>
+PKG_LICENSE:=LGPL-2.1-or-later BSD-2-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libssh:libssh
+
+CMAKE_INSTALL:=1
+CMAKE_BINARY_SUBDIR:=build
+PKG_BUILD_FLAGS:=no-mips16
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libssh
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=$(PKG_SOURCE_URL)
+  TITLE:=SSH library
+  DEPENDS:=+libpthread +librt +zlib +libmbedtls
+endef
+
+define Package/libssh/description
+ libssh is a mulitplatform C library implementing the SSHv2 and SSHv1 protocol
+ for client and server implementations.
+endef
+
+CMAKE_OPTIONS += \
+	-DHAVE_STRTOULL=1 \
+	-DHAVE_GETADDRINFO=1 \
+	-DHAVE_TERMIOS_H=1 \
+	-DWITH_EXAMPLES:BOOL=OFF \
+	-DWITH_GCRYPT:BOOL=OFF \
+	-DWITH_MBEDTLS:BOOL=ON \
+	-DWITH_GSSAPI:BOOL=OFF \
+	-DWITH_LIBZ:BOOL=ON \
+	-DWITH_NACL:BOOL=OFF \
+	-DWITH_PCAP:BOOL=OFF \
+	-DWITH_SERVER:BOOL=ON \
+	-DWITH_SFTP:BOOL=ON \
+	-UWITH_STACK_CLASH_PROTECTION \
+	-DWITH_STACK_CLASH_PROTECTION=0 \
+	-UWITH_STACK_PROTECTOR \
+	-DWITH_STACK_PROTECTOR=0 \
+	-UWITH_STACK_PROTECTOR_STRONG \
+	-DWITH_STACK_PROTECTOR_STRONG=0 \
+	-DHAVE_WORDS_BIGENDIAN=$(if $(CONFIG_BIG_ENDIAN),1,0)
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libssh.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libssh.pc
+endef
+
+define Package/libssh/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libssh* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libssh))
diff --git a/external/subpack/libs/libssh/patches/100-mbedtls_fix.patch b/external/subpack/libs/libssh/patches/100-mbedtls_fix.patch
new file mode 100644
index 0000000..4a6309c
--- /dev/null
+++ b/external/subpack/libs/libssh/patches/100-mbedtls_fix.patch
@@ -0,0 +1,53 @@
+--- a/cmake/Modules/FindMbedTLS.cmake
++++ b/cmake/Modules/FindMbedTLS.cmake
+@@ -34,7 +34,7 @@ set(_MBEDTLS_ROOT_HINTS_AND_PATHS
+ 
+ find_path(MBEDTLS_INCLUDE_DIR
+     NAMES
+-        mbedtls/config.h
++        mbedtls/version.h
+     HINTS
+         ${_MBEDTLS_ROOT_HINTS_AND_PATHS}
+     PATH_SUFFIXES
+@@ -72,7 +72,13 @@ find_library(MBEDTLS_X509_LIBRARY
+ set(MBEDTLS_LIBRARIES ${MBEDTLS_SSL_LIBRARY} ${MBEDTLS_CRYPTO_LIBRARY}
+         ${MBEDTLS_X509_LIBRARY})
+ 
+-if (MBEDTLS_INCLUDE_DIR AND EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h")
++if (MBEDTLS_INCLUDE_DIR AND EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h")
++    file(STRINGS "${MBEDTLS_INCLUDE_DIR}/mbedtls/build_info.h" _mbedtls_version_str REGEX
++            "^#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"[0-9]+.[0-9]+.[0-9]+\"")
++
++    string(REGEX REPLACE "^.*MBEDTLS_VERSION_STRING.*([0-9]+.[0-9]+.[0-9]+).*"
++            "\\1" MBEDTLS_VERSION "${_mbedtls_version_str}")
++elseif (MBEDTLS_INCLUDE_DIR AND EXISTS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h")
+     file(STRINGS "${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h" _mbedtls_version_str REGEX
+             "^#[\t ]*define[\t ]+MBEDTLS_VERSION_STRING[\t ]+\"[0-9]+.[0-9]+.[0-9]+\"")
+ 
+@@ -93,7 +99,7 @@ if (MBEDTLS_VERSION)
+             in the system variable MBEDTLS_ROOT_DIR"
+     )
+ else (MBEDTLS_VERSION)
+-    find_package_handle_standard_args(MBedTLS
++    find_package_handle_standard_args(MbedTLS
+         "Could NOT find mbedTLS, try to set the path to mbedLS root folder in
+         the system variable MBEDTLS_ROOT_DIR"
+         MBEDTLS_INCLUDE_DIR
+--- a/src/libmbedcrypto.c
++++ b/src/libmbedcrypto.c
+@@ -118,8 +118,14 @@ int hmac_update(HMACCTX c, const void *d
+ 
+ int hmac_final(HMACCTX c, unsigned char *hashmacbuf, size_t *len)
+ {
++    const mbedtls_md_info_t *md_info;
+     int rc;
+-    *len = (unsigned int)mbedtls_md_get_size(c->md_info);
++#if MBEDTLS_VERSION_MAJOR >= 3
++	md_info = mbedtls_md_info_from_ctx(c);
++#else
++	md_info = c->md_info;
++#endif
++    *len = (unsigned int)mbedtls_md_get_size(md_info);
+     rc = !mbedtls_md_hmac_finish(c, hashmacbuf);
+     mbedtls_md_free(c);
+     SAFE_FREE(c);
diff --git a/external/subpack/libs/libssh2/Makefile b/external/subpack/libs/libssh2/Makefile
new file mode 100644
index 0000000..c605bf5
--- /dev/null
+++ b/external/subpack/libs/libssh2/Makefile
@@ -0,0 +1,74 @@
+#
+# Copyright (C) 2015-2018 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:=libssh2
+PKG_VERSION:=1.11.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://www.libssh2.org/download
+PKG_HASH:=3736161e41e2693324deb38c26cfdc3efe6209d634ba4258db1cecff6a5ad461
+
+PKG_MAINTAINER:=Jiri Slachta <jiri@slachta.eu>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libssh2:libssh2
+
+CMAKE_INSTALL:=1
+
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_LIBSSH2_MBEDTLS \
+	CONFIG_LIBSSH2_OPENSSL
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libssh2
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=SSH2 library
+  URL:=https://www.libssh2.org/
+  DEPENDS:=+LIBSSH2_MBEDTLS:libmbedtls +!LIBSSH2_MBEDTLS:libopenssl +zlib
+  ABI_VERSION:=1
+endef
+
+define Package/libssh2/description
+ libssh2 is a client-side C library implementing the SSH2 protocol.
+endef
+
+define Package/libssh2/config
+if PACKAGE_libssh2
+
+choice
+	prompt "Choose crypto backend"
+	default LIBSSH2_OPENSSL
+
+	config LIBSSH2_OPENSSL
+	bool "openssl"
+
+	config LIBSSH2_MBEDTLS
+	bool "mbedtls"
+endchoice
+
+endif
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_SHARED_LIBS=ON \
+	-DBUILD_TESTING=OFF \
+	-DENABLE_ZLIB_COMPRESSION=ON \
+	-DCLEAR_MEMORY=ON \
+	-DCRYPTO_BACKEND=$(if $(CONFIG_LIBSSH2_MBEDTLS),mbedTLS,OpenSSL)
+
+define Package/libssh2/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libssh2.so.$(ABI_VERSION)* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libssh2))
diff --git a/external/subpack/libs/libstrophe/Config.in b/external/subpack/libs/libstrophe/Config.in
new file mode 100644
index 0000000..ec45f75
--- /dev/null
+++ b/external/subpack/libs/libstrophe/Config.in
@@ -0,0 +1,14 @@
+choice
+	depends on PACKAGE_libstrophe
+	prompt "Select XML library"
+	default libstrophe-expat
+
+config libstrophe-expat
+	bool "expat"
+	select PACKAGE_libexpat
+
+config libstrophe-libxml2
+	bool "libxml2"
+	select PACKAGE_libxml2
+
+endchoice
diff --git a/external/subpack/libs/libstrophe/Makefile b/external/subpack/libs/libstrophe/Makefile
new file mode 100644
index 0000000..7473731
--- /dev/null
+++ b/external/subpack/libs/libstrophe/Makefile
@@ -0,0 +1,70 @@
+#
+# Copyright (C) 2015 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:=libstrophe
+PKG_VERSION:=0.13.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/strophe/libstrophe/releases/download/$(PKG_VERSION)
+PKG_HASH:=86c0abd348ae66feb40b6886f2c7f04525f1d5b20a48c10d4db4ed532dc63f22
+
+PKG_MAINTAINER:=Chih-Wei Chen <changeway@gmail.com>
+PKG_LICENSE:=MIT OR GPL-3.0-only
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_libstrophe-libxml2 \
+	CONFIG_libstrophe-expat
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libstrophe
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=XMPP client library
+	URL:=http://strophe.im/libstrophe
+	DEPENDS:= +libopenssl +libstrophe-libxml2:libxml2 +libstrophe-expat:libexpat +zlib
+	MENU:=1
+endef
+
+define Package/libstrophe/description
+	A simple, lightweight C library for writing XMPP clients
+endef
+
+define Package/libstrophe/config
+	source "$(SOURCE)/Config.in"
+endef
+
+CONFIGURE_ARGS += \
+	--with$(if $(CONFIG_libstrophe-libxml2),,out)-libxml2
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/ $(1)/usr/
+
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libstrophe.{la,a,so*} $(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libstrophe.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libstrophe/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libstrophe.so.* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libstrophe))
diff --git a/external/subpack/libs/libtalloc/Makefile b/external/subpack/libs/libtalloc/Makefile
new file mode 100644
index 0000000..904a2cb
--- /dev/null
+++ b/external/subpack/libs/libtalloc/Makefile
@@ -0,0 +1,91 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=talloc
+PKG_VERSION:=2.4.2
+MAJOR_VERSION:=2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://www.samba.org/ftp/talloc
+PKG_HASH:=85ecf9e465e20f98f9950a52e9a411e14320bc555fa257d87697b7e7a9b1d8a6
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=LGPL-3.0-or-later
+
+PKG_BUILD_PARALLEL:=0
+PKG_BUILD_DEPENDS:=python3/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+define Package/libtalloc
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Core memory allocator used in Samba
+  DEPENDS:=$(ICONV_DEPENDS) +libattr
+  URL:=https://talloc.samba.org/talloc/doc/html/index.html
+endef
+
+define Package/libtalloc/description
+  talloc is a hierarchical, reference counted memory pool system with destructors.
+endef
+
+CROSS = " \
+	\nChecking simple C program: \"hello world\" \
+	\nrpath library support: (127, \"\") \
+	\n-Wl,--version-script support: (127, \"\") \
+	\nChecking getconf LFS_CFLAGS: NO \
+	\nChecking for large file support without additional flags: OK \
+	\nChecking correct behavior of strtoll: OK \
+	\nChecking for working strptime: NO \
+	\nChecking for C99 vsnprintf: \"1\" \
+	\nChecking for HAVE_SHARED_MMAP: NO \
+	\nChecking for HAVE_MREMAP: NO \
+	\nChecking for HAVE_INCOHERENT_MMAP: (2, \"\") \
+	\nChecking for HAVE_SECURE_MKSTEMP: OK \
+	\n"
+
+define Build/Configure
+	(cd $(PKG_BUILD_DIR); \
+		echo -e >cache.txt $(CROSS) " \
+			\nChecking uname machine type: \"$(ARCH)\" \
+			\nChecking uname release type: \"$(LINUX_VERSION)\" \
+			\nChecking uname sysname type: \"Linux\" \
+			\nChecking uname version type: \"$(LINUX_UNAME_VERSION)\" \
+		\n" ; \
+		$(CONFIGURE_VARS) \
+		PYTHONHASHSEED=1 \
+		./buildtools/bin/waf configure \
+			--prefix=/usr \
+			--sysconfdir=/etc \
+			--localstatedir=/var \
+			--with-libiconv="$(ICONV_PREFIX)" \
+			--cross-compile \
+			--cross-answers=cache.txt \
+			--disable-python \
+			--disable-rpath \
+			--disable-rpath-install \
+	)
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/bin/default/libtalloc.so $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_BUILD_DIR)/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_BUILD_DIR)/bin/default/talloc.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libtalloc/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/bin/default/libtalloc.so $(1)/usr/lib/libtalloc.so.$(MAJOR_VERSION)
+	(cd $(1)/usr/lib; ln -sf libtalloc.so.$(MAJOR_VERSION) libtalloc.so)
+endef
+
+$(eval $(call BuildPackage,libtalloc))
diff --git a/external/subpack/libs/libtalloc/patches/100-Remove_libbsd_dependency_check.patch b/external/subpack/libs/libtalloc/patches/100-Remove_libbsd_dependency_check.patch
new file mode 100644
index 0000000..c970dc8
--- /dev/null
+++ b/external/subpack/libs/libtalloc/patches/100-Remove_libbsd_dependency_check.patch
@@ -0,0 +1,69 @@
+--- a/lib/replace/wscript
++++ b/lib/replace/wscript
+@@ -441,33 +441,13 @@ def configure(conf):
+ 
+     conf.CHECK_FUNCS('prctl dirname basename')
+ 
+-    strlcpy_in_bsd = False
++    # Not checking for libbsd
++    conf.CHECK_FUNCS('strlcpy strlcat')
++    conf.CHECK_FUNCS('getpeereid')
++    conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h')
++    conf.CHECK_FUNCS('setproctitle_init')
+ 
+-    # libbsd on some platforms provides strlcpy and strlcat
+-    if not conf.CHECK_FUNCS('strlcpy strlcat'):
+-        if conf.CHECK_FUNCS_IN('strlcpy strlcat', 'bsd', headers='bsd/string.h',
+-                               checklibc=True):
+-            strlcpy_in_bsd = True
+-    elif conf.env.enable_fuzzing:
+-        # Just to complicate it more, some versions of Honggfuzz have
+-        # got strlcpy and strlcat in libc, but not in <string.h>
+-        # (unless it is there coincidentally, on a BSD). Therefore we
+-        # can't use CHECK_FUNCS alone to decide whether to add the
+-        # headers to replace.h.
+-        #
+-        # As this is only known to happen on a fuzzing compiler, we'll
+-        # skip the check when not in fuzzing mode.
+-        conf.CHECK_HEADERS('bsd/string.h')
+-
+-    if not conf.CHECK_FUNCS('getpeereid'):
+-        conf.CHECK_FUNCS_IN('getpeereid', 'bsd', headers='sys/types.h bsd/unistd.h')
+-    if not conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h'):
+-        conf.CHECK_FUNCS_IN('setproctitle', 'bsd', headers='sys/types.h bsd/unistd.h')
+-    if not conf.CHECK_FUNCS('setproctitle_init'):
+-        conf.CHECK_FUNCS_IN('setproctitle_init', 'bsd', headers='sys/types.h bsd/unistd.h')
+-
+-    if not conf.CHECK_FUNCS('closefrom'):
+-        conf.CHECK_FUNCS_IN('closefrom', 'bsd', headers='bsd/unistd.h')
++    conf.CHECK_FUNCS('closefrom')
+ 
+     conf.CHECK_CODE('''
+                 struct ucred cred;
+@@ -850,9 +830,6 @@ syscall(SYS_copy_file_range,0,NULL,0,NUL
+ 
+     # look for a method of finding the list of network interfaces
+     for method in ['HAVE_IFACE_GETIFADDRS', 'HAVE_IFACE_AIX', 'HAVE_IFACE_IFCONF', 'HAVE_IFACE_IFREQ']:
+-        bsd_for_strlcpy = ''
+-        if strlcpy_in_bsd:
+-            bsd_for_strlcpy = ' bsd'
+         if conf.CHECK_CODE('''
+                            #define %s 1
+                            #define NO_CONFIG_H 1
+@@ -865,7 +842,7 @@ syscall(SYS_copy_file_range,0,NULL,0,NUL
+                            #include "tests/getifaddrs.c"
+                            ''' % method,
+                            method,
+-                           lib='nsl socket' + bsd_for_strlcpy,
++                           lib='nsl socket',
+                            addmain=False,
+                            execute=True):
+             break
+@@ -913,7 +890,6 @@ def build(bld):
+                 break
+ 
+     extra_libs = ''
+-    if bld.CONFIG_SET('HAVE_LIBBSD'): extra_libs += ' bsd'
+     if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt'
+     if bld.CONFIG_SET('REPLACE_REQUIRES_LIBSOCKET_LIBNSL'): extra_libs += ' socket nsl'
+ 
diff --git a/external/subpack/libs/libtasn1/Makefile b/external/subpack/libs/libtasn1/Makefile
new file mode 100644
index 0000000..36116ad
--- /dev/null
+++ b/external/subpack/libs/libtasn1/Makefile
@@ -0,0 +1,72 @@
+#
+# Copyright (C) 2005-2008 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:=libtasn1
+PKG_VERSION:=4.19.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
+PKG_HASH:=1613f0ac1cf484d6ec0ce3b8c06d56263cc7242f1c23b30d82d23de345a63f7a
+
+PKG_MAINTAINER:=Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LIB
+PKG_CPE_ID:=cpe:/a:gnu:libtasn1
+
+#PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=gc-sections
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+define Package/libtasn1
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=An ASN.1 and DER structures manipulation library
+  URL:=https://www.gnu.org/software/libtasn1/
+endef
+
+define Package/libtasn1/description
+ This is a library for Abstract Syntax Notation One (ASN.1) and
+ Distinguish Encoding Rules (DER) manipulation.
+endef
+
+HOST_CFLAGS += -std=gnu99
+
+HOST_CONFIGURE_ARGS += \
+	--disable-shared \
+	--with-pic
+
+CONFIGURE_ARGS += \
+	--disable-doc \
+	--disable-gcc-warnings \
+	--disable-ld-version-script \
+	--disable-valgrind-tests
+
+define Build/InstallDev
+	# $(INSTALL_DIR) $(1)/usr/bin
+	# $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libtasn1.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtasn1.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libtasn1*.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libtasn1/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtasn1.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,libtasn1))
diff --git a/external/subpack/libs/libtheora/Makefile b/external/subpack/libs/libtheora/Makefile
new file mode 100644
index 0000000..0a19cba
--- /dev/null
+++ b/external/subpack/libs/libtheora/Makefile
@@ -0,0 +1,68 @@
+#
+# Copyright (C) 2008-2012 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:=libtheora
+PKG_VERSION:=1.1.1
+PKG_RELEASE:=1
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://downloads.xiph.org/releases/theora/
+PKG_HASH:=b6ae1ee2fa3d42ac489287d3ec34c5885730b1296f0801ae577a35193d3affbc
+
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING LICENSE
+
+PKG_FIXUP:=autoreconf
+PKG_BUILD_DEPENDS:=libvorbis
+
+include $(INCLUDE_DIR)/package.mk
+
+PKG_INSTALL=1
+
+define Package/libtheora
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libtheora
+  URL:=http://xiph.org/theora/
+  MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+  DEPENDS:=+libogg
+endef
+
+define Package/libtheora/description
+Theora is Xiph.Org's first publicly released video codec, intended
+for use within the Foundation's Ogg multimedia streaming system.
+Theora is derived directly from On2's VP3 codec; Currently the
+encoders are nearly identical, but Theora will make use of new
+features supported by the decoder to improve over what is
+is possible with VP3.
+endef
+
+define Build/Configure
+	$(call Build/Configure/Default, \
+		--disable-examples \
+		--disable-oggtest \
+		--disable-vorbistest \
+		--disable-sdltest \
+	)
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/theora/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/theora/* $(1)/usr/include/theora/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.{so*,a,la} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libtheora/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libtheora))
diff --git a/external/subpack/libs/libtheora/patches/001-no_docs_tests.patch b/external/subpack/libs/libtheora/patches/001-no_docs_tests.patch
new file mode 100644
index 0000000..d035b93
--- /dev/null
+++ b/external/subpack/libs/libtheora/patches/001-no_docs_tests.patch
@@ -0,0 +1,31 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -8,7 +8,7 @@ else
+ EXAMPLES_DIR =
+ endif
+ 
+-SUBDIRS = lib include doc tests m4 $(EXAMPLES_DIR)
++SUBDIRS = lib include m4 $(EXAMPLES_DIR)
+ 
+ 
+ # we include the whole debian/ dir in EXTRA_DIST because there's a problem
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -164,7 +164,7 @@ AUTOMAKE_OPTIONS = foreign 1.6 dist-zip
+ @THEORA_ENABLE_EXAMPLES_TRUE@EXAMPLES_DIR = examples
+ @THEORA_ENABLE_EXAMPLES_FALSE@EXAMPLES_DIR = 
+ 
+-SUBDIRS = lib include doc tests m4 $(EXAMPLES_DIR)
++SUBDIRS = lib include m4 $(EXAMPLES_DIR)
+ 
+ # we include the whole debian/ dir in EXTRA_DIST because there's a problem
+ # with autotools and HFS+ MacOSX file systems that caused debian/Makefile.am
+@@ -200,7 +200,7 @@ DIST_COMMON = README AUTHORS COPYING Mak
+ 	missing mkinstalldirs theora-uninstalled.pc.in theora.pc.in \
+ 	theoradec-uninstalled.pc.in theoradec.pc.in \
+ 	theoraenc-uninstalled.pc.in theoraenc.pc.in
+-DIST_SUBDIRS = lib include doc tests m4 examples
++DIST_SUBDIRS = lib include m4 examples
+ all: config.h
+ 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+ 
diff --git a/external/subpack/libs/libtheora/patches/002-no_sdl_check.patch b/external/subpack/libs/libtheora/patches/002-no_sdl_check.patch
new file mode 100644
index 0000000..f27e4dd
--- /dev/null
+++ b/external/subpack/libs/libtheora/patches/002-no_sdl_check.patch
@@ -0,0 +1,14 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -313,11 +313,6 @@ fi
+ dnl check for SDL
+ HAVE_SDL=no
+ 
+-AM_PATH_SDL(,[
+-  HAVE_SDL=yes
+-  SDL_LIBS=`$SDL_CONFIG --libs`
+-],AC_MSG_WARN([*** Unable to find SDL -- Not compiling example players ***]))
+-
+ dnl check for OSS
+ HAVE_OSS=no
+ AC_CHECK_HEADERS([sys/soundcard.h soundcard.h machine/soundcard.h],[
diff --git a/external/subpack/libs/libtins/Config.in b/external/subpack/libs/libtins/Config.in
new file mode 100644
index 0000000..1d5efd1
--- /dev/null
+++ b/external/subpack/libs/libtins/Config.in
@@ -0,0 +1,32 @@
+# libtins configuration
+menu "Configuration"
+	depends on PACKAGE_libtins
+
+config LIBTINS_ENABLE_ACK_TRACKER
+	bool "Enable ACK tracker"
+	default n
+
+config LIBTINS_ENABLE_CXX11
+	bool "Enable C++11"
+	default y
+
+config LIBTINS_ENABLE_DOT11
+	bool "Enable IEEE 802.11 support (select this to access ENABLE_WPA2 option)"
+	help
+		If selected, this also allows configuring WPA2 support which requires openssl
+	default n
+
+config LIBTINS_ENABLE_PCAP
+	bool "Enable PCAP library support"
+	default y
+
+config LIBTINS_ENABLE_TCP_STREAM_CUSTOM_DATA
+	bool "Enable TCP stream custom data"
+	default n
+
+config LIBTINS_ENABLE_WPA2
+	depends on LIBTINS_ENABLE_DOT11
+	bool "Enable WPA2 (this selects libopenssl)"
+	default n
+endmenu
+
diff --git a/external/subpack/libs/libtins/Makefile b/external/subpack/libs/libtins/Makefile
new file mode 100644
index 0000000..34a1f9b
--- /dev/null
+++ b/external/subpack/libs/libtins/Makefile
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2017 Steven Hessing
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libtins
+PKG_VERSION:=4.5
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=v$(PKG_VERSION)
+PKG_SOURCE_URL:=https://github.com/mfontanini/libtins
+PKG_MIRROR_HASH:=85c5a15beca56552ba3f33e10f2a82ee4c47be2b3334d163304362188a37b13a
+
+PKG_MAINTAINER:= Steven Hessing <steven.hessing@gmail.com>
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+CMAKE_INSTALL:=1
+PKG_BUILD_FLAGS:=gc-sections lto
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libtins
+  SECTION:=net
+  CATEGORY:=Libraries
+  TITLE:=libtins
+  URL:=https://libtins.github.io/
+  DEPENDS:=+libstdcpp +LIBTINS_ENABLE_PCAP:libpcap +LIBTINS_ENABLE_WPA2:libopenssl
+  MENU:=1
+endef
+
+define Package/libtins/config
+	source "$(SOURCE)/Config.in"
+endef
+
+define Package/libtins/description
+  libtins is a high-level, multiplatform C++ network packet sniffing and crafting library.
+endef
+
+CMAKE_OPTIONS += \
+	-D_RUN_RESULT_VAR=FORCE \
+	-DLIBTINS_BUILD_EXAMPLES=OFF \
+	-DLIBTINS_BUILD_TESTS=OFF \
+	-DLIBTINS_ENABLE_ACK_TRACKER=$(if $(CONFIG_LIBTINS_ENABLE_ACK_TRACKER),ON,OFF) \
+	-DLIBTINS_ENABLE_CXX11=$(if $(CONFIG_LIBTINS_ENABLE_CXX11),ON,OFF) \
+	-DLIBTINS_ENABLE_DOT11=$(if $(CONFIG_LIBTINS_ENABLE_DOT11),ON,OFF) \
+	-DLIBTINS_ENABLE_PCAP=$(if $(CONFIG_LIBTINS_ENABLE_PCAP),ON,OFF) \
+	-DLIBTINS_ENABLE_TCP_STREAM_CUSTOM_DATA=$(if $(CONFIG_LIBTINS_ENABLE_TCP_STREAM_CUSTOM_DATA),ON,OFF) \
+	-DLIBTINS_ENABLE_WPA2=$(if $(CONFIG_LIBTINS_ENABLE_WPA2),ON,OFF)
+
+TARGET_LDFLAGS += -Wl,--as-needed
+
+define Package/libtins/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtins.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libtins))
diff --git a/external/subpack/libs/libtins/patches/010-pkgconfig.patch b/external/subpack/libs/libtins/patches/010-pkgconfig.patch
new file mode 100644
index 0000000..c478666
--- /dev/null
+++ b/external/subpack/libs/libtins/patches/010-pkgconfig.patch
@@ -0,0 +1,10 @@
+--- a/libtins.pc.in
++++ b/libtins.pc.in
+@@ -1,6 +1,6 @@
+ prefix=@pkgconfig_prefix@
+ exec_prefix=@pkgconfig_exec_prefix@
+-libdir=@pkgconfig_libdir@
++libdir=${exec_prefix}/lib
+ includedir=${prefix}/include
+ 
+ Name: libtins
diff --git a/external/subpack/libs/libtins/patches/110-fix_ch_switch_timing_value.patch b/external/subpack/libs/libtins/patches/110-fix_ch_switch_timing_value.patch
new file mode 100644
index 0000000..76594c6
--- /dev/null
+++ b/external/subpack/libs/libtins/patches/110-fix_ch_switch_timing_value.patch
@@ -0,0 +1,11 @@
+--- a/include/tins/dot11/dot11_base.h
++++ b/include/tins/dot11/dot11_base.h
+@@ -182,7 +182,7 @@ public:
+         DMS_RESP,
+         LINK_ID,
+         WAKEUP_SCHEDULE,
+-        CH_SWITCH_TIMING,
++        CH_SWITCH_TIMING = 104,
+         PTI_CONTROL,
+         TPU_BUFFER_STATUS,
+         INTERWORKING,
diff --git a/external/subpack/libs/libtirpc/Makefile b/external/subpack/libs/libtirpc/Makefile
new file mode 100644
index 0000000..ee455fe
--- /dev/null
+++ b/external/subpack/libs/libtirpc/Makefile
@@ -0,0 +1,57 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libtirpc
+PKG_VERSION:=1.3.4
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=@SF/libtirpc
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_HASH:=1e0b0c7231c5fa122e06c0609a76723664d068b0dba3b8219b63e6340b347860
+
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libtirpc_project:libtirpc
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+HOST_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+define Package/libtirpc
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Library TI RPC for RPC bindings
+  URL:=http://libtirpc.sourceforge.net/
+  DEPENDS:=+libpthread
+endef
+
+CONFIGURE_ARGS += --disable-gssapi
+HOST_CONFIGURE_ARGS += --disable-gssapi --disable-shared
+
+ifeq ($(HOST_OS),Darwin)
+HOST_CONFIGURE_ARGS += --disable-symvers
+endif
+
+TARGET_CFLAGS += -DGQ
+HOST_CFLAGS += -DGQ
+
+define Package/libtirpc/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtirpc.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/etc
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/netconfig $(1)/etc/
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtirpc.{a,so*} $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libtirpc.pc $(1)/usr/lib/pkgconfig/libtirpc.pc
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,libtirpc))
diff --git a/external/subpack/libs/libtirpc/patches/001-clang.patch b/external/subpack/libs/libtirpc/patches/001-clang.patch
new file mode 100644
index 0000000..53da7f8
--- /dev/null
+++ b/external/subpack/libs/libtirpc/patches/001-clang.patch
@@ -0,0 +1,103 @@
+--- a/tirpc/reentrant.h
++++ b/tirpc/reentrant.h
+@@ -36,7 +36,7 @@
+  * These definitions are only guaranteed to be valid on Linux. 
+  */
+ 
+-#if defined(__linux__)
++#if defined(__linux__) || defined(__MACH__)
+ 
+ #include <pthread.h>
+ 
+--- a/tirpc/rpc/rpcent.h
++++ b/tirpc/rpc/rpcent.h
+@@ -50,7 +50,7 @@ extern "C" {
+ 
+ /* These are defined in /usr/include/rpc/netdb.h, unless we are using
+    the C library without RPC support. */
+-#if defined(__UCLIBC__) && !defined(__UCLIBC_HAS_RPC__) || !defined(__GLIBC__)
++#if (defined(__UCLIBC__) && !defined(__UCLIBC_HAS_RPC__) || !defined(__GLIBC__)) && !defined(__MACH__)
+ struct rpcent {
+ 	char	*r_name;	/* name of server for this rpc program */
+ 	char	**r_aliases;	/* alias list */
+--- a/src/rpc_com.h
++++ b/src/rpc_com.h
+@@ -63,6 +63,14 @@ void __xprt_set_raddr(SVCXPRT *, const s
+ 
+ extern int __svc_maxrec;
+ 
++#ifndef SOL_IP
++#define SOL_IP IPPROTO_IP
++#endif
++
++#ifndef SOL_IPV6
++#define SOL_IPV6 IPPROTO_IPV6
++#endif
++
+ #ifdef __cplusplus
+ }
+ #endif
+--- a/src/svc_dg.c
++++ b/src/svc_dg.c
+@@ -37,6 +37,11 @@
+  *
+  * Does some caching in the hopes of achieving execute-at-most-once semantics.
+  */
++
++#ifdef __APPLE__
++#define __APPLE_USE_RFC_3542
++#endif
++
+ #include <pthread.h>
+ #include <reentrant.h>
+ #include <sys/types.h>
+--- a/src/svc_raw.c
++++ b/src/svc_raw.c
+@@ -43,6 +43,7 @@
+ #include <sys/types.h>
+ #include <rpc/raw.h>
+ #include <stdlib.h>
++#include <string.h>
+ 
+ #ifndef UDPMSGSIZE
+ #define	UDPMSGSIZE 8800
+--- a/src/getpeereid.c
++++ b/src/getpeereid.c
+@@ -29,12 +29,17 @@
+ #include <sys/socket.h>
+ #include <sys/un.h>
+ 
++#if __APPLE__ || __FreeBSD__
++#include <sys/ucred.h>
++#endif
++
+ #include <errno.h>
+ #include <unistd.h>
+ 
+ int
+ getpeereid(int s, uid_t *euid, gid_t *egid)
+ {
++#if defined(SO_PEERCRED)
+ 	struct ucred uc;
+ 	socklen_t uclen;
+ 	int error;
+@@ -48,4 +53,19 @@ getpeereid(int s, uid_t *euid, gid_t *eg
+ 	*euid = uc.uid;
+ 	*egid = uc.gid;
+ 	return (0);
++#elif defined(LOCAL_PEERCRED)
++	struct xucred uc;
++	socklen_t uclen;
++	int error;
++
++	uclen = sizeof(uc);
++	error = getsockopt(s, SOL_LOCAL, LOCAL_PEERCRED, &uc, &uclen); /*  SCM_CREDENTIALS */
++	if (error != 0)
++		return (error);
++	*euid = uc.cr_uid;
++	*egid = uc.cr_gid;
++	return (0);
++#else
++	return (ENOTSUP);
++#endif
+  }
diff --git a/external/subpack/libs/libtorrent-rasterbar/Makefile b/external/subpack/libs/libtorrent-rasterbar/Makefile
new file mode 100644
index 0000000..f0071dd
--- /dev/null
+++ b/external/subpack/libs/libtorrent-rasterbar/Makefile
@@ -0,0 +1,73 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libtorrent-rasterbar
+PKG_VERSION:=2.0.9
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/arvidn/libtorrent/releases/download/v$(PKG_VERSION)/
+PKG_HASH:=90cd92b6061c5b664840c3d5e151d43fedb24f5b2b24e14425ffbb884ef1798e
+
+PKG_MAINTAINER:=David Yang <mmyangfl@gmail.com>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libtorrent-rasterbar/Default
+	TITLE:=Rasterbar BitTorrent library
+	URL:=https://libtorrent.org/
+endef
+
+define Package/libtorrent-rasterbar
+	$(call Package/libtorrent-rasterbar/Default)
+	SECTION:=libs
+	CATEGORY:=Libraries
+	DEPENDS:=+boost-system +libopenssl +libatomic +libstdcpp
+endef
+
+#define Package/python3-libtorrent
+#	$(call Package/libtorrent-rasterbar/Default)
+#	SECTION:=lang
+#	CATEGORY:=Languages
+#	SUBMENU:=Python
+#	TITLE+= (Python 3)
+#	DEPENDS:=+libtorrent-rasterbar +boost-python
+#endef
+
+define Package/libtorrent-rasterbar/description
+	Rasterbar libtorrent is a C++ library that aims to be a good alternative to
+	all the other bittorrent implementations around.
+endef
+
+#define Package/python3-libtorrent/description
+#	$(call Package/libtorrent-rasterbar/description)
+#	This package contains Python 3 bindings for the libtorrent-rasterbar library.
+#endef
+
+#CMAKE_OPTIONS += \
+#	-Dpython-bindings=ON \
+#	-Dpython-egg-info=ON
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libtorrent $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtorrent-rasterbar.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libtorrent-rasterbar.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libtorrent-rasterbar/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtorrent-rasterbar.so.* $(1)/usr/lib/
+endef
+
+#define Package/python3-libtorrent/install
+#	$(INSTALL_DIR) $(1)/usr/lib/python2.7/site-packages
+#	$(CP) $(PKG_INSTALL_DIR)/usr/lib/python2.7/site-packages/*.so* $(1)/usr/lib/python2.7/site-packages/
+#endef
+
+$(eval $(call BuildPackage,libtorrent-rasterbar))
+#$(eval $(call BuildPackage,python3-libtorrent))
diff --git a/external/subpack/libs/libtorrent/Makefile b/external/subpack/libs/libtorrent/Makefile
new file mode 100644
index 0000000..1116181
--- /dev/null
+++ b/external/subpack/libs/libtorrent/Makefile
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2007-2015 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:=libtorrent
+PKG_VERSION:=0.13.8
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/rakshasa/libtorrent/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=0f6c2e7ffd3a1723ab47fdac785ec40f85c0a5b5a42c1d002272205b988be722
+
+PKG_MAINTAINER:=Rosen Penev <rosenp@gmail.com>
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libtorrent
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Rakshasa's BitTorrent library
+  URL:=https://rakshasa.github.io/rtorrent/
+  DEPENDS:=+libopenssl +libstdcpp +zlib
+  BUILDONLY:=1
+endef
+
+define Package/libtorrent/description
+ LibTorrent is a BitTorrent library written in C++ for *nix, with a focus on
+ high performance and good code. The library differentiates itself from other
+ implementations by transferring directly from file pages to the network stack.
+ On high-bandwidth connections it is able to seed at 3 times the speed of the
+ official client.
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--enable-aligned \
+	--enable-openssl \
+	--disable-debug \
+	--disable-instrumentation \
+	--with-epoll \
+	--with-zlib=$(STAGING_DIR)/usr \
+	--without-kqueue
+
+TARGET_CXXFLAGS += -faligned-new
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/torrent $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtorrent.a $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libtorrent.pc $(1)/usr/lib/pkgconfig/
+endef
+
+$(eval $(call BuildPackage,libtorrent))
diff --git a/external/subpack/libs/libtorrent/patches/010-usleep.patch b/external/subpack/libs/libtorrent/patches/010-usleep.patch
new file mode 100644
index 0000000..e3522f6
--- /dev/null
+++ b/external/subpack/libs/libtorrent/patches/010-usleep.patch
@@ -0,0 +1,54 @@
+--- a/src/data/hash_queue.cc
++++ b/src/data/hash_queue.cc
+@@ -38,9 +38,10 @@
+ 
+ #define __STDC_FORMAT_MACROS
+ 
++#include <chrono>
++#include <thread>
+ #include <functional>
+ #include <rak/functional.h>
+-#include <unistd.h>
+ 
+ #include "torrent/exceptions.h"
+ #include "torrent/data/download_data.h"
+@@ -137,7 +138,7 @@ HashQueue::remove(HashQueueNode::id_type
+ 
+       while ((done_itr = m_done_chunks.find(hash_chunk)) == m_done_chunks.end()) {
+         pthread_mutex_unlock(&m_done_chunks_lock);
+-        usleep(100);
++        std::this_thread::sleep_for(std::chrono::microseconds(100));
+         pthread_mutex_lock(&m_done_chunks_lock);
+       }
+ 
+--- a/src/torrent/utils/thread_base.cc
++++ b/src/torrent/utils/thread_base.cc
+@@ -37,8 +37,9 @@
+ #include "config.h"
+ 
+ #include <cstring>
++#include <chrono>
++#include <thread>
+ #include <signal.h>
+-#include <unistd.h>
+ 
+ #include "exceptions.h"
+ #include "poll.h"
+@@ -97,7 +98,7 @@ thread_base::stop_thread_wait() {
+   release_global_lock();
+ 
+   while (!is_inactive()) {
+-    usleep(1000);
++    std::this_thread::sleep_for(std::chrono::milliseconds(1));
+   }  
+ 
+   acquire_global_lock();
+@@ -161,7 +162,7 @@ thread_base::event_loop(thread_base* thr
+       }
+ 
+       // Add the sleep call when testing interrupts, etc.
+-      // usleep(50);
++      // std::this_thread::sleep_for(std::chrono::microseconds(50));
+ 
+       int poll_flags = 0;
+ 
diff --git a/external/subpack/libs/libucontext/Makefile b/external/subpack/libs/libucontext/Makefile
new file mode 100644
index 0000000..3515eab
--- /dev/null
+++ b/external/subpack/libs/libucontext/Makefile
@@ -0,0 +1,61 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libucontext
+PKG_VERSION:=1.3.2
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/kaniini/libucontext
+PKG_SOURCE_VERSION:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_MIRROR_HASH:=eef55c05aca03c6d62672838638f49daa95ab8f9bf87126df32cedfe150e333c
+
+PKG_MAINTAINER:=Volker Christian <me@vchrist.at>
+PKG_LICENSE:=ISC
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_FLAGS:=no-mips16
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libucontext
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libucontext is a library which provides the ucontext.h C API
+  URL:=https://github.com/kaniini/libucontext
+  DEPENDS:=@USE_MUSL
+endef
+
+define Package/libucontext-tests
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Test applications for libucontext
+  URL:=https://github.com/kaniini/libucontext
+  DEPENDS:=libucontext
+endef
+
+define Package/libucontext/description
+  This package is a development package aimed to be linked to
+  libraries/applications which need the SYS-V ucontext API.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libucontext $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libucontext* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libucontext.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libucontext/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libucontext*.so.* $(1)/usr/lib/
+endef
+
+define Package/libucontext-tests/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(MESON_BUILD_DIR)/test_libucontext_posix $(1)/usr/bin/
+	$(INSTALL_BIN) $(MESON_BUILD_DIR)/test_libucontext $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libucontext))
+$(eval $(call BuildPackage,libucontext-tests))
diff --git a/external/subpack/libs/libudev-zero/Makefile b/external/subpack/libs/libudev-zero/Makefile
new file mode 100644
index 0000000..ea5177b
--- /dev/null
+++ b/external/subpack/libs/libudev-zero/Makefile
@@ -0,0 +1,51 @@
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libudev-zero
+PKG_VERSION:=1.0.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/illiliti/libudev-zero/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=0bd89b657d62d019598e6c7ed726ff8fed80e8ba092a83b484d66afb80b77da5
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libudev-zero
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Drop-in replacement for libudev
+  URL:=https://github.com/illiliti/libudev-zero
+  DEPENDS:=+libevdev
+  PROVIDES:=libudev
+  CONFLICTS:=libudev eudev udev
+endef
+
+MAKE_FLAGS += \
+	PREFIX=/usr
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libudev.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libudev.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libudev.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libudev-zero/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libudev.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libudev-zero))
diff --git a/external/subpack/libs/libuecc/Makefile b/external/subpack/libs/libuecc/Makefile
new file mode 100644
index 0000000..afd2af2
--- /dev/null
+++ b/external/subpack/libs/libuecc/Makefile
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 2012-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:=libuecc
+PKG_VERSION:=7
+PKG_RELEASE:=2
+
+PKG_MAINTAINER:=Matthias Schiffer <mschiffer@universe-factory.net>
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/neocturne/libuecc/releases/download/v$(PKG_VERSION)
+PKG_HASH:=b94aef08eab5359d0facaa7ead2ce81b193eef0c61379d9835213ebc0a46257a
+
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=COPYRIGHT
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libuecc
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Very small Elliptic Curve Cryptography library
+  URL:=https://github.com/neocturne/libuecc/
+endef
+
+TARGET_CFLAGS += -ffunction-sections -fdata-sections
+
+CMAKE_OPTIONS += \
+	-DCMAKE_BUILD_TYPE:String="MINSIZEREL"
+
+
+define Package/libuecc/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libuecc.so* $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libuecc-$(PKG_VERSION) $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libuecc.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libuecc.pc $(1)/usr/lib/pkgconfig/
+endef
+
+$(eval $(call BuildPackage,libuecc))
diff --git a/external/subpack/libs/libugpio/Makefile b/external/subpack/libs/libugpio/Makefile
new file mode 100644
index 0000000..53775d3
--- /dev/null
+++ b/external/subpack/libs/libugpio/Makefile
@@ -0,0 +1,72 @@
+#
+# Copyright (C) 2012-2015 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:=libugpio
+PKG_VERSION:=0.0.7
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://github.com/mhei/libugpio/releases/download/v$(PKG_VERSION)
+PKG_HASH:=4e0ae6f9cd3d670eb5ba9595a24696a034fda3c7c1900aa9d2cae5a4cd9dab64
+
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LESSER
+
+PKG_MAINTAINER:=Michael Heimpold <mhei@heimpold.de>
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libugpio
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=https://github.com/mhei/libugpio
+  TITLE:=Library for using sysfs gpio interface from C programs
+  DEPENDS:=@GPIO_SUPPORT
+endef
+
+define Package/libugpio/description
+  libugpio is a library to ease the use of linux kernel's sysfs
+  gpio interface from C programs and/or other libraries.
+endef
+
+define Package/gpioctl-sysfs
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Tool for controlling gpio pins
+  DEPENDS:=+libugpio
+endef
+
+define Package/gpioctl-sysfs/description
+  Tool for controlling gpio pins using the sysfs api provided by the kernel.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/ugpio $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libugpio.{so*,a} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libugpio.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libugpio/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libugpio.so.* $(1)/usr/lib/
+endef
+
+define Package/gpioctl-sysfs/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/gpioctl $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libugpio))
+$(eval $(call BuildPackage,gpioctl-sysfs))
diff --git a/external/subpack/libs/libuhttpd/Makefile b/external/subpack/libs/libuhttpd/Makefile
new file mode 100644
index 0000000..460eaaa
--- /dev/null
+++ b/external/subpack/libs/libuhttpd/Makefile
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2018 Jianhui Zhao
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libuhttpd
+PKG_VERSION:=3.14.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL=https://github.com/zhaojh329/libuhttpd/releases/download/v$(PKG_VERSION)
+PKG_HASH:=ce2abbc599a922c4bac12f1cdf3e9c9740f387f819a54ca01e9fed60905baa40
+
+PKG_MAINTAINER:=Jianhui Zhao <zhaojh329@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libuhttpd/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=Networking
+  TITLE:=A lightweight HTTP server library based on libev
+  URL:=https://github.com/zhaojh329/libuhttpd
+  DEPENDS:=+libev $(2)
+  VARIANT:=$(1)
+  PROVIDES:=libuhttpd
+endef
+
+Package/libuhttpd-openssl=$(call Package/libuhttpd/Default,openssl,+PACKAGE_libuhttpd-openssl:libopenssl)
+Package/libuhttpd-wolfssl=$(call Package/libuhttpd/Default,wolfssl,+PACKAGE_libuhttpd-wolfssl:libwolfssl)
+Package/libuhttpd-mbedtls=$(call Package/libuhttpd/Default,mbedtls,+PACKAGE_libuhttpd-mbedtls:libmbedtls +PACKAGE_libuhttpd-mbedtls:zlib)
+Package/libuhttpd-nossl=$(call Package/libuhttpd/Default,nossl)
+
+CMAKE_OPTIONS += -DBUILD_EXAMPLE=OFF
+TARGET_CFLAGS += -Wno-error=deprecated-declarations
+
+ifeq ($(BUILD_VARIANT),openssl)
+  CMAKE_OPTIONS += -DUSE_OPENSSL=ON
+else ifeq ($(BUILD_VARIANT),wolfssl)
+  CMAKE_OPTIONS += -DUSE_WOLFSSL=ON
+else ifeq ($(BUILD_VARIANT),mbedtls)
+  CMAKE_OPTIONS += -DUSE_MBEDTLS=ON
+else
+  CMAKE_OPTIONS += -DSSL_SUPPORT=OFF
+endif
+
+define Package/libuhttpd-$(BUILD_VARIANT)/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libuhttpd.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libuhttpd-openssl))
+$(eval $(call BuildPackage,libuhttpd-mbedtls))
+$(eval $(call BuildPackage,libuhttpd-wolfssl))
+$(eval $(call BuildPackage,libuhttpd-nossl))
diff --git a/external/subpack/libs/libulfius/Makefile b/external/subpack/libs/libulfius/Makefile
new file mode 100644
index 0000000..6512da8
--- /dev/null
+++ b/external/subpack/libs/libulfius/Makefile
@@ -0,0 +1,64 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libulfius
+PKG_VERSION:=2.7.10
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/babelouest/ulfius/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=616c5df99584071461a1285dd7155883f7d2b94abf0931038feeebd3da3a6def
+
+PKG_MAINTAINER:=Toni Uhlig <matzeton@googlemail.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)-$(BUILD_VARIANT)/ulfius-$(PKG_VERSION)
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libulfius/default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=Networking
+  TITLE:=Web Framework to build REST APIs, Webservices or any HTTP endpoint in C language.
+  URL:=https://github.com/babelouest/ulfius
+endef
+
+define Package/libulfius-nossl
+$(call Package/libulfius/default)
+  VARIANT:=nossl
+  DEFAULT_VARIANT:=1
+  DEPENDS:=+libmicrohttpd +libcurl +liborcania
+  PROVIDES:=libulfius
+endef
+
+define Package/libulfius-gnutls
+$(call Package/libulfius/default)
+  TITLE+= with SSL support
+  VARIANT:=gnutls
+  DEPENDS:=+libmicrohttpd +libcurl +liborcania +libgnutls +zlib
+  PROVIDES:=libulfius
+endef
+
+CMAKE_OPTIONS += \
+	-D_GNU_SOURCE=ON \
+	-DDOWNLOAD_DEPENDENCIES=OFF \
+	-DBUILD_WEBSOCKET=OFF \
+	-DSEARCH_ORCANIA_U=ON \
+	-DWITH_CURL=ON \
+	-DWITH_JANSSON=OFF \
+	-DWITH_STRSTR=ON \
+	-DWITH_YDER=OFF \
+	-DSEARCH_YDER=OFF \
+	-DCMAKE_BUILD_TYPE=Release
+
+ifeq ($(BUILD_VARIANT),gnutls)
+	CMAKE_OPTIONS += -DWITH_GNUTLS=ON
+else
+	CMAKE_OPTIONS += -DWITH_GNUTLS=OFF
+endif
+
+$(eval $(call BuildPackage,libulfius-gnutls))
+$(eval $(call BuildPackage,libulfius-nossl))
diff --git a/external/subpack/libs/libulfius/patches/0001-cmake-pc-orcania-found.patch b/external/subpack/libs/libulfius/patches/0001-cmake-pc-orcania-found.patch
new file mode 100644
index 0000000..b95b8c0
--- /dev/null
+++ b/external/subpack/libs/libulfius/patches/0001-cmake-pc-orcania-found.patch
@@ -0,0 +1,11 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -257,7 +257,7 @@ if (SEARCH_ORCANIA_U)
+     set(Orcania_FIND_QUIETLY ON) # force to find Orcania quietly
+     include(FindOrcania)
+     find_package(Orcania ${ORCANIA_VERSION_REQUIRED} QUIET) # try to find orcania
+-    if (NOT ORCANIA_FOUND)
++    if (NOT ORCANIA_FOUND AND NOT PC_ORCANIA_FOUND)
+         if (DOWNLOAD_DEPENDENCIES)
+             include(DownloadProject)
+             download_project(PROJ orcania # ... otherwise, download archive
diff --git a/external/subpack/libs/libupm/Makefile b/external/subpack/libs/libupm/Makefile
new file mode 100644
index 0000000..3f7c3e6
--- /dev/null
+++ b/external/subpack/libs/libupm/Makefile
@@ -0,0 +1,367 @@
+#
+# Copyright (C) 2015-2018 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:=libupm
+PKG_VERSION:=2.0.0
+PKG_RELEASE:=7
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/intel-iot-devkit/upm/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=7dd2f4165b71e071d100b58d6a392f3cf57b0f257c82ffabf49e931b5ed6bc23
+PKG_BUILD_DIR:=$(BUILD_DIR)/upm-$(PKG_VERSION)
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>, Hirokazu MORIKAWA <morikw2@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+CMAKE_INSTALL:=1
+CMAKE_BINARY_SUBDIR:=build
+PKG_BUILD_FLAGS:=no-mips16
+PYTHON3_PKG_BUILD:=0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+include ../../lang/python/python3-package.mk
+
+UPM_MODULES:= \
+	a110x abp ad8232 adafruitms1438 adafruitss adc121c021 adis16448 ads1x15 adxl335 adxl345 \
+	adxrs610 am2315 apa102 apds9002 apds9930 at42qt1070 bh1749 bh1750 bh1792 biss0001 bma220 \
+	bma250e bmg160 bmi160 bmm150 bmp280 bmpx8x bmx055 bno055 button buzzer cjq4435 collision \
+	cwlsxxa dfrec dfrorp dfrph ds1307 ds1808lc ds18b20 ds2413 ecezo ecs1030 \
+	ehr eldriver electromagnet emg enc03r flex gas gp2y0a gprs \
+	gsr guvas12d h3lis331dl hcsr04 hdc1000 hdxxvxta hka5 hlg150h hm11 hmc5883l hmtrp hp20x \
+	ht9170 htu21d hx711 ili9341 ims ina132 interfaces isd1820 itg3200 jhd1313m1 joystick12 kx122 \
+	kxcjk1013 kxtj3 l298 l3gd20 lcd lcdks lcm1602 ldt0028 led lidarlitev3 light linefinder lis2ds12 \
+	lis3dh lm35 lol loudness lp8860 lpd8806 lsm303agr lsm303d lsm303dlh lsm6ds3h lsm6dsl lsm9ds0 \
+	m24lr64e mag3110 max30100 max31723 max31855 max44000 max44009 max5487 maxds3231m maxsonarez \
+	mb704x mcp2515 mcp9808 md mg811 mhz16 mic micsv89 mlx90614 mma7361 mma7455 mma7660 mma8x5x \
+	mmc35240 moisture mpl3115a2 mpr121 mpu9150 mq303a ms5611 ms5803 my9221 nlgpio16 nmea_gps \
+	nrf24l01 nrf8001 nunchuck o2 otp538u p9813 pca9685 pn532 ppd42ns pulsensor relay rf22 \
+	rfr359f rgbringcoder rhusb rn2903 rotary rotaryencoder rpr220 rsc scam sensortemplate \
+	servo sht1x si1132 si114x si7005 slide sm130 smartdrive speaker ssd1351 st7735 stepmotor \
+	sx1276 sx6119 t6713 ta12200 tca9548a tcs3414cs tcs37727 teams temperature \
+	tex00 th02 tm1637 tmp006 tsl2561 ttp223 uartat uln200xa ultrasonic urm37 utilities vdiv \
+	veml6070 water waterlevel wfs wheelencoder wt5001 xbee yg1006 zfm20 \
+	vcap t3311 hwxpxx h803x ozw curieimu
+# (require libbacnet) tb7300 t8100 e50hx bacnetmstp
+# (require libtinyb) 2jciebu01_ble 2jciebu01_usb
+
+CMAKE_OPTIONS += \
+	-DBUILDSWIGNODE=OFF \
+	-DWERROR=OFF \
+	-DPYTHON2LIBS_FOUND=FALSE \
+	-DPYTHON2INTERP_FOUND=FALSE \
+
+define Package/libupm/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=IoT
+  URL:=https://github.com/intel-iot-devkit/upm
+  DEPENDS:=+libmraa +librt
+endef
+
+define Package/libupm/Default/description
+  UPM is a high level repository that provides software drivers for a wide variety
+of commonly used sensors and actuators. These software drivers interact with the
+underlying hardware platform through calls to MRAA APIs.
+  MRAA that allows you to use various sensors on platforms such as the Intel Galileo,
+Intel Edison, Minnowboard MAX and others.
+endef
+
+define Package/libupm
+  $(call Package/libupm/Default)
+  TITLE:=Intel IoT sensor library - Full
+  DEPENDS+=+libjpeg +libmodbus +openzwave
+  DEPENDS+= $(foreach module, $(UPM_MODULES), +libupm-$(module))
+  DEPENDS+= $(foreach module, $(UPM_MODULES), +libupm-$(module)-python3)
+endef
+
+define Package/libupm/description
+$(call Package/libupm/Default/description)
+
+This package contains sensor libraries
+endef
+
+define Package/libupm/install/Default
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libupm*-$(2).so* $(1)/usr/lib/ ;
+endef
+
+define Package/libupm/install/Default-python3
+	$(INSTALL_DIR) $(1)/usr/lib/python$(PYTHON3_VERSION)/site-packages/upm
+	$(CP) $(CMAKE_BINARY_DIR)/$(if $(filter interfaces, $(2)),,src/)$(2)/python$(PYTHON3_VERSION)/pyupm_$(2).py \
+		$(1)/usr/lib/python$(PYTHON3_VERSION)/site-packages/upm/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/python$(PYTHON3_VERSION)/site-packages/upm/_pyupm_$(2).so \
+		$(1)/usr/lib/python$(PYTHON3_VERSION)/site-packages/upm/ ;
+endef
+
+define Package/libupm/install
+	$(foreach module, $(UPM_MODULES), \
+		$(call Package/libupm/install/Default,$(1),$(module)) \
+		$(call Package/libupm/install/Default-python3,$(1),$(module)))
+endef
+
+define UpmPackage
+define UpmPackage/depends
+  ifeq ($$(1),adafruitms1438)
+    DEPENDS+=+libupm-pca9685
+  endif
+  ifeq ($$(1),ads1x15)
+    DEPENDS+=+libupm-interfaces
+  endif
+  ifeq ($$(1),apa102)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($(1),bh1749)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),bh1750)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($(1),bh1792)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),bma250e)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),bmg160)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),bmi160)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),bmm150)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),bmp280)
+    DEPENDS+=+libupm-interfaces +libupm-utilities
+  endif
+  ifeq ($$(1),bmpx8x)
+    DEPENDS+=+libupm-interfaces +libupm-utilities
+  endif
+  ifeq ($$(1),bmx055)
+    DEPENDS+=+libupm-utilities +libupm-bma250e +libupm-bmg160 +libupm-bmm150
+  endif
+  ifeq ($$(1),bno055)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),buzzer)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),cjq4435)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),dfrec)
+    DEPENDS+=+libupm-utilities +libupm-ds18b20
+  endif
+  ifeq ($$(1),ds18b20)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),dfrorp)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),ds1808lc)
+    DEPENDS+=+libupm-interfaces
+  endif
+  ifeq ($$(1),ecezo)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),enc03r)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),guvas12d)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),hcsr04)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),hka5)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),hlg150h)
+    DEPENDS+=+libupm-interfaces
+  endif
+  ifeq ($$(1),ims)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),jhd1313m1)
+    DEPENDS+=+libupm-utilities +libupm-lcm1602
+  endif
+  ifeq ($$(1),kxtj3)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),lcm1602)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),lcdks)
+    DEPENDS+=+libupm-utilities +libupm-lcm1602
+  endif
+  ifeq ($$(1),lis2ds12)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),lis3dh)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),lp8860)
+    DEPENDS+=+libupm-interfaces
+  endif
+  ifeq ($$(1),lsm303agr)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),lsm303d)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),lsm6ds3h)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),lsm6dsl)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),m24lr64e)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),max30100)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),max44009)
+    DEPENDS+=+libupm-interfaces
+  endif
+  ifeq ($$(1),mb704x)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),mcp2515)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),md)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),mma7361)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),ms5611)
+    DEPENDS+=+libupm-interfaces
+  endif
+  ifeq ($$(1),ms5803)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),my9221)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),nmea_gps)
+    DEPENDS+=+libupm-utilities +libatomic
+  endif
+  ifeq ($$(1),nunchuck)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),otp538u)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),p9813)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),ppd42ns)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),rn2903)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),rsc)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),servo)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),sht1x)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),si1132)
+    DEPENDS+=+libupm-interfaces
+  endif
+  ifeq ($$(1),si7005)
+    DEPENDS+=+libupm-interfaces
+  endif
+  ifeq ($$(1),speaker)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),t6713)
+    DEPENDS+=+libupm-interfaces
+  endif
+  ifeq ($$(1),tsl2561)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),uartat)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),uln200xa)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),urm37)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),wfs)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),zfm20)
+    DEPENDS+=+libupm-utilities
+  endif
+  ifeq ($$(1),vcap)
+    DEPENDS+=+libjpeg
+  endif
+  ifeq ($$(1),t3311)
+    DEPENDS+=+libmodbus
+  endif
+  ifeq ($$(1),ozw)
+    DEPENDS+=+openzwave
+  endif
+  ifeq ($$(1),hwxpxx)
+    DEPENDS+=+libmodbus
+  endif
+  ifeq ($$(1),h803x)
+    DEPENDS+=+libmodbus
+  endif
+endef
+
+define Package/libupm-$(1)
+  $(call Package/libupm/Default)
+  $(call UpmPackage/depends,$(1))
+  TITLE:=$(1) C/C++ library
+endef
+
+define Package/libupm-$(1)/description
+$(call Package/libupm/Default/description)
+
+This package contains $(1) sensor C/C++ library
+endef
+
+define Package/libupm-$(1)-python3
+  $(call Package/libupm/Default)
+  $(call UpmPackage/depends,$(1))
+  TITLE:=$(1) Python3 library
+  DEPENDS+=+libupm-$(1) +libmraa-python3 +python3-light
+endef
+
+define Package/libupm-$(1)-python3/description
+$(call Package/libupm/Default/description)
+
+This package contains $(1) sensor Python3 library
+endef
+
+define Package/libupm-$(1)/install
+	$(call Package/libupm/install/Default,$$(1),$(1))
+endef
+define Package/libupm-$(1)-python3/install
+	$(call Package/libupm/install/Default-python3,$$(1),$(1))
+endef
+endef
+
+$(eval $(call BuildPackage,libupm))
+$(foreach module, $(UPM_MODULES), \
+	$(eval $(call UpmPackage,$(module))) \
+	$(eval $(call BuildPackage,libupm-$(module))) \
+	$(eval $(call BuildPackage,libupm-$(module)-python3)))
diff --git a/external/subpack/libs/libupm/patches/001-version.patch b/external/subpack/libs/libupm/patches/001-version.patch
new file mode 100644
index 0000000..b1f9c9f
--- /dev/null
+++ b/external/subpack/libs/libupm/patches/001-version.patch
@@ -0,0 +1,18 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -231,14 +231,7 @@ include(GNUInstallDirs)
+ set (LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}" CACHE PATH "Installation path for libraries")
+ 
+ # Make a version file containing the current version from git.
+-include (GetGitRevisionDescription)
+-git_describe (VERSION "--tags")
+-# If git_describe fails, use a dirty version
+-if (${VERSION} MATCHES -NOTFOUND)
+-  set (VERSION "v1.7.1")
+-  message (WARNING "Failed to retrieve UPM version with 'git describe' (using "
+-      "${VERSION}). Check that git is installed and this is a valid git repo.")
+-endif ()
++  set (VERSION "v2.0.0")
+ 
+ message (STATUS "UPM Version ${VERSION}")
+ 
diff --git a/external/subpack/libs/libupm/patches/002-at42qt1070-id.patch b/external/subpack/libs/libupm/patches/002-at42qt1070-id.patch
new file mode 100644
index 0000000..295bfd5
--- /dev/null
+++ b/external/subpack/libs/libupm/patches/002-at42qt1070-id.patch
@@ -0,0 +1,11 @@
+--- a/src/at42qt1070/at42qt1070.cxx
++++ b/src/at42qt1070/at42qt1070.cxx
+@@ -53,7 +53,7 @@ AT42QT1070::AT42QT1070(int bus, uint8_t
+         return;
+     }
+ 
+-    if (readChipID() != 0x2E) {
++    if (readChipID() != 0x1b && readChipID() != 0x2E) {
+         throw std::runtime_error("Chip ID does not match the expected value (2Eh)");
+     }
+ 
diff --git a/external/subpack/libs/libupm/patches/003-link-atomic.patch b/external/subpack/libs/libupm/patches/003-link-atomic.patch
new file mode 100644
index 0000000..e7e9959
--- /dev/null
+++ b/external/subpack/libs/libupm/patches/003-link-atomic.patch
@@ -0,0 +1,8 @@
+--- a/src/nmea_gps/CMakeLists.txt
++++ b/src/nmea_gps/CMakeLists.txt
+@@ -6,4 +6,4 @@ upm_mixed_module_init (NAME nmea_gps
+     CPP_SRC nmea_gps.cxx
+     FTI_SRC nmea_gps_fti.c
+     CPP_WRAPS_C
+-    REQUIRES mraa utilities-c ${CMAKE_THREAD_LIBS_INIT})
++    REQUIRES mraa utilities-c atomic ${CMAKE_THREAD_LIBS_INIT})
diff --git a/external/subpack/libs/libupm/patches/004-uint8_t.patch b/external/subpack/libs/libupm/patches/004-uint8_t.patch
new file mode 100644
index 0000000..46d25ed
--- /dev/null
+++ b/external/subpack/libs/libupm/patches/004-uint8_t.patch
@@ -0,0 +1,103 @@
+--- a/src/bma250e/bma250e.cxx
++++ b/src/bma250e/bma250e.cxx
+@@ -195,35 +195,35 @@ BMA250E::BMA250E(std::string initStr) :
+             fifoConfig(mode, axes);
+         }
+         if(tok.substr(0, 20) == "setInterruptEnable0:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(20), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(20), nullptr, 0);
+             setInterruptEnable0(bits);
+         }
+         if(tok.substr(0, 20) == "setInterruptEnable1:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(20), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(20), nullptr, 0);
+             setInterruptEnable1(bits);
+         }
+         if(tok.substr(0, 20) == "setInterruptEnable2:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(20), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(20), nullptr, 0);
+             setInterruptEnable2(bits);
+         }
+         if(tok.substr(0, 17) == "setInterruptMap0:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(17), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(17), nullptr, 0);
+             setInterruptMap0(bits);
+         }
+         if(tok.substr(0, 17) == "setInterruptMap1:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(17), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(17), nullptr, 0);
+             setInterruptMap1(bits);
+         }
+         if(tok.substr(0, 17) == "setInterruptMap2:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(17), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(17), nullptr, 0);
+             setInterruptMap2(bits);
+         }
+         if(tok.substr(0, 16) == "setInterruptSrc:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(16), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(16), nullptr, 0);
+             setInterruptSrc(bits);
+         }
+         if(tok.substr(0, 26) == "setInterruptOutputControl:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(26), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(26), nullptr, 0);
+             setInterruptOutputControl(bits);
+         }
+         if(tok.substr(0, 26) == "setInterruptLatchBehavior:") {
+--- a/src/bmg160/bmg160.cxx
++++ b/src/bmg160/bmg160.cxx
+@@ -173,23 +173,23 @@ BMG160::BMG160(std::string initStr) : mr
+             fifoConfig(mode, axes);
+         }
+         if(tok.substr(0, 20) == "setInterruptEnable0:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(20), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(20), nullptr, 0);
+             setInterruptEnable0(bits);
+         }
+         if(tok.substr(0, 17) == "setInterruptMap0:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(17), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(17), nullptr, 0);
+             setInterruptMap0(bits);
+         }
+         if(tok.substr(0, 17) == "setInterruptMap1:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(17), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(17), nullptr, 0);
+             setInterruptMap1(bits);
+         }
+         if(tok.substr(0, 16) == "setInterruptSrc:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(16), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(16), nullptr, 0);
+             setInterruptSrc(bits);
+         }
+         if(tok.substr(0, 26) == "setInterruptOutputControl:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(26), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(26), nullptr, 0);
+             setInterruptOutputControl(bits);
+         }
+         if(tok.substr(0, 26) == "setInterruptLatchBehavior:") {
+--- a/src/bmm150/bmm150.cxx
++++ b/src/bmm150/bmm150.cxx
+@@ -170,19 +170,19 @@ BMM150::BMM150(std::string initStr) : mr
+             setOpmode(opmode);
+         }
+         if(tok.substr(0, 19) == "setInterruptEnable:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(19), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(19), nullptr, 0);
+             setInterruptEnable(bits);
+         }
+         if(tok.substr(0, 19) == "setInterruptConfig:") {
+-            u_int8_t bits = (u_int8_t)std::stoul(tok.substr(19), nullptr, 0);
++            uint8_t bits = (uint8_t)std::stoul(tok.substr(19), nullptr, 0);
+             setInterruptConfig(bits);
+         }
+         if(tok.substr(0, 17) == "setRepetitionsXY:") {
+-            u_int8_t reps = (u_int8_t)std::stoul(tok.substr(17), nullptr, 0);
++            uint8_t reps = (uint8_t)std::stoul(tok.substr(17), nullptr, 0);
+             setRepetitionsXY(reps);
+         }
+         if(tok.substr(0, 16) == "setRepetitionsZ:") {
+-            u_int8_t reps = (u_int8_t)std::stoul(tok.substr(16), nullptr, 0);
++            uint8_t reps = (uint8_t)std::stoul(tok.substr(16), nullptr, 0);
+             setRepetitionsZ(reps);
+         }
+         if(tok.substr(0, 14) == "setPresetMode:") {
diff --git a/external/subpack/libs/libupm/patches/005-support_v12.patch b/external/subpack/libs/libupm/patches/005-support_v12.patch
new file mode 100644
index 0000000..c9d9c66
--- /dev/null
+++ b/external/subpack/libs/libupm/patches/005-support_v12.patch
@@ -0,0 +1,11 @@
+--- a/src/carrays_uint32_t.i
++++ b/src/carrays_uint32_t.i
+@@ -24,7 +24,7 @@
+ %typemap(in) uint32_t {
+   int ecode2 = 0 ;
+   if (($input)->IsInt32())
+-    $1 = ($input)->Uint32Value();
++    $1 = ($input)->Uint32Value(SWIGV8_CURRENT_CONTEXT()).FromJust();
+   else
+     SWIG_exception_fail(SWIG_ArgError(ecode2), "failed to convert uint32");
+ }
diff --git a/external/subpack/libs/libupm/patches/011-gcc-13-compatibility-fixes.patch b/external/subpack/libs/libupm/patches/011-gcc-13-compatibility-fixes.patch
new file mode 100644
index 0000000..feed25e
--- /dev/null
+++ b/external/subpack/libs/libupm/patches/011-gcc-13-compatibility-fixes.patch
@@ -0,0 +1,26 @@
+--- a/src/mcp9808/mcp9808.hpp
++++ b/src/mcp9808/mcp9808.hpp
+@@ -30,6 +30,10 @@
+ #include <string>
+ #include <interfaces/iTemperature.hpp>
+ 
++#ifndef uint8_t
++#include <cstdint>
++#endif
++
+ #define MCP9808_REG_CONFIG  0x01
+ #define MCP9808_REG_AMBIENT_TEMP 0x05
+ #define MCP9808_REG_MANUF_ID 0x06
+--- a/src/micsv89/micsv89.hpp
++++ b/src/micsv89/micsv89.hpp
+@@ -27,6 +27,10 @@
+ #include <iostream>
+ #include <string>
+ 
++#ifndef uint8_t
++#include <cstdint>
++#endif
++
+ #include <interfaces/iGas.hpp>
+ 
+ namespace mraa { class I2c;}
diff --git a/external/subpack/libs/libupnp/Makefile b/external/subpack/libs/libupnp/Makefile
new file mode 100644
index 0000000..f4edb3e
--- /dev/null
+++ b/external/subpack/libs/libupnp/Makefile
@@ -0,0 +1,97 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libupnp
+PKG_VERSION:=1.14.18
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@SF/pupnp
+PKG_HASH:=16a7cee93ce2868ae63ab1a8164dc7de43577c59983b9f61293a310d6888dceb
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libupnp_project:libupnp
+
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_PACKAGE_libupnp-sample \
+	CONFIG_IPV6
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libupnp/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=http://pupnp.sourceforge.net/
+endef
+
+define Package/libupnp
+  $(call Package/libupnp/Default)
+  DEPENDS:=+libpthread
+  TITLE:=UPnP SDK library
+  MENU:=1
+endef
+
+define Package/libupnp/description
+The portable SDK for UPnP Devices (libupnp) provides developers with an API and
+open source code for building control points, devices, and bridges that are
+compliant with Version 1.0 of the  Universal Plug and Play Device Architecture
+Specification.
+endef
+
+define Package/libupnp-sample
+  $(call Package/libupnp/Default)
+  DEPENDS:=libupnp
+  TITLE:=UPnP sample applications
+endef
+
+define Package/libupnp-sample/description
+TVcontrolpoint & tvdevice sample applications run inside /etc/upnp-tvdevice/
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_TESTING=OFF \
+	-Dclient=ON \
+	-Ddevice=ON \
+	-Dwebserver=ON \
+	-Dssdp=ON \
+	-Doptssdp=OFF \
+	-Dsoap=ON \
+	-Dgena=ON \
+	-Dtools=ON \
+	-Dipv6=O$(if $(CONFIG_IPV6),N,FF) \
+	-Dunspecified_server=OFF \
+	-Dopen_ssl=OFF \
+	-Dblocking_tcp_connections=ON \
+	-Dscriptsupport=OFF \
+	-Dpostwrite=OFF \
+	-Dreuseaddr=ON \
+	-Dsamples=O$(if $(CONFIG_PACKAGE_libupnp-sample),N,FF) \
+	-DDOWNLOAD_AND_BUILD_DEPS=OFF
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/upnp $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib{ixml,upnp}.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/cmake
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/cmake/* $(1)/usr/lib/cmake
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libupnp.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libupnp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib{ixml,upnp}.so.* $(1)/usr/lib/
+endef
+
+define Package/libupnp-sample/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/tv* $(1)/usr/bin
+	$(INSTALL_DIR) $(1)/usr/share/upnp
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/upnp/tv* $(1)/usr/share/upnp
+endef
+
+$(eval $(call BuildPackage,libupnp))
+$(eval $(call BuildPackage,libupnp-sample))
diff --git a/external/subpack/libs/libupnp/patches/010-format.patch b/external/subpack/libs/libupnp/patches/010-format.patch
new file mode 100644
index 0000000..ea69435
--- /dev/null
+++ b/external/subpack/libs/libupnp/patches/010-format.patch
@@ -0,0 +1,47 @@
+From 155eb2a6dea9489e3d206bfe6ef6612cb93becc4 Mon Sep 17 00:00:00 2001
+From: Rosen Penev <rosenp@gmail.com>
+Date: Sat, 29 Jun 2024 16:59:10 -0700
+Subject: [PATCH] fix 32-bit format warnings
+
+Seems this PRIzu takes size_t, not unsigned long.
+
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+---
+ upnp/src/gena/gena_device.c              | 2 +-
+ upnp/src/genlib/net/http/httpreadwrite.c | 7 ++-----
+ 2 files changed, 3 insertions(+), 6 deletions(-)
+
+--- a/upnp/src/gena/gena_device.c
++++ b/upnp/src/gena/gena_device.c
+@@ -449,7 +449,7 @@ static char *AllocGenaHeaders(
+ 		"%s%s%" PRIzu "%s%s%s",
+ 		HEADER_LINE_1,
+ 		HEADER_LINE_2A,
+-		(unsigned long)strlen(propertySet) + 2,
++		strlen(propertySet) + 2,
+ 		HEADER_LINE_2B,
+ 		HEADER_LINE_3,
+ 		HEADER_LINE_4);
+--- a/upnp/src/genlib/net/http/httpreadwrite.c
++++ b/upnp/src/genlib/net/http/httpreadwrite.c
+@@ -626,7 +626,7 @@ int http_SendMessage(SOCKINFO *info, int
+ 					rc = snprintf(Chunk_Header,
+ 						sizeof(Chunk_Header),
+ 						"%" PRIzx "\r\n",
+-						(unsigned long)num_read);
++						num_read);
+ 					if (rc < 0 ||
+ 						(unsigned int)rc >=
+ 							sizeof(Chunk_Header)) {
+@@ -1765,10 +1765,7 @@ int http_MakeMessage(membuffer *buf,
+ 		} else if (c == 'd') {
+ 			/* integer */
+ 			num = (size_t)va_arg(argp, int);
+-			rc = snprintf(tempbuf,
+-				sizeof(tempbuf),
+-				"%" PRIzu,
+-				(unsigned long)num);
++			rc = snprintf(tempbuf, sizeof(tempbuf), "%" PRIzu, num);
+ 			if (rc < 0 || (unsigned int)rc >= sizeof(tempbuf) ||
+ 				membuffer_append(buf, tempbuf, strlen(tempbuf)))
+ 				goto error_handler;
diff --git a/external/subpack/libs/libupnpp/Makefile b/external/subpack/libs/libupnpp/Makefile
new file mode 100644
index 0000000..cbe2d63
--- /dev/null
+++ b/external/subpack/libs/libupnpp/Makefile
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 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:=libupnpp
+PKG_VERSION:=0.26.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://www.lesbonscomptes.com/upmpdcli/downloads
+PKG_HASH:=b0e089783c5893c16afe23d90a6ee6947c2ec34ca6c3cf555622f7d9cc2b2b3c
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libupnpp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=https://www.lesbonscomptes.com/upmpdcli
+  DEPENDS+=+libnpupnp
+  TITLE:=The libupnpp C++ library wraps libupnp for easier use by upmpdcli and upplay
+endef
+
+define Package/libupnpp/description
+libupnpp defines useful objects over libupnp and can be used to create both devices
+and control points. It is shared by upmpdcli and upplay.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libupnpp $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libupnpp.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libupnpp.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libupnpp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libupnpp.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libupnpp))
diff --git a/external/subpack/libs/liburcu/Makefile b/external/subpack/libs/liburcu/Makefile
new file mode 100644
index 0000000..70ad97d
--- /dev/null
+++ b/external/subpack/libs/liburcu/Makefile
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2015 OpenWrt.org
+# Copyright (C) 2014-2018 CZ.NIC, z.s.p.o. <knot-dns@labs.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:=liburcu
+PKG_VERSION:=0.14.1
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=Daniel Salzman <daniel.salzman@nic.cz>
+PKG_LICENSE:=LGPL-2.1-or-later GPL-2.0-or-later MIT
+PKG_LICENSE_FILES:=lgpl-2.1.txt gpl-2.0.txt lgpl-relicensing.txt
+
+PKG_SOURCE:=userspace-rcu-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://lttng.org/files/urcu/
+PKG_HASH:=231acb13dc6ec023e836a0f0666f6aab47dc621ecb1d2cd9d9c22f922678abc0
+PKG_BUILD_DIR:=$(BUILD_DIR)/userspace-rcu-$(PKG_VERSION)
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=no-mips16
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/liburcu
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=User-space Read-Copy-Update library
+	URL:=https://lttng.org/
+	DEPENDS:=+libpthread @!arc
+endef
+
+define Package/liburcu/description
+	Userspace Read-Copy-Update library.
+endef
+
+ifeq ($(CONFIG_arc),)
+define Build/InstallDev
+	$(INSTALL_DIR)						$(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/urcu*		$(1)/usr/include/
+	$(INSTALL_DIR)						$(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liburcu*.{a,so*}	$(1)/usr/lib/
+	$(INSTALL_DIR)						$(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc		$(1)/usr/lib/pkgconfig/
+endef
+endif
+
+define Package/liburcu/install
+	$(INSTALL_DIR)					$(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liburcu*.so.*	$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,liburcu))
diff --git a/external/subpack/libs/liburcu/patches/010-no-tests.patch b/external/subpack/libs/liburcu/patches/010-no-tests.patch
new file mode 100644
index 0000000..2efade1
--- /dev/null
+++ b/external/subpack/libs/liburcu/patches/010-no-tests.patch
@@ -0,0 +1,10 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,6 +1,6 @@
+ ACLOCAL_AMFLAGS=-I m4
+ 
+-SUBDIRS = include src doc tests extras
++SUBDIRS = include src
+ 
+ dist_doc_DATA = LICENSE \
+ 		README.md
diff --git a/external/subpack/libs/liburing/Makefile b/external/subpack/libs/liburing/Makefile
new file mode 100644
index 0000000..8d682de
--- /dev/null
+++ b/external/subpack/libs/liburing/Makefile
@@ -0,0 +1,58 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=liburing
+PKG_VERSION:=2.7
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://git.kernel.dk/cgit/liburing/snapshot
+PKG_HASH:=cc5268f97d089bc21d3d5848959e6620b2dfc85023b92479dad0496b2c51df06
+
+PKG_MAINTAINER:=Christian Lachner <gladiac@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/liburing
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=io_uring library
+  URL:=https://git.kernel.dk/cgit/liburing
+  DEPENDS:=@KERNEL_IO_URING
+endef
+
+define Package/liburing/description
+  liburing provides helpers to setup and teardown io_uring instances,
+  and also a simplified interface for applications that don't need
+  (or want) to deal with the full kernel side implementation.
+  For more info on io_uring, please see: https://kernel.dk/io_uring.pdf
+endef
+
+CONFIGURE_ARGS:=--prefix=$(CONFIGURE_PREFIX) --cc="${TARGET_CC}"
+
+define Build/Compile
+	$(MAKE) $(PKG_BUILD_DIR) \
+		DSTROOT="$(PKG_INSTALL_DIR)"
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.{so*,a} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/liburing.pc $(1)/usr/lib/pkgconfig/
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/liburing.pc
+	$(SED) 's,/usr/lib,$$$${prefix}/lib,g' $(1)/usr/lib/pkgconfig/liburing.pc
+endef
+
+define Package/liburing/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liburing.so $(PKG_INSTALL_DIR)/usr/lib/liburing.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,liburing))
diff --git a/external/subpack/libs/libusb-compat/Makefile b/external/subpack/libs/libusb-compat/Makefile
new file mode 100644
index 0000000..037f590
--- /dev/null
+++ b/external/subpack/libs/libusb-compat/Makefile
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2010-2015 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:=libusb-compat
+PKG_VERSION:=0.1.8
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://github.com/libusb/libusb-compat-0.1/releases/download/v$(PKG_VERSION)
+PKG_HASH:=b692dcf674c070c8c0bee3c8230ce4ee5903f926d77dc8b968a4dd1b70f9b05c
+
+PKG_MAINTAINER:= Felix Fietkau <nbd@nbd.name>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libusb-compat
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libusb-0.1 compatibility library
+  DEPENDS:=+libusb-1.0
+  URL:=https://libusb.info/
+  ABI_VERSION:=4
+endef
+
+define Package/libusb-compat/description
+  libusb is a C library that gives applications easy access to USB devices on
+  many different operating systems.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/libusb-config $(1)/usr/bin/
+	$(SED) \
+		's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \
+		$(1)/usr/bin/libusb-config
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/libusb-config $(2)/bin/
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/usb.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libusb* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libusb.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libusb-compat/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libusb-0.1.so.$(ABI_VERSION)* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libusb-compat))
diff --git a/external/subpack/libs/libusbmuxd/Makefile b/external/subpack/libs/libusbmuxd/Makefile
new file mode 100644
index 0000000..3ad1dab
--- /dev/null
+++ b/external/subpack/libs/libusbmuxd/Makefile
@@ -0,0 +1,93 @@
+#
+# Copyright (C) 2012-2014 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:=libusbmuxd
+PKG_VERSION:=2.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://github.com/libimobiledevice/libusbmuxd/releases/download/$(PKG_VERSION)
+PKG_HASH:=c35bf68f8e248434957bd5b234c389b02206a06ecd9303a7fb931ed7a5636b16
+
+PKG_MAINTAINER:=Rosen Penev <rosenp@gmail.com>
+PKG_CPE_ID:=cpe:/a:libimobiledevice:libusbmuxd
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libusbmuxd/Default
+  TITLE:=USB multiplexing daemon
+  URL:=https://www.libimobiledevice.org/
+  SUBMENU:=libimobiledevice
+endef
+
+define Package/libusbmuxd/Default/description
+  This daemon is in charge of multiplexing connections over USB to an iPhone or
+  iPod touch. To users, it means you can sync your music, contacts, photos, etc.
+  over USB. To developers, it means you can connect to any listening localhost
+  socket on the device. usbmuxd is not used for tethering data transfer, which
+  uses a dedicated USB interface as a virtual network device.
+endef
+
+define Package/libusbmuxd
+  $(call Package/libusbmuxd/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE+= library
+  DEPENDS:=+libplist +libimobiledevice-glue +libpthread +libxml2 +zlib
+  PKG_LICENSE:=LGPL-2.1-or-later
+  PKG_LICENSE_FILES:=COPYING
+endef
+
+define Package/libusbmuxd/description
+  $(call Package/libusbmuxd/Default/description)
+  This package contains the libusbmuxd shared library.
+endef
+
+define Package/libusbmuxd-utils
+  $(call Package/libusbmuxd/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE+= utilies
+  DEPENDS:=+libusbmuxd
+  LICENSE:=GPL-2.0-or-later
+endef
+
+define Package/libusbmuxd-utils/description
+  $(call Package/libusbmuxd/Default/description)
+  This package contains the libusbmuxd utilities.
+endef
+
+CONFIGURE_ARGS += \
+	--disable-static
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libusbmuxd-2.0.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libusbmuxd-2.0.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libusbmuxd/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libusbmuxd-2.0.so.* $(1)/usr/lib/
+endef
+
+define Package/libusbmuxd-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/iproxy $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/inetcat $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libusbmuxd))
+$(eval $(call BuildPackage,libusbmuxd-utils))
diff --git a/external/subpack/libs/libutp/Makefile b/external/subpack/libs/libutp/Makefile
new file mode 100644
index 0000000..025669e
--- /dev/null
+++ b/external/subpack/libs/libutp/Makefile
@@ -0,0 +1,46 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libutp
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/transmission/libutp
+PKG_SOURCE_DATE:=2023-02-14
+PKG_SOURCE_VERSION:=c95738b1a6644b919e5b64d3ea9736cfc5894e0b
+PKG_MIRROR_HASH:=abc2013d44bc30e4e12f89334f3f196243178699eeefbfc52744652889a150e6
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libutp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=The uTorrent Transport Protocol library
+  DEPENDS:=+libstdcpp
+endef
+
+# MAKE_VARS+=OPT="-I$(PKG_BUILD_DIR)/include/libutp -I$(PKG_BUILD_DIR)/include"
+
+CMAKE_OPTIONS += \
+	-DLIBUTP_SHARED:BOOL=YES \
+	-DLIBUTP_ENABLE_INSTALL:BOOL=YES \
+	-DLIBUTP_ENABLE_WERROR:BOOL=YES \
+	-DLIBUTP_BUILD_PROGRAMS:BOOL=NO
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/libutp $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libutp/*.h $(1)/usr/include/libutp
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libutp.so $(1)/usr/lib/
+endef
+
+define Package/libutp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/libutp.so $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libutp))
diff --git a/external/subpack/libs/libuv/Makefile b/external/subpack/libs/libuv/Makefile
new file mode 100644
index 0000000..df691ed
--- /dev/null
+++ b/external/subpack/libs/libuv/Makefile
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2015-2017 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:=libuv
+PKG_VERSION:=1.48.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-v$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://dist.libuv.org/dist/v$(PKG_VERSION)/
+PKG_HASH:=7f1db8ac368d89d1baf163bac1ea5fe5120697a73910c8ae6b2fffb3551d59fb
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-v$(PKG_VERSION)
+
+PKG_MAINTAINER:=Marko Ratkaj <markoratkaj@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:libuv_project:libuv
+
+CMAKE_BINARY_SUBDIR:=out/cmake
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libuv
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Cross-platform asychronous I/O library
+  URL:=https://libuv.org/
+  DEPENDS:=+libpthread +librt
+  ABI_VERSION:=1
+endef
+
+define Package/libuv/description
+ libuv is a multi-platform support library with a focus on asynchronous I/O. It
+ was primarily developed for use by Node.js, but it's also used by Luvit, Julia,
+ pyuv, and others.
+endef
+
+CMAKE_OPTIONS += -DBUILD_TESTING=OFF
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libuv.pc
+	$(SED) 's,/usr/lib,$$$${prefix}/lib,g' $(1)/usr/lib/pkgconfig/libuv.pc
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libuv-static.pc
+	$(SED) 's,/usr/lib,$$$${prefix}/lib,g' $(1)/usr/lib/pkgconfig/libuv-static.pc
+endef
+
+define Package/libuv/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libuv.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libuv))
diff --git a/external/subpack/libs/libuwifi/Makefile b/external/subpack/libs/libuwifi/Makefile
new file mode 100644
index 0000000..7399af0
--- /dev/null
+++ b/external/subpack/libs/libuwifi/Makefile
@@ -0,0 +1,53 @@
+#
+# Copyright (C) 2016 Bruno Randolf (br1@einfach.org)
+#               2019 Nick Hainke (vincent@systemli.org)
+#
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libuwifi
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/br101/libuwifi
+PKG_SOURCE_DATE:=2024-03-27
+PKG_SOURCE_VERSION:=9006d3b379927854fb077e1013ed297b66920547
+PKG_MIRROR_HASH:=905c6696fb43fab730b1a485a17bd49fd77eeceaec99b8b51b890be6bd0ccde4
+
+PKG_MAINTAINER:=Bruno Randolf <br1@einfach.org>, Nick Hainke <vincent@systemli.org>
+PKG_LICENSE:=LGPL-3.0-only
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libuwifi
+	SECTION:=libs
+	CATEGORY:=Libraries
+	DEPENDS:=+libradiotap +libnl-tiny
+	TITLE:=Userspace Wifi Library
+endef
+
+define Package/libuwifi/description
+	Library for parsing, generating and analyzing Wifi (WLAN 802.11) frames in userspace and related functions.
+endef
+
+MAKE_FLAGS += DEBUG=0 LIBNL=tiny BUILD_RADIOTAP=0
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/uwifi
+
+	$(CP) $(PKG_BUILD_DIR)/include/uwifi/*.h $(1)/usr/include/uwifi
+	$(CP) $(PKG_BUILD_DIR)/linux/*.h $(1)/usr/include/uwifi
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/build/libuwifi.{a,so*} $(1)/usr/lib/
+endef
+
+define Package/libuwifi/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/build/libuwifi.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libuwifi))
diff --git a/external/subpack/libs/libuwsc/Makefile b/external/subpack/libs/libuwsc/Makefile
new file mode 100644
index 0000000..d7d245b
--- /dev/null
+++ b/external/subpack/libs/libuwsc/Makefile
@@ -0,0 +1,91 @@
+#
+# Copyright (C) 2018 Jianhui Zhao
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libuwsc
+PKG_VERSION:=3.3.5
+PKG_RELEASE:=6
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL=https://github.com/zhaojh329/libuwsc/releases/download/v$(PKG_VERSION)
+PKG_HASH:=a06b7324671e181ffe3165e93e6f94c7ac1380f69e32a52e80c8da7016acd60d
+
+PKG_MAINTAINER:=Jianhui Zhao <jianhuizhao329@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+CMAKE_INSTALL:=1
+
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_LIBUWSC_openssl_LUA_BINDING \
+	CONFIG_LIBUWSC_wolfssl_LUA_BINDING \
+	CONFIG_LIBUWSC_mbedtls_LUA_BINDING \
+	CONFIG_LIBUWSC_nossl_LUA_BINDING
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libuwsc/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=Networking
+  TITLE:=A lightweight WebSocket client library based on libev
+  URL:=https://github.com/zhaojh329/libuwsc
+  DEPENDS:=+libev $(2)
+  VARIANT:=$(1)
+  PROVIDES:=libuwsc
+endef
+
+Package/libuwsc-openssl=$(call Package/libuwsc/Default,openssl,+PACKAGE_libuwsc-openssl:libopenssl)
+Package/libuwsc-wolfssl=$(call Package/libuwsc/Default,wolfssl,+PACKAGE_libuwsc-wolfssl:libwolfssl)
+Package/libuwsc-mbedtls=$(call Package/libuwsc/Default,mbedtls,+PACKAGE_libuwsc-mbedtls:libmbedtls)
+Package/libuwsc-nossl=$(call Package/libuwsc/Default,nossl)
+
+define Package/libuwsc/config
+menu "Configuration"
+	depends on PACKAGE_libuwsc-$(1)
+
+config LIBUWSC_$(1)_LUA_BINDING
+	bool
+	default n
+	prompt "Lua binding for libuwsc"
+endmenu
+endef
+
+Package/libuwsc-openssl/config=$(call Package/libuwsc/config,openssl)
+Package/libuwsc-wolfssl/config=$(call Package/libuwsc/config,wolfssl)
+Package/libuwsc-mbedtls/config=$(call Package/libuwsc/config,mbedtls)
+Package/libuwsc-nossl/config=$(call Package/libuwsc/config,nossl)
+
+ifeq ($(BUILD_VARIANT),openssl)
+  CMAKE_OPTIONS += -DUWSC_USE_OPENSSL=ON
+else ifeq ($(BUILD_VARIANT),wolfssl)
+  CMAKE_OPTIONS += -DUWSC_USE_WOLFSSL=ON
+else ifeq ($(BUILD_VARIANT),mbedtls)
+  CMAKE_OPTIONS += -DUWSC_USE_MBEDTLS=ON
+else
+  CMAKE_OPTIONS += -DUWSC_SSL_SUPPORT=OFF
+endif
+
+ifneq ($(CONFIG_LIBUWSC_$(BUILD_VARIANT)_LUA_BINDING),)
+  CMAKE_OPTIONS += -DUWSC_LUA_SUPPORT=ON
+endif
+
+define Package/libuwsc-$(BUILD_VARIANT)/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libuwsc.so* $(1)/usr/lib/
+ifneq ($(CONFIG_LIBUWSC_$(BUILD_VARIANT)_LUA_BINDING),)
+	$(INSTALL_DIR) $(1)/usr/lib/lua
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lua/uwsc.so $(1)/usr/lib/lua
+endif
+endef
+
+$(eval $(call BuildPackage,libuwsc-openssl))
+$(eval $(call BuildPackage,libuwsc-wolfssl))
+$(eval $(call BuildPackage,libuwsc-mbedtls))
+$(eval $(call BuildPackage,libuwsc-nossl))
diff --git a/external/subpack/libs/libuwsc/patches/001-fix_find_lua.patch b/external/subpack/libs/libuwsc/patches/001-fix_find_lua.patch
new file mode 100644
index 0000000..00d5c3e
--- /dev/null
+++ b/external/subpack/libs/libuwsc/patches/001-fix_find_lua.patch
@@ -0,0 +1,21 @@
+--- /dev/null
++++ b/cmake/Modules/FindLua.cmake
+@@ -0,0 +1,18 @@
++# - Try to find lua
++# Once done this will define
++#  LUA_FOUND          - System has lua
++#  LUA_INCLUDE_DIR    - The lua include directories
++#  LUA_LIBRARY        - The libraries needed to use lua
++
++find_path(LUA_INCLUDE_DIR lua.h)
++find_library(LUA_LIBRARY lua)
++
++include(FindPackageHandleStandardArgs)
++# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE
++# if all listed variables are TRUE and the requested version matches.
++find_package_handle_standard_args(Lua REQUIRED_VARS
++                                  LUA_LIBRARY LUA_INCLUDE_DIR
++                                  VERSION_VAR LUA_VERSION)
++
++mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY)
++
diff --git a/external/subpack/libs/libuwsc/patches/010-gcc11.patch b/external/subpack/libs/libuwsc/patches/010-gcc11.patch
new file mode 100644
index 0000000..5a1fd5b
--- /dev/null
+++ b/external/subpack/libs/libuwsc/patches/010-gcc11.patch
@@ -0,0 +1,11 @@
+--- a/src/lua/uwsc_lua.c
++++ b/src/lua/uwsc_lua.c
+@@ -177,7 +177,7 @@ static int uwsc_lua_on(lua_State *L)
+     else
+         luaL_argcheck(L, false, 2, "available event name: open message error close");
+ 
+-	return 0;
++    return 0;
+ }
+ 
+ static int __uwsc_lua_send(lua_State *L, int op)
diff --git a/external/subpack/libs/libuwsc/patches/100-cmake-fix-wolfssl-detection.patch b/external/subpack/libs/libuwsc/patches/100-cmake-fix-wolfssl-detection.patch
new file mode 100644
index 0000000..7f63f33
--- /dev/null
+++ b/external/subpack/libs/libuwsc/patches/100-cmake-fix-wolfssl-detection.patch
@@ -0,0 +1,10 @@
+--- a/src/ssl.c
++++ b/src/ssl.c
+@@ -54,6 +54,7 @@ struct uwsc_ssl_ctx {
+ #include <openssl/err.h>
+ #elif UWSC_HAVE_WOLFSSL
+ #define WC_NO_HARDEN
++#include <wolfssl/options.h>
+ #include <wolfssl/openssl/ssl.h>
+ #include <wolfssl/openssl/err.h>
+ #endif
diff --git a/external/subpack/libs/libv4l/Makefile b/external/subpack/libs/libv4l/Makefile
new file mode 100644
index 0000000..7f23f4d
--- /dev/null
+++ b/external/subpack/libs/libv4l/Makefile
@@ -0,0 +1,121 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=v4l-utils
+PKG_VERSION:=1.28.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://www.linuxtv.org/downloads/v4l-utils
+PKG_HASH:=fcb1ac1f22c1673e932b1779384f61cd6b7dd76e0e500bfb57e7a598588980b4
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+
+PKG_BUILD_FLAGS:=no-mips16
+
+PKG_BUILD_DEPENDS:=!USE_GLIBC:argp-standalone
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_BUILD_NLS \
+	CONFIG_PACKAGE_v4l-utils
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libv4l/Default
+  TITLE:=Video 4 Linux
+  URL:=https://www.linuxtv.org/
+endef
+
+define Package/libv4l/Default/description
+  libv4l is a collection of libraries which adds a thin abstraction layer on
+  top of video4linux2 devices. The purpose of this (thin) layer is to make it
+  easy for application writers to support a wide variety of devices without
+  having to write separate code for different devices in the same class. libv4l
+  consists of 3 different libraries: libv4lconvert, libv4l1 and libv4l2.
+
+  libv4l1 offers the (deprecated) v4l1 API on top of v4l2 devices, independent
+  of the drivers for those devices supporting v4l1 compatibility (which many
+  v4l2 drivers do not).
+
+  libv4l2 offers the v4l2 API on top of v4l2 devices, while adding for the
+  application transparent libv4lconvert conversion where necessary.
+endef
+
+define Package/libv4l
+  $(call Package/libv4l/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE+= wrapper libraries
+  DEPENDS:=$(ICONV_DEPENDS)
+  LICENSE:=LGPL-2.1-or-later
+  LICENSE_FILES:=COPYING.libv4l
+endef
+
+define Package/libv4l/description
+  $(call Package/libv4l/Default/description)
+endef
+
+define Package/v4l-utils
+  $(call Package/libv4l/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE+= utilities
+  DEPENDS:=+libudev +libv4l +libstdcpp $(ICONV_DEPENDS) $(INTL_DEPENDS)
+  LICENSE:=GPL-2.0-or-later
+  LICENSE_FILES:=COPYING
+endef
+
+define Package/v4l-utils/description
+  $(call Package/libv4l/Default/description)
+  This package contains the video4linux utilities.
+endef
+
+MESON_ARGS += \
+	-Db_lto=true \
+	-Ddefault_library=both \
+	-Dbpf=disabled \
+	-Dgconv=disabled \
+	-Djpeg=disabled \
+	-Dlibdvbv5=disabled \
+	-Dqv4l2=disabled \
+	-Dqvidcap=disabled \
+	-Dv4l-utils=$(if $(CONFIG_PACKAGE_v4l-utils),true,false) \
+	-Ddoxygen-doc=disabled
+
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libv4l{1,2,convert,2rds}.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libv4l{1,2,convert,2rds}.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libv4l/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libv4l{1,2,convert,2rds}.so.* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/libv4l
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libv4l/v4l{1compat,2convert}.so $(1)/usr/lib/libv4l/
+endef
+
+define Package/v4l-utils/install
+	$(INSTALL_DIR) $(1)/etc
+	$(CP) $(PKG_INSTALL_DIR)/etc/rc_maps.cfg $(1)/etc/
+	$(CP) $(PKG_INSTALL_DIR)/etc/rc_keymaps $(1)/etc/
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/{rds,media,cx18,ivtv}-ctl $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/decode_tm6000 $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ir-{ctl,keytable} $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/v4l2-{compliance,ctl,sysfs-path} $(1)/usr/bin/
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/cec-{compliance,ctl,follower} $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libv4l))
+$(eval $(call BuildPackage,v4l-utils))
diff --git a/external/subpack/libs/libv4l/patches/010-intl.patch b/external/subpack/libs/libv4l/patches/010-intl.patch
new file mode 100644
index 0000000..b541f46
--- /dev/null
+++ b/external/subpack/libs/libv4l/patches/010-intl.patch
@@ -0,0 +1,50 @@
+--- a/lib/libdvbv5/meson.build
++++ b/lib/libdvbv5/meson.build
+@@ -124,6 +124,7 @@ install_headers(libdvbv5_api, subdir: 'l
+ 
+ libdvbv5_deps = [
+     dep_iconv,
++    dep_intl,
+     dep_libm,
+     dep_librt,
+     dep_libudev,
+--- a/meson.build
++++ b/meson.build
+@@ -202,6 +202,8 @@ size_t iconv (iconv_t cd, char * *inbuf,
+     endif
+ endif
+ 
++dep_intl = dependency('intl')
++
+ have_gconv = cc.has_header('gconv.h', required : get_option('gconv'))
+ 
+ # Detect system gconv directory
+--- a/utils/dvb/meson.build
++++ b/utils/dvb/meson.build
+@@ -1,5 +1,6 @@
+ dvb_common_deps =  [
+     dep_argp,
++    dep_intl,
+     dep_libdvbv5,
+     dep_libudev,
+     dep_threads,
+--- a/utils/ir-ctl/meson.build
++++ b/utils/ir-ctl/meson.build
+@@ -12,6 +12,7 @@ ir_ctl_sources = files(
+ 
+ ir_ctl_deps =  [
+     dep_argp,
++    dep_intl,
+ ]
+ 
+ ir_ctl = executable('ir-ctl',
+--- a/utils/keytable/meson.build
++++ b/utils/keytable/meson.build
+@@ -11,6 +11,7 @@ ir_keytable_sources = files(
+ 
+ ir_keytable_deps = [
+     dep_argp,
++    dep_intl,
+ ]
+ 
+ ir_keytable_system_dir = udevdir
diff --git a/external/subpack/libs/libv4l/patches/020-musl.patch b/external/subpack/libs/libv4l/patches/020-musl.patch
new file mode 100644
index 0000000..b96113e
--- /dev/null
+++ b/external/subpack/libs/libv4l/patches/020-musl.patch
@@ -0,0 +1,50 @@
+--- a/utils/v4l2-tracer/retrace.cpp
++++ b/utils/v4l2-tracer/retrace.cpp
+@@ -10,10 +10,7 @@ extern struct retrace_context ctx_retrac
+ void retrace_mmap(json_object *mmap_obj, bool is_mmap64)
+ {
+ 	json_object *mmap_args_obj;
+-	if (is_mmap64)
+-		json_object_object_get_ex(mmap_obj, "mmap64", &mmap_args_obj);
+-	else
+-		json_object_object_get_ex(mmap_obj, "mmap", &mmap_args_obj);
++	json_object_object_get_ex(mmap_obj, "mmap", &mmap_args_obj);
+ 
+ 	json_object *len_obj;
+ 	json_object_object_get_ex(mmap_args_obj, "len", &len_obj);
+@@ -46,10 +43,7 @@ void retrace_mmap(json_object *mmap_obj,
+ 		return;
+ 
+ 	void *buf_address_retrace_pointer = nullptr;
+-	if (is_mmap64)
+-		buf_address_retrace_pointer = mmap64(0, len, prot, flags, fd_retrace, off);
+-	else
+-		buf_address_retrace_pointer = mmap(0, len, prot, flags, fd_retrace, off);
++	buf_address_retrace_pointer = mmap(0, len, prot, flags, fd_retrace, off);
+ 
+ 	if (buf_address_retrace_pointer == MAP_FAILED) {
+ 		if (is_mmap64)
+@@ -116,10 +110,7 @@ void retrace_open(json_object *jobj, boo
+ 	int fd_trace = json_object_get_int(fd_trace_obj);
+ 
+ 	json_object *open_args_obj;
+-	if (is_open64)
+-		json_object_object_get_ex(jobj, "open64", &open_args_obj);
+-	else
+-		json_object_object_get_ex(jobj, "open", &open_args_obj);
++	json_object_object_get_ex(jobj, "open", &open_args_obj);
+ 
+ 	json_object *path_obj;
+ 	std::string path_trace;
+@@ -148,10 +139,7 @@ void retrace_open(json_object *jobj, boo
+ 		mode = s2number(json_object_get_string(mode_obj));
+ 
+ 	int fd_retrace = 0;
+-	if (is_open64)
+-		fd_retrace = open64(path_retrace.c_str(), oflag, mode);
+-	else
+-		fd_retrace = open(path_retrace.c_str(), oflag, mode);
++	fd_retrace = open(path_retrace.c_str(), oflag, mode);
+ 
+ 	if (fd_retrace <= 0) {
+ 		line_info("\n\tCan't open: %s", path_retrace.c_str());
diff --git a/external/subpack/libs/libvorbis/Makefile b/external/subpack/libs/libvorbis/Makefile
new file mode 100644
index 0000000..a4bf632
--- /dev/null
+++ b/external/subpack/libs/libvorbis/Makefile
@@ -0,0 +1,67 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libvorbis
+PKG_VERSION:=1.3.7
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=http://downloads.xiph.org/releases/vorbis/
+PKG_HASH:=b33cc4934322bcbf6efcbacf49e3ca01aadbea4114ec9589d1b1e9d20f72954b
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:xiph.org:libvorbis
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libvorbis
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libvorbis
+  URL:=http://xiph.org/vorbis/
+  DEPENDS:=+libogg
+endef
+
+define Package/libvorbis/description
+Vorbis is a general purpose audio and music encoding format
+contemporary to MPEG-4's AAC and TwinVQ, the next generation beyond
+MPEG audio layer 3. Unlike the MPEG sponsored formats (and other
+proprietary formats such as RealAudio G2 and Windows' flavor of the
+month), the Vorbis CODEC specification belongs to the public domain.
+All the technical details are published and documented, and any
+software entity may make full use of the format without license
+fee, royalty or patent concerns.
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_SHARED_LIBS=ON
+
+ifneq ($(findstring arm,$(CONFIG_ARCH)),)
+	TARGET_CFLAGS += -flto
+	TARGET_CXX_FLAGS += -flto
+	TARGET_LDFLAGS += -flto
+endif
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/vorbisenc.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/vorbisenc.pc
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/vorbisfile.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/vorbisfile.pc
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/vorbis.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/vorbis.pc
+endef
+
+define Package/libvorbis/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libvorbis))
diff --git a/external/subpack/libs/libvorbis/patches/010-cmake_soname.patch b/external/subpack/libs/libvorbis/patches/010-cmake_soname.patch
new file mode 100644
index 0000000..fd63e1f
--- /dev/null
+++ b/external/subpack/libs/libvorbis/patches/010-cmake_soname.patch
@@ -0,0 +1,44 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -28,8 +28,8 @@ set(PROJECT_VERSION_MINOR ${CMAKE_MATCH_
+ set(PROJECT_VERSION_PATCH ${CMAKE_MATCH_3})
+ set(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
+ 
+-# Helper function to get version-info
+-function(get_version_info result current_var_name age_var_name revision_var_name)
++# Helper function to get library versions
++function(get_lib_versions version_result soversion_result current_var_name age_var_name revision_var_name)
+     string(REGEX MATCH "${current_var_name}=([0-9]*)" DUMMY ${CONFIGURE_AC_CONTENTS})
+     set(VERSION_INFO_CURRENT ${CMAKE_MATCH_1})
+ 
+@@ -41,7 +41,8 @@ function(get_version_info result current
+ 
+     math(EXPR VERSION_INFO_CURRENT_MINUS_AGE "${VERSION_INFO_CURRENT} - ${VERSION_INFO_AGE}")
+ 
+-    set(${result} "${VERSION_INFO_CURRENT_MINUS_AGE}.${VERSION_INFO_AGE}.${VERSION_INFO_REVISION}" PARENT_SCOPE)
++    set(${version_result} "${VERSION_INFO_CURRENT_MINUS_AGE}.${VERSION_INFO_AGE}.${VERSION_INFO_REVISION}" PARENT_SCOPE)
++    set(${soversion_result} "${VERSION_INFO_CURRENT_MINUS_AGE}" PARENT_SCOPE)
+ endfunction()
+ 
+ # Helper function to configure pkg-config files
+--- a/lib/CMakeLists.txt
++++ b/lib/CMakeLists.txt
+@@ -78,12 +78,12 @@ if (NOT BUILD_FRAMEWORK)
+     add_library(vorbisenc ${VORBISENC_SOURCES})
+     add_library(vorbisfile ${VORBISFILE_SOURCES})
+ 
+-    get_version_info(VORBIS_VERSION_INFO "V_LIB_CURRENT" "V_LIB_AGE" "V_LIB_REVISION")
+-    set_target_properties(vorbis PROPERTIES SOVERSION ${VORBIS_VERSION_INFO})
+-    get_version_info(VORBISENC_VERSION_INFO "VE_LIB_CURRENT" "VE_LIB_AGE" "VE_LIB_REVISION")
+-    set_target_properties(vorbisenc PROPERTIES SOVERSION ${VORBISENC_VERSION_INFO})
+-    get_version_info(VORBISFILE_VERSION_INFO "VF_LIB_CURRENT" "VF_LIB_AGE" "VF_LIB_REVISION")
+-    set_target_properties(vorbisfile PROPERTIES SOVERSION ${VORBISFILE_VERSION_INFO})
++    get_lib_versions(VORBIS_VERSION VORBIS_SOVERSION "V_LIB_CURRENT" "V_LIB_AGE" "V_LIB_REVISION")
++    set_target_properties(vorbis PROPERTIES VERSION ${VORBIS_VERSION} SOVERSION ${VORBIS_SOVERSION})
++    get_lib_versions(VORBISENC_VERSION VORBISENC_SOVERSION "VE_LIB_CURRENT" "VE_LIB_AGE" "VE_LIB_REVISION")
++    set_target_properties(vorbisenc PROPERTIES VERSION ${VORBISENC_VERSION} SOVERSION ${VORBISENC_SOVERSION})
++    get_lib_versions(VORBISFILE_VERSION VORBISFILE_SOVERSION "VF_LIB_CURRENT" "VF_LIB_AGE" "VF_LIB_REVISION")
++    set_target_properties(vorbisfile PROPERTIES VERSION ${VORBISFILE_VERSION} SOVERSION ${VORBISFILE_SOVERSION})
+ 
+     target_include_directories(vorbis
+         PUBLIC
diff --git a/external/subpack/libs/libvorbisidec/Makefile b/external/subpack/libs/libvorbisidec/Makefile
new file mode 100644
index 0000000..fffd00a
--- /dev/null
+++ b/external/subpack/libs/libvorbisidec/Makefile
@@ -0,0 +1,58 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libvorbisidec
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_DATE:=2024-06-11
+PKG_SOURCE_URL:=https://gitlab.xiph.org/xiph/tremor.git
+PKG_SOURCE_VERSION:=9b78f57f4335f7158dbb82df00645d2ba57e0d33
+PKG_MIRROR_HASH:=521a65a192078fd70ac402c54a8b35986280ce96117c9b9a10f769e4caec7135
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_FLAGS:=no-mips16
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libvorbisidec
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A fixed-point Ogg/Vorbis decoder library
+  DEPENDS:= +libogg
+  URL:=http://wiki.xiph.org/index.php/Tremor
+endef
+
+define Package/libvorbisidec/description
+  libvorbisidec is "tremor", a fixed-point implementation of libvorbis.
+  It is suitable as a replacement for libvorbis in tremor-aware applications.
+  Tremor is a decoder only.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+CONFIGURE_ARGS += --enable-shared --enable-static
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/tremor $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libvorbisidec.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libvorbisidec/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libvorbisidec.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libvorbisidec))
diff --git a/external/subpack/libs/libvpx/Makefile b/external/subpack/libs/libvpx/Makefile
new file mode 100644
index 0000000..540dbbc
--- /dev/null
+++ b/external/subpack/libs/libvpx/Makefile
@@ -0,0 +1,80 @@
+#
+# Copyright (C) 2008-2015 OpenWrt.org
+# Copyright (C) 2016 Luiz Angelo Daros de Luca
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libvpx
+PKG_VERSION:=1.14.1
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://chromium.googlesource.com/webm/libvpx
+PKG_MIRROR_HASH:=a9737eadde24611fbbf080f28c792d804ea0970dadbc9421b427e18bb8f14820
+PKG_SOURCE_VERSION:=v$(PKG_VERSION)
+
+PKG_MAINTAINER:=Luiz Angelo Daros de Luca <luizluca@gmail.com>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:webmproject:libvpx
+PKG_BUILD_PARALLEL:=1
+
+PKG_ABI_VERSION:=$(subst $(space),.,$(wordlist 1, 2, $(subst .,$(space),$(PKG_VERSION))))
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libvpx
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libvpx
+  URL:=https://www.webmproject.org/
+  DEPENDS:=+libpthread
+  ABI_VERSION:=$(PKG_ABI_VERSION)
+endef
+
+define Package/libvpx/description
+   libvpx is a VP8/VP9 Codec SDK.
+endef
+
+CONFIGURE_ARGS = \
+	--target=generic-gnu \
+	--prefix=$(CONFIGURE_PREFIX) \
+	--libdir=/usr/lib \
+	--enable-static \
+	--enable-shared \
+	--disable-examples \
+	--disable-docs \
+	--disable-unit-tests \
+
+# Add --enable-small as openwrt gcc flags are overwritten
+ifneq ($(findstring -Os,$(TARGET_CFLAGS)),)
+CONFIGURE_ARGS += --enable-small
+endif
+
+# libvpx expects gcc as linker but uses $LD if provided
+# However, OpenWRT defines LD as *-uclibc-ld and not *-gcc
+CONFIGURE_VARS := $(filter-out LD=%,$(CONFIGURE_VARS)) LD="$(TARGET_CC)" \
+       CROSS=$(GNU_TARGET_NAME)
+MAKE_FLAGS := $(filter-out LD=%,$(MAKE_FLAGS)) LD="$(TARGET_CC)"
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/vpx/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/vpx/* $(1)/usr/include/vpx/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.{so*,a} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libvpx/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libvpx))
diff --git a/external/subpack/libs/libwebp/Makefile b/external/subpack/libs/libwebp/Makefile
new file mode 100644
index 0000000..a3f0755
--- /dev/null
+++ b/external/subpack/libs/libwebp/Makefile
@@ -0,0 +1,55 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libwebp
+PKG_VERSION:=1.4.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://storage.googleapis.com/downloads.webmproject.org/releases/webp
+PKG_HASH:=61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5
+
+PKG_MAINTAINER:=Alexandru Ardelean <ardeleanalex@gmail.com>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+
+CMAKE_INSTALL:=1
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libwebp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=WebP library
+  URL:=https://www.webmproject.org
+endef
+
+define Package/libwebp/description
+  The libwebp package contains a library for the WebP format.
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_SHARED_LIBS=ON \
+	-DWEBP_BUILD_ANIM_UTILS=OFF \
+	-DWEBP_BUILD_CWEBP=OFF \
+	-DWEBP_BUILD_DWEBP=OFF \
+	-DWEBP_BUILD_GIF2WEBP=OFF \
+	-DWEBP_BUILD_IMG2WEBP=OFF \
+	-DWEBP_BUILD_VWEBP=OFF \
+	-DWEBP_BUILD_WEBPINFO=OFF \
+	-DWEBP_BUILD_WEBPMUX=OFF \
+	-DWEBP_BUILD_EXTRAS=OFF
+
+ifneq ($(findstring arm,$(CONFIG_ARCH)),)
+ifeq ($(findstring neon,$(CONFIG_CPU_TYPE)),)
+CMAKE_OPTIONS += -DWEBP_ENABLE_SIMD=OFF
+endif
+endif
+
+define Package/libwebp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib*.s* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libwebp))
diff --git a/external/subpack/libs/libwebp/patches/010-mips16.patch b/external/subpack/libs/libwebp/patches/010-mips16.patch
new file mode 100644
index 0000000..b48d854
--- /dev/null
+++ b/external/subpack/libs/libwebp/patches/010-mips16.patch
@@ -0,0 +1,11 @@
+--- a/src/dsp/cpu.h
++++ b/src/dsp/cpu.h
+@@ -124,7 +124,7 @@
+ //------------------------------------------------------------------------------
+ // MIPS defines.
+ 
+-#if defined(__mips__) && !defined(__mips64) && defined(__mips_isa_rev) && \
++#if defined(__mips__) && !defined(__mips16) && !defined(__mips64) && defined(__mips_isa_rev) && \
+     (__mips_isa_rev >= 1) && (__mips_isa_rev < 6)
+ #define WEBP_USE_MIPS32
+ #if (__mips_isa_rev >= 2)
diff --git a/external/subpack/libs/libwebsockets/Makefile b/external/subpack/libs/libwebsockets/Makefile
new file mode 100644
index 0000000..2fe7927
--- /dev/null
+++ b/external/subpack/libs/libwebsockets/Makefile
@@ -0,0 +1,113 @@
+#
+# Copyright (C) 2014-2015 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:=libwebsockets
+PKG_VERSION:=4.3.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=https://codeload.github.com/warmcat/libwebsockets/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=6fd33527b410a37ebc91bb64ca51bdabab12b076bc99d153d7c5dd405e4bdf90
+
+PKG_SOURCE_VERSION:=v$(PKG_VERSION)
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_DEPENDS:=libubox
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_OPTIONS += -DLWS_IPV6=$(if $(CONFIG_IPV6),ON,OFF)
+CMAKE_OPTIONS += -DISABLE_WERROR=ON
+CMAKE_OPTIONS += -DCMAKE_BUILD_TYPE=Release
+CMAKE_OPTIONS += -DLWS_WITH_EXTERNAL_POLL=ON
+CMAKE_OPTIONS += -DLWS_WITH_ULOOP=ON
+
+# turn off all test apps
+CMAKE_OPTIONS += -DLWS_WITHOUT_TESTAPPS=ON
+CMAKE_OPTIONS += -DLWS_WITHOUT_TEST_SERVER=ON
+CMAKE_OPTIONS += -DLWS_WITHOUT_TEST_SERVER_EXTPOLL=ON
+CMAKE_OPTIONS += -DLWS_WITHOUT_TEST_PING=ON
+CMAKE_OPTIONS += -DLWS_WITHOUT_TEST_CLIENT=ON
+
+define Package/libwebsockets/Default
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=libwebsockets
+	DEPENDS:=+zlib +libcap +libubox
+	URL:=https://libwebsockets.org
+	MAINTAINER:=Karl Palsson <karlp@etactica.com>
+endef
+
+define Package/libwebsockets-openssl
+	$(call Package/libwebsockets/Default)
+	TITLE += (OpenSSL)
+	DEPENDS += +libopenssl
+	VARIANT:=openssl
+	CONFLICTS:=libwebsockets-full
+endef
+
+define Package/libwebsockets-mbedtls
+	$(call Package/$(PKG_NAME)/Default)
+	TITLE += (mbedTLS)
+	DEPENDS += +libmbedtls
+	VARIANT:=mbedtls
+	PROVIDES:=libwebsockets
+	CONFLICTS:=libwebsockets-openssl
+endef
+
+define Package/libwebsockets-full
+	$(call Package/libwebsockets/Default)
+	TITLE += (Full - OpenSSL, libuv, plugins, CGI)
+	DEPENDS += +libopenssl +libuv
+	VARIANT:=full
+	PROVIDES:=libwebsockets libwebsockets-openssl
+endef
+
+ifeq ($(BUILD_VARIANT),openssl)
+    CMAKE_OPTIONS += -DLWS_OPENSSL_CLIENT_CERTS=/etc/ssl/certs
+    CMAKE_OPTIONS += -DLWS_WITH_SSL=ON
+endif
+
+ifeq ($(BUILD_VARIANT),mbedtls)
+    CMAKE_OPTIONS += -DLWS_WITH_MBEDTLS=1
+endif
+
+ifeq ($(BUILD_VARIANT),full)
+    CMAKE_OPTIONS += -DLWS_OPENSSL_CLIENT_CERTS=/etc/ssl/certs
+    CMAKE_OPTIONS += -DLWS_WITH_SSL=ON
+    CMAKE_OPTIONS += -DLWS_WITH_LIBUV=ON
+    CMAKE_OPTIONS += -DLWS_WITH_PLUGINS=ON
+    CMAKE_OPTIONS += -DLWS_WITH_SERVER_STATUS=ON
+    CMAKE_OPTIONS += -DLWS_WITH_ACCESS_LOG=ON
+    CMAKE_OPTIONS += -DLWS_WITH_CGI=ON
+    CMAKE_OPTIONS += -DLWS_UNIX_SOCK=ON
+endif
+
+define Package/libwebsockets/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libwebsockets*.so* $(1)/usr/lib/
+endef
+
+Package/libwebsockets-mbedtls/install = $(Package/libwebsockets/install)
+Package/libwebsockets-openssl/install = $(Package/libwebsockets/install)
+
+define Package/libwebsockets-full/install
+	$(call Package/libwebsockets/install,$(1))
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libwebsockets-evlib_uv.so* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libwebsockets-openssl))
+$(eval $(call BuildPackage,libwebsockets-mbedtls))
+$(eval $(call BuildPackage,libwebsockets-full))
diff --git a/external/subpack/libs/libwebsockets/patches/110-mbedtls36_compilefix.patch b/external/subpack/libs/libwebsockets/patches/110-mbedtls36_compilefix.patch
new file mode 100644
index 0000000..aeec8e6
--- /dev/null
+++ b/external/subpack/libs/libwebsockets/patches/110-mbedtls36_compilefix.patch
@@ -0,0 +1,23 @@
+From 017dfcb144c557bb4bc72669168ad7b70a34ce57 Mon Sep 17 00:00:00 2001
+From: Seo Suchan <tjtncks@gmail.com>
+Date: Fri, 3 May 2024 17:18:46 +0900
+Subject: [PATCH 1/2] mbedtls: fix compile on mbedtls 3.6+ they moved
+ mbedtls_x509_get_name into interal zone, this declares it again in a file I
+ looked approperate to hold one
+
+Signed-off-by: Seo Suchan <tjtncks@gmail.com>
+---
+ lib/tls/mbedtls/private-lib-tls-mbedtls.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/lib/tls/mbedtls/private-lib-tls-mbedtls.h
++++ b/lib/tls/mbedtls/private-lib-tls-mbedtls.h
+@@ -57,3 +57,8 @@ lws_tls_mbedtls_cert_info(mbedtls_x509_c
+ int
+ lws_x509_get_crt_ext(mbedtls_x509_crt *crt, mbedtls_x509_buf *skid,
+ 		     lws_mbedtls_x509_authority *akid);
++
++/* redefine hidden mbedtls internal functions*/
++int
++mbedtls_x509_get_name(unsigned char **p, const unsigned char *end,
++                          mbedtls_x509_name *cur);
diff --git a/external/subpack/libs/libwebsockets/patches/120-removed-mbedtlsverc.patch b/external/subpack/libs/libwebsockets/patches/120-removed-mbedtlsverc.patch
new file mode 100644
index 0000000..61d7f6d
--- /dev/null
+++ b/external/subpack/libs/libwebsockets/patches/120-removed-mbedtlsverc.patch
@@ -0,0 +1,36 @@
+From adcc5a1ccb9f6ffe9fca793ea67e6c3e7ad8274a Mon Sep 17 00:00:00 2001
+From: Seo Suchan <tjtncks@gmail.com>
+Date: Tue, 7 May 2024 12:46:08 +0900
+Subject: [PATCH 2/2] mbedtls: make it no longer depend on mbedtls_version_c
+ complie flag
+
+everything that code does is already done as macro constants
+and openwrt doesn't build with mbedtls with that flag by default
+
+Signed-off-by: Seo Suchan <tjtncks@gmail.com>
+---
+ lib/core/context.c | 13 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/lib/core/context.c
++++ b/lib/core/context.c
+@@ -788,11 +788,15 @@ lws_create_context(const struct lws_cont
+ #endif /* network */
+ 
+ #if defined(LWS_WITH_MBEDTLS)
+-	mbedtls_version_get_string(mbedtls_version);
+-#endif
++	{
+ 
+-#if defined(LWS_WITH_MBEDTLS)
+-	lwsl_cx_notice(context, "LWS: %s, MbedTLS-%s %s%s", library_version, mbedtls_version, opts_str, s);
++#if defined(MBEDTLS_VERSION_C)
++		mbedtls_version_get_string(mbedtls_version);
++#else
++		lws_snprintf(mbedtls_version, sizeof(mbedtls_version), "%s", MBEDTLS_VERSION_STRING);
++#endif
++		lwsl_cx_notice(context, "LWS: %s, MbedTLS-%s %s%s", library_version, mbedtls_version, opts_str, s);
++	}
+ #else
+ 	lwsl_cx_notice(context, "LWS: %s, %s%s", library_version, opts_str, s);
+ #endif
diff --git a/external/subpack/libs/libx264/Makefile b/external/subpack/libs/libx264/Makefile
new file mode 100644
index 0000000..05c5c3d
--- /dev/null
+++ b/external/subpack/libs/libx264/Makefile
@@ -0,0 +1,87 @@
+#
+# Copyright (C) 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:=x264
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://code.videolan.org/videolan/x264.git
+PKG_SOURCE_DATE:=2024-05-13
+PKG_SOURCE_VERSION:=4613ac3c15fd75cebc4b9f65b7fb95e70a3acce1
+PKG_MIRROR_HASH:=03d8ca3495185504a601e36bff017e1044cb3f6c32cb567fb12d6f9707bb78cd
+
+PKG_MAINTAINER:=Adrian Panella <ianchi74@outlook.com>
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+TARGET_CFLAGS:=$(filter-out -O%,$(TARGET_CFLAGS))
+MAKE_FLAGS:=$(filter-out LD=%,$(MAKE_FLAGS)) LD="$(TARGET_CC) -o"
+
+# Instead of blacklisting a boatload of platforms just enable
+# optimization where it makes sense (matters) ie ARMv7+ and x86_64
+
+ifneq ($(findstring cortex-a,$(CONFIG_CPU_TYPE)),)
+  CONFIGURE_ARGS += --enable-lto
+else
+  ifneq ($(CONFIG_TARGET_x86_64),)
+    CONFIGURE_ARGS += --enable-lto
+    ifeq ($(CONFIG_NASM),y)
+      CONFIGURE_VARS+= AS=nasm
+      MAKE_FLAGS+= AS=nasm
+    endif
+  else
+    CONFIGURE_VARS+= AS=
+    MAKE_FLAGS+= AS=
+    CONFIGURE_ARGS += --disable-asm
+  endif
+endif
+
+CONFIGURE_ARGS += \
+		--disable-cli \
+		--enable-shared \
+		--disable-opencl \
+		--enable-pic \
+		--disable-avs \
+		--disable-ffms \
+		--disable-gpac \
+		--disable-lsmash
+
+define Package/libx264
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=H264/AVC free codec library
+  DEPENDS:=+libpthread @BUILD_PATENTED
+  URL:=https://www.videolan.org/developers/x264.html
+endef
+
+define Package/libx264/description
+  x264 is a free software library for encoding
+  video streams into the H.264/MPEG-4 AVC compression format.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/x264/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libx264/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libx264))
diff --git a/external/subpack/libs/libx264/patches/001-fix-x32-build-by-disabling-asm.patch b/external/subpack/libs/libx264/patches/001-fix-x32-build-by-disabling-asm.patch
new file mode 100644
index 0000000..c36afb9
--- /dev/null
+++ b/external/subpack/libs/libx264/patches/001-fix-x32-build-by-disabling-asm.patch
@@ -0,0 +1,48 @@
+From 66b120079fb21ed38cab0900c63360b0a7853eaa Mon Sep 17 00:00:00 2001
+From: Christopher Larson <chris_larson@mentor.com>
+Date: Tue, 13 Dec 2016 14:22:32 -0700
+Subject: [PATCH] Fix X32 build by disabling asm
+
+This applies gentoo's x32 patch, adjusted slightly, which disables asm support
+for x32 as well as correcting -m.
+
+Debian has a different patch which does the same, and there's a superior yet
+out of date patch series on the x264 list which keeps asm support enabled, but
+doesn't successfully build at this time, and my assembly is very rusty.
+
+Upstream-Status: Pending
+Signed-off-by: Christopher Larson <chris_larson@mentor.com>
+---
+ configure | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/configure
++++ b/configure
+@@ -771,7 +771,13 @@ case $host_cpu in
+         AS_EXT=".asm"
+         ASFLAGS="$ASFLAGS -DARCH_X86_64=1 -I\$(SRCPATH)/common/x86/"
+         stack_alignment=16
+-        [ $compiler = GNU ] && CFLAGS="-m64 $CFLAGS" && LDFLAGS="-m64 $LDFLAGS"
++        if [ $compiler = GNU ]; then
++            if cpp_check "" "" "__ILP32__" ; then
++                CFLAGS="-mx32 $CFLAGS" && LDFLAGS="-mx32 $LDFLAGS"
++            else
++                CFLAGS="-m64 $CFLAGS" && LDFLAGS="-m64 $LDFLAGS"
++            fi
++        fi
+         if [ "$SYS" = MACOSX ]; then
+             ASFLAGS="$ASFLAGS -f macho64 -DPREFIX"
+             if cc_check '' "-arch x86_64"; then
+@@ -790,7 +796,11 @@ case $host_cpu in
+                 RCFLAGS="--target=pe-x86-64 $RCFLAGS"
+             fi
+         else
+-            ASFLAGS="$ASFLAGS -f elf64"
++            if cpp_check "" "" "__ILP32__" ; then
++                asm=no
++            else
++                ASFLAGS="$ASFLAGS -f elf64"
++            fi
+         fi
+         ;;
+     powerpc*)
diff --git a/external/subpack/libs/libx264/patches/002-dont-default-to-cortex-a9-with-neon.patch b/external/subpack/libs/libx264/patches/002-dont-default-to-cortex-a9-with-neon.patch
new file mode 100644
index 0000000..101821a
--- /dev/null
+++ b/external/subpack/libs/libx264/patches/002-dont-default-to-cortex-a9-with-neon.patch
@@ -0,0 +1,28 @@
+From a72bf499a0674fc75eedf15008b424e28f67e4bd Mon Sep 17 00:00:00 2001
+From: Andrei Gherzan <andrei@gherzan.ro>
+Date: Fri, 2 Feb 2018 15:10:08 +0200
+Subject: [PATCH] dont default to cortex-a9 with neon
+
+-march flag is not in CFLAGS so this will always default to
+ -mcpu=cortex-a8 -mfpu=neon.
+
+Upstream-Status: Pending
+
+Signed-off-by: Andrei Gherzan <andrei@gherzan.ro>
+Signed-off-by: Maxin B. John <maxin.john@intel.com>
+---
+ configure | 3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/configure
++++ b/configure
+@@ -988,9 +988,6 @@ if [ $asm = auto -a \( $ARCH = X86 -o $A
+ fi
+ 
+ if [ $asm = auto -a $ARCH = ARM ] ; then
+-    # set flags so neon is built by default
+-    [ $compiler == CL ] || echo $CFLAGS | grep -Eq '(-mcpu|-march|-mfpu)' || CFLAGS="$CFLAGS -mcpu=cortex-a8 -mfpu=neon"
+-
+     cc_check '' '' '__asm__("add r0, r1, r2");' && define HAVE_ARM_INLINE_ASM
+     if [ $compiler = CL ] && cpp_check '' '' 'defined(_M_ARM) && _M_ARM >= 7' ; then
+         define HAVE_ARMV6
diff --git a/external/subpack/libs/libxcrypt/Makefile b/external/subpack/libs/libxcrypt/Makefile
new file mode 100644
index 0000000..316e0f2
--- /dev/null
+++ b/external/subpack/libs/libxcrypt/Makefile
@@ -0,0 +1,55 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libxcrypt
+PKG_VERSION:=4.4.36
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/besser82/libxcrypt/releases/download/v$(PKG_VERSION)
+PKG_HASH:=e5e1f4caee0a01de2aee26e3138807d6d3ca2b8e67287966d1fefd65e1fd8943
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LIB
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libxcrypt
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=https://github.com/besser82/libxcrypt
+  TITLE:=Extended crypt library
+  BUILDONLY:=1
+endef
+
+define Package/libxcrypt/description
+  libxcrypt is a modern library for one-way hashing of passwords. It supports
+  a wide variety of both modern and historical hashing methods: yescrypt,
+  gost-yescrypt, scrypt, bcrypt, sha512crypt, sha256crypt, md5crypt, SunMD5,
+  sha1crypt, NT, bsdicrypt, bigcrypt, and descrypt. It provides the traditional
+  Unix crypt and crypt_r interfaces, as well as a set of extended interfaces
+  pioneered by Openwall Linux, crypt_rn, crypt_ra, crypt_gensalt,
+  crypt_gensalt_rn, and crypt_gensalt_ra.
+endef
+
+CONFIGURE_ARGS += \
+	--disable-shared \
+	--disable-failure-tokens \
+	--disable-xcrypt-compat-files \
+	--disable-obsolete-api \
+	--enable-hashes=solaris \
+	--with-pic
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/libxcrypt
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcrypt.{a,la} $(1)/usr/lib/libxcrypt
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*crypt.pc $(1)/usr/lib/pkgconfig/
+endef
+
+$(eval $(call BuildPackage,libxcrypt))
diff --git a/external/subpack/libs/libxerces-c/Makefile b/external/subpack/libs/libxerces-c/Makefile
new file mode 100644
index 0000000..00e2c70
--- /dev/null
+++ b/external/subpack/libs/libxerces-c/Makefile
@@ -0,0 +1,90 @@
+#
+# Copyright (C) 2015-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:=xerces-c
+PKG_VERSION:=3.2.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@APACHE/xerces/c/3/sources
+PKG_HASH:=6239e6035645b21bc9bf7f02004db334dce3fe6d85428ee4fe7e180c2d948230
+
+PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libxerces-c/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Validating XML parser library for C++
+  URL:=https://xerces.apache.org/
+endef
+
+define Package/libxerces-c
+$(call Package/libxerces-c/Default)
+  DEPENDS:=$(ICONV_DEPENDS) +libstdcpp
+endef
+
+define Package/libxerces-c-samples
+$(call Package/libxerces-c/Default)
+  TITLE+= (samples)
+  DEPENDS+=+libxerces-c
+endef
+
+define Package/libxerces-c/description
+  Xerces-C++ is a validating XML parser written in a portable subset of
+  C++. Xerces-C++ makes it easy to give your application the ability
+  to read and write XML data. A shared library is provided for parsing,
+  generating, manipulating, and validating XML documents. Xerces-C++ is
+  faithful to the XML 1.0 recommendation and associated standards (DOM
+  1.0, DOM 2.0, SAX 1.0, SAX 2.0, Namespaces, XML Schema Part 1 and
+  Part 2). It also provides experimental implementations of XML 1.1
+  and DOM Level 3.0. The parser provides high performance, modularity,
+  and scalability.
+endef
+
+define Package/libxerces-c-samples/description
+  Validating XML parser library for C++ (samples)
+endef
+
+CMAKE_OPTIONS += \
+	-DCMAKE_DISABLE_FIND_PACKAGE_ICU=ON \
+	-Dmessage-loader=inmemory \
+	-Dnetwork-accessor=socket \
+	-Dtranscoder=iconv
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/xercesc
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/xercesc/* $(1)/usr/include/xercesc/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/cmake/XercesC
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/cmake/XercesC/* $(1)/usr/lib/cmake/XercesC
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/xerces-c.pc $(1)/usr/lib/pkgconfig/xerces-c.pc
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/xerces-c.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/xerces-c.pc
+endef
+
+define Package/libxerces-c/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so $(1)/usr/lib/
+endef
+
+define Package/libxerces-c-samples/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libxerces-c))
+$(eval $(call BuildPackage,libxerces-c-samples))
diff --git a/external/subpack/libs/libxmlb/Config.in b/external/subpack/libs/libxmlb/Config.in
new file mode 100644
index 0000000..812e8cf
--- /dev/null
+++ b/external/subpack/libs/libxmlb/Config.in
@@ -0,0 +1,16 @@
+menu "Select libxmlb options"
+	depends on PACKAGE_libxmlb
+
+config LIBXMLB_LZMA
+	bool "LZMA"
+	default n
+	help
+	  Compile libxmlb with LZMA support
+
+config LIBXMLB_ZSTD
+	bool "zstd"
+	default n
+	help
+	  Compile libxmlb with zstd support
+
+endmenu
diff --git a/external/subpack/libs/libxmlb/Makefile b/external/subpack/libs/libxmlb/Makefile
new file mode 100644
index 0000000..c010b0e
--- /dev/null
+++ b/external/subpack/libs/libxmlb/Makefile
@@ -0,0 +1,76 @@
+#
+# Copyright (C) 2024 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See https://www.gnu.org/licenses/gpl-2.0.txt for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libxmlb
+PKG_VERSION:=0.3.19
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/hughsie/libxmlb/releases/download/$(PKG_VERSION)
+PKG_HASH:=0a3ec258b12dbf10e5fe840b2421c84137eb7cc1b09c3de6210f3f7d51733733
+
+PKG_MAINTAINER:=Lukas Voegl <lvoegl@tdt.de>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_BUILD_DEPENDS:=glib2/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libxmlb
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=libxmlb
+  URL:=https://github.com/hughsie/libxmlb
+  DEPENDS:= \
+	+glib2 \
+	+LIBXMLB_LZMA:liblzma \
+	+LIBXMLB_ZSTD:libzstd
+endef
+
+define Package/libxmlb/description
+  Library to help create and query binary XML blobs.
+endef
+
+define Package/libxmlb/config
+	source "$(SOURCE)/Config.in"
+endef
+
+MESON_ARGS += \
+	-Db_lto=true \
+	-Dgtkdoc=false \
+	-Dintrospection=false \
+	-Dtests=false \
+	-Dcli=false \
+	-Dstemmer=false \
+	-Dlzma=$(if $(CONFIG_LIBXMLB_LZMA),enabled,disabled) \
+	-Dzstd=$(if $(CONFIG_LIBXMLB_ZSTD),enabled,disabled)
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/libxmlb-2
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libxmlb-2/xmlb.h $(1)/usr/include/libxmlb-2
+
+	$(INSTALL_DIR) $(1)/usr/include/libxmlb-2/libxmlb
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libxmlb-2/libxmlb/*.h $(1)/usr/include/libxmlb-2/libxmlb
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libxmlb.so* $(1)/usr/lib
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/xmlb.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/libxmlb/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libxmlb.so* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libxmlb))
diff --git a/external/subpack/libs/libxslt/Makefile b/external/subpack/libs/libxslt/Makefile
new file mode 100644
index 0000000..d958659
--- /dev/null
+++ b/external/subpack/libs/libxslt/Makefile
@@ -0,0 +1,163 @@
+#
+# Copyright (C) 2014 - 2018 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:=libxslt
+PKG_VERSION:=1.1.42
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@GNOME/libxslt/$(basename $(PKG_VERSION))
+PKG_HASH:=85ca62cac0d41fc77d3f6033da9df6fd73d20ea2fc18b0a3609ffb4110e1baeb
+
+PKG_MAINTAINER:=Jiri Slachta <jiri@slachta.eu>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:xmlsoft:libxslt
+
+HOST_BUILD_DEPENDS:=libxml2/host
+CMAKE_BINARY_SUBDIR:=openwrt-build
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/cmake.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libxslt
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libxml2 $(ICONV_DEPENDS)
+  TITLE:=Gnome XSLT library
+  URL:=http://xmlsoft.org/XSLT/
+endef
+
+define Package/libxslt/description
+ A library for XML transformation using XSLT.
+endef
+
+define Package/libexslt
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libxslt
+  TITLE:=Gnome XSLT library Extension
+  URL:=http://xmlsoft.org/XSLT/EXSLT/
+endef
+
+define Package/libexslt/description
+ An extension for XSLT.
+endef
+
+define Package/xsltproc
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libxslt +PACKAGE_xsltproc:libexslt
+  TITLE:=Gnome XSLT xsltproc Utility
+  URL:=http://xmlsoft.org/XSLT/
+endef
+
+define Package/xsltproc/description
+ XSLT XML transformation utility.
+endef
+
+CMAKE_HOST_OPTIONS += \
+	-DBUILD_SHARED_LIBS=OFF \
+	-DLIBXSLT_WITH_DEBUGGER=OFF \
+	-DLIBXSLT_WITH_CRYPTO=OFF \
+	-DLIBXSLT_WITH_MEM_DEBUG=OFF \
+	-DLIBXSLT_WITH_MODULES=OFF \
+	-DLIBXSLT_WITH_PROFILER=OFF \
+	-DLIBXSLT_WITH_PYTHON=OFF \
+	-DLIBXSLT_WITH_TESTS=OFF \
+	-DLIBXSLT_WITH_THREADS=ON \
+	-DLIBXSLT_WITH_XSLT_DEBUG=OFF
+
+CMAKE_OPTIONS += \
+	-DBUILD_SHARED_LIBS=ON \
+	-DLIBXSLT_WITH_DEBUGGER=OFF \
+	-DLIBXSLT_WITH_CRYPTO=OFF \
+	-DLIBXSLT_WITH_MEM_DEBUG=OFF \
+	-DLIBXSLT_WITH_MODULES=OFF \
+	-DLIBXSLT_WITH_PROFILER=ON \
+	-DLIBXSLT_WITH_PYTHON=OFF \
+	-DLIBXSLT_WITH_TESTS=OFF \
+	-DLIBXSLT_WITH_THREADS=ON \
+	-DLIBXSLT_WITH_XSLT_DEBUG=OFF
+
+define Build/InstallDev/Xslt
+	$(INSTALL_DIR) $(1)/usr/bin $(2)/bin $(1)/usr/include/libxslt \
+		$(1)/usr/include/libexslt $(1)/usr/lib \
+		$(1)/usr/lib/pkgconfig
+
+	$(INSTALL_BIN) \
+		$(PKG_INSTALL_DIR)/usr/bin/xslt-config \
+		$(2)/bin/
+
+	$(LN) $(STAGING_DIR)/host/bin/xslt-config $(1)/usr/bin/xslt-config
+
+	$(SED) \
+		's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \
+		$(2)/bin/xslt-config
+
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/include/libxslt/* \
+		$(1)/usr/include/libxslt/
+
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxslt.so* \
+		$(1)/usr/lib/
+
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libxslt.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Build/InstallDev/Exslt
+	$(INSTALL_DIR) $(1)/usr/include/libexslt $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/include/libexslt/* \
+		$(1)/usr/include/libexslt/
+
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libexslt.so* \
+		$(1)/usr/lib/
+
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libexslt.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Build/InstallDev
+	 $(call Build/InstallDev/Xslt,$(1),$(2))
+	 $(if $(CONFIG_PACKAGE_libexslt),$(call Build/InstallDev/Exslt,$(1),$(2)))
+endef
+
+define Package/libxslt/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxslt.so* \
+		$(1)/usr/lib/
+endef
+
+define Package/libexslt/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libexslt.so* \
+		$(1)/usr/lib/
+endef
+
+define Package/xsltproc/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) \
+		$(PKG_INSTALL_DIR)/usr/bin/xsltproc \
+		$(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libxslt))
+$(eval $(call BuildPackage,libexslt))
+$(eval $(call BuildPackage,xsltproc))
+$(eval $(call HostBuild))
diff --git a/external/subpack/libs/libyaml-cpp/Makefile b/external/subpack/libs/libyaml-cpp/Makefile
new file mode 100644
index 0000000..15072b5
--- /dev/null
+++ b/external/subpack/libs/libyaml-cpp/Makefile
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 2017 Steven Hessing
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libyaml-cpp
+PKG_VERSION:=0.7.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=yaml-cpp-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/jbeder/yaml-cpp/tar.gz/yaml-cpp-$(PKG_VERSION)?
+PKG_HASH:=43e6a9fcb146ad871515f0d0873947e5d497a1c9c60c58cb102a97b47208b7c3
+PKG_BUILD_DIR:=$(BUILD_DIR)/yaml-cpp-yaml-cpp-$(PKG_VERSION)
+
+PKG_MAINTAINER:= Steven Hessing <steven.hessing@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:yaml-cpp_project:yaml-cpp
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libyaml-cpp
+  SECTION:=development
+  CATEGORY:=Libraries
+  TITLE:=libyaml-cpp
+  URL:=https://github.com/jbeder/yaml-cpp
+  DEPENDS:=+libstdcpp
+  ABI_VERSION:=0.7
+endef
+
+define Package/libyaml-cpp/description
+  yaml-cpp is a YAML parser and emitter in C++ matching the YAML 1.2 spec.
+endef
+
+CMAKE_OPTIONS += \
+	-DYAML_BUILD_SHARED_LIBS=ON \
+	-DYAML_CPP_BUILD_TESTS=OFF \
+	-DYAML_CPP_BUILD_TOOLS=OFF
+
+define Package/libyaml-cpp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libyaml-cpp.so.$(ABI_VERSION) $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libyaml-cpp))
diff --git a/external/subpack/libs/libyaml-cpp/patches/010-libcxx.patch b/external/subpack/libs/libyaml-cpp/patches/010-libcxx.patch
new file mode 100644
index 0000000..26128be
--- /dev/null
+++ b/external/subpack/libs/libyaml-cpp/patches/010-libcxx.patch
@@ -0,0 +1,21 @@
+From 78f338e4ee69bb00fb37faf50f448eeedc8b824c Mon Sep 17 00:00:00 2001
+From: Mark Jan van Kampen <mjvk@allseas.com>
+Date: Tue, 13 Oct 2020 11:19:57 +0200
+Subject: [PATCH] Adds assert to enable compilation with libcxx+gcc
+
+Somehow this instantiates a template properly otherwise the build fails
+---
+ include/yaml-cpp/node/iterator.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/include/yaml-cpp/node/iterator.h
++++ b/include/yaml-cpp/node/iterator.h
+@@ -15,6 +15,8 @@
+ #include <utility>
+ #include <vector>
+ 
++static_assert(std::is_constructible<YAML::Node, const YAML::Node&>::value, "Node must be copy constructable");
++
+ namespace YAML {
+ namespace detail {
+ struct iterator_value : public Node, std::pair<Node, Node> {
diff --git a/external/subpack/libs/libyang/Makefile b/external/subpack/libs/libyang/Makefile
new file mode 100644
index 0000000..840d039
--- /dev/null
+++ b/external/subpack/libs/libyang/Makefile
@@ -0,0 +1,61 @@
+#
+# Copyright (C) 2017 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:=libyang
+PKG_VERSION:=2.1.80
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/CESNET/libyang/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=fc4744839b64628939d291e5c4f3841f2a9aef38a465682703794341687a51c4
+
+PKG_MAINTAINER:=Jakov Smolic <jakov.smolic@sartura.hr>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:cesnet:libyang
+
+CMAKE_INSTALL:=1
+CMAKE_BINARY_SUBDIR:=build
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libyang
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=YANG data modeling language library
+  URL:=https://github.com/CESNET/libyang
+  DEPENDS:=+libpcre2 +libpthread
+endef
+
+define Package/yanglint
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=YANG data modeling language utility
+  URL:=https://github.com/CESNET/libyang
+  DEPENDS:=+libyang
+endef
+
+define Package/libyang/description
+ libyang is YANG data modelling language parser and toolkit written (and providing API) in C.
+ The library is used e.g. in libnetconf2, Netopeer2 or sysrepo projects.
+endef
+
+define Package/libyang/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libyang.so* $(1)/usr/lib/
+endef
+
+define Package/yanglint/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/yanglint $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libyang))
+$(eval $(call BuildPackage,yanglint))
diff --git a/external/subpack/libs/libyubikey/Makefile b/external/subpack/libs/libyubikey/Makefile
new file mode 100644
index 0000000..37e20f3
--- /dev/null
+++ b/external/subpack/libs/libyubikey/Makefile
@@ -0,0 +1,47 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libyubikey
+PKG_VERSION:=1.13
+PKG_RELEASE:=2
+
+PKG_SOURCE:=libyubikey-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://developers.yubico.com/yubico-c/Releases
+PKG_HASH:=04edd0eb09cb665a05d808c58e1985f25bb7c5254d2849f36a0658ffc51c3401
+PKG_MAINTAINER:=Stuart B. Wilkins <stuwilkins@mac.com>
+PKG_LICENSE_FILES:=COPYING
+PKG_LICENSE:=BSD-2-Clause
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libyubikey
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=The Yubico yubikey c library
+  URL:=https://developers.yubico.com/yubico-c/
+endef
+
+define Package/libyubikey/description
+	The c library for the yubikey from Yubico
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/include
+	$(CP) $(PKG_BUILD_DIR)/yubikey.h $(STAGING_DIR)/usr/include
+	$(INSTALL_DIR) $(STAGING_DIR)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/.libs/libyubikey.so* $(STAGING_DIR)/usr/lib
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--disable-static
+
+define Package/libyubikey/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/modhex $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/ykgenerate $(1)/usr/bin/
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/ykparse $(1)/usr/bin/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/.libs/libyubikey.so.* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libyubikey))
diff --git a/external/subpack/libs/libzip/Makefile b/external/subpack/libs/libzip/Makefile
new file mode 100644
index 0000000..215c5ca
--- /dev/null
+++ b/external/subpack/libs/libzip/Makefile
@@ -0,0 +1,137 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libzip
+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:=dc3c8d5b4c8bbd09626864f6bcf93de701540f761d76b85d7c7d710f4bd90318
+
+PKG_MAINTAINER:=Michael Heimpold <mhei@heimpold.de>
+
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:libzip:libzip
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libzip/Default
+  TITLE:=libzip ($(2))
+  URL:=https://libzip.org/
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=Compression
+  DEPENDS:=+zlib $(3)
+  VARIANT:=$(1)
+  PROVIDES:=libzip
+endef
+
+define Package/libzip-$(BUILD_VARIANT)/description
+ A C library for reading, creating, and modifying zip archives.
+endef
+
+Package/libzip-nossl=$(call Package/libzip/Default,nossl,w/o encryption support)
+Package/libzip-openssl=$(call Package/libzip/Default,openssl,OpenSSL,+PACKAGE_libzip-openssl:libopenssl)
+Package/libzip-gnutls=$(call Package/libzip/Default,gnutls,GnuTLS,+PACKAGE_libzip-gnutls:libgnutls)
+Package/libzip-mbedtls=$(call Package/libzip/Default,mbedtls,mbedTLS,+PACKAGE_libzip-mbedtls:libmbedtls)
+
+define Package/zipcmp
+  TITLE:=zipcmp
+  URL:=https://libzip.org/
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Compression
+  DEPENDS:=+libzip +USE_MUSL:musl-fts
+endef
+
+define Package/zipcmp/description
+ This package contains the command line tool zipcmp from libzip.
+endef
+
+define Package/zipmerge
+  TITLE:=zipmerge
+  URL:=https://libzip.org/
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Compression
+  DEPENDS:=+libzip
+endef
+
+define Package/zipmerge/description
+ This package contains the command line tool zipmerge from libzip.
+endef
+
+define Package/ziptool
+  TITLE:=ziptool
+  URL:=https://libzip.org/
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Compression
+  DEPENDS:=+libzip
+endef
+
+define Package/ziptool/description
+ This package contains the command line tool ziptool from libzip.
+endef
+
+CMAKE_OPTIONS += -DENABLE_COMMONCRYPTO=OFF
+ifeq ($(BUILD_VARIANT),gnutls)
+  CMAKE_OPTIONS += -DENABLE_GNUTLS=ON
+else
+  CMAKE_OPTIONS += -DENABLE_GNUTLS=OFF
+endif
+ifeq ($(BUILD_VARIANT),openssl)
+  CMAKE_OPTIONS += -DENABLE_OPENSSL=ON
+else
+  CMAKE_OPTIONS += -DENABLE_OPENSSL=OFF
+endif
+ifeq ($(BUILD_VARIANT),mbedtls)
+  CMAKE_OPTIONS += -DENABLE_MBEDTLS=ON
+else
+  CMAKE_OPTIONS += -DENABLE_MBEDTLS=OFF
+endif
+
+CMAKE_OPTIONS += -DENABLE_BZIP2=OFF
+CMAKE_OPTIONS += -DENABLE_LZMA=OFF
+CMAKE_OPTIONS += -DENABLE_ZSTD=OFF
+CMAKE_OPTIONS += -DBUILD_REGRESS=OFF
+CMAKE_OPTIONS += -DBUILD_EXAMPLES=OFF
+CMAKE_OPTIONS += -DBUILD_DOC=OFF
+CMAKE_OPTIONS += -DBUILD_TOOLS=ON
+
+define Package/libzip-$(BUILD_VARIANT)/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libzip.so.* $(1)/usr/lib/
+endef
+
+define Package/zipcmp/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/zipcmp $(1)/usr/bin/
+endef
+
+define Package/zipmerge/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/zipmerge $(1)/usr/bin/
+endef
+
+define Package/ziptool/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ziptool $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libzip-gnutls))
+$(eval $(call BuildPackage,libzip-mbedtls))
+$(eval $(call BuildPackage,libzip-openssl))
+$(eval $(call BuildPackage,libzip-nossl))
+$(eval $(call BuildPackage,zipcmp))
+$(eval $(call BuildPackage,zipmerge))
+$(eval $(call BuildPackage,ziptool))
diff --git a/external/subpack/libs/lmdb/Makefile b/external/subpack/libs/lmdb/Makefile
new file mode 100644
index 0000000..77a23b4
--- /dev/null
+++ b/external/subpack/libs/lmdb/Makefile
@@ -0,0 +1,98 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=lmdb
+PKG_VERSION:=0.9.33
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://git.openldap.org/openldap/openldap.git
+PKG_SOURCE_VERSION:=LMDB_$(PKG_VERSION)
+PKG_MIRROR_HASH:=cf6c73e3397ab8b8d81f45dd49a9becccf3c44727ffc640d4b905afda992b58b
+
+PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec1@gmail.com>
+PKG_LICENSE:=OLDAP-2.8
+PKG_LICENSE_FILES:=LICENSE
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+MAKE_PATH:=libraries/liblmdb
+
+define Package/lmdb/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Lightning Memory-Mapped Database
+  URL:=https://symas.com/lmdb/
+endef
+
+define Package/lmdb
+	$(call Package/lmdb/Default)
+  TITLE+= shared library
+endef
+
+define Package/lmdb/description
+  LMDB is an ultra-fast, ultra-compact key-value
+  embedded data store developed for the OpenLDAP Project.
+endef
+
+define Package/lmdb-utils
+	$(call Package/lmdb/Default)
+  TITLE+= utils
+  MDEPENDS+= lmdb
+endef
+
+define Package/lmdb-utils/description
+  LMDB environment status and copy tool
+endef
+
+define Package/lmdb-test
+	$(call Package/lmdb/Default)
+  TITLE+= test
+  MDEPENDS+= lmdb
+endef
+
+define Package/lmdb-test/description
+  LMDB test application
+endef
+
+define Build/Prepare
+	$(call Build/Prepare/Default)
+	$(SED) 's,%%PKG_VERSION%%,$(PKG_VERSION),g' $(PKG_BUILD_DIR)/liblmdb.pc
+endef
+
+define Build/Compile
+	$(MAKE) -C "$(PKG_BUILD_DIR)/$(MAKE_PATH)/" \
+		CC="$(TARGET_CC)" \
+		CFLAGS+="$(TARGET_CFLAGS)" \
+		LDFLAGS+="$(TARGET_LDFLAGS) $(if $(CONFIG_USE_GLIBC),-lpthread)" \
+		FPIC="$(FPIC)" \
+		AR="$(TARGET_AR)"
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/$(MAKE_PATH)/lmdb.h $(1)/usr/include
+	$(CP) $(PKG_BUILD_DIR)/$(MAKE_PATH)/liblmdb.{a,so} $(1)/usr/lib
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(CP) $(PKG_BUILD_DIR)/liblmdb.pc $(1)/usr/lib/pkgconfig/lmdb.pc
+endef
+
+define Package/lmdb/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/local/lib/*.so $(1)/usr/lib
+endef
+
+define Package/lmdb-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/local/bin/mdb_{stat,copy,dump,load} $(1)/usr/bin
+endef
+
+define Package/lmdb-test/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(MAKE_PATH)/mtest $(1)/usr/bin
+endef
+
+$(eval $(call BuildPackage,lmdb))
+$(eval $(call BuildPackage,lmdb-utils))
+$(eval $(call BuildPackage,lmdb-test))
diff --git a/external/subpack/libs/lmdb/patches/010-fix-makefile.patch b/external/subpack/libs/lmdb/patches/010-fix-makefile.patch
new file mode 100644
index 0000000..b31b6d5
--- /dev/null
+++ b/external/subpack/libs/lmdb/patches/010-fix-makefile.patch
@@ -0,0 +1,23 @@
+--- a/libraries/liblmdb/Makefile
++++ b/libraries/liblmdb/Makefile
+@@ -34,6 +34,7 @@ libdir = $(exec_prefix)/lib
+ includedir = $(prefix)/include
+ datarootdir = $(prefix)/share
+ mandir = $(datarootdir)/man
++FPIC ?= -fPIC
+ 
+ ########################################################################
+ 
+@@ -87,10 +88,10 @@ midl.o: midl.c midl.h
+ 	$(CC) $(CFLAGS) $(CPPFLAGS) -c midl.c
+ 
+ mdb.lo: mdb.c lmdb.h midl.h
+-	$(CC) $(CFLAGS) -fPIC $(CPPFLAGS) -c mdb.c -o $@
++	$(CC) $(CFLAGS) $(FPIC) $(CPPFLAGS) -c mdb.c -o $@
+ 
+ midl.lo: midl.c midl.h
+-	$(CC) $(CFLAGS) -fPIC $(CPPFLAGS) -c midl.c -o $@
++	$(CC) $(CFLAGS) $(FPIC) $(CPPFLAGS) -c midl.c -o $@
+ 
+ %:	%.o
+ 	$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
diff --git a/external/subpack/libs/lmdb/src/liblmdb.pc b/external/subpack/libs/lmdb/src/liblmdb.pc
new file mode 100644
index 0000000..d6fcaf6
--- /dev/null
+++ b/external/subpack/libs/lmdb/src/liblmdb.pc
@@ -0,0 +1,12 @@
+prefix=/usr
+exec_prefix=/usr
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+
+Name: Lightning Memory-Mapped Database
+Description: Lightning Memory-Mapped Database
+Version: %%PKG_VERSION%%
+Requires:
+Libs: -L${libdir} -llmdb
+Cflags: -I${includedir}
diff --git a/external/subpack/libs/log4cplus/Makefile b/external/subpack/libs/log4cplus/Makefile
new file mode 100644
index 0000000..a5c1f06
--- /dev/null
+++ b/external/subpack/libs/log4cplus/Makefile
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2019 Banglang Huang <banglang.huang@foxmail.com>
+# Copyright (C) 2019 Rosy Song <rosysong@rosinson.com>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=log4cplus
+PKG_VERSION:=2.1.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@SF/$(PKG_NAME)
+PKG_HASH:=a1d8e67a207f90a9dd4f82b28a1f3ac6dead5a80c2bed071277a9e865698a82b
+
+PKG_MAINTAINER:=BangLang Huang <banglang.huang@foxmail.com>, Rosy Song <rosysong@rosinson.com>
+PKG_LICENSE:=BSD-2-Clause Apache-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+CMAKE_INSTALL:=1
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/log4cplus
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A simple to use C++ logging API
+  URL:=https://sourceforge.net/p/log4cplus/wiki/Home/
+  DEPENDS:=+libstdcpp
+endef
+
+define Package/log4cplus/description
+  log4cplus is a simple to use C++11 logging API providing thread--safe,
+  flexible, and arbitrarily granular control over log management and
+  configuration. It is modeled after the Java log4j API.
+endef
+
+OPTIONS:= \
+	-DLOG4CPLUS_BUILD_LOGGINGSERVER:BOOL=OFF \
+	-DLOG4CPLUS_BUILD_TESTING:BOOL=OFF \
+	-DLOG4CPLUS_ENABLE_DECORATED_LIBRARY_NAME:BOOL=OFF \
+	-DUNICODE:BOOL=OFF \
+	-DWITH_ICONV:BOOL=OFF
+
+CMAKE_HOST_OPTIONS += $(OPTIONS) -DBUILD_SHARED_LIBS=OFF
+CMAKE_OPTIONS += $(OPTIONS) -DBUILD_SHARED_LIBS=ON
+
+TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
+
+define Package/log4cplus/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liblog4cplus*.so* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,log4cplus))
+$(eval $(call HostBuild))
diff --git a/external/subpack/libs/loudmouth/Makefile b/external/subpack/libs/loudmouth/Makefile
new file mode 100644
index 0000000..5123904
--- /dev/null
+++ b/external/subpack/libs/loudmouth/Makefile
@@ -0,0 +1,73 @@
+#
+# Copyright (C) 2007-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:=loudmouth
+PKG_VERSION:=1.5.4
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/mcabber/loudmouth/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=d1f66d479bb9a2794c52e997a9db9271f7fd004e264fe1ff4302607deb083375
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/loudmouth
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+glib2 +libopenssl +PACKAGE_krb5-libs:krb5-libs
+  TITLE:=loudmouth
+  URL:=https://github.com/mcabber/loudmouth
+endef
+
+define Package/loudmouth/description
+  Lightweight and easy-to-use C library for programming with the Jabber protocol
+endef
+
+CONFIGURE_ARGS += \
+	--disable-debug \
+	--without-compile-warnings \
+	--without-idn \
+	--with-ssl=openssl
+
+CONFIGURE_VARS += \
+	ac_cv_lib_crypto_BIO_f_base64=yes \
+	ac_cv_lib_ssl_SSL_new=yes
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/loudmouth-1.0/ \
+		$(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/loudmouth/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,loudmouth))
diff --git a/external/subpack/libs/loudmouth/patches/900-disable-docs-examples-tests.patch b/external/subpack/libs/loudmouth/patches/900-disable-docs-examples-tests.patch
new file mode 100644
index 0000000..d664e84
--- /dev/null
+++ b/external/subpack/libs/loudmouth/patches/900-disable-docs-examples-tests.patch
@@ -0,0 +1,27 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,7 +1,7 @@
+ include $(top_srcdir)/build/Makefile.am.lm
+ 
+-SUBDIRS = loudmouth docs examples $(TEST_DIRS)
+-DIST_SUBDIRS = loudmouth docs examples tests
++SUBDIRS = loudmouth
++DIST_SUBDIRS = loudmouth
+ 
+ ACLOCAL_AMFLAGS = -I m4
+ 
+--- a/configure.ac
++++ b/configure.ac
+@@ -320,12 +320,7 @@ AC_SUBST(LOUDMOUTH_LIBS)
+ 
+ AC_OUTPUT([
+ Makefile
+-docs/Makefile
+-docs/reference/Makefile
+ loudmouth/Makefile
+-examples/Makefile
+-tests/Makefile
+-tests/parser-tests/Makefile
+ loudmouth-1.0.pc])
+ 
+ dnl ==========================================================================
diff --git a/external/subpack/libs/lttng-ust/Makefile b/external/subpack/libs/lttng-ust/Makefile
new file mode 100644
index 0000000..0e90bf8
--- /dev/null
+++ b/external/subpack/libs/lttng-ust/Makefile
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2013-2015 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:=lttng-ust
+PKG_VERSION:=2.13.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://lttng.org/files/$(PKG_NAME)/
+PKG_HASH:=f1d7bb4984a3dc5dacd3b7bcb4c10c04b041b0eecd7cba1fef3d8f86aff02bd6
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=LGPL-2.1 GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:lttng:ust
+
+PKG_FIXUP:=autoreconf
+PKG_BUILD_FLAGS:=no-mips16
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/lttng-ust
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Linux Trace Toolkit: next generation (library)
+  URL:=https://lttng.org/
+  DEPENDS:= +liburcu +libuuid +librt
+endef
+
+CONFIGURE_ARGS += \
+	--disable-numa \
+	--disable-python-agent \
+	--disable-examples \
+	--disable-man-pages \
+	--with-pic
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/lttng $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liblttng-ust*.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/lttng-ust* $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/lttng-ust/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liblttng*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,lttng-ust))
diff --git a/external/subpack/libs/lttng-ust/patches/100-no-tests.patch b/external/subpack/libs/lttng-ust/patches/100-no-tests.patch
new file mode 100644
index 0000000..0849671
--- /dev/null
+++ b/external/subpack/libs/lttng-ust/patches/100-no-tests.patch
@@ -0,0 +1,10 @@
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -7,7 +7,6 @@ SUBDIRS = \
+ 	src \
+ 	tools \
+ 	doc \
+-	tests \
+ 	extras
+ 
+ dist_doc_DATA = \
diff --git a/external/subpack/libs/lzo/Makefile b/external/subpack/libs/lzo/Makefile
new file mode 100644
index 0000000..2a74630
--- /dev/null
+++ b/external/subpack/libs/lzo/Makefile
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2006-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:=lzo
+PKG_VERSION:=2.10
+PKG_RELEASE:=4
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.oberhumer.com/opensource/lzo/download/
+PKG_HASH:=c0f892943208266f9b6543b3ae308fab6284c5c90e627931446fb49b4221a072
+
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:oberhumer:lzo
+
+CMAKE_BINARY_SUBDIR:=openwrt-build
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/liblzo
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A real-time data compression library
+  URL:=http://www.oberhumer.com/opensource/lzo/
+  ABI_VERSION:=2
+endef
+
+define Package/liblzo/description
+ LZO is a data compression library which is suitable for data de-/compression
+ in real-time. This means it favours speed over compression ratio.
+endef
+
+CMAKE_OPTIONS += \
+	-DENABLE_SHARED=ON \
+	-DENABLE_STATIC=ON \
+	-DBUILD_TESTING=OFF
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/lzo $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liblzo2.{a,so*} $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/lzo2.pc $(1)/usr/lib/pkgconfig
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/lzo2.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/lzo2.pc
+endef
+
+define Package/liblzo/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/liblzo2.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,liblzo))
diff --git a/external/subpack/libs/minizip/Makefile b/external/subpack/libs/minizip/Makefile
new file mode 100644
index 0000000..3f126c6
--- /dev/null
+++ b/external/subpack/libs/minizip/Makefile
@@ -0,0 +1,70 @@
+#
+# Copyright © 2020 David Woodhouse <dwmw2@infradead.org>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=minizip-ng
+PKG_VERSION:=4.0.7
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/zlib-ng/minizip-ng/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=a87f1f734f97095fe1ef0018217c149d53d0f78438bcb77af38adc21dff2dfbc
+
+PKG_MAINTAINER:=David Woodhouse <dwmw2@infradead.org>
+PKG_LICENSE:=Zlib
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:zlib-ng:minizip-ng
+
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_OPTIONS += \
+	-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
+	-DINSTALL_INC_DIR=/usr/include/minizip \
+	-DBUILD_SHARED_LIBS=ON \
+	-DMZ_BZIP2=OFF \
+	-DMZ_ICONV=OFF \
+	-DMZ_LIBBSD=OFF \
+	-DMZ_LZMA=OFF \
+	-DMZ_OPENSSL=OFF \
+	-DMZ_PKCRYPT=OFF \
+	-DMZ_ZSTD=OFF
+
+define Package/minizip
+  TITLE:=Fork of the popular zip manipulation library found in the zlib distribution
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+zlib
+  URL:=https://github.com/zlib-ng/minizip-ng
+endef
+
+define Package/minizip-dev
+  SECTION:=devel
+  CATEGORY:=Development
+  SUBMENU:=Libraries
+  DEPENDS:=minizip
+  TITLE:=Development files for the minizip library
+endef
+
+define Package/minizip/description
+  minizip is a zip manipulation library written in C that is supported on Windows, macOS, and Linux
+endef
+
+define Package/minizip/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libminizip.so.* $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/minizip.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/minizip.pc
+endef
+
+$(eval $(call BuildPackage,minizip))
diff --git a/external/subpack/libs/msgpack-c/Makefile b/external/subpack/libs/msgpack-c/Makefile
new file mode 100644
index 0000000..7cdaae7
--- /dev/null
+++ b/external/subpack/libs/msgpack-c/Makefile
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-3.0-only
+#
+# Copyright (C) 2021 ImmortalWrt.org
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=msgpack-c
+PKG_VERSION:=6.0.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/msgpack/msgpack-c/tar.gz/c-$(PKG_VERSION)?
+PKG_HASH:=af6f3cf25edb220aa2140b09bb5bdd73ddf00938194bd94ebe5c92090cccb466
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-c-$(PKG_VERSION)
+
+PKG_LICENSE:=BSL-1.0
+PKG_LICENSE_FILES:=COPYING LICENSE_1_0.txt
+PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
+
+PKG_BUILD_PARALLEL:=1
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_OPTIONS+= \
+	-DBUILD_SHARED_LIBS=ON \
+	-DMSGPACK_BUILD_EXAMPLES=OFF \
+	-DMSGPACK_BUILD_TESTS=OFF \
+	-DMSGPACK_ENABLE_STATIC=OFF
+
+define Package/msgpack-c
+  SECTION:=lib
+  CATEGORY:=Libraries
+  TITLE:=MessagePack implementation for C
+  URL:=https://github.com/msgpack/msgpack-c
+endef
+
+define Package/msgpack-c/description
+  MessagePack is an efficient binary serialization format, which lets
+  you exchange data among multiple languages like JSON, except that
+  it's faster and smaller. Small integers are encoded into a single
+  byte and short strings require only one extra byte in addition to
+  the strings themselves.
+endef
+
+define Package/msgpack-c/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libmsgpack-c.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,msgpack-c))
diff --git a/external/subpack/libs/mtdev/Makefile b/external/subpack/libs/mtdev/Makefile
new file mode 100644
index 0000000..586f47f
--- /dev/null
+++ b/external/subpack/libs/mtdev/Makefile
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2007-2015 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:=mtdev
+PKG_VERSION:=1.1.7
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://bitmath.org/code/mtdev/
+PKG_HASH:=a107adad2101fecac54ac7f9f0e0a0dd155d954193da55c2340c97f2ff1d814e
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/mtdev
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Multitouch Protocol Translation Library
+  URL:=http://bitmath.org/code/mtdev/
+endef
+
+define Package/mtdev/description
+  The mtdev is a stand-alone library which transforms all variants of
+  kernel MT events to the slotted type B protocol. The events put into
+  mtdev may be from any MT device, specifically type A without contact
+  tracking, type A with contact tracking, or type B with contact
+  tracking. See the kernel documentation for further details.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/mtdev/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,mtdev))
diff --git a/external/subpack/libs/mtdev/patches/010-format.patch b/external/subpack/libs/mtdev/patches/010-format.patch
new file mode 100644
index 0000000..c456c4b
--- /dev/null
+++ b/external/subpack/libs/mtdev/patches/010-format.patch
@@ -0,0 +1,11 @@
+--- a/test/mtdev-test.c
++++ b/test/mtdev-test.c
+@@ -38,7 +38,7 @@
+ #endif
+ 
+ /* year-proof millisecond event time */
+-typedef uint64_t mstime_t;
++typedef unsigned long long mstime_t;
+ 
+ static int use_event(const struct input_event *ev)
+ {
diff --git a/external/subpack/libs/mxml/Makefile b/external/subpack/libs/mxml/Makefile
new file mode 100644
index 0000000..8698a72
--- /dev/null
+++ b/external/subpack/libs/mxml/Makefile
@@ -0,0 +1,53 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mxml
+PKG_VERSION:=3.3.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/michaelrsweet/$(PKG_NAME)/releases/download/v$(PKG_VERSION)/
+PKG_HASH:=0c663ed1fe393b5619f80101798202eea43534abd7c8aff389022fd8c1dacc32
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+
+PKG_FIXUP:=autoreconf
+
+PKG_MAINTAINER:=Espen Jürgensen <espenjurgensen+openwrt@gmail.com>
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:mini-xml_project:mini-xml
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/mxml
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Mini-XML
+  URL:=http://www.minixml.org/
+  DEPENDS:=+zlib
+endef
+
+define Package/mxml/description
+  A small xml library.
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static
+
+define Build/InstallDev
+	mkdir -p $(1)/usr/include
+	$(CP) $(PKG_BUILD_DIR)/mxml.h $(1)/usr/include/
+	mkdir -p $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/libmxml.so* $(1)/usr/lib/
+	mkdir -p $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_BUILD_DIR)/mxml.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/mxml/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/libmxml.so.*  $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,mxml))
diff --git a/external/subpack/libs/nacl/Makefile b/external/subpack/libs/nacl/Makefile
new file mode 100644
index 0000000..dcea86b
--- /dev/null
+++ b/external/subpack/libs/nacl/Makefile
@@ -0,0 +1,50 @@
+#
+# Copyright (C) 2011-2014 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:=nacl
+PKG_VERSION:=20110221
+PKG_RELEASE:=2
+
+PKG_MAINTAINER:=Matthias Schiffer <mschiffer@universe-factory.net>
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://hyperelliptic.org/nacl
+PKG_HASH:=4f277f89735c8b0b8a6bbd043b3efb3fa1cc68a9a5da6a076507d067fc3b3bf8
+
+PKG_LICENSE:=Public-Domain
+
+PKG_BUILD_FLAGS:=no-mips16
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/nacl
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=NaCl Networking and Cryptography library
+  URL:=http://nacl.cace-project.eu/
+  BUILDONLY:=1
+endef
+
+define Build/Compile
+	(cd $(PKG_BUILD_DIR) && \
+			CC="$(TARGET_CC)" \
+			CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
+			AR="$(TARGET_CROSS)ar" \
+			RANLIB="$(TARGET_CROSS)ranlib" \
+		$(CURDIR)/do-openwrt \
+	)
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/nacl
+	$(CP) $(PKG_BUILD_DIR)/build/include/*.h $(1)/usr/include/nacl/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/build/lib/libnacl.a $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,nacl))
diff --git a/external/subpack/libs/nacl/do-openwrt b/external/subpack/libs/nacl/do-openwrt
new file mode 100755
index 0000000..ba4fde3
--- /dev/null
+++ b/external/subpack/libs/nacl/do-openwrt
@@ -0,0 +1,206 @@
+#!/bin/sh
+set -e
+
+# nacl/do
+# D. J. Bernstein
+# Public domain.
+
+version=`cat version`
+project=nacl
+
+top="`pwd`/build"
+bin="$top/bin"
+lib="$top/lib"
+include="$top/include"
+work="$top/work"
+
+
+# and work around bug in GNU sort
+LANG=C
+export LANG
+
+rm -rf "$top"
+mkdir -p "$top"
+mkdir -p "$bin"
+mkdir -p "$lib"
+mkdir -p "$include"
+
+exec >"$top/log"
+exec 2>&1
+exec 5>"$top/data"
+exec </dev/null
+
+echo "=== `date` === starting"
+
+echo "=== `date` === building inttypes"
+for target in int8 int16 int32 int64 uint8 uint16 uint32 uint64; do
+  (
+    echo "#ifndef crypto_${target}_h"
+    echo "#define crypto_${target}_h"
+    echo ""
+    echo "#include <stdint.h>"
+    echo ""
+    echo "typedef ${target}_t crypto_${target};"
+    echo ""
+    echo "#endif"
+  ) > "$include/crypto_$target.h"
+done
+
+echo "=== `date` === building randombytes"
+rm -rf "$work"
+mkdir -p "$work"
+cp -pr randombytes/* "$work"
+(
+  cd "$work"
+
+  cp devurandom.c randombytes-impl.c
+  cp devurandom.h randombytes-impl.h
+  $CC $CFLAGS -c randombytes-impl.c
+  mkdir -p lib
+  mv randombytes-impl.o lib/randombytes.o
+  mkdir -p include
+  mv randombytes-impl.h include/randombytes.h
+)
+cp -pr "$work"/lib/* "$lib"
+cp -pr "$work"/include/* "$include"
+
+rm -rf "$work"
+mkdir -p "$work"
+echo 'void crypto_'"$project"'_base(void) { ; }' > "$work/${project}_base.c"
+( cd "$work" && $CC $CFLAGS -c ${project}_base.c )
+$AR cr "$lib/lib${project}.a" "$work/${project}_base.o"
+( $RANLIB "$lib/lib${project}.a" || exit 0 )
+
+# loop over operations
+cat OPERATIONS \
+| while read o
+do
+  [ -d "$o" ] || continue
+
+  # for each operation, loop over primitives
+  ls "$o" \
+  | sort \
+  | while read p
+  do
+    [ -d "$o/$p" ] || continue
+    op="${o}_${p}"
+
+    startdate=`date +%Y%m%d`
+
+    echo "=== `date` === $o/$p"
+
+    rm -rf "$work"
+    mkdir -p "$work"
+
+    if [ -d "$o/$p/ref" ]; then
+      implementationdir="$o/$p/ref"
+    else
+      implementationdir="$o/$p/portable"
+    fi
+
+    opi=`echo "$implementationdir" | tr ./- ___`
+
+    echo "=== `date` === $implementationdir"
+
+    cfiles=`ls "$implementationdir" | grep '\.c$' || :`
+    sfiles=`ls "$implementationdir" | grep '\.[sS]$' || :`
+
+    cp -p "$o"/*.c "$work"
+
+    cp -pr "$implementationdir"/* "$work"
+
+    cp -p MACROS "$work/MACROS"
+    cp -p PROTOTYPES.c "$work/PROTOTYPES.c"
+
+    (
+      cd "$work"
+      (
+	echo "#ifndef ${o}_H"
+	echo "#define ${o}_H"
+	echo ""
+	echo "#include \"${op}.h\""
+	echo ""
+	egrep "${o}"'$|'"${o}"'\(|'"${o}"'_' < MACROS \
+	  | sed "s/$o/$op/" | while read mop
+	do
+	  echo "#define ${mop} ${mop}" | sed "s/$op/$o/"
+	done
+	echo "#define ${o}_PRIMITIVE \"${p}\""
+	echo "#define ${o}_IMPLEMENTATION ${op}_IMPLEMENTATION"
+	echo "#define ${o}_VERSION ${op}_VERSION"
+	echo ""
+	echo "#endif"
+      ) > "$o.h"
+      (
+	echo "#ifndef ${op}_H"
+	echo "#define ${op}_H"
+	echo ""
+	sed 's/[ 	]CRYPTO_/ '"${opi}"'_/g' < api.h
+	echo '#ifdef __cplusplus'
+	  #echo '#include <string>'
+	  #egrep "${o}"'$|'"${o}"'\(|'"${o}"'_' < PROTOTYPES.cpp \
+	  #    | sed "s/$o/$opi/"
+	echo 'extern "C" {'
+	echo '#endif'
+	egrep "${o}"'$|'"${o}"'\(|'"${o}"'_' < PROTOTYPES.c \
+	  | sed "s/$o/$opi/"
+	echo '#ifdef __cplusplus'
+	echo '}'
+	echo '#endif'
+	echo ""
+	egrep "${o}"'$|'"${o}"'\(|'"${o}"'_' < MACROS \
+	  | sed "s/$o/$opi/" | while read mopi
+	do
+	    echo "#define ${mopi} ${mopi}" | sed "s/$opi/$op/"
+	done
+	echo "#define ${op}_IMPLEMENTATION \"${implementationdir}\""
+	echo "#ifndef ${opi}_VERSION"
+	echo "#define ${opi}_VERSION \"-\""
+	echo "#endif"
+	echo "#define ${op}_VERSION ${opi}_VERSION"
+	echo ""
+	echo "#endif"
+      ) > "$op.h"
+
+      echo "=== `date` === $implementationdir $CC $CFLAGS"
+      for f in $cfiles $sfiles
+      do
+	ok=1
+	$CC $CFLAGS \
+	    -I. -I"$include" \
+	    -c "$f" >errors 2>&1 || ok=0
+	( if [ `wc -l < errors` -lt 25 ]
+	  then
+	    cat errors
+	  else
+	    head errors
+	    echo ...
+	    tail errors
+	  fi
+	) \
+	| while read err
+	do
+	  echo "$version $startdate $o $p fromcompiler $implementationdir $f $err" >&5
+	done
+
+	[ "$ok" = 1 ]
+      done
+
+      for f in *.o
+      do
+	mv "$f" "${opi}-$f"
+      done
+    )
+
+    echo "=== `date` === $implementationdir $CC $CFLAGS finishing"
+
+    $AR cr "$lib/lib${project}.a" "$work"/*.o \
+    && ( $RANLIB "$lib/lib${project}.a" || exit 0 ) \
+    && cp -p "$work/$op.h" "$include/$op.h" \
+    && [ -f "$o/$p/selected" ] \
+    && cp -p "$work/$o.h" "$include/$o.h" \
+    || :
+  done
+done
+
+echo "=== `date` === finishing"
diff --git a/external/subpack/libs/neon/Makefile b/external/subpack/libs/neon/Makefile
new file mode 100644
index 0000000..9df650b
--- /dev/null
+++ b/external/subpack/libs/neon/Makefile
@@ -0,0 +1,81 @@
+#
+# Copyright (C) 2007-2014 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:=neon
+PKG_VERSION:=0.32.4
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://notroj.github.io/neon
+PKG_HASH:=b1e2120e4ae07df952c4a858731619733115c5f438965de4fab41d6bf7e7a508
+
+PKG_MAINTAINER:=Federico Di Marco <fededim@gmail.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=src/COPYING.LIB
+PKG_CPE_ID:=cpe:/a:webdav:neon
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libneon
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=HTTP and WebDAV client library
+  URL:=https://notroj.github.io/neon/
+  DEPENDS:=+libopenssl +libexpat +zlib
+endef
+
+define Package/libneon/description
+  neon is an HTTP and WebDAV client library, with a C interface. Features:
+
+  - High-level wrappers for common HTTP and WebDAV operations (GET, MOVE, DELETE, etc)
+  - Low-level interface to the HTTP request/response engine, allowing the use of arbitrary HTTP methods, headers, etc.
+  - Authentication support including Basic and Digest support, along with GSSAPI-based Negotiate on Unix, and
+    SSPI-based Negotiate/NTLM on Win32
+  - SSL/TLS support using OpenSSL or GnuTLS; exposing an abstraction layer for verifying server certificates, handling client
+    certificates, and examining certificate properties. Smartcard-based client certificates are also supported via a
+    PKCS11 wrapper interface.
+  - Abstract interface to parsing XML using libxml2 or expat, and wrappers for simplifying handling XML HTTP response bodies
+  - WebDAV metadata support; wrappers for PROPFIND and PROPPATCH to simplify property manipulation.
+endef
+
+CONFIGURE_VARS += \
+	ne_cv_os_uname="Linux"
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--with-expat \
+	--with-ssl="openssl" \
+	--without-egd \
+	--without-gssapi \
+	--without-libproxy
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/neon-config $(1)/usr/bin/
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/neon $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libneon.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/neon.pc $(1)/usr/lib/pkgconfig/
+	$(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(1)/usr/bin/neon-config
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/neon-config $(2)/bin/neon-config
+endef
+
+define Package/libneon/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libneon.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libneon))
diff --git a/external/subpack/libs/neon/patches/010-no-xmlto.patch b/external/subpack/libs/neon/patches/010-no-xmlto.patch
new file mode 100644
index 0000000..34f3c5f
--- /dev/null
+++ b/external/subpack/libs/neon/patches/010-no-xmlto.patch
@@ -0,0 +1,20 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -45,7 +45,7 @@ INSTALL = @INSTALL@
+ transform = @program_transform_name@
+ 
+ LIBTOOL = @LIBTOOL@
+-XMLTO = xmlto
++XMLTO = /bin/true
+ GCOV = gcov
+ XGETTEXT_OPTS = --keyword=_ --keyword=N_ --msgid-bugs-address=neon@lists.manyfish.co.uk \
+ 		--default-domain=neon --flag ne_print_request_header:3:c-format \
+@@ -148,7 +148,7 @@ install-memleak:
+ 	@echo "ERROR: purposes only; this copy of neon must not be installed."
+ 	@false
+ 
+-install-yes: install-lib install-headers install-config install-docs install-nls
++install-yes: install-lib install-headers install-config install-nls
+ 
+ # libtool does all the necessary magic here
+ install-lib: subdirs
diff --git a/external/subpack/libs/newt/Makefile b/external/subpack/libs/newt/Makefile
new file mode 100644
index 0000000..30b9b5b
--- /dev/null
+++ b/external/subpack/libs/newt/Makefile
@@ -0,0 +1,125 @@
+#
+# Copyright (C) 2006-2011 OpenWrt.org
+# Copyright (C) 2011 SMBPhone Inc.
+# Copyright (C) 2019-2020, 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:=newt
+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:=5ded7e221f85f642521c49b1826c8de19845aa372baf5d630a51774b544fbdbb
+
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+PKG_LICENSE:=LGPL-2.0-only
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:fedorahosted:newt
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+PYTHON3_PKG_BUILD:=0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include ../../lang/python/python3-package.mk
+
+define Package/newt/Default
+  TITLE:=Newt
+  URL:=https://pagure.io/newt
+endef
+
+define Package/newt/Default/description
+  Newt is a programming library for color text mode, widget based user
+  interfaces.  Newt can be used to add stacked windows, entry widgets,
+  checkboxes, radio buttons, labels, plain text fields, scrollbars, etc.,
+  to text mode user interfaces.  Newt is based on the slang library.
+endef
+
+define Package/libnewt
+$(call Package/newt/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE+= library
+  DEPENDS:=+libslang2 $(INTL_DEPENDS)
+endef
+
+define Package/libnewt/description
+$(call Package/newt/Default/description)
+endef
+
+define Package/whiptail
+$(call Package/newt/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Display dialog boxes from shell scripts
+  DEPENDS:=+libnewt +libpopt +libslang2
+endef
+
+define Package/whiptail/description
+  A lightweight replacement for the dialog command (dialog boxes from shell
+  scripts), based on libnewt.
+endef
+
+define Package/python3-newt
+$(call Package/newt/Default)
+  SECTION:=lang
+  CATEGORY:=Languages
+  SUBMENU:=Python
+  TITLE+= module for Python
+  DEPENDS:=+libnewt +python3-light
+endef
+
+define Package/python3-newt/description
+$(call Package/newt/Default/description)
+
+  This is the Newt module for Python 3.
+endef
+
+CONFIGURE_ARGS+= \
+	--enable-largefile \
+	--with-python=python$(PYTHON3_VERSION) \
+	--without-tcl \
+	--without-gpm-support \
+	--with-colorsfile=/etc/newt/palette
+
+CONFIGURE_VARS += $(if $(CONFIG_BUILD_NLS),ac_cv_lib_c_gettext=no)
+
+MAKE_VARS+= PYTHON_CONFIG_PATH="$(STAGING_DIR)/host/bin"
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/newt.h $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnewt.{a,so*} $(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libnewt.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libnewt/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnewt.so* $(1)/usr/lib/
+endef
+
+define Package/whiptail/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/whiptail $(1)/usr/bin/
+endef
+
+# Don't install files from usr/bin
+Py3Package/python3-newt/install:=:
+
+$(eval $(call BuildPackage,libnewt))
+$(eval $(call BuildPackage,whiptail))
+
+$(eval $(call Py3Package,python3-newt))
+$(eval $(call BuildPackage,python3-newt))
+$(eval $(call BuildPackage,python3-newt-src))
diff --git a/external/subpack/libs/newt/patches/002-use-target-ar-python-config.patch b/external/subpack/libs/newt/patches/002-use-target-ar-python-config.patch
new file mode 100644
index 0000000..479567e
--- /dev/null
+++ b/external/subpack/libs/newt/patches/002-use-target-ar-python-config.patch
@@ -0,0 +1,25 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -84,12 +84,7 @@ showkey:	showkey.o $(LIBNEWT)
+ 
+ _snack.$(SOEXT):   snack.c $(LIBNEWTSH)
+ 	@[ -n "$(PYTHONVERS)" ] && for ver in $(PYTHONVERS); do \
+-		pyconfig=$$ver-config; \
+-		if ! $$pyconfig --cflags > /dev/null 2>&1 && \
+-				python-config --cflags > /dev/null 2>&1; then \
+-			echo $$pyconfig not found, using python-config; \
+-			pyconfig=python-config; \
+-		fi; \
++		pyconfig=$(PYTHON_CONFIG_PATH)/$$ver-config; \
+ 		mkdir -p $$ver; \
+ 		PCFLAGS=`$$pyconfig --cflags`; \
+ 		PIFLAGS=`$$pyconfig --includes`; \
+@@ -109,7 +104,7 @@ whiptcl.$(SOEXT): $(WHIPTCLOBJS) $(LIBNE
+ 	$(CC) -shared $(SHCFLAGS) $(LDFLAGS) -o whiptcl.$(SOEXT) $(WHIPTCLOBJS) -L. -lnewt  $(LIBTCL) -lpopt $(LIBS)
+ 
+ $(LIBNEWT): $(LIBOBJS)
+-	ar rv $@ $^
++	$(AR) rv $@ $^
+ 
+ newt.o $(SHAREDDIR)/newt.o: newt.c Makefile
+ 
diff --git a/external/subpack/libs/newt/patches/python_memory_allocation.patch b/external/subpack/libs/newt/patches/python_memory_allocation.patch
new file mode 100644
index 0000000..4dd3b29
--- /dev/null
+++ b/external/subpack/libs/newt/patches/python_memory_allocation.patch
@@ -0,0 +1,35 @@
+Author: Thomas Viehmann <tv@beamnet.de>
+Description: Fix for python memory handling
+Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=445392
+Last-Updated: 2014-06-11
+Forwarded: no
+
+--- a/snack.c
++++ b/snack.c
+@@ -366,7 +366,7 @@ static PyTypeObject snackWidgetType = {
+ static snackWidget * snackWidgetNew (void) {
+     snackWidget * widget;
+      
+-    widget = PyObject_NEW(snackWidget, &snackWidgetType);
++    widget = PyObject_New(snackWidget, &snackWidgetType);
+     if (!widget)
+ 	return NULL;
+ 
+@@ -932,7 +932,7 @@ static snackForm * formCreate(PyObject *
+     if (help == Py_None)
+ 	help = NULL;
+ 
+-    form = PyObject_NEW(snackForm, &snackFormType);
++    form = PyObject_New(snackForm, &snackFormType);
+     form->fo = newtForm(NULL, help, 0);
+ 
+     return form;
+@@ -944,7 +944,7 @@ static snackGrid * gridCreate(PyObject *
+ 
+     if (!PyArg_ParseTuple(args, "ii", &cols, &rows)) return NULL;
+ 
+-    grid = PyObject_NEW(snackGrid, &snackGridType);
++    grid = PyObject_New(snackGrid, &snackGridType);
+     grid->grid = newtCreateGrid(cols, rows);
+ 
+     return grid;
diff --git a/external/subpack/libs/newt/test.sh b/external/subpack/libs/newt/test.sh
new file mode 100644
index 0000000..ae90067
--- /dev/null
+++ b/external/subpack/libs/newt/test.sh
@@ -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
diff --git a/external/subpack/libs/nghttp2/Makefile b/external/subpack/libs/nghttp2/Makefile
new file mode 100644
index 0000000..21282ea
--- /dev/null
+++ b/external/subpack/libs/nghttp2/Makefile
@@ -0,0 +1,44 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nghttp2
+PKG_VERSION:=1.63.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:=4879c75dd32a74421b9857924449460b8341796c0613ba114ab2188e4622354b
+
+PKG_MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:nghttp2:nghttp2
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libnghttp2
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Library implementing the framing layer of HTTP/2
+  ABI_VERSION:=14
+endef
+
+define Package/libnghttp2/description
+ C library implementing the framing layer of the HTTP/2 protocol. It can be used to build a HTTP/2-capable HTTP client or server
+endef
+
+CMAKE_OPTIONS += \
+        -DENABLE_LIB_ONLY=ON
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libnghttp2.pc
+	$(SED) 's,/usr/lib,$$$${prefix}/lib,g' $(1)/usr/lib/pkgconfig/libnghttp2.pc
+endef
+
+define Package/libnghttp2/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libnghttp2.so.* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libnghttp2))
diff --git a/external/subpack/libs/nghttp3/Makefile b/external/subpack/libs/nghttp3/Makefile
new file mode 100644
index 0000000..e57e8ba
--- /dev/null
+++ b/external/subpack/libs/nghttp3/Makefile
@@ -0,0 +1,44 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nghttp3
+PKG_VERSION:=1.5.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/ngtcp2/nghttp3/releases/download/v$(PKG_VERSION)/
+PKG_HASH:=8c00e3910ea2ad1218dafebcf8dd2ffdf030c992d9ceb65834d29e5e5278dd0d
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Aleksey Vasilenko <aleksey.vasilenko@gmail.com>
+
+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 Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libnghttp3.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libnghttp3.pc
+endef
+
+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/external/subpack/libs/ngtcp2/Makefile b/external/subpack/libs/ngtcp2/Makefile
new file mode 100644
index 0000000..80927ab
--- /dev/null
+++ b/external/subpack/libs/ngtcp2/Makefile
@@ -0,0 +1,46 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ngtcp2
+PKG_VERSION:=1.7.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/ngtcp2/ngtcp2/releases/download/v$(PKG_VERSION)/
+PKG_HASH:=e07c79090f96f6738fabab2129657c53f0cc05164de3662592581ca5425617b1
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Aleksey Vasilenko <aleksey.vasilenko@gmail.com>
+
+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
+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 Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libngtcp2.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libngtcp2.pc
+endef
+
+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))
diff --git a/external/subpack/libs/nlohmannjson/Makefile b/external/subpack/libs/nlohmannjson/Makefile
new file mode 100644
index 0000000..b2bbf5f
--- /dev/null
+++ b/external/subpack/libs/nlohmannjson/Makefile
@@ -0,0 +1,44 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nlohmannjson
+PKG_VERSION:=3.11.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).zip
+PKG_SOURCE_URL:=https://codeload.github.com/nlohmann/json/zip/v$(PKG_VERSION)?
+PKG_HASH:=95651d7d1fcf2e5c3163c3d37df6d6b3e9e5027299e6bd050d157322ceda9ac9
+PKG_BUILD_DIR:=$(BUILD_DIR)/json-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Leonid Esman <leonid.esman@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE.MIT
+PKG_CPE_ID:=cpe:/a:json-for-modern-cpp_project:json-for-modern-cpp
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/nlohmannjson
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=JSON for Modern C++
+  URL:=https://nlohmann.github.io/json/
+  BUILDONLY:=1
+endef
+
+define Package/nlohmannjson/description
+  Niels Lohmann's JSON headers-only library for modern C++
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/nlohmann
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/nlohmann/json.hpp $(1)/usr/include/nlohmann
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/nlohmann/json_fwd.hpp $(1)/usr/include/nlohmann
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/nlohmann_json.pc $(1)/usr/lib/pkgconfig
+endef
+
+$(eval $(call BuildPackage,nlohmannjson))
diff --git a/external/subpack/libs/npth/Makefile b/external/subpack/libs/npth/Makefile
new file mode 100644
index 0000000..a7c2547
--- /dev/null
+++ b/external/subpack/libs/npth/Makefile
@@ -0,0 +1,66 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=npth
+PKG_VERSION:=1.6
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://gnupg.org/ftp/gcrypt/$(PKG_NAME)
+PKG_HASH:=1393abd9adcf0762d34798dc34fdcf4d0d22a8410721e76f1e3afcd1daa4e2d1
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LIB
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libnpth
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=The New GNU Portable Threads Library
+  URL:=https://gnupg.org/software/npth/index.html
+  DEPENDS:=+libgpg-error
+endef
+
+define Package/libnpth/description
+nPth is a library to provide the GNU Pth API and thus a non-preemptive threads implementation. 
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(2)/bin $(1)/usr/bin
+	$(INSTALL_BIN) \
+		$(PKG_INSTALL_DIR)/usr/bin/npth-config \
+		$(2)/bin/
+	$(SED) \
+		's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \
+		$(2)/bin/npth-config
+	ln -sf $(STAGING_DIR)/host/bin/npth-config $(1)/usr/bin/npth-config
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/include/npth.h \
+		$(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libnpth.{la,so*} \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/share/aclocal
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/share/aclocal/npth.m4 \
+		$(1)/usr/share/aclocal/
+endef
+
+define Package/libnpth/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libnpth.so.* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libnpth))
diff --git a/external/subpack/libs/nspr/Makefile b/external/subpack/libs/nspr/Makefile
new file mode 100644
index 0000000..41a9d52
--- /dev/null
+++ b/external/subpack/libs/nspr/Makefile
@@ -0,0 +1,91 @@
+#
+# Copyright (C) 2019 Lucian Cristian
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nspr
+PKG_VERSION:=4.35
+PKG_RELEASE:=2
+PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
+PKG_LICENSE:=MPL-2.0
+PKG_CPE_ID:=cpe:/a:mozilla:netscape_portable_runtime
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:= \
+    https://download.cdn.mozilla.net/pub/$(PKG_NAME)/releases/v$(PKG_VERSION)/src/ \
+    https://archive.mozilla.org/pub/$(PKG_NAME)/releases/v$(PKG_VERSION)/src/
+PKG_HASH:=7ea3297ea5969b5d25a5dd8d47f2443cda88e9ee746301f6e1e1426f8a6abc8f
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+PKG_FIXUP:=autoreconf
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+
+CONFIGURE_PATH = ./nspr
+MAKE_PATH = ./nspr
+PKG_AUTOMAKE_PATHS = $(PKG_BUILD_DIR)/nspr
+LBITS = $(shell $(TARGET_CC) -dM -E - </dev/null | grep -q "__LP64__" && echo 64 || echo 32)
+
+ifeq ($(LBITS),64)
+    conf=--enable-64bit
+endif
+
+export MUSL=$(if $(CONFIG_LIBC_USE_GLIBC),0,1)
+TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed $(FPIC)
+ifneq ($(CONFIG_USE_MUSL),)
+  TARGET_CFLAGS += -D_LARGEFILE64_SOURCE
+endif
+
+CONFIGURE_ARGS += \
+    --build=$(GNU_HOST_NAME) \
+    --host=$(GNU_HOST_NAME) \
+    --target=$(REAL_GNU_TARGET_NAME) \
+    --disable-debug \
+    --with-pthreads \
+    $(if $(CONFIG_IPV6),--enable-ipv6,--disable-ipv6) \
+    $(conf)
+
+define Build/Compile
+	CROSS_COMPILE=1 CFLAGS="-DXP_UNIX $(HOST_CFLAGS)" LDFLAGS="" CC="$(HOSTCC)" \
+	    $(MAKE) -C $(PKG_BUILD_DIR)/nspr/config
+	$(call Build/Compile/Default)
+endef
+
+define Package/nspr
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Netscape Portable Runtime (NSPR)
+  URL:=https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSPR
+  DEPENDS:=+libpthread
+endef
+
+define Package/nspr/description
+  Netscape Portable Runtime (NSPR) provides a platform-neutral API for system
+  level and libc-like functions. The API is used in the Mozilla clients, many
+  of Red Hat's and Oracle's server applications, and other software offerings.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) \
+	    $(1)/usr/include \
+	    $(1)/usr/lib/ \
+	    $(1)/usr/lib/pkgconfig/ \
+	    $(1)/usr/share/aclocal/
+
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/nspr $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/aclocal/* $(1)/usr/share/aclocal/
+endef
+
+define Package/nspr/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,nspr))
diff --git a/external/subpack/libs/nspr/patches/001-Makefile.in_rm_BUILD_STRING_and_BUILD_TIME.patch b/external/subpack/libs/nspr/patches/001-Makefile.in_rm_BUILD_STRING_and_BUILD_TIME.patch
new file mode 100644
index 0000000..4b4b6fb
--- /dev/null
+++ b/external/subpack/libs/nspr/patches/001-Makefile.in_rm_BUILD_STRING_and_BUILD_TIME.patch
@@ -0,0 +1,92 @@
+From 8a592e4ead4ed6befe6044da3dd2dc7523c33905 Mon Sep 17 00:00:00 2001
+From: Mingli Yu <Mingli.Yu@windriver.com>
+Date: Fri, 16 Nov 2018 13:52:49 +0800
+Subject: [PATCH] Makefile.in: remove _BUILD_STRING and _BUILD_TIME
+
+Remove _BUILD_STRING and _BUILD_TIME to avoid
+adding timestamp to _pl_bld.h which can result
+in adding timestamp in library file such as
+libnspr4.so.
+ $ readelf --wide --decompress --hex-dump=.rodata libnspr4.so
+ [snip]
+  0x00004000 32303138 2d31312d 31352030 353a3439 2018-11-15 05:49
+ [snip]
+
+Upstream-Status: Pending
+
+Signed-off-by: Mingli Yu <Mingli.Yu@windriver.com>
+---
+ lib/ds/Makefile.in        | 8 +-------
+ lib/libc/src/Makefile.in  | 8 +-------
+ lib/prstreams/Makefile.in | 8 +-------
+ pr/src/Makefile.in        | 8 +-------
+ 4 files changed, 4 insertions(+), 28 deletions(-)
+
+--- a/nspr/lib/ds/Makefile.in
++++ b/nspr/lib/ds/Makefile.in
+@@ -110,13 +110,7 @@ GARBAGE += $(TINC)
+ 
+ $(TINC):
+ 	@$(MAKE_OBJDIR)
+-	@$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+-	@if test ! -z "$(SH_NOW)"; then \
+-	    $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+-	else \
+-	    true; \
+-	fi
+-	@$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
++	@$(ECHO) '#define _PRODUCTION "$(PROD)"' > $(TINC)
+ 
+ 
+ $(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC)
+--- a/nspr/lib/libc/src/Makefile.in
++++ b/nspr/lib/libc/src/Makefile.in
+@@ -112,13 +112,7 @@ GARBAGE += $(TINC)
+ 
+ $(TINC):
+ 	@$(MAKE_OBJDIR)
+-	@$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+-	@if test ! -z "$(SH_NOW)"; then \
+-	    $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+-	else \
+-	    true; \
+-	fi
+-	@$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
++	@$(ECHO) '#define _PRODUCTION "$(PROD)"' > $(TINC)
+ 
+ 
+ $(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC)
+--- a/nspr/lib/prstreams/Makefile.in
++++ b/nspr/lib/prstreams/Makefile.in
+@@ -110,13 +110,7 @@ endif
+ 
+ $(TINC):
+ 	@$(MAKE_OBJDIR)
+-	@$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+-	@if test ! -z "$(SH_NOW)"; then \
+-	    $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+-	else \
+-	    true; \
+-	fi
+-	@$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
++	@$(ECHO) '#define _PRODUCTION "$(PROD)"' > $(TINC)
+ 
+ 
+ $(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC)
+--- a/nspr/pr/src/Makefile.in
++++ b/nspr/pr/src/Makefile.in
+@@ -306,13 +306,7 @@ GARBAGE += $(TINC)
+ 
+ $(TINC):
+ 	@$(MAKE_OBJDIR)
+-	@$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+-	@if test ! -z "$(SH_NOW)"; then \
+-	    $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+-	else \
+-	    true; \
+-	fi
+-	@$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
++	@$(ECHO) '#define _PRODUCTION "$(PROD)"' > $(TINC)
+ 
+ 
+ $(OBJDIR)/prvrsion.$(OBJ_SUFFIX): prvrsion.c $(TINC)
diff --git a/external/subpack/libs/nspr/patches/002-native_and_musl_fix.patch b/external/subpack/libs/nspr/patches/002-native_and_musl_fix.patch
new file mode 100644
index 0000000..d2c2d73
--- /dev/null
+++ b/external/subpack/libs/nspr/patches/002-native_and_musl_fix.patch
@@ -0,0 +1,23 @@
+--- a/nspr/config/config.mk
++++ b/nspr/config/config.mk
+@@ -126,6 +126,9 @@ endif
+ 
+ ifeq ($(USE_IPV6),1)
+ DEFINES += -D_PR_INET6
++ifeq ($(MUSL),1)
++CFLAGS += -D_PR_POLL_AVAILABLE -D_PR_HAVE_OFF64_T -D_PR_INET6 -D_PR_HAVE_INET_NTOP -D_PR_HAVE_GETHOSTBYNAME2 -D_PR_HAVE_GETADDRINFO -D_PR_INET6_PROBE
++endif
+ endif
+ 
+ ifeq ($(MOZ_UNICODE),1)
+--- a/nspr/config/Makefile.in
++++ b/nspr/config/Makefile.in
+@@ -30,7 +30,7 @@ CSRCS	= now.c
+ 
+ # This version hasn't been ported for us; the one in mozilla/config has
+ ifneq ($(OS_ARCH),OS2)
+-CSRCS  += nsinstall.c
++#CSRCS  += nsinstall.c
+  
+ PLSRCS	= nfspwd.pl
+ endif
diff --git a/external/subpack/libs/nss/Makefile b/external/subpack/libs/nss/Makefile
new file mode 100644
index 0000000..c96741f
--- /dev/null
+++ b/external/subpack/libs/nss/Makefile
@@ -0,0 +1,162 @@
+#
+# Copyright (C) 2019 Lucian Cristian
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nss
+PKG_VERSION:=3.93
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:= \
+    https://download.cdn.mozilla.net/pub/security/$(PKG_NAME)/releases/NSS_$(subst .,_,$(PKG_VERSION))_RTM/src \
+    https://archive.mozilla.org/pub/security/$(PKG_NAME)/releases/NSS_$(subst .,_,$(PKG_VERSION))_RTM/src
+PKG_HASH:=15f54bb72048eb105f8c0e936a04b899e74c3db9a19bbc1e00acee2af9476a8a
+
+PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
+PKG_LICENSE:=MPL-2.0
+PKG_LICENSE_FILES:=nss/COPYING
+PKG_CPE_ID:=cpe:/a:mozilla:network_security_services
+
+PKG_BUILD_PARALLEL:=0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libnss
+  SECTION:=libs
+  SUBMENU:=SSL
+  CATEGORY:=Libraries
+  TITLE:=Mozilla's SSL and TLS implementation
+  URL:=https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS
+  DEPENDS:=+libpthread +libsqlite3 +nspr
+endef
+
+define Package/nss-utils
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=Utilities for Mozilla's SSL and TLS implementation
+  URL:=https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS
+  DEPENDS:=+libnss
+endef
+
+define Package/libnss/description
+  Network Security Services (NSS) is a set of libraries designed to support
+  cross-platform development of security-enabled client and server applications.
+  Applications built with NSS can support SSL v2 and v3, TLS, PKCS 5, PKCS 7,
+  PKCS 11, PKCS 12, S/MIME, X.509 v3 certificates, and other security standards.
+endef
+
+CONFIGURE_PATH = ./nss
+MAKE_PATH = ./nss
+
+LBITS = $(shell $(TARGET_CC) -dM -E - </dev/null | grep -q "__LP64__" && echo 64 || echo 32)
+
+ifeq ($(LBITS),64)
+    export USE_64=1
+endif
+
+ifeq ($(CONFIG_CPU_TYPE),"xscale")
+TARGET_CFLAGS+= -mfloat-abi=softfp
+endif
+
+ifneq ($(findstring arm,$(CONFIG_ARCH)),)
+ifeq ($(findstring neon,$(CONFIG_CPU_TYPE)),)
+export NSS_DISABLE_ARM32_NEON
+endif
+endif
+
+export NATIVE_CC=$(HOSTCC)
+export NATIVE_FLAGS=$(HOST_CFLAGS)
+export NSS_ENABLE_WERROR=0
+
+MAKE_FLAGS += \
+	CROSS_COMPILE=1 \
+	BUILD_OPT=1 \
+	NSDISTMODE=copy \
+	NSS_DISABLE_GTESTS=1 \
+	NSS_USE_SYSTEM_SQLITE=1 \
+	OS_ARCH=Linux \
+	OS_TEST=$(ARCH) \
+	fpic="$(FPIC)" \
+	NSPR_INCLUDE_DIR=$(STAGING_DIR)/usr/include/nspr \
+	SEED_ONLY_DEV_URANDOM=1 \
+	NS_USE_GCC=1 \
+	FREEBL_NO_DEPEND=1 \
+	NSS_PKIX_NO_LDAP=1 \
+	ALLOW_OPT_CODE_SIZE=1 \
+	OPT_CODE_SIZE=1 \
+	OS_REL_CFLAGS="$(TARGET_CFLAGS)"
+
+#native compile nsinstall
+define Build/Configure
+	USE_NATIVE=1 OS_REL_CFLAGS="$(HOST_CFLAGS)" LDFLAGS="$(HOST_LDFLAGS)" \
+	CC="$(HOSTCC)" CPU_ARCH="$(HOST_ARCH)" \
+	    $(MAKE) -C $(PKG_BUILD_DIR)/nss/coreconf/nsinstall
+endef
+
+define Build/Compile
+	$(call Build/Compile/Default,nss_build_all)
+endef
+
+define Package/libnss/conffiles
+/etc/pki/nssdb
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) \
+	 $(2)/bin \
+	 $(1)/usr/bin \
+	 $(1)/usr/include/nss \
+	 $(1)/usr/lib \
+	 $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_BUILD_DIR)/dist/private/nss/*.h \
+	  $(1)/usr/include/nss/
+	$(CP) $(PKG_BUILD_DIR)/dist/public/nss/*.h \
+	  $(1)/usr/include/nss/
+	$(CP) $(PKG_BUILD_DIR)/dist/build_dir/lib/*.so \
+	  $(1)/usr/lib/
+	$(CP) $(PKG_BUILD_DIR)/nss/config/*.pc \
+	  $(1)/usr/lib/pkgconfig/
+	$(CP) $(PKG_BUILD_DIR)/nss/config/nss-config \
+	  $(1)/usr/bin/
+	$(SED) 's,^\(prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \
+	  $(1)/usr/bin/nss-config
+	$(LN) ../../usr/bin/nss-config \
+	  $(2)/bin/
+endef
+
+define Package/nss-utils/install
+	$(INSTALL_DIR) \
+	 $(1)/usr/bin
+	$(CP) $(PKG_BUILD_DIR)/dist/build_dir/bin/certutil $(1)/usr/bin
+	$(CP) $(PKG_BUILD_DIR)/dist/build_dir/bin/pk12util $(1)/usr/bin
+endef
+
+#for now pack only libreswan needed libs
+define Package/libnss/install
+	$(INSTALL_DIR) \
+	 $(1)/usr/lib \
+	 $(1)/etc/pki/nssdb \
+	 $(1)/etc/ipsec.d
+
+	$(CP) $(PKG_BUILD_DIR)/dist/build_dir/lib/libfreebl3.so $(1)/usr/lib/
+	$(CP) $(PKG_BUILD_DIR)/dist/build_dir/lib/libnss3.so $(1)/usr/lib/
+	$(CP) $(PKG_BUILD_DIR)/dist/build_dir/lib/libnssckbi.so $(1)/usr/lib/
+	$(CP) $(PKG_BUILD_DIR)/dist/build_dir/lib/libnssutil3.so $(1)/usr/lib/
+	$(CP) $(PKG_BUILD_DIR)/dist/build_dir/lib/libsmime3.so $(1)/usr/lib/
+	$(CP) $(PKG_BUILD_DIR)/dist/build_dir/lib/libsoftokn3.so $(1)/usr/lib/
+	$(CP) $(PKG_BUILD_DIR)/dist/build_dir/lib/libssl3.so $(1)/usr/lib/
+#	Provide databases with a blank certificate
+	$(CP)	./files/blank-cert9.db $(1)/etc/pki/nssdb/cert9.db
+	$(CP)	./files/blank-key4.db $(1)/etc/pki/nssdb/key4.db
+	$(CP)	./files/system-pkcs11.txt $(1)/etc/pki/nssdb/pkcs11.txt
+	ln -s /etc/pki/nssdb/cert9.db $(1)/etc/ipsec.d/cert9.db
+	ln -s /etc/pki/nssdb/key4.db $(1)/etc/ipsec.d/key4.db
+	ln -s /etc/pki/nssdb/pkcs11.txt $(1)/etc/ipsec.d/pkcs11.txt
+endef
+
+$(eval $(call BuildPackage,nss-utils))
+$(eval $(call BuildPackage,libnss))
diff --git a/external/subpack/libs/nss/files/blank-cert9.db b/external/subpack/libs/nss/files/blank-cert9.db
new file mode 100644
index 0000000..7d4bcf2
--- /dev/null
+++ b/external/subpack/libs/nss/files/blank-cert9.db
Binary files differ
diff --git a/external/subpack/libs/nss/files/blank-key4.db b/external/subpack/libs/nss/files/blank-key4.db
new file mode 100644
index 0000000..d47f08d
--- /dev/null
+++ b/external/subpack/libs/nss/files/blank-key4.db
Binary files differ
diff --git a/external/subpack/libs/nss/files/system-pkcs11.txt b/external/subpack/libs/nss/files/system-pkcs11.txt
new file mode 100644
index 0000000..1a264e9
--- /dev/null
+++ b/external/subpack/libs/nss/files/system-pkcs11.txt
@@ -0,0 +1,5 @@
+library=
+name=NSS Internal PKCS #11 Module
+parameters=configdir='sql:/etc/pki/nssdb' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' 
+NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[ECC,RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30})
+
diff --git a/external/subpack/libs/nss/patches/001-nss_standalone.patch b/external/subpack/libs/nss/patches/001-nss_standalone.patch
new file mode 100644
index 0000000..8a2c9d6
--- /dev/null
+++ b/external/subpack/libs/nss/patches/001-nss_standalone.patch
@@ -0,0 +1,247 @@
+Submitted By:            DJ Lucas <dj_AT_linuxfromscratch_DOT_org>
+Date:                    2016-12-27
+Initial Package Version: 3.12.4
+Upstream Status:         Not applicable
+Origin:                  Self, rediffed for nss-3.28.
+Description:             Adds auto-generated nss.pc and nss-config script, and
+                         allows building without nspr in the source tree.
+                         For 3.40.1, Requires: updated to nspr >= 4.20.
+                         For 3.46.1, Requires: updated to nspr >= 4.21.
+                         For 3.48, Requires: updated to nspr >= 4.24.
+                         For 3.51.1, Requires: updated to nspr >= 4.25.
+
+--- a/nss/Makefile
++++ b/nss/Makefile
+@@ -48,7 +48,6 @@ include $(CORE_DEPTH)/coreconf/rules.mk
+ #######################################################################
+ 
+ nss_build_all:
+-	$(MAKE) build_nspr
+ 	$(MAKE) all
+ 	$(MAKE) latest
+ 
+--- /dev/null
++++ b/nss/config/Makefile
+@@ -0,0 +1,40 @@
++CORE_DEPTH = ..
++DEPTH      = ..
++
++include $(CORE_DEPTH)/coreconf/config.mk
++
++NSS_MAJOR_VERSION = `grep "NSS_VMAJOR" ../lib/nss/nss.h | awk '{print $$3}'`
++NSS_MINOR_VERSION = `grep "NSS_VMINOR" ../lib/nss/nss.h | awk '{print $$3}'`
++NSS_PATCH_VERSION = `grep "NSS_VPATCH" ../lib/nss/nss.h | awk '{print $$3}'`
++PREFIX = /usr
++
++all: export libs
++
++export:
++	# Create the nss.pc file
++	mkdir -p $(DIST)/lib/pkgconfig
++	sed -e "s,@prefix@,$(PREFIX)," \
++	    -e "s,@exec_prefix@,\$${prefix}," \
++	    -e "s,@libdir@,\$${prefix}/lib," \
++	    -e "s,@includedir@,\$${prefix}/include/nss," \
++	    -e "s,@NSS_MAJOR_VERSION@,$(NSS_MAJOR_VERSION),g" \
++	    -e "s,@NSS_MINOR_VERSION@,$(NSS_MINOR_VERSION)," \
++	    -e "s,@NSS_PATCH_VERSION@,$(NSS_PATCH_VERSION)," \
++	    nss.pc.in > nss.pc
++	chmod 0644 nss.pc
++	ln -sf ../../../../nss/config/nss.pc $(DIST)/lib/pkgconfig
++
++	# Create the nss-config script
++	mkdir -p $(DIST)/bin
++	sed -e "s,@prefix@,$(PREFIX)," \
++	    -e "s,@NSS_MAJOR_VERSION@,$(NSS_MAJOR_VERSION)," \
++	    -e "s,@NSS_MINOR_VERSION@,$(NSS_MINOR_VERSION)," \
++	    -e "s,@NSS_PATCH_VERSION@,$(NSS_PATCH_VERSION)," \
++	    nss-config.in > nss-config
++	chmod 0755 nss-config
++	ln -sf ../../../nss/config/nss-config $(DIST)/bin
++
++libs:
++
++dummy: all export libs
++
+--- /dev/null
++++ b/nss/config/nss-config.in
+@@ -0,0 +1,153 @@
++#!/bin/sh
++
++prefix=@prefix@
++
++major_version=@NSS_MAJOR_VERSION@
++minor_version=@NSS_MINOR_VERSION@
++patch_version=@NSS_PATCH_VERSION@
++
++usage()
++{
++	cat <<EOF
++Usage: nss-config [OPTIONS] [LIBRARIES]
++Options:
++	[--prefix[=DIR]]
++	[--exec-prefix[=DIR]]
++	[--includedir[=DIR]]
++	[--libdir[=DIR]]
++	[--version]
++	[--libs]
++	[--cflags]
++Dynamic Libraries:
++	nss
++	nssutil
++	smime
++	ssl
++	softokn
++EOF
++	exit $1
++}
++
++if test $# -eq 0; then
++	usage 1 1>&2
++fi
++
++lib_nss=yes
++lib_nssutil=yes
++lib_smime=yes
++lib_ssl=yes
++lib_softokn=yes
++
++while test $# -gt 0; do
++  case "$1" in
++  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
++  *) optarg= ;;
++  esac
++
++  case $1 in
++    --prefix=*)
++      prefix=$optarg
++      ;;
++    --prefix)
++      echo_prefix=yes
++      ;;
++    --exec-prefix=*)
++      exec_prefix=$optarg
++      ;;
++    --exec-prefix)
++      echo_exec_prefix=yes
++      ;;
++    --includedir=*)
++      includedir=$optarg
++      ;;
++    --includedir)
++      echo_includedir=yes
++      ;;
++    --libdir=*)
++      libdir=$optarg
++      ;;
++    --libdir)
++      echo_libdir=yes
++      ;;
++    --version)
++      echo ${major_version}.${minor_version}.${patch_version}
++      ;;
++    --cflags)
++      echo_cflags=yes
++      ;;
++    --libs)
++      echo_libs=yes
++      ;;
++    nss)
++      lib_nss=yes
++      ;;
++    nssutil)
++      lib_nssutil=yes
++      ;;
++    smime)
++      lib_smime=yes
++      ;;
++    ssl)
++      lib_ssl=yes
++      ;;
++    softokn)
++      lib_softokn=yes
++      ;;
++    *)
++      usage 1 1>&2
++      ;;
++  esac
++  shift
++done
++
++# Set variables that may be dependent upon other variables
++if test -z "$exec_prefix"; then
++    exec_prefix=`pkg-config --variable=exec_prefix nss`
++fi
++if test -z "$includedir"; then
++    includedir=`pkg-config --variable=includedir nss`
++fi
++if test -z "$libdir"; then
++    libdir=`pkg-config --variable=libdir nss`
++fi
++
++if test "$echo_prefix" = "yes"; then
++    echo $prefix
++fi
++
++if test "$echo_exec_prefix" = "yes"; then
++    echo $exec_prefix
++fi
++
++if test "$echo_includedir" = "yes"; then
++    echo $includedir
++fi
++
++if test "$echo_libdir" = "yes"; then
++    echo $libdir
++fi
++
++if test "$echo_cflags" = "yes"; then
++    echo -I$includedir
++fi
++
++if test "$echo_libs" = "yes"; then
++      libdirs="-L$libdir"
++      if test -n "$lib_nss"; then
++	libdirs="$libdirs -lnss${major_version}"
++      fi
++      if test -n "$lib_nssutil"; then
++        libdirs="$libdirs -lnssutil${major_version}"
++      fi
++      if test -n "$lib_smime"; then
++	libdirs="$libdirs -lsmime${major_version}"
++      fi
++      if test -n "$lib_ssl"; then
++	libdirs="$libdirs -lssl${major_version}"
++      fi
++      if test -n "$lib_softokn"; then
++        libdirs="$libdirs -lsoftokn${major_version}"
++      fi
++      echo $libdirs
++fi      
++
+--- /dev/null
++++ b/nss/config/nss.pc.in
+@@ -0,0 +1,12 @@
++prefix=@prefix@
++exec_prefix=@exec_prefix@
++libdir=@libdir@
++includedir=@includedir@
++
++Name: NSS
++Description: Network Security Services
++Version: @NSS_MAJOR_VERSION@.@NSS_MINOR_VERSION@.@NSS_PATCH_VERSION@
++Requires: nspr >= 4.25
++Libs: -L@libdir@ -lnss@NSS_MAJOR_VERSION@ -lnssutil@NSS_MAJOR_VERSION@ -lsmime@NSS_MAJOR_VERSION@ -lssl@NSS_MAJOR_VERSION@ -lsoftokn@NSS_MAJOR_VERSION@
++Cflags: -I${includedir}
++
+--- a/nss/manifest.mn
++++ b/nss/manifest.mn
+@@ -10,7 +10,7 @@ IMPORTS =	nspr20/v4.8 \
+ 
+ RELEASE = nss
+ 
+-DIRS = coreconf lib cmd cpputil gtests
++DIRS = coreconf lib cmd cpputil config
+ 
+ HAVE_ALL_TARGET := 1
+ 
diff --git a/external/subpack/libs/nss/patches/002-os_test.patch b/external/subpack/libs/nss/patches/002-os_test.patch
new file mode 100644
index 0000000..648f571
--- /dev/null
+++ b/external/subpack/libs/nss/patches/002-os_test.patch
@@ -0,0 +1,18 @@
+--- a/nss/coreconf/arch.mk
++++ b/nss/coreconf/arch.mk
+@@ -20,13 +20,13 @@
+ # Macros for getting the OS architecture
+ #
+ 
+-OS_ARCH := $(subst /,_,$(shell uname -s))
++OS_ARCH ?= $(subst /,_,$(shell uname -s))
+ 
+ #
+ # Attempt to differentiate between sparc and x86 Solaris
+ #
+ 
+-OS_TEST := $(shell uname -m)
++OS_TEST ?= $(shell uname -m)
+ ifeq ($(OS_TEST),i86pc)
+     OS_RELEASE := $(shell uname -r)_$(OS_TEST)
+ else
diff --git a/external/subpack/libs/nss/patches/003-openwrt_fix.patch b/external/subpack/libs/nss/patches/003-openwrt_fix.patch
new file mode 100644
index 0000000..c7a3d83
--- /dev/null
+++ b/external/subpack/libs/nss/patches/003-openwrt_fix.patch
@@ -0,0 +1,84 @@
+--- a/nss/lib/dbm/src/dirent.h
++++ b/nss/lib/dbm/src/dirent.h
+@@ -30,7 +30,7 @@
+ #define MAXNAMLEN FILENAME_MAX
+ 
+ #else
+-#include <param.h>
++#include <sys/param.h>
+ #endif
+ #endif
+ 
+--- a/nss/coreconf/rules.mk
++++ b/nss/coreconf/rules.mk
+@@ -176,7 +176,7 @@ $(LIBRARY): $(OBJS) | $$(@D)/d
+ ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET)))
+ 	$(AR) $(subst /,\\,$(OBJS))
+ else
+-	$(AR) $(OBJS)
++	$(AR) rcs $@ $(OBJS)
+ endif
+ 	$(RANLIB) $@
+ 
+--- a/nss/coreconf/arch.mk
++++ b/nss/coreconf/arch.mk
+@@ -284,7 +284,7 @@ else
+     OBJDIR_NAME_COMPILER = $(COMPILER_TAG)
+ endif
+ OBJDIR_NAME_BASE = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(OBJDIR_NAME_COMPILER)$(LIBC_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG)
+-OBJDIR_NAME = $(OBJDIR_NAME_BASE).OBJ
++OBJDIR_NAME = build_dir
+ 
+ 
+ ifeq (,$(filter-out WIN%,$(OS_TARGET)))
+--- a/nss/coreconf/Linux.mk
++++ b/nss/coreconf/Linux.mk
+@@ -114,11 +114,6 @@ LIBC_TAG		= _glibc
+ endif
+ 
+ ifdef BUILD_OPT
+-ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
+-	OPTIMIZER = -Os
+-else
+-	OPTIMIZER = -O2
+-endif
+ ifdef MOZ_DEBUG_SYMBOLS
+ 	ifdef MOZ_DEBUG_FLAGS
+ 		OPTIMIZER += $(MOZ_DEBUG_FLAGS)
+@@ -150,7 +145,8 @@ ifdef USE_PTHREADS
+ 	DEFINES		+= -D_REENTRANT
+ endif
+ 
+-DSO_CFLAGS		= -fPIC
++ifndef USE_NATIVE
++DSO_CFLAGS		= $(fpic)
+ DSO_LDOPTS		= -shared $(ARCHFLAG) -Wl,--gc-sections
+ # The linker on Red Hat Linux 7.2 and RHEL 2.1 (GNU ld version 2.11.90.0.8)
+ # incorrectly reports undefined references in the libraries we link with, so
+@@ -166,6 +162,7 @@ LDFLAGS		   += $(ARCHFLAG) -z noexecstac
+ ifdef _SBOX_DIR
+ LDFLAGS			+= -Wl,-rpath-link,/usr/lib:/lib
+ endif
++endif
+ 
+ G++INCLUDES		= -I/usr/include/g++
+ 
+@@ -201,7 +198,7 @@ RPATH = -Wl,-rpath,'$$ORIGIN:/opt/sun/pr
+ endif
+ endif
+ 
+-MKSHLIB         = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) $(RPATH)
++MKSHLIB         = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) $(RPATH) $(fpic) -Wl,--gc-sections,--as-needed
+ 
+ ifdef MAPFILE
+ 	MKSHLIB += -Wl,--version-script,$(MAPFILE)
+--- a/nss/coreconf/UNIX.mk
++++ b/nss/coreconf/UNIX.mk
+@@ -10,7 +10,6 @@ AR          = ar cr $@
+ LDOPTS     += -L$(SOURCE_LIB_DIR)
+ 
+ ifdef BUILD_OPT
+-	OPTIMIZER  += -O
+ 	DEFINES    += -UDEBUG -DNDEBUG
+ else
+ 	OPTIMIZER  += -g
diff --git a/external/subpack/libs/nss/patches/010-nanosleep.patch b/external/subpack/libs/nss/patches/010-nanosleep.patch
new file mode 100644
index 0000000..414ebf3
--- /dev/null
+++ b/external/subpack/libs/nss/patches/010-nanosleep.patch
@@ -0,0 +1,33 @@
+--- a/nss/lib/freebl/stubs.c
++++ b/nss/lib/freebl/stubs.c
+@@ -506,7 +506,8 @@ extern PRStatus
+ PR_Sleep_stub(PRIntervalTime ticks)
+ {
+     STUB_SAFE_CALL1(PR_Sleep, ticks);
+-    usleep(ticks * 1000);
++    const struct timespec req = {0, ticks * 1000 * 1000};
++    nanosleep(&req, NULL);
+     return PR_SUCCESS;
+ }
+ 
+--- a/nss/lib/sqlite/sqlite3.c
++++ b/nss/lib/sqlite/sqlite3.c
+@@ -39626,7 +39626,8 @@ static int proxyConchLock(unixFile *pFil
+       
+       if( nTries==1 ){
+         conchModTime = buf.st_mtimespec;
+-        usleep(500000); /* wait 0.5 sec and try the lock again*/
++        const struct timespec req = {0, 500 * 1000 * 1000};
++        nanosleep(&req, NULL); /* wait 0.5 sec and try the lock again*/
+         continue;  
+       }
+ 
+@@ -39652,7 +39653,7 @@ static int proxyConchLock(unixFile *pFil
+           /* don't break the lock on short read or a version mismatch */
+           return SQLITE_BUSY;
+         }
+-        usleep(10000000); /* wait 10 sec and try the lock again */
++        sleep(10); /* wait 10 sec and try the lock again */
+         continue; 
+       }
+       
diff --git a/external/subpack/libs/nss/patches/020-getopt.patch b/external/subpack/libs/nss/patches/020-getopt.patch
new file mode 100644
index 0000000..f6239e0
--- /dev/null
+++ b/external/subpack/libs/nss/patches/020-getopt.patch
@@ -0,0 +1,12 @@
+--- a/nss/coreconf/nsinstall/nsinstall.c
++++ b/nss/coreconf/nsinstall/nsinstall.c
+@@ -32,8 +32,8 @@ typedef unsigned int mode_t;
+ 
+ #define HAVE_FCHMOD
+ 
+-#ifdef LINUX
+ #include <getopt.h>
++#ifdef LINUX
+ #endif
+ 
+ #if defined(SCO) || defined(UNIXWARE) || defined(SNI) || defined(NCR) || defined(NEC)
diff --git a/external/subpack/libs/oniguruma/Makefile b/external/subpack/libs/oniguruma/Makefile
new file mode 100644
index 0000000..d40a5c3
--- /dev/null
+++ b/external/subpack/libs/oniguruma/Makefile
@@ -0,0 +1,56 @@
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=oniguruma
+PKG_VERSION:=6.9.9
+PKG_RELEASE:=1
+
+PKG_SOURCE:=onig-v$(subst _,-,$(PKG_VERSION)).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/kkos/oniguruma/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=001aa1202e78448f4c0bf1a48c76e556876b36f16d92ce3207eccfd61d99f2a0
+
+PKG_MAINTAINER:=Eneas U de Queiroz <cotequeiroz@gmail.com>
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:oniguruma_project:oniguruma
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/oniguruma
+    SECTION:=libs
+    CATEGORY:=Libraries
+    TITLE:=Regular expression library for different character encodings
+    URL:=https://github.com/kkos/oniguruma
+    ABI_VERSION:=5
+endef
+
+define Package/oniguruma/description
+   Oniguruma is a modern and flexible regular expressions library.
+   It encompasses features from different regular expression implementations that
+   traditionally exist in different languages.
+
+   Character encoding can be specified per regular expression object.
+endef
+
+CONFIGURE_ARGS += --enable-posix-api
+
+define Package/oniguruma/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/libonig.so.$(ABI_VERSION) $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/{include,lib}
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+	$(SED) 's,/usr,$(STAGING_DIR)/usr,g' $(1)/usr/lib/pkgconfig/oniguruma.pc
+endef
+
+$(eval $(call BuildPackage,oniguruma))
diff --git a/external/subpack/libs/openblas/Makefile b/external/subpack/libs/openblas/Makefile
new file mode 100644
index 0000000..cc38425
--- /dev/null
+++ b/external/subpack/libs/openblas/Makefile
@@ -0,0 +1,125 @@
+#
+# Copyright (C) 2021 Alexandru Ardelean <ardeleanalex@gmail.com>
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=OpenBLAS
+PKG_VERSION:=0.3.28
+PKG_RELEASE:=1
+
+PKG_SOURCE:=OpenBLAS-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/OpenMathLib/OpenBLAS/releases/download/v$(PKG_VERSION)/
+PKG_HASH:=f1003466ad074e9b0c8d421a204121100b0751c96fc6fcf3d1456bd12f8a00a1
+PKG_LICENSE:=BSD-3-Clause
+PKG_CPE_ID:=cpe:/a:openblas_project:openblas
+PKG_MAINTAINER:=Alexandru Ardelean <ardeleanalex@gmail.com>
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/openblas
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=An optimized library for BLAS (Basic Linear Algebra Subprograms)
+  URL:=https://www.openblas.net/
+  DEPENDS:= \
+       @!arc \
+       @!powerpc \
+       @!SOFT_FLOAT \
+       +INSTALL_GFORTRAN:libgfortran
+endef
+
+define Package/openblas/description
+  OpenBLAS is an optimized BLAS (Basic Linear Algebra Subprograms) library
+  based on GotoBLAS2 1.13 BSD version.
+endef
+
+define Package/openblas/config
+menu "Configuration"
+depends on PACKAGE_openblas
+
+config OPENBLAS_TARGET_OVERRIDE
+	string
+	prompt "Manual CPU target override (from the OpenBLAS TargetList.txt file)"
+
+endmenu
+endef
+
+OPENBLAS_TARGET=$(call qstrip,$(CONFIG_OPENBLAS_TARGET_OVERRIDE))
+
+ifeq ($(OPENBLAS_TARGET),)
+# initialize to GENERIC as default
+OPENBLAS_TARGET:=GENERIC
+
+ifneq ($(findstring cortex-a9,$(CONFIG_CPU_TYPE)),)
+	ifneq ($(findstring neon,$(CONFIG_CPU_TYPE)),)
+		# CORTEXA9 relies on NEON
+		OPENBLAS_TARGET:=CORTEXA9
+	else
+		# Fallback for CPUs without NEON
+		OPENBLAS_TARGET:=ARMV7
+	endif
+else ifneq ($(findstring cortex-a15,$(CONFIG_CPU_TYPE)),)
+	OPENBLAS_TARGET:=CORTEXA15
+else ifneq ($(findstring cortex-a53,$(CONFIG_CPU_TYPE)),)
+	OPENBLAS_TARGET:=CORTEXA53
+else ifneq ($(findstring cortex-a72,$(CONFIG_CPU_TYPE)),)
+	OPENBLAS_TARGET:=CORTEXA72
+else ifeq ($(ARCH),aarch64)
+  OPENBLAS_TARGET:=ARMV8
+else ifeq ($(ARCH),arm)
+  OPENBLAS_TARGET:=ARMV5
+else ifeq ($(ARCH),mips)
+  OPENBLAS_TARGET:=MIPS24K
+else ifeq ($(ARCH),mipsel)
+  OPENBLAS_TARGET:=MIPS24K
+else ifeq ($(ARCH),powerpc)
+  OPENBLAS_TARGET:=PPC440
+else ifeq ($(ARCH),riscv64)
+  OPENBLAS_TARGET:=RISCV64_GENERIC
+endif
+endif # ifeq ($(OPENBLAS_TARGET),)
+
+ifeq ($(CONFIG_ARCH_64BIT),y)
+OPENBLAS_BINARY:=64
+else
+OPENBLAS_BINARY:=32
+endif
+
+MAKE_FLAGS += \
+	CROSS=1 \
+	CC=$(TARGET_CC_NOCACHE) \
+	CXX=$(TARGET_CXX_NOCACHE) \
+	HOSTCC=$(HOSTCC_NOCACHE) \
+	CROSS_SUFFIX=$(TARGET_CROSS) \
+	BINARY=$(OPENBLAS_BINARY) \
+	MAKE_NB_JOBS=-1 \
+	NUM_THREADS=2 \
+	PREFIX=/usr \
+	COMMON_OPT="" \
+	ONLY_CBLAS=1 \
+	TARGET=$(call qstrip,$(OPENBLAS_TARGET))
+
+ifneq ($(CONFIG_INSTALL_GFORTRAN),y)
+MAKE_FLAGS += NOFORTRAN=1
+endif
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/openblas.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/openblas.pc
+endef
+
+define Package/openblas/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libopenblas*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,openblas))
diff --git a/external/subpack/libs/openldap/Config.in b/external/subpack/libs/openldap/Config.in
new file mode 100644
index 0000000..a886bb5
--- /dev/null
+++ b/external/subpack/libs/openldap/Config.in
@@ -0,0 +1,44 @@
+if PACKAGE_libopenldap
+	config OPENLDAP_DEBUG
+		bool "Enable debugging information"
+		default y
+		help
+		  Enable debugging information. This option must be enabled
+		  for the loglevel directive to work.
+	config OPENLDAP_CRYPT
+		bool "Crypt(3) passwords support"
+		default n
+		help
+		  With crypt(3) password storage scheme enabled, OpenLDAP can
+		  receive and store SHA-256 and SHA-512 password hashes from
+		  Samba AD-DC. If this option is disabled, synchronization of
+		  passwords between Samba AD-DC (v4.5 and above) and OpenLDAP
+		  requires use of cleartext passwords.
+		  To enable crypt(3) password synchronization functionality:
+		  1. Re-include crypt(3) support in OpenWRT by enabling 'Include
+		  crypt() support for SHA256, SHA512 and Blowfish ciphers' option
+		  in "Advanced configuration options (for developers)" ->
+		  "Toolchain Options".
+		  2. Provision AD-DC with 'password hash userPassword schemes'
+		  option. For more information, see smb.conf manpage for details
+		  on 'password hash userPassword schemes'.
+		  3. Use a script to synchronize passwords from AD-DC to
+		  OpenLDAP. See samba-tool manpage for 'user syncpasswords'.
+	config OPENLDAP_MONITOR
+		bool "Enable monitor backend"
+		default n
+		help
+		  Enable monitor backend to obtain information about the running
+		  status of the daemon. See OpenLDAP documentation for more
+		  information.
+	config OPENLDAP_DB47
+		bool "Berkeley DB support"
+		default n
+		help
+		  Enable Berkeley DB support (BDB).
+	config OPENLDAP_ICU
+		bool "ICU support"
+		default n
+		help
+		  Enable ICU (International Components for Unicode) support.
+endif
diff --git a/external/subpack/libs/openldap/Makefile b/external/subpack/libs/openldap/Makefile
new file mode 100644
index 0000000..f23d122
--- /dev/null
+++ b/external/subpack/libs/openldap/Makefile
@@ -0,0 +1,182 @@
+#
+# Copyright (C) 2006-2015 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:=openldap
+PKG_VERSION:=2.6.8
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tgz
+PKG_SOURCE_URL:=https://mirror.eu.oneandone.net/software/openldap/openldap-release/ \
+	https://www.openldap.org/software/download/OpenLDAP/openldap-release/
+PKG_HASH:=48969323e94e3be3b03c6a132942dcba7ef8d545f2ad35401709019f696c3c4e
+PKG_LICENSE:=OLDAP-2.8
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:openldap:openldap
+
+PKG_FIXUP:=autoreconf
+
+# Fixes the following:
+# libtool: Version mismatch error.  This is libtool 2.4.2, but the
+# libtool: definition of this LT_INIT comes from libtool 2.4.6.
+# libtool: You should recreate aclocal.m4 with macros from libtool 2.4.2
+# libtool: and run autoconf again.
+PKG_REMOVE_FILES:=build/ltversion.m4
+
+PKG_CONFIG_DEPENDS := \
+        CONFIG_OPENLDAP_DEBUG \
+        CONFIG_OPENLDAP_CRYPT \
+        CONFIG_OPENLDAP_MONITOR \
+        CONFIG_OPENLDAP_DB47 \
+        CONFIG_OPENLDAP_ICU
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libopenldap/Default
+  SECTION:=net
+  CATEGORY:=Network
+  SUBMENU:=OpenLDAP
+  TITLE:=LDAP directory suite
+  URL:=https://www.openldap.org/
+  MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+endef
+
+define Package/libopenldap
+  $(call Package/libopenldap/Default)
+  MENU:=1
+  DEPENDS:=+libopenssl +libsasl2 +libpthread +libuuid +OPENLDAP_DB47:libdb47 +OPENLDAP_ICU:icu
+  TITLE+= (libraries)
+endef
+
+define Package/openldap/config
+  source "$(SOURCE)/Config.in"
+endef
+
+define Package/libopenldap/description
+OpenLDAP Software is an open source implementation of the Lightweight Directory Access Protocol (LDAP). This package contains the shared LDAP client libraries, needed by other programs.
+endef
+
+define Package/libopenldap/conffiles
+/etc/openldap/ldap.conf
+endef
+
+define Package/openldap-utils
+  $(call Package/libopenldap/Default)
+  DEPENDS:=+libopenldap
+  TITLE+= (utilities)
+endef
+
+define Package/openldap-utils/description
+This package contains client programs required to access LDAP servers.
+endef
+
+define Package/openldap-server
+  $(call Package/libopenldap/Default)
+  DEPENDS:=+libopenldap +libuuid
+  TITLE+= (server)
+endef
+
+define Package/openldap-server/description
+This package contains server programs required to provide LDAP services.
+endef
+
+define Package/openldap-server/conffiles
+/etc/openldap/slapd.conf
+/etc/init.d/ldap
+endef
+
+TARGET_CFLAGS += $(FPIC) -lpthread \
+	-DURANDOM_DEVICE=\\\"/dev/urandom\\\"
+
+CONFIGURE_ARGS += \
+	--enable-dynamic \
+	--enable-syslog \
+	--with-cyrus-sasl \
+	--with-threads \
+	--with-tls \
+	--with-yielding-select="yes" \
+	--enable-null \
+	--disable-relay
+
+
+ifdef CONFIG_OPENLDAP_CRYPT
+	CONFIGURE_ARGS+= --enable-crypt
+else
+	CONFIGURE_ARGS+= --disable-crypt
+endif
+
+ifdef CONFIG_OPENLDAP_MONITOR
+	CONFIGURE_ARGS+= --enable-monitor
+else
+	CONFIGURE_ARGS+= --disable-monitor
+endif
+
+ifdef CONFIG_OPENLDAP_DEBUG
+	CONFIGURE_ARGS+= --enable-debug
+else
+	CONFIGURE_ARGS+= --disable-debug
+endif
+
+ifdef CONFIG_OPENLDAP_DB47
+	CONFIGURE_ARGS+= \
+		--enable-bdb \
+		--enable-hdb
+else
+	CONFIGURE_ARGS+= \
+		--disable-bdb \
+		--disable-hdb
+endif
+
+ifndef CONFIG_OPENLDAP_ICU
+	CONFIGURE_VARS += \
+		ol_cv_lib_icu="no"
+endif
+
+define Build/Compile
+	$(MAKE) -C $(PKG_BUILD_DIR) \
+		DESTDIR="$(PKG_INSTALL_DIR)" \
+		HOSTCC="$(HOSTCC)" \
+		depend all install
+	cd $(PKG_BUILD_DIR)/libraries/liblmdb && $(MAKE) $(CONFIGURE_VARS)
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/{lber,ldap}*.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib{lber,ldap}*.{a,so*} $(1)/usr/lib/
+endef
+
+define Package/libopenldap/install
+	$(INSTALL_DIR) $(1)/etc/openldap $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/etc/openldap/ldap.conf $(1)/etc/openldap/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/lib{lber,ldap}*.so.* $(1)/usr/lib/
+endef
+
+define Package/openldap-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/ldap* $(1)/usr/bin/
+endef
+
+define Package/openldap-server/install
+	$(INSTALL_DIR) $(1)/etc/init.d
+	$(INSTALL_BIN) ./files/ldap.init $(1)/etc/init.d/ldap
+	$(INSTALL_DIR) $(1)/etc/openldap/schema
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/etc/openldap/schema/* $(1)/etc/openldap/schema/
+	$(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/openldap/slapd.conf $(1)/etc/openldap/
+	$(INSTALL_DIR) $(1)/usr/sbin
+	# NB: OpenLDAP installs slapd into libexecdir, not sbindir
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/lib/slapd $(1)/usr/sbin/
+	$(eval SLAPTOOLS := slapadd slapcat slapdn slapindex slappasswd slaptest slapauth slapacl slapschema)
+	for i in $(SLAPTOOLS); do \
+		$(LN) ./slapd $(1)/usr/sbin/$$$$i; \
+	done
+endef
+
+$(eval $(call BuildPackage,libopenldap))
+$(eval $(call BuildPackage,openldap-utils))
+$(eval $(call BuildPackage,openldap-server))
diff --git a/external/subpack/libs/openldap/files/ldap.init b/external/subpack/libs/openldap/files/ldap.init
new file mode 100644
index 0000000..2209e76
--- /dev/null
+++ b/external/subpack/libs/openldap/files/ldap.init
@@ -0,0 +1,19 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2009-2011 OpenWrt.org
+
+START=60
+
+SERVICE_USE_PID=1
+
+start() {
+	mkdir -m 0755 -p /var/openldap-data
+	service_start /usr/sbin/slapd -h "ldap://localhost/ ldaps:///"
+}
+
+stop() {
+	service_stop /usr/sbin/slapd
+}
+
+reload() {
+	service_reload /usr/sbin/slapd
+}
diff --git a/external/subpack/libs/openldap/patches/001-automake-compat.patch b/external/subpack/libs/openldap/patches/001-automake-compat.patch
new file mode 100644
index 0000000..d1e4b2a
--- /dev/null
+++ b/external/subpack/libs/openldap/patches/001-automake-compat.patch
@@ -0,0 +1,296 @@
+--- a/clients/tools/Makefile.in
++++ b/clients/tools/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS	= ldapsearch.c ldapmodify.c ldapdelete.c ldapmodrdn.c \
+ 		ldappasswd.c ldapwhoami.c ldapvc.c ldapcompare.c \
+ 		ldapexop.c ldapurl.c common.c
+--- a/libraries/liblber/Makefile.in
++++ b/libraries/liblber/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ LIBRARY = liblber.la
+ 
+ NT_SRCS = nt_err.c
+--- a/libraries/libldap/Makefile.in
++++ b/libraries/libldap/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ LIBRARY = libldap.la
+ 
+ PROGRAMS = apitest dntest ftest ltest urltest testavl
+--- a/libraries/liblunicode/Makefile.in
++++ b/libraries/liblunicode/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ LIBRARY = liblunicode.a
+ 
+ XXDIR = $(srcdir)/ucdata/
+--- a/libraries/liblutil/Makefile.in
++++ b/libraries/liblutil/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ LIBRARY	= liblutil.a
+ 
+ LDAP_INCDIR= ../../include       
+--- a/libraries/librewrite/Makefile.in
++++ b/libraries/librewrite/Makefile.in
+@@ -16,6 +16,8 @@
+ ## Copyright 2000-2001 Pierangelo Masarati <ando@sys-net.it>
+ ##
+ 
++SHELL = @SHELL@
++
+ SRCS = config.c context.c info.c ldapmap.c map.c params.c rule.c \
+ 	session.c subst.c var.c xmap.c escapemap.c \
+ 	parse.c rewrite.c
+--- a/libraries/Makefile.in
++++ b/libraries/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SUBDIRS= \
+ 	liblutil \
+ 	liblber \
+--- a/servers/lloadd/Makefile.in
++++ b/servers/lloadd/Makefile.in
+@@ -13,6 +13,7 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
+ 
+ XSRCS	= version.c
+ 
+--- a/servers/slapd/back-asyncmeta/Makefile.in
++++ b/servers/slapd/back-asyncmeta/Makefile.in
+@@ -19,6 +19,8 @@
+ ## based on back-meta module for inclusion in OpenLDAP Software.
+ ## This work was sponsored by Ericsson
+ 
++SHELL = @SHELL@
++
+ SRCS	= init.c config.c search.c message_queue.c bind.c add.c compare.c \
+ 		delete.c modify.c modrdn.c map.c \
+ 		conn.c candidates.c dncache.c meta_result.c
+--- a/servers/slapd/back-dnssrv/Makefile.in
++++ b/servers/slapd/back-dnssrv/Makefile.in
+@@ -18,6 +18,8 @@
+ #  The DNSSRV backend was written by Kurt D. Zeilenga.
+ #
+ 
++SHELL = @SHELL@
++
+ SRCS	= init.c bind.c search.c config.c referral.c
+ OBJS	= init.lo bind.lo search.lo config.lo referral.lo
+ 
+--- a/servers/slapd/back-ldap/Makefile.in
++++ b/servers/slapd/back-ldap/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS	= init.c config.c search.c bind.c unbind.c add.c compare.c \
+ 		delete.c modify.c modrdn.c extended.c chain.c \
+ 		distproc.c monitor.c pbind.c
+--- a/servers/slapd/back-ldif/Makefile.in
++++ b/servers/slapd/back-ldif/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS = ldif.c
+ OBJS = ldif.lo
+ 
+--- a/servers/slapd/back-mdb/Makefile.in
++++ b/servers/slapd/back-mdb/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS = init.c tools.c config.c \
+ 	add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
+ 	extended.c operational.c \
+--- a/servers/slapd/back-meta/Makefile.in
++++ b/servers/slapd/back-meta/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS	= init.c config.c search.c bind.c unbind.c add.c compare.c \
+ 		delete.c modify.c modrdn.c suffixmassage.c map.c \
+ 		conn.c candidates.c dncache.c
+--- a/servers/slapd/back-monitor/Makefile.in
++++ b/servers/slapd/back-monitor/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS = init.c search.c compare.c modify.c bind.c \
+ 	operational.c \
+ 	cache.c entry.c \
+--- a/servers/slapd/back-null/Makefile.in
++++ b/servers/slapd/back-null/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS = null.c
+ OBJS = null.lo
+ 
+--- a/servers/slapd/back-passwd/Makefile.in
++++ b/servers/slapd/back-passwd/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS	= search.c config.c init.c
+ OBJS	= search.lo config.lo init.lo
+ 
+--- a/servers/slapd/back-perl/Makefile.in
++++ b/servers/slapd/back-perl/Makefile.in
+@@ -14,6 +14,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS	= init.c search.c close.c config.c bind.c compare.c \
+ 		modify.c add.c modrdn.c delete.c
+ OBJS	= init.lo search.lo close.lo config.lo bind.lo compare.lo \
+--- a/servers/slapd/back-relay/Makefile.in
++++ b/servers/slapd/back-relay/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS	= init.c op.c
+ OBJS	= init.lo op.lo
+ 
+--- a/servers/slapd/back-sock/Makefile.in
++++ b/servers/slapd/back-sock/Makefile.in
+@@ -17,6 +17,8 @@
+ ## This work was initially developed by Brian Candler for inclusion
+ ## in OpenLDAP Software.
+ 
++SHELL = @SHELL@
++
+ SRCS	= init.c config.c opensock.c search.c bind.c unbind.c add.c \
+ 		delete.c modify.c modrdn.c compare.c result.c extended.c
+ OBJS	= init.lo config.lo opensock.lo search.lo bind.lo unbind.lo add.lo \
+--- a/servers/slapd/back-sql/Makefile.in
++++ b/servers/slapd/back-sql/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS	= init.c config.c search.c bind.c compare.c operational.c \
+ 		entry-id.c schema-map.c sql-wrap.c modify.c util.c \
+ 		add.c delete.c modrdn.c api.c
+--- a/servers/slapd/back-wt/Makefile.in
++++ b/servers/slapd/back-wt/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS = init.c tools.c config.c \
+        add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
+        extended.c operational.c \
+--- a/servers/slapd/Makefile.in
++++ b/servers/slapd/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SLAPTOOLS=slapadd slapcat slapdn slapindex slapmodify slappasswd slaptest slapauth slapacl slapschema
+ PROGRAMS=slapd $(SLAPTOOLS)
+ XPROGRAMS=sslapd libbackends.a .backend liboverlays.a
+--- a/servers/slapd/overlays/Makefile.in
++++ b/servers/slapd/overlays/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS = overlays.c \
+ 	accesslog.c \
+ 	auditlog.c \
+--- a/servers/slapd/pwmods/Makefile.in
++++ b/servers/slapd/pwmods/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ SRCS = argon2.c
+ 
+ LTONLY_MOD = $(LTONLY_mod)
+--- a/servers/slapd/slapi/Makefile.in
++++ b/servers/slapd/slapi/Makefile.in
+@@ -14,6 +14,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ LIBRARY = libslapi.la
+ 
+ #all-common: $(LIBRARY) $(PROGRAMS)
+--- a/tests/progs/Makefile.in
++++ b/tests/progs/Makefile.in
+@@ -13,6 +13,8 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
++SHELL = @SHELL@
++
+ PROGRAMS = slapd-tester slapd-search slapd-read slapd-addel slapd-modrdn \
+ 		slapd-modify slapd-bind slapd-mtread ldif-filter slapd-watcher
+ 
diff --git a/external/subpack/libs/openldap/patches/002-no-doc-and-tests-subdir.patch b/external/subpack/libs/openldap/patches/002-no-doc-and-tests-subdir.patch
new file mode 100644
index 0000000..1af9759
--- /dev/null
+++ b/external/subpack/libs/openldap/patches/002-no-doc-and-tests-subdir.patch
@@ -0,0 +1,11 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -13,7 +13,7 @@
+ ## top-level directory of the distribution or, alternatively, at
+ ## <http://www.OpenLDAP.org/license.html>.
+ 
+-SUBDIRS= include libraries clients servers tests doc
++SUBDIRS= include libraries clients servers
+ CLEANDIRS=
+ INSTALLDIRS= 
+ 
diff --git a/external/subpack/libs/openldap/patches/020-autofs-schema.patch b/external/subpack/libs/openldap/patches/020-autofs-schema.patch
new file mode 100644
index 0000000..11c73f5
--- /dev/null
+++ b/external/subpack/libs/openldap/patches/020-autofs-schema.patch
@@ -0,0 +1,26 @@
+--- /dev/null
++++ b/servers/slapd/schema/autofs.schema
+@@ -0,0 +1,23 @@
++attributetype ( 1.3.6.1.1.1.1.31 NAME 'automountMapName'
++	DESC 'Automount map name'
++	EQUALITY caseExactMatch
++	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
++
++attributetype ( 1.3.6.1.1.1.1.32 NAME 'automountKey'
++	DESC 'Automount key value'
++	EQUALITY caseExactMatch
++	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
++
++attributetype ( 1.3.6.1.1.1.1.33 NAME 'automountInformation'
++	DESC 'Automount information'
++	EQUALITY caseExactMatch
++	SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
++
++objectclass ( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTURAL
++	MUST ( automountMapName )
++	MAY ( description ) )
++
++objectclass ( 1.3.6.1.1.1.2.17 NAME 'automount' SUP top STRUCTURAL
++	DESC 'Automount'
++	MUST ( automountKey $ automountInformation )
++	MAY description )
diff --git a/external/subpack/libs/openldap/patches/110-reproducible-builds.patch b/external/subpack/libs/openldap/patches/110-reproducible-builds.patch
new file mode 100644
index 0000000..b3f724f
--- /dev/null
+++ b/external/subpack/libs/openldap/patches/110-reproducible-builds.patch
@@ -0,0 +1,24 @@
+--- a/build/mkversion
++++ b/build/mkversion
+@@ -50,12 +50,6 @@ if test $# != 1 ; then
+ fi
+ 
+ APPLICATION=$1
+-# Reproducible builds set SOURCE_DATE_EPOCH, want constant strings
+-if [ -n "${SOURCE_DATE_EPOCH}" ]; then
+-   WHOWHERE="openldap"
+-else
+-   WHOWHERE="$USER@$(uname -n):$(pwd)"
+-fi
+ 
+ cat << __EOF__
+ /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+@@ -77,7 +71,6 @@ static const char copyright[] =
+ "COPYING RESTRICTIONS APPLY\n";
+ 
+ $static $const char $SYMBOL[] =
+-"@(#) \$$PACKAGE: $APPLICATION $VERSION (" __DATE__ " " __TIME__ ") \$\n"
+-"\t$WHOWHERE\n";
++"@(#) \$$PACKAGE: $APPLICATION $VERSION\$\n";
+ 
+ __EOF__
diff --git a/external/subpack/libs/openldap/patches/750-no-strip.patch b/external/subpack/libs/openldap/patches/750-no-strip.patch
new file mode 100644
index 0000000..8cffb4f
--- /dev/null
+++ b/external/subpack/libs/openldap/patches/750-no-strip.patch
@@ -0,0 +1,22 @@
+--- a/clients/tools/Makefile.in
++++ b/clients/tools/Makefile.in
+@@ -131,7 +131,7 @@ install-local:	FORCE
+ 	-$(MKDIR) $(DESTDIR)$(bindir)
+ 	@(								\
+ 	    for prg in $(PROGRAMS); do					\
+-		$(LTINSTALL) $(INSTALLFLAGS) $(STRIP_OPTS) -m 755 $$prg$(EXEEXT)	\
++		$(LTINSTALL) $(INSTALLFLAGS) -m 755 $$prg$(EXEEXT)	\
+ 		    $(DESTDIR)$(bindir);				\
+ 	    done							\
+ 	)
+--- a/servers/slapd/Makefile.in
++++ b/servers/slapd/Makefile.in
+@@ -377,7 +377,7 @@ install-local-srv: install-slapd install
+ install-slapd: FORCE
+ 	-$(MKDIR) $(DESTDIR)$(libexecdir)
+ 	-$(MKDIR) $(DESTDIR)$(localstatedir)/run
+-	$(LTINSTALL) $(INSTALLFLAGS) $(STRIP_OPTS) -m 755 \
++	$(LTINSTALL) $(INSTALLFLAGS) -m 755 \
+ 		slapd$(EXEEXT) $(DESTDIR)$(libexecdir)
+ 	@for i in $(SUBDIRS); do \
+ 	    if test -d $$i && test -f $$i/Makefile ; then \
diff --git a/external/subpack/libs/openldap/patches/901-reduce-slapd-default-mem-usage.patch b/external/subpack/libs/openldap/patches/901-reduce-slapd-default-mem-usage.patch
new file mode 100644
index 0000000..4681871
--- /dev/null
+++ b/external/subpack/libs/openldap/patches/901-reduce-slapd-default-mem-usage.patch
@@ -0,0 +1,11 @@
+--- a/servers/slapd/slapd.conf
++++ b/servers/slapd/slapd.conf
+@@ -59,7 +59,7 @@ database config
+ #######################################################################
+ 
+ database	mdb
+-maxsize		1073741824
++maxsize		8388608
+ suffix		"dc=my-domain,dc=com"
+ rootdn		"cn=Manager,dc=my-domain,dc=com"
+ # Cleartext passwords, especially for the rootdn, should
diff --git a/external/subpack/libs/openpgm/Makefile b/external/subpack/libs/openpgm/Makefile
new file mode 100644
index 0000000..256fd1c
--- /dev/null
+++ b/external/subpack/libs/openpgm/Makefile
@@ -0,0 +1,65 @@
+#
+# Copyright (C) 2021 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:=openpgm
+PKG_VERSION:=5.3.128
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL_FILE:=release-5-3-128
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_URL_FILE).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/steve-o/openpgm/tar.gz
+PKG_HASH:=8d707ef8dda45f4a7bc91016d7f2fed6a418637185d76c7ab30b306499c6d393
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_URL_FILE)
+
+PKG_FIXUP:=autoreconf
+MAKE_PATH:=openpgm/pgm
+PKG_AUTOMAKE_PATHS:=$(MAKE_PATH)
+
+PKG_MAINTAINER:=Ye Holmes <yeholmes@outlook.com>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=$(MAKE_PATH)/LICENSE
+PKG_CPE_ID:=cpe:/a:openpgm:openpgm
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/openpgm
+  TITLE:=OpenPGM, an implementation of the PGM protocol
+  URL:=http://openpgm.googlecode.com/
+  SECTION:=libs
+  CATEGORY:=Libraries
+endef
+
+define Package/openpgm/description
+  OpenPGM is a library implementing the PGM reliable multicast
+  network protocol. For more information about OpenPGM, see:
+  http://openpgm.googlecode.com/
+endef
+
+CONFIGURE_VARS += ac_cv_file__proc_cpuinfo=yes \
+    ac_cv_file__dev_rtc=no ac_cv_file__dev_hpet=no
+CONFIGURE_ARGS += --enable-static=no --enable-shared=yes
+
+define Build/Configure
+	$(call Build/Configure/Default,,,$(MAKE_PATH))
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/pgm
+	$(CP) $(PKG_BUILD_DIR)/$(MAKE_PATH)/include/pgm/* $(1)/usr/include/pgm/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_BUILD_DIR)/$(MAKE_PATH)/.libs/libpgm*.so* $(1)/usr/lib/
+	$(CP) $(PKG_BUILD_DIR)/$(MAKE_PATH)/openpgm-5.3.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/openpgm/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/$(MAKE_PATH)/.libs/libpgm*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,openpgm))
diff --git a/external/subpack/libs/openpgm/patches/0001-Rename-openpgm-5.2.pc.in.patch b/external/subpack/libs/openpgm/patches/0001-Rename-openpgm-5.2.pc.in.patch
new file mode 100644
index 0000000..cda1ebe
--- /dev/null
+++ b/external/subpack/libs/openpgm/patches/0001-Rename-openpgm-5.2.pc.in.patch
@@ -0,0 +1,45 @@
+From 240634b1afb968a051f8c68696eae2a582a02450 Mon Sep 17 00:00:00 2001
+From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+Date: Mon, 31 Aug 2020 20:16:25 +0200
+Subject: [PATCH 1/2] Rename openpgm-5.2.pc.in
+
+This will fix the following build failure:
+
+config.status: error: cannot find input file: `openpgm-5.3.pc.in'
+
+Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+---
+ openpgm/pgm/{openpgm-5.2.pc.in => openpgm-5.3.pc.in} | 0
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ rename openpgm/pgm/{openpgm-5.2.pc.in => openpgm-5.3.pc.in} (100%)
+
+--- a/openpgm/pgm/openpgm-5.2.pc.in
++++ /dev/null
+@@ -1,12 +0,0 @@
+-prefix=@prefix@
+-exec_prefix=@exec_prefix@
+-libdir=@libdir@
+-includedir=@includedir@
+-
+-Name: OpenPGM
+-Description: PGM Protocol Library.
+-Version: @PACKAGE_VERSION@
+-# packagers may wish to move @LIBS@ to Libs.private for platforms with
+-# versions of pkg-config that support static linking.
+-Libs: -L${libdir} -lpgm @LIBS@
+-Cflags: -I${includedir}/pgm-@VERSION_MAJOR@.@VERSION_MINOR@
+--- /dev/null
++++ b/openpgm/pgm/openpgm-5.3.pc.in
+@@ -0,0 +1,12 @@
++prefix=@prefix@
++exec_prefix=@exec_prefix@
++libdir=@libdir@
++includedir=@includedir@
++
++Name: OpenPGM
++Description: PGM Protocol Library.
++Version: @PACKAGE_VERSION@
++# packagers may wish to move @LIBS@ to Libs.private for platforms with
++# versions of pkg-config that support static linking.
++Libs: -L${libdir} -lpgm @LIBS@
++Cflags: -I${includedir}/pgm-@VERSION_MAJOR@.@VERSION_MINOR@
diff --git a/external/subpack/libs/openpgm/patches/0002-openpgm-pgm-checksum.c-fix-build-with-32-bits-MMX.patch b/external/subpack/libs/openpgm/patches/0002-openpgm-pgm-checksum.c-fix-build-with-32-bits-MMX.patch
new file mode 100644
index 0000000..7634c00
--- /dev/null
+++ b/external/subpack/libs/openpgm/patches/0002-openpgm-pgm-checksum.c-fix-build-with-32-bits-MMX.patch
@@ -0,0 +1,33 @@
+From b7fa865fa6b06d97d424c500fd1c4bc44c096359 Mon Sep 17 00:00:00 2001
+From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+Date: Sun, 1 Nov 2020 22:46:18 +0100
+Subject: [PATCH 2/2] openpgm/pgm/checksum.c: fix build with 32 bits MMX
+
+Build with i386-pentium-mmx or i686 is broken since version 5-3-128 and
+https://github.com/steve-o/openpgm/commit/b276dc15be5d4e6e1143b9de25d09f63f9c85135
+because _mm_cvtm64_si64 is undefined resulting in the following build
+failure for example on zeromq:
+
+/srv/storage/autobuild/run/instance-3/output-1/host/opt/ext-toolchain/bin/../lib/gcc/i586-buildroot-linux-musl/8.3.0/../../../../i586-buildroot-linux-musl/bin/ld: /srv/storage/autobuild/run/instance-3/output-1/host/i586-buildroot-linux-musl/sysroot/usr/lib32/libpgm-5.3.so.0: undefined reference to `_mm_cvtm64_si64'
+
+So use the fallback if __x86_64__ is not defined
+
+Fixes:
+ - http://autobuild.buildroot.org/results/01d9be37e8a743307128f53f41785654c9971e1a
+
+Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+---
+ openpgm/pgm/checksum.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/openpgm/pgm/checksum.c
++++ b/openpgm/pgm/checksum.c
+@@ -948,7 +948,7 @@ do_csumcpy_mmx (
+ 
+ 		sum = _mm_add_pi32 (sum, lo);
+ 		sum = _mm_add_pi32 (sum, hi);
+-#if 1
++#if defined(__x86_64__)
+ 		*(int64_t*)dst = _mm_cvtm64_si64 (tmp);
+ #else		
+ 		((int*)dst)[1] = _mm_cvtsi64_si32 (tmp);
diff --git a/external/subpack/libs/opus/Makefile b/external/subpack/libs/opus/Makefile
new file mode 100644
index 0000000..2297141
--- /dev/null
+++ b/external/subpack/libs/opus/Makefile
@@ -0,0 +1,74 @@
+#
+# 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:=opus
+PKG_VERSION:=1.5.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://downloads.xiph.org/releases/opus
+PKG_HASH:=65c1d2f78b9f2fb20082c38cbe47c951ad5839345876e46941612ee87f9a7ce1
+
+PKG_MAINTAINER:=Ted Hess <thess@kitchensync.net>, Ian Leonard <antonlacon@gmail.com>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:opus-codec:opus
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libopus
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=OPUS Audio Codec
+  URL:=https://opus-codec.org
+endef
+
+define Package/libopus/description
+ Opus is a totally open, royalty-free, highly versatile audio codec. Opus is
+ unmatched for interactive speech and music transmission over the Internet, but
+ is also intended for storage and streaming applications.
+endef
+
+CONFIGURE_ARGS+= \
+	--disable-doc \
+	--disable-extra-programs
+
+ifeq ($(CONFIG_SOFT_FLOAT),y)
+	CONFIGURE_ARGS+= \
+		--enable-fixed-point
+endif
+
+ifneq ($(findstring neon,$(CONFIG_CPU_TYPE))$(findstring aarch64,$(CONFIG_ARCH)),)
+	CONFIGURE_ARGS+= \
+		--enable-fixed-point
+endif
+
+CPU_ASM_BLACKLIST:=xscale arm926ej-s
+ifneq ($(findstring $(call qstrip,$(CONFIG_CPU_TYPE)),$(CPU_ASM_BLACKLIST)),)
+	CONFIGURE_ARGS+= --disable-asm
+endif
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/opus $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libopus.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/opus.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libopus/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libopus.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libopus))
diff --git a/external/subpack/libs/opusfile/Makefile b/external/subpack/libs/opusfile/Makefile
new file mode 100644
index 0000000..80d64a1
--- /dev/null
+++ b/external/subpack/libs/opusfile/Makefile
@@ -0,0 +1,57 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=opusfile
+PKG_VERSION:=0.12
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://downloads.xiph.org/releases/opus/
+PKG_HASH:=118d8601c12dd6a44f52423e68ca9083cc9f2bfe72da7a8c1acb22a80ae3550b
+
+PKG_MAINTAINER:=Eduardo Abinader <eduardoabinader@gmail.com>
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:xiph:opusfile
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libopusfile
+   SECTION:=libs
+   CATEGORY:=Libraries
+   DEPENDS:=+libogg +libopus +libopenssl
+   TITLE:=OPUS file library
+   URL:=http://opus-codec.org/
+endef
+
+define Package/libopusfile/description
+ The opusfile library provides seeking, decode, and playback of Opus streams in the Ogg container (.opus files)
+endef
+
+CONFIGURE_ARGS += \
+	--without-flac \
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/opusfile.pc $(1)/usr/lib/pkgconfig/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/opusurl.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libopusfile/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libopusfile))
diff --git a/external/subpack/libs/p11-kit/Makefile b/external/subpack/libs/p11-kit/Makefile
new file mode 100644
index 0000000..945b0b9
--- /dev/null
+++ b/external/subpack/libs/p11-kit/Makefile
@@ -0,0 +1,70 @@
+#
+# Copyright (C) 2011-2014 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:=p11-kit
+PKG_VERSION:=0.25.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/p11-glue/p11-kit/releases/download/$(PKG_VERSION)
+PKG_HASH:=d8ddce1bb7e898986f9d250ccae7c09ce14d82f1009046d202a0eb1b428b2adc
+
+PKG_MAINTAINER:=Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:p11-kit_project:p11-kit
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/p11-kit
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A library that provides a way to load and enumerate PKCS11 modules.
+  URL:=https://p11-glue.github.io/p11-glue/p11-kit.html
+  DEPENDS:=+libtasn1 +libpthread
+endef
+
+define Package/p11-kit/description
+  Provides a way to load and enumerate PKCS11 modules. Provides a
+  standard configuration setup for installing PKCS11 modules in such a
+  way that they are discoverable.
+endef
+
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+MESON_ARGS += \
+	-Dhash_impl=internal \
+	-Dlibffi=disabled \
+	-Dtrust_module=disabled \
+	-Dstrict=false \
+	-Dsystemd=disabled \
+	-Dgtk_doc=false \
+	-Dman=false \
+	-Dnls=false
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/p11-kit-1/p11-kit/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/p11-kit-1/p11-kit/* $(1)/usr/include/p11-kit-1/p11-kit/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libp11-kit.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/p11-kit-1.pc $(1)/usr/lib/pkgconfig/p11-kit-1.pc
+endef
+
+define Package/p11-kit/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libp11-kit.so.* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/etc/pkcs11/modules/
+ifneq ($(CONFIG_PACKAGE_libopensc),)
+	$(CP) ./files/opensc.module $(1)/etc/pkcs11/modules/
+endif
+endef
+
+$(eval $(call BuildPackage,p11-kit))
diff --git a/external/subpack/libs/p11-kit/files/opensc.module b/external/subpack/libs/p11-kit/files/opensc.module
new file mode 100644
index 0000000..5f59814
--- /dev/null
+++ b/external/subpack/libs/p11-kit/files/opensc.module
@@ -0,0 +1 @@
+module: /usr/lib/opensc-pkcs11.so
diff --git a/external/subpack/libs/p11-kit/patches/010-format.patch b/external/subpack/libs/p11-kit/patches/010-format.patch
new file mode 100644
index 0000000..587f289
--- /dev/null
+++ b/external/subpack/libs/p11-kit/patches/010-format.patch
@@ -0,0 +1,29 @@
+From c203931e32040f2ffb41461f3e3a5ebf3829ef63 Mon Sep 17 00:00:00 2001
+From: Rosen Penev <rosenp@gmail.com>
+Date: Fri, 28 Jun 2024 13:07:07 -0700
+Subject: [PATCH] fix format warning with 32-bit platforms on musl
+
+musl uses 64-bit time_t, even on 32-bit platforms. Cast to avoid the warning.
+---
+ p11-kit/server.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/p11-kit/server.c
++++ b/p11-kit/server.c
+@@ -45,6 +45,7 @@
+ #include <assert.h>
+ #include <errno.h>
+ #include <fcntl.h>
++#include <inttypes.h>
+ #include <limits.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+@@ -558,7 +559,7 @@ server_loop (Server *server,
+ 
+ 		/* timeout */
+ 		if (ret == 0 && children_avail == 0 && timeout != NULL) {
+-			p11_message (_("no connections to %s for %lu secs, exiting"), server->socket_name, timeout->tv_sec);
++			p11_message (_("no connections to %s for %" PRIu64 " secs, exiting"), server->socket_name, (uint64_t)timeout->tv_sec);
+ 			break;
+ 		}
+ 
diff --git a/external/subpack/libs/pcapplusplus/Makefile b/external/subpack/libs/pcapplusplus/Makefile
new file mode 100644
index 0000000..63d52f1
--- /dev/null
+++ b/external/subpack/libs/pcapplusplus/Makefile
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2021 Michal Hrusecky <michal.hrusecky@turris.com>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=pcapplusplus
+PKG_VERSION:=21.11
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-source-linux.tar.gz
+PKG_HASH:=a936aa5b11dcb6d2ad764749d339fc683021bbf8badc1e493e17e61e50a1cbb1
+PKG_SOURCE_URL:=https://github.com/seladb/PcapPlusPlus/releases/download/v$(PKG_VERSION)/
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/pcapplusplus-$(PKG_VERSION)-source-linux
+
+PKG_LICENSE:=Unlicense
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/pcapplusplus
+  SECTION:=net
+  CATEGORY:=Network
+  URL:=https://pcapplusplus.github.io/
+  TITLE:=Library for getting information about the passing traffic
+  DEPENDS:=+libpcap +libstdcpp
+endef
+
+define Build/Compile
+	cd $(PKG_BUILD_DIR)/PcapPlusPlus; ./configure-linux.sh --install-dir /usr
+	make -C $(PKG_BUILD_DIR)/PcapPlusPlus CXXFLAGS="$(TARGET_CXXFLAGS) -fPIC" CFLAGS="$(TARGET_CFLAGS) -fPIC" CXX="$(TARGET_CXX)" CC="$(TARGET_CC)" AR=$(TARGET_AR) libs
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_BUILD_DIR)/PcapPlusPlus/Dist/header/*.h $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib
+	# Convert static libraries to shared ones
+	$(TARGET_CXX) $(TARGET_CXXFLAGS) -shared -o $(1)/usr/lib/libCommon++.so -Wl,--whole-archive $(PKG_BUILD_DIR)/PcapPlusPlus/Dist/libCommon++.a -Wl,--no-whole-archive
+	$(TARGET_CXX) $(TARGET_CXXFLAGS) -shared -o $(1)/usr/lib/libPacket++.so -Wl,--whole-archive $(PKG_BUILD_DIR)/PcapPlusPlus/Dist/libPacket++.a -Wl,--no-whole-archive
+	$(TARGET_CXX) $(TARGET_CXXFLAGS) -shared -o $(1)/usr/lib/libPcap++.so -Wl,--whole-archive $(PKG_BUILD_DIR)/PcapPlusPlus/Dist/libPcap++.a -Wl,--no-whole-archive
+	$(CP) $(PKG_BUILD_DIR)/PcapPlusPlus/Dist/lib*.a $(1)/usr/lib
+endef
+
+define Package/pcapplusplus/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	# Convert static libraries to shared ones
+	$(TARGET_CXX) $(TARGET_CXXFLAGS) -shared -o $(1)/usr/lib/libCommon++.so -Wl,--whole-archive $(PKG_BUILD_DIR)/PcapPlusPlus/Dist/libCommon++.a -Wl,--no-whole-archive
+	$(TARGET_CXX) $(TARGET_CXXFLAGS) -shared -o $(1)/usr/lib/libPacket++.so -Wl,--whole-archive $(PKG_BUILD_DIR)/PcapPlusPlus/Dist/libPacket++.a -Wl,--no-whole-archive
+	$(TARGET_CXX) $(TARGET_CXXFLAGS) -shared -o $(1)/usr/lib/libPcap++.so -Wl,--whole-archive $(PKG_BUILD_DIR)/PcapPlusPlus/Dist/libPcap++.a -Wl,--no-whole-archive
+endef
+
+$(eval $(call BuildPackage,pcapplusplus))
diff --git a/external/subpack/libs/pixman/Makefile b/external/subpack/libs/pixman/Makefile
new file mode 100644
index 0000000..e91a57c
--- /dev/null
+++ b/external/subpack/libs/pixman/Makefile
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2018 Yousong Zhou <yszhou4tech@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:=pixman
+PKG_VERSION:=0.43.4
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://www.cairographics.org/releases
+PKG_HASH:=a0624db90180c7ddb79fc7a9151093dc37c646d8c38d3f232f767cf64b85a226
+
+PKG_MAINTAINER:=Yousong Zhou <yszhou4tech@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:pixman:pixman
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/pixman
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=a low-level software library for pixel manipulation
+  URL:=https://www.pixman.org/
+endef
+
+define Package/pixman/description
+  Pixman is a low-level software library for pixel manipulation, providing
+  features such as image compositing and trapezoid rasterization. Important
+  users of pixman are the cairo graphics library and the X server.
+endef
+
+define Package/pixman/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpixman*.so* $(1)/usr/lib
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,pixman))
diff --git a/external/subpack/libs/poco/Makefile b/external/subpack/libs/poco/Makefile
new file mode 100644
index 0000000..3f79f48
--- /dev/null
+++ b/external/subpack/libs/poco/Makefile
@@ -0,0 +1,86 @@
+#
+# Copyright (C) 2007-2016 OpenWrt.org
+# Copyright (C) 2017 Daniel Engberg <daniel.engberg.lists@pyret.net>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=poco
+PKG_VERSION:=1.11.0
+PKG_RELEASE:=2
+
+ifeq ($(BUILD_VARIANT),all)
+_PKG_VERSION:=${PKG_VERSION}-all
+PKG_HASH:=b08cf73926fa92a6c8f3c712e8fb217d5d0c2fa5248ec0281f251fe1e925d2f1
+else
+_PKG_VERSION:=${PKG_VERSION}
+PKG_HASH:=06ddc4934ff0a11be425d697f861c15b43b77b610e3642a2f85d0c34d7425ea4
+endif
+
+PKG_SOURCE:=$(PKG_NAME)-$(_PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://pocoproject.org/releases/$(PKG_NAME)-$(PKG_VERSION)
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(_PKG_VERSION)
+
+PKG_MAINTAINER:=Jean-Michel Julien <jean-michel.julien@trilliantinc.com>
+PKG_LICENSE:=BSL-1.0
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:pocoproject:poco
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/poco
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Poco C++ libraries
+  URL:=https://www.pocoproject.org/
+  DEPENDS:=+libstdcpp +libpthread +librt @!arc
+  VARIANT:=minimal
+endef
+
+define Package/poco/description
+  POrtable COmponents, a modern and powerful open source C++ class libraries
+  and frameworks for building network and internet-based applications that
+  run on desktop, server and embedded systems.
+endef
+
+define Package/poco-all
+  $(call Package/poco)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE+=(Complete Edition)
+  DEPENDS+=+libopenssl +libmariadb +libpq +unixodbc
+  VARIANT:=all
+endef
+
+define Package/poco-all/description
+  POrtable COmponents, a modern and powerful open source C++ class libraries
+  and frameworks for building network and internet-based applications that
+  run on desktop, server and embedded systems. The Complete Edition contains
+  all libraries.
+endef
+
+define Package/poco/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libPoco*.so* $(1)/usr/lib/
+endef
+
+define Package/poco-all/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libPoco*.so* $(1)/usr/lib/
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/Poco $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libPoco*.so* $(1)/usr/lib/
+endef
+
+
+$(eval $(call BuildPackage,poco))
+$(eval $(call BuildPackage,poco-all))
diff --git a/external/subpack/libs/poco/patches/100-configure.patch b/external/subpack/libs/poco/patches/100-configure.patch
new file mode 100644
index 0000000..389acb6
--- /dev/null
+++ b/external/subpack/libs/poco/patches/100-configure.patch
@@ -0,0 +1,15 @@
+--- a/configure
++++ b/configure
+@@ -249,9 +249,9 @@ while [ $# -ge 1 ]; do
+ 		;;
+ 
+ 	*)
+-		showhelp
+-		exit 1
+-		;;
++#		showhelp
++#		exit 1
++#		;;
+ 	esac
+ 
+  	shift
diff --git a/external/subpack/libs/poco/patches/200-strerror.patch b/external/subpack/libs/poco/patches/200-strerror.patch
new file mode 100644
index 0000000..b1cb708
--- /dev/null
+++ b/external/subpack/libs/poco/patches/200-strerror.patch
@@ -0,0 +1,11 @@
+--- a/Foundation/src/Error.cpp
++++ b/Foundation/src/Error.cpp
+@@ -64,7 +64,7 @@ namespace Poco {
+ 
+ #if (_XOPEN_SOURCE >= 600) || POCO_OS == POCO_OS_ANDROID || __APPLE__
+ 			setMessage(strerror_r(err, _buffer, sizeof(_buffer)));
+-#elif _GNU_SOURCE
++#elif (defined(_GNU_SOURCE) && defined(__GLIBC__))
+ 			setMessage(strerror_r(err, _buffer, sizeof(_buffer)));
+ #else
+ 			setMessage(strerror(err));
diff --git a/external/subpack/libs/postgresql/Makefile b/external/subpack/libs/postgresql/Makefile
new file mode 100644
index 0000000..f0cd1b2
--- /dev/null
+++ b/external/subpack/libs/postgresql/Makefile
@@ -0,0 +1,257 @@
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=postgresql
+PKG_VERSION:=15.6
+PKG_RELEASE:=1
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=PostgreSQL
+PKG_CPE_ID:=cpe:/a:postgresql:postgresql
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=\
+	https://ftp.postgresql.org/pub/source/v$(PKG_VERSION) \
+	http://ftp.postgresql.org/pub/source/v$(PKG_VERSION) \
+	ftp://ftp.postgresql.org/pub/source/v$(PKG_VERSION)
+
+PKG_HASH:=8455146ed9c69c93a57de954aead0302cafad035c2b242175d6aa1e17ebcb2fb
+
+PKG_BUILD_FLAGS:=no-mips16
+PKG_FIXUP:=autoreconf
+PKG_MACRO_PATHS:=config
+PKG_BUILD_DEPENDS:=postgresql/host
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libpq
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libpthread
+  TITLE:=PostgreSQL client library
+  URL:=http://www.postgresql.org/
+  SUBMENU:=Database
+endef
+
+define Package/libpq/description
+PostgreSQL client library.
+endef
+
+define Package/pgsql-cli
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libncursesw +libpq +libreadline +librt +zlib
+  TITLE:=Command Line Interface (CLI) to PostgreSQL databases
+  URL:=http://www.postgresql.org/
+  SUBMENU:=Database
+endef
+
+define Package/pgsql-cli/description
+Command Line Interface (CLI) to PostgreSQL databases.
+endef
+
+define Package/pgsql-cli-extra
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+libncursesw +libpq +libreadline +librt +zlib
+  TITLE:=Command Line extras for PostgreSQL databases
+  URL:=http://www.postgresql.org/
+  SUBMENU:=Database
+endef
+
+define Package/pgsql-cli-extra/description
+Command Line extras for PostgreSQL databases.
+endef
+
+define Package/pgsql-server
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS:=+pgsql-cli +blockd
+  TITLE:=PostgreSQL databases Server
+  URL:=http://www.postgresql.org/
+  SUBMENU:=Database
+  USERID:=postgres=5432:postgres=5432
+endef
+
+define Package/pgsql-server/description
+PostgreSQL databases Server.
+endef
+
+PGSQL_SERVER_BIN := \
+	pg_amcheck \
+	pg_archivecleanup \
+	pg_basebackup \
+	pg_checksums \
+	pg_controldata \
+	pg_ctl \
+	pg_dump \
+	pg_dumpall \
+	pg_isready \
+	pg_recvlogical \
+	pg_receivewal \
+	pg_resetwal \
+	pg_restore \
+	pg_rewind \
+	pg_upgrade \
+	pg_verifybackup \
+	pg_waldump \
+	postgres \
+	initdb
+
+PGSQL_CLI_EXTRA_BIN := \
+	clusterdb	\
+	createdb	\
+	createuser	\
+	dropdb		\
+	dropuser	\
+	oid2name	\
+	pgbench		\
+	reindexdb	\
+	vacuumdb	\
+	vacuumlo
+
+PGSQL_CONFIG_VARS:= \
+	pgac_cv_snprintf_long_long_int_format="%lld" \
+	pgac_cv_snprintf_size_t_support=yes \
+	USE_DEV_URANDOM=1 \
+	ac_cv_file__dev_urandom="/dev/urandom" \
+	ZIC=zic
+
+ifeq ($(CONFIG_USE_UCLIBC),y)
+# PostgreSQL does not build against uClibc with locales
+# enabled, due to an uClibc bug, see
+# http://lists.uclibc.org/pipermail/uclibc/2014-April/048326.html
+# so overwrite automatic detection and disable locale support
+PGSQL_CONFIG_VARS+= \
+		pgac_cv_type_locale_t=no
+endif
+
+TARGET_CONFIGURE_OPTS+=$(PGSQL_CONFIG_VARS)
+
+HOST_CONFIGURE_ARGS += \
+			--disable-nls \
+			--disable-rpath \
+			--without-bonjour \
+			--without-gssapi \
+			--without-ldap \
+			--without-openssl \
+			--without-pam \
+			--without-perl \
+			--without-python \
+			--without-readline \
+			--without-tcl \
+			--without-systemd \
+			--with-zlib="yes" \
+			--enable-depend
+
+CONFIGURE_ARGS += \
+			$(DISABLE_NLS) \
+			--disable-rpath \
+			--without-bonjour \
+			--without-gssapi \
+			--without-ldap \
+			--without-openssl \
+			--without-pam \
+			--without-perl \
+			--without-python \
+			--without-tcl \
+			--without-systemd \
+			--with-zlib="yes" \
+			--enable-depend \
+			$(if $(CONFIG_arc),--disable-spinlocks)
+
+HOST_CFLAGS += -std=gnu99
+
+# Need a native zic and pg_config for build
+define Host/Compile
+	+$(HOST_MAKE_VARS) MAKELEVEL=0 $(MAKE) -C $(HOST_BUILD_DIR)/src/bin/pg_config CC="$(HOSTCC)"
+	+$(HOST_MAKE_VARS) MAKELEVEL=0 $(MAKE) -C $(HOST_BUILD_DIR)/src/timezone CC="$(HOSTCC)"
+endef
+
+define Host/Install
+	$(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/lib/
+	$(INSTALL_BIN) $(HOST_BUILD_DIR)/src/common/libpgcommon.a $(STAGING_DIR_HOSTPKG)/lib/
+	$(INSTALL_BIN) $(HOST_BUILD_DIR)/src/port/libpgport.a $(STAGING_DIR_HOSTPKG)/lib/
+	$(INSTALL_BIN) $(HOST_BUILD_DIR)/src/bin/pg_config/pg_config $(STAGING_DIR_HOSTPKG)/lib/
+	$(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/bin/
+	$(INSTALL_BIN) $(HOST_BUILD_DIR)/src/timezone/zic $(STAGING_DIR_HOSTPKG)/bin/
+endef
+
+define Build/Compile
+	$(MAKE) -C $(PKG_BUILD_DIR) MAKELEVEL=0 all contrib
+endef
+
+# because PROFILE means something else in the project Makefile
+unexport PROFILE
+
+define Package/libpq/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpq.so.* $(1)/usr/lib/
+endef
+
+define Package/pgsql-cli/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/psql $(1)/usr/bin/
+endef
+
+define Package/pgsql-cli-extra/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(foreach bin,$(PGSQL_CLI_EXTRA_BIN),$(PKG_INSTALL_DIR)/usr/bin/$(bin)) $(1)/usr/bin/
+endef
+
+define Package/pgsql-server/conffiles
+/etc/config/postgresql
+endef
+
+define Package/pgsql-server/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(foreach bin,$(PGSQL_SERVER_BIN),$(PKG_INSTALL_DIR)/usr/bin/$(bin)) $(1)/usr/bin/
+
+	ln -sf postgres $(1)/usr/bin/postmaster
+
+	$(INSTALL_DIR) $(1)/usr/share/postgresql
+	$(CP) $(PKG_INSTALL_DIR)/usr/share/postgresql/* \
+		$(1)/usr/share/postgresql
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/postgresql \
+		$(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/lib/functions
+	$(INSTALL_BIN) ./files/postgresql.sh $(1)/lib/functions/
+
+	$(INSTALL_DIR) $(1)/etc/config
+	$(INSTALL_DATA) ./files/postgresql.config $(1)/etc/config/postgresql
+
+	$(INSTALL_DIR) $(1)/etc/init.d
+	$(INSTALL_BIN) ./files/postgresql.init $(1)/etc/init.d/postgresql
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(STAGING_DIR_HOSTPKG)/lib/pg_config $(1)/usr/bin
+	$(INSTALL_DIR) $(1)/host/bin/
+	$(LN) $(STAGING_DIR)/usr/bin/pg_config $(1)/host/bin
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libpq $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/libpq-fe.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/pg_config.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/pg_config_manual.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/postgres_ext.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/pg_config_ext.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/postgresql $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpq.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libpq.pc $(1)/usr/lib/pkgconfig/
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,libpq))
+$(eval $(call BuildPackage,pgsql-cli))
+$(eval $(call BuildPackage,pgsql-cli-extra))
+$(eval $(call BuildPackage,pgsql-server))
diff --git a/external/subpack/libs/postgresql/files/postgresql.config b/external/subpack/libs/postgresql/files/postgresql.config
new file mode 100644
index 0000000..4760bf1
--- /dev/null
+++ b/external/subpack/libs/postgresql/files/postgresql.config
@@ -0,0 +1,2 @@
+config postgresql config
+	option PGDATA	/var/postgresql/data
diff --git a/external/subpack/libs/postgresql/files/postgresql.init b/external/subpack/libs/postgresql/files/postgresql.init
new file mode 100644
index 0000000..5761336
--- /dev/null
+++ b/external/subpack/libs/postgresql/files/postgresql.init
@@ -0,0 +1,92 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006-2015 OpenWrt.org
+START=50
+
+PROG=/usr/bin/postmaster
+
+USE_PROCD=1
+
+fix_hosts() {
+	# make sure localhost (without a dot) is in /etc/hosts
+	grep -q 'localhost$' /etc/hosts || echo '127.0.0.1 localhost' >> /etc/hosts
+}
+
+fix_perms() {
+	# for whatever reason, /dev/null gets wrong perms
+	chmod a+w /dev/null
+}
+
+cleanup() {
+	if [ -f "$1/postmaster.pid" ]; then
+		rm "$1/postmaster.pid"
+	fi
+}
+
+start_service() {
+	. /lib/functions/postgresql.sh
+
+	config_load "postgresql"
+	config_get pgdata config PGDATA
+	config_get pgopts config PGOPTS
+
+	user_exists postgres 5432 || user_add postgres 5432
+	group_exists postgres 5432 || group_add postgres 5432
+
+	[ "$_BOOT" = "1" ] &&
+		[ "$(procd_get_mountpoints $pgdata)" ] && return 0
+
+	fix_perms
+	fix_hosts
+
+	if [ ! -e "${pgdata}/PG_VERSION" ]; then
+		pg_init_data ${pgdata}
+		[ $? -gt 0 ] && return 1
+	fi
+
+	cleanup "${pgdata}"
+
+	mkdir -m 0755 -p /var/run/postgresql
+	chmod 0750 /var/run/postgresql
+	chown postgres:postgres /var/run/postgresql
+	procd_open_instance postmaster
+	procd_set_param user postgres
+	procd_set_param command $PROG
+	procd_append_param command -D "${pgdata}"
+	procd_append_param command -k "/var/run/postgresql"
+	[ -n "${pgopts}" ] && procd_append_param command -o "${pgopts}"
+	procd_set_param respawn retry=60
+	procd_add_jail postgresql log
+	procd_add_jail_mount /usr/lib/postgresql /usr/share/postgresql
+	procd_add_jail_mount_rw /var/run/postgresql "${pgdata}"
+	procd_add_jail_mount_rw /dev/shm
+	procd_set_param stderr 1
+	procd_set_param stdout 1
+	procd_close_instance
+
+	procd_open_instance uci_dbinit
+	procd_set_param user postgres
+	procd_set_param command /lib/functions/postgresql.sh init "${pgdata}"
+	procd_set_param stdout 1
+	procd_set_param stderr 1
+	procd_close_instance
+}
+
+boot() {
+	_BOOT=1 start
+}
+
+service_triggers() {
+	config_load "postgresql"
+	config_get pgdata config PGDATA
+	procd_add_restart_mount_trigger "${pgdata}"
+}
+
+stop_service() {
+	procd_send_signal "postgresql" postmaster SIGTERM
+}
+
+status_service() {
+	config_load "postgresql"
+	config_get pgdata config PGDATA
+	/usr/bin/pg_ctl status -U postgres -D "${pgdata}"
+}
diff --git a/external/subpack/libs/postgresql/files/postgresql.sh b/external/subpack/libs/postgresql/files/postgresql.sh
new file mode 100644
index 0000000..e1076d5
--- /dev/null
+++ b/external/subpack/libs/postgresql/files/postgresql.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+
+PSQL="/usr/bin/psql"
+
+free_megs() {
+	fsdir=$1
+	while [ ! -d "$fsdir" ]; do
+		fsdir="$(dirname "$fsdir")"
+	done
+	df -m $fsdir | while read fs bl us av cap mnt; do [ "$av" = "Available" ] || echo $av; done
+}
+
+pg_init_data() {
+	# make sure we got at least 50MB of free space
+	[ $(free_megs "$1") -lt 50 ] && return 1
+	pg_ctl initdb -U postgres -D "$1"
+}
+
+pg_server_ready() {
+	t=0
+	while [ $t -le 90 ]; do
+		psql -h /var/run/postgresql/ -U postgres -c "\q" 1>/dev/null 2>/dev/null && return 0
+		t=$((t+1))
+		sleep 1
+	done
+	return 1
+}
+
+
+pg_test_db() {
+	echo "SELECT datname FROM pg_catalog.pg_database WHERE datname = '$1';" |
+		$PSQL -h /var/run/postgresql -w -U "postgres" -d "template1" -q |
+			grep -q "0 rows" && return 1
+
+	return 0
+}
+
+pg_include_sql() {
+	if [ "$3" ]; then
+		env PGPASSWORD="$3" $PSQL -h /var/run/postgresql -U "$2" -d "$1" -e -f "$4"
+		return $?
+	else
+		$PSQL -w -h /var/run/postgresql -U "$2" -d "$1" -e -f "$4"
+		return $?
+	fi
+}
+
+# $1: dbname, $2: username, $3: password, $4: sql populate script
+pg_require_db() {
+	local ret
+	local dbname="$1"
+	local dbuser="$2"
+	local dbpass="$3"
+	local exuser
+
+	pg_test_db $@ && return 0
+
+	shift ; shift ; shift
+
+	echo "CREATE DATABASE $dbname;" |
+		$PSQL -h /var/run/postgresql -U postgres -d template1 -e || return $?
+
+	if [ "$dbuser" ]; then
+		echo "SELECT usename FROM pg_catalog.pg_user WHERE usename = '$dbuser';" |
+			$PSQL -h /var/run/postgresql -U postgres -d template1 -e | grep -q "0 rows" &&
+			( echo -n "CREATE USER $dbuser"
+			[ "$dbpass" ] && echo -n " WITH PASSWORD '$dbpass'"
+			echo " NOCREATEDB NOSUPERUSER NOCREATEROLE NOINHERIT;" ) |
+				$PSQL -h /var/run/postgresql -U postgres -d template1 -e
+
+		echo "GRANT ALL PRIVILEGES ON DATABASE \"$dbname\" TO $dbuser;" |
+			$PSQL -h /var/run/postgresql -U postgres -d template1 -e
+	fi
+
+	while [ "$1" ]; do
+		pg_include_sql "$dbname" "$dbuser" "$dbpass" "$1"
+		ret=$?
+		[ $ret != 0 ] && break
+		shift
+	done
+
+	return $ret
+}
+
+uci_require_db() {
+	local dbname dbuser dbpass dbscript
+	config_get dbname $1 name
+	config_get dbuser $1 user
+	config_get dbpass $1 pass
+	config_get dbscript $1 script
+	pg_require_db "$dbname" "$dbuser" "$dbpass" $dbscript
+}
+
+[ "$1" = "init" ] && {
+	. /lib/functions.sh
+	pg_server_ready $2 || exit 1
+	config_load postgresql
+	config_foreach uci_require_db postgres-db
+}
diff --git a/external/subpack/libs/postgresql/patches/050-build-contrib.patch b/external/subpack/libs/postgresql/patches/050-build-contrib.patch
new file mode 100644
index 0000000..88a23f0
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/050-build-contrib.patch
@@ -0,0 +1,11 @@
+--- a/GNUmakefile.in
++++ b/GNUmakefile.in
+@@ -8,7 +8,7 @@ subdir =
+ top_builddir = .
+ include $(top_builddir)/src/Makefile.global
+ 
+-$(call recurse,all install,src config)
++$(call recurse,all install,src config contrib)
+ 
+ docs:
+ 	$(MAKE) -C doc all
diff --git a/external/subpack/libs/postgresql/patches/200-ranlib.patch b/external/subpack/libs/postgresql/patches/200-ranlib.patch
new file mode 100644
index 0000000..d4184a3
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/200-ranlib.patch
@@ -0,0 +1,10 @@
+--- a/src/port/Makefile
++++ b/src/port/Makefile
+@@ -83,6 +83,7 @@ uninstall:
+ libpgport.a: $(OBJS)
+ 	rm -f $@
+ 	$(AR) $(AROPT) $@ $^
++	$(RANLIB) libpgport.a
+ 
+ # getaddrinfo.o and getaddrinfo_shlib.o need PTHREAD_CFLAGS (but getaddrinfo_srv.o does not)
+ getaddrinfo.o: CFLAGS+=$(PTHREAD_CFLAGS)
diff --git a/external/subpack/libs/postgresql/patches/300-fix-includes.patch b/external/subpack/libs/postgresql/patches/300-fix-includes.patch
new file mode 100644
index 0000000..3611c8e
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/300-fix-includes.patch
@@ -0,0 +1,14 @@
+--- a/src/bin/pg_ctl/pg_ctl.c
++++ b/src/bin/pg_ctl/pg_ctl.c
+@@ -12,9 +12,11 @@
+ #include "postgres_fe.h"
+ 
+ #include <fcntl.h>
++#include <pwd.h>
+ #include <signal.h>
+ #include <time.h>
+ #include <sys/stat.h>
++#include <sys/types.h>
+ #include <sys/wait.h>
+ #include <unistd.h>
+ 
diff --git a/external/subpack/libs/postgresql/patches/700-no-arm-crc-march-change.patch b/external/subpack/libs/postgresql/patches/700-no-arm-crc-march-change.patch
new file mode 100644
index 0000000..33637f5
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/700-no-arm-crc-march-change.patch
@@ -0,0 +1,15 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -2239,9 +2239,9 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [
+ # flags. If not, check if adding -march=armv8-a+crc flag helps.
+ # CFLAGS_ARMV8_CRC32C is set if the extra flag is required.
+ PGAC_ARMV8_CRC32C_INTRINSICS([])
+-if test x"$pgac_armv8_crc32c_intrinsics" != x"yes"; then
+-  PGAC_ARMV8_CRC32C_INTRINSICS([-march=armv8-a+crc])
+-fi
++#if test x"$pgac_armv8_crc32c_intrinsics" != x"yes"; then
++#  PGAC_ARMV8_CRC32C_INTRINSICS([-march=armv8-a+crc])
++#fi
+ AC_SUBST(CFLAGS_ARMV8_CRC32C)
+ 
+ # Select CRC-32C implementation.
diff --git a/external/subpack/libs/postgresql/patches/800-busybox-default-pager.patch b/external/subpack/libs/postgresql/patches/800-busybox-default-pager.patch
new file mode 100644
index 0000000..b1222cb
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/800-busybox-default-pager.patch
@@ -0,0 +1,14 @@
+--- a/src/include/fe_utils/print.h
++++ b/src/include/fe_utils/print.h
+@@ -19,11 +19,7 @@
+ 
+ 
+ /* This is not a particularly great place for this ... */
+-#ifndef __CYGWIN__
+-#define DEFAULT_PAGER "more"
+-#else
+ #define DEFAULT_PAGER "less"
+-#endif
+ 
+ enum printFormat
+ {
diff --git a/external/subpack/libs/postgresql/patches/900-pg_ctl-setuid.patch b/external/subpack/libs/postgresql/patches/900-pg_ctl-setuid.patch
new file mode 100644
index 0000000..64d558f
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/900-pg_ctl-setuid.patch
@@ -0,0 +1,107 @@
+--- a/src/bin/pg_ctl/pg_ctl.c
++++ b/src/bin/pg_ctl/pg_ctl.c
+@@ -96,6 +96,7 @@ static char *event_source = NULL;
+ static char *register_servicename = "PostgreSQL";	/* FIXME: + version ID? */
+ static char *register_username = NULL;
+ static char *register_password = NULL;
++static char *username = "";
+ static char *argv0 = NULL;
+ static bool allow_core_files = false;
+ static time_t start_time;
+@@ -2086,6 +2087,9 @@ do_help(void)
+ #endif
+ 	printf(_("  -s, --silent           only print errors, no informational messages\n"));
+ 	printf(_("  -t, --timeout=SECS     seconds to wait when using -w option\n"));
++#if !defined(WIN32) && !defined(__CYGWIN__)
++	printf(_("  -U, --username=NAME    user name of account PostgreSQL server is running as\n"));
++#endif
+ 	printf(_("  -V, --version          output version information, then exit\n"));
+ 	printf(_("  -w, --wait             wait until operation completes (default)\n"));
+ 	printf(_("  -W, --no-wait          do not wait until operation completes\n"));
+@@ -2298,6 +2302,7 @@ main(int argc, char **argv)
+ 		{"options", required_argument, NULL, 'o'},
+ 		{"silent", no_argument, NULL, 's'},
+ 		{"timeout", required_argument, NULL, 't'},
++		{"username", required_argument, NULL, 'U'},
+ 		{"core-files", no_argument, NULL, 'c'},
+ 		{"wait", no_argument, NULL, 'w'},
+ 		{"no-wait", no_argument, NULL, 'W'},
+@@ -2338,20 +2343,6 @@ main(int argc, char **argv)
+ 		}
+ 	}
+ 
+-	/*
+-	 * Disallow running as root, to forestall any possible security holes.
+-	 */
+-#ifndef WIN32
+-	if (geteuid() == 0)
+-	{
+-		write_stderr(_("%s: cannot be run as root\n"
+-					   "Please log in (using, e.g., \"su\") as the "
+-					   "(unprivileged) user that will\n"
+-					   "own the server process.\n"),
+-					 progname);
+-		exit(1);
+-	}
+-#endif
+ 
+ 	env_wait = getenv("PGCTLTIMEOUT");
+ 	if (env_wait != NULL)
+@@ -2437,11 +2428,15 @@ main(int argc, char **argv)
+ 					wait_seconds_arg = true;
+ 					break;
+ 				case 'U':
++#if defined(WIN32) || defined(__CYGWIN__)
+ 					if (strchr(optarg, '\\'))
+ 						register_username = pg_strdup(optarg);
+ 					else
+ 						/* Prepend .\ for local accounts */
+ 						register_username = psprintf(".\\%s", optarg);
++#else
++					username = pg_strdup(optarg);
++#endif
+ 					break;
+ 				case 'w':
+ 					do_wait = true;
+@@ -2523,6 +2518,41 @@ main(int argc, char **argv)
+ 		exit(1);
+ 	}
+ 
++	/*
++	 * Disallow running as root, to forestall any possible security holes.
++	 */
++#if !defined(WIN32) && !defined(__CYGWIN__)
++	if (geteuid() == 0)
++	{
++		struct passwd *p;
++		if (!username || !strlen(username)) {
++			fprintf(stderr,
++					_("%s: when run as root, username needs to be provided\n"),
++					progname);
++			exit(1);
++		}
++		p = getpwnam(username);
++		if (!p) {
++			fprintf(stderr,
++					_("%s: invalid username: %s\n"),
++					progname, username);
++			exit(1);
++		}
++		if (!p->pw_uid) {
++			fprintf(stderr,
++					_("%s: user needs to be non-root\n"),
++					progname);
++			exit(1);
++		}
++		if (setgid(p->pw_gid) || setuid(p->pw_uid)) {
++			fprintf(stderr,
++					_("%s: failed to set user id %d: %d (%s)\n"),
++					progname, p->pw_uid, errno, strerror(errno));
++			exit(1);
++		}
++	}
++#endif
++
+ 	/* Note we put any -D switch into the env var above */
+ 	pg_config = getenv("PGDATA");
+ 	if (pg_config)
diff --git a/external/subpack/libs/protobuf-c/Makefile b/external/subpack/libs/protobuf-c/Makefile
new file mode 100644
index 0000000..3a76b11
--- /dev/null
+++ b/external/subpack/libs/protobuf-c/Makefile
@@ -0,0 +1,66 @@
+#
+# Copyright (C) 2011 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:=libprotobuf-c
+PKG_VERSION:=1.4.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=protobuf-c-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/protobuf-c/protobuf-c/releases/download/v$(PKG_VERSION)
+PKG_HASH:=4cc4facd508172f3e0a4d3a8736225d472418aee35b4ad053384b137b220339f
+PKG_BUILD_DIR:=$(BUILD_DIR)/protobuf-c-$(PKG_VERSION)
+HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/protobuf-c-$(PKG_VERSION)
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=BSD-2-Clause
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:protobuf-c_project:protobuf-c
+
+HOST_BUILD_DEPENDS:=protobuf/host
+PKG_BUILD_DEPENDS:=protobuf
+
+CMAKE_INSTALL:=1
+CMAKE_SOURCE_SUBDIR:=build-cmake
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libprotobuf-c
+  TITLE:=Protocol Buffers library
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=https://github.com/protobuf-c/protobuf-c
+endef
+
+define Package/libprotobuf-c/description
+  Runtime library to use Google Protocol Buffers from C applications.
+  Protocol Buffers are a way of encoding structured data in an efficient yet
+  extensible format. Google uses Protocol Buffers for almost all of its
+  internal RPC protocols and file formats.
+endef
+
+CMAKE_HOST_OPTIONS += \
+	-DBUILD_SHARED_LIBS=OFF \
+	-DCMAKE_CXX_STANDARD=11 \
+	-DCMAKE_SKIP_RPATH=OFF \
+	-DCMAKE_INSTALL_RPATH="${STAGING_DIR_HOSTPKG}/lib"
+
+CMAKE_OPTIONS += \
+	-DBUILD_SHARED_LIBS=ON \
+	-DBUILD_PROTOC=OFF
+
+define Package/libprotobuf-c/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libprotobuf-c.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libprotobuf-c))
+$(eval $(call HostBuild))
+
diff --git a/external/subpack/libs/protobuf/Makefile b/external/subpack/libs/protobuf/Makefile
new file mode 100644
index 0000000..7e60e84
--- /dev/null
+++ b/external/subpack/libs/protobuf/Makefile
@@ -0,0 +1,113 @@
+#
+# Copyright (C) 2007-2015 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:=protobuf
+PKG_VERSION:=3.17.3
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-cpp-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/google/protobuf/releases/download/v$(PKG_VERSION)
+PKG_HASH:=51cec99f108b83422b7af1170afd7aeb2dd77d2bcbb7b6bad1f92509e9ccf8cb
+
+PKG_MAINTAINER:=Ken Keys <kkeys@caida.org>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+PKG_CPE_ID:=cpe:/a:google:protobuf
+
+CMAKE_SOURCE_SUBDIR:=cmake
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/protobuf/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=A structured data encoding library
+  URL:=https://github.com/google/protobuf
+  DEPENDS:=+zlib +libpthread +libatomic +libstdcpp
+endef
+
+define Package/protobuf
+  $(call Package/protobuf/Default)
+  DEPENDS+=+protobuf-lite
+endef
+
+define Package/protobuf-lite
+  $(call Package/protobuf/Default)
+endef
+
+define Package/protobuf/description/Default
+Protocol Buffers are a way of encoding structured data in an efficient
+yet extensible format. Google uses Protocol Buffers for almost all
+of its internal RPC protocols and file formats.
+endef
+
+define Package/protobuf/description
+$(call Package/protobuf/description/Default)
+
+This package provides the libprotoc, libprotobuf, and libprotobuf-lite
+libraries.  For a much smaller protobuf package, see "protobuf-lite".
+
+endef
+
+define Package/protobuf-lite/description
+$(call Package/protobuf/description/Default)
+
+This package provides the libprotobuf-lite library.
+
+endef
+
+CMAKE_HOST_OPTIONS += \
+	-Dprotobuf_BUILD_PROTOC_BINARIES=ON \
+	-Dprotobuf_BUILD_TESTS=OFF \
+	-DBUILD_SHARED_LIBS=OFF \
+	-DCMAKE_INSTALL_LIBDIR=lib
+
+CMAKE_OPTIONS += \
+	-Dprotobuf_BUILD_PROTOC_BINARIES=ON \
+	-Dprotobuf_BUILD_TESTS=OFF \
+	-Dprotobuf_WITH_ZLIB=ON \
+	-DBUILD_SHARED_LIBS=ON
+
+TARGET_LDFLAGS += -latomic
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/protobuf.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/protobuf.pc
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/protobuf-lite.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/protobuf-lite.pc
+endef
+
+define Package/protobuf-lite/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib
+
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libprotobuf-lite.so* \
+		$(1)/usr/lib/
+endef
+
+define Package/protobuf/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib
+
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libprotoc.so*  \
+		$(1)/usr/lib/
+
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libprotobuf.so* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,protobuf))
+$(eval $(call BuildPackage,protobuf-lite))
+$(eval $(call HostBuild))
diff --git a/external/subpack/libs/protobuf/patches/010-rpath.patch b/external/subpack/libs/protobuf/patches/010-rpath.patch
new file mode 100644
index 0000000..ef3e98a
--- /dev/null
+++ b/external/subpack/libs/protobuf/patches/010-rpath.patch
@@ -0,0 +1,24 @@
+--- a/cmake/install.cmake
++++ b/cmake/install.cmake
+@@ -16,8 +16,8 @@ foreach(_library ${_protobuf_libraries})
+     $<BUILD_INTERFACE:${protobuf_source_dir}/src>
+     $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
+   if (UNIX AND NOT APPLE)
+-    set_property(TARGET ${_library}
+-      PROPERTY INSTALL_RPATH "$ORIGIN")
++#   set_property(TARGET ${_library}
++#      PROPERTY INSTALL_RPATH "$ORIGIN")
+   elseif (APPLE)
+     set_property(TARGET ${_library}
+       PROPERTY INSTALL_RPATH "@loader_path")
+@@ -34,8 +34,8 @@ if (protobuf_BUILD_PROTOC_BINARIES)
+     BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
+     COMPONENT protoc)
+   if (UNIX AND NOT APPLE)
+-    set_property(TARGET protoc
+-      PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
++#    set_property(TARGET protoc
++#      PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
+   elseif (APPLE)
+     set_property(TARGET protoc
+       PROPERTY INSTALL_RPATH "@loader_path/../lib")
diff --git a/external/subpack/libs/psqlodbc/Makefile b/external/subpack/libs/psqlodbc/Makefile
new file mode 100644
index 0000000..4f91669
--- /dev/null
+++ b/external/subpack/libs/psqlodbc/Makefile
@@ -0,0 +1,78 @@
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=psqlodbc
+PKG_VERSION:=11.00.0000
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://ftp.postgresql.org/pub/odbc/versions/src
+PKG_HASH:=703e6b87022f95ffa00d9f86c8f0a877f8a55b9b3be0942081f382e794112a86
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=LGPL-2.0-or-later
+PKG_LICENSE_FILES:=license.txt
+
+PKG_BUILD_DEPENDS:=unixodbc/host
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+CONFIGURE_ARGS += \
+	--with-unixodbc=$(STAGING_DIR)/host/bin/odbc_config \
+	--with-libpq=$(STAGING_DIR)/usr
+
+define Package/psqlodbc/Default
+  SUBMENU:=Database
+  URL:=https://odbc.postgresql.org/
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Postgresql driver for ODBC
+  DEPENDS:=+unixodbc +libpq
+endef
+
+define Package/psqlodbca
+$(call Package/psqlodbc/Default)
+  TITLE:=psqlODBC - PostgreSQL ODBC driver (ASCII)
+endef
+
+define Package/psqlodbcw
+$(call Package/psqlodbc/Default)
+  TITLE:=psqlODBC - PostgreSQL ODBC driver (UTF-8)
+endef
+
+define Package/psqlodbca/description
+	psqlODBC is the official PostgreSQL ODBC Driver.
+	It is released under the Library General Public Licence, or LGPL.
+endef
+
+define Package/psqlodbcw/description
+$(call Package/psqlodbca/description)
+	(UTF-8 version)
+endef
+
+define Package/psqlodbca/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/psqlodbca.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/etc/odbcinst.ini.d
+	echo "[PostgreSQL ANSI]" > $(1)/etc/odbcinst.ini.d/psqlodbca.ini
+	echo "Description = PostgreSQL ODBC driver (ANSI version)" >> $(1)/etc/odbcinst.ini.d/psqlodbca.ini
+	echo "Driver = /usr/lib/psqlodbca.so" >> $(1)/etc/odbcinst.ini.d/psqlodbca.ini
+
+endef
+
+define Package/psqlodbcw/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/psqlodbcw.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/etc/odbcinst.ini.d
+	echo "[PostgreSQL Unicode]" > $(1)/etc/odbcinst.ini.d/psqlodbcw.ini
+	echo "Description = PostgreSQL ODBC driver (Unicode version)" >> $(1)/etc/odbcinst.ini.d/psqlodbcw.ini
+	echo "Driver = /usr/lib/psqlodbcw.so" >> $(1)/etc/odbcinst.ini.d/psqlodbcw.ini
+endef
+
+$(eval $(call BuildPackage,psqlodbca))
+$(eval $(call BuildPackage,psqlodbcw))
diff --git a/external/subpack/libs/pthsem/Makefile b/external/subpack/libs/pthsem/Makefile
new file mode 100644
index 0000000..f9f35a5
--- /dev/null
+++ b/external/subpack/libs/pthsem/Makefile
@@ -0,0 +1,66 @@
+#
+# Copyright (C) 2008-2015 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:=pthsem
+PKG_VERSION:=2.0.8
+PKG_RELEASE:=7
+
+PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.auto.tuwien.ac.at/~mkoegler/pth/
+PKG_HASH:=4024cafdd5d4bce2b1778a6be5491222c3f6e7ef1e43971264c451c0012c5c01
+
+PKG_MAINTAINER:=Othmar Truniger <github@truniger.ch>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+PKG_FORTIFY_SOURCE:=0
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/pthsem
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=GNU pth extended with semaphore support
+  URL:=http://www.auto.tuwien.ac.at/~mkoegler/index.php/pth
+endef
+
+define Package/pthsem/description
+  GNU pth is a user mode multi threading library.
+  pthsem is an extend version, with support for semaphores added. It can be installed parallel to a normal pth.
+endef
+
+# The musl libc provides a proper implementation of sigaltstack() so
+# prevent configure from wrongly assuming a broken Linux platform
+CONFIGURE_VARS += \
+	ac_cv_check_sjlj=ssjlj
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/pthsem-config $(1)/usr/bin/
+	$(SED) 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' $(1)/usr/bin/pthsem-config
+
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP)   $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP)   $(PKG_INSTALL_DIR)/usr/lib/libpthsem.{a,la,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/pthsem.pc $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/pthsem-config $(2)/bin/
+endef
+
+define Package/pthsem/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libpthsem.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,pthsem))
diff --git a/external/subpack/libs/pthsem/patches/001-linux3x-fix.patch b/external/subpack/libs/pthsem/patches/001-linux3x-fix.patch
new file mode 100644
index 0000000..60aff54
--- /dev/null
+++ b/external/subpack/libs/pthsem/patches/001-linux3x-fix.patch
@@ -0,0 +1,11 @@
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -892,6 +892,8 @@ case $PLATFORM in
+         case "x`uname -r`" in
+ changequote(, )dnl
+             x2.[23456789]* ) ;;
++changequote(, )dnl
++            x3.* ) ;;
+ changequote([, ])
+             * ) braindead=yes ;;
+         esac
diff --git a/external/subpack/libs/pthsem/patches/002-fix-signal.h b/external/subpack/libs/pthsem/patches/002-fix-signal.h
new file mode 100644
index 0000000..7979153
--- /dev/null
+++ b/external/subpack/libs/pthsem/patches/002-fix-signal.h
@@ -0,0 +1,22 @@
+--- a/pth.h.in
++++ b/pth.h.in
+@@ -43,7 +43,7 @@
+ #include <time.h>          /* for struct timespec */
+ #include <sys/time.h>      /* for struct timeval  */
+ #include <sys/socket.h>    /* for sockaddr        */
+-#include <sys/signal.h>    /* for sigset_t        */
++#include <signal.h>        /* for sigset_t        */
+ @EXTRA_INCLUDE_SYS_SELECT_H@
+ 
+     /* fallbacks for essential typedefs */
+--- a/pthread.h.in
++++ b/pthread.h.in
+@@ -111,7 +111,7 @@ typedef int __vendor_sched_param;
+ #include <sys/types.h>     /* for ssize_t         */
+ #include <sys/time.h>      /* for struct timeval  */
+ #include <sys/socket.h>    /* for sockaddr        */
+-#include <sys/signal.h>    /* for sigset_t        */
++#include <signal.h>        /* for sigset_t        */
+ #include <time.h>          /* for struct timespec */
+ #include <unistd.h>        /* for off_t           */
+ @EXTRA_INCLUDE_SYS_SELECT_H@
diff --git a/external/subpack/libs/pthsem/patches/003-linux4x-fix.patch b/external/subpack/libs/pthsem/patches/003-linux4x-fix.patch
new file mode 100644
index 0000000..167ba4e
--- /dev/null
+++ b/external/subpack/libs/pthsem/patches/003-linux4x-fix.patch
@@ -0,0 +1,11 @@
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -894,6 +894,8 @@ changequote(, )dnl
+             x2.[23456789]* ) ;;
+ changequote(, )dnl
+             x3.* ) ;;
++changequote(, )dnl
++            x4.* ) ;;
+ changequote([, ])
+             * ) braindead=yes ;;
+         esac
diff --git a/external/subpack/libs/qrencode/Makefile b/external/subpack/libs/qrencode/Makefile
new file mode 100644
index 0000000..c5a5572
--- /dev/null
+++ b/external/subpack/libs/qrencode/Makefile
@@ -0,0 +1,97 @@
+#
+# Copyright (C) 2006-2017 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:=qrencode
+PKG_VERSION:=4.1.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://fukuchi.org/works/qrencode
+PKG_HASH:=e455d9732f8041cf5b9c388e345a641fd15707860f928e94507b1961256a6923
+
+PKG_MAINTAINER:=Jonathan Bennett <JBennett@incomsystems.biz>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_CONFIG_DEPENDS:=CONFIG_QRENCODE_PNG
+
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libqrencode
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Library for encoding data in a QR Code symbol
+  MENU:=1
+  URL:=https://fukuchi.org/works/qrencode/
+  DEPENDS:=+QRENCODE_PNG:libpng
+endef
+
+define Package/libqrencode/description
+Libqrencode is a C library for encoding data in a QR Code symbol,
+a kind of 2D symbology that can be scanned by handy terminals such
+as a mobile phone with CCD. The capacity of QR Code is up to 7000
+digits or 4000 characters, and is highly robust.
+endef
+
+define Package/libqrencode/config
+  config QRENCODE_PNG
+	bool "Enable PNG output"
+	depends on PACKAGE_libqrencode
+	select PACKAGE_libpng
+	default n
+endef
+
+define Package/qrencode
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=qrencode binary for producing qr codes
+  URL:=http://fukuchi.org/works/qrencode/
+  DEPENDS:=+libqrencode
+endef
+
+define Package/qrencode/description
+Qrencode is a C program for encoding data in a QR Code symbol,
+a kind of 2D symbology that can be scanned by handy terminals such
+as a mobile phone with CCD. The capacity of QR Code is up to 7000
+digits or 4000 characters, and is highly robust.
+endef
+
+CMAKE_OPTIONS += \
+	-DCMAKE_DISABLE_FIND_PACKAGE_PNG=O$(if $(CONFIG_QRENCODE_PNG),FF,N) \
+	-DWITHOUT_PNG=O$(if $(CONFIG_QRENCODE_PNG),FF,N) \
+	-DWITH_TOOLS=O$(if $(CONFIG_PACKAGE_qrencode),N,FF) \
+	-DWITH_TESTS=OFF \
+	-DBUILD_SHARED_LIBS=ON
+
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/qrencode.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libqrencode.so* $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libqrencode.pc $(1)/usr/lib/pkgconfig/
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libqrencode.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libqrencode.pc
+endef
+
+define Package/libqrencode/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libqrencode.so* $(1)/usr/lib/
+endef
+
+define Package/qrencode/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/qrencode $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libqrencode))
+$(eval $(call BuildPackage,qrencode))
diff --git a/external/subpack/libs/redis/Makefile b/external/subpack/libs/redis/Makefile
new file mode 100644
index 0000000..cb6030f
--- /dev/null
+++ b/external/subpack/libs/redis/Makefile
@@ -0,0 +1,100 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=redis
+PKG_VERSION:=6.2.14
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=https://download.redis.io/releases/
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_HASH:=34e74856cbd66fdb3a684fb349d93961d8c7aa668b06f81fd93ff267d09bc277
+
+PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec1@gmail.com>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:redis:redis
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+MAKE_FLAGS+= \
+	MALLOC="libc" \
+	USE_JEMALLOC="no" \
+	PREFIX="$(PKG_INSTALL_DIR)/usr" \
+	ARCH=""
+
+TARGET_LDFLAGS += -latomic
+
+define Package/redis/Default
+  SUBMENU:=Database
+  SECTION:=libs
+  CATEGORY:=Libraries
+  URL:=https://redis.io
+endef
+
+define Package/redis-server
+$(call  Package/redis/Default)
+  TITLE:=Redis server
+  DEPENDS:=+libpthread +libatomic
+endef
+
+define Package/redis-cli
+$(call  Package/redis/Default)
+  TITLE:=Redis cli
+  DEPENDS+=+libatomic
+endef
+
+define Package/redis-utils
+$(call  Package/redis/Default)
+  TITLE:=Redis utilities
+  DEPENDS:=+redis-server
+endef
+
+define Package/redis-full
+$(call  Package/redis/Default)
+  TITLE:=All Redis binaries (server,cli and utils)
+  DEPENDS:=+redis-utils +redis-cli
+  BUILDONLY:=1
+endef
+
+define Package/redis-full/description
+  Redis is an open source, BSD licensed, advanced key-value cache and store.
+  It is often referred to as a data structure server since keys can contain
+  strings, hashes, lists, sets, sorted sets, bitmaps and hyperloglogs.
+endef
+
+define Package/redis-server/conffiles
+/etc/redis.conf
+endef
+
+define Build/Compile
+	$(MAKE) -C "$(PKG_BUILD_DIR)/deps/hiredis" static $(MAKE_FLAGS)  $(MAKE_VARS)
+	$(MAKE) -C "$(PKG_BUILD_DIR)/deps/linenoise" $(MAKE_FLAGS)  $(MAKE_VARS)
+	$(MAKE) -C "$(PKG_BUILD_DIR)/deps/lua" posix $(MAKE_FLAGS)  $(MAKE_VARS) AR="${AR} ru"
+	$(call Build/Compile/Default)
+endef
+
+define Package/redis-server/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/redis-server $(1)/usr/bin/
+	$(INSTALL_DIR) $(1)/etc/init.d
+	$(INSTALL_BIN) ./files/redis.init $(1)/etc/init.d/redis
+	$(INSTALL_DIR) $(1)/etc
+	$(INSTALL_DATA) $(PKG_BUILD_DIR)/redis.conf $(1)/etc/
+	$(SED) "s|^dir .*|dir /var/lib/redis|" $(1)/etc/redis.conf
+endef
+
+define Package/redis-cli/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/redis-cli $(1)/usr/bin/
+endef
+
+define Package/redis-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/redis-{check-aof,benchmark} $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,redis-full))
+$(eval $(call BuildPackage,redis-server))
+$(eval $(call BuildPackage,redis-cli))
+$(eval $(call BuildPackage,redis-utils))
diff --git a/external/subpack/libs/redis/files/redis.init b/external/subpack/libs/redis/files/redis.init
new file mode 100755
index 0000000..686514d
--- /dev/null
+++ b/external/subpack/libs/redis/files/redis.init
@@ -0,0 +1,17 @@
+#!/bin/sh /etc/rc.common
+
+USE_PROCD=1
+START=95
+STOP=10
+
+REDIS_BIN="/usr/bin/redis-server"
+REDIS_CONFIG="/etc/redis.conf"
+REDIS_PID="/var/run/redis.pid"
+REDIS_DATA="/var/lib/redis"
+
+start_service() {
+	mkdir -p "$REDIS_DATA"
+	procd_open_instance redis
+	procd_set_param command "$REDIS_BIN" "$REDIS_CONFIG"
+	procd_close_instance
+}
diff --git a/external/subpack/libs/redis/patches/020-fix-atomicvar.patch b/external/subpack/libs/redis/patches/020-fix-atomicvar.patch
new file mode 100644
index 0000000..bf98b0e
--- /dev/null
+++ b/external/subpack/libs/redis/patches/020-fix-atomicvar.patch
@@ -0,0 +1,20 @@
+--- a/src/atomicvar.h
++++ b/src/atomicvar.h
+@@ -81,7 +81,7 @@
+ #define ANNOTATE_HAPPENS_AFTER(v)  ((void) v)
+ #endif
+ 
+-#if !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && defined(__STDC_VERSION__) && \
++#if defined(CONFIG_EDAC_ATOMIC_SCRUB) && !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && defined(__STDC_VERSION__) && \
+     (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__)
+ /* Use '_Atomic' keyword if the compiler supports. */
+ #undef  redisAtomic
+@@ -126,7 +126,7 @@
+     __atomic_store_n(&var,value,__ATOMIC_SEQ_CST)
+ #define REDIS_ATOMIC_API "atomic-builtin"
+ 
+-#elif defined(HAVE_ATOMIC)
++#elif defined(CONFIG_EDAC_ATOMIC_SCRUB) && defined(HAVE_ATOMIC)
+ /* Implementation using __sync macros. */
+ 
+ #define atomicIncr(var,count) __sync_add_and_fetch(&var,(count))
diff --git a/external/subpack/libs/rpcsvc-proto/Makefile b/external/subpack/libs/rpcsvc-proto/Makefile
new file mode 100644
index 0000000..710a9e6
--- /dev/null
+++ b/external/subpack/libs/rpcsvc-proto/Makefile
@@ -0,0 +1,51 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=rpcsvc-proto
+PKG_VERSION:=1.4.3
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/thkukuk/rpcsvc-proto/releases/download/v$(PKG_VERSION)
+PKG_HASH:=69315e94430f4e79c74d43422f4a36e6259e97e67e2677b2c7d7060436bd99b1
+
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_FIXUP:=autoreconf
+
+HOST_BUILD_DEPENDS:=gettext-full/host
+PKG_BUILD_DEPENDS:=rpcsvc-proto/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+define Package/rpcsvc-proto
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=rpcgen and rpcsvc proto.x files from glibc
+  URL:=https://github.com/thkukuk/rpcsvc-proto
+  DEPENDS:=$(INTL_DEPENDS)
+  BUILDONLY:=1
+endef
+
+define Package/rpcsvc-proto/description
+  This package contains rpcsvc proto.x files from glibc, which are missing in libtirpc.
+  Additional it contains rpcgen, which is needed to create header files and sources from protocol files.
+endef
+
+# need to use host tool
+define Build/Prepare
+	$(Build/Prepare/Default)
+	$(SED) 's,.*/rpcgen/rpcgen,\t$(STAGING_DIR_HOSTPKG)/bin/rpcgen,' $(PKG_BUILD_DIR)/rpcsvc/Makefile.am
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/rpcsvc $(1)/usr/include/
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,rpcsvc-proto))
diff --git a/external/subpack/libs/sbc/Makefile b/external/subpack/libs/sbc/Makefile
new file mode 100644
index 0000000..fd14717
--- /dev/null
+++ b/external/subpack/libs/sbc/Makefile
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2015 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:=sbc
+PKG_VERSION:=2.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@KERNEL/linux/bluetooth/
+PKG_HASH:=8f12368e1dbbf55e14536520473cfb338c84b392939cc9b64298360fd4a07992
+
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LIB
+PKG_MAINTAINER:=
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/sbc
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=sbc encoding library
+  DEPENDS:=+libsndfile
+  URL:=http://www.bluez.org
+endef
+
+define Package/sbc/description
+  Low Complexity Subband Coding for bluetooth audio profiles encoding and decoding.
+  Needed for A2DP support.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/sbc
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/sbc/sbc.h $(1)/usr/include/sbc/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsbc* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/sbc.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/sbc/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/sbc* $(1)/usr/bin/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsbc.so* $(1)/usr/lib/
+endef
+
+
+$(eval $(call BuildPackage,sbc))
diff --git a/external/subpack/libs/serdisplib/Makefile b/external/subpack/libs/serdisplib/Makefile
new file mode 100644
index 0000000..8b36a4a
--- /dev/null
+++ b/external/subpack/libs/serdisplib/Makefile
@@ -0,0 +1,83 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=serdisplib
+PKG_VERSION:=2.02
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/serdisplib
+PKG_HASH:=447b74007dc157b0378044245649850b26432b9185b6540ff681fcb0765c4d8b
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=GPL-2.0-or-later
+PLG_LICENSE_FILES:=COPYING
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+PKG_BUILD_DEPENDS:=libusb-compat
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/serdisplib
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=serdisplib
+  URL:=http://serdisplib.sourceforge.net/
+endef
+
+define Package/serdisplib/description
+ serdisplib started as a library to drive serial displays with
+ built-in controllers. It can optionally dynamically link with
+ libusb-compat, libgd and libpthread, some features require having
+ those packages installed as well.
+endef
+
+define Package/serdisplib-tools
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE:=serdisplib tools
+  URL:=http://serdisplib.sourceforge.net/
+  DEPENDS:=+serdisplib +libgd
+endef
+
+define Package/serdisplib-tools/description
+ serdisplib started as a library to drive serial displays with
+ built-in controllers. This package contains tools for serdisplib:
+ * l4m132c_tool
+ * l4m320t_tool
+ * multidisplay
+ * sdcmegtron_tool
+ * touchscreen_tool
+endef
+
+CONFIGURE_VARS += \
+	ac_cv_build=$(GNU_TARGET_NAME)
+
+CONFIGURE_ARGS += \
+	--enable-dynloading \
+	--disable-statictools
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/serdisplib
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/serdisplib/*.h $(1)/usr/include/serdisplib
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libserdisp.{a,so*} $(1)/usr/lib/
+endef
+
+define Package/serdisplib/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libserdisp.so* $(1)/usr/lib/
+endef
+
+define Package/serdisplib-tools/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/l4m132c_tool $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/l4m320t_tool $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/multidisplay $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/sdcmegtron_tool $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/touchscreen_tool $(1)/usr/bin
+endef
+
+$(eval $(call BuildPackage,serdisplib))
+$(eval $(call BuildPackage,serdisplib-tools))
diff --git a/external/subpack/libs/serdisplib/patches/002-allow-1bpp-framebuffer.patch b/external/subpack/libs/serdisplib/patches/002-allow-1bpp-framebuffer.patch
new file mode 100644
index 0000000..ada4281
--- /dev/null
+++ b/external/subpack/libs/serdisplib/patches/002-allow-1bpp-framebuffer.patch
@@ -0,0 +1,21 @@
+--- a/src/serdisp_specific_framebuffer.c
++++ b/src/serdisp_specific_framebuffer.c
+@@ -312,13 +312,15 @@ serdisp_t* serdisp_framebuffer_setup(con
+ 
+     if (fb_success) {
+       /* check if colour mode is supported */
+-      if (! (vinfo.bits_per_pixel == 16 || vinfo.bits_per_pixel == 24 || vinfo.bits_per_pixel == 32) ) {
++      if (! (vinfo.bits_per_pixel == 1 ||vinfo.bits_per_pixel == 16 || vinfo.bits_per_pixel == 24 || vinfo.bits_per_pixel == 32) ) {
+         sd_error(SERDISP_ERUNTIME, "unsupported colour depth (%d)", vinfo.bits_per_pixel);
+         fb_success = 0;
+       }
+     }
+-
+-    dd->scrbuf_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel/8;
++    if (vinfo.bits_per_pixel == 1)
++        dd->scrbuf_size = (vinfo.xres * vinfo.yres) / 8;
++    else
++        dd->scrbuf_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel/8;
+ 
+     if (fb_success) {
+       /* map framebuffer device to memory */
diff --git a/external/subpack/libs/serdisplib/patches/010-cross-compile.patch b/external/subpack/libs/serdisplib/patches/010-cross-compile.patch
new file mode 100644
index 0000000..3393222
--- /dev/null
+++ b/external/subpack/libs/serdisplib/patches/010-cross-compile.patch
@@ -0,0 +1,101 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -44,8 +44,8 @@ all:
+ 	done && test -z "$$fail"
+ 
+ install:
+-	$(top_srcdir)/mkinstalldirs $(libdir)/pkgconfig
+-	$(INSTALL_DATA) serdisplib.pc $(libdir)/pkgconfig/
++	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(libdir)/pkgconfig
++	$(INSTALL_DATA) serdisplib.pc $(DESTDIR)$(libdir)/pkgconfig/
+ 	@for dir in ${subdirs}; do \
+ 	  (cd $(srcdir) && cd $$dir && $(MAKE) install) \
+ 	  || case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
+--- a/server/Makefile.in
++++ b/server/Makefile.in
+@@ -102,9 +102,9 @@ distclean: clean
+ 
+ 
+ install: $(PROGRAMS)
+-	$(top_srcdir)/mkinstalldirs $(bindir)
+-	$(top_srcdir)/mkinstalldirs $(sbindir)
+-	$(top_srcdir)/mkinstalldirs $(sysconfdir)
++	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(bindir)
++	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(sbindir)
++	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(sysconfdir)
+ 	list='$(PROGRAMS_SBIN)'; \
+ 	for prog in $$list; do \
+ 	  $(INSTALL_PROGRAM) $$prog $(sbindir)/ ; \
+--- a/src/Makefile.in
++++ b/src/Makefile.in
+@@ -28,7 +28,7 @@ includedir = @includedir@
+ datarootdir = @datarootdir@
+ 
+ CC=@CC@
+-AR=@AR@ -r
++AR=@AR@
+ LN_S=@LN_S@
+ INSTALL=@INSTALL@
+ INSTALL_PROGRAM = @INSTALL_PROGRAM@
+@@ -184,14 +184,14 @@ programs: $(PROGRAMS)
+ 	$(CC) $(CFLAGS) $(DEFINES) -c $<
+ 
+ $(LIB_DIR)/$(LIB_STATIC): $(LIB_OBJECTS)
+-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/lib
+-	$(AR) $(LIB_DIR)/$(LIB_STATIC) $(LIB_OBJECTS)
++	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(top_srcdir)/lib
++	$(AR) -r -- $(LIB_DIR)/$(LIB_STATIC) $(LIB_OBJECTS)
+ 
+ $(LIB_DIR)/$(LIB_SHARED): $(LIB_OBJECTS)
+-	$(top_srcdir)/mkinstalldirs $(top_srcdir)/lib
++	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(top_srcdir)/lib
+ 	$(CC) -fPIC -shared $(SONAME_FLAG) -o $(LIB_DIR)/$(LIB_SHARED) $(LIB_OBJECTS) $(LDFLAGS) $(EXTRA_LIBS)
+-	cd $(LIB_DIR) && $(LN_S) -f $(LIB_SHARED) lib$(LIB_NAME).so.$(VERSION_MAJOR)
+-	cd $(LIB_DIR) && $(LN_S) -f lib$(LIB_NAME).so.$(VERSION_MAJOR) lib$(LIB_NAME).so
++	cd $(DESTDIR)$(LIB_DIR) && $(LN_S) -f $(LIB_SHARED) lib$(LIB_NAME).so.$(VERSION_MAJOR)
++	cd $(DESTDIR)$(LIB_DIR) && $(LN_S) -f lib$(LIB_NAME).so.$(VERSION_MAJOR) lib$(LIB_NAME).so
+ 
+ testserdisp: $(LIB_DIR)/$(LIB_STATIC) $(OBJECTS)
+ 	$(CC) -o testserdisp $(OBJECTS) $(LIB_SERDISP) $(EXTRA_LIBS_STATIC)
+@@ -204,20 +204,20 @@ distclean: clean
+ 	/bin/rm -f Makefile
+ 
+ install: $(LIB_DIR)/$(LIB_SHARED) $(LIB_DIR)/$(LIB_STATIC)
+-	$(top_srcdir)/mkinstalldirs $(bindir)
+-	$(top_srcdir)/mkinstalldirs $(libdir)
+-	$(top_srcdir)/mkinstalldirs $(includedir)
+-	$(top_srcdir)/mkinstalldirs $(includedir)/serdisplib
++	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(bindir)
++	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(libdir)
++	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(includedir)
++	$(top_srcdir)/mkinstalldirs $(DESTDIR)$(includedir)/serdisplib
+ 	
+-	$(INSTALL_PROGRAM) $(PROGRAMS) $(bindir)/
+-	$(INSTALL_PROGRAM) $(LIB_DIR)/$(LIB_SHARED) $(libdir)/
+-	$(INSTALL_DATA) $(LIB_DIR)/$(LIB_STATIC) $(libdir)/
++	$(INSTALL_PROGRAM) $(PROGRAMS) $(DESTDIR)$(bindir)/
++	$(INSTALL_PROGRAM) $(LIB_DIR)/$(LIB_SHARED) $(DESTDIR)$(libdir)/
++	$(INSTALL_DATA) $(LIB_DIR)/$(LIB_STATIC) $(DESTDIR)$(libdir)/
+ 	list='$(LIB_HEADERFILES)'; \
+ 	for headerfile in $$list; do \
+-	  $(INSTALL_DATA) ../include/serdisplib/$$headerfile $(includedir)/serdisplib/ ; \
++	  $(INSTALL_DATA) ../include/serdisplib/$$headerfile $(DESTDIR)$(includedir)/serdisplib/ ; \
+ 	done
+-	cd $(libdir) && $(LN_S) -f $(LIB_SHARED) lib$(LIB_NAME).so.$(VERSION_MAJOR)
+-	cd $(libdir) && $(LN_S) -f lib$(LIB_NAME).so.$(VERSION_MAJOR) lib$(LIB_NAME).so
++	cd $(DESTDIR)$(libdir) && $(LN_S) -f $(LIB_SHARED) lib$(LIB_NAME).so.$(VERSION_MAJOR)
++	cd $(DESTDIR)$(libdir) && $(LN_S) -f lib$(LIB_NAME).so.$(VERSION_MAJOR) lib$(LIB_NAME).so
+ 
+ uninstall:
+ 	-/bin/rm -f $(libdir)/libserdisp*
+--- a/tools/Makefile.in
++++ b/tools/Makefile.in
+@@ -151,7 +151,7 @@ distclean: clean
+ install: $(PROGRAMS)
+ 	list='$(PROGRAMS)'; \
+ 	for prog in $$list; do \
+-	  $(INSTALL_PROGRAM) $$prog $(bindir)/ ; \
++	  $(INSTALL_PROGRAM) $$prog $(DESTDIR)$(bindir)/ ; \
+ 	done
+ 
+ uninstall: $(PROGRAMS)
diff --git a/external/subpack/libs/slang2/Makefile b/external/subpack/libs/slang2/Makefile
new file mode 100644
index 0000000..48a909f
--- /dev/null
+++ b/external/subpack/libs/slang2/Makefile
@@ -0,0 +1,195 @@
+#
+# Copyright (C) 2006-2011 Openwrt.org
+# Copyright (C) 2011 SMBPhone Inc.
+# Copyright (C) 2019, 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:=slang
+PKG_VERSION:=2.3.3
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://www.jedsoft.org/releases/slang \
+	https://www.jedsoft.org/releases/slang/old
+PKG_HASH:=f9145054ae131973c61208ea82486d5dd10e3c5cdad23b7c4a0617743c8f5a18
+
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
+
+PKG_BUILD_PARALLEL:=0
+PKG_CONFIG_DEPENDS:= \
+	CONFIG_BUILD_NLS \
+	CONFIG_PACKAGE_libslang2-mod-onig \
+	CONFIG_PACKAGE_libslang2-mod-png \
+	CONFIG_PACKAGE_libslang2-mod-zlib
+
+SLANG_MODULES:= base64 chksum csv fcntl fork histogram iconv json onig \
+	png rand select slsmg socket stats sysconf termios varray zlib
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/libslang2/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=S-Lang Programmer's Library
+  URL:=https://www.jedsoft.org/slang/
+endef
+
+define Package/libslang2/Default/description
+Multi-platform programmer's library providing facilities for interactive
+applications. Includes such things as display/screen management,
+keyboard input, keymaps, etc. Includes the embeddable S-Lang
+interpreter.
+endef
+
+define Package/libslang2
+$(call Package/libslang2/Default)
+  DEPENDS:=+terminfo
+endef
+
+define Package/libslang2/description
+$(call Package/libslang2/Default/description)
+endef
+
+define Package/libslang2-modules
+$(call Package/libslang2/Default)
+  TITLE+= (all modules)
+  DEPENDS:=@PACKAGE_libslang2 $(foreach mod,$(SLANG_MODULES),+libslang2-mod-$(mod))
+endef
+
+define Package/libslang2-modules/description
+$(call Package/libslang2/Default/description)
+
+This package installs all of S-Lang's bundled modules.
+endef
+
+define Package/libslang2-mod/Default
+$(call Package/libslang2/Default)
+  DEPENDS:=@PACKAGE_libslang2
+endef
+
+define Package/libslang2-mod-iconv
+$(call Package/libslang2-mod/Default)
+  TITLE+= (iconv module)
+  DEPENDS+=$(ICONV_DEPENDS)
+endef
+
+define Package/libslang2-mod-onig
+$(call Package/libslang2-mod/Default)
+  TITLE+= (onig module)
+  DEPENDS+=+PACKAGE_libslang2-mod-onig:oniguruma
+endef
+
+define Package/libslang2-mod-png
+$(call Package/libslang2-mod/Default)
+  TITLE+= (png module)
+  DEPENDS+=+PACKAGE_libslang2-mod-png:libpng
+endef
+
+define Package/libslang2-mod-zlib
+$(call Package/libslang2-mod/Default)
+  TITLE+= (zlib module)
+  DEPENDS+=+PACKAGE_libslang2-mod-zlib:zlib
+endef
+
+define Package/slsh
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=S-Lang shell
+  URL:=https://www.jedsoft.org/slang/slsh.html
+  DEPENDS:=+libslang2 +libslang2-modules
+endef
+
+define Package/slsh/description
+This is a shell which is mostly just a wrapper around the S-Lang
+Interpreter, which is part of the S-Lang Library.
+endef
+
+TARGET_CFLAGS+= $(FPIC)
+
+CONFIGURE_ARGS+= \
+	--enable-largefile \
+	--enable-warnings \
+	--with-readline=slang \
+	--with-terminfo=default \
+	--without-pcre \
+	--without-x \
+	$(if $(CONFIG_BUILD_NLS),--with-iconv="$(ICONV_PREFIX)",--without-iconv) \
+	$(if $(CONFIG_PACKAGE_libslang2-mod-onig),--with-onig="$(STAGING_DIR)/usr",--without-onig) \
+	$(if $(CONFIG_PACKAGE_libslang2-mod-png),--with-png="$(STAGING_DIR)/usr",--without-png) \
+	$(if $(CONFIG_PACKAGE_libslang2-mod-zlib),--with-z="$(STAGING_DIR)/usr",--without-z)
+
+define Build/Compile
+	$(call Build/Compile/Default,)
+	$(call Build/Compile/Default,static)
+endef
+
+# Default install last, so that the dynamic slsh is installed
+define Build/Install
+	$(call Build/Install/Default,install-static)
+	$(call Build/Install/Default,)
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libslang.{a,so*} $(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/slang.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libslang2/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libslang.so* $(1)/usr/lib/
+endef
+
+Package/libslang2-modules/install:=:
+
+define Package/slsh/install
+	$(INSTALL_DIR) $(1)/etc
+	$(CP) $(PKG_INSTALL_DIR)/etc/slsh.rc $(1)/etc/
+
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/slsh $(1)/usr/bin/
+
+	$(INSTALL_DIR) $(1)/usr/share
+	$(CP) $(PKG_INSTALL_DIR)/usr/share/slsh/ $(1)/usr/share/
+endef
+
+define BuildModule
+  ifndef Package/libslang2-mod-$(1)
+    define Package/libslang2-mod-$(1)
+    $$(call Package/libslang2-mod/Default)
+      TITLE+= ($(1) module)
+    endef
+  endif
+
+  define Package/libslang2-mod-$(1)/description
+$$(call Package/libslang2/Default/description)
+
+This package contains the $(1) module.
+  endef
+
+  define Package/libslang2-mod-$(1)/install
+	$$(INSTALL_DIR) $$(1)/usr/lib/slang/v2/modules
+	$$(CP) $$(PKG_INSTALL_DIR)/usr/lib/slang/v2/modules/$(1)-module.so $$(1)/usr/lib/slang/v2/modules/
+  endef
+
+  $$(eval $$(call BuildPackage,libslang2-mod-$(1)))
+endef
+
+$(foreach mod,$(SLANG_MODULES),$(eval $(call BuildModule,$(mod))))
+
+$(eval $(call BuildPackage,libslang2))
+$(eval $(call BuildPackage,libslang2-modules))
+$(eval $(call BuildPackage,slsh))
diff --git a/external/subpack/libs/slang2/patches/001-skip-terminfo-dir-test.patch b/external/subpack/libs/slang2/patches/001-skip-terminfo-dir-test.patch
new file mode 100644
index 0000000..dcd02f5
--- /dev/null
+++ b/external/subpack/libs/slang2/patches/001-skip-terminfo-dir-test.patch
@@ -0,0 +1,11 @@
+--- a/configure
++++ b/configure
+@@ -6987,7 +6987,7 @@ TERMCAP=-ltermcap
+ 
+ for terminfo_dir in $JD_Terminfo_Dirs
+ do
+-   if test -d $terminfo_dir
++   if true
+    then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ $as_echo "yes" >&6; }
diff --git a/external/subpack/libs/slang2/patches/002-use-target-ar.patch b/external/subpack/libs/slang2/patches/002-use-target-ar.patch
new file mode 100644
index 0000000..d2ef8bb
--- /dev/null
+++ b/external/subpack/libs/slang2/patches/002-use-target-ar.patch
@@ -0,0 +1,11 @@
+--- a/src/Makefile.in
++++ b/src/Makefile.in
+@@ -73,7 +73,7 @@ INSTALL_DATA	= @INSTALL_DATA@
+ MKINSDIR	= @CONFIG_DIR@/autoconf/mkinsdir.sh
+ RM 		= rm -f
+ RM_R		= rm -rf
+-AR_CR 		= ar cr
++AR_CR 		= $(AR) cr
+ RMDIR 		= rmdir
+ LN 		= /bin/ln -sf
+ CP 		= cp
diff --git a/external/subpack/libs/speex/Makefile b/external/subpack/libs/speex/Makefile
new file mode 100644
index 0000000..9f493ee
--- /dev/null
+++ b/external/subpack/libs/speex/Makefile
@@ -0,0 +1,68 @@
+#
+# Copyright (C) 2006-2017 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:=speex
+PKG_VERSION:=1.2.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://downloads.us.xiph.org/releases/speex/
+PKG_HASH:=4b44d4f2b38a370a2d98a78329fefc56a0cf93d1c1be70029217baae6628feea
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+PKG_CPE_ID:=cpe:/a:xiph:speex
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libspeex
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Open source speech compression codec library
+  URL:=http://www.speex.org/
+  MAINTAINER:=Peter Wagner <tripolar@gmx.at>
+endef
+
+define Package/libspeex/description
+	Open source patent-free speech compression codec library.
+	Speex is an Open Source/Free Software patent-free audio compression
+	format designed for speech. The Speex Project aims to lower the
+	barrier of entry for voice applications by providing a free
+	alternative to expensive proprietary speech codecs. Moreover, Speex
+	is well-adapted to Internet applications and provides useful features
+	that are not present in most other codecs.
+
+	This package contains the shared codec library, needed by other programs.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/speex $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libspeex.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/speex.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libspeex/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libspeex.so.* $(1)/usr/lib/
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--disable-binaries \
+	$(if $(CONFIG_SOFT_FLOAT),--enable-fixed-point --disable-float-api --disable-vbr)
+
+$(eval $(call BuildPackage,libspeex))
diff --git a/external/subpack/libs/speexdsp/Makefile b/external/subpack/libs/speexdsp/Makefile
new file mode 100644
index 0000000..14a350c
--- /dev/null
+++ b/external/subpack/libs/speexdsp/Makefile
@@ -0,0 +1,65 @@
+#
+# Copyright (C) 2006-2017 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:=speexdsp
+PKG_VERSION:=1.2.0
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://downloads.us.xiph.org/releases/speex/
+PKG_HASH:=682042fc6f9bee6294ec453f470dadc26c6ff29b9c9e9ad2ffc1f4312fd64771
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libspeexdsp
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Open source speech compression codec library output to DSP
+  URL:=http://www.speex.org/
+  MAINTAINER:=Peter Wagner <tripolar@gmx.at>
+endef
+
+define Package/libspeexdsp/description
+	Open source patent-free speech compression codec library.
+	Speex is an Open Source/Free Software patent-free audio compression
+	format designed for speech. The Speex Project aims to lower the
+	barrier of entry for voice applications by providing a free
+	alternative to expensive proprietary speech codecs. Moreover, Speex
+	is well-adapted to Internet applications and provides useful features
+	that are not present in most other codecs.
+
+	This package contains the shared dsp library, needed by other programs.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/speex $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libspeexdsp.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/speexdsp.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libspeexdsp/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libspeexdsp.so.* $(1)/usr/lib/
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--enable-static \
+	--disable-examples \
+	$(if $(CONFIG_SOFT_FLOAT),--enable-fixed-point --disable-float-api)
+
+$(eval $(call BuildPackage,libspeexdsp))
diff --git a/external/subpack/libs/spice-protocol/Makefile b/external/subpack/libs/spice-protocol/Makefile
new file mode 100644
index 0000000..213de0d
--- /dev/null
+++ b/external/subpack/libs/spice-protocol/Makefile
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2019-2020 Yousong Zhou <yszhou4tech@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:=spice-protocol
+PKG_VERSION:=0.14.4
+PKG_RELEASE:=1
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://www.spice-space.org/download/releases
+PKG_HASH:=04ffba610d9fd441cfc47dfaa135d70096e60b1046d2119d8db2f8ea0d17d912
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_MAINTAINER:=Yousong Zhou <yszhou4tech@gmail.com>
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/spice-protocol
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=SPICE - headers defining protocols
+  URL:=https://www.spice-space.org/index.html
+  BUILDONLY:=1
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/share/pkgconfig/* $(1)/usr/lib/pkgconfig
+endef
+
+$(eval $(call BuildPackage,spice-protocol))
diff --git a/external/subpack/libs/spice/Makefile b/external/subpack/libs/spice/Makefile
new file mode 100644
index 0000000..c8b06da
--- /dev/null
+++ b/external/subpack/libs/spice/Makefile
@@ -0,0 +1,78 @@
+#
+# Copyright (C) 2019 Yousong Zhou <yszhou4tech@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:=spice
+PKG_VERSION:=0.15.0
+PKG_RELEASE:=3
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=https://www.spice-space.org/download/releases/spice-server
+PKG_HASH:=b320cf8f4bd2852750acb703c15b72856027e5a8554f8217dfbb3cc09deba0f5
+
+PKG_MAINTAINER:=Yousong Zhou <yszhou4tech@gmail.com>
+PKG_LICENSE:=LGPL-2.1-only
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:spice_project:spice
+
+PKG_BUILD_DEPENDS:=spice-protocol
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/libspice-server
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=SPICE server library
+  URL:=https://www.spice-space.org/index.html
+  DEPENDS:=+glib2 +libjpeg +libopenssl +pixman +zlib +libstdcpp
+endef
+
+# audio codec
+MESON_ARGS += \
+	-Dopus=disabled
+
+MESON_ARGS += \
+	-Dgstreamer=no \
+	-Dlz4=false \
+	-Dsasl=false \
+	-Dsmartcard=disabled \
+	-Dalignment-checks=false \
+	-Dextra-checks=false \
+	-Dstatistics=false \
+	-Dmanual=false \
+	-Dinstrumentation=no \
+	-Dtests=false
+
+MESON_ARGS += \
+	-Dspice-common:alignment-checks=false \
+	-Dspice-common:extra-checks=false \
+	-Dspice-common:opus=disabled \
+	-Dspice-common:instrumentation=no \
+	-Dspice-common:smartcard=disabled \
+	-Dspice-common:python-checks=false \
+	-Dspice-common:manual=false \
+	-Dspice-common:generate-code=none \
+	-Dspice-common:tests=false \
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/spice-server
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/spice-server/*.h $(1)/usr/include/spice-server
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libspice-server.* $(1)/usr/lib
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/spice-server.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/libspice-server/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libspice-server.so* $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,libspice-server))
diff --git a/external/subpack/libs/spice/patches/010-doxy.patch b/external/subpack/libs/spice/patches/010-doxy.patch
new file mode 100644
index 0000000..837cad4
--- /dev/null
+++ b/external/subpack/libs/spice/patches/010-doxy.patch
@@ -0,0 +1,7 @@
+--- a/meson.build
++++ b/meson.build
+@@ -229,4 +229,3 @@ endif
+ configure_file(output : 'config.h',
+                configuration : spice_server_config_data)
+ 
+-run_target('doxy', command : './doxygen.sh')
diff --git a/external/subpack/libs/spice/patches/030-include-generated-code.patch b/external/subpack/libs/spice/patches/030-include-generated-code.patch
new file mode 100644
index 0000000..0e93d7d
--- /dev/null
+++ b/external/subpack/libs/spice/patches/030-include-generated-code.patch
@@ -0,0 +1,32 @@
+From 0ce9cecd0912f78b75600f3f428bdd943bf9622b Mon Sep 17 00:00:00 2001
+From: Rosen Penev <rosenp@gmail.com>
+Date: Fri, 9 Oct 2020 04:19:01 -0700
+Subject: [PATCH] don't regenerate [de]marshallers
+
+The release tarballs already include these files.
+
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+---
+ subprojects/spice-common/common/meson.build | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/subprojects/spice-common/common/meson.build
++++ b/subprojects/spice-common/common/meson.build
+@@ -189,4 +189,17 @@ if spice_common_generate_server_code
+   spice_common_server_dep = declare_dependency(sources : spice_common_server_dep_sources,
+                                                link_with : spice_common_server_lib,
+                                                dependencies : spice_common_dep)
++else
++  spice_common_server_sources = ['generated_server_marshallers.c', 'generated_server_marshallers.h']
++  spice_common_server_sources += ['generated_server_demarshallers.c']
++  spice_common_server_dep_sources = ['generated_server_marshallers.c', 'generated_server_marshallers.h']
++  spice_common_server_dep_sources += ['generated_server_demarshallers.c']
++
++  spice_common_server_lib = static_library('spice-common-server', spice_common_server_sources,
++                                           install : false,
++                                           dependencies : spice_common_dep)
++
++  spice_common_server_dep = declare_dependency(sources : spice_common_server_dep_sources,
++                                               link_with : spice_common_server_lib,
++                                               dependencies : spice_common_dep)
+ endif
diff --git a/external/subpack/libs/spice/patches/040-only-server.patch b/external/subpack/libs/spice/patches/040-only-server.patch
new file mode 100644
index 0000000..1506407
--- /dev/null
+++ b/external/subpack/libs/spice/patches/040-only-server.patch
@@ -0,0 +1,11 @@
+--- a/meson.build
++++ b/meson.build
+@@ -208,8 +208,6 @@ add_project_arguments(cxx_compiler.get_s
+ # Subdirectories
+ #
+ subdir('server')
+-subdir('tools')
+-subdir('docs')
+ 
+ #
+ # write config.h
diff --git a/external/subpack/libs/spice/patches/050-no-mkenums.patch b/external/subpack/libs/spice/patches/050-no-mkenums.patch
new file mode 100644
index 0000000..106f9d7
--- /dev/null
+++ b/external/subpack/libs/spice/patches/050-no-mkenums.patch
@@ -0,0 +1,29 @@
+From 60f49745eb80eb84ff293cfadf8092b66b6a088c Mon Sep 17 00:00:00 2001
+From: Rosen Penev <rosenp@gmail.com>
+Date: Fri, 9 Oct 2020 04:22:31 -0700
+Subject: [PATCH] don't regenerate enums files
+
+The release tarballs already include these files.
+
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+---
+ server/meson.build | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+--- a/server/meson.build
++++ b/server/meson.build
+@@ -43,13 +43,7 @@ spice_server_headers = [
+ 
+ install_headers(spice_server_headers, subdir : 'spice-server')
+ 
+-# generate enums
+-gnome = import('gnome')
+-spice_server_enums = gnome.mkenums('spice-server-enums',
+-                                   sources : 'spice-server.h',
+-                                   symbol_prefix : 'SPICE',
+-                                   c_template: 'spice-server-enums.c.tmpl',
+-                                   h_template: 'spice-server-enums.h.tmpl')
++spice_server_enums = ['spice-server-enums.c', 'spice-server-enums.h']
+ 
+ spice_server_sources = [
+   spice_server_headers,
diff --git a/external/subpack/libs/sqlite3/Config-cli.in b/external/subpack/libs/sqlite3/Config-cli.in
new file mode 100644
index 0000000..752db6e
--- /dev/null
+++ b/external/subpack/libs/sqlite3/Config-cli.in
@@ -0,0 +1,24 @@
+menu "Configuration"
+	depends on PACKAGE_sqlite3-cli
+
+choice
+	prompt "Select command-line editing support"
+	default SQLITE3_LIBEDIT
+
+	config SQLITE3_LIBEDIT
+	bool "libedit"
+	help
+	  Link against libedit. This is the default.
+
+	config SQLITE3_READLINE
+	bool "readline"
+	help
+	  Link against GNU readline.
+
+	config SQLITE3_READLINE_NONE
+	bool "none"
+	help
+	  Disable command-line editing support.
+
+endchoice
+endmenu
diff --git a/external/subpack/libs/sqlite3/Config-lib.in b/external/subpack/libs/sqlite3/Config-lib.in
new file mode 100644
index 0000000..12313c6
--- /dev/null
+++ b/external/subpack/libs/sqlite3/Config-lib.in
@@ -0,0 +1,54 @@
+menu "Configuration"
+	depends on PACKAGE_libsqlite3
+
+config SQLITE3_BATCH_ATOMIC_WRITE
+	bool "Batch-atomic write support"
+	default n
+	help
+	  Enable batch-atomic write optimization (supported only on F2FS).
+
+config SQLITE3_COLUMN_METADATA
+	bool "Column metadata API extensions"
+	default y
+	help
+	  Includes some additional APIs that provide convenient access to
+	  meta-data about tables and queries.
+
+config SQLITE3_DYNAMIC_EXTENSIONS
+	bool "Dynamic extensions"
+	default y
+	help
+	  Enable loadable extensions.
+
+config SQLITE3_FTS3
+	bool "FTS3 support"
+	default y
+	help
+	  Enable FTS3 support.
+
+config SQLITE3_FTS4
+	bool "FTS4 support"
+	depends on SQLITE3_FTS3
+	default y
+	help
+	  Enable FTS4 support.
+
+config SQLITE3_FTS5
+	bool "FTS5 support"
+	default y
+	help
+	  Enable FTS5 support.
+
+config SQLITE3_RTREE
+	bool "R-Tree support"
+	default y
+	help
+	  Enable R-Tree support.
+
+config SQLITE3_SESSION
+	bool "Session extension"
+	default n
+	help
+	  Enable the session extension (default no).
+
+endmenu
diff --git a/external/subpack/libs/sqlite3/Makefile b/external/subpack/libs/sqlite3/Makefile
new file mode 100644
index 0000000..ade91e2
--- /dev/null
+++ b/external/subpack/libs/sqlite3/Makefile
@@ -0,0 +1,142 @@
+#
+# Copyright (C) 2006-2014 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:=sqlite
+PKG_VERSION:=3460100
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-autoconf-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://www.sqlite.org/2024/
+PKG_HASH:=67d3fe6d268e6eaddcae3727fce58fcc8e9c53869bdd07a0c61e38ddf2965071
+
+PKG_CPE_ID:=cpe:/a:sqlite:sqlite
+PKG_LICENSE:=PUBLICDOMAIN
+PKG_LICENSE_FILES:=
+PKG_MAINTAINER:=
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-autoconf-$(PKG_VERSION)
+PKG_BUILD_PARALLEL:=1
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
+PKG_CONFIG_DEPENDS := \
+	CONFIG_SQLITE3_BATCH_ATOMIC_WRITE \
+	CONFIG_SQLITE3_COLUMN_METADATA \
+	CONFIG_SQLITE3_DYNAMIC_EXTENSIONS \
+	CONFIG_SQLITE3_FTS3 \
+	CONFIG_SQLITE3_FTS4 \
+	CONFIG_SQLITE3_FTS5 \
+	CONFIG_SQLITE3_LIBEDIT \
+	CONFIG_SQLITE3_READLINE \
+	CONFIG_SQLITE3_RTREE \
+	CONFIG_SQLITE3_SESSION
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/sqlite3/Default
+  SUBMENU:=Database
+  TITLE:=SQLite (v3.x) database engine
+  URL:=https://www.sqlite.org/
+endef
+
+define Package/sqlite3/Default/description
+ SQLite is a small C library that implements a self-contained, embeddable,
+ zero-configuration SQL database engine.
+endef
+
+define Package/libsqlite3
+  $(call Package/sqlite3/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libpthread +zlib
+  TITLE+= (library)
+  ABI_VERSION:=0
+endef
+
+define Package/libsqlite3/description
+$(call Package/sqlite3/Default/description)
+ This package contains the SQLite (v3.x) shared library, used by other
+ programs.
+endef
+
+define Package/libsqlite3/config
+  source "$(SOURCE)/Config-lib.in"
+endef
+
+define Package/sqlite3-cli
+  $(call Package/sqlite3/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  DEPENDS := \
+	  +libsqlite3 \
+	  +SQLITE3_LIBEDIT:libedit \
+	  +SQLITE3_READLINE:libreadline \
+	  +SQLITE3_READLINE:libncursesw
+  TITLE+= (cli)
+endef
+
+define Package/sqlite3-cli/description
+$(call Package/sqlite3/Default/description)
+ This package contains a terminal-based front-end to the SQLite (v3.x) library
+ that can evaluate queries interactively and display the results in multiple
+ formats.
+endef
+
+define Package/sqlite3-cli/config
+  source "$(SOURCE)/Config-cli.in"
+endef
+
+TARGET_CFLAGS += \
+	-DHAVE_ISNAN \
+	-DHAVE_MALLOC_USABLE_SIZE \
+	-DSQLITE_ENABLE_UNLOCK_NOTIFY \
+	$(if $(CONFIG_SQLITE3_BATCH_ATOMIC_WRITE),-DSQLITE_ENABLE_BATCH_ATOMIC_WRITE) \
+	$(if $(CONFIG_SQLITE3_COLUMN_METADATA),-DSQLITE_ENABLE_COLUMN_METADATA)
+
+CONFIGURE_ARGS += \
+	--disable-debug \
+	--disable-static-shell \
+	--enable-shared \
+	--enable-static \
+	--enable-threadsafe \
+	$(if $(CONFIG_SQLITE3_DYNAMIC_EXTENSIONS),--enable-dynamic-extensions,--disable-dynamic-extensions) \
+	$(if $(CONFIG_SQLITE3_FTS3),--enable-fts3,--disable-fts3) \
+	$(if $(CONFIG_SQLITE3_FTS4),--enable-fts4,--disable-fts4) \
+	$(if $(CONFIG_SQLITE3_FTS5),--enable-fts5,--disable-fts5) \
+	$(if $(CONFIG_SQLITE3_RTREE),--enable-rtree,--disable-rtree) \
+	$(if $(CONFIG_SQLITE3_SESSION),--enable-session,--disable-session)
+
+ifeq ($(CONFIG_SQLITE3_LIBEDIT),y)
+CONFIGURE_ARGS+=--disable-readline
+else ifeq ($(CONFIG_SQLITE3_READLINE),y)
+CONFIGURE_ARGS+=--disable-editline
+else
+CONFIGURE_ARGS+=--disable-editline --disable-readline
+endif
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsqlite3.{a,so*} $(1)/usr/lib
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/sqlite3{,ext}.h $(1)/usr/include
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/sqlite3.pc $(1)/usr/lib/pkgconfig
+endef
+
+define Package/libsqlite3/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libsqlite3.so.$(ABI_VERSION)* $(1)/usr/lib
+endef
+
+define Package/sqlite3-cli/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/sqlite3 $(1)/usr/bin
+endef
+
+$(eval $(call BuildPackage,libsqlite3))
+$(eval $(call BuildPackage,sqlite3-cli))
diff --git a/external/subpack/libs/sx1302_hal/Makefile b/external/subpack/libs/sx1302_hal/Makefile
new file mode 100644
index 0000000..661968d
--- /dev/null
+++ b/external/subpack/libs/sx1302_hal/Makefile
@@ -0,0 +1,109 @@
+#
+# Copyright (C) 2022 TDT AG <development@tdt.de>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=sx1302_hal
+PKG_VERSION:=2.1.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/Lora-net/sx1302_hal/tar.gz/V$(PKG_VERSION)?
+PKG_HASH:=4b62aa6a83ad449c68fdd844fc35024586c9faabca3c5a90a2544735b380de5b
+
+PKG_MAINTAINER:=Marcus Schref <mschref@tdt.de>
+PKG_LICENSE:=MIT BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE.TXT
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/sx1302_hal/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  SUBMENU:=IoT
+  TITLE:=SX1302/SX1303 HAL
+endef
+
+define Package/sx1302_hal-tests
+  $(call Package/sx1302_hal/Default)
+  TITLE+=(Tests)
+  DEPENDS:=+kmod-usb-acm
+endef
+
+define Package/sx1302_hal-tests/description
+  Tests for SX1302/SX1303 Hardware Abstraction Layer
+endef
+
+define Package/sx1302_hal-utils
+  $(call Package/sx1302_hal/Default)
+  TITLE+=(Utilities)
+  DEPENDS:=+kmod-usb-acm
+endef
+
+define Package/sx1302_hal-utils/description
+  Utilities for SX1302/SX1303 Hardware Abstraction Layer
+endef
+
+CFLAGS = $(TARGET_CFLAGS)
+
+define Build/Compile
+	$(MAKE) -C $(PKG_BUILD_DIR)/libtools \
+		CROSS_COMPILE="$(TARGET_CROSS)" \
+		ARCH="$(ARCH)"
+
+	$(MAKE) -C $(PKG_BUILD_DIR)/libloragw \
+		CROSS_COMPILE="$(TARGET_CROSS)" \
+		ARCH="$(ARCH)"
+
+	$(MAKE) -C $(PKG_BUILD_DIR)/util_boot \
+		CROSS_COMPILE="$(TARGET_CROSS)" \
+		ARCH="$(ARCH)"
+
+	$(MAKE) -C $(PKG_BUILD_DIR)/util_chip_id \
+		CROSS_COMPILE="$(TARGET_CROSS)" \
+		ARCH="$(ARCH)"
+
+	$(MAKE) -C $(PKG_BUILD_DIR)/util_net_downlink \
+		CROSS_COMPILE="$(TARGET_CROSS)" \
+		ARCH="$(ARCH)"
+
+	$(MAKE) -C $(PKG_BUILD_DIR)/util_spectral_scan \
+		CROSS_COMPILE="$(TARGET_CROSS)" \
+		ARCH="$(ARCH)"
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_BUILD_DIR)/libtools/inc/tinymt32.h $(1)/usr/include
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/libtools/libtinymt32.a $(1)/usr/lib
+
+	$(INSTALL_DIR) $(1)/usr/include/lgw
+	$(CP) $(PKG_BUILD_DIR)/libloragw/inc/*.h $(1)/usr/include/lgw
+
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/libloragw/*.a $(1)/usr/lib
+endef
+
+define Package/sx1302_hal-tests/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/libloragw/test* $(1)/usr/bin
+endef
+
+define Package/sx1302_hal-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/util_boot/boot $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/util_chip_id/chip_id $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/util_net_downlink/net_downlink \
+		$(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_BUILD_DIR)/util_spectral_scan/spectral_scan \
+		$(1)/usr/bin
+endef
+
+$(eval $(call BuildPackage,sx1302_hal-tests))
+$(eval $(call BuildPackage,sx1302_hal-utils))
diff --git a/external/subpack/libs/sx1302_hal/patches/000-edit_cflags.patch b/external/subpack/libs/sx1302_hal/patches/000-edit_cflags.patch
new file mode 100644
index 0000000..9a6fde2
--- /dev/null
+++ b/external/subpack/libs/sx1302_hal/patches/000-edit_cflags.patch
@@ -0,0 +1,35 @@
+From 389e8138f543baf334442ca52edf5f7b4cfe13dc Mon Sep 17 00:00:00 2001
+From: Marcus Schref <mschref@web.de>
+Date: Mon, 22 Aug 2022 10:02:13 +0200
+Subject: [PATCH] sx1302_hal: edit cflags
+
+Enable use of TARGET_CFLAGS in addition to specified CFLAGS
+
+Signed-off-by: Marcus Schref <mschref@web.de>
+---
+ libloragw/Makefile | 2 +-
+ libtools/Makefile  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/libloragw/Makefile
++++ b/libloragw/Makefile
+@@ -11,7 +11,7 @@ CROSS_COMPILE ?=
+ CC := $(CROSS_COMPILE)gcc
+ AR := $(CROSS_COMPILE)ar
+ 
+-CFLAGS := -O2 -Wall -Wextra -std=c99 -Iinc -I. -I../libtools/inc
++CFLAGS += -O2 -Wall -Wextra -std=c99 -Iinc -I. -I../libtools/inc
+ 
+ OBJDIR = obj
+ INCLUDES = $(wildcard inc/*.h) $(wildcard ../libtools/inc/*.h)
+--- a/libtools/Makefile
++++ b/libtools/Makefile
+@@ -7,7 +7,7 @@ CROSS_COMPILE ?=
+ CC := $(CROSS_COMPILE)gcc
+ AR := $(CROSS_COMPILE)ar
+ 
+-CFLAGS := -O2 -Wall -Wextra -std=c99 -Iinc -I.
++CFLAGS += -O2 -Wall -Wextra -std=c99 -Iinc -I.
+ 
+ OBJDIR = obj
+ INCLUDES = $(wildcard inc/*.h)
diff --git a/external/subpack/libs/sx1302_hal/patches/001-add_compatibility_with_basicstation.patch b/external/subpack/libs/sx1302_hal/patches/001-add_compatibility_with_basicstation.patch
new file mode 100644
index 0000000..4d93a59
--- /dev/null
+++ b/external/subpack/libs/sx1302_hal/patches/001-add_compatibility_with_basicstation.patch
@@ -0,0 +1,22 @@
+From a6ae15dc6709e32f0604b6eeb0f07cc50bde18b1 Mon Sep 17 00:00:00 2001
+From: Marcus Schref <mschref@web.de>
+Date: Mon, 22 Aug 2022 10:06:03 +0200
+Subject: [PATCH] sx1302_hal: add compatibility with basicstation
+
+Add LGW_LBT_ISSUE define used by Basicstation
+
+Signed-off-by: Marcus Schref <mschref@web.de>
+---
+ libloragw/inc/loragw_hal.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/libloragw/inc/loragw_hal.h
++++ b/libloragw/inc/loragw_hal.h
+@@ -45,6 +45,7 @@ License: Revised BSD License, see LICENS
+ #define LGW_HAL_SUCCESS     0
+ #define LGW_HAL_ERROR       -1
+ #define LGW_LBT_NOT_ALLOWED 1
++#define LGW_LBT_ISSUE 1
+ 
+ /* radio-specific parameters */
+ #define LGW_XTAL_FREQU      32000000            /* frequency of the RF reference oscillator */
diff --git a/external/subpack/libs/sx1302_hal/test.sh b/external/subpack/libs/sx1302_hal/test.sh
new file mode 100644
index 0000000..3958edc
--- /dev/null
+++ b/external/subpack/libs/sx1302_hal/test.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if [ "$1" = 'sx1302_hal-tests' ]; then
+	test_loragw_com -h 2>&1 | grep "$2"
+elif [ "$1" = 'sx1302_hal-utils' ]; then
+	chip_id -h 2>&1 | grep "$2"
+fi
diff --git a/external/subpack/libs/taglib/Makefile b/external/subpack/libs/taglib/Makefile
new file mode 100644
index 0000000..6f16c2b
--- /dev/null
+++ b/external/subpack/libs/taglib/Makefile
@@ -0,0 +1,65 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=taglib
+PKG_VERSION:=2.0.1
+PKG_RELEASE:=1
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/taglib/taglib
+PKG_SOURCE_VERSION:=v$(PKG_VERSION)
+PKG_MIRROR_HASH:=2422e6c4ce9ea59882b6a9c078309bb95d6c11537b769f2ff22bc2fa977c56f3
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING.LGPL
+PKG_CPE_ID:=cpe:/a:taglib:taglib
+
+PKG_BUILD_FLAGS:=lto
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/taglib
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=taglib
+  URL:=https://github.com/taglib/taglib
+  DEPENDS:=+zlib +libstdcpp
+endef
+
+define Package/taglib/description
+  TagLib is a library for reading and editing the metadata of several
+  popular audio formats. Currently it supports both ID3v1 and ID3v2 for
+  MP3 files, Ogg Vorbis comments and ID3 tags in FLAC, MPC, Speex, WavPack,
+  TrueAudio, WAV, AIFF, MP4, APE, DSF, DFF, and ASF files.
+endef
+
+CMAKE_OPTIONS += \
+	-DBUILD_SHARED_LIBS=ON
+	-DBUILD_TESTS=OFF \
+	-DBUILD_EXAMPLES=OFF \
+	-DBUILD_BINDINGS=OFF \
+	-DNO_ITUNES_HACKS=ON
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) '/^prefix=\|^exec_prefix=/s|/usr|$(STAGING_DIR)/usr|' $(1)/usr/bin/taglib-config
+	$(SED) '/^includedir=/s|/usr|$(STAGING_DIR)/usr|' $(1)/usr/bin/taglib-config
+	$(SED) '/^libdir=/s|/usr|$(STAGING_DIR)/usr|' $(1)/usr/bin/taglib-config
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/taglib.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/taglib.pc
+	$(INSTALL_DIR) $(2)/bin
+	$(LN) ../../usr/bin/taglib-config $(2)/bin/taglib-config
+endef
+
+define Package/taglib/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtag.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,taglib))
diff --git a/external/subpack/libs/tcp_wrappers/Makefile b/external/subpack/libs/tcp_wrappers/Makefile
new file mode 100644
index 0000000..07a11fa
--- /dev/null
+++ b/external/subpack/libs/tcp_wrappers/Makefile
@@ -0,0 +1,65 @@
+#
+# Copyright (C) 2006 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:=tcp_wrappers
+PKG_VERSION:=7.6
+PKG_RELEASE:=4
+
+PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=ftp://ftp.porcupine.org/pub/security
+PKG_HASH:=9543d7adedf78a6de0b221ccbbd1952e08b5138717f4ade814039bb489a4315d
+
+PKG_LICENSE:=BSD
+PKG_LICENE_FILES:=DISCLAIMER
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)_$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libwrap
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Security wrapper library for TCP services
+  URL:=ftp://ftp.porcupine.org/pub/security/index.html
+  MAINTAINER:=Peter Wagner <tripolar@gmx.at>
+endef
+
+TARGET_CFLAGS += $(FPIC) -Wall
+
+define Build/Compile
+	$(MAKE) -C $(PKG_BUILD_DIR) \
+		$(TARGET_CONFIGURE_OPTS) \
+		OPT_CFLAGS="$(TARGET_CFLAGS)" \
+		$(TARGET_EXTRA_LIBS) \
+		NETGROUP= \
+		VSYSLOG= \
+		BUGS= \
+		EXTRA_CFLAGS="-DSYS_ERRLIST_DEFINED -DHAVE_STRERROR -DHAVE_WEAKSYMS -D_REENTRANT -DINET6=1 \
+			-Dss_family=__ss_family -Dss_len=__ss_len" \
+		FACILITY=LOG_DAEMON \
+		SEVERITY=LOG_INFO \
+		REAL_DAEMON_DIR=/usr/sbin \
+		STYLE="-DPROCESS_OPTIONS" \
+		tidy all
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_BUILD_DIR)/tcpd.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/libwrap.a $(1)/usr/lib/
+	$(CP) $(PKG_BUILD_DIR)/shared/libwrap.so* $(1)/usr/lib/
+endef
+
+define Package/libwrap/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/shared/libwrap.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libwrap))
diff --git a/external/subpack/libs/tcp_wrappers/patches/001-debian_subset.patch b/external/subpack/libs/tcp_wrappers/patches/001-debian_subset.patch
new file mode 100644
index 0000000..7d22cb0
--- /dev/null
+++ b/external/subpack/libs/tcp_wrappers/patches/001-debian_subset.patch
@@ -0,0 +1,940 @@
+--- a/hosts_access.c
++++ b/hosts_access.c
+@@ -240,6 +240,26 @@ struct request_info *request;
+     }
+ }
+ 
++/* hostfile_match - look up host patterns from file */
++
++static int hostfile_match(path, host)
++char   *path;
++struct hosts_info *host;
++{
++    char    tok[BUFSIZ];
++    int     match = NO;
++    FILE   *fp;
++
++    if ((fp = fopen(path, "r")) != 0) {
++        while (fscanf(fp, "%s", tok) == 1 && !(match = host_match(tok, host)))
++            /* void */ ;
++        fclose(fp);
++    } else if (errno != ENOENT) {
++        tcpd_warn("open %s: %m", path);
++    }
++    return (match);
++}
++
+ /* host_match - match host name and/or address against pattern */
+ 
+ static int host_match(tok, host)
+@@ -267,6 +287,8 @@ struct host_info *host;
+ 	tcpd_warn("netgroup support is disabled");	/* not tcpd_jump() */
+ 	return (NO);
+ #endif
++    } else if (tok[0] == '/') {                         /* /file hack */
++        return (hostfile_match(tok, host));
+     } else if (STR_EQ(tok, "KNOWN")) {		/* check address and name */
+ 	char   *name = eval_hostname(host);
+ 	return (STR_NE(eval_hostaddr(host), unknown) && HOSTNAME_KNOWN(name));
+--- a/tcpd.h
++++ b/tcpd.h
+@@ -4,6 +4,27 @@
+   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+   */
+ 
++#ifndef _TCPWRAPPERS_TCPD_H
++#define _TCPWRAPPERS_TCPD_H
++
++/* someone else may have defined this */
++#undef  __P
++
++/* use prototypes if we have an ANSI C compiler or are using C++ */
++#if defined(__STDC__) || defined(__cplusplus)
++#define __P(args)       args
++#else
++#define __P(args)       ()
++#endif
++
++/* Need definitions of struct sockaddr_in and FILE. */
++#include <netinet/in.h>
++#include <stdio.h>
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
+ /* Structure to describe one communications endpoint. */
+ 
+ #define STRING_LENGTH	128		/* hosts, users, processes */
+@@ -25,10 +46,10 @@ struct request_info {
+     char    pid[10];			/* access via eval_pid(request) */
+     struct host_info client[1];		/* client endpoint info */
+     struct host_info server[1];		/* server endpoint info */
+-    void  (*sink) ();			/* datagram sink function or 0 */
+-    void  (*hostname) ();		/* address to printable hostname */
+-    void  (*hostaddr) ();		/* address to printable address */
+-    void  (*cleanup) ();		/* cleanup function or 0 */
++    void  (*sink) __P((int));		/* datagram sink function or 0 */
++    void  (*hostname) __P((struct host_info *)); /* address to printable hostname */
++    void  (*hostaddr) __P((struct host_info *)); /* address to printable address */
++    void  (*cleanup) __P((struct request_info *)); /* cleanup function or 0 */
+     struct netconfig *config;		/* netdir handle */
+ };
+ 
+@@ -61,25 +82,30 @@ extern char paranoid[];
+ /* Global functions. */
+ 
+ #if defined(TLI) || defined(PTX) || defined(TLI_SEQUENT)
+-extern void fromhost();			/* get/validate client host info */
++extern void fromhost __P((struct request_info *));	/* get/validate client host info */
+ #else
+ #define fromhost sock_host		/* no TLI support needed */
+ #endif
+ 
+-extern int hosts_access();		/* access control */
+-extern void shell_cmd();		/* execute shell command */
+-extern char *percent_x();		/* do %<char> expansion */
+-extern void rfc931();			/* client name from RFC 931 daemon */
+-extern void clean_exit();		/* clean up and exit */
+-extern void refuse();			/* clean up and exit */
+-extern char *xgets();			/* fgets() on steroids */
+-extern char *split_at();		/* strchr() and split */
+-extern unsigned long dot_quad_addr();	/* restricted inet_addr() */
++extern void shell_cmd __P((char *));	/* execute shell command */
++extern char *percent_x __P((char *, int, char *, struct request_info *)); /* do %<char> expansion */
++extern void rfc931 __P((struct sockaddr_in *, struct sockaddr_in *, char *)); /* client name from RFC 931 daemon */
++extern void clean_exit __P((struct request_info *)); /* clean up and exit */
++extern void refuse __P((struct request_info *));	/* clean up and exit */
++extern char *xgets __P((char *, int, FILE *));	/* fgets() on steroids */
++extern char *split_at __P((char *, int));	/* strchr() and split */
++extern unsigned long dot_quad_addr __P((char *)); /* restricted inet_addr() */
+ 
+ /* Global variables. */
+ 
++#ifdef HAVE_WEAKSYMS
++extern int allow_severity __attribute__ ((weak)); /* for connection logging */
++extern int deny_severity __attribute__ ((weak)); /* for connection logging */
++#else
+ extern int allow_severity;		/* for connection logging */
+ extern int deny_severity;		/* for connection logging */
++#endif
++
+ extern char *hosts_allow_table;		/* for verification mode redirection */
+ extern char *hosts_deny_table;		/* for verification mode redirection */
+ extern int hosts_access_verbose;	/* for verbose matching mode */
+@@ -92,9 +118,14 @@ extern int resident;			/* > 0 if residen
+   */
+ 
+ #ifdef __STDC__
++extern int hosts_access(struct request_info *request);
++extern int hosts_ctl(char *daemon, char *client_name, char *client_addr, 
++                     char *client_user);
+ extern struct request_info *request_init(struct request_info *,...);
+ extern struct request_info *request_set(struct request_info *,...);
+ #else
++extern int hosts_access();
++extern int hosts_ctl();
+ extern struct request_info *request_init();	/* initialize request */
+ extern struct request_info *request_set();	/* update request structure */
+ #endif
+@@ -117,27 +148,31 @@ extern struct request_info *request_set(
+   * host_info structures serve as caches for the lookup results.
+   */
+ 
+-extern char *eval_user();		/* client user */
+-extern char *eval_hostname();		/* printable hostname */
+-extern char *eval_hostaddr();		/* printable host address */
+-extern char *eval_hostinfo();		/* host name or address */
+-extern char *eval_client();		/* whatever is available */
+-extern char *eval_server();		/* whatever is available */
++extern char *eval_user __P((struct request_info *));	/* client user */
++extern char *eval_hostname __P((struct host_info *));	/* printable hostname */
++extern char *eval_hostaddr __P((struct host_info *));	/* printable host address */
++extern char *eval_hostinfo __P((struct host_info *));	/* host name or address */
++extern char *eval_client __P((struct request_info *));	/* whatever is available */
++extern char *eval_server __P((struct request_info *));	/* whatever is available */
+ #define eval_daemon(r)	((r)->daemon)	/* daemon process name */
+ #define eval_pid(r)	((r)->pid)	/* process id */
+ 
+ /* Socket-specific methods, including DNS hostname lookups. */
+ 
+-extern void sock_host();		/* look up endpoint addresses */
+-extern void sock_hostname();		/* translate address to hostname */
+-extern void sock_hostaddr();		/* address to printable address */
++/* look up endpoint addresses */
++extern void sock_host __P((struct request_info *));
++/* translate address to hostname */
++extern void sock_hostname __P((struct host_info *));
++/* address to printable address */
++extern void sock_hostaddr __P((struct host_info *));
++
+ #define sock_methods(r) \
+ 	{ (r)->hostname = sock_hostname; (r)->hostaddr = sock_hostaddr; }
+ 
+ /* The System V Transport-Level Interface (TLI) interface. */
+ 
+ #if defined(TLI) || defined(PTX) || defined(TLI_SEQUENT)
+-extern void tli_host();			/* look up endpoint addresses etc. */
++extern void tli_host __P((struct request_info *));	/* look up endpoint addresses etc. */
+ #endif
+ 
+  /*
+@@ -178,7 +213,7 @@ extern struct tcpd_context tcpd_context;
+   * behavior.
+   */
+ 
+-extern void process_options();		/* execute options */
++extern void process_options __P((char *, struct request_info *)); /* execute options */
+ extern int dry_run;			/* verification flag */
+ 
+ /* Bug workarounds. */
+@@ -217,3 +252,9 @@ extern char *fix_strtok();
+ #define strtok	my_strtok
+ extern char *my_strtok();
+ #endif
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* tcpd.h */
+--- a/Makefile
++++ b/Makefile
+@@ -1,5 +1,10 @@
++GLIBC=$(shell grep -s -c __GLIBC__ /usr/include/features.h)
++
+ # @(#) Makefile 1.23 97/03/21 19:27:20
+ 
++# unset the HOSTNAME environment variable
++HOSTNAME =
++
+ what:
+ 	@echo
+ 	@echo "Usage: edit the REAL_DAEMON_DIR definition in the Makefile then:"
+@@ -19,7 +24,7 @@ what:
+ 	@echo "	generic (most bsd-ish systems with sys5 compatibility)"
+ 	@echo "	386bsd aix alpha apollo bsdos convex-ultranet dell-gcc dgux dgux543"
+ 	@echo "	dynix epix esix freebsd hpux irix4 irix5 irix6 isc iunix"
+-	@echo "	linux machten mips(untested) ncrsvr4 netbsd next osf power_unix_211"
++	@echo "	linux gnu machten mips(untested) ncrsvr4 netbsd next osf power_unix_211"
+ 	@echo "	ptx-2.x ptx-generic pyramid sco sco-nis sco-od2 sco-os5 sinix sunos4"
+ 	@echo "	sunos40 sunos5 sysv4 tandem ultrix unicos7 unicos8 unixware1 unixware2"
+ 	@echo "	uts215 uxp"
+@@ -43,8 +48,8 @@ what:
+ # Ultrix 4.x SunOS 4.x ConvexOS 10.x Dynix/ptx
+ #REAL_DAEMON_DIR=/usr/etc
+ #
+-# SysV.4 Solaris 2.x OSF AIX
+-#REAL_DAEMON_DIR=/usr/sbin
++# SysV.4 Solaris 2.x OSF AIX Linux
++REAL_DAEMON_DIR=/usr/sbin
+ #
+ # BSD 4.4
+ #REAL_DAEMON_DIR=/usr/libexec
+@@ -141,10 +146,21 @@ freebsd:
+ 	LIBS= RANLIB=ranlib ARFLAGS=rv AUX_OBJ= NETGROUP= TLI= \
+ 	EXTRA_CFLAGS=-DSYS_ERRLIST_DEFINED VSYSLOG= all
+ 
++ifneq ($(GLIBC),0)
++MYLIB=-lnsl
++endif
++
+ linux:
+ 	@make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
+-	LIBS= RANLIB=ranlib ARFLAGS=rv AUX_OBJ=setenv.o \
+-	NETGROUP= TLI= EXTRA_CFLAGS="-DBROKEN_SO_LINGER" all
++	LIBS=$(MYLIB) RANLIB=ranlib ARFLAGS=rv AUX_OBJ=weak_symbols.o \
++	NETGROUP=-DNETGROUP TLI= VSYSLOG= BUGS= all \
++	EXTRA_CFLAGS="-DSYS_ERRLIST_DEFINED -DHAVE_WEAKSYMS -D_REENTRANT"
++
++gnu:
++	@make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
++	LIBS=$(MYLIB) RANLIB=ranlib ARFLAGS=rv AUX_OBJ=weak_symbols.o \
++	NETGROUP=-DNETGROUP TLI= VSYSLOG= BUGS= all \
++	EXTRA_CFLAGS="-DHAVE_STRERROR -DHAVE_WEAKSYMS -D_REENTRANT"
+ 
+ # This is good for many SYSV+BSD hybrids with NIS, probably also for HP-UX 7.x.
+ hpux hpux8 hpux9 hpux10:
+@@ -391,7 +407,7 @@ AR	= ar
+ # the ones provided with this source distribution. The environ.c module
+ # implements setenv(), getenv(), and putenv().
+ 
+-AUX_OBJ= setenv.o
++#AUX_OBJ= setenv.o
+ #AUX_OBJ= environ.o
+ #AUX_OBJ= environ.o strcasecmp.o
+ 
+@@ -454,7 +470,8 @@ AUX_OBJ= setenv.o
+ # host name aliases. Compile with -DSOLARIS_24_GETHOSTBYNAME_BUG to work
+ # around this. The workaround does no harm on other Solaris versions.
+ 
+-BUGS = -DGETPEERNAME_BUG -DBROKEN_FGETS -DLIBC_CALLS_STRTOK
++BUGS =
++#BUGS = -DGETPEERNAME_BUG -DBROKEN_FGETS -DLIBC_CALLS_STRTOK
+ #BUGS = -DGETPEERNAME_BUG -DBROKEN_FGETS -DINET_ADDR_BUG
+ #BUGS = -DGETPEERNAME_BUG -DBROKEN_FGETS -DSOLARIS_24_GETHOSTBYNAME_BUG
+ 
+@@ -464,7 +481,7 @@ BUGS = -DGETPEERNAME_BUG -DBROKEN_FGETS
+ # If your system supports NIS or YP-style netgroups, enable the following
+ # macro definition. Netgroups are used only for host access control.
+ #
+-#NETGROUP= -DNETGROUP
++NETGROUP= -DNETGROUP
+ 
+ ###############################################################
+ # System dependencies: whether or not your system has vsyslog()
+@@ -491,7 +508,7 @@ VSYSLOG	= -Dvsyslog=myvsyslog
+ # Uncomment the next definition to turn on the language extensions
+ # (examples: allow, deny, banners, twist and spawn).
+ # 
+-#STYLE	= -DPROCESS_OPTIONS	# Enable language extensions.
++STYLE	= -DPROCESS_OPTIONS	# Enable language extensions.
+ 
+ ################################################################
+ # Optional: Changing the default disposition of logfile records
+@@ -514,7 +531,7 @@ VSYSLOG	= -Dvsyslog=myvsyslog
+ #
+ # The LOG_XXX names below are taken from the /usr/include/syslog.h file.
+ 
+-FACILITY= LOG_MAIL	# LOG_MAIL is what most sendmail daemons use
++FACILITY= LOG_DAEMON	# LOG_MAIL is what most sendmail daemons use
+ 
+ # The syslog priority at which successful connections are logged.
+ 
+@@ -610,7 +627,7 @@ TABLES	= -DHOSTS_DENY=\"/etc/hosts.deny\
+ # Paranoid mode implies hostname lookup. In order to disable hostname
+ # lookups altogether, see the next section.
+ 
+-PARANOID= -DPARANOID
++#PARANOID= -DPARANOID
+ 
+ ########################################
+ # Optional: turning off hostname lookups
+@@ -623,7 +640,7 @@ PARANOID= -DPARANOID
+ # In order to perform selective hostname lookups, disable paranoid
+ # mode (see previous section) and comment out the following definition.
+ 
+-HOSTNAME= -DALWAYS_HOSTNAME
++#HOSTNAME= -DALWAYS_HOSTNAME
+ 
+ #############################################
+ # Optional: Turning on host ADDRESS checking
+@@ -649,28 +666,46 @@ HOSTNAME= -DALWAYS_HOSTNAME
+ # source-routed traffic in the kernel. Examples: 4.4BSD derivatives,
+ # Solaris 2.x, and Linux. See your system documentation for details.
+ #
+-# KILL_OPT= -DKILL_IP_OPTIONS
++KILL_OPT= -DKILL_IP_OPTIONS
+ 
+ ## End configuration options
+ ############################
+ 
+ # Protection against weird shells or weird make programs.
+ 
++CC	= gcc
+ SHELL	= /bin/sh
+-.c.o:;	$(CC) $(CFLAGS) -c $*.c
++.c.o:;	$(CC) $(CFLAGS) -o $*.o -c $*.c
++
++SOMAJOR = 0
++SOMINOR = 7.6
++
++LIB	= libwrap.a
++SHLIB	= shared/libwrap.so.$(SOMAJOR).$(SOMINOR)
++SHLIBSOMAJ= shared/libwrap.so.$(SOMAJOR)
++SHLIBSO	= shared/libwrap.so
++SHLIBFLAGS = -Lshared -lwrap
+ 
+-CFLAGS	= -O -DFACILITY=$(FACILITY) $(ACCESS) $(PARANOID) $(NETGROUP) \
++shared/%.o: %.c
++	$(CC) $(CFLAGS) $(SHCFLAGS) -c $< -o $@
++
++CFLAGS	= -O2 -g -DFACILITY=$(FACILITY) $(ACCESS) $(PARANOID) $(NETGROUP) \
+ 	$(BUGS) $(SYSTYPE) $(AUTH) $(UMASK) \
+ 	-DREAL_DAEMON_DIR=\"$(REAL_DAEMON_DIR)\" $(STYLE) $(KILL_OPT) \
+ 	-DSEVERITY=$(SEVERITY) -DRFC931_TIMEOUT=$(RFC931_TIMEOUT) \
+ 	$(UCHAR) $(TABLES) $(STRINGS) $(TLI) $(EXTRA_CFLAGS) $(DOT) \
+ 	$(VSYSLOG) $(HOSTNAME)
+ 
++SHLINKFLAGS = -shared -Xlinker -soname -Xlinker libwrap.so.$(SOMAJOR) -lc $(LIBS)
++SHCFLAGS = -fPIC -shared -D_REENTRANT
++
+ LIB_OBJ= hosts_access.o options.o shell_cmd.o rfc931.o eval.o \
+ 	hosts_ctl.o refuse.o percent_x.o clean_exit.o $(AUX_OBJ) \
+ 	$(FROM_OBJ) fix_options.o socket.o tli.o workarounds.o \
+ 	update.o misc.o diag.o percent_m.o myvsyslog.o
+ 
++SHLIB_OBJ= $(addprefix shared/, $(LIB_OBJ));
++
+ FROM_OBJ= fromhost.o
+ 
+ KIT	= README miscd.c tcpd.c fromhost.c hosts_access.c shell_cmd.c \
+@@ -684,46 +719,78 @@ KIT	= README miscd.c tcpd.c fromhost.c h
+ 	refuse.c tcpdchk.8 setenv.c inetcf.c inetcf.h scaffold.c \
+ 	scaffold.h tcpdmatch.8 README.NIS
+ 
+-LIB	= libwrap.a
+-
+-all other: config-check tcpd tcpdmatch try-from safe_finger tcpdchk
++all other: config-check tcpd tcpdmatch try-from safe_finger tcpdchk $(LIB)
+ 
+ # Invalidate all object files when the compiler options (CFLAGS) have changed.
+ 
+ config-check:
+ 	@set +e; test -n "$(REAL_DAEMON_DIR)" || { make; exit 1; }
+-	@set +e; echo $(CFLAGS) >/tmp/cflags.$$$$ ; \
+-	if cmp cflags /tmp/cflags.$$$$ ; \
+-	then rm /tmp/cflags.$$$$ ; \
+-	else mv /tmp/cflags.$$$$ cflags ; \
++	@set +e; echo $(CFLAGS) >cflags.new ; \
++	if cmp cflags cflags.new ; \
++	then rm cflags.new ; \
++	else mv cflags.new cflags ; \
+ 	fi >/dev/null 2>/dev/null
++	@if [ ! -d shared ]; then mkdir shared; fi
+ 
+ $(LIB):	$(LIB_OBJ)
+ 	rm -f $(LIB)
+ 	$(AR) $(ARFLAGS) $(LIB) $(LIB_OBJ)
+ 	-$(RANLIB) $(LIB)
+ 
+-tcpd:	tcpd.o $(LIB)
+-	$(CC) $(CFLAGS) -o $@ tcpd.o $(LIB) $(LIBS)
++$(SHLIB): $(SHLIB_OBJ)
++	rm -f $(SHLIB)
++	$(CC) -o $(SHLIB) $(SHLINKFLAGS) $(SHLIB_OBJ)
++	ln -s $(notdir $(SHLIB)) $(SHLIBSOMAJ)
++	ln -s $(notdir $(SHLIBSOMAJ)) $(SHLIBSO)
++
++tcpd:	tcpd.o $(SHLIB)
++	$(CC) $(CFLAGS) -o $@ tcpd.o $(SHLIBFLAGS)
+ 
+-miscd:	miscd.o $(LIB)
+-	$(CC) $(CFLAGS) -o $@ miscd.o $(LIB) $(LIBS)
++miscd:	miscd.o $(SHLIB)
++	$(CC) $(CFLAGS) -o $@ miscd.o $(SHLIBFLAGS)
+ 
+-safe_finger: safe_finger.o $(LIB)
+-	$(CC) $(CFLAGS) -o $@ safe_finger.o $(LIB) $(LIBS)
++safe_finger: safe_finger.o $(SHLIB)
++	$(CC) $(CFLAGS) -o $@ safe_finger.o $(SHLIBFLAGS)
+ 
+ TCPDMATCH_OBJ = tcpdmatch.o fakelog.o inetcf.o scaffold.o
+ 
+-tcpdmatch: $(TCPDMATCH_OBJ) $(LIB)
+-	$(CC) $(CFLAGS) -o $@ $(TCPDMATCH_OBJ) $(LIB) $(LIBS)
++tcpdmatch: $(TCPDMATCH_OBJ) $(SHLIB)
++	$(CC) $(CFLAGS) -o $@ $(TCPDMATCH_OBJ) $(SHLIBFLAGS)
+ 
+-try-from: try-from.o fakelog.o $(LIB)
+-	$(CC) $(CFLAGS) -o $@ try-from.o fakelog.o $(LIB) $(LIBS)
++try-from: try-from.o fakelog.o $(SHLIB)
++	$(CC) $(CFLAGS) -o $@ try-from.o fakelog.o $(SHLIBFLAGS)
+ 
+ TCPDCHK_OBJ = tcpdchk.o fakelog.o inetcf.o scaffold.o
+ 
+-tcpdchk: $(TCPDCHK_OBJ) $(LIB)
+-	$(CC) $(CFLAGS) -o $@ $(TCPDCHK_OBJ) $(LIB) $(LIBS)
++tcpdchk: $(TCPDCHK_OBJ) $(SHLIB)
++	$(CC) $(CFLAGS) -o $@ $(TCPDCHK_OBJ) $(SHLIBFLAGS)
++
++install: install-lib install-bin install-dev
++
++install-lib:
++	install -o root -g root -m 0644 $(SHLIB) ${DESTDIR}/lib/
++	ln -s $(notdir $(SHLIB)) ${DESTDIR}/lib/$(notdir $(SHLIBSOMAJ))
++
++install-bin:
++	install -o root -g root -m 0755 tcpd ${DESTDIR}/usr/sbin/
++	install -o root -g root -m 0755 tcpdchk ${DESTDIR}/usr/sbin/
++	install -o root -g root -m 0755 tcpdmatch ${DESTDIR}/usr/sbin/
++	install -o root -g root -m 0755 try-from ${DESTDIR}/usr/sbin/
++	install -o root -g root -m 0755 safe_finger ${DESTDIR}/usr/sbin/
++	install -o root -g root -m 0644 tcpd.8 ${DESTDIR}/usr/share/man/man8/
++	install -o root -g root -m 0644 tcpdchk.8 ${DESTDIR}/usr/share/man/man8/
++	install -o root -g root -m 0644 tcpdmatch.8 ${DESTDIR}/usr/share/man/man8/
++	install -o root -g root -m 0644 hosts_access.5 ${DESTDIR}/usr/share/man/man5/
++	install -o root -g root -m 0644 hosts_options.5 ${DESTDIR}/usr/share/man/man5/
++
++install-dev:
++	ln -s /lib/$(notdir $(SHLIBSOMAJ)) ${DESTDIR}/usr/lib/$(notdir $(SHLIBSO))
++	install -o root -g root -m 0644 hosts_access.3 ${DESTDIR}/usr/share/man/man3/
++	install -o root -g root -m 0644 tcpd.h ${DESTDIR}/usr/include/
++	install -o root -g root -m 0644 $(LIB) ${DESTDIR}/usr/lib/
++	ln -s hosts_access.3 ${DESTDIR}/usr/share/man/man3/hosts_ctl.3
++	ln -s hosts_access.3 ${DESTDIR}/usr/share/man/man3/request_init.3
++	ln -s hosts_access.3 ${DESTDIR}/usr/share/man/man3/request_set.3
+ 
+ shar:	$(KIT)
+ 	@shar $(KIT)
+@@ -739,7 +806,8 @@ archive:
+ 
+ clean:
+ 	rm -f tcpd miscd safe_finger tcpdmatch tcpdchk try-from *.[oa] core \
+-	cflags
++	cflags libwrap*.so*
++	rm -rf shared
+ 
+ tidy:	clean
+ 	chmod -R a+r .
+@@ -885,5 +953,6 @@ update.o: cflags
+ update.o: mystdarg.h
+ update.o: tcpd.h
+ vfprintf.o: cflags
++weak_symbols.o: tcpd.h
+ workarounds.o: cflags
+ workarounds.o: tcpd.h
+--- a/hosts_access.5
++++ b/hosts_access.5
+@@ -8,9 +8,9 @@ name, host name/address) patterns.  Exam
+ impatient reader is encouraged to skip to the EXAMPLES section for a
+ quick introduction.
+ .PP
+-An extended version of the access control language is described in the
+-\fIhosts_options\fR(5) document. The extensions are turned on at
+-program build time by building with -DPROCESS_OPTIONS.
++The extended version of the access control language is described in the
++\fIhosts_options\fR(5) document. \fBNote that this language supersedes
++the meaning of \fIshell_command\fB as documented below.\fR
+ .PP
+ In the following text, \fIdaemon\fR is the the process name of a
+ network daemon process, and \fIclient\fR is the name and/or address of
+@@ -40,7 +40,7 @@ A newline character is ignored when it i
+ character. This permits you to break up long lines so that they are
+ easier to edit.
+ .IP \(bu
+-Blank lines or lines that begin with a `#\' character are ignored.
++Blank lines or lines that begin with a `#' character are ignored.
+ This permits you to insert comments and whitespace so that the tables
+ are easier to read.
+ .IP \(bu
+@@ -69,26 +69,33 @@ checks are case insensitive.
+ .SH PATTERNS
+ The access control language implements the following patterns:
+ .IP \(bu
+-A string that begins with a `.\' character. A host name is matched if
++A string that begins with a `.' character. A host name is matched if
+ the last components of its name match the specified pattern.  For
+-example, the pattern `.tue.nl\' matches the host name
+-`wzv.win.tue.nl\'.
++example, the pattern `.tue.nl' matches the host name
++`wzv.win.tue.nl'.
+ .IP \(bu
+-A string that ends with a `.\' character. A host address is matched if
++A string that ends with a `.' character. A host address is matched if
+ its first numeric fields match the given string.  For example, the
+-pattern `131.155.\' matches the address of (almost) every host on the
++pattern `131.155.' matches the address of (almost) every host on the
+ Eind\%hoven University network (131.155.x.x).
+ .IP \(bu
+-A string that begins with an `@\' character is treated as an NIS
++A string that begins with an `@' character is treated as an NIS
+ (formerly YP) netgroup name. A host name is matched if it is a host
+ member of the specified netgroup. Netgroup matches are not supported
+ for daemon process names or for client user names.
+ .IP \(bu
+-An expression of the form `n.n.n.n/m.m.m.m\' is interpreted as a
+-`net/mask\' pair. A host address is matched if `net\' is equal to the
+-bitwise AND of the address and the `mask\'. For example, the net/mask
+-pattern `131.155.72.0/255.255.254.0\' matches every address in the
+-range `131.155.72.0\' through `131.155.73.255\'.
++An expression of the form `n.n.n.n/m.m.m.m' is interpreted as a
++`net/mask' pair. A host address is matched if `net' is equal to the
++bitwise AND of the address and the `mask'. For example, the net/mask
++pattern `131.155.72.0/255.255.254.0' matches every address in the
++range `131.155.72.0' through `131.155.73.255'.
++.IP \(bu
++A string that begins with a `/' character is treated as a file
++name. A host name or address is matched if it matches any host name
++or address pattern listed in the named file. The file format is
++zero or more lines with zero or more host name or address patterns
++separated by whitespace.  A file name pattern can be used anywhere
++a host name or address pattern can be used.
+ .SH WILDCARDS
+ The access control language supports explicit wildcards:
+ .IP ALL
+@@ -115,19 +122,19 @@ without -DPARANOID when you want more co
+ .ne 6
+ .SH OPERATORS
+ .IP EXCEPT
+-Intended use is of the form: `list_1 EXCEPT list_2\'; this construct
++Intended use is of the form: `list_1 EXCEPT list_2'; this construct
+ matches anything that matches \fIlist_1\fR unless it matches
+ \fIlist_2\fR.  The EXCEPT operator can be used in daemon_lists and in
+ client_lists. The EXCEPT operator can be nested: if the control
+-language would permit the use of parentheses, `a EXCEPT b EXCEPT c\'
+-would parse as `(a EXCEPT (b EXCEPT c))\'.
++language would permit the use of parentheses, `a EXCEPT b EXCEPT c'
++would parse as `(a EXCEPT (b EXCEPT c))'.
+ .br
+ .ne 6
+ .SH SHELL COMMANDS
+ If the first-matched access control rule contains a shell command, that
+ command is subjected to %<letter> substitutions (see next section).
+ The result is executed by a \fI/bin/sh\fR child process with standard
+-input, output and error connected to \fI/dev/null\fR.  Specify an `&\'
++input, output and error connected to \fI/dev/null\fR.  Specify an `&'
+ at the end of the command if you do not want to wait until it has
+ completed.
+ .PP
+@@ -159,7 +166,7 @@ depending on how much information is ava
+ .IP %u
+ The client user name (or "unknown").
+ .IP %%
+-Expands to a single `%\' character.
++Expands to a single `%' character.
+ .PP
+ Characters in % expansions that may confuse the shell are replaced by
+ underscores.
+@@ -243,9 +250,9 @@ A positive IDENT lookup result (the clie
+ less trustworthy. It is possible for an intruder to spoof both the
+ client connection and the IDENT lookup, although doing so is much
+ harder than spoofing just a client connection. It may also be that
+-the client\'s IDENT server is lying.
++the client's IDENT server is lying.
+ .PP
+-Note: IDENT lookups don\'t work with UDP services. 
++Note: IDENT lookups don't work with UDP services. 
+ .SH EXAMPLES
+ The language is flexible enough that different types of access control
+ policy can be expressed with a minimum of fuss. Although the language
+@@ -285,7 +292,7 @@ ALL: LOCAL @some_netgroup
+ .br
+ ALL: .foobar.edu EXCEPT terminalserver.foobar.edu
+ .PP
+-The first rule permits access from hosts in the local domain (no `.\'
++The first rule permits access from hosts in the local domain (no `.'
+ in the host name) and from members of the \fIsome_netgroup\fP
+ netgroup.  The second rule permits access from all hosts in the
+ \fIfoobar.edu\fP domain (notice the leading dot), with the exception of
+@@ -322,8 +329,8 @@ in.tftpd: LOCAL, .my.domain
+ /etc/hosts.deny:
+ .in +3
+ .nf
+-in.tftpd: ALL: (/some/where/safe_finger -l @%h | \\
+-	/usr/ucb/mail -s %d-%h root) &
++in.tftpd: ALL: (/usr/sbin/safe_finger -l @%h | \\
++	/usr/bin/mail -s %d-%h root) &
+ .fi
+ .PP
+ The safe_finger command comes with the tcpd wrapper and should be
+@@ -349,7 +356,7 @@ control rule; when the length of an acce
+ capacity of an internal buffer; when an access control rule is not
+ terminated by a newline character; when the result of %<letter>
+ expansion would overflow an internal buffer; when a system call fails
+-that shouldn\'t.  All problems are reported via the syslog daemon.
++that shouldn't.  All problems are reported via the syslog daemon.
+ .SH FILES
+ .na
+ .nf
+--- a/rfc931.c
++++ b/rfc931.c
+@@ -33,7 +33,7 @@ static char sccsid[] = "@(#) rfc931.c 1.
+ 
+ int     rfc931_timeout = RFC931_TIMEOUT;/* Global so it can be changed */
+ 
+-static jmp_buf timebuf;
++static sigjmp_buf timebuf;
+ 
+ /* fsocket - open stdio stream on top of socket */
+ 
+@@ -62,7 +62,7 @@ int     protocol;
+ static void timeout(sig)
+ int     sig;
+ {
+-    longjmp(timebuf, sig);
++    siglongjmp(timebuf, sig);
+ }
+ 
+ /* rfc931 - return remote user name, given socket structures */
+@@ -99,7 +99,7 @@ char   *dest;
+ 	 * Set up a timer so we won't get stuck while waiting for the server.
+ 	 */
+ 
+-	if (setjmp(timebuf) == 0) {
++	if (sigsetjmp(timebuf,1) == 0) {
+ 	    signal(SIGALRM, timeout);
+ 	    alarm(rfc931_timeout);
+ 
+--- a/tcpd.8
++++ b/tcpd.8
+@@ -94,7 +94,7 @@ configuration files.
+ .PP
+ The example assumes that the network daemons live in /usr/etc. On some
+ systems, network daemons live in /usr/sbin or in /usr/libexec, or have
+-no `in.\' prefix to their name.
++no `in.' prefix to their name.
+ .SH EXAMPLE 2
+ This example applies when \fItcpd\fR expects that the network daemons
+ are left in their original place.
+@@ -110,26 +110,26 @@ finger  stream  tcp  nowait  nobody  /us
+ becomes:
+ .sp
+ .ti +5
+-finger  stream  tcp  nowait  nobody  /some/where/tcpd     in.fingerd
++finger  stream  tcp  nowait  nobody  /usr/sbin/tcpd       in.fingerd
+ .sp
+ .fi
+ .PP
+ The example assumes that the network daemons live in /usr/etc. On some
+ systems, network daemons live in /usr/sbin or in /usr/libexec, the
+-daemons have no `in.\' prefix to their name, or there is no userid
++daemons have no `in.' prefix to their name, or there is no userid
+ field in the inetd configuration file.
+ .PP
+ Similar changes will be needed for the other services that are to be
+-covered by \fItcpd\fR.  Send a `kill -HUP\' to the \fIinetd\fR(8)
++covered by \fItcpd\fR.  Send a `kill -HUP' to the \fIinetd\fR(8)
+ process to make the changes effective. AIX users may also have to
+-execute the `inetimp\' command.
++execute the `inetimp' command.
+ .SH EXAMPLE 3
+ In the case of daemons that do not live in a common directory ("secret"
+ or otherwise), edit the \fIinetd\fR configuration file so that it
+ specifies an absolute path name for the process name field. For example:
+ .nf
+ .sp
+-    ntalk  dgram  udp  wait  root  /some/where/tcpd  /usr/local/lib/ntalkd
++    ntalk  dgram  udp  wait  root  /usr/sbin/tcpd  /usr/sbin/in.ntalkd
+ .sp
+ .fi
+ .PP
+--- a/hosts_access.3
++++ b/hosts_access.3
+@@ -3,7 +3,7 @@
+ hosts_access, hosts_ctl, request_init, request_set \- access control library
+ .SH SYNOPSIS
+ .nf
+-#include "tcpd.h"
++#include <tcpd.h>
+ 
+ extern int allow_severity;
+ extern int deny_severity;
+--- a/options.c
++++ b/options.c
+@@ -473,6 +473,9 @@ static struct syslog_names log_fac[] = {
+ #ifdef LOG_CRON
+     "cron", LOG_CRON,
+ #endif
++#ifdef LOG_FTP
++    "ftp", LOG_FTP,
++#endif
+ #ifdef LOG_LOCAL0
+     "local0", LOG_LOCAL0,
+ #endif
+--- a/fix_options.c
++++ b/fix_options.c
+@@ -35,7 +35,12 @@ struct request_info *request;
+ #ifdef IP_OPTIONS
+     unsigned char optbuf[BUFFER_SIZE / 3], *cp;
+     char    lbuf[BUFFER_SIZE], *lp;
++#if !defined(__GLIBC__)
+     int     optsize = sizeof(optbuf), ipproto;
++#else /* __GLIBC__ */
++    size_t  optsize = sizeof(optbuf);
++    int     ipproto;
++#endif /* __GLIBC__ */
+     struct protoent *ip;
+     int     fd = request->fd;
+     unsigned int opt;
+--- a/workarounds.c
++++ b/workarounds.c
+@@ -163,7 +163,11 @@ int    *fromlen;
+ int     fix_getpeername(sock, sa, len)
+ int     sock;
+ struct sockaddr *sa;
++#if !defined(__GLIBC__)
+ int    *len;
++#else /* __GLIBC__ */
++size_t *len;
++#endif /* __GLIBC__ */
+ {
+     int     ret;
+     struct sockaddr_in *sin = (struct sockaddr_in *) sa;
+--- a/socket.c
++++ b/socket.c
+@@ -76,7 +76,11 @@ struct request_info *request;
+ {
+     static struct sockaddr_in client;
+     static struct sockaddr_in server;
++#if !defined (__GLIBC__)
+     int     len;
++#else /* __GLIBC__ */
++    size_t  len;
++#endif /* __GLIBC__ */
+     char    buf[BUFSIZ];
+     int     fd = request->fd;
+ 
+@@ -224,7 +228,11 @@ int     fd;
+ {
+     char    buf[BUFSIZ];
+     struct sockaddr_in sin;
++#if !defined(__GLIBC__)
+     int     size = sizeof(sin);
++#else /* __GLIBC__ */
++    size_t  size = sizeof(sin);
++#endif /* __GLIBC__ */
+ 
+     /*
+      * Eat up the not-yet received datagram. Some systems insist on a
+--- a/safe_finger.c
++++ b/safe_finger.c
+@@ -26,21 +26,24 @@ static char sccsid[] = "@(#) safe_finger
+ #include <stdio.h>
+ #include <ctype.h>
+ #include <pwd.h>
++#include <syslog.h>
+ 
+ extern void exit();
+ 
+ /* Local stuff */
+ 
+-char    path[] = "PATH=/bin:/usr/bin:/usr/ucb:/usr/bsd:/etc:/usr/etc:/usr/sbin";
++char    path[] = "PATH=/bin:/usr/bin:/sbin:/usr/sbin";
+ 
+ #define	TIME_LIMIT	60		/* Do not keep listinging forever */
+ #define	INPUT_LENGTH	100000		/* Do not keep listinging forever */
+ #define	LINE_LENGTH	128		/* Editors can choke on long lines */
+ #define	FINGER_PROGRAM	"finger"	/* Most, if not all, UNIX systems */
+ #define	UNPRIV_NAME	"nobody"	/* Preferred privilege level */
+-#define	UNPRIV_UGID	32767		/* Default uid and gid */
++#define	UNPRIV_UGID	65534		/* Default uid and gid */
+ 
+ int     finger_pid;
++int	allow_severity = SEVERITY;
++int	deny_severity = LOG_WARNING;
+ 
+ void    cleanup(sig)
+ int     sig;
+--- a/hosts_options.5
++++ b/hosts_options.5
+@@ -58,12 +58,12 @@ Notice the leading dot on the domain nam
+ Execute, in a child process, the specified shell command, after
+ performing the %<letter> expansions described in the hosts_access(5)
+ manual page.  The command is executed with stdin, stdout and stderr
+-connected to the null device, so that it won\'t mess up the
++connected to the null device, so that it won't mess up the
+ conversation with the client host. Example:
+ .sp
+ .nf
+ .ti +3
+-spawn (/some/where/safe_finger -l @%h | /usr/ucb/mail root) &
++spawn (/usr/sbin/safe_finger -l @%h | /usr/bin/mail root) &
+ .fi
+ .sp
+ executes, in a background child process, the shell command "safe_finger
+--- a/tcpdchk.c
++++ b/tcpdchk.c
+@@ -350,6 +350,8 @@ char   *pat;
+ {
+     if (pat[0] == '@') {
+ 	tcpd_warn("%s: daemon name begins with \"@\"", pat);
++    } else if (pat[0] == '/') {
++        tcpd_warn("%s: daemon name begins with \"/\"", pat);
+     } else if (pat[0] == '.') {
+ 	tcpd_warn("%s: daemon name begins with dot", pat);
+     } else if (pat[strlen(pat) - 1] == '.') {
+@@ -382,6 +384,8 @@ char   *pat;
+ {
+     if (pat[0] == '@') {			/* @netgroup */
+ 	tcpd_warn("%s: user name begins with \"@\"", pat);
++    } else if (pat[0] == '/') {
++        tcpd_warn("%s: user name begins with \"/\"", pat);
+     } else if (pat[0] == '.') {
+ 	tcpd_warn("%s: user name begins with dot", pat);
+     } else if (pat[strlen(pat) - 1] == '.') {
+@@ -402,8 +406,13 @@ char   *pat;
+ static int check_host(pat)
+ char   *pat;
+ {
++    char    buf[BUFSIZ];
+     char   *mask;
+     int     addr_count = 1;
++    FILE   *fp;
++    struct tcpd_context saved_context;
++    char   *cp;
++    char   *wsp = " \t\r\n";
+ 
+     if (pat[0] == '@') {			/* @netgroup */
+ #ifdef NO_NETGRENT
+@@ -422,6 +431,21 @@ char   *pat;
+ 	tcpd_warn("netgroup support disabled");
+ #endif
+ #endif
++    } else if (pat[0] == '/') {                 /* /path/name */
++        if ((fp = fopen(pat, "r")) != 0) {
++            saved_context = tcpd_context;
++            tcpd_context.file = pat;
++            tcpd_context.line = 0;
++            while (fgets(buf, sizeof(buf), fp)) {
++                tcpd_context.line++;
++                for (cp = strtok(buf, wsp); cp; cp = strtok((char *) 0, wsp))
++                    check_host(cp);
++            }
++            tcpd_context = saved_context;
++            fclose(fp);
++        } else if (errno != ENOENT) {
++            tcpd_warn("open %s: %m", pat);
++        }
+     } else if (mask = split_at(pat, '/')) {	/* network/netmask */
+ 	if (dot_quad_addr(pat) == INADDR_NONE
+ 	    || dot_quad_addr(mask) == INADDR_NONE)
+--- a/percent_m.c
++++ b/percent_m.c
+@@ -13,7 +13,7 @@ static char sccsid[] = "@(#) percent_m.c
+ #include <string.h>
+ 
+ extern int errno;
+-#ifndef SYS_ERRLIST_DEFINED
++#if !defined(SYS_ERRLIST_DEFINED) && !defined(HAVE_STRERROR)
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+ #endif
+@@ -29,11 +29,15 @@ char   *ibuf;
+ 
+     while (*bp = *cp)
+ 	if (*cp == '%' && cp[1] == 'm') {
++#ifdef HAVE_STRERROR
++            strcpy(bp, strerror(errno));
++#else
+ 	    if (errno < sys_nerr && errno > 0) {
+ 		strcpy(bp, sys_errlist[errno]);
+ 	    } else {
+ 		sprintf(bp, "Unknown error %d", errno);
+ 	    }
++#endif
+ 	    bp += strlen(bp);
+ 	    cp += 2;
+ 	} else {
+--- a/scaffold.c
++++ b/scaffold.c
+@@ -180,10 +180,12 @@ struct request_info *request;
+ 
+ /* ARGSUSED */
+ 
+-void    rfc931(request)
+-struct request_info *request;
++void    rfc931(rmt_sin, our_sin, dest)
++struct sockaddr_in *rmt_sin;
++struct sockaddr_in *our_sin;
++char   *dest;
+ {
+-    strcpy(request->user, unknown);
++    strcpy(dest, unknown);
+ }
+ 
+ /* check_path - examine accessibility */
+--- /dev/null
++++ b/weak_symbols.c
+@@ -0,0 +1,11 @@
++ /*
++  * @(#) weak_symbols.h 1.5 99/12/29 23:50
++  * 
++  * Author: Anthony Towns <ajt@debian.org>
++  */
++
++#ifdef HAVE_WEAKSYMS
++#include <syslog.h>
++int deny_severity = LOG_WARNING;
++int allow_severity = SEVERITY; 
++#endif
diff --git a/external/subpack/libs/tcp_wrappers/patches/002-opt_cflags.patch b/external/subpack/libs/tcp_wrappers/patches/002-opt_cflags.patch
new file mode 100644
index 0000000..1f38eb3
--- /dev/null
+++ b/external/subpack/libs/tcp_wrappers/patches/002-opt_cflags.patch
@@ -0,0 +1,12 @@
+--- a/Makefile
++++ b/Makefile
+@@ -689,7 +689,8 @@ SHLIBFLAGS = -Lshared -lwrap
+ shared/%.o: %.c
+ 	$(CC) $(CFLAGS) $(SHCFLAGS) -c $< -o $@
+ 
+-CFLAGS	= -O2 -g -DFACILITY=$(FACILITY) $(ACCESS) $(PARANOID) $(NETGROUP) \
++OPT_CFLAGS = -O2 -g
++CFLAGS	= $(OPT_CFLAGS) -DFACILITY=$(FACILITY) $(ACCESS) $(PARANOID) $(NETGROUP) \
+ 	$(BUGS) $(SYSTYPE) $(AUTH) $(UMASK) \
+ 	-DREAL_DAEMON_DIR=\"$(REAL_DAEMON_DIR)\" $(STYLE) $(KILL_OPT) \
+ 	-DSEVERITY=$(SEVERITY) -DRFC931_TIMEOUT=$(RFC931_TIMEOUT) \
diff --git a/external/subpack/libs/tcp_wrappers/patches/003-scaffold_malloc.patch b/external/subpack/libs/tcp_wrappers/patches/003-scaffold_malloc.patch
new file mode 100644
index 0000000..ecda5ae
--- /dev/null
+++ b/external/subpack/libs/tcp_wrappers/patches/003-scaffold_malloc.patch
@@ -0,0 +1,17 @@
+--- a/scaffold.c
++++ b/scaffold.c
+@@ -20,13 +20,12 @@ static char sccs_id[] = "@(#) scaffold.c
+ #include <syslog.h>
+ #include <setjmp.h>
+ #include <string.h>
++#include <stdlib.h>
+ 
+ #ifndef INADDR_NONE
+ #define	INADDR_NONE	(-1)		/* XXX should be 0xffffffff */
+ #endif
+ 
+-extern char *malloc();
+-
+ /* Application-specific. */
+ 
+ #include "tcpd.h"
diff --git a/external/subpack/libs/tcp_wrappers/patches/004-ipv4_prefix.patch b/external/subpack/libs/tcp_wrappers/patches/004-ipv4_prefix.patch
new file mode 100644
index 0000000..8520097
--- /dev/null
+++ b/external/subpack/libs/tcp_wrappers/patches/004-ipv4_prefix.patch
@@ -0,0 +1,72 @@
+--- a/hosts_access.5
++++ b/hosts_access.5
+@@ -90,6 +90,9 @@ bitwise AND of the address and the `mask
+ pattern `131.155.72.0/255.255.254.0' matches every address in the
+ range `131.155.72.0' through `131.155.73.255'.
+ .IP \(bu
++An expression of the form `n.n.n.n/m\' is interpreted as a
++`net/prefixlen\' pair, as below, for IPv4 addresses.
++.IP \(bu
+ A string that begins with a `/' character is treated as a file
+ name. A host name or address is matched if it matches any host name
+ or address pattern listed in the named file. The file format is
+--- a/tcpd.h
++++ b/tcpd.h
+@@ -95,6 +95,7 @@ extern void refuse __P((struct request_i
+ extern char *xgets __P((char *, int, FILE *));	/* fgets() on steroids */
+ extern char *split_at __P((char *, int));	/* strchr() and split */
+ extern unsigned long dot_quad_addr __P((char *)); /* restricted inet_addr() */
++extern unsigned long prefix_to_netmask __P((char *)); /* 0-32 prefix length */
+ 
+ /* Global variables. */
+ 
+--- a/misc.c
++++ b/misc.c
+@@ -14,6 +14,8 @@ static char sccsic[] = "@(#) misc.c 1.2
+ #include <arpa/inet.h>
+ #include <stdio.h>
+ #include <string.h>
++#include <ctype.h>
++#include <stdlib.h>
+ 
+ #include "tcpd.h"
+ 
+@@ -85,3 +87,22 @@ char   *str;
+     }
+     return (runs == 4 ? inet_addr(str) : INADDR_NONE);
+ }
++
++/* prefix_to_netmask - convert prefix (0-32) to netmask */
++
++unsigned long prefix_to_netmask(str)
++char	*str;
++{
++    unsigned long prefix;
++    char *endptr;
++
++    if (!isdigit(str[0]))
++	return INADDR_NONE;
++
++    prefix = strtoul(str, &endptr, 10);
++    if ((endptr == str) || (*endptr != '\0') || (prefix > 32))
++	return INADDR_NONE;
++
++    return htonl(~0UL << (32 - prefix));
++}
++
+--- a/hosts_access.c
++++ b/hosts_access.c
+@@ -345,7 +345,12 @@ char   *string;
+     if ((addr = dot_quad_addr(string)) == INADDR_NONE)
+ 	return (NO);
+     if ((net = dot_quad_addr(net_tok)) == INADDR_NONE
+-	|| (mask = dot_quad_addr(mask_tok)) == INADDR_NONE) {
++	|| ((mask = dot_quad_addr(mask_tok)) == INADDR_NONE
++	    && strcmp(mask_tok, "255.255.255.255")
++	    && (mask = prefix_to_netmask(mask_tok)) == INADDR_NONE
++	    && strcmp(mask_tok, "32"))) {
++	/* 255.255.255.255 == INADDR_NONE, separate check needed. TJ. */
++	/* 32 == INADDR_NONE, separate check needed. philipp */
+ 	tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok);
+ 	return (NO);				/* not tcpd_jump() */
+     }
diff --git a/external/subpack/libs/tcp_wrappers/patches/005-no--lnsl-on-musl.patch b/external/subpack/libs/tcp_wrappers/patches/005-no--lnsl-on-musl.patch
new file mode 100644
index 0000000..050df9b
--- /dev/null
+++ b/external/subpack/libs/tcp_wrappers/patches/005-no--lnsl-on-musl.patch
@@ -0,0 +1,20 @@
+--- a/Makefile
++++ b/Makefile
+@@ -1,4 +1,4 @@
+-GLIBC=$(shell grep -s -c __GLIBC__ /usr/include/features.h)
++GLIBC=$(shell grep -s -c __GLIBC__ ${STAGING_DIR}/usr/include/features.h)
+ 
+ # @(#) Makefile 1.23 97/03/21 19:27:20
+ 
+@@ -146,9 +146,11 @@ freebsd:
+ 	LIBS= RANLIB=ranlib ARFLAGS=rv AUX_OBJ= NETGROUP= TLI= \
+ 	EXTRA_CFLAGS=-DSYS_ERRLIST_DEFINED VSYSLOG= all
+ 
++ifneq ($(GLIBC),)
+ ifneq ($(GLIBC),0)
+ MYLIB=-lnsl
+ endif
++endif
+ 
+ linux:
+ 	@make REAL_DAEMON_DIR=$(REAL_DAEMON_DIR) STYLE=$(STYLE) \
diff --git a/external/subpack/libs/tcp_wrappers/patches/006-compilation-warnings.patch b/external/subpack/libs/tcp_wrappers/patches/006-compilation-warnings.patch
new file mode 100644
index 0000000..57a4e7c
--- /dev/null
+++ b/external/subpack/libs/tcp_wrappers/patches/006-compilation-warnings.patch
@@ -0,0 +1,737 @@
+--- a/clean_exit.c
++++ b/clean_exit.c
+@@ -9,10 +9,11 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) clean_exit.c 1.4 94/12/28 17:42:19";
++static char sccsid[] __attribute__((__unused__)) = "@(#) clean_exit.c 1.4 94/12/28 17:42:19";
+ #endif
+ 
+ #include <stdio.h>
++#include <unistd.h>
+ 
+ extern void exit();
+ 
+--- a/diag.c
++++ b/diag.c
+@@ -10,7 +10,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) diag.c 1.1 94/12/28 17:42:20";
++static char sccsid[] __attribute__((__unused__)) = "@(#) diag.c 1.1 94/12/28 17:42:20";
+ #endif
+ 
+ /* System libraries */
+--- a/eval.c
++++ b/eval.c
+@@ -19,7 +19,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) eval.c 1.3 95/01/30 19:51:45";
++static char sccsid[] __attribute__((__unused__)) = "@(#) eval.c 1.3 95/01/30 19:51:45";
+ #endif
+ 
+ /* System libraries. */
+--- a/fakelog.c
++++ b/fakelog.c
+@@ -6,7 +6,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) fakelog.c 1.3 94/12/28 17:42:21";
++static char sccsid[] __attribute__((__unused__)) = "@(#) fakelog.c 1.3 94/12/28 17:42:21";
+ #endif
+ 
+ #include <stdio.h>
+@@ -17,7 +17,7 @@ static char sccsid[] = "@(#) fakelog.c 1
+ 
+ /* ARGSUSED */
+ 
+-openlog(name, logopt, facility)
++void    openlog(name, logopt, facility)
+ char   *name;
+ int     logopt;
+ int     facility;
+@@ -27,7 +27,7 @@ int     facility;
+ 
+ /* vsyslog - format one record */
+ 
+-vsyslog(severity, fmt, ap)
++void    vsyslog(severity, fmt, ap)
+ int     severity;
+ char   *fmt;
+ va_list ap;
+@@ -43,7 +43,7 @@ va_list ap;
+ 
+ /* VARARGS */
+ 
+-VARARGS(syslog, int, severity)
++void    VARARGS(syslog, int, severity)
+ {
+     va_list ap;
+     char   *fmt;
+@@ -56,7 +56,7 @@ VARARGS(syslog, int, severity)
+ 
+ /* closelog - dummy */
+ 
+-closelog()
++void    closelog()
+ {
+     /* void */
+ }
+--- a/fix_options.c
++++ b/fix_options.c
+@@ -6,7 +6,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) fix_options.c 1.6 97/04/08 02:29:19";
++static char sccsid[] __attribute__((__unused__)) = "@(#) fix_options.c 1.6 97/04/08 02:29:19";
+ #endif
+ 
+ #include <sys/types.h>
+@@ -29,14 +29,14 @@ static char sccsid[] = "@(#) fix_options
+ 
+ /* fix_options - get rid of IP-level socket options */
+ 
+-fix_options(request)
+-struct request_info *request;
++void    fix_options(request)
++struct  request_info *request;
+ {
+ #ifdef IP_OPTIONS
+     unsigned char optbuf[BUFFER_SIZE / 3], *cp;
+     char    lbuf[BUFFER_SIZE], *lp;
+ #if !defined(__GLIBC__)
+-    int     optsize = sizeof(optbuf), ipproto;
++    unsigned int  optsize = sizeof(optbuf), ipproto;
+ #else /* __GLIBC__ */
+     size_t  optsize = sizeof(optbuf);
+     int     ipproto;
+--- a/fromhost.c
++++ b/fromhost.c
+@@ -11,7 +11,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) fromhost.c 1.17 94/12/28 17:42:23";
++static char sccsid[] __attribute__((__unused__)) = "@(#) fromhost.c 1.17 94/12/28 17:42:23";
+ #endif
+ 
+ #if defined(TLI) || defined(PTX) || defined(TLI_SEQUENT)
+--- a/hosts_access.c
++++ b/hosts_access.c
+@@ -18,7 +18,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) hosts_access.c 1.21 97/02/12 02:13:22";
++static char sccsid[] __attribute__((__unused__)) = "@(#) hosts_access.c 1.21 97/02/12 02:13:22";
+ #endif
+ 
+ /* System libraries. */
+--- a/hosts_ctl.c
++++ b/hosts_ctl.c
+@@ -12,7 +12,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) hosts_ctl.c 1.4 94/12/28 17:42:27";
++static char sccsid[] __attribute__((__unused__)) = "@(#) hosts_ctl.c 1.4 94/12/28 17:42:27";
+ #endif
+ 
+ #include <stdio.h>
+--- a/inetcf.c
++++ b/inetcf.c
+@@ -6,7 +6,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) inetcf.c 1.7 97/02/12 02:13:23";
++static char sccsid[] __attribute__((__unused__)) = "@(#) inetcf.c 1.7 97/02/12 02:13:23";
+ #endif
+ 
+ #include <sys/types.h>
+@@ -14,6 +14,7 @@ static char sccsid[] = "@(#) inetcf.c 1.
+ #include <stdio.h>
+ #include <errno.h>
+ #include <string.h>
++#include <stdlib.h>
+ 
+ extern int errno;
+ extern void exit();
+@@ -21,6 +22,8 @@ extern void exit();
+ #include "tcpd.h"
+ #include "inetcf.h"
+ 
++extern int check_path(char *, struct stat *);
++
+  /*
+   * Network configuration files may live in unusual places. Here are some
+   * guesses. Shorter names follow longer ones.
+--- a/misc.c
++++ b/misc.c
+@@ -5,7 +5,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsic[] = "@(#) misc.c 1.2 96/02/11 17:01:29";
++static char sccsid[] __attribute__((__unused__)) = "@(#) misc.c 1.2 96/02/11 17:01:29";
+ #endif
+ 
+ #include <sys/types.h>
+--- a/myvsyslog.c
++++ b/myvsyslog.c
+@@ -8,7 +8,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) myvsyslog.c 1.1 94/12/28 17:42:33";
++static char sccsid[] __attribute__((__unused__)) = "@(#) myvsyslog.c 1.1 94/12/28 17:42:33";
+ #endif
+ 
+ #ifdef vsyslog
+--- a/options.c
++++ b/options.c
+@@ -29,7 +29,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) options.c 1.17 96/02/11 17:01:31";
++static char sccsid[] __attribute__((__unused__)) = "@(#) options.c 1.17 96/02/11 17:01:31";
+ #endif
+ 
+ /* System libraries. */
+@@ -47,6 +47,8 @@ static char sccsid[] = "@(#) options.c 1
+ #include <ctype.h>
+ #include <setjmp.h>
+ #include <string.h>
++#include <stdlib.h>
++#include <unistd.h>
+ 
+ #ifndef MAXPATHNAMELEN
+ #define MAXPATHNAMELEN  BUFSIZ
+@@ -108,21 +110,21 @@ struct option {
+ /* List of known keywords. Add yours here. */
+ 
+ static struct option option_table[] = {
+-    "user", user_option, NEED_ARG,
+-    "group", group_option, NEED_ARG,
+-    "umask", umask_option, NEED_ARG,
+-    "linger", linger_option, NEED_ARG,
+-    "keepalive", keepalive_option, 0,
+-    "spawn", spawn_option, NEED_ARG | EXPAND_ARG,
+-    "twist", twist_option, NEED_ARG | EXPAND_ARG | USE_LAST,
+-    "rfc931", rfc931_option, OPT_ARG,
+-    "setenv", setenv_option, NEED_ARG | EXPAND_ARG,
+-    "nice", nice_option, OPT_ARG,
+-    "severity", severity_option, NEED_ARG,
+-    "allow", allow_option, USE_LAST,
+-    "deny", deny_option, USE_LAST,
+-    "banners", banners_option, NEED_ARG,
+-    0,
++   { "user", user_option, NEED_ARG },
++   { "group", group_option, NEED_ARG },
++   { "umask", umask_option, NEED_ARG },
++   { "linger", linger_option, NEED_ARG },
++   { "keepalive", keepalive_option, 0 },
++   { "spawn", spawn_option, NEED_ARG | EXPAND_ARG },
++   { "twist", twist_option, NEED_ARG | EXPAND_ARG | USE_LAST },
++   { "rfc931", rfc931_option, OPT_ARG },
++   { "setenv", setenv_option, NEED_ARG | EXPAND_ARG },
++   { "nice", nice_option, OPT_ARG },
++   { "severity", severity_option, NEED_ARG },
++   { "allow", allow_option, USE_LAST },
++   { "deny", deny_option, USE_LAST },
++   { "banners", banners_option, NEED_ARG },
++   { 0 },
+ };
+ 
+ /* process_options - process access control options */
+@@ -447,88 +449,88 @@ struct syslog_names {
+ 
+ static struct syslog_names log_fac[] = {
+ #ifdef LOG_KERN
+-    "kern", LOG_KERN,
++    { "kern", LOG_KERN },
+ #endif
+ #ifdef LOG_USER
+-    "user", LOG_USER,
++    { "user", LOG_USER },
+ #endif
+ #ifdef LOG_MAIL
+-    "mail", LOG_MAIL,
++    { "mail", LOG_MAIL },
+ #endif
+ #ifdef LOG_DAEMON
+-    "daemon", LOG_DAEMON,
++    { "daemon", LOG_DAEMON },
+ #endif
+ #ifdef LOG_AUTH
+-    "auth", LOG_AUTH,
++    { "auth", LOG_AUTH },
+ #endif
+ #ifdef LOG_LPR
+-    "lpr", LOG_LPR,
++    { "lpr", LOG_LPR },
+ #endif
+ #ifdef LOG_NEWS
+-    "news", LOG_NEWS,
++    { "news", LOG_NEWS },
+ #endif
+ #ifdef LOG_UUCP
+-    "uucp", LOG_UUCP,
++    { "uucp", LOG_UUCP },
+ #endif
+ #ifdef LOG_CRON
+-    "cron", LOG_CRON,
++    { "cron", LOG_CRON },
+ #endif
+ #ifdef LOG_FTP
+-    "ftp", LOG_FTP,
++    { "ftp", LOG_FTP },
+ #endif
+ #ifdef LOG_LOCAL0
+-    "local0", LOG_LOCAL0,
++    { "local0", LOG_LOCAL0 },
+ #endif
+ #ifdef LOG_LOCAL1
+-    "local1", LOG_LOCAL1,
++    { "local1", LOG_LOCAL1 },
+ #endif
+ #ifdef LOG_LOCAL2
+-    "local2", LOG_LOCAL2,
++    { "local2", LOG_LOCAL2 },
+ #endif
+ #ifdef LOG_LOCAL3
+-    "local3", LOG_LOCAL3,
++    { "local3", LOG_LOCAL3 },
+ #endif
+ #ifdef LOG_LOCAL4
+-    "local4", LOG_LOCAL4,
++    { "local4", LOG_LOCAL4 },
+ #endif
+ #ifdef LOG_LOCAL5
+-    "local5", LOG_LOCAL5,
++    { "local5", LOG_LOCAL5 },
+ #endif
+ #ifdef LOG_LOCAL6
+-    "local6", LOG_LOCAL6,
++    { "local6", LOG_LOCAL6 },
+ #endif
+ #ifdef LOG_LOCAL7
+-    "local7", LOG_LOCAL7,
++    { "local7", LOG_LOCAL7 },
+ #endif
+-    0,
++    { 0 },
+ };
+ 
+ static struct syslog_names log_sev[] = {
+ #ifdef LOG_EMERG
+-    "emerg", LOG_EMERG,
++    { "emerg", LOG_EMERG },
+ #endif
+ #ifdef LOG_ALERT
+-    "alert", LOG_ALERT,
++    { "alert", LOG_ALERT },
+ #endif
+ #ifdef LOG_CRIT
+-    "crit", LOG_CRIT,
++    { "crit", LOG_CRIT },
+ #endif
+ #ifdef LOG_ERR
+-    "err", LOG_ERR,
++    { "err", LOG_ERR },
+ #endif
+ #ifdef LOG_WARNING
+-    "warning", LOG_WARNING,
++    { "warning", LOG_WARNING },
+ #endif
+ #ifdef LOG_NOTICE
+-    "notice", LOG_NOTICE,
++    { "notice", LOG_NOTICE },
+ #endif
+ #ifdef LOG_INFO
+-    "info", LOG_INFO,
++    { "info", LOG_INFO },
+ #endif
+ #ifdef LOG_DEBUG
+-    "debug", LOG_DEBUG,
++    { "debug", LOG_DEBUG },
+ #endif
+-    0,
++    { 0 },
+ };
+ 
+ /* severity_map - lookup facility or severity value */
+@@ -589,7 +591,7 @@ char   *string;
+     if (src[0] == 0)
+ 	return (0);
+ 
+-    while (ch = *src) {
++    while ((ch = *src)) {
+ 	if (ch == ':') {
+ 	    if (*++src == 0)
+ 		tcpd_warn("rule ends in \":\"");
+--- a/patchlevel.h
++++ b/patchlevel.h
+@@ -1,3 +1,3 @@
+ #ifndef lint
+-static char patchlevel[] = "@(#) patchlevel 7.6 97/03/21 19:27:23";
++static char patchlevel[] __attribute__((__unused__)) = "@(#) patchlevel 7.6 97/03/21 19:27:23";
+ #endif
+--- a/percent_m.c
++++ b/percent_m.c
+@@ -5,7 +5,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) percent_m.c 1.1 94/12/28 17:42:37";
++static char sccsid[] __attribute__((__unused__)) = "@(#) percent_m.c 1.1 94/12/28 17:42:37";
+ #endif
+ 
+ #include <stdio.h>
+@@ -27,7 +27,7 @@ char   *ibuf;
+     char   *bp = obuf;
+     char   *cp = ibuf;
+ 
+-    while (*bp = *cp)
++    while ((*bp = *cp))
+ 	if (*cp == '%' && cp[1] == 'm') {
+ #ifdef HAVE_STRERROR
+             strcpy(bp, strerror(errno));
+--- a/percent_x.c
++++ b/percent_x.c
+@@ -11,7 +11,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) percent_x.c 1.4 94/12/28 17:42:37";
++static char sccsid[] __attribute__((__unused__)) = "@(#) percent_x.c 1.4 94/12/28 17:42:37";
+ #endif
+ 
+ /* System libraries. */
+@@ -19,6 +19,7 @@ static char sccsid[] = "@(#) percent_x.c
+ #include <stdio.h>
+ #include <syslog.h>
+ #include <string.h>
++#include <unistd.h>
+ 
+ extern void exit();
+ 
+--- a/refuse.c
++++ b/refuse.c
+@@ -8,7 +8,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) refuse.c 1.5 94/12/28 17:42:39";
++static char sccsid[] __attribute__((__unused__)) = "@(#) refuse.c 1.5 94/12/28 17:42:39";
+ #endif
+ 
+ /* System libraries. */
+--- a/rfc931.c
++++ b/rfc931.c
+@@ -10,7 +10,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) rfc931.c 1.10 95/01/02 16:11:34";
++static char sccsid[] __attribute__((__unused__)) = "@(#) rfc931.c 1.10 95/01/02 16:11:34";
+ #endif
+ 
+ /* System libraries. */
+@@ -23,6 +23,7 @@ static char sccsid[] = "@(#) rfc931.c 1.
+ #include <setjmp.h>
+ #include <signal.h>
+ #include <string.h>
++#include <unistd.h>
+ 
+ /* Local stuff. */
+ 
+@@ -152,7 +153,7 @@ char   *dest;
+ 		     * protocol, not part of the data.
+ 		     */
+ 
+-		    if (cp = strchr(user, '\r'))
++		    if ((cp = strchr(user, '\r')))
+ 			*cp = 0;
+ 		    result = user;
+ 		}
+--- a/safe_finger.c
++++ b/safe_finger.c
+@@ -15,7 +15,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) safe_finger.c 1.4 94/12/28 17:42:41";
++static char sccsid[] __attribute__((__unused__)) = "@(#) safe_finger.c 1.4 94/12/28 17:42:41";
+ #endif
+ 
+ /* System libraries */
+@@ -27,6 +27,10 @@ static char sccsid[] = "@(#) safe_finger
+ #include <ctype.h>
+ #include <pwd.h>
+ #include <syslog.h>
++#include <fcntl.h>
++#include <stdlib.h>
++#include <sys/wait.h>
++#include <unistd.h>
+ 
+ extern void exit();
+ 
+@@ -45,6 +49,8 @@ int     finger_pid;
+ int	allow_severity = SEVERITY;
+ int	deny_severity = LOG_WARNING;
+ 
++int     pipe_stdin();
++
+ void    cleanup(sig)
+ int     sig;
+ {
+@@ -52,7 +58,7 @@ int     sig;
+     exit(0);
+ }
+ 
+-main(argc, argv)
++int     main(argc, argv)
+ int     argc;
+ char  **argv;
+ {
+--- a/scaffold.c
++++ b/scaffold.c
+@@ -5,7 +5,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccs_id[] = "@(#) scaffold.c 1.6 97/03/21 19:27:24";
++static char sccsid[] __attribute__((__unused__)) = "@(#) scaffold.c 1.6 97/03/21 19:27:24";
+ #endif
+ 
+ /* System libraries. */
+--- a/shell_cmd.c
++++ b/shell_cmd.c
+@@ -9,7 +9,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) shell_cmd.c 1.5 94/12/28 17:42:44";
++static char sccsid[] __attribute__((__unused__)) = "@(#) shell_cmd.c 1.5 94/12/28 17:42:44";
+ #endif
+ 
+ /* System libraries. */
+@@ -20,6 +20,9 @@ static char sccsid[] = "@(#) shell_cmd.c
+ #include <stdio.h>
+ #include <syslog.h>
+ #include <string.h>
++#include <fcntl.h>
++#include <sys/wait.h>
++#include <unistd.h>
+ 
+ extern void exit();
+ 
+--- a/socket.c
++++ b/socket.c
+@@ -16,7 +16,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) socket.c 1.15 97/03/21 19:27:24";
++static char sccsid[] __attribute__((__unused__)) = "@(#) socket.c 1.15 97/03/21 19:27:24";
+ #endif
+ 
+ /* System libraries. */
+@@ -77,7 +77,7 @@ struct request_info *request;
+     static struct sockaddr_in client;
+     static struct sockaddr_in server;
+ #if !defined (__GLIBC__)
+-    int     len;
++    unsigned int  len;
+ #else /* __GLIBC__ */
+     size_t  len;
+ #endif /* __GLIBC__ */
+@@ -229,7 +229,7 @@ int     fd;
+     char    buf[BUFSIZ];
+     struct sockaddr_in sin;
+ #if !defined(__GLIBC__)
+-    int     size = sizeof(sin);
++    unsigned int  size = sizeof(sin);
+ #else /* __GLIBC__ */
+     size_t  size = sizeof(sin);
+ #endif /* __GLIBC__ */
+--- a/tcpd.c
++++ b/tcpd.c
+@@ -11,7 +11,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) tcpd.c 1.10 96/02/11 17:01:32";
++static char sccsid[] __attribute__((__unused__)) = "@(#) tcpd.c 1.10 96/02/11 17:01:32";
+ #endif
+ 
+ /* System libraries. */
+@@ -24,6 +24,7 @@ static char sccsid[] = "@(#) tcpd.c 1.10
+ #include <stdio.h>
+ #include <syslog.h>
+ #include <string.h>
++#include <unistd.h>
+ 
+ #ifndef MAXPATHNAMELEN
+ #define MAXPATHNAMELEN	BUFSIZ
+@@ -38,10 +39,12 @@ static char sccsid[] = "@(#) tcpd.c 1.10
+ #include "patchlevel.h"
+ #include "tcpd.h"
+ 
++extern void fix_options(struct request_info *);
++
+ int     allow_severity = SEVERITY;	/* run-time adjustable */
+ int     deny_severity = LOG_WARNING;	/* ditto */
+ 
+-main(argc, argv)
++int     main(argc, argv)
+ int     argc;
+ char  **argv;
+ {
+--- a/tcpd.h
++++ b/tcpd.h
+@@ -184,10 +184,10 @@ extern void tli_host __P((struct request
+ 
+ #ifdef __STDC__
+ extern void tcpd_warn(char *, ...);	/* report problem and proceed */
+-extern void tcpd_jump(char *, ...);	/* report problem and jump */
++extern void tcpd_jump(char *, ...) __attribute__((__noreturn__));	/* report problem and jump */
+ #else
+ extern void tcpd_warn();
+-extern void tcpd_jump();
++extern void tcpd_jump() __attribute__((__noreturn__));
+ #endif
+ 
+ struct tcpd_context {
+--- a/tcpdchk.c
++++ b/tcpdchk.c
+@@ -15,7 +15,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) tcpdchk.c 1.8 97/02/12 02:13:25";
++static char sccsid[] __attribute__((__unused__)) = "@(#) tcpdchk.c 1.8 97/02/12 02:13:25";
+ #endif
+ 
+ /* System libraries. */
+@@ -30,6 +30,7 @@ static char sccsid[] = "@(#) tcpdchk.c 1
+ #include <errno.h>
+ #include <netdb.h>
+ #include <string.h>
++#include <unistd.h>
+ 
+ extern int errno;
+ extern void exit();
+@@ -199,13 +200,15 @@ struct request_info *request;
+     char    sv_list[BUFLEN];		/* becomes list of daemons */
+     char   *cl_list;			/* becomes list of requests */
+     char   *sh_cmd;			/* becomes optional shell command */
++#ifndef PROCESS_OPTIONS
+     char    buf[BUFSIZ];
++#endif
+     int     verdict;
+     struct tcpd_context saved_context;
+ 
+     saved_context = tcpd_context;		/* stupid compilers */
+ 
+-    if (fp = fopen(table, "r")) {
++    if ((fp = fopen(table, "r"))) {
+ 	tcpd_context.file = table;
+ 	tcpd_context.line = 0;
+ 	while (xgets(sv_list, sizeof(sv_list), fp)) {
+@@ -331,7 +334,7 @@ char   *list;
+ 	    clients = 0;
+ 	} else {
+ 	    clients++;
+-	    if (host = split_at(cp + 1, '@')) {	/* user@host */
++	    if ((host = split_at(cp + 1, '@'))) {	/* user@host */
+ 		check_user(cp);
+ 		check_host(host);
+ 	    } else {
+@@ -446,7 +449,7 @@ char   *pat;
+         } else if (errno != ENOENT) {
+             tcpd_warn("open %s: %m", pat);
+         }
+-    } else if (mask = split_at(pat, '/')) {	/* network/netmask */
++    } else if ((mask = split_at(pat, '/'))) {	/* network/netmask */
+ 	if (dot_quad_addr(pat) == INADDR_NONE
+ 	    || dot_quad_addr(mask) == INADDR_NONE)
+ 	    tcpd_warn("%s/%s: bad net/mask pattern", pat, mask);
+--- a/tcpdmatch.c
++++ b/tcpdmatch.c
+@@ -14,7 +14,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) tcpdmatch.c 1.5 96/02/11 17:01:36";
++static char sccsid[] __attribute__((__unused__)) = "@(#) tcpdmatch.c 1.5 96/02/11 17:01:36";
+ #endif
+ 
+ /* System libraries. */
+@@ -29,6 +29,8 @@ static char sccsid[] = "@(#) tcpdmatch.c
+ #include <syslog.h>
+ #include <setjmp.h>
+ #include <string.h>
++#include <stdlib.h>
++#include <unistd.h>
+ 
+ extern void exit();
+ extern int optind;
+--- a/tli.c
++++ b/tli.c
+@@ -15,7 +15,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) tli.c 1.15 97/03/21 19:27:25";
++static char sccsid[] __attribute__((__unused__)) = "@(#) tli.c 1.15 97/03/21 19:27:25";
+ #endif
+ 
+ #ifdef TLI
+--- a/try-from.c
++++ b/try-from.c
+@@ -11,7 +11,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) try-from.c 1.2 94/12/28 17:42:55";
++static char sccsid[] __attribute__((__unused__)) = "@(#) try-from.c 1.2 94/12/28 17:42:55";
+ #endif
+ 
+ /* System libraries. */
+@@ -37,7 +37,7 @@ static char sccsid[] = "@(#) try-from.c
+ int     allow_severity = SEVERITY;	/* run-time adjustable */
+ int     deny_severity = LOG_WARNING;	/* ditto */
+ 
+-main(argc, argv)
++int     main(argc, argv)
+ int     argc;
+ char  **argv;
+ {
+--- a/update.c
++++ b/update.c
+@@ -14,7 +14,7 @@
+   */
+ 
+ #ifndef lint
+-static char sccsid[] = "@(#) update.c 1.1 94/12/28 17:42:56";
++static char sccsid[] __attribute__((__unused__)) = "@(#) update.c 1.1 94/12/28 17:42:56";
+ #endif
+ 
+ /* System libraries */
+@@ -22,6 +22,7 @@ static char sccsid[] = "@(#) update.c 1.
+ #include <stdio.h>
+ #include <syslog.h>
+ #include <string.h>
++#include <unistd.h>
+ 
+ /* Local stuff. */
+ 
diff --git a/external/subpack/libs/tdb/Makefile b/external/subpack/libs/tdb/Makefile
new file mode 100644
index 0000000..d78043d
--- /dev/null
+++ b/external/subpack/libs/tdb/Makefile
@@ -0,0 +1,86 @@
+#
+# Copyright (C) 2007-2014 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:=tdb
+PKG_VERSION:=1.4.3
+PKG_RELEASE:=2
+PKG_LICENSE:=GPL-2.0
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://www.samba.org/ftp/tdb/
+PKG_HASH:=c8058393dfa15f47e11ebd2f1d132693f0b3b3b8bf22d0201bfb305026f88a1b
+
+PKG_BUILD_DEPENDS:=python3/host
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+# for $(LINUX_VERSION)
+include $(INCLUDE_DIR)/kernel.mk
+# for $(VERSION_DIST)
+include $(INCLUDE_DIR)/version.mk
+
+define Package/tdb
+  SUBMENU:=Database
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Trivial Database
+  URL:=http://sourceforge.net/projects/tdb/
+  MAINTAINER:=Dmitry V. Zimin <pfzim@mail.ru>
+endef
+
+define Package/tdb/description
+  TDB is a Trivial Database. In concept, it is very much like GDBM,
+  and BSD's DB except that it allows multiple simultaneous writers
+  and uses locking internally to keep writers from trampling on
+  each other. TDB is also extremely small.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/tdb.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib/
+endef
+
+CONFIGURE_ARGS:= \
+	--cross-compile \
+	--cross-answers="$(PKG_BUILD_DIR)/cache.txt" \
+	--prefix=$(CONFIGURE_PREFIX) \
+	--exec-prefix=$(CONFIGURE_PREFIX) \
+	--bindir=$(CONFIGURE_PREFIX)/bin \
+	--sbindir=$(CONFIGURE_PREFIX)/sbin \
+	--libexecdir=$(CONFIGURE_PREFIX)/lib \
+	--sysconfdir=/etc \
+	--datadir=$(CONFIGURE_PREFIX)/share \
+	--localstatedir=/var \
+	--mandir=$(CONFIGURE_PREFIX)/man \
+	--infodir=$(CONFIGURE_PREFIX)/info \
+	--disable-python \
+	--disable-rpath \
+	--disable-rpath-install \
+	--disable-rpath-private-install
+
+define Build/Configure
+	$(CP) ./files/tdb.cache.txt $(PKG_BUILD_DIR)/cache.txt
+	echo -e "\nChecking uname sysname type: \"$(VERSION_DIST)\" \
+		\nChecking uname release type: \"$(LINUX_VERSION)-$(GNU_TARGET_NAME)\" \
+		\nChecking uname machine type: \"$(ARCH)\" \
+		\nChecking uname version type: \"$(VERSION_DIST) Linux-$(LINUX_VERSION) $(shell date +%Y-%m-%d)\"\n" >> $(PKG_BUILD_DIR)/cache.txt;
+	$(call Build/Configure/Default)
+endef
+
+define Package/tdb/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/*.so.* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,tdb))
+
diff --git a/external/subpack/libs/tdb/files/tdb.cache.txt b/external/subpack/libs/tdb/files/tdb.cache.txt
new file mode 100644
index 0000000..714d534
--- /dev/null
+++ b/external/subpack/libs/tdb/files/tdb.cache.txt
@@ -0,0 +1,36 @@
+Checking simple C program: OK
+rpath library support: OK
+-Wl,--version-script support: OK
+Checking getconf LFS_CFLAGS: NO
+Checking for large file support without additional flags: OK
+Checking for -D_LARGE_FILES: OK
+Checking correct behavior of strtoll: NO
+Checking for working strptime: OK
+Checking for C99 vsnprintf: OK
+Checking for HAVE_SHARED_MMAP: OK
+Checking for HAVE_MREMAP: OK
+Checking for HAVE_INCOHERENT_MMAP: NO
+Checking for HAVE_SECURE_MKSTEMP: OK
+Checking for HAVE_IFACE_GETIFADDRS: OK
+Checking for kernel change notify support: OK
+Checking for Linux kernel oplocks: OK
+Checking for kernel share modes: OK
+Checking if can we convert from CP850 to UCS-2LE: OK
+Checking if can we convert from UTF-8 to UCS-2LE: OK
+Checking whether we can use Linux thread-specific credentials with 32-bit system calls: OK
+Checking whether we can use Linux thread-specific credentials: OK
+Checking whether setreuid is available: OK
+Checking whether setresuid is available: OK
+Checking whether seteuid is available: OK
+Checking whether fcntl locking is available: OK
+Checking whether fcntl lock supports open file description locks: OK
+Checking for the maximum value of the 'time_t' type: OK
+Checking whether the realpath function allows a NULL argument: OK
+Checking whether POSIX capabilities are available: OK
+Checking for ftruncate extend: OK
+vfs_fileid checking for statfs() and struct statfs.f_fsid: OK
+getcwd takes a NULL argument: OK
+Checking value of NSIG: "65"
+Checking value of _NSIG: "65"
+Checking value of SIGRTMAX: "64"
+Checking value of SIGRTMIN: "34"
diff --git a/external/subpack/libs/tdb/patches/100-Remove_libbsd_dependency_check.patch b/external/subpack/libs/tdb/patches/100-Remove_libbsd_dependency_check.patch
new file mode 100644
index 0000000..4fe2c66
--- /dev/null
+++ b/external/subpack/libs/tdb/patches/100-Remove_libbsd_dependency_check.patch
@@ -0,0 +1,58 @@
+--- a/lib/replace/wscript
++++ b/lib/replace/wscript
+@@ -416,22 +416,13 @@ def configure(conf):
+ 
+     conf.CHECK_FUNCS('prctl dirname basename')
+ 
+-    strlcpy_in_bsd = False
++    # Not checking for libbsd
++    conf.CHECK_FUNCS('strlcpy strlcat')
++    conf.CHECK_FUNCS('getpeereid')
++    conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h')
++    conf.CHECK_FUNCS('setproctitle_init')
+ 
+-    # libbsd on some platforms provides strlcpy and strlcat
+-    if not conf.CHECK_FUNCS('strlcpy strlcat'):
+-        if conf.CHECK_FUNCS_IN('strlcpy strlcat', 'bsd', headers='bsd/string.h',
+-                               checklibc=True):
+-            strlcpy_in_bsd = True
+-    if not conf.CHECK_FUNCS('getpeereid'):
+-        conf.CHECK_FUNCS_IN('getpeereid', 'bsd', headers='sys/types.h bsd/unistd.h')
+-    if not conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h'):
+-        conf.CHECK_FUNCS_IN('setproctitle', 'bsd', headers='sys/types.h bsd/unistd.h')
+-    if not conf.CHECK_FUNCS('setproctitle_init'):
+-        conf.CHECK_FUNCS_IN('setproctitle_init', 'bsd', headers='sys/types.h bsd/unistd.h')
+-
+-    if not conf.CHECK_FUNCS('closefrom'):
+-        conf.CHECK_FUNCS_IN('closefrom', 'bsd', headers='bsd/unistd.h')
++    conf.CHECK_FUNCS('closefrom')
+ 
+     conf.CHECK_CODE('''
+                 struct ucred cred;
+@@ -808,9 +799,6 @@ def configure(conf):
+ 
+     # look for a method of finding the list of network interfaces
+     for method in ['HAVE_IFACE_GETIFADDRS', 'HAVE_IFACE_AIX', 'HAVE_IFACE_IFCONF', 'HAVE_IFACE_IFREQ']:
+-        bsd_for_strlcpy = ''
+-        if strlcpy_in_bsd:
+-            bsd_for_strlcpy = ' bsd'
+         if conf.CHECK_CODE('''
+                            #define %s 1
+                            #define NO_CONFIG_H 1
+@@ -823,7 +811,7 @@ def configure(conf):
+                            #include "tests/getifaddrs.c"
+                            ''' % method,
+                            method,
+-                           lib='nsl socket' + bsd_for_strlcpy,
++                           lib='nsl socket',
+                            addmain=False,
+                            execute=True):
+             break
+@@ -871,7 +859,6 @@ def build(bld):
+                 break
+ 
+     extra_libs = ''
+-    if bld.CONFIG_SET('HAVE_LIBBSD'): extra_libs += ' bsd'
+     if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt'
+     if bld.CONFIG_SET('REPLACE_REQUIRES_LIBSOCKET_LIBNSL'): extra_libs += ' socket nsl'
+ 
diff --git a/external/subpack/libs/tdb/patches/101_wafsamba-replace-echo-n-with-printf.patch b/external/subpack/libs/tdb/patches/101_wafsamba-replace-echo-n-with-printf.patch
new file mode 100644
index 0000000..9b8aca0
--- /dev/null
+++ b/external/subpack/libs/tdb/patches/101_wafsamba-replace-echo-n-with-printf.patch
@@ -0,0 +1,25 @@
+From: https://gitlab.com/samba-team/samba/-/merge_requests/2374/diffs?commit_id=90bb371863d5a44845f47ebbceeb60842b46eda7
+
+From 79b2f38c27c8df918d8260fe838f55bcf6d3eb73 Mon Sep 17 00:00:00 2001
+From: "Sergey V. Lobanov" <sergey@lobanov.in>
+Date: Thu, 10 Feb 2022 00:02:17 +0300
+Subject: [PATCH] wafsamba: replace 'echo -n' with printf
+
+This patch makes samba_cross.py compatible with old bash (e.g. 3.2)
+
+Signed-off-by: Sergey V. Lobanov <sergey@lobanov.in>
+---
+ buildtools/wafsamba/samba_cross.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/buildtools/wafsamba/samba_cross.py
++++ b/buildtools/wafsamba/samba_cross.py
+@@ -134,7 +134,7 @@ class cross_Popen(Utils.subprocess.Popen
+                 cross_answers_incomplete = True
+                 add_answer(ca_file, msg, ans)
+             (retcode, retstring) = ans
+-            args = ['/bin/sh', '-c', "echo -n '%s'; exit %d" % (retstring, retcode)]
++            args = ['/bin/sh', '-c', "printf '%s'; exit %d" % (retstring, retcode)]
+         real_Popen.__init__(*(obj, args), **kw)
+ 
+ 
diff --git a/external/subpack/libs/tiff/Makefile b/external/subpack/libs/tiff/Makefile
new file mode 100644
index 0000000..0e7bbd6
--- /dev/null
+++ b/external/subpack/libs/tiff/Makefile
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2006-2018 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:=tiff
+PKG_VERSION:=4.7.0
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://download.osgeo.org/libtiff
+PKG_HASH:=67160e3457365ab96c5b3286a0903aa6e78bdc44c4bc737d2e486bcecb6ba976
+
+PKG_MAINTAINER:=Jiri Slachta <jiri@slachta.eu>
+PKG_LICENSE:=libtiff
+PKG_LICENSE_FILES:=COPYRIGHT
+PKG_CPE_ID:=cpe:/a:libtiff:libtiff
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/tiff/Default
+  TITLE:=TIFF
+  URL:=http://simplesystems.org/libtiff/
+endef
+
+define Package/libtiff
+$(call Package/tiff/Default)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE+= library
+  DEPENDS:=+zlib +libjpeg
+  ABI_VERSION:=6
+endef
+
+define Package/tiff-utils
+$(call Package/tiff/Default)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  SUBMENU:=Image Manipulation
+  TITLE+= utilities
+  DEPENDS:=+libtiff
+endef
+
+CMAKE_OPTIONS += \
+	-Dld-version-script=OFF \
+	-Dold-jpeg=OFF \
+	-Djbig=OFF \
+	-Dlzma=OFF \
+	-Dzstd=OFF \
+	-Dwebp=OFF \
+	-Djpeg12=OFF \
+	-Dcxx=OFF \
+	-Dlibdeflate=OFF
+
+define Build/InstallDev
+	$(call Build/InstallDev/cmake,$(1))
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libtiff-4.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libtiff-4.pc
+endef
+
+define Package/libtiff/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libtiff.so.$(ABI_VERSION)* $(1)/usr/lib
+endef
+
+define Package/tiff-utils/install
+	$(INSTALL_DIR) $(1)/usr/bin
+	$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/* $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,libtiff))
+$(eval $(call BuildPackage,tiff-utils))
diff --git a/external/subpack/libs/tinycdb/Makefile b/external/subpack/libs/tinycdb/Makefile
new file mode 100644
index 0000000..05d56ca
--- /dev/null
+++ b/external/subpack/libs/tinycdb/Makefile
@@ -0,0 +1,63 @@
+# 
+# Copyright (C) 2014 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:=tinycdb
+PKG_RELEASE:=2
+PKG_SOURCE_URL:=http://www.corpit.ru/mjt/tinycdb/
+PKG_VERSION:=0.78
+PKG_HASH:=50678f432d8ada8d69f728ec11c3140e151813a7847cf30a62d86f3a720ed63c
+PKG_MAINTAINER:=Denis Shulyaka <Shulyaka@gmail.com>
+PKG_LICENSE:=NLPL
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+# Pass CPPFLAGS in the CFLAGS as otherwise the build system will
+# ignore them.
+TARGET_CFLAGS+=$(TARGET_CPPFLAGS)
+
+MAKE_FLAGS+= \
+	CFLAGS="$(TARGET_CFLAGS)" \
+	LDFLAGS="$(TARGET_LDFLAGS)"
+
+CDB_INST_STRING:=prefix=/usr install install-sharedlib install-piclib
+
+define Package/tinycdb
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=a Constant DataBase
+  URL:=http://www.corpit.ru/mjt/tinycdb.html
+  ABI_VERSION=1
+endef
+
+define Package/tinycdb/description
+ TinyCDB is a very fast and simple package for creating and reading constant data bases
+endef
+
+define Package/tinycdb/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libcdb.so.$(ABI_VERSION) $(1)/usr/lib
+endef
+
+define Build/Compile
+	$(call Build/Compile/Default,shared staticlib piclib)
+endef
+
+define Build/Install
+	$(call Build/Install/Default,$(CDB_INST_STRING))
+endef
+
+define Build/InstallDev
+	cd $(PKG_BUILD_DIR); $(MAKE) DESTDIR=$(1) $(CDB_INST_STRING)
+endef
+
+$(eval $(call BuildPackage,tinycdb))
diff --git a/external/subpack/libs/tinycdb/patches/100-Makefile.patch b/external/subpack/libs/tinycdb/patches/100-Makefile.patch
new file mode 100644
index 0000000..f309a8e
--- /dev/null
+++ b/external/subpack/libs/tinycdb/patches/100-Makefile.patch
@@ -0,0 +1,24 @@
+--- a/Makefile
++++ b/Makefile
+@@ -86,17 +86,17 @@ $(PICLIB): $(LIB_OBJS_PIC)
+ $(SHAREDLIB): $(LIB_OBJS_PIC) $(LIBMAP)
+ 	-rm -f $(SOLIB)
+ 	ln -s $@ $(SOLIB)
+-	$(LD) $(LDFLAGS) $(LDFLAGS_SHARED) -o $@ \
++	$(CC) $(LDFLAGS) $(LDFLAGS_SHARED) -o $@ \
+ 	 $(LDFLAGS_SONAME)$(SHAREDLIB) $(LDFLAGS_VSCRIPT)$(LIBMAP) \
+ 	 $(LIB_OBJS_PIC)
+ 
+ cdb: cdb.o $(CDB_USELIB)
+-	$(LD) $(LDFLAGS) -o $@ cdb.o $(CDB_USELIB)
++	$(CC) $(LDFLAGS) -o $@ cdb.o $(CDB_USELIB)
+ cdb-shared: cdb.o $(SHAREDLIB)
+-	$(LD) $(LDFLAGS) -o $@ cdb.o $(SHAREDLIB)
++	$(CC) $(LDFLAGS) -o $@ cdb.o $(SHAREDLIB)
+ 
+ $(NSS_CDB): $(NSS_OBJS) $(NSS_USELIB) $(NSSMAP)
+-	$(LD) $(LDFLAGS) $(LDFLAGS_SHARED) -o $@ \
++	$(CC) $(LDFLAGS) $(LDFLAGS_SHARED) -o $@ \
+ 	 $(LDFLAGS_SONAME)$@ $(LDFLAGS_VSCRIPT)$(NSSMAP) \
+ 	 $(NSS_OBJS) $(NSS_USELIB)
+ 
diff --git a/external/subpack/libs/totem-pl-parser/Makefile b/external/subpack/libs/totem-pl-parser/Makefile
new file mode 100644
index 0000000..626d412
--- /dev/null
+++ b/external/subpack/libs/totem-pl-parser/Makefile
@@ -0,0 +1,64 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=totem-pl-parser
+PKG_VERSION:=3.26.6
+PKG_RELEASE:=1
+
+PKG_SOURCE:=totem-pl-parser-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@GNOME/totem-pl-parser/$(basename $(PKG_VERSION))
+PKG_HASH:=c0df0f68d5cf9d7da43c81c7f13f11158358368f98c22d47722f3bd04bd3ac1c
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=LGPL-2-or-later
+PKG_LICENSE_FILES:=COPYING.LIB
+
+PKG_BUILD_DEPENDS:=glib2/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/totem-pl-parser
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+glib2 +libxml2 +shared-mime-info
+  TITLE:=totem-pl-parser
+  URL:=https://gitlab.gnome.org/GNOME/totem-pl-parser
+endef
+
+define Package/totem-pl-parser/decription
+  totem-pl-parser is a simple GObject-based library to parse a host of playlist formats
+endef
+
+MESON_ARGS += -Dintrospection=false \
+              -Denable-libarchive=no \
+              -Denable-libgcrypt=no
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/totem-pl-parser/ \
+		$(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc \
+		$(1)/usr/lib/pkgconfig/
+endef
+
+define Package/totem-pl-parser/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/*.so* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,totem-pl-parser))
diff --git a/external/subpack/libs/totem-pl-parser/patches/totem-pl-parser-3.26.6-initialize.patch b/external/subpack/libs/totem-pl-parser/patches/totem-pl-parser-3.26.6-initialize.patch
new file mode 100644
index 0000000..29d7e77
--- /dev/null
+++ b/external/subpack/libs/totem-pl-parser/patches/totem-pl-parser-3.26.6-initialize.patch
@@ -0,0 +1,11 @@
+--- a/plparse/totem-pl-parser.c
++++ b/plparse/totem-pl-parser.c
+@@ -1760,7 +1760,7 @@ totem_pl_parser_glob_is_ignored (TotemPl
+ {
+ 	GHashTableIter iter;
+ 	gpointer key;
+-	int ret;
++	int ret = -1;
+ 
+ 	g_mutex_lock (&parser->priv->ignore_mutex);
+ 	g_hash_table_iter_init (&iter, parser->priv->ignore_globs);
diff --git a/external/subpack/libs/uci2/Makefile b/external/subpack/libs/uci2/Makefile
new file mode 100644
index 0000000..c876a84
--- /dev/null
+++ b/external/subpack/libs/uci2/Makefile
@@ -0,0 +1,52 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=uci2
+PKG_VERSION:=1.0
+PKG_RELEASE:=2
+
+PKG_SOURCE_URL:=https://github.com/sartura/uci2.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_DATE:=2021-07-12
+PKG_SOURCE_VERSION:=56064182acdd8fa522abab67fdbaa10c2a28165c
+PKG_MIRROR_HASH:=94059a5cf110ecc04cfb9a8ffc160f9bd6a03518d4c4b195500d8eff001be9aa
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_DATE).tar.gz
+
+PKG_MAINTAINER:=Jakov Petrina <jakov.petrina@sartura.hr>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libuci2/Default
+	TITLE:=AST-based C parser library for UCI
+	URL:=https://github.com/sartura/uci2
+endef
+
+define Package/libuci2
+	$(call Package/libuci2/Default)
+	SECTION:=libs
+	CATEGORY:=Libraries
+endef
+
+define Package/libuci2/description
+UCI2 is a C library that provides an alternative UCI parser with an Abstract
+Syntax Tree (AST) representation of configuration files.
+endef
+
+CMAKE_OPTIONS += \
+	-DENABLE_TESTS=OFF
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/{libuci2,uci2_ast}.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libuci2.so $(1)/usr/lib/
+endef
+
+define Package/libuci2/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libuci2.so $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libuci2))
diff --git a/external/subpack/libs/udns/Makefile b/external/subpack/libs/udns/Makefile
new file mode 100644
index 0000000..6eb81ee
--- /dev/null
+++ b/external/subpack/libs/udns/Makefile
@@ -0,0 +1,74 @@
+#
+# Copyright (C) 2017 Yousong Zhou <yszhou4tech@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:=udns
+PKG_VERSION:=0.4
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_HASH:=115108dc791a2f9e99e150012bcb459d9095da2dd7d80699b584ac0ac3768710
+PKG_SOURCE_URL:=http://www.corpit.ru/mjt/udns
+PKG_LICENSE:=LGPL-2.1
+PKG_MAINTAINER:=Yousong Zhou <yszhou4tech@gmail.com>
+
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libudns
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=DNS Resolver Library
+  URL:=http://www.corpit.ru/mjt/udns.html
+endef
+
+define Package/libudns/description
+  UDNS is a stub DNS resolver library with ability to perform both syncronous
+  and asyncronous DNS queries.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/* $(1)/usr/lib
+endef
+
+define Package/libudns/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libudns.so* $(1)/usr/lib/
+endef
+
+define udns-utility-template
+  define Package/udns-$(1)
+    SECTION:=utils
+    CATEGORY:=Utilities
+    TITLE:= $(2)
+    URL:=http://www.corpit.ru/mjt/udns.html
+    DEPENDS:=+libudns
+  endef
+
+  define Package/udns-$(1)/install
+	$(INSTALL_DIR) $$(1)/usr/bin
+	$(CP) $(PKG_INSTALL_DIR)/usr/bin/$(1) $$(1)/usr/bin/
+  endef
+
+endef
+
+CONFIGURE_ARGS += $(DISABLE_IPV6)
+
+$(eval $(call udns-utility-template,dnsget,a simple DNS query tool))
+$(eval $(call udns-utility-template,rblcheck,a simple DNSBL lookups tool))
+$(eval $(call udns-utility-template,ex-rdns,a parallel rDNS resolver))
+
+$(eval $(call BuildPackage,libudns))
+$(eval $(call BuildPackage,udns-dnsget))
+$(eval $(call BuildPackage,udns-rblcheck))
+$(eval $(call BuildPackage,udns-ex-rdns))
diff --git a/external/subpack/libs/udns/patches/0001-use-autotools.patch b/external/subpack/libs/udns/patches/0001-use-autotools.patch
new file mode 100644
index 0000000..52cd5a2
--- /dev/null
+++ b/external/subpack/libs/udns/patches/0001-use-autotools.patch
@@ -0,0 +1,78 @@
+--- /dev/null
++++ b/configure.ac
+@@ -0,0 +1,56 @@
++# Copyright 2016 Yousong Zhou
++
++AC_PREREQ([2.67])
++AC_INIT([libudns], [0.4])
++AC_CONFIG_HEADERS([config.h])
++
++AM_INIT_AUTOMAKE([foreign])
++LT_INIT
++
++dnl Checks for programs.
++AC_PROG_CC
++AC_PROG_INSTALL
++AC_PROG_LN_S
++AC_PROG_LIBTOOL
++
++dnl Checks for library functions.
++AC_CHECK_LIB(socket, connect)
++AC_CHECK_FUNCS([malloc memset socket])
++AC_CHECK_FUNCS([getopt poll])
++AC_CHECK_FUNCS([inet_pton inet_ntop],
++			   [AC_DEFINE([HAVE_INET_PTON_NTOP], [1], [Have inet_pton and inet_ntop])])
++
++AC_ARG_ENABLE(ipv6,
++  AC_HELP_STRING([--disable-ipv6],[disable IPv6 support]),
++  [case "${enable_ipv6}" in
++    no)
++      AC_MSG_NOTICE([disabling IPv6 at user request])
++      ipv6=no
++      ;;
++    yes)
++      ipv6=yes
++	  force_ipv6=yes
++      ;;
++    *)
++      AC_MSG_ERROR([Invalid --enable-ipv6 argument \`$enable_ipv6'])
++      ;;
++    esac
++  ], [
++    dnl If nothing is specified, assume auto-detection.
++    ipv6=yes
++	force_ipv6=no
++  ]
++)
++
++if test "x$ipv6" = "xyes"; then
++  AC_CHECK_TYPE([struct sockaddr_in6],
++    [AC_DEFINE([HAVE_IPv6], [1], [Have ipv6 support])],
++    [if test "x$force_ipv6" = "xyes"; then
++      AC_MSG_ERROR([ipv6 support requested but cannot be fulfilled])
++     fi],
++    [#include <sys/socket.h>
++     #include <netinet/in.h>])
++fi
++
++AC_CONFIG_FILES([Makefile])
++AC_OUTPUT
+--- /dev/null
++++ b/Makefile.am
+@@ -0,0 +1,16 @@
++# Copyright 2016 Yousong Zhou
++
++lib_LTLIBRARIES=libudns.la
++libudns_la_SOURCES= udns_dn.c udns_dntosp.c udns_parse.c udns_resolver.c udns_init.c \
++	udns_misc.c udns_XtoX.c \
++	udns_rr_a.c udns_rr_ptr.c udns_rr_mx.c udns_rr_txt.c udns_bl.c \
++	udns_rr_srv.c udns_rr_naptr.c udns_codes.c udns_jran.c
++include_HEADERS= udns.h
++
++bin_PROGRAMS = dnsget rblcheck ex-rdns
++dnsget_SOURCES = dnsget.c
++rblcheck_SOURCES = rblcheck.c
++ex_rdns_SOURCES = ex-rdns.c
++dnsget_LDADD = $(top_builddir)/libudns.la
++rblcheck_LDADD = $(top_builddir)/libudns.la
++ex_rdns_LDADD = $(top_builddir)/libudns.la
diff --git a/external/subpack/libs/unixodbc/Makefile b/external/subpack/libs/unixodbc/Makefile
new file mode 100644
index 0000000..e862b19
--- /dev/null
+++ b/external/subpack/libs/unixodbc/Makefile
@@ -0,0 +1,219 @@
+#
+# Copyright (C) 2014 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:=unixodbc
+PKG_VERSION:=2.3.12
+PKG_RELEASE:=3
+
+PKG_SOURCE:=unixODBC-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.unixodbc.org
+PKG_HASH:=f210501445ce21bf607ba51ef8c125e10e22dffdffec377646462df5f01915ec
+
+PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
+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)
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=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
+#  PKG_BUILD_DEPENDS:=unixodbc/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+CONFIGURE_ARGS += \
+	--disable-gui \
+	--with-pic \
+	--enable-drivers
+
+define Package/unixodbc/Default
+  SUBMENU:=Database
+  TITLE:=unixODBC
+  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)
+  TITLE+= (libraries)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libodbc +libodbccr +libodbcinst
+endef
+
+define Package/unixodbc/description
+$(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)
+  SECTION:=utils
+  CATEGORY:=Utilities
+  TITLE+= Tools
+  DEPENDS:=+libodbc +libodbcinst +libltdl +libreadline
+endef
+
+define Package/unixodbc-tools/description
+$(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)
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=PostgreSQL driver for ODBC
+  DEPENDS:=+libodbc +libpq +libltdl +libpthread
+  ABI_VERSION:=2
+endef
+
+define Package/pgsqlodbc/description
+$(call Package/unixodbc/Default/description)
+
+This package provides the PostgreSQL driver for ODBC.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(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)/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
+endef
+
+define Package/libodbc/install
+	$(INSTALL_DIR) $(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/
+endef
+
+define Package/pgsqlodbc/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libodbcpsql.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/etc/odbcinst.ini.d/
+	$(INSTALL_DATA) ./files/pgsqlodbc.ini $(1)/etc/odbcinst.ini.d/
+endef
+
+define Host/Configure
+	$(call Host/Configure/Default)
+	$(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
+	$(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/
+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))
+$(eval $(call HostBuild))
diff --git a/external/subpack/libs/unixodbc/files/odbc.init b/external/subpack/libs/unixodbc/files/odbc.init
new file mode 100644
index 0000000..32ae7f8
--- /dev/null
+++ b/external/subpack/libs/unixodbc/files/odbc.init
@@ -0,0 +1,26 @@
+#!/bin/sh /etc/rc.common
+
+START=50
+
+gen_odbcinst() {
+	local inifile
+
+	echo "[ODBC]"
+	echo "Trace = off"
+	echo "TraceFile ="
+
+	for inifile in /etc/odbcinst.ini.d/*.ini; do
+		cat "$inifile"
+	done
+}
+
+start() {
+	[ ! -d /tmp/etc ] && mkdir /tmp/etc
+
+	gen_odbcinst > /tmp/etc/odbcinst.ini.new
+	chmod 0644 /tmp/etc/odbcinst.ini.new
+
+	[ -e /tmp/etc/odbcinst.ini ] && ( rm /tmp/etc/odbcinst.ini || return 1 )
+
+	mv /tmp/etc/odbcinst.ini.new /tmp/etc/odbcinst.ini
+}
diff --git a/external/subpack/libs/unixodbc/files/pgsqlodbc.ini b/external/subpack/libs/unixodbc/files/pgsqlodbc.ini
new file mode 100644
index 0000000..54a64bc
--- /dev/null
+++ b/external/subpack/libs/unixodbc/files/pgsqlodbc.ini
@@ -0,0 +1,3 @@
+[PostgreSQL]
+Description = unixODBC PostgreSQL driver
+Driver = /usr/lib/libodbcpsql.so
diff --git a/external/subpack/libs/unixodbc/patches/010-gcc14.patch b/external/subpack/libs/unixodbc/patches/010-gcc14.patch
new file mode 100644
index 0000000..51fe4e8
--- /dev/null
+++ b/external/subpack/libs/unixodbc/patches/010-gcc14.patch
@@ -0,0 +1,43 @@
+From 45f501e1be2db6b017cc242c79bfb9de32b332a1 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 29 Jan 2024 08:27:29 +0100
+Subject: [PATCH] PostgreSQL driver: Fix incompatible pointer-to-integer types
+
+These result in out-of-bounds stack writes on 64-bit architectures
+(caller has 4 bytes, callee writes 8 bytes), and seem to have gone
+unnoticed on little-endian architectures (although big-endian
+architectures must be broken).
+
+This change is required to avoid a build failure with GCC 14.
+---
+ Drivers/Postgre7.1/info.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/Drivers/Postgre7.1/info.c
++++ b/Drivers/Postgre7.1/info.c
+@@ -1779,14 +1779,14 @@ char *table_name;
+ char index_name[MAX_INFO_STRING];
+ short fields_vector[8];
+ char isunique[10], isclustered[10];
+-SDWORD index_name_len, fields_vector_len;
++SQLLEN index_name_len, fields_vector_len;
+ TupleNode *row;
+ int i;
+ HSTMT hcol_stmt;
+ StatementClass *col_stmt, *indx_stmt;
+ char column_name[MAX_INFO_STRING], relhasrules[MAX_INFO_STRING];
+ char **column_names = 0;
+-Int4 column_name_len;
++SQLLEN column_name_len;
+ int total_columns = 0;
+ char error = TRUE;
+ ConnInfo *ci;
+@@ -2136,7 +2136,7 @@ HSTMT htbl_stmt;
+ StatementClass *tbl_stmt;
+ char tables_query[STD_STATEMENT_LEN];
+ char attname[MAX_INFO_STRING];
+-SDWORD attname_len;
++SQLLEN attname_len;
+ char pktab[MAX_TABLE_LEN + 1];
+ Int2 result_cols;
+ 
diff --git a/external/subpack/libs/unixodbc/test.sh b/external/subpack/libs/unixodbc/test.sh
new file mode 100644
index 0000000..d4c42a4
--- /dev/null
+++ b/external/subpack/libs/unixodbc/test.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+[ "$1" = unixodbc-tools ] || exit 0
+
+isql --version | grep -Fx "unixODBC $PKG_VERSION"
diff --git a/external/subpack/libs/uw-imap/Makefile b/external/subpack/libs/uw-imap/Makefile
new file mode 100644
index 0000000..5af93a5
--- /dev/null
+++ b/external/subpack/libs/uw-imap/Makefile
@@ -0,0 +1,73 @@
+#
+# Copyright (C) 2017 Lucian Cristian <lucian.cristian@gmail.com>
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=uw-imap
+PKG_VERSION:=2007f
+PKG_RELEASE:=5
+
+PKG_SOURCE:=imap-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:= \
+	https://www.mirrorservice.org/sites/ftp.cac.washington.edu/imap \
+	http://ftp.ntua.gr/pub/net/mail/imap \
+	http://gd.tuwien.ac.at/infosys/mail/imap
+
+PKG_HASH:=53e15a2b5c1bc80161d42e9f69792a3fa18332b7b771910131004eb520004a28
+PKG_BUILD_DIR:=$(BUILD_DIR)/imap-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
+
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=LICENSE.txt
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/uw-imap
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=University of Washington IMAP toolkit
+  URL:=https://www.washington.edu/imap/
+  DEPENDS:=+libpthread +libopenssl
+endef
+
+define Package/uw-imap/description
+    The UW IMAP tookit includes the following:
+    c-lient library : an API (application programming interface) used to build email clients and servers,
+    including support for IMAP,POP3, SMTP and NNTP protocols and for local mailbox file access on Unix and Windows
+endef
+
+TARGET_CFLAGS += \
+	-fPIC -DPIC -D_REENTRANT -DDISABLE_POP_PROXY -fno-strict-aliasing -Wno-pointer-sign \
+	-Wno-implicit-function-declaration -Wno-incompatible-pointer-types
+
+MAKE_FLAGS += \
+	SSLINCLUDE=$(STAGING_DIR)/usr/include SSLCERTS=/etc/ssl/certs GCCOPTLEVEL=" -Os" \
+	SSLDIR=$(STAGING_DIR)/usr SHLIBNAME=libc-client.so.$(PKG_VERSION) $(if $(CONFIG_IPV6),IP=6,IP=4)
+
+define Build/Compile
+    $(MAKE) -C $(PKG_BUILD_DIR) slx EXTRACFLAGS='$(TARGET_CFLAGS)' CC='$(TARGET_CC)' $(MAKE_FLAGS)
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR)	$(1)/usr/lib \
+			$(1)/usr/include/c-client
+	$(CP) $(PKG_BUILD_DIR)/c-client/libc-client.so.$(PKG_VERSION) $(1)/usr/lib/
+	$(LN) libc-client.so.$(PKG_VERSION) $(1)/usr/lib/libc-client.so
+	$(CP) $(PKG_BUILD_DIR)/c-client/linkage.{c,h} $(1)/usr/include/c-client/
+	$(CP) $(PKG_BUILD_DIR)/src/c-client/*.h $(1)/usr/include/c-client/
+	$(CP) $(PKG_BUILD_DIR)/src/osdep/unix/*.h $(1)/usr/include/c-client/
+	$(LN) os_slx.h $(1)/usr/include/c-client/osdep.h
+endef
+
+define Package/uw-imap/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_BUILD_DIR)/c-client/libc-client.so.$(PKG_VERSION) $(1)/usr/lib/
+	$(LN) libc-client.so.$(PKG_VERSION) $(1)/usr/lib/libc-client.so
+endef
+
+
+$(eval $(call BuildPackage,uw-imap))
diff --git a/external/subpack/libs/uw-imap/patches/001-fix_Makefiles_and_shlib.patch b/external/subpack/libs/uw-imap/patches/001-fix_Makefiles_and_shlib.patch
new file mode 100644
index 0000000..db83f98
--- /dev/null
+++ b/external/subpack/libs/uw-imap/patches/001-fix_Makefiles_and_shlib.patch
@@ -0,0 +1,167 @@
+--- a/Makefile
++++ b/Makefile
+@@ -638,10 +638,6 @@ ip6:
+ 	@echo + yourself, try adding IP6=4 to the make command line.
+ 	@echo +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 	@echo
+-	@echo Do you want to build with IPv6 anyway?  Type y or n please:
+-	@$(SH) -c 'read x; case "$$x" in y) exit 0;; *) (make noip6;exit 1);; esac'
+-	@echo OK, I will remember that you really want to build with IPv6.
+-	@echo You will not see this message again.
+ 	@$(TOUCH) ip6
+ 
+ noip6:
+@@ -678,20 +674,18 @@ an ua:
+ 	$(TOOLS)/$@ "$(LN)" src/tmail tmail
+ 	$(LN) $(TOOLS)/$@ .
+ 
+-build:	OSTYPE rebuild rebuildclean bundled
++build:	OSTYPE rebuild rebuildclean
+ 
+ OSTYPE:
+ 	@$(MAKE) ip$(IP)
+ 	@echo Building c-client for $(BUILDTYPE)...
+ 	@$(TOUCH) SPECIALS
+-	echo `$(CAT) SPECIALS` $(EXTRASPECIALS) > c-client/SPECIALS
+ 	$(CD) c-client;$(MAKE) $(BUILDTYPE) EXTRACFLAGS='$(EXTRACFLAGS)'\
+ 	 EXTRALDFLAGS='$(EXTRALDFLAGS)'\
+ 	 EXTRADRIVERS='$(EXTRADRIVERS)'\
+ 	 EXTRAAUTHENTICATORS='$(EXTRAAUTHENTICATORS)'\
+ 	 PASSWDTYPE=$(PASSWDTYPE) SSLTYPE=$(SSLTYPE) IP=$(IP)\
+-	 $(SPECIALS) $(EXTRASPECIALS)
+-	echo $(BUILDTYPE) > OSTYPE
++	 $(SPECIALS) $(EXTRASPECIALS) OSTYPE=$(BUILDTYPE)
+ 	$(TOUCH) rebuild
+ 
+ rebuild:
+--- a/src/osdep/unix/Makefile
++++ b/src/osdep/unix/Makefile
+@@ -96,11 +96,11 @@ CHECKPW=std
+ LOGINPW=std
+ SIGTYPE=bsd
+ CRXTYPE=std
+-ACTIVEFILE=/usr/lib/news/active
+-SPOOLDIR=/usr/spool
++ACTIVEFILE=/var/lib/news/active
++SPOOLDIR=/var/spool
+ MAILSPOOL=$(SPOOLDIR)/mail
+ NEWSSPOOL=$(SPOOLDIR)/news
+-RSHPATH=/usr/ucb/rsh
++RSHPATH=/usr/bin/rsh
+ MD5PWD=/etc/cram-md5.pwd
+ # Tries one of the test alternatives below if not specified.
+ LOCKPGM=
+@@ -154,7 +154,7 @@ BINARIES=osdep.o mail.o misc.o newsrc.o
+  dummy.o pseudo.o netmsg.o flstring.o fdstring.o \
+  rfc822.o nntp.o smtp.o imap4r1.o pop3.o \
+  unix.o mbx.o mmdf.o tenex.o mtx.o news.o phile.o mh.o mx.o mix.o
+-CFLAGS=-g
++CFLAGS=$(BASECFLAGS) $(EXTRACFLAGS) -DCHUNKSIZE=$(CHUNKSIZE)
+ 
+ CAT=cat
+ MAKE=make
+@@ -162,6 +162,16 @@ MV=mv
+ RM=rm -rf
+ SH=sh
+ 
++OSCFLAGS= $(SSLCFLAGS) \
++	 -DCREATEPROTO=$(CREATEPROTO) -DEMPTYPROTO=$(EMPTYPROTO) \
++	 -DMD5ENABLE=\"$(MD5PWD)\" -DMAILSPOOL=\"$(MAILSPOOL)\" \
++	 -DANONYMOUSHOME=\"$(MAILSPOOL)/anonymous\" \
++	 -DACTIVEFILE=\"$(ACTIVEFILE)\" -DNEWSSPOOL=\"$(NEWSSPOOL)\" \
++	 -DRSHPATH=\"$(RSHPATH)\" -DLOCKPGM=\"$(LOCKPGM)\" \
++	 -DLOCKPGM1=\"$(LOCKPGM1)\" -DLOCKPGM2=\"$(LOCKPGM2)\" \
++	 -DLOCKPGM3=\"$(LOCKPGM3)\"
++
++LDFLAGS= $(BASELDFLAGS) $(EXTRALDFLAGS) $(SSLLDFLAGS)
+ 
+ # Primary build command
+ 
+@@ -174,7 +184,7 @@ BUILD=$(MAKE) build EXTRACFLAGS='$(EXTRA
+ # Here if no make argument established
+ 
+ missing: osdep.h
+-	$(MAKE) all `$(CAT) SPECIALS`
++	$(MAKE) all $(SPECIALS)
+ 
+ osdep.h:
+ 	@echo You must specify what type of system
+@@ -674,7 +684,7 @@ slx:	# Secure Linux
+ 	@echo You are building for libc6/glibc versions of Secure Linux
+ 	@echo If you want libc5 versions you must use sl5 instead!
+ 	@echo If you want libc4 versions you must use sl4 instead!
+-	$(BUILD) `$(CAT) SPECIALS` OS=$@ \
++	$(BUILD) $(SPECIALS) OS=$@ \
+ 	 SIGTYPE=psx CHECKPW=psx CRXTYPE=nfs \
+ 	 SPOOLDIR=/var/spool \
+ 	 ACTIVEFILE=/var/lib/news/active \
+@@ -863,7 +873,7 @@ $(ARCHIVE): $(BINARIES)
+ 	@$(SH) ARCHIVE
+ 
+ .c.o:
+-	`$(CAT) CCTYPE` -c `$(CAT) CFLAGS` $*.c
++	$(CC) -c $(CFLAGS) $*.c
+ 
+ 
+ # Cleanup
+@@ -922,8 +932,8 @@ osdep.o:mail.h misc.h env.h fs.h ftl.h n
+ 	@echo If you get No such file error messages for files x509.h, ssl.h,
+ 	@echo pem.h, buffer.h, bio.h, and crypto.h, that means that OpenSSL
+ 	@echo is not installed on your system.  Either install OpenSSL first
+-	@echo or build with command: make `$(CAT) OSTYPE` SSLTYPE=none
+-	`$(CAT) CCTYPE` -c `$(CAT) CFLAGS` `$(CAT) OSCFLAGS` -c osdep.c
++	@echo or build with command: make $(OSTYPE) SSLTYPE=none
++	$(CC) -c $(CFLAGS) $(OSCFLAGS) -c osdep.c
+ 
+ osdep.c: osdepbas.c osdepckp.c osdeplog.c osdepssl.c
+ 	$(CAT) osdepbas.c osdepckp.c osdeplog.c osdepssl.c > osdep.c
+@@ -962,21 +972,14 @@ os_sol.h:
+ 
+ # Once-only environment setup
+ 
+-once:	onceenv ckp$(PASSWDTYPE) ssl$(SSLTYPE) osdep.c
++once:	ssl$(SSLTYPE) onceenv ckp$(PASSWDTYPE) osdep.c
+ 
+ onceenv:
+ 	@echo Once-only environment setup...
+-	echo $(CC) > CCTYPE
+-	echo $(BASECFLAGS) '$(EXTRACFLAGS)' -DCHUNKSIZE=$(CHUNKSIZE) > CFLAGS
+-	echo -DCREATEPROTO=$(CREATEPROTO) -DEMPTYPROTO=$(EMPTYPROTO) \
+-	 -DMD5ENABLE=\"$(MD5PWD)\" -DMAILSPOOL=\"$(MAILSPOOL)\" \
+-	 -DANONYMOUSHOME=\"$(MAILSPOOL)/anonymous\" \
+-	 -DACTIVEFILE=\"$(ACTIVEFILE)\" -DNEWSSPOOL=\"$(NEWSSPOOL)\" \
+-	 -DRSHPATH=\"$(RSHPATH)\" -DLOCKPGM=\"$(LOCKPGM)\" \
+-	 -DLOCKPGM1=\"$(LOCKPGM1)\" -DLOCKPGM2=\"$(LOCKPGM2)\" \
+-	 -DLOCKPGM3=\"$(LOCKPGM3)\" > OSCFLAGS
+-	echo $(BASELDFLAGS) $(EXTRALDFLAGS) > LDFLAGS
+ 	echo "$(ARRC) $(ARCHIVE) $(BINARIES);$(RANLIB) $(ARCHIVE)" > ARCHIVE
++	echo "$(OSCFLAGS)" > OSCFLAGS
++	echo "$(CC) $(CFLAGS) $(OSCFLAGS) -shared  -Wl,-soname,libc-client.so \
++	-o $(SHLIBNAME) $(BINARIES) $(LDFLAGS)" >> ARCHIVE
+ 	echo $(OS) > OSTYPE
+ 	./drivers $(EXTRADRIVERS) $(DEFAULTDRIVERS) dummy
+ 	./mkauths $(EXTRAAUTHENTICATORS) $(DEFAULTAUTHENTICATORS)
+@@ -1055,7 +1058,6 @@ sslsco:	sbasic sldsco
+ sbasic:	# UNIX OpenSSL
+ 	@echo Building with SSL
+ 	$(LN) ssl_unix.c osdepssl.c
+-	echo $(SSLCFLAGS) >> OSCFLAGS
+ 	echo "  ssl_onceonlyinit ();" >> linkage.c
+ 
+ snopwd:	# Plaintext disable
+@@ -1063,13 +1065,12 @@ snopwd:	# Plaintext disable
+ 	echo "  mail_parameters (NIL,SET_DISABLEPLAINTEXT,(void *) 2);" >> linkage.c
+ 
+ sldunix:# Normal UNIX SSL load flags
+-	echo $(SSLLDFLAGS) >> LDFLAGS
++	@echo Normal UNIX SSL load flags
+ 
+ 
+ sldsco:	# SCO SSL load flags
+ # Note: Tim Rice says that SSL has to be lunk before other libraries on SCO.
+-	echo $(SSLLDFLAGS) `cat LDFLAGS` > LDFLAGS.tmp
+-	mv LDFLAGS.tmp LDFLAGS
++	@echo SCO SSL load flags
+ 
+ 
+ # A monument to a hack of long ago and far away...
diff --git a/external/subpack/libs/uw-imap/patches/002-imap-2004a-doc.patch b/external/subpack/libs/uw-imap/patches/002-imap-2004a-doc.patch
new file mode 100644
index 0000000..fecf95d
--- /dev/null
+++ b/external/subpack/libs/uw-imap/patches/002-imap-2004a-doc.patch
@@ -0,0 +1,30 @@
+Patch by Robert Scheck <redhat@linuxnetz.de> for uw-imap >= 2004a, which corrects
+paths to imapd, ipop2d and ipop3d in the man pages. 
+
+This patch is based on Red Hat Bugzilla ID #127271 and solves ID #229781.
+
+--- a/src/imapd/imapd.8
++++ b/src/imapd/imapd.8
+@@ -16,7 +16,7 @@
+ .SH NAME
+ IMAPd \- Internet Message Access Protocol server
+ .SH SYNOPSIS
+-.B /usr/etc/imapd
++.B /usr/sbin/imapd
+ .SH DESCRIPTION
+ .I imapd
+ is a server which supports the
+--- a/src/ipopd/ipopd.8
++++ b/src/ipopd/ipopd.8
+@@ -16,9 +16,9 @@
+ .SH NAME
+ IPOPd \- Post Office Protocol server
+ .SH SYNOPSIS
+-.B /usr/etc/ipop2d
++.B /usr/sbin/ipop2d
+ .PP
+-.B /usr/etc/ipop3d
++.B /usr/sbin/ipop3d
+ .SH DESCRIPTION
+ .I ipop2d
+ and
diff --git a/external/subpack/libs/uw-imap/patches/003-imap-2007e-overflow.patch b/external/subpack/libs/uw-imap/patches/003-imap-2007e-overflow.patch
new file mode 100644
index 0000000..48e473f
--- /dev/null
+++ b/external/subpack/libs/uw-imap/patches/003-imap-2007e-overflow.patch
@@ -0,0 +1,12 @@
+--- a/src/c-client/rfc822.c
++++ b/src/c-client/rfc822.c
+@@ -384,6 +384,9 @@ void rfc822_parse_content (BODY *body,ST
+ 	if (CHR (bs) == '\012'){/* following LF? */
+ 	  c = SNX (bs); i--;	/* yes, slurp it */
+ 	}
++	if (!i)			/* Make sure we don't get an overflow for */
++	  break;		/* messages ending on \015 (or the following */
++				/* i-- will cause i to be MAXINT. Not good.) */
+       case '\012':		/* at start of a line, start with -- ? */
+ 	if (!(i && i-- && ((c = SNX (bs)) == '-') && i-- &&
+ 	      ((c = SNX (bs)) == '-'))) break;
diff --git a/external/subpack/libs/uw-imap/patches/005-imap-2007e-authmd5.patch b/external/subpack/libs/uw-imap/patches/005-imap-2007e-authmd5.patch
new file mode 100644
index 0000000..0758dc1
--- /dev/null
+++ b/external/subpack/libs/uw-imap/patches/005-imap-2007e-authmd5.patch
@@ -0,0 +1,28 @@
+--- a/src/c-client/auth_md5.c
++++ b/src/c-client/auth_md5.c
+@@ -42,17 +42,17 @@ typedef struct {
+ 
+ /* Prototypes */
+ 
+-long auth_md5_valid (void);
+-long auth_md5_client (authchallenge_t challenger,authrespond_t responder,
++static long auth_md5_valid (void);
++static long auth_md5_client (authchallenge_t challenger,authrespond_t responder,
+ 		      char *service,NETMBX *mb,void *stream,
+ 		      unsigned long *trial,char *user);
+-char *auth_md5_server (authresponse_t responder,int argc,char *argv[]);
+-char *auth_md5_pwd (char *user);
++static char *auth_md5_server (authresponse_t responder,int argc,char *argv[]);
++static char *auth_md5_pwd (char *user);
+ char *apop_login (char *chal,char *user,char *md5,int argc,char *argv[]);
+-char *hmac_md5 (char *text,unsigned long tl,char *key,unsigned long kl);
+-void md5_init (MD5CONTEXT *ctx);
+-void md5_update (MD5CONTEXT *ctx,unsigned char *data,unsigned long len);
+-void md5_final (unsigned char *digest,MD5CONTEXT *ctx);
++static char *hmac_md5 (char *text,unsigned long tl,char *key,unsigned long kl);
++static void md5_init (MD5CONTEXT *ctx);
++static void md5_update (MD5CONTEXT *ctx,unsigned char *data,unsigned long len);
++static void md5_final (unsigned char *digest,MD5CONTEXT *ctx);
+ static void md5_transform (unsigned long *state,unsigned char *block);
+ static void md5_encode (unsigned char *dst,unsigned long *src,int len);
+ static void md5_decode (unsigned long *dst,unsigned char *src,int len);
diff --git a/external/subpack/libs/uw-imap/patches/006-imap-2007f-format-security.patch b/external/subpack/libs/uw-imap/patches/006-imap-2007f-format-security.patch
new file mode 100644
index 0000000..ce35b3b
--- /dev/null
+++ b/external/subpack/libs/uw-imap/patches/006-imap-2007f-format-security.patch
@@ -0,0 +1,11 @@
+--- a/src/osdep/unix/flocklnx.c
++++ b/src/osdep/unix/flocklnx.c
+@@ -57,7 +57,7 @@ int safe_flock (int fd,int op)
+     case ENOLCK:		/* lock table is full */
+       sprintf (tmp,"File locking failure: %s",strerror (errno));
+       mm_log (tmp,WARN);	/* give the user a warning of what happened */
+-      if (!logged++) syslog (LOG_ERR,tmp);
++      if (!logged++) syslog (LOG_ERR, "%s", tmp);
+ 				/* return failure if non-blocking lock */
+       if (op & LOCK_NB) return -1;
+       sleep (5);		/* slow down in case it loops */
diff --git a/external/subpack/libs/uw-imap/patches/007-imap-2007e-poll.patch b/external/subpack/libs/uw-imap/patches/007-imap-2007e-poll.patch
new file mode 100644
index 0000000..0948700
--- /dev/null
+++ b/external/subpack/libs/uw-imap/patches/007-imap-2007e-poll.patch
@@ -0,0 +1,186 @@
+http://anonscm.debian.org/cgit/collab-maint/uw-imap.git/plain/debian/patches/1005_poll.patch
+
+Description: Use poll(2) instead of select(2) to support more than 1024 file descriptors
+Author: Ben Smithurst <ben.smithurst@gradwell.com>
+Bug-Debian: https://bugs.debian.org/478193
+
+--- a/src/osdep/unix/os_lnx.c
++++ b/src/osdep/unix/os_lnx.c
+@@ -41,6 +41,7 @@
+ extern int errno;		/* just in case */
+ #include <pwd.h>
+ #include "misc.h"
++#include <poll.h>
+ 
+ 
+ #include "fs_unix.c"
+--- a/src/osdep/unix/os_slx.c
++++ b/src/osdep/unix/os_slx.c
+@@ -42,6 +42,7 @@ extern int errno;		/* just in case */
+ #include <pwd.h>
+ #include <shadow.h>
+ #include "misc.h"
++#include <poll.h>
+ 
+ 
+ #include "fs_unix.c"
+--- a/src/osdep/unix/tcp_unix.c
++++ b/src/osdep/unix/tcp_unix.c
+@@ -235,12 +235,11 @@ TCPSTREAM *tcp_open (char *host,char *se
+ int tcp_socket_open (int family,void *adr,size_t adrlen,unsigned short port,
+ 		     char *tmp,int *ctr,char *hst)
+ {
+-  int i,ti,sock,flgs;
++  int i,ti,sock,flgs,tmo;
++  struct pollfd pfd;
+   size_t len;
+   time_t now;
+   struct protoent *pt = getprotobyname ("tcp");
+-  fd_set rfds,wfds,efds;
+-  struct timeval tmo;
+   struct sockaddr *sadr = ip_sockaddr (family,adr,adrlen,port,&len);
+   blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
+ 				/* fetid Solaris */
+@@ -252,14 +251,6 @@ int tcp_socket_open (int family,void *ad
+     sprintf (tmp,"Unable to create TCP socket: %s",strerror (errno));
+     (*bn) (BLOCK_NONSENSITIVE,data);
+   }
+-  else if (sock >= FD_SETSIZE) {/* unselectable sockets are useless */
+-    sprintf (tmp,"Unable to create selectable TCP socket (%d >= %d)",
+-	     sock,FD_SETSIZE);
+-    (*bn) (BLOCK_NONSENSITIVE,data);
+-    close (sock);
+-    sock = -1;
+-    errno = EMFILE;
+-  }
+ 
+   else {			/* get current socket flags */
+     flgs = fcntl (sock,F_GETFL,0);
+@@ -284,16 +275,11 @@ int tcp_socket_open (int family,void *ad
+     if ((sock >= 0) && ctr) {	/* want open timeout? */
+       now = time (0);		/* open timeout */
+       ti = ttmo_open ? now + ttmo_open : 0;
+-      tmo.tv_usec = 0;
+-      FD_ZERO (&rfds);		/* initialize selection vector */
+-      FD_ZERO (&wfds);		/* initialize selection vector */
+-      FD_ZERO (&efds);		/* handle errors too */
+-      FD_SET (sock,&rfds);	/* block for error or readable or writable */
+-      FD_SET (sock,&wfds);
+-      FD_SET (sock,&efds);
++      pfd.fd = sock;
++      pfd.events = POLLIN | POLLOUT;
+       do {			/* block under timeout */
+-	tmo.tv_sec = ti ? ti - now : 0;
+-	i = select (sock+1,&rfds,&wfds,&efds,ti ? &tmo : NIL);
++	tmo = ti ? ti - now : 0;
++	i = poll (&pfd, 1, ti ? tmo * 1000 : -1);
+ 	now = time (0);		/* fake timeout if interrupt & time expired */
+ 	if ((i < 0) && (errno == EINTR) && ti && (ti <= now)) i = 0;
+       } while ((i < 0) && (errno == EINTR));
+@@ -302,7 +288,7 @@ int tcp_socket_open (int family,void *ad
+ 	fcntl (sock,F_SETFL,flgs);
+ 	/* This used to be a zero-byte read(), but that crashes Solaris */
+ 				/* get socket status */
+-	if(FD_ISSET(sock, &rfds)) while (((i = *ctr = read (sock,tmp,1)) < 0) && (errno == EINTR));
++	if(pfd.revents & POLLIN) while (((i = *ctr = read (sock,tmp,1)) < 0) && (errno == EINTR));
+       }	
+       if (i <= 0) {		/* timeout or error? */
+ 	i = i ? errno : ETIMEDOUT;/* determine error code */
+@@ -545,9 +531,8 @@ long tcp_getbuffer (TCPSTREAM *stream,un
+     stream->ictr -=n;
+   }
+   if (size) {
+-    int i;
+-    fd_set fds,efds;
+-    struct timeval tmo;
++    int i, tmo;
++    struct pollfd pfd;
+     time_t t = time (0);
+     blocknotify_t bn=(blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
+     (*bn) (BLOCK_TCPREAD,NIL);
+@@ -556,16 +541,13 @@ long tcp_getbuffer (TCPSTREAM *stream,un
+       time_t now = tl;
+       time_t ti = ttmo_read ? now + ttmo_read : 0;
+       if (tcpdebug) mm_log ("Reading TCP buffer",TCPDEBUG);
+-      tmo.tv_usec = 0;
+-      FD_ZERO (&fds);		/* initialize selection vector */
+-      FD_ZERO (&efds);		/* handle errors too */
+-				/* set bit in selection vectors */
+-      FD_SET (stream->tcpsi,&fds);
+-      FD_SET (stream->tcpsi,&efds);
++
++      pfd.events = POLLIN;
++      pfd.fd = stream->tcpsi;
+       errno = NIL;		/* initially no error */
+       do {			/* block under timeout */
+-	tmo.tv_sec = ti ? ti - now : 0;
+-	i = select (stream->tcpsi+1,&fds,NIL,&efds,ti ? &tmo : NIL);
++	tmo = ti ? ti - now : 0;
++	i = poll (&pfd, 1, ti ? tmo * 1000 : -1);
+ 	now = time (0);		/* fake timeout if interrupt & time expired */
+ 	if ((i < 0) && (errno == EINTR) && ti && (ti <= now)) i = 0;
+       } while ((i < 0) && (errno == EINTR));
+@@ -605,9 +587,8 @@ long tcp_getbuffer (TCPSTREAM *stream,un
+ 
+ long tcp_getdata (TCPSTREAM *stream)
+ {
+-  int i;
+-  fd_set fds,efds;
+-  struct timeval tmo;
++  int i, tmo;
++  struct pollfd pfd;
+   time_t t = time (0);
+   blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
+   if (stream->tcpsi < 0) return NIL;
+@@ -617,15 +598,12 @@ long tcp_getdata (TCPSTREAM *stream)
+     time_t now = tl;
+     time_t ti = ttmo_read ? now + ttmo_read : 0;
+     if (tcpdebug) mm_log ("Reading TCP data",TCPDEBUG);
+-    tmo.tv_usec = 0;
+-    FD_ZERO (&fds);		/* initialize selection vector */
+-    FD_ZERO (&efds);		/* handle errors too */
+-    FD_SET (stream->tcpsi,&fds);/* set bit in selection vectors */
+-    FD_SET (stream->tcpsi,&efds);
++    pfd.fd = stream->tcpsi;
++    pfd.events = POLLIN;
+     errno = NIL;		/* initially no error */
+     do {			/* block under timeout */
+-      tmo.tv_sec = ti ? ti - now : 0;
+-      i = select (stream->tcpsi+1,&fds,NIL,&efds,ti ? &tmo : NIL);
++      tmo = ti ? ti - now : 0;
++      i = poll (&pfd, 1, ti ? tmo * 1000 : -1);
+       now = time (0);		/* fake timeout if interrupt & time expired */
+       if ((i < 0) && (errno == EINTR) && ti && (ti <= now)) i = 0;
+     } while ((i < 0) && (errno == EINTR));
+@@ -677,9 +655,8 @@ long tcp_soutr (TCPSTREAM *stream,char *
+ 
+ long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size)
+ {
+-  int i;
+-  fd_set fds,efds;
+-  struct timeval tmo;
++  int i, tmo;
++  struct pollfd pfd;
+   time_t t = time (0);
+   blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL);
+   if (stream->tcpso < 0) return NIL;
+@@ -689,15 +666,12 @@ long tcp_sout (TCPSTREAM *stream,char *s
+     time_t now = tl;
+     time_t ti = ttmo_write ? now + ttmo_write : 0;
+     if (tcpdebug) mm_log ("Writing to TCP",TCPDEBUG);
+-    tmo.tv_usec = 0;
+-    FD_ZERO (&fds);		/* initialize selection vector */
+-    FD_ZERO (&efds);		/* handle errors too */
+-    FD_SET (stream->tcpso,&fds);/* set bit in selection vector */
+-    FD_SET(stream->tcpso,&efds);/* set bit in error selection vector */
++    pfd.fd = stream->tcpso;
++    pfd.events = POLLOUT;
+     errno = NIL;		/* block and write */
+     do {			/* block under timeout */
+-      tmo.tv_sec = ti ? ti - now : 0;
+-      i = select (stream->tcpso+1,NIL,&fds,&efds,ti ? &tmo : NIL);
++      tmo = ti ? ti - now : 0;
++      i = poll (&pfd, 1, ti ? tmo * 1000 : -1);
+       now = time (0);		/* fake timeout if interrupt & time expired */
+       if ((i < 0) && (errno == EINTR) && ti && (ti <= now)) i = 0;
+     } while ((i < 0) && (errno == EINTR));
diff --git a/external/subpack/libs/uw-imap/patches/010-imap-2007f-openssl-1.1.patch b/external/subpack/libs/uw-imap/patches/010-imap-2007f-openssl-1.1.patch
new file mode 100644
index 0000000..93482f9
--- /dev/null
+++ b/external/subpack/libs/uw-imap/patches/010-imap-2007f-openssl-1.1.patch
@@ -0,0 +1,81 @@
+From c3f68d987c00284d91ad6599a013b7111662545b Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+Date: Fri, 2 Sep 2016 21:33:33 +0000
+Subject: [PATCH] uw-imap: compile against openssl 1.1.0
+
+I *think* I replaced access to cert->name with certificate's subject name. I
+assume that the re-aranged C-code is doing the same thing. A double check
+wouldn't hurt :)
+
+Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
+---
+ src/osdep/unix/ssl_unix.c | 28 +++++++++++++++++-----------
+ 1 file changed, 17 insertions(+), 11 deletions(-)
+
+--- a/src/osdep/unix/ssl_unix.c
++++ b/src/osdep/unix/ssl_unix.c
+@@ -59,7 +59,7 @@ typedef struct ssl_stream {
+ static SSLSTREAM *ssl_start(TCPSTREAM *tstream,char *host,unsigned long flags);
+ static char *ssl_start_work (SSLSTREAM *stream,char *host,unsigned long flags);
+ static int ssl_open_verify (int ok,X509_STORE_CTX *ctx);
+-static char *ssl_validate_cert (X509 *cert,char *host);
++static char *ssl_validate_cert (X509 *cert,char *host, char *cert_subj);
+ static long ssl_compare_hostnames (unsigned char *s,unsigned char *pat);
+ static char *ssl_getline_work (SSLSTREAM *stream,unsigned long *size,
+ 			       long *contd);
+@@ -210,6 +210,7 @@ static char *ssl_start_work (SSLSTREAM *
+   BIO *bio;
+   X509 *cert;
+   unsigned long sl,tl;
++  char cert_subj[250];
+   char *s,*t,*err,tmp[MAILTMPLEN];
+   sslcertificatequery_t scq =
+     (sslcertificatequery_t) mail_parameters (NIL,GET_SSLCERTIFICATEQUERY,NIL);
+@@ -266,14 +267,19 @@ static char *ssl_start_work (SSLSTREAM *
+   if (SSL_write (stream->con,"",0) < 0)
+     return ssl_last_error ? ssl_last_error : "SSL negotiation failed";
+ 				/* need to validate host names? */
+-  if (!(flags & NET_NOVALIDATECERT) &&
+-      (err = ssl_validate_cert (cert = SSL_get_peer_certificate (stream->con),
+-				host))) {
+-				/* application callback */
+-    if (scq) return (*scq) (err,host,cert ? cert->name : "???") ? NIL : "";
++  if (!(flags & NET_NOVALIDATECERT)) {
++
++	cert_subj[0] = '\0';
++	cert = SSL_get_peer_certificate(stream->con);
++	if (cert)
++		X509_NAME_oneline(X509_get_subject_name(cert), cert_subj, sizeof(cert_subj));
++	err = ssl_validate_cert (cert, host, cert_subj);
++	if (err)
++		/* application callback */
++		if (scq) return (*scq) (err,host,cert ? cert_subj : "???") ? NIL : "";
+ 				/* error message to return via mm_log() */
+-    sprintf (tmp,"*%.128s: %.255s",err,cert ? cert->name : "???");
+-    return ssl_last_error = cpystr (tmp);
++	sprintf (tmp,"*%.128s: %.255s",err,cert ? cert_subj : "???");
++	return ssl_last_error = cpystr (tmp);
+   }
+   return NIL;
+ }
+@@ -313,7 +319,7 @@ static int ssl_open_verify (int ok,X509_
+  * Returns: NIL if validated, else string of error message
+  */
+ 
+-static char *ssl_validate_cert (X509 *cert,char *host)
++static char *ssl_validate_cert (X509 *cert,char *host, char *cert_subj)
+ {
+   int i,n;
+   char *s,*t,*ret;
+@@ -322,9 +328,9 @@ static char *ssl_validate_cert (X509 *ce
+ 				/* make sure have a certificate */
+   if (!cert) ret = "No certificate from server";
+ 				/* and that it has a name */
+-  else if (!cert->name) ret = "No name in certificate";
++  else if (cert_subj[0] == '\0') ret = "No name in certificate";
+ 				/* locate CN */
+-  else if (s = strstr (cert->name,"/CN=")) {
++  else if (s = strstr (cert_subj,"/CN=")) {
+     if (t = strchr (s += 4,'/')) *t = '\0';
+ 				/* host name matches pattern? */
+     ret = ssl_compare_hostnames (host,s) ? NIL :
diff --git a/external/subpack/libs/uw-imap/patches/020-deprecated-openssl.patch b/external/subpack/libs/uw-imap/patches/020-deprecated-openssl.patch
new file mode 100644
index 0000000..672b26a
--- /dev/null
+++ b/external/subpack/libs/uw-imap/patches/020-deprecated-openssl.patch
@@ -0,0 +1,62 @@
+--- a/src/osdep/unix/ssl_unix.c
++++ b/src/osdep/unix/ssl_unix.c
+@@ -35,6 +35,7 @@
+ #include <bio.h>
+ #include <crypto.h>
+ #include <rand.h>
++#include <rsa.h>
+ #undef crypt
+ 
+ #define SSLBUFLEN 8192
+@@ -90,6 +91,11 @@ static char *start_tls = NIL;	/* non-NIL
+ 
+ static int sslonceonly = 0;
+ 
++#if OPENSSL_API_COMPAT >= 0x10100000L
++#define SSL_CTX_need_tmp_RSA(ctx) 0
++#define SSL_CTX_set_tmp_rsa_callback(ctx, cb)    while(0) (cb)(NULL, 0, 0)
++#endif
++
+ void ssl_onceonlyinit (void)
+ {
+   if (!sslonceonly++) {		/* only need to call it once */
+@@ -114,7 +120,6 @@ void ssl_onceonlyinit (void)
+ 				/* apply runtime linkage */
+     mail_parameters (NIL,SET_SSLDRIVER,(void *) &ssldriver);
+     mail_parameters (NIL,SET_SSLSTART,(void *) ssl_start);
+-    SSL_library_init ();	/* add all algorithms */
+   }
+ }
+ 
+@@ -220,9 +225,7 @@ static char *ssl_start_work (SSLSTREAM *
+     (sslclientkey_t) mail_parameters (NIL,GET_SSLCLIENTKEY,NIL);
+   if (ssl_last_error) fs_give ((void **) &ssl_last_error);
+   ssl_last_host = host;
+-  if (!(stream->context = SSL_CTX_new ((flags & NET_TLSCLIENT) ?
+-				       TLSv1_client_method () :
+-				       SSLv23_client_method ())))
++  if (!(stream->context = SSL_CTX_new (TLS_client_method())))
+     return "SSL context failed";
+   SSL_CTX_set_options (stream->context,0);
+ 				/* disable certificate validation? */
+@@ -695,9 +698,6 @@ void ssl_server_init (char *server)
+   SSLSTREAM *stream = (SSLSTREAM *) memset (fs_get (sizeof (SSLSTREAM)),0,
+ 					    sizeof (SSLSTREAM));
+   ssl_onceonlyinit ();		/* make sure algorithms added */
+-  ERR_load_crypto_strings ();
+-  SSL_load_error_strings ();
+-				/* build specific certificate/key file names */
+   sprintf (cert,"%s/%s-%s.pem",SSL_CERT_DIRECTORY,server,tcp_serveraddr ());
+   sprintf (key,"%s/%s-%s.pem",SSL_KEY_DIRECTORY,server,tcp_serveraddr ());
+ 				/* use non-specific name if no specific cert */
+@@ -708,9 +708,7 @@ void ssl_server_init (char *server)
+     if (stat (key,&sbuf)) strcpy (key,cert);
+   }
+ 				/* create context */
+-  if (!(stream->context = SSL_CTX_new (start_tls ?
+-				       TLSv1_server_method () :
+-				       SSLv23_server_method ())))
++  if (!(stream->context = SSL_CTX_new (TLS_server_method())))
+     syslog (LOG_ALERT,"Unable to create SSL context, host=%.80s",
+ 	    tcp_clienthost ());
+   else {			/* set context options */
diff --git a/external/subpack/libs/vips/Makefile b/external/subpack/libs/vips/Makefile
new file mode 100644
index 0000000..5806bd7
--- /dev/null
+++ b/external/subpack/libs/vips/Makefile
@@ -0,0 +1,84 @@
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=vips
+PKG_VERSION:=8.15.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/libvips/libvips/releases/download/v$(PKG_VERSION)
+PKG_HASH:=a2ab15946776ca7721d11cae3215f20f1f097b370ff580cd44fc0f19387aee84
+
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:libvips:libvips
+
+PKG_BUILD_DEPENDS:=glib2/host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/meson.mk
+
+define Package/vips
+  $(call Package/vips/Default)
+  SECTION:=multimedia
+  CATEGORY:=Multimedia
+  TITLE:=An image manipulation library
+  URL:=https://libvips.github.io/libvips/
+  DEPENDS:=+glib2 +libexif +libexpat +libjpeg +libpng +giflib +libxml2
+endef
+
+MESON_ARGS += \
+	-Dgtk_doc=false \
+	-Dintrospection=disabled \
+	-Danalyze=false \
+	-Dcfitsio=disabled \
+	-Dfftw=disabled \
+	-Darchive=disabled \
+	-Dimagequant=disabled \
+	-Dlcms=disabled \
+	-Dwebp=disabled \
+	-Dmagick=disabled \
+	-Dmagick-package=disabled \
+	-Dmatio=disabled \
+	-Dnifti=disabled \
+	-Dopenexr=disabled \
+	-Dopenslide=disabled \
+	-Dorc=disabled \
+	-Dpangocairo=disabled \
+	-Dpdfium=disabled \
+	-Dpoppler=disabled \
+	-Dppm=false \
+	-Dradiance=false \
+	-Drsvg=disabled \
+	-Dtiff=disabled \
+	-Dzlib=disabled \
+	-Dcgif=enabled \
+	-Djpeg=enabled \
+	-Dexif=enabled \
+	-Dpng=enabled \
+
+TARGET_CXXFLAGS += -fno-rtti
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/vips
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/vips/* $(1)/usr/include/vips
+
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libvips.so* $(1)/usr/lib/
+
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig/
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/vips.pc $(1)/usr/lib/pkgconfig/vips.pc
+endef
+
+define Package/vips/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libvips.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,vips))
diff --git a/external/subpack/libs/websocketpp/Makefile b/external/subpack/libs/websocketpp/Makefile
new file mode 100644
index 0000000..a3daae5
--- /dev/null
+++ b/external/subpack/libs/websocketpp/Makefile
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2018 Bruno Randolf (br1@einfach.org)
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=websocketpp
+PKG_VERSION:=0.8.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/zaphoyd/websocketpp/archive/$(PKG_VERSION)/
+PKG_HASH:=6ce889d85ecdc2d8fa07408d6787e7352510750daa66b5ad44aacb47bea76755
+
+PKG_MAINTAINER:=Bruno Randolf <br1@einfach.org>
+PKG_LICENSE:=BSD-3-Clause
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:zaphoyd:websocketpp
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+CMAKE_INSTALL:=1
+
+define Package/websocketpp
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=WebSocket++
+	URL:=https://www.zaphoyd.com/websocketpp
+	BUILDONLY:=1
+endef
+
+define Package/websocketpp/description
+	WebSocket++ is a header only C++ library that implements RFC6455
+	The WebSocket Protocol.
+endef
+
+$(eval $(call BuildPackage,websocketpp))
diff --git a/external/subpack/libs/xmlrpc-c/Makefile b/external/subpack/libs/xmlrpc-c/Makefile
new file mode 100644
index 0000000..61fe717
--- /dev/null
+++ b/external/subpack/libs/xmlrpc-c/Makefile
@@ -0,0 +1,217 @@
+#
+# Copyright (C) 2007-2014 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:=xmlrpc-c
+PKG_VERSION:=1.59.03
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tgz
+PKG_SOURCE_URL:=@SF/xmlrpc-c/Xmlrpc-c%20Super%20Stable/$(PKG_VERSION)
+PKG_HASH:=bdb71db42ab0be51591555885d11682b044c1034d4a3296401bf921ec0b233fe
+
+PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
+PKG_LICENSE:=VARIOUS
+PKG_LICENSE_FILES:=doc/COPYING
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/xmlrpc-c/Default
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=XML-RPC library
+  URL:=http://xmlrpc-c.sourceforge.net/
+endef
+
+define Package/xmlrpc-c-common
+  $(call Package/xmlrpc-c/Default)
+  TITLE+= - common
+  DEPENDS+= +libpthread
+  HIDDEN:=1
+endef
+
+define Package/xmlrpc-c-internal
+  $(call Package/xmlrpc-c/Default)
+  TITLE+= (uses internal expat variant)
+  DEPENDS:=+xmlrpc-c-common
+  PROVIDES:=xmlrpc-c
+  VARIANT:=internal
+endef
+
+define Package/xmlrpc-c-libxml2
+  $(call Package/xmlrpc-c/Default)
+  TITLE+= (uses libxml2)
+  DEPENDS:=+xmlrpc-c-common +libxml2
+  PROVIDES:=xmlrpc-c
+  VARIANT:=libxml2
+endef
+
+define Package/xmlrpc-c-client
+  $(call Package/xmlrpc-c/Default)
+  TITLE+= - client
+  DEPENDS:=+xmlrpc-c +libcurl
+endef
+
+define Package/xmlrpc-c-server
+  $(call Package/xmlrpc-c/Default)
+  TITLE+= - server
+  DEPENDS:=+xmlrpc-c
+endef
+
+define Package/xmlrpc-c-abyss
+  $(call Package/xmlrpc-c/Default)
+  TITLE+= - abyss
+  DEPENDS:=+xmlrpc-c-common
+endef
+
+define Package/xmlrpc-c-server-abyss
+  $(call Package/xmlrpc-c/Default)
+  TITLE+= - abyss server
+  DEPENDS:=+xmlrpc-c-server +xmlrpc-c-abyss
+endef
+
+define Package/xmlrpc-c/description/Default
+    Programming library for writing an XML-RPC server or client in C or C++.
+    XML-RPC is a standard network protocol to allow a client program to make
+    a simple remote procedure call (RPC) type request of a server.
+endef
+
+Package/xmlrpc-c-common/description = $(Package/xmlrpc-c/description/Default)
+Package/xmlrpc-c-libxml2/description = $(Package/xmlrpc-c/description/Default)
+Package/xmlrpc-c-internal/description = $(Package/xmlrpc-c/description/Default)
+
+Package/xmlrpc-c-libxml2/description += Uses external libxml2 library (quite big)
+Package/xmlrpc-c-internal/description += Uses internal expat variant (stripped down)
+
+CONFIGURE_ARGS+= \
+	--disable-wininet-client \
+	--disable-libwww-client \
+	--disable-cgi-server \
+	--disable-cplusplus \
+	--without-libwww-ssl \
+	--disable-abyss-openssl
+
+ifeq ($(BUILD_VARIANT),libxml2)
+	CONFIGURE_ARGS += \
+		--enable-libxml2-backend
+endif
+
+ifeq ($(BUILD_VARIANT),internal)
+	CONFIGURE_ARGS += \
+		--disable-libxml2-backend
+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 )
+	$(call Build/Compile/Default)
+endef
+
+TARGET_VARIANT=$(if $(ALL_VARIANTS),$(if $(VARIANT),$(VARIANT),$(firstword $(ALL_VARIANTS))))
+ifeq ($(if $(TARGET_VARIANT),$(BUILD_VARIANT)),$(TARGET_VARIANT))
+  define Build/InstallDev
+	$(INSTALL_DIR) \
+		$(1)/usr/include \
+		$(1)/usr/lib \
+		$(1)/usr/bin \
+		$(1)/usr/lib/pkgconfig \
+		$(2)/bin
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/include/* \
+		$(1)/usr/include/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxmlrpc*.{a,so*} \
+		$(1)/usr/lib/
+	$(INSTALL_BIN) \
+		$(PKG_INSTALL_DIR)/usr/bin/xmlrpc-c-config \
+		$(2)/bin/
+	$(SED) 's,PREFIX="/usr",PREFIX="$(STAGING_DIR)/usr",g' $(2)/bin/xmlrpc-c-config
+	$(SED) \
+		's,HEADERINST_DIR="/usr/include",HEADERINST_DIR="$(STAGING_DIR)/usr/include",g' \
+		$(2)/bin/xmlrpc-c-config
+	$(SED) \
+		's,LIBINST_DIR="/usr/lib",LIBINST_DIR="$(STAGING_DIR)/usr/lib",g' \
+		$(2)/bin/xmlrpc-c-config
+	$(INSTALL_DATA) \
+		$(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc \
+		$(1)/usr/lib/pkgconfig/
+  endef
+endif
+
+define Package/xmlrpc-c-libxml2/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxmlrpc.so* \
+		$(1)/usr/lib/
+endef
+
+define Package/xmlrpc-c-internal/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxmlrpc.so* \
+		$(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxmlrpc_xmltok.so* \
+		$(1)/usr/lib/
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxmlrpc_xmlparse.so* \
+		$(1)/usr/lib/
+endef
+
+define Package/xmlrpc-c-server/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxmlrpc_server.so* \
+		$(1)/usr/lib/
+endef
+
+define Package/xmlrpc-c-abyss/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxmlrpc_abyss.so* \
+		$(1)/usr/lib/
+endef
+
+define Package/xmlrpc-c-server-abyss/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxmlrpc_server_abyss.so* \
+		$(1)/usr/lib/
+endef
+
+define Package/xmlrpc-c-client/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxmlrpc_client* \
+		$(1)/usr/lib/
+endef
+
+define Package/xmlrpc-c-common/install
+	$(INSTALL_DIR) \
+		$(1)/usr/lib
+	$(CP) \
+		$(PKG_INSTALL_DIR)/usr/lib/libxmlrpc_util.so* \
+		$(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,xmlrpc-c-common))
+$(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-client))
diff --git a/external/subpack/libs/xmlrpc-c/patches/001-fix-pkg-config-files.patch b/external/subpack/libs/xmlrpc-c/patches/001-fix-pkg-config-files.patch
new file mode 100644
index 0000000..e52d11e
--- /dev/null
+++ b/external/subpack/libs/xmlrpc-c/patches/001-fix-pkg-config-files.patch
@@ -0,0 +1,299 @@
+--- a/lib/abyss/src/Makefile
++++ b/lib/abyss/src/Makefile
+@@ -131,13 +131,15 @@ SOCKLIB=$(SOCKETLIBOPT)
+ xmlrpc_abyss.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_abyss"                                  >>$@
+ 	@echo "Description: Xmlrpc-c Abyss HTTP C library"                 >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc_util"                                      >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_abyss $(SOCKLIB)"        >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_abyss $(SOCKLIB)'           >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ # Need this dependency for those who don't use depend.mk.
+ # Without it, version.h doesn't get created.
+--- a/lib/abyss++/Makefile
++++ b/lib/abyss++/Makefile
+@@ -120,13 +120,15 @@ $(LIBXMLRPC_ABYSSPP_MODS:%=%.osh): \
+ xmlrpc_abyss++.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_abyss++"                                >>$@
+ 	@echo "Description: Xmlrpc-c Abyss HTTP C++ library"               >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc_abyss xmlrpc_util++"                       >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_abyss++"                 >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_abyss++'                    >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ #-----------------------------------------------------------------------------
+ #  MISCELLANEOUS RULES
+--- a/lib/expat/Makefile
++++ b/lib/expat/Makefile
+@@ -34,13 +34,15 @@ xmltok/all: gennmtab/all
+ xmlrpc_expat.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_expat"                                  >>$@
+ 	@echo "Description: Xmlrpc-c XML parsing library"                  >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc_util"                                      >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_xmlparse -lxmlrpc_xmltok" >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_xmlparse -lxmlrpc_xmltok'   >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ .PHONY: clean
+ clean: $(SUBDIRS:%=%/clean) clean-common
+--- a/lib/libutil/Makefile
++++ b/lib/libutil/Makefile
+@@ -112,13 +112,15 @@ libxmlrpc_util.a: LIBOBJECTS = $(TARGET_
+ xmlrpc_util.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_util"                                   >>$@
+ 	@echo "Description: Xmlrpc-c utility functions library"            >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: "                                                 >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_util"                    >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_util'                       >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ .PHONY: install
+ install: install-common
+--- a/lib/libutil++/Makefile
++++ b/lib/libutil++/Makefile
+@@ -101,13 +101,15 @@ libxmlrpc_util++.a: LIBOBJECTS = $(LIBXM
+ xmlrpc_util++.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_util++"                                 >>$@
+ 	@echo "Description: Xmlrpc-c C++ utility functions library"        >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc_util"                                      >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_util++"                  >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_util++'                     >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ #-----------------------------------------------------------------------------
+ #  MISCELLANEOUS RULES
+--- a/lib/openssl/Makefile
++++ b/lib/openssl/Makefile
+@@ -81,13 +81,15 @@ INCLUDES = \
+ xmlrpc_openssl.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_openssl"                                >>$@
+ 	@echo "Description: Openssl convenience function from Xmlrpc-c package"                 >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc_util"                                      >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_openssl"                 >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir}  -lxmlrpc_openssl'                   >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ #-----------------------------------------------------------------------------
+ #  MISCELLANEOUS
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -333,57 +333,67 @@ libxmlrpc_client.ldflags:
+ xmlrpc.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
+-	@echo "Name:        xmlrpc"                                        >>$@
+-	@echo "Description: Xmlrpc-c basic XML-RPC library"                >>$@
+-	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
++	@echo 'Name:        xmlrpc'                                        >>$@
++	@echo 'Description: Xmlrpc-c basic XML-RPC library'                >>$@
++	@echo 'Version:     $(XMLRPC_VERSION_STRING)'                      >>$@
+ 	@echo	                                                           >>$@
+-	@echo "Requires: xmlrpc_util $(XML_PKGCONFIG_REQ)"                 >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc"                         >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Requires: xmlrpc_util $(XML_PKGCONFIG_REQ)'                 >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc'                            >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ xmlrpc_client.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_client"                                 >>$@
+ 	@echo "Description: Xmlrpc-c XML-RPC client library"               >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc xmlrpc_util"                               >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_client"                  >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_client'                     >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ xmlrpc_server.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_server"                                 >>$@
+ 	@echo "Description: Xmlrpc-c XML-RPC server library"               >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc xmlrpc_util"                               >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_server"                  >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_server'                     >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ xmlrpc_server_abyss.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_server_abyss"                           >>$@
+ 	@echo "Description: Xmlrpc-c Abyss XML-RPC server library"         >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc xmlrpc_server xmlrpc_abyss xmlrpc_util"    >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_server_abyss"            >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_server_abyss'               >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ xmlrpc_server_cgi.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_server_cgi"                             >>$@
+ 	@echo "Description: Xmlrpc-c CGI XML-RPC server library"           >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc xmlrpc_server xmlrpc_util"                 >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_server_cgi"              >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_server_cgi'                 >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ .PHONY: check
+ check:
+--- a/src/cpp/Makefile
++++ b/src/cpp/Makefile
+@@ -355,57 +355,67 @@ $(TRANSPORT_CONFIG_USERS:%=%.o) $(TRANSP
+ xmlrpc++.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc++"                                      >>$@
+ 	@echo "Description: Xmlrpc-c basic XML-RPC C++ library"            >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc xmlrpc_util"                               >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc++"                       >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc++'                          >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ xmlrpc_client++.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_client++"                               >>$@
+ 	@echo "Description: Xmlrpc-c XML-RPC client C++ library"           >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc++ xmlrpc_client xmlrpc_util++ xmlrpc_util" >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_client++"                >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_client++'                   >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ xmlrpc_server++.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_server++"                               >>$@
+ 	@echo "Description: Xmlrpc-c XML-RPC server C++ library"           >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc++ xmlrpc xmlrpc_server xmlrpc_util++ xmlrpc_util" >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_server++"                >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_server++'                   >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ xmlrpc_server_abyss++.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_server_abyss++"                         >>$@
+ 	@echo "Description: Xmlrpc-c Abyss XML-RPC server C++ library"     >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+ 	@echo "Requires: xmlrpc++ xmlrpc xmlrpc_server++ xmlrpc_abyss xmlrpc_util++ xmlrpc_util"    >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_server_abyss"            >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_server_abyss++'             >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ xmlrpc_server_pstream++.pc:
+ 	rm -f $@
+ 	@echo "Echoes to '$@' suppressed here ..."
++	@echo -e '$(PKGCONFIG_VAR_SET)'                                    >>$@
++	@echo	                                                           >>$@
+ 	@echo "Name:        xmlrpc_server_pstream"                         >>$@
+ 	@echo "Description: Xmlrpc-c packet stream XML-RPC server library" >>$@
+ 	@echo "Version:     $(XMLRPC_VERSION_STRING)"                      >>$@
+ 	@echo	                                                           >>$@
+-	@echo "Requires: xmlrpc++ xmlrpc xmlrpc_server++ xmlrpc_util++ xmlrpc_util"                 >>$@
+-	@echo "Libs:     -L$(LIBDESTDIR) -lxmlrpc_server_pstream++ -lxmlrpc_packetsocket"              >>$@
+-	@echo "Cflags:   -I$(HEADERDESTDIR)"                               >>$@
++	@echo "Requires: xmlrpc++ xmlrpc xmlrpc_server++ xmlrpc_util++ xmlrpc_util" >>$@
++	@echo 'Libs:     -L$${libdir} -lxmlrpc_server_pstream++' -lxmlrpc_packetsocket >>$@
++	@echo 'Cflags:   -I$${includedir}'                                 >>$@
+ 
+ #-----------------------------------------------------------------------------
+ #  MISCELLANEOUS RULES
+--- a/common.mk
++++ b/common.mk
+@@ -584,6 +584,11 @@ PROGRAMDESTDIR   = $(DESTDIR)$(PROGRAMIN
+ MANDESTDIR       = $(DESTDIR)$(MANINST_DIR)
+ PKGCONFIGDESTDIR = $(DESTDIR)$(PKGCONFIGINST_DIR)
+ 
++# The following value, in a pkg-config file, sets the conventional pkg-config
++# variables that the pkg-config user can override at pkg-config time.
++PKGCONFIG_VAR_SET = \
++  prefix=$(PREFIX)\nexec_prefix=$${prefix}\nincludedir=$${prefix}/include\nlibdir=$${exec_prefix}/lib
++
+ 
+ ##############################################################################
+ #                           INSTALL RULES                                    #
diff --git a/external/subpack/libs/xmlrpc-c/patches/002-remove-unnecessary-linking.patch b/external/subpack/libs/xmlrpc-c/patches/002-remove-unnecessary-linking.patch
new file mode 100644
index 0000000..0e21dcf
--- /dev/null
+++ b/external/subpack/libs/xmlrpc-c/patches/002-remove-unnecessary-linking.patch
@@ -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 = \
diff --git a/external/subpack/libs/xmlrpc-c/patches/010-nanosleep.patch b/external/subpack/libs/xmlrpc-c/patches/010-nanosleep.patch
new file mode 100644
index 0000000..52703cb
--- /dev/null
+++ b/external/subpack/libs/xmlrpc-c/patches/010-nanosleep.patch
@@ -0,0 +1,20 @@
+--- a/lib/libutil/sleep.c
++++ b/lib/libutil/sleep.c
+@@ -8,7 +8,7 @@
+ #  include <windows.h>
+ #  include <process.h>
+ #else
+-#  include <unistd.h>
++#  include <time.h>
+ #endif
+ 
+ 
+@@ -18,6 +18,7 @@ xmlrpc_millisecond_sleep(unsigned int co
+ #if MSVCRT
+     SleepEx(milliseconds, true);
+ #else
+-    usleep(milliseconds * 1000);
++    const struct timespec req = {0, milliseconds * 1000 * 1000};
++    nanosleep(&req, NULL);
+ #endif
+ }
diff --git a/external/subpack/libs/xr_usb_serial_common/Makefile b/external/subpack/libs/xr_usb_serial_common/Makefile
new file mode 100644
index 0000000..85348c2
--- /dev/null
+++ b/external/subpack/libs/xr_usb_serial_common/Makefile
@@ -0,0 +1,39 @@
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=usb-serial-xr_usb_serial_common
+PKG_SOURCE_DATE:=2023-03-21
+PKG_SOURCE_VERSION:=90ad530166f096347a5a57b6f9eb21c422a40fd9
+PKG_RELEASE:=3
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/kasbert/epsolar-tracer
+PKG_MIRROR_HASH:=0907dfbcb18cc0b2ff3e2af79eb7943c5215ec176db994a89832aef606c98a1a
+
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=LICENSE
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/usb-serial-xr_usb_serial_common
+	SECTION:=kernel
+	CATEGORY:=Kernel modules
+	SUBMENU:=USB Support
+	TITLE:=Support for Exar USB to RS-485/RS-422
+	URL:=https://www.exar.com/content/document.ashx?id=21651
+	FILES:=$(PKG_BUILD_DIR)/xr_usb_serial_common-1a/xr_usb_serial_common.$(LINUX_KMOD_SUFFIX)
+	AUTOLOAD:=$(call AutoProbe,xr_usb_serial_common)
+	DEPENDS+=kmod-usb-serial
+endef
+
+define Build/Compile
+	+$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
+		ARCH="$(LINUX_KARCH)" \
+		CROSS_COMPILE="$(TARGET_CROSS)" \
+		M="$(PKG_BUILD_DIR)/xr_usb_serial_common-1a" \
+		modules
+endef
+
+$(eval $(call KernelPackage,usb-serial-xr_usb_serial_common))
diff --git a/external/subpack/libs/xr_usb_serial_common/patches/0001-fix-kernel-6.6-builds.patch b/external/subpack/libs/xr_usb_serial_common/patches/0001-fix-kernel-6.6-builds.patch
new file mode 100644
index 0000000..beb3188
--- /dev/null
+++ b/external/subpack/libs/xr_usb_serial_common/patches/0001-fix-kernel-6.6-builds.patch
@@ -0,0 +1,52 @@
+From 5115918c11cc99e93586cef7f33d8d3907b7258a Mon Sep 17 00:00:00 2001
+From: Adam Duskett <adam.duskett@amarulasolutions.com>
+Date: Wed, 3 Apr 2024 12:45:41 -0600
+Subject: [PATCH] Support Linux >= 6.2.0
+
+FROM: https://github.com/kasbert/epsolar-tracer/pull/61
+
+Signed-off-by: Adam Duskett <adam.duskett@amarulasolutions.com>
+---
+ xr_usb_serial_common-1a/xr_usb_serial_common.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/xr_usb_serial_common-1a/xr_usb_serial_common.c
++++ b/xr_usb_serial_common-1a/xr_usb_serial_common.c
+@@ -643,8 +643,13 @@ static void xr_usb_serial_tty_close(stru
+ 	tty_port_close(&xr_usb_serial->port, tty, filp);
+ }
+ 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)
++static ssize_t xr_usb_serial_tty_write(struct tty_struct *tty,
++					const unsigned char *buf, size_t count)
++#else
+ static int xr_usb_serial_tty_write(struct tty_struct *tty,
+ 					const unsigned char *buf, int count)
++#endif
+ {
+ 	struct xr_usb_serial *xr_usb_serial = tty->driver_data;
+ 	int stat;
+@@ -655,7 +660,11 @@ static int xr_usb_serial_tty_write(struc
+ 	if (!count)
+ 		return 0;
+ 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)
++	dev_vdbg(&xr_usb_serial->data->dev, "%s - count %zd\n", __func__, count);
++#else
+ 	dev_vdbg(&xr_usb_serial->data->dev, "%s - count %d\n", __func__, count);
++#endif
+ 
+ 	spin_lock_irqsave(&xr_usb_serial->write_lock, flags);
+ 	wbn = xr_usb_serial_wb_alloc(xr_usb_serial);
+@@ -672,7 +681,11 @@ static int xr_usb_serial_tty_write(struc
+ 	}
+ 
+ 	count = (count > xr_usb_serial->writesize) ? xr_usb_serial->writesize : count;
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 2, 0)
++	dev_vdbg(&xr_usb_serial->data->dev, "%s - write %zd\n", __func__, count);
++#else
+ 	dev_vdbg(&xr_usb_serial->data->dev, "%s - write %d\n", __func__, count);
++#endif
+ 	memcpy(wb->buf, buf, count);
+ 	wb->len = count;
+ 
diff --git a/external/subpack/libs/yajl/Makefile b/external/subpack/libs/yajl/Makefile
new file mode 100644
index 0000000..800ce3d
--- /dev/null
+++ b/external/subpack/libs/yajl/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2014, 2015 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:=yajl
+PKG_VERSION:=2.1.0
+PKG_RELEASE:=3
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/lloyd/yajl
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_MIRROR_HASH:=cd8a319a51947100a22173b20f26e5db0db764eb122c81cde87afa30ddbd1fb8
+
+PKG_MAINTAINER:=Charles Southerland <charlie@stuphlabs.com>
+PKG_LICENSE:=ISC
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:yajl_project:yajl
+
+CMAKE_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/yajl
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Yet Another JSON Library
+  URL:=https://lloyd.github.io/yajl
+endef
+
+define Package/yajl/description
+  Yet Another JSON Library. YAJL is a small event-driven (SAX-style)
+JSON parser written in ANSI C, and a small validating JSON generator.
+YAJL is released under the ISC license.
+
+  YAJL was created by Lloyd Hilaiel.
+endef
+
+define Package/yajl/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libyajl.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,yajl))
diff --git a/external/subpack/libs/yajl/patches/010-CVE-2023-33460.patch b/external/subpack/libs/yajl/patches/010-CVE-2023-33460.patch
new file mode 100644
index 0000000..4edc1d3
--- /dev/null
+++ b/external/subpack/libs/yajl/patches/010-CVE-2023-33460.patch
@@ -0,0 +1,41 @@
+From 31531a6e6b5641398237ce15b7e62da02d975fc6 Mon Sep 17 00:00:00 2001
+From: Like Ma <likemartinma@gmail.com>
+Date: Sat, 2 Dec 2023 19:55:55 +0800
+Subject: [PATCH] Fix for CVE-2023-33460a
+
+Memory leak in yajl 2.1.0 with use of yajl_tree_parse function
+See https://github.com/lloyd/yajl/issues/250#issuecomment-1628695214
+
+Origin: https://github.com/openEuler-BaseService/yajl/commit/23a122eddaa28165a6c219000adcc31ff9a8a698
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1039984
+Bug: https://github.com/lloyd/yajl/issues/250
+---
+ src/yajl_tree.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/src/yajl_tree.c
++++ b/src/yajl_tree.c
+@@ -143,7 +143,7 @@ static yajl_val context_pop(context_t *c
+     ctx->stack = stack->next;
+ 
+     v = stack->value;
+-
++    free (stack->key);
+     free (stack);
+ 
+     return (v);
+@@ -444,7 +444,14 @@ yajl_val yajl_tree_parse (const char *in
+              snprintf(error_buffer, error_buffer_size, "%s", internal_err_str);
+              YA_FREE(&(handle->alloc), internal_err_str);
+         }
++        while(ctx.stack != NULL) {
++             yajl_val v = context_pop(&ctx);
++             yajl_tree_free(v);
++        }
+         yajl_free (handle);
++        //If the requested memory is not released in time, it will cause memory leakage
++        if(ctx.root)
++            yajl_tree_free(ctx.root);
+         return NULL;
+     }
+ 
diff --git a/external/subpack/libs/yaml/Makefile b/external/subpack/libs/yaml/Makefile
new file mode 100644
index 0000000..bc1da75
--- /dev/null
+++ b/external/subpack/libs/yaml/Makefile
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2008-2015 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:=yaml
+PKG_VERSION:=0.2.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://pyyaml.org/download/libyaml/
+PKG_HASH:=c642ae9b75fee120b2d96c712538bd2cf283228d2337df2cf2988e3c02678ef4
+
+PKG_MAINTAINER:=
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:pyyaml_project:pyyaml
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+define Package/libyaml
+  SUBMENU:=Languages
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Fast YAML 1.1 parser and emitter library
+  URL:=https://pyyaml.org/wiki/LibYAML
+endef
+
+TARGET_CFLAGS += $(FPIC)
+
+HOST_CONFIGURE_ARGS += --disable-shared
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/yaml.h $(1)/usr/include/
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libyaml*.{a,so*} $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/yaml*.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libyaml/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libyaml*.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,libyaml))
+$(eval $(call HostBuild))
diff --git a/external/subpack/libs/yubico-pam/Makefile b/external/subpack/libs/yubico-pam/Makefile
new file mode 100644
index 0000000..165c92f
--- /dev/null
+++ b/external/subpack/libs/yubico-pam/Makefile
@@ -0,0 +1,44 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=yubico-pam
+PKG_VERSION:=2.27
+PKG_RELEASE:=1
+
+PKG_SOURCE:=pam_yubico-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://developers.yubico.com/yubico-pam/Releases
+PKG_HASH:=63d02788852644d871746e1a7a1d16c272c583c226f62576f5ad232a6a44e18c
+PKG_BUILD_DIR:=$(BUILD_DIR)/pam_yubico-$(PKG_VERSION)
+
+PKG_MAINTAINER:=Stuart B. Wilkins <stuwilkins@mac.com>
+PKG_LICENSE_FILES:=COPYING
+PKG_LICENSE:=BSD-2-Clause
+
+PKG_INSTALL:=1
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/yubico-pam
+	SECTION:=libs
+	CATEGORY:=Libraries
+	TITLE:=The Yubico PAM module
+	URL:=https://developers.yubico.com/yubico-pam/
+	DEPENDS:=+ykclient +ykpers +libyubikey +libpam +curl
+endef
+
+define Package/yubico-pam/description
+	The Yubico PAM module provides an easy way to integrate the YubiKey
+	into your existing user authentication infrastructure.
+endef
+
+CONFIGURE_ARGS += \
+	--enable-shared \
+	--disable-static \
+	--without-ldap
+
+define Package/yubico-pam/install
+	$(INSTALL_DIR) $(1)/usr/lib/security
+	$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/security/pam_yubico.so $(1)/usr/lib/security
+endef
+
+$(eval $(call BuildPackage,yubico-pam))
diff --git a/external/subpack/libs/zlog/Makefile b/external/subpack/libs/zlog/Makefile
new file mode 100644
index 0000000..cfca1fc
--- /dev/null
+++ b/external/subpack/libs/zlog/Makefile
@@ -0,0 +1,42 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=zlog
+PKG_VERSION:=1.2.17
+PKG_RELEASE:=2
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=https://github.com/HardySimpson/zlog
+PKG_SOURCE_VERSION:=$(PKG_VERSION)
+PKG_MIRROR_HASH:=501d89c6883de14e8e6c53e1597f425814b3b467b31da04c50390d4924efecf3
+
+PKG_MAINTAINER:=Marko Ratkaj <markoratkaj@gmail.com>
+PKG_LICENSE:=Apache-2.0
+PKG_LICENSE_FILES:=COPYING
+PKG_CPE_ID:=cpe:/a:zlog_project:zlog
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/zlog
+  SECTION:=libs
+  CATEGORY:=Libraries
+  TITLE:=Pure C logging library
+  URL:=http://hardysimpson.github.io/zlog/
+endef
+
+define Package/zlog/description
+  zlog is a reliable, high-performance, thread safe, flexible, clear-model, pure C logging library.
+endef
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include/ $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libzlog.* $(1)/usr/lib/
+endef
+
+define Package/zlog/install
+	$(INSTALL_DIR) $(1)/usr/lib/
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libzlog.so* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,zlog))
diff --git a/external/subpack/libs/zlog/patches/010-cmake.patch b/external/subpack/libs/zlog/patches/010-cmake.patch
new file mode 100644
index 0000000..736185a
--- /dev/null
+++ b/external/subpack/libs/zlog/patches/010-cmake.patch
@@ -0,0 +1,10 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -25,7 +25,6 @@ SET(zlog_so_ver ${CPACK_PACKAGE_VERSION_
+ message(STATUS "plateform : ${CMAKE_SYSTEM}")
+ 
+ add_definitions("-g -Wall -Wstrict-prototypes")
+-set(CMAKE_C_FLAGS "-std=c99 -pedantic -D_DEFAULT_SOURCE")
+ set(CMAKE_C_FLAGS_DEBUG "-ggdb3 -DDEBUG")
+ set(CMAKE_C_FLAGS_RELEASE "-O2")
+ 
diff --git a/external/subpack/libs/zmq/Makefile b/external/subpack/libs/zmq/Makefile
new file mode 100644
index 0000000..c9dccd0
--- /dev/null
+++ b/external/subpack/libs/zmq/Makefile
@@ -0,0 +1,126 @@
+#
+# Copyright (C) 2016 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# This Makefile for ZeroMQ
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=zeromq
+PKG_VERSION:=4.3.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/zeromq/libzmq/releases/download/v$(PKG_VERSION)
+PKG_HASH:=6653ef5910f17954861fe72332e68b03ca6e4d9c7160eb3a8de5a5a913bfab43
+
+PKG_MAINTAINER:=Dirk Chang <dirk@kooiot.com>
+PKG_LICENSE:=GPL-3.0-or-later
+PKG_LICENSE_FILES:=LICENCE.txt
+PKG_CPE_ID:=cpe:/a:zeromq:libzmq
+
+CMAKE_BINARY_SUBDIR:=openwrt-build
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libzmq/default
+  TITLE:=ZeroMQ - Message Queue engine
+  URL:=http://www.zeromq.org/
+  SECTION:=libs
+  CATEGORY:=Libraries
+  DEPENDS:=+libuuid +libstdcpp
+  PROVIDES:=libzmq
+endef
+
+define Package/libzmq/default-config
+config LIBZMQ_$(2)_WITH_OPENPGM
+	depends on PACKAGE_libzmq-$(1)
+	bool "enable openpgm support for libzmq-$(1)"
+	default n
+endef
+
+define Package/libzmq-nc
+  $(call Package/libzmq/default)
+  VARIANT:=nc
+  DEPENDS+=+LIBZMQ_NC_WITH_OPENPGM:openpgm
+endef
+
+define Package/libzmq-curve
+  $(call Package/libzmq/default)
+  VARIANT:=curve
+  TITLE+= (CurveZMQ)
+  DEPENDS+=+libsodium +LIBZMQ_CURVE_WITH_OPENPGM:openpgm
+endef
+
+define Package/libzmq-nc/description
+ This package contains the ZeroMQ messaging engine shared library.
+endef
+
+define Package/libzmq-curve/description
+ $(call Package/libzmq-nc/description)
+ Includes CurveZMQ security by libsodium.
+endef
+
+define Package/libzmq-nc/config
+	$(call Package/libzmq/default-config,nc,NC)
+endef
+
+define Package/libzmq-curve/config
+	$(call Package/libzmq/default-config,curve,CURVE)
+endef
+
+CMAKE_OPTIONS += \
+	-DA2X_EXECUTABLE=OFF \
+	-DASCIIDOC_EXECUTABLE=OFF \
+	-DBUILD_STATIC=OFF \
+	-DZMQ_HAVE_SOCK_CLOEXEC=ON \
+	-DZMQ_HAVE_SO_KEEPALIVE=ON \
+	-DZMQ_HAVE_TCP_KEEPCNT=ON \
+	-DZMQ_HAVE_TCP_KEEPIDLE=ON \
+	-DZMQ_HAVE_TCP_KEEPINTVL=ON \
+	-DZMQ_HAVE_TCP_KEEPALIVE=ON \
+	-DENABLE_CURVE=ON \
+	-DENABLE_EVENTFD=ON \
+	-DPOLLER=epoll \
+	-DRT_LIBRARY=OFF \
+	-DZMQ_BUILD_TESTS=OFF
+
+ifeq ($(BUILD_VARIANT),curve)
+	CMAKE_OPTIONS += -DWITH_LIBSODIUM=ON
+else
+  	CMAKE_OPTIONS += -DWITH_LIBSODIUM=OFF
+endif
+
+ifeq ($(CONFIG_LIBZMQ_NC_WITH_OPENPGM),y)
+	CMAKE_OPTIONS += -DWITH_OPENPGM=ON
+else ifeq ($(CONFIG_LIBZMQ_CURVE_WITH_OPENPGM),y)
+	CMAKE_OPTIONS += -DWITH_OPENPGM=ON
+else
+	CMAKE_OPTIONS += -DWITH_OPENPGM=OFF
+endif
+
+define Build/InstallDev
+	$(INSTALL_DIR) $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/zmq.h $(1)/usr/include
+	$(CP) $(PKG_INSTALL_DIR)/usr/include/zmq_utils.h $(1)/usr/include
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libzmq.so* $(1)/usr/lib/
+	$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libzmq.pc $(1)/usr/lib/pkgconfig/
+	$(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libzmq.pc
+	$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libzmq.pc
+endef
+
+define Package/libzmq-nc/install
+	$(INSTALL_DIR) $(1)/usr/lib
+	$(CP) $(PKG_INSTALL_DIR)/usr/lib/libzmq.so.* $(1)/usr/lib/
+endef
+
+Package/libzmq-curve/install=$(Package/libzmq-nc/install)
+
+$(eval $(call BuildPackage,libzmq-nc))
+$(eval $(call BuildPackage,libzmq-curve))
diff --git a/external/subpack/libs/zmq/patches/010-fix-openpgm-linking-for-zeromq.patch b/external/subpack/libs/zmq/patches/010-fix-openpgm-linking-for-zeromq.patch
new file mode 100644
index 0000000..2fc711b
--- /dev/null
+++ b/external/subpack/libs/zmq/patches/010-fix-openpgm-linking-for-zeromq.patch
@@ -0,0 +1,40 @@
+From 68546793d3ead9fef78f4b6670b4bee92ae99bc8 Mon Sep 17 00:00:00 2001
+From: Ye Holmes <yeholmes@outlook.com>
+Date: Wed, 17 Feb 2021 19:26:52 +0800
+Subject: [PATCH] fix-openpgm-linking-for-zeromq
+
+---
+ CMakeLists.txt | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -809,7 +809,7 @@ else()
+     # message(FATAL_ERROR "WITH_OPENPGM not implemented")
+ 
+     if(NOT OPENPGM_PKGCONFIG_NAME)
+-      set(OPENPGM_PKGCONFIG_NAME "openpgm-5.2")
++      set(OPENPGM_PKGCONFIG_NAME "openpgm-5.3")
+     endif()
+ 
+     set(OPENPGM_PKGCONFIG_NAME
+@@ -820,6 +820,8 @@ else()
+ 
+     if(OPENPGM_FOUND)
+       message(STATUS ${OPENPGM_PKGCONFIG_NAME}" found")
++      find_library(OPENPGM_LIBRARIES NAMES libpgm pgm)
++      set(pkg_config_libs_private "${pkg_config_libs_private} -lpgm")
+       set(pkg_config_names_private "${pkg_config_names_private} ${OPENPGM_PKGCONFIG_NAME}")
+     else()
+       message(
+@@ -1494,6 +1496,10 @@ if(BUILD_SHARED)
+     endif()
+   endif()
+ 
++  if(OPENPGM_FOUND)
++   target_link_libraries(libzmq ${OPENPGM_LIBRARIES})
++  endif()
++
+   if(HAVE_WS2_32)
+     target_link_libraries(libzmq ws2_32)
+   elseif(HAVE_WS2)
diff --git a/external/subpack/libs/zmq/patches/020-no-libbsd.patch b/external/subpack/libs/zmq/patches/020-no-libbsd.patch
new file mode 100644
index 0000000..641b69b
--- /dev/null
+++ b/external/subpack/libs/zmq/patches/020-no-libbsd.patch
@@ -0,0 +1,121 @@
+From 872a773fac1e2880428d82e9f589ff16a5fde727 Mon Sep 17 00:00:00 2001
+From: Guilherme Janczak <guilherme.janczak@yandex.com>
+Date: Fri, 6 May 2022 18:42:52 +0000
+Subject: [PATCH] remove libbsd
+
+libbsd is only used once and as part of a larger, incorrect function.
+I rewrote the code that used it without the need for it.
+---
+ CMakeLists.txt               | 41 ++++++-----------------------
+ builds/cmake/platform.hpp.in |  2 --
+ src/compat.hpp               | 51 +++++++++++++++++++++++-------------
+ 8 files changed, 50 insertions(+), 101 deletions(-)
+
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1484,10 +1484,6 @@ if(BUILD_SHARED)
+     target_link_libraries(libzmq ${NSS3_LIBRARIES})
+   endif()
+ 
+-  if(LIBBSD_FOUND)
+-    target_link_libraries(libzmq ${LIBBSD_LIBRARIES})
+-  endif()
+-
+   if(SODIUM_FOUND)
+     target_link_libraries(libzmq ${SODIUM_LIBRARIES})
+     # On Solaris, libsodium depends on libssp
+@@ -1534,10 +1530,6 @@ if(BUILD_STATIC)
+     target_include_directories(libzmq-static PRIVATE "${GNUTLS_INCLUDE_DIR}")
+   endif()
+ 
+-  if(LIBBSD_FOUND)
+-    target_link_libraries(libzmq-static ${LIBBSD_LIBRARIES})
+-  endif()
+-
+   if(NSS3_FOUND)
+     target_link_libraries(libzmq-static ${NSS3_LIBRARIES})
+   endif()
+@@ -1607,10 +1599,6 @@ if(BUILD_SHARED)
+         target_include_directories(${perf-tool} PRIVATE "${GNUTLS_INCLUDE_DIR}")
+       endif()
+ 
+-      if(LIBBSD_FOUND)
+-        target_link_libraries(${perf-tool} ${LIBBSD_LIBRARIES})
+-      endif()
+-
+       if(NSS3_FOUND)
+         target_link_libraries(${perf-tool} ${NSS3_LIBRARIES})
+       endif()
+--- a/builds/cmake/platform.hpp.in
++++ b/builds/cmake/platform.hpp.in
+@@ -56,8 +56,6 @@
+ #cmakedefine ZMQ_HAVE_PTHREAD_SET_AFFINITY
+ #cmakedefine HAVE_ACCEPT4
+ #cmakedefine HAVE_STRNLEN
+-#cmakedefine ZMQ_HAVE_STRLCPY
+-#cmakedefine ZMQ_HAVE_LIBBSD
+ 
+ #cmakedefine ZMQ_HAVE_IPC
+ #cmakedefine ZMQ_HAVE_STRUCT_SOCKADDR_UN
+--- a/src/compat.hpp
++++ b/src/compat.hpp
+@@ -10,26 +10,41 @@
+ #define strcasecmp _stricmp
+ #define strtok_r strtok_s
+ #else
+-#ifndef ZMQ_HAVE_STRLCPY
+-#ifdef ZMQ_HAVE_LIBBSD
+-#include <bsd/string.h>
+-#else
+-static inline size_t
+-strlcpy (char *dest_, const char *src_, const size_t dest_size_)
+-{
+-    size_t remain = dest_size_;
+-    for (; remain && *src_; --remain, ++src_, ++dest_) {
+-        *dest_ = *src_;
+-    }
+-    return dest_size_ - remain;
+-}
+-#endif
+-#endif
++/*
++ * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcpy-s-wcscpy-s-mbscpy-s?view=msvc-170
++ */
+ template <size_t size>
+-static inline int strcpy_s (char (&dest_)[size], const char *const src_)
++static inline int strcpy_s (char (&dst)[size], const char *const src)
+ {
+-    const size_t res = strlcpy (dest_, src_, size);
+-    return res >= size ? ERANGE : 0;
++    size_t i;
++
++    if (src == NULL) {
++        /*
++         * XXX:
++         * Microsoft's documentation is ambiguous.
++         *
++         * How does Microsoft handle size == 0 when src is NULL?
++         * Do they return ERANGE?
++         *
++         * How does Microsoft handle size == 0 when src is non-NULL?
++         * Do they write a '\0' to *dst anyway?
++         */
++        if (size > 0)
++            *dst = '\0';
++        return (errno = EINVAL);
++    }
++
++    for (i = 0;; i++) {
++        if (i >= size) {
++            if (size > 0)
++                *dst = '\0';
++            return (errno = ERANGE);
++        }
++        dst[i] = src[i];
++        if (src[i] == '\0')
++            return 0;
++    }
++    /* NOTREACHED */
+ }
+ #endif
+