]> Liquid.me.uk: Repositories - local-repo/.git/commitdiff
modified: net-p2p/monero/Manifest master origin/HEAD origin/master
authorRalphred <ralphred@liquid.me.uk>
Wed, 2 Apr 2025 17:34:42 +0000 (18:34 +0100)
committerRalphred <ralphred@liquid.me.uk>
Wed, 2 Apr 2025 17:34:42 +0000 (18:34 +0100)
203 files changed:
acct-group/monero/Manifest [new file with mode: 0644]
acct-group/monero/metadata.xml [new file with mode: 0644]
acct-group/monero/monero-0.ebuild [new file with mode: 0644]
acct-user/monero/Manifest [new file with mode: 0644]
acct-user/monero/metadata.xml [new file with mode: 0644]
acct-user/monero/monero-0.ebuild [new file with mode: 0644]
app-admin/webmin/Manifest [new file with mode: 0644]
app-admin/webmin/files/gentoo-setup [new file with mode: 0644]
app-admin/webmin/files/gentoo-setup-1.974 [new file with mode: 0644]
app-admin/webmin/files/gentoo-setup-2.202 [new file with mode: 0644]
app-admin/webmin/files/init.d.webmin [new file with mode: 0644]
app-admin/webmin/files/webmin.service [new file with mode: 0644]
app-admin/webmin/webmin-1.881.ebuild [new file with mode: 0644]
app-admin/webmin/webmin-1.974.ebuild [new file with mode: 0644]
app-admin/webmin/webmin-1.974.ebuild.old [new file with mode: 0644]
app-admin/webmin/webmin-2.105.ebuild [new file with mode: 0644]
app-admin/webmin/webmin-2.202.ebuild [new file with mode: 0644]
app-mobilephone/scrcpy/Manifest [new file with mode: 0644]
app-mobilephone/scrcpy/scrcpy-1.12.1.ebuild [new file with mode: 0644]
app-office/libreoffice-l10n/Manifest [new file with mode: 0644]
app-office/libreoffice-l10n/files/lo_gen_langs.sh [new file with mode: 0644]
app-office/libreoffice-l10n/libreoffice-l10n-7.0.6.2.ebuild [new file with mode: 0644]
app-office/libreoffice-l10n/libreoffice-l10n-7.1.3.2.ebuild [new file with mode: 0644]
app-office/libreoffice-l10n/libreoffice-l10n-7.1.4.2.ebuild [new file with mode: 0644]
app-office/libreoffice-l10n/metadata.xml [new file with mode: 0644]
dev-libs/boost/Manifest [new file with mode: 0644]
dev-libs/boost/files/boost-1.71.0-build-auto_index-tool.patch [new file with mode: 0644]
dev-libs/boost/files/boost-1.71.0-context-x32.patch [new file with mode: 0644]
dev-libs/boost/files/boost-1.71.0-disable_icu_rpath.patch [new file with mode: 0644]
dev-libs/boost/files/boost-1.73-boost-mpi-python-PEP-328.patch [new file with mode: 0644]
dev-libs/boost/files/boost-1.73-property-tree-include.patch [new file with mode: 0644]
dev-libs/boost/files/boost-1.74-CVE-2012-2677.patch [new file with mode: 0644]
dev-libs/boost/files/boost-1.76-boost-numpy.patch [new file with mode: 0644]
dev-libs/boost/files/boost-1.76-sparc-define.patch [new file with mode: 0644]
dev-libs/supercop/Manifest [new file with mode: 0644]
dev-libs/supercop/supercop-0_p20200827.ebuild [new file with mode: 0644]
dev-perl/Data-Entropy/Data-Entropy-0.007.0.ebuild [new file with mode: 0644]
dev-perl/Data-Entropy/Manifest [new file with mode: 0644]
dev-perl/HTTP-Lite/HTTP-Lite-2.44.ebuild [new file with mode: 0644]
dev-perl/HTTP-Lite/Manifest [new file with mode: 0644]
eclass/palemoon-5.eclass [new file with mode: 0644]
eclass/palemoon-bin-0.eclass [new file with mode: 0644]
games-util/mangohud/Manifest [new file with mode: 0644]
games-util/mangohud/mangohud-0.7.2.ebuild [new file with mode: 0644]
games-util/oversteer/Manifest [new file with mode: 0644]
games-util/oversteer/oversteer-0.5.2.ebuild [new file with mode: 0644]
games-util/oversteer/oversteer-0.8.0.ebuild [new file with mode: 0644]
games-util/simulationcraft/Manifest [new file with mode: 0644]
games-util/simulationcraft/simulationcraft-9999.ebuild [new file with mode: 0644]
kde-apps/kdeutils-meta/Manifest [new file with mode: 0644]
kde-apps/kdeutils-meta/kdeutils-meta-22.04.3.ebuild [new file with mode: 0644]
kde-apps/konsole/Manifest [new file with mode: 0644]
kde-apps/konsole/files/konsole-24.05.2-cmake.patch [new file with mode: 0644]
kde-apps/konsole/konsole-24.05.2-r2.ebuild [new file with mode: 0644]
kde-frameworks/oxygen-icons/Manifest [new file with mode: 0644]
kde-frameworks/oxygen-icons/metadata.xml [new file with mode: 0644]
kde-frameworks/oxygen-icons/oxygen-icons-5.116.0.ebuild [new file with mode: 0644]
kde-plasma/plasma-meta/Manifest [new file with mode: 0644]
kde-plasma/plasma-meta/plasma-meta-5.24.6-r1.ebuild [new file with mode: 0644]
kde-plasma/powerdevil/Manifest [new file with mode: 0644]
kde-plasma/powerdevil/powerdevil-5.24.6.ebuild [new file with mode: 0644]
layout.conf [new file with mode: 0644]
lxde-base/lxsession-0.5.5-dir.tar.gz [new file with mode: 0644]
lxde-base/lxsession.dir.tar.gz [new file with mode: 0644]
lxde-base/lxsession/Manifest [new file with mode: 0644]
lxde-base/lxsession/files/lxsession-0.5.5-no-polkit-pt2.patch [new file with mode: 0644]
lxde-base/lxsession/files/lxsession-0.5.5-no-polkit.patch [new file with mode: 0644]
lxde-base/lxsession/files/lxsession-0.5.5-notify-daemon-default.patch [new file with mode: 0644]
lxde-base/lxsession/files/lxsession-0.5.5-reload.patch [new file with mode: 0644]
lxde-base/lxsession/lxsession-0.5.5-r1.ebuild [new file with mode: 0644]
mail-filter/libmilter/Manifest [new file with mode: 0644]
mail-filter/libmilter/libmilter-1.0.2_p1-r1.ebuild [new file with mode: 0644]
mail-mta/sendmail/Manifest [new file with mode: 0644]
mail-mta/sendmail/sendmail-8.16.1.ebuild [new file with mode: 0644]
media-libs/libsdl2/Manifest [new file with mode: 0644]
media-libs/libsdl2/files/libsdl2-2.0.14-static-libs.patch [new file with mode: 0644]
media-libs/libsdl2/libsdl2-2.0.14-r1.ebuild [new file with mode: 0644]
media-plugins/eq10q/Manifest [new file with mode: 0644]
media-plugins/eq10q/eq10q-2.2_p1.ebuild [new file with mode: 0644]
media-plugins/eq10q/files/eq10q-2.2_p1.patch [new file with mode: 0644]
media-sound/audacity/Manifest [new file with mode: 0644]
media-sound/audacity/audacity-3.0.2-r1.ebuild [new file with mode: 0644]
media-sound/audacity/audacity-3.0.2.ebuild [new file with mode: 0644]
media-sound/audacity/files/audacity-3.0.2-disable-ccache.patch [new file with mode: 0644]
media-sound/audacity/files/audacity-3.0.2-fix-gettimeofday.patch [new file with mode: 0644]
media-sound/audacity/files/audacity-3.0.2-fix-jack_support.patch [new file with mode: 0644]
media-sound/audacity/files/audacity-3.0.2-fix-metainfo.patch [new file with mode: 0644]
media-sound/audacity/files/audacity-3.0.2-gentoo-wx-build.patch [new file with mode: 0644]
media-sound/audacity/metadata.xml [new file with mode: 0644]
media-sound/jack2/Manifest [new file with mode: 0644]
media-sound/jack2/jack2-1.9.18.ebuild [new file with mode: 0644]
media-video/pipewire/Manifest [new file with mode: 0644]
media-video/pipewire/files/pipewire-0.3.25-enable-failed-mlock-warning.patch [new file with mode: 0644]
media-video/pipewire/files/pipewire-0.3.25-fix-docdir-path.patch [new file with mode: 0644]
media-video/pipewire/files/pipewire-0.3.25-non-systemd-integration.patch [new file with mode: 0644]
media-video/pipewire/files/pipewire-0.3.28-revert-openaptx-restriction.patch [new file with mode: 0644]
media-video/pipewire/files/pipewire-0.3.29-revert-openaptx-restriction.patch [new file with mode: 0644]
media-video/pipewire/files/pipewire-launcher.sh [new file with mode: 0644]
media-video/pipewire/files/pipewire.desktop [new file with mode: 0644]
media-video/pipewire/pipewire-0.3.22.ebuild-borked [new file with mode: 0644]
metadata/layout.conf [new file with mode: 0644]
metadata/md5-cache/media-sound/audacity-3.0.2 [new file with mode: 0644]
net-im/discord-bin/Manifest [new file with mode: 0644]
net-im/discord-bin/discord-bin-0.0.19.ebuild [new file with mode: 0644]
net-im/discord-bin/discord-bin-0.0.22.ebuild [new file with mode: 0644]
net-im/discord-bin/discord-bin-0.0.23.ebuild [new file with mode: 0644]
net-im/discord-bin/discord-bin-0.0.24.ebuild [new file with mode: 0644]
net-im/discord-bin/metadata.xml [new file with mode: 0644]
net-im/discord/Manifest [new file with mode: 0644]
net-im/discord/discord-0.0.25.ebuild [new file with mode: 0644]
net-im/discord/discord-0.0.46.ebuild [new file with mode: 0644]
net-im/discord/discord-0.0.64.ebuild [new file with mode: 0644]
net-im/discord/discord-0.0.65.ebuild [new file with mode: 0644]
net-im/discord/discord-0.0.66.ebuild [new file with mode: 0644]
net-im/discord/discord-0.0.69.ebuild [new file with mode: 0644]
net-im/discord/discord-0.0.70.ebuild [new file with mode: 0644]
net-im/discord/discord-0.0.71.ebuild [new file with mode: 0644]
net-im/discord/discord-0.0.72.ebuild [new file with mode: 0644]
net-im/discord/files/launcher.sh [new file with mode: 0644]
net-misc/xmrig/Manifest [new file with mode: 0644]
net-misc/xmrig/files/logrotated [new file with mode: 0644]
net-misc/xmrig/files/xmrig-6.12.2-nonotls.patch [new file with mode: 0644]
net-misc/xmrig/files/xmrig.initd [new file with mode: 0755]
net-misc/xmrig/files/xmrig.service [new file with mode: 0644]
net-misc/xmrig/files/xmrigd.1.initd [new file with mode: 0755]
net-misc/xmrig/files/xmrigd.confd [new file with mode: 0644]
net-misc/xmrig/xmrig-6.21.1.ebuild [new file with mode: 0644]
net-misc/xmrig/xmrig-6.22.2-r1.ebuild [new file with mode: 0644]
net-misc/xmrig/xmrig-6.22.2.ebuild [new file with mode: 0644]
net-misc/xmrig/xmrig-6.22.2.ebuild.save [new file with mode: 0644]
net-p2p/monero/Manifest [new file with mode: 0644]
net-p2p/monero/files/logrotated [new file with mode: 0644]
net-p2p/monero/files/monero-0.17.3.2-unbundle-dependencies.patch [new file with mode: 0644]
net-p2p/monero/files/monero-0.18.3.3-miniupnp-api-18.patch [new file with mode: 0644]
net-p2p/monero/files/monero-0.18.3.3-unbundle-dependencies.patch [new file with mode: 0644]
net-p2p/monero/files/monero-0.18.3.4-boost-1.85.patch [new file with mode: 0644]
net-p2p/monero/files/monero-0.18.4.0-unbundle-dependencies.patch [new file with mode: 0644]
net-p2p/monero/files/monerod.conf [new file with mode: 0644]
net-p2p/monero/files/monerod.confd [new file with mode: 0644]
net-p2p/monero/files/monerod.initd [new file with mode: 0644]
net-p2p/monero/files/monerod.service [new file with mode: 0644]
net-p2p/monero/metadata.xml [new file with mode: 0644]
net-p2p/monero/monero-0.18.3.4-r1.ebuild [new file with mode: 0644]
net-p2p/monero/monero-0.18.3.4-r2.ebuild [new file with mode: 0644]
net-p2p/monero/monero-0.18.4.0-r1.ebuild [new file with mode: 0644]
net-p2p/p2pool/Manifest [new file with mode: 0644]
net-p2p/p2pool/files/SChernykh.asc [new file with mode: 0644]
net-p2p/p2pool/files/flags.cmake [new file with mode: 0644]
net-p2p/p2pool/files/logrotated [new file with mode: 0644]
net-p2p/p2pool/files/p2pool.confd [new file with mode: 0644]
net-p2p/p2pool/files/p2pool.initd [new file with mode: 0755]
net-p2p/p2pool/metadata.xml [new file with mode: 0644]
net-p2p/p2pool/p2pool-4.3-r1.ebuild [new file with mode: 0644]
net-p2p/p2pool/p2pool-4.3.ebuild [new file with mode: 0644]
net-p2p/p2pool/p2pool-4.4.ebuild [new file with mode: 0644]
profiles/categories [new file with mode: 0644]
profiles/repo_name [new file with mode: 0644]
sci-libs/miopen/Manifest [new file with mode: 0644]
sci-libs/miopen/files/miopen-4.2.0-disable-no-inline-boost.patch [new file with mode: 0644]
sci-libs/miopen/files/miopen-4.2.0-gcc11-numeric_limits.patch [new file with mode: 0644]
sci-libs/miopen/files/miopen-4.3.0-enable-test.patch [new file with mode: 0644]
sci-libs/miopen/files/miopen-4.3.0-fix-interface-include-in-HIP_COMPILER_FLAGS.patch [new file with mode: 0644]
sci-libs/miopen/files/miopen-5.0.2-strip-xnack-in-flags.patch [new file with mode: 0644]
sci-libs/miopen/files/miopen-5.1.3-avoid-metadata-error-for-vanilla-clang.patch [new file with mode: 0644]
sci-libs/miopen/files/miopen-5.1.3-deprecate-clang-ocl.patch [new file with mode: 0644]
sci-libs/miopen/files/miopen-5.1.3-gfx1031.patch [new file with mode: 0644]
sci-libs/miopen/files/miopen-5.1.3-include-array.patch [new file with mode: 0644]
sci-libs/miopen/files/miopen-5.1.3-no-strip.patch [new file with mode: 0644]
sci-libs/miopen/miopen-5.7.1.ebuild [new file with mode: 0644]
sys-apps/accountsservice/Manifest [new file with mode: 0644]
sys-apps/accountsservice/accountsservice-22.08.8.ebuild [new file with mode: 0644]
sys-apps/accountsservice/files/accountsservice-22.04.62-gentoo-system-users.patch [new file with mode: 0644]
sys-fs/eudev/Manifest [new file with mode: 0644]
sys-fs/eudev/eudev-3.2.11-r4.ebuild [new file with mode: 0644]
sys-fs/eudev/files/40-gentoo.rules [new file with mode: 0644]
sys-fs/eudev/files/udev-postmount [new file with mode: 0644]
sys-kernel/gentooAI-sources/Manifest [new file with mode: 0644]
sys-kernel/gentooAI-sources/files/patch.6.13.3 [new file with mode: 0644]
sys-kernel/gentooAI-sources/gentooAI-sources-6.13.3-r1.ebuild [new file with mode: 0644]
sys-kernel/gentooAI-sources/gentooAI-sources-6.13.5.ebuild [new file with mode: 0644]
sys-kernel/raspberrypi-sources/Manifest [new file with mode: 0644]
sys-kernel/raspberrypi-sources/files/raspberrypi-sources-5.15.32-gentoo-kconfig.patch [new file with mode: 0644]
sys-kernel/raspberrypi-sources/files/raspberrypi-sources-6.1.21-gentoo-kconfig.patch [new file with mode: 0644]
sys-kernel/raspberrypi-sources/files/raspberrypi-sources-AI.patch [new file with mode: 0644]
sys-kernel/raspberrypi-sources/raspberrypi-sources-6.6.74_p20250127.ebuild [new file with mode: 0644]
www-client/vivaldi/Manifest [new file with mode: 0644]
www-client/vivaldi/vivaldi-5.2.2623.48.ebuild [new file with mode: 0644]
www-client/vivaldi/vivaldi-5.3.2679.68.ebuild [new file with mode: 0644]
www-misc/zoneminder/Manifest [new file with mode: 0644]
www-misc/zoneminder/files/10_zoneminder.conf [new file with mode: 0644]
www-misc/zoneminder/files/README.gentoo [new file with mode: 0644]
www-misc/zoneminder/files/conf.d [new file with mode: 0644]
www-misc/zoneminder/files/init.d [new file with mode: 0644]
www-misc/zoneminder/files/zoneminder.service [new file with mode: 0644]
www-misc/zoneminder/metadata.xml [new file with mode: 0644]
www-misc/zoneminder/zoneminder-1.36.20.ebuild [new file with mode: 0644]
www-misc/zoneminder/zoneminder-1.36.21.ebuild [new file with mode: 0644]
x11-misc/appmenu-gtk-module/Manifest [new file with mode: 0644]
x11-misc/appmenu-gtk-module/appmenu-gtk-module-0.7.3-r2.ebuild [new file with mode: 0644]
x11-misc/appmenu-gtk-module/files/appmenu-gtk-module [new file with mode: 0644]
x11-misc/appmenu-gtk-module/files/appmenu-gtk-module-0.7.6-fix-pkgconfig.patch [new file with mode: 0644]
x11-misc/appmenu-gtk-module/files/appmenu-gtk-module-0.7.6-no-automagic-gtk.patch [new file with mode: 0644]
x11-misc/appmenu-gtk-module/files/appmenu-gtk-module-0.7.6-no-automagic-unitdir.patch [new file with mode: 0644]

diff --git a/acct-group/monero/Manifest b/acct-group/monero/Manifest
new file mode 100644 (file)
index 0000000..aa1c269
--- /dev/null
@@ -0,0 +1,2 @@
+EBUILD monero-0.ebuild 180 BLAKE2B 4275585a0d24f242a5192cd76b4d2005b28c9ad837ddc3111f97231a497993d4003f6326f0650d5ffed4f0fb093d46b4982e71c4d6a80638a94825c93aeff0e1 SHA512 1882c41e0e4efcf8cfd3f30573eac90e46e503c10ca33beacb2733055b388e0163c44853b3e6d2d8046935632176976c1fe49ab7b247db42411fea225b473bd1
+MISC metadata.xml 250 BLAKE2B 5674fb0bb7a4c1cc86968afb79a07af52df8c0c6330ec1cf677f234ee3f904b83e6730d6ec161207b648fba9ac624a70297a0b8c01cf90f9f3dda471cbbfaf80 SHA512 d5d8c8a67e1564de542b662edab5c020ae361653e10d5961a17f000576a293161c25fa3c9968739c2d773edeb95c2097733aab0dfca2786e19a9a7eb88208fd5
diff --git a/acct-group/monero/metadata.xml b/acct-group/monero/metadata.xml
new file mode 100644 (file)
index 0000000..82808a0
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+  <maintainer type="person">
+    <email>telans@posteo.de</email>
+    <name>James Beddek</name>
+  </maintainer>
+</pkgmetadata>
diff --git a/acct-group/monero/monero-0.ebuild b/acct-group/monero/monero-0.ebuild
new file mode 100644 (file)
index 0000000..a05b241
--- /dev/null
@@ -0,0 +1,10 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-group
+
+KEYWORDS="amd64 ~arm ~arm64 ~x86"
+
+ACCT_GROUP_ID=-1
diff --git a/acct-user/monero/Manifest b/acct-user/monero/Manifest
new file mode 100644 (file)
index 0000000..edb13b1
--- /dev/null
@@ -0,0 +1,2 @@
+EBUILD monero-0.ebuild 226 BLAKE2B 96b612801095b29374d83c3ef70bd26eb62ed971ece49c66f95931da1fe05467c189f73a14968bec8ea8de8429665c91492ea030322469d67ab4b9642cd7be12 SHA512 d5c781632169319c8e890da89ee435a10d6ddf4b3253516c3f2a75ff2ee68259f7d50e3226d4078c039f0a1b30d40154e0f343928d6c4bf0cd4433ec9de1e128
+MISC metadata.xml 250 BLAKE2B 5674fb0bb7a4c1cc86968afb79a07af52df8c0c6330ec1cf677f234ee3f904b83e6730d6ec161207b648fba9ac624a70297a0b8c01cf90f9f3dda471cbbfaf80 SHA512 d5d8c8a67e1564de542b662edab5c020ae361653e10d5961a17f000576a293161c25fa3c9968739c2d773edeb95c2097733aab0dfca2786e19a9a7eb88208fd5
diff --git a/acct-user/monero/metadata.xml b/acct-user/monero/metadata.xml
new file mode 100644 (file)
index 0000000..82808a0
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+  <maintainer type="person">
+    <email>telans@posteo.de</email>
+    <name>James Beddek</name>
+  </maintainer>
+</pkgmetadata>
diff --git a/acct-user/monero/monero-0.ebuild b/acct-user/monero/monero-0.ebuild
new file mode 100644 (file)
index 0000000..bad298b
--- /dev/null
@@ -0,0 +1,13 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit acct-user
+
+KEYWORDS="amd64 ~arm ~arm64 ~x86"
+
+ACCT_USER_ID=-1
+ACCT_USER_GROUPS=( monero )
+
+acct-user_add_deps
diff --git a/app-admin/webmin/Manifest b/app-admin/webmin/Manifest
new file mode 100644 (file)
index 0000000..124e19f
--- /dev/null
@@ -0,0 +1,18 @@
+AUX gentoo-setup 13727 BLAKE2B dca9dadd5775006f5bfbeee870723db8806a2236c984e2b4cec70031101f97fc5d4e1e1fd9219f27cdaa31ee860d247f71a01180b392154c16ca6554b1f73483 SHA512 fa6fde84eb9a16fea5d019fd920aed2a2f5dd51e5f32fa407fd1c424a0627eaafab7cd3b572a57e4f97e06ce5b6b5a7373ac377776a474a8512e077130eadc6e
+AUX gentoo-setup-1.974 13727 BLAKE2B dca9dadd5775006f5bfbeee870723db8806a2236c984e2b4cec70031101f97fc5d4e1e1fd9219f27cdaa31ee860d247f71a01180b392154c16ca6554b1f73483 SHA512 fa6fde84eb9a16fea5d019fd920aed2a2f5dd51e5f32fa407fd1c424a0627eaafab7cd3b572a57e4f97e06ce5b6b5a7373ac377776a474a8512e077130eadc6e
+AUX gentoo-setup-2.202 13727 BLAKE2B dca9dadd5775006f5bfbeee870723db8806a2236c984e2b4cec70031101f97fc5d4e1e1fd9219f27cdaa31ee860d247f71a01180b392154c16ca6554b1f73483 SHA512 fa6fde84eb9a16fea5d019fd920aed2a2f5dd51e5f32fa407fd1c424a0627eaafab7cd3b572a57e4f97e06ce5b6b5a7373ac377776a474a8512e077130eadc6e
+AUX init.d.webmin 2287 BLAKE2B 87deae2864a57dbaad5ce437454a908671b9232d72023a81c8fa291c74a527cffb94c22a10f38abf119d0aba0d1d8012d197b44170e26a2c3af335e5feae8726 SHA512 a6df7e99f21099d306740d032ef0d339864c107aea87cffb7a7180776810c516cdc9892e8409c593066aa6bc9366e752c62094aef0f1b36ca21ede1b9f9fe5a4
+AUX webmin.service 416 BLAKE2B aef00b0f948286c54736613e37f114e6ffd90453cc6eadc3afffe7fa114df4e6a8b91e4f02da6fdfaa3eb2f57254e5e6785b201d0461f28839742cc13d883816 SHA512 7cf86342db3d34cbe39b62fa768660ba7dd160d9c0d113ef6a3a176187fa0c72531bed38e3203cf627ab05c1ac4d9a8b9e829d1baa9739d63dfa74f09c445f1e
+DIST webmin-1.881-minimal.tar.gz 2827351 BLAKE2B b8ea9964147c09c91413fbdad3b6a0e5161497296bb33b614161e370ac1292ac9cdf752483835fb279aa70ba41eb09f2774d08caa58861049e467346ad0b64ff SHA512 5b855c5562a6eb6a8fd836e3bd1dcc30696b7f63776d0f8b5ee69f5e219c749210436315fe5fd8f811f4f19e02fe4d7d3cff451a831b085101081b97b8ce794d
+DIST webmin-1.881.tar.gz 28903876 BLAKE2B beaab3282ccbbe7716fe35e62ee93e64b636f420fa9235398954904b5e14888cdc4b0acd5126184dcdab59274d3e5b71a7997df3e73e18c55849b7197f024971 SHA512 eab1acb53aca5e947bb9fac1c08a32e9eeca2903bc19595fbc8e19895bda8f4c3432550c2a87cf8c2b577b223b97566b046b7c339bd8754266544f5777560cc7
+DIST webmin-1.974-minimal.tar.gz 3628248 BLAKE2B 60268150a9d25233dde59be280d4917bc62e4d3dfd94bb8705b823596a22a5fa7438c5d0f373a791f98a1f885cce160136a991e654d551b369c3426b03e77ed3 SHA512 175b507bf5c3a656ff999313b08ff4ace4cb19a4ff7987f2569e9dcd2ce5aa41a2e6db4505c7c7d78754cab0d7747374ac82d25f1b77ff1617df740df451e3e4
+DIST webmin-1.974.tar.gz 45412074 BLAKE2B d62469797d009d47f0e327f00457abc54b515ea88ff41c2049a320eeee6ff516bbbafba80ae038ae592260704d1bfa4a72f9eb2da8d9ea18ce5f071f85419b86 SHA512 612a88337a6915a6e2249a44c6279c310ddf71745b7a8ea799e111d170f874e12c1f3a1c08112f333560b107b1bb44153455e967499d4eba29c626630747801f
+DIST webmin-2.105-minimal.tar.gz 4642671 BLAKE2B d85129110865e7521f0743fd5151525fb0dd8b17be2bb20299c1a50c2f4e78e14bcf229aada4abf61b5132d4eabe3b7862e0da7b9c1d6b119b8e33efca233d6f SHA512 48b674526ce0b71d112dcf4868ae7f1c7cb1c1dec6d4fc68161b8d6a06333dc4d5a700b84760d2a6e2406fc6b8c6bf07bc9705a2109ff54634220f020e3bf3b3
+DIST webmin-2.105.tar.gz 46439259 BLAKE2B d86c70459755992a1745b7091e9dfc5bee4b0886d337004e23a66ed444f978948c6c6a72ccfa2d4212d5cd32f1eabfa52c9076c8ba14f5c847ee9b40c314cfa1 SHA512 c2813641452051fe37b5178e201195ba343091670443602dae2ad3d77902f8f79b0924689b260278035ecbea0d41e7c945dd67f903f0c4740c3a04bf853dd9c0
+DIST webmin-2.202-minimal.tar.gz 4639136 BLAKE2B 8ca693d91099084daaba266971347e9dc3b63e97b82093e69c5f2057fb75b57dbb415036d641176cf666282b29f1830d1d1e9120bd65d22a03653155d2298674 SHA512 61aec98760a1b8f0c7beba61719ce676d3689d6f6de8f5cee767659b1ba31b73453e4b2b6bc330645204b291692503f16181df222ca41491a0ba5c2674888099
+DIST webmin-2.202.tar.gz 46511919 BLAKE2B f58f34346330eac0406a17d5ccc4ca6cc584fd46afe5df428df581fe0014f0afb4143233101a6dab913ca8e5e23427748a4395571c949095995bc7b43af518be SHA512 84cce8c4eeda62018b98f21b0c620c8746ea77ab6b7304a76e8e3a074e74e030541d14e7223b4f31b5e1203f375d3c0e2c8f3aa072023a92df63108e55082c6a
+EBUILD webmin-1.881.ebuild 10428 BLAKE2B b38d8a76fb0b6e20e53710d4504e443ec3ef9ad138f36aad7a7234c6c64aa1e63f62c1936b2f69c5ce791627ff7a5bda209a96d91ab916151ca5eeb0af0ed341 SHA512 bbed283a33a8ea41f802210fda68ce9721d8a0eebdeb6f28faaae62445ce53dcb7fda89505a896fcffe48d350ef1ded10a5808b7aa942719e729afafc84df099
+EBUILD webmin-1.974.ebuild 10428 BLAKE2B b38d8a76fb0b6e20e53710d4504e443ec3ef9ad138f36aad7a7234c6c64aa1e63f62c1936b2f69c5ce791627ff7a5bda209a96d91ab916151ca5eeb0af0ed341 SHA512 bbed283a33a8ea41f802210fda68ce9721d8a0eebdeb6f28faaae62445ce53dcb7fda89505a896fcffe48d350ef1ded10a5808b7aa942719e729afafc84df099
+EBUILD webmin-2.105.ebuild 9996 BLAKE2B 398489c0488ebc95fd059f905742b5975f96f639dc8ca2b7ccb4034967bc5e0130d0b16969ba352ac36768c542b33f902228cf74ff9f0ceee455977d19a1505f SHA512 c898cc552ce9ac38310d8a6be1d48861dbc732508ec9d3d4566aee244909b137a1a60cd3ea429965d27bf150f520c545331b52da72ecc3cf72a396bb292543dd
+EBUILD webmin-2.202.ebuild 9996 BLAKE2B 398489c0488ebc95fd059f905742b5975f96f639dc8ca2b7ccb4034967bc5e0130d0b16969ba352ac36768c542b33f902228cf74ff9f0ceee455977d19a1505f SHA512 c898cc552ce9ac38310d8a6be1d48861dbc732508ec9d3d4566aee244909b137a1a60cd3ea429965d27bf150f520c545331b52da72ecc3cf72a396bb292543dd
+MISC webmin-1.974.ebuild.old 2512 BLAKE2B 59ce4619734f1fe0194c4978b29b279e4bd320f0712b97ae81615f6b6298c6036cc0659627e179d178ae9cdab12ae76d9e6f05c543fb768838aae86e44309ba7 SHA512 845c1aaa0e3249560e33705d3c0be546fbd17dace5c88b2ebd2df9c0b5de760f398fb144c76081a67617c1c6861ff2cbc9740af5ade10bd0d641f62f3c59364e
diff --git a/app-admin/webmin/files/gentoo-setup b/app-admin/webmin/files/gentoo-setup
new file mode 100644 (file)
index 0000000..680dfbb
--- /dev/null
@@ -0,0 +1,438 @@
+#!/bin/sh
+# gentoo-setup.sh
+#
+# Version 1.2
+#
+# A modified original Webmin setup.sh script to comply with Gentoo specifics
+#
+# Modification done by: PhobosK <phobosk@kbfx.net>
+#
+# This script runs after the webmin archive is installed, and in the pkg_config() phase.
+# It does setup the various config files of Webmin depending on if it is
+# a new install, an upgrade or a reset.
+
+LANG=
+export LANG
+
+if [ -z ${wadir} ]; then
+       echo "You can't run this script outside of the 'emerge --config app-admin/webmin' command."
+       exit 1
+fi
+
+# All things we do is from the Webmin install dir - $wadir
+cd $wadir
+
+
+# Are we hard resetting everything?
+# If yes, we do:
+# 1. Run the specific Webmin $wadir/run-uninstalls.pl
+#       It runs all uninstall.pl files in every module's folder.
+#       They delete all the set specific Webmin cron jobs.
+#       If bumping you should go through these files using the command:
+#       find . -name uninstall.pl -exec cat {} \; -print
+# 2. Delete the whole /etc/webmin content, keeping only the gentoo .keep_* files
+if [ "$reset" = "hard" ]; then
+       echo "Running Webmin's specific uninstall procedures.. (Please ignore any possible errors)"
+       (WEBMIN_CONFIG=$config_dir WEBMIN_VAR=$var_dir LANG= "$wadir/run-uninstalls.pl")
+       echo "..done"
+       echo ""
+
+       echo "Deleting the content of user's config folder: $config_dir .."
+       find $config_dir ! -name '.keep_*' -delete 2>/dev/null
+       echo "..done"
+       echo ""
+fi
+
+
+# Are we soft resetting?
+# If yes we do:
+# - Delete the $config_dir/config file so we get new config values
+if [ "$reset" = "soft" ]; then
+       echo "Deleting the user's $config_dir/config file.."
+       if [ -f "$config_dir/config" ]; then
+               rm -f "$config_dir/config"
+       fi
+       echo "..done"
+       echo ""
+fi
+
+
+# Get all available modules of this version
+allmods=`echo */module.info | sed -e 's/\/module.info//g'`
+
+# Get current Webmin version
+ver=`cat "$wadir/version"`
+
+if [ -r "$config_dir/config" ]; then
+       upgrading=1
+fi
+
+
+# Check if upgrading from an old version
+if [ "$upgrading" = 1 ]; then
+       echo "Updating existant Webmin's config files.."
+
+       # Get current var path
+       if [ -r "$config_dir/var-path" ]; then
+               _var_dir=`cat $config_dir/var-path`
+               if [ -n ${_var_dir} ]; then
+                       var_dir=${_var_dir}
+               fi
+       fi
+
+       # Get current perl path
+       if [ -r "$config_dir/perl-path" ]; then
+               _perl=`cat $config_dir/perl-path`
+               if [ -n ${_perl} ]; then
+                       perl=${_perl}
+               fi
+       fi
+
+       # Get old os name and version
+       os_type=`grep "^os_type=" $config_dir/config | sed -e 's/os_type=//g'`
+       os_version=`grep "^os_version=" $config_dir/config | sed -e 's/os_version=//g'`
+       real_os_type=`grep "^real_os_type=" $config_dir/config | sed -e 's/real_os_type=//g'`
+       real_os_version=`grep "^real_os_version=" $config_dir/config | sed -e 's/real_os_version=//g'`
+
+       # Get port, ssl, no_ssl2, no_ssl3, ssl_redirect, no_sslcompression, ssl_honorcipherorder, no_tls1, no_tls1_1 and keyfile
+       port=`grep "^port=" $config_dir/miniserv.conf | sed -e 's/port=//g'`
+       ssl=`grep "^ssl=" $config_dir/miniserv.conf | sed -e 's/ssl=//g'`
+       no_ssl2=`grep "^no_ssl2=" $config_dir/miniserv.conf | sed -e 's/no_ssl2=//g'`
+       no_ssl3=`grep "^no_ssl3=" $config_dir/miniserv.conf | sed -e 's/no_ssl3=//g'`
+       ssl_redirect=`grep "^ssl_redirect=" $config_dir/miniserv.conf | sed -e 's/ssl_redirect=//g'`
+       ssl_honorcipherorder=`grep "^ssl_honorcipherorder=" $config_dir/miniserv.conf | sed -e 's/ssl_honorcipherorder=//g'`
+       no_sslcompression=`grep "^no_sslcompression=" $config_dir/miniserv.conf | sed -e 's/no_sslcompression=//g'`
+       no_tls1=`grep "^no_tls1=" $config_dir/miniserv.conf | sed -e 's/no_tls1=//g'`
+       no_tls1_1=`grep "^no_tls1_1=" $config_dir/miniserv.conf | sed -e 's/no_tls1_1=//g'`
+       keyfile=`grep "^keyfile=" $config_dir/miniserv.conf | sed -e 's/keyfile=//g'`
+
+       # Update ACLs
+       $perl "$wadir/newmods.pl" $config_dir $allmods
+
+       # Update miniserv.conf with new root directory, mime types file and server info
+       grep -v "^root=" $config_dir/miniserv.conf | grep -v "^mimetypes=" | grep -v "^server=" >$tempdir/$$.miniserv.conf
+       mv $tempdir/$$.miniserv.conf $config_dir/miniserv.conf
+       echo "root=$wadir" >> $config_dir/miniserv.conf
+       echo "mimetypes=$wadir/mime.types" >> $config_dir/miniserv.conf
+       echo "server=MiniServ/$ver" >> $config_dir/miniserv.conf
+       grep logout= $config_dir/miniserv.conf >/dev/null
+       if [ $? != "0" ]; then
+               echo "logout=$config_dir/logout-flag" >> $config_dir/miniserv.conf
+       fi
+
+       # Remove old cache of module infos
+       rm -f $config_dir/module.infos.cache
+       echo "..done"
+       echo ""
+else
+       # Create webserver's new config files
+       echo "Creating Webmin's new config files.."
+
+       echo $perl > $config_dir/perl-path
+       echo $var_dir > $config_dir/var-path
+
+       # Create a totally new conf file
+       cfile=$config_dir/miniserv.conf
+       echo "port=$port" > $cfile
+       echo "root=$wadir" >> $cfile
+       echo "mimetypes=$wadir/mime.types" >> $cfile
+       echo "addtype_cgi=internal/cgi" >> $cfile
+       echo "realm=Webmin Server" >> $cfile
+       echo "logfile=$var_dir/miniserv.log" >> $cfile
+       echo "errorlog=$var_dir/miniserv.error" >> $cfile
+       echo "pidfile=$pidfile" >> $cfile
+       echo "logtime=168" >> $cfile
+       echo "ppath=$ppath" >> $cfile
+       echo "ssl=$ssl" >> $cfile
+       echo "no_ssl2=$no_ssl2" >> $cfile
+       echo "no_ssl3=$no_ssl3" >> $cfile
+       echo "ssl_redirect=$ssl_redirect" >> $cfile
+       echo "ssl_honorcipherorder=$ssl_honorcipherorder" >> $cfile
+       echo "no_sslcompression=$no_sslcompression" >> $cfile
+       echo "no_tls1=$no_tls1" >> $cfile
+       echo "no_tls1_1=$no_tls1_1" >> $cfile
+       echo "keyfile=$keyfile" >> $cfile
+       echo "env_WEBMIN_CONFIG=$config_dir" >> $cfile
+       echo "env_WEBMIN_VAR=$var_dir" >> $cfile
+       echo "atboot=$atboot" >> $cfile
+       echo "logout=$config_dir/logout-flag" >> $cfile
+       echo "listen=10000" >> $cfile
+       echo "denyfile=\\.pl\$" >> $cfile
+       echo "log=1" >> $cfile
+       echo "blockhost_failures=5" >> $cfile
+       echo "blockhost_time=60" >> $cfile
+       echo "syslog=1" >> $cfile
+       echo "session=1" >> $cfile
+       echo "premodules=WebminCore" >> $cfile
+       echo "server=MiniServ/$ver" >> $cfile
+
+       # Append package-specific info to config file.
+       # miniserv-conf can be created by upstream or by us in src_install phase (see there).
+       if [ -f "$wadir/miniserv-conf" ]; then
+               cat "$wadir/miniserv-conf" >>$cfile
+       fi
+
+       # Create the default user allowed to login - root only
+       login="root"
+
+       if [ -r /etc/shadow ]; then
+               #crypt=`grep "^root:" /etc/shadow | cut -f 2 -d :`
+               crypt=x
+       else
+               crypt=`grep "^root:" /etc/passwd | cut -f 2 -d :`
+       fi
+
+       ufile=$config_dir/miniserv.users
+       echo "$login:$crypt:0" > $ufile
+       chmod 600 $ufile
+
+
+       echo "userfile=$ufile" >> $cfile
+       chmod 600 $cfile
+       echo "..done"
+       echo ""
+
+       echo "Creating access control file.."
+       afile=$config_dir/webmin.acl
+       echo "$login: $allmods" > $afile
+       chmod 600 $afile
+       echo "..done"
+       echo ""
+fi
+
+
+# Create start, stop, restart and reload Gentoo compliant Webmin scripts
+# We use sys-apps/openrc functions which is already pulled by sys-apps/baselayout
+# or systemctl if we run under systemd
+echo "Creating start and stop scripts.."
+rm -f $config_dir/{start,stop,restart,reload}
+
+# The start script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/start"
+#!/bin/sh
+
+if [ ! -f "${pidfile}" ]; then
+       if [[ -d /run/systemd/system ]] ; then
+               systemctl start webmin.service
+       else
+               rc-service --ifexists -- webmin start
+       fi
+fi
+END
+
+# The stop script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/stop"
+#!/bin/sh
+
+if [[ -d /run/systemd/system ]] ; then
+       systemctl stop webmin.service
+else
+       rc-service --ifexists -- webmin --ifstarted stop
+fi
+END
+
+# The restart script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/restart"
+#!/bin/sh
+
+if [[ -d /run/systemd/system ]] ; then
+       systemctl try-restart webmin.service
+else
+       rc-service --ifexists -- webmin --ifstarted restart
+fi
+END
+
+# The reload script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/reload"
+#!/bin/sh
+
+if [[ -d /run/systemd/system ]] ; then
+       systemctl reload-or-try-restart webmin.service
+else
+       rc-service --ifexists -- webmin --ifstarted reload
+fi
+END
+
+chmod 755 $config_dir/{start,stop,restart,reload}
+echo "..done"
+echo ""
+
+
+if [ "$upgrading" = 1 ]; then
+       echo "Updating other config files.."
+else
+       echo "Copying other config files.."
+fi
+
+# This just copies and merges the Webmin's release config files, with user's in the /etc/webmin folder
+newmods=`$perl "$wadir/copyconfig.pl" "$os_type/$real_os_type" "$os_version/$real_os_version" "$wadir" $config_dir "" $allmods`
+if [ "$upgrading" != 1 ]; then
+       # Store the OS and version
+       echo "os_type=$os_type" >> $config_dir/config
+       echo "os_version=$os_version" >> $config_dir/config
+       echo "real_os_type=$real_os_type" >> $config_dir/config
+       echo "real_os_version=$real_os_version" >> $config_dir/config
+
+       # Turn on logging by default
+       echo "log=1" >> $config_dir/config
+
+       # Disallow unknown referers by default
+       echo "referers_none=1" >>$config_dir/config
+else
+       # one-off hack to set log variable in config from miniserv.conf
+       grep log= $config_dir/config >/dev/null
+       if [ "$?" = "1" ]; then
+               grep log= $config_dir/miniserv.conf >> $config_dir/config
+               grep logtime= $config_dir/miniserv.conf >> $config_dir/config
+               grep logclear= $config_dir/miniserv.conf >> $config_dir/config
+       fi
+
+       # Disallow unknown referers if not set
+       grep referers_none= $config_dir/config >/dev/null
+       if [ "$?" != "0" ]; then
+               echo "referers_none=1" >>$config_dir/config
+       fi
+fi
+echo $ver > $config_dir/version
+echo "..done"
+echo ""
+
+# Set passwd_ fields in miniserv.conf from global config
+for field in passwd_file passwd_uindex passwd_pindex passwd_cindex passwd_mindex; do
+       grep $field= $config_dir/miniserv.conf >/dev/null
+       if [ "$?" != "0" ]; then
+               grep $field= $config_dir/config >> $config_dir/miniserv.conf
+       fi
+done
+grep passwd_mode= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo passwd_mode=0 >> $config_dir/miniserv.conf
+fi
+
+grep ssl_honorcipherorder= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo ssl_honorcipherorder=1 >> $config_dir/miniserv.conf
+fi
+
+# Disable SSL compression to defeat BEAST attack
+grep no_sslcompression= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo no_sslcompression=1 >> $config_dir/miniserv.conf
+fi
+
+# Tighten SSL security
+grep no_ssl2= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo no_ssl2=1 >> $config_dir/miniserv.conf
+fi
+
+grep no_ssl3= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo no_ssl3=1 >> $config_dir/miniserv.conf
+fi
+
+grep no_tls1= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+    echo no_tls1=1 >> $config_dir/miniserv.conf
+fi
+
+grep no_tls1_1= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+    echo no_tls1_1=1 >> $config_dir/miniserv.conf
+fi
+
+# Make Perl crypt MD5 the default
+grep md5pass= $config_dir/config >/dev/null
+if [ "$?" != "0" ]; then
+       echo md5pass=1 >> $config_dir/config
+fi
+
+# Set a special theme if none was set before
+if [ "$theme" = "" ]; then
+       theme=`cat "$wadir/defaulttheme" 2>/dev/null`
+fi
+oldthemeline=`grep "^theme=" $config_dir/config`
+oldtheme=`echo $oldthemeline | sed -e 's/theme=//g'`
+if [ "$theme" != "" ] && [ "$oldthemeline" = "" ] && [ -d "$wadir/$theme" ]; then
+       themelist=$theme
+fi
+
+# Set a special overlay if none was set before
+if [ "$overlay" = "" ]; then
+       overlay=`cat "$wadir/defaultoverlay" 2>/dev/null`
+fi
+if [ "$overlay" != "" ] && [ "$theme" != "" ] && [ -d "$wadir/$overlay" ]; then
+       themelist="$themelist $overlay"
+fi
+
+# Apply the theme and maybe overlay
+if [ "$themelist" != "" ]; then
+       echo "theme=$themelist" >> $config_dir/config
+       echo "preroot=$themelist" >> $config_dir/miniserv.conf
+fi
+
+# If the old blue-theme is still in use, change it (new in 1.730)
+oldtheme=`grep "^theme=" $config_dir/config | sed -e 's/theme=//g'`
+if [ "$oldtheme" = "blue-theme" ]; then
+   sed -i -e 's/theme=blue-theme/theme=gray-theme/g' $config_dir/config
+   sed -i -e 's/preroot=blue-theme/preroot=gray-theme/g' $config_dir/miniserv.conf
+fi
+
+# Set the product field in the global config
+grep product= $config_dir/config >/dev/null
+if [ "$?" != "0" ]; then
+       echo product=webmin >> $config_dir/config
+fi
+
+# If password delays are not specifically disabled, enable them
+grep passdelay= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo passdelay=1 >> $config_dir/miniserv.conf
+fi
+
+
+echo "Changing ownership and permissions.."
+# Make all config dirs non-world-readable
+for m in $newmods; do
+       chown -R root:root $config_dir/$m
+       chmod -R og-rw $config_dir/$m
+done
+
+# Make miniserv config files non-world-readable
+for f in miniserv.conf miniserv.users; do
+       chown -R root:root $config_dir/$f
+       chmod -R og-rw $config_dir/$f
+done
+chmod +r $config_dir/version
+
+# Fix up bad permissions from some older installs
+for m in ldap-client ldap-server ldap-useradmin mailboxes mysql postgresql servers virtual-server; do
+       if [ -d "$config_dir/$m" ]; then
+               chown root:root $config_dir/$m
+               chmod og-rw $config_dir/$m
+               chmod og-rw $config_dir/$m/config 2>/dev/null
+       fi
+done
+echo "..done"
+echo ""
+
+
+# This executes all postinstall.pl for every module
+# If you do bump, you should look at the specific changes they do with this command in root folder:
+# find . -name postinstall.pl -exec cat {} \; -print
+# Generally they are safe to run 'cause they change only user's config in /etc/webmin
+# or setup some cron jobs
+if [ "$nopostinstall" = "" ]; then
+       echo "Running postinstall scripts.. (Please ignore any possible errors)"
+       (cd "$wadir" ; WEBMIN_CONFIG=$config_dir WEBMIN_VAR=$var_dir "$wadir/run-postinstalls.pl")
+       echo "..done"
+       echo ""
+fi
+
+# Enable background collection
+if [ "$upgrading" != 1 -a -r $config_dir/system-status/enable-collection.pl ]; then
+       echo "Enabling background status collection.. (Please ignore any possible errors)"
+       $config_dir/system-status/enable-collection.pl 5
+       echo "..done"
+       echo ""
+fi
diff --git a/app-admin/webmin/files/gentoo-setup-1.974 b/app-admin/webmin/files/gentoo-setup-1.974
new file mode 100644 (file)
index 0000000..680dfbb
--- /dev/null
@@ -0,0 +1,438 @@
+#!/bin/sh
+# gentoo-setup.sh
+#
+# Version 1.2
+#
+# A modified original Webmin setup.sh script to comply with Gentoo specifics
+#
+# Modification done by: PhobosK <phobosk@kbfx.net>
+#
+# This script runs after the webmin archive is installed, and in the pkg_config() phase.
+# It does setup the various config files of Webmin depending on if it is
+# a new install, an upgrade or a reset.
+
+LANG=
+export LANG
+
+if [ -z ${wadir} ]; then
+       echo "You can't run this script outside of the 'emerge --config app-admin/webmin' command."
+       exit 1
+fi
+
+# All things we do is from the Webmin install dir - $wadir
+cd $wadir
+
+
+# Are we hard resetting everything?
+# If yes, we do:
+# 1. Run the specific Webmin $wadir/run-uninstalls.pl
+#       It runs all uninstall.pl files in every module's folder.
+#       They delete all the set specific Webmin cron jobs.
+#       If bumping you should go through these files using the command:
+#       find . -name uninstall.pl -exec cat {} \; -print
+# 2. Delete the whole /etc/webmin content, keeping only the gentoo .keep_* files
+if [ "$reset" = "hard" ]; then
+       echo "Running Webmin's specific uninstall procedures.. (Please ignore any possible errors)"
+       (WEBMIN_CONFIG=$config_dir WEBMIN_VAR=$var_dir LANG= "$wadir/run-uninstalls.pl")
+       echo "..done"
+       echo ""
+
+       echo "Deleting the content of user's config folder: $config_dir .."
+       find $config_dir ! -name '.keep_*' -delete 2>/dev/null
+       echo "..done"
+       echo ""
+fi
+
+
+# Are we soft resetting?
+# If yes we do:
+# - Delete the $config_dir/config file so we get new config values
+if [ "$reset" = "soft" ]; then
+       echo "Deleting the user's $config_dir/config file.."
+       if [ -f "$config_dir/config" ]; then
+               rm -f "$config_dir/config"
+       fi
+       echo "..done"
+       echo ""
+fi
+
+
+# Get all available modules of this version
+allmods=`echo */module.info | sed -e 's/\/module.info//g'`
+
+# Get current Webmin version
+ver=`cat "$wadir/version"`
+
+if [ -r "$config_dir/config" ]; then
+       upgrading=1
+fi
+
+
+# Check if upgrading from an old version
+if [ "$upgrading" = 1 ]; then
+       echo "Updating existant Webmin's config files.."
+
+       # Get current var path
+       if [ -r "$config_dir/var-path" ]; then
+               _var_dir=`cat $config_dir/var-path`
+               if [ -n ${_var_dir} ]; then
+                       var_dir=${_var_dir}
+               fi
+       fi
+
+       # Get current perl path
+       if [ -r "$config_dir/perl-path" ]; then
+               _perl=`cat $config_dir/perl-path`
+               if [ -n ${_perl} ]; then
+                       perl=${_perl}
+               fi
+       fi
+
+       # Get old os name and version
+       os_type=`grep "^os_type=" $config_dir/config | sed -e 's/os_type=//g'`
+       os_version=`grep "^os_version=" $config_dir/config | sed -e 's/os_version=//g'`
+       real_os_type=`grep "^real_os_type=" $config_dir/config | sed -e 's/real_os_type=//g'`
+       real_os_version=`grep "^real_os_version=" $config_dir/config | sed -e 's/real_os_version=//g'`
+
+       # Get port, ssl, no_ssl2, no_ssl3, ssl_redirect, no_sslcompression, ssl_honorcipherorder, no_tls1, no_tls1_1 and keyfile
+       port=`grep "^port=" $config_dir/miniserv.conf | sed -e 's/port=//g'`
+       ssl=`grep "^ssl=" $config_dir/miniserv.conf | sed -e 's/ssl=//g'`
+       no_ssl2=`grep "^no_ssl2=" $config_dir/miniserv.conf | sed -e 's/no_ssl2=//g'`
+       no_ssl3=`grep "^no_ssl3=" $config_dir/miniserv.conf | sed -e 's/no_ssl3=//g'`
+       ssl_redirect=`grep "^ssl_redirect=" $config_dir/miniserv.conf | sed -e 's/ssl_redirect=//g'`
+       ssl_honorcipherorder=`grep "^ssl_honorcipherorder=" $config_dir/miniserv.conf | sed -e 's/ssl_honorcipherorder=//g'`
+       no_sslcompression=`grep "^no_sslcompression=" $config_dir/miniserv.conf | sed -e 's/no_sslcompression=//g'`
+       no_tls1=`grep "^no_tls1=" $config_dir/miniserv.conf | sed -e 's/no_tls1=//g'`
+       no_tls1_1=`grep "^no_tls1_1=" $config_dir/miniserv.conf | sed -e 's/no_tls1_1=//g'`
+       keyfile=`grep "^keyfile=" $config_dir/miniserv.conf | sed -e 's/keyfile=//g'`
+
+       # Update ACLs
+       $perl "$wadir/newmods.pl" $config_dir $allmods
+
+       # Update miniserv.conf with new root directory, mime types file and server info
+       grep -v "^root=" $config_dir/miniserv.conf | grep -v "^mimetypes=" | grep -v "^server=" >$tempdir/$$.miniserv.conf
+       mv $tempdir/$$.miniserv.conf $config_dir/miniserv.conf
+       echo "root=$wadir" >> $config_dir/miniserv.conf
+       echo "mimetypes=$wadir/mime.types" >> $config_dir/miniserv.conf
+       echo "server=MiniServ/$ver" >> $config_dir/miniserv.conf
+       grep logout= $config_dir/miniserv.conf >/dev/null
+       if [ $? != "0" ]; then
+               echo "logout=$config_dir/logout-flag" >> $config_dir/miniserv.conf
+       fi
+
+       # Remove old cache of module infos
+       rm -f $config_dir/module.infos.cache
+       echo "..done"
+       echo ""
+else
+       # Create webserver's new config files
+       echo "Creating Webmin's new config files.."
+
+       echo $perl > $config_dir/perl-path
+       echo $var_dir > $config_dir/var-path
+
+       # Create a totally new conf file
+       cfile=$config_dir/miniserv.conf
+       echo "port=$port" > $cfile
+       echo "root=$wadir" >> $cfile
+       echo "mimetypes=$wadir/mime.types" >> $cfile
+       echo "addtype_cgi=internal/cgi" >> $cfile
+       echo "realm=Webmin Server" >> $cfile
+       echo "logfile=$var_dir/miniserv.log" >> $cfile
+       echo "errorlog=$var_dir/miniserv.error" >> $cfile
+       echo "pidfile=$pidfile" >> $cfile
+       echo "logtime=168" >> $cfile
+       echo "ppath=$ppath" >> $cfile
+       echo "ssl=$ssl" >> $cfile
+       echo "no_ssl2=$no_ssl2" >> $cfile
+       echo "no_ssl3=$no_ssl3" >> $cfile
+       echo "ssl_redirect=$ssl_redirect" >> $cfile
+       echo "ssl_honorcipherorder=$ssl_honorcipherorder" >> $cfile
+       echo "no_sslcompression=$no_sslcompression" >> $cfile
+       echo "no_tls1=$no_tls1" >> $cfile
+       echo "no_tls1_1=$no_tls1_1" >> $cfile
+       echo "keyfile=$keyfile" >> $cfile
+       echo "env_WEBMIN_CONFIG=$config_dir" >> $cfile
+       echo "env_WEBMIN_VAR=$var_dir" >> $cfile
+       echo "atboot=$atboot" >> $cfile
+       echo "logout=$config_dir/logout-flag" >> $cfile
+       echo "listen=10000" >> $cfile
+       echo "denyfile=\\.pl\$" >> $cfile
+       echo "log=1" >> $cfile
+       echo "blockhost_failures=5" >> $cfile
+       echo "blockhost_time=60" >> $cfile
+       echo "syslog=1" >> $cfile
+       echo "session=1" >> $cfile
+       echo "premodules=WebminCore" >> $cfile
+       echo "server=MiniServ/$ver" >> $cfile
+
+       # Append package-specific info to config file.
+       # miniserv-conf can be created by upstream or by us in src_install phase (see there).
+       if [ -f "$wadir/miniserv-conf" ]; then
+               cat "$wadir/miniserv-conf" >>$cfile
+       fi
+
+       # Create the default user allowed to login - root only
+       login="root"
+
+       if [ -r /etc/shadow ]; then
+               #crypt=`grep "^root:" /etc/shadow | cut -f 2 -d :`
+               crypt=x
+       else
+               crypt=`grep "^root:" /etc/passwd | cut -f 2 -d :`
+       fi
+
+       ufile=$config_dir/miniserv.users
+       echo "$login:$crypt:0" > $ufile
+       chmod 600 $ufile
+
+
+       echo "userfile=$ufile" >> $cfile
+       chmod 600 $cfile
+       echo "..done"
+       echo ""
+
+       echo "Creating access control file.."
+       afile=$config_dir/webmin.acl
+       echo "$login: $allmods" > $afile
+       chmod 600 $afile
+       echo "..done"
+       echo ""
+fi
+
+
+# Create start, stop, restart and reload Gentoo compliant Webmin scripts
+# We use sys-apps/openrc functions which is already pulled by sys-apps/baselayout
+# or systemctl if we run under systemd
+echo "Creating start and stop scripts.."
+rm -f $config_dir/{start,stop,restart,reload}
+
+# The start script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/start"
+#!/bin/sh
+
+if [ ! -f "${pidfile}" ]; then
+       if [[ -d /run/systemd/system ]] ; then
+               systemctl start webmin.service
+       else
+               rc-service --ifexists -- webmin start
+       fi
+fi
+END
+
+# The stop script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/stop"
+#!/bin/sh
+
+if [[ -d /run/systemd/system ]] ; then
+       systemctl stop webmin.service
+else
+       rc-service --ifexists -- webmin --ifstarted stop
+fi
+END
+
+# The restart script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/restart"
+#!/bin/sh
+
+if [[ -d /run/systemd/system ]] ; then
+       systemctl try-restart webmin.service
+else
+       rc-service --ifexists -- webmin --ifstarted restart
+fi
+END
+
+# The reload script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/reload"
+#!/bin/sh
+
+if [[ -d /run/systemd/system ]] ; then
+       systemctl reload-or-try-restart webmin.service
+else
+       rc-service --ifexists -- webmin --ifstarted reload
+fi
+END
+
+chmod 755 $config_dir/{start,stop,restart,reload}
+echo "..done"
+echo ""
+
+
+if [ "$upgrading" = 1 ]; then
+       echo "Updating other config files.."
+else
+       echo "Copying other config files.."
+fi
+
+# This just copies and merges the Webmin's release config files, with user's in the /etc/webmin folder
+newmods=`$perl "$wadir/copyconfig.pl" "$os_type/$real_os_type" "$os_version/$real_os_version" "$wadir" $config_dir "" $allmods`
+if [ "$upgrading" != 1 ]; then
+       # Store the OS and version
+       echo "os_type=$os_type" >> $config_dir/config
+       echo "os_version=$os_version" >> $config_dir/config
+       echo "real_os_type=$real_os_type" >> $config_dir/config
+       echo "real_os_version=$real_os_version" >> $config_dir/config
+
+       # Turn on logging by default
+       echo "log=1" >> $config_dir/config
+
+       # Disallow unknown referers by default
+       echo "referers_none=1" >>$config_dir/config
+else
+       # one-off hack to set log variable in config from miniserv.conf
+       grep log= $config_dir/config >/dev/null
+       if [ "$?" = "1" ]; then
+               grep log= $config_dir/miniserv.conf >> $config_dir/config
+               grep logtime= $config_dir/miniserv.conf >> $config_dir/config
+               grep logclear= $config_dir/miniserv.conf >> $config_dir/config
+       fi
+
+       # Disallow unknown referers if not set
+       grep referers_none= $config_dir/config >/dev/null
+       if [ "$?" != "0" ]; then
+               echo "referers_none=1" >>$config_dir/config
+       fi
+fi
+echo $ver > $config_dir/version
+echo "..done"
+echo ""
+
+# Set passwd_ fields in miniserv.conf from global config
+for field in passwd_file passwd_uindex passwd_pindex passwd_cindex passwd_mindex; do
+       grep $field= $config_dir/miniserv.conf >/dev/null
+       if [ "$?" != "0" ]; then
+               grep $field= $config_dir/config >> $config_dir/miniserv.conf
+       fi
+done
+grep passwd_mode= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo passwd_mode=0 >> $config_dir/miniserv.conf
+fi
+
+grep ssl_honorcipherorder= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo ssl_honorcipherorder=1 >> $config_dir/miniserv.conf
+fi
+
+# Disable SSL compression to defeat BEAST attack
+grep no_sslcompression= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo no_sslcompression=1 >> $config_dir/miniserv.conf
+fi
+
+# Tighten SSL security
+grep no_ssl2= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo no_ssl2=1 >> $config_dir/miniserv.conf
+fi
+
+grep no_ssl3= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo no_ssl3=1 >> $config_dir/miniserv.conf
+fi
+
+grep no_tls1= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+    echo no_tls1=1 >> $config_dir/miniserv.conf
+fi
+
+grep no_tls1_1= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+    echo no_tls1_1=1 >> $config_dir/miniserv.conf
+fi
+
+# Make Perl crypt MD5 the default
+grep md5pass= $config_dir/config >/dev/null
+if [ "$?" != "0" ]; then
+       echo md5pass=1 >> $config_dir/config
+fi
+
+# Set a special theme if none was set before
+if [ "$theme" = "" ]; then
+       theme=`cat "$wadir/defaulttheme" 2>/dev/null`
+fi
+oldthemeline=`grep "^theme=" $config_dir/config`
+oldtheme=`echo $oldthemeline | sed -e 's/theme=//g'`
+if [ "$theme" != "" ] && [ "$oldthemeline" = "" ] && [ -d "$wadir/$theme" ]; then
+       themelist=$theme
+fi
+
+# Set a special overlay if none was set before
+if [ "$overlay" = "" ]; then
+       overlay=`cat "$wadir/defaultoverlay" 2>/dev/null`
+fi
+if [ "$overlay" != "" ] && [ "$theme" != "" ] && [ -d "$wadir/$overlay" ]; then
+       themelist="$themelist $overlay"
+fi
+
+# Apply the theme and maybe overlay
+if [ "$themelist" != "" ]; then
+       echo "theme=$themelist" >> $config_dir/config
+       echo "preroot=$themelist" >> $config_dir/miniserv.conf
+fi
+
+# If the old blue-theme is still in use, change it (new in 1.730)
+oldtheme=`grep "^theme=" $config_dir/config | sed -e 's/theme=//g'`
+if [ "$oldtheme" = "blue-theme" ]; then
+   sed -i -e 's/theme=blue-theme/theme=gray-theme/g' $config_dir/config
+   sed -i -e 's/preroot=blue-theme/preroot=gray-theme/g' $config_dir/miniserv.conf
+fi
+
+# Set the product field in the global config
+grep product= $config_dir/config >/dev/null
+if [ "$?" != "0" ]; then
+       echo product=webmin >> $config_dir/config
+fi
+
+# If password delays are not specifically disabled, enable them
+grep passdelay= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo passdelay=1 >> $config_dir/miniserv.conf
+fi
+
+
+echo "Changing ownership and permissions.."
+# Make all config dirs non-world-readable
+for m in $newmods; do
+       chown -R root:root $config_dir/$m
+       chmod -R og-rw $config_dir/$m
+done
+
+# Make miniserv config files non-world-readable
+for f in miniserv.conf miniserv.users; do
+       chown -R root:root $config_dir/$f
+       chmod -R og-rw $config_dir/$f
+done
+chmod +r $config_dir/version
+
+# Fix up bad permissions from some older installs
+for m in ldap-client ldap-server ldap-useradmin mailboxes mysql postgresql servers virtual-server; do
+       if [ -d "$config_dir/$m" ]; then
+               chown root:root $config_dir/$m
+               chmod og-rw $config_dir/$m
+               chmod og-rw $config_dir/$m/config 2>/dev/null
+       fi
+done
+echo "..done"
+echo ""
+
+
+# This executes all postinstall.pl for every module
+# If you do bump, you should look at the specific changes they do with this command in root folder:
+# find . -name postinstall.pl -exec cat {} \; -print
+# Generally they are safe to run 'cause they change only user's config in /etc/webmin
+# or setup some cron jobs
+if [ "$nopostinstall" = "" ]; then
+       echo "Running postinstall scripts.. (Please ignore any possible errors)"
+       (cd "$wadir" ; WEBMIN_CONFIG=$config_dir WEBMIN_VAR=$var_dir "$wadir/run-postinstalls.pl")
+       echo "..done"
+       echo ""
+fi
+
+# Enable background collection
+if [ "$upgrading" != 1 -a -r $config_dir/system-status/enable-collection.pl ]; then
+       echo "Enabling background status collection.. (Please ignore any possible errors)"
+       $config_dir/system-status/enable-collection.pl 5
+       echo "..done"
+       echo ""
+fi
diff --git a/app-admin/webmin/files/gentoo-setup-2.202 b/app-admin/webmin/files/gentoo-setup-2.202
new file mode 100644 (file)
index 0000000..680dfbb
--- /dev/null
@@ -0,0 +1,438 @@
+#!/bin/sh
+# gentoo-setup.sh
+#
+# Version 1.2
+#
+# A modified original Webmin setup.sh script to comply with Gentoo specifics
+#
+# Modification done by: PhobosK <phobosk@kbfx.net>
+#
+# This script runs after the webmin archive is installed, and in the pkg_config() phase.
+# It does setup the various config files of Webmin depending on if it is
+# a new install, an upgrade or a reset.
+
+LANG=
+export LANG
+
+if [ -z ${wadir} ]; then
+       echo "You can't run this script outside of the 'emerge --config app-admin/webmin' command."
+       exit 1
+fi
+
+# All things we do is from the Webmin install dir - $wadir
+cd $wadir
+
+
+# Are we hard resetting everything?
+# If yes, we do:
+# 1. Run the specific Webmin $wadir/run-uninstalls.pl
+#       It runs all uninstall.pl files in every module's folder.
+#       They delete all the set specific Webmin cron jobs.
+#       If bumping you should go through these files using the command:
+#       find . -name uninstall.pl -exec cat {} \; -print
+# 2. Delete the whole /etc/webmin content, keeping only the gentoo .keep_* files
+if [ "$reset" = "hard" ]; then
+       echo "Running Webmin's specific uninstall procedures.. (Please ignore any possible errors)"
+       (WEBMIN_CONFIG=$config_dir WEBMIN_VAR=$var_dir LANG= "$wadir/run-uninstalls.pl")
+       echo "..done"
+       echo ""
+
+       echo "Deleting the content of user's config folder: $config_dir .."
+       find $config_dir ! -name '.keep_*' -delete 2>/dev/null
+       echo "..done"
+       echo ""
+fi
+
+
+# Are we soft resetting?
+# If yes we do:
+# - Delete the $config_dir/config file so we get new config values
+if [ "$reset" = "soft" ]; then
+       echo "Deleting the user's $config_dir/config file.."
+       if [ -f "$config_dir/config" ]; then
+               rm -f "$config_dir/config"
+       fi
+       echo "..done"
+       echo ""
+fi
+
+
+# Get all available modules of this version
+allmods=`echo */module.info | sed -e 's/\/module.info//g'`
+
+# Get current Webmin version
+ver=`cat "$wadir/version"`
+
+if [ -r "$config_dir/config" ]; then
+       upgrading=1
+fi
+
+
+# Check if upgrading from an old version
+if [ "$upgrading" = 1 ]; then
+       echo "Updating existant Webmin's config files.."
+
+       # Get current var path
+       if [ -r "$config_dir/var-path" ]; then
+               _var_dir=`cat $config_dir/var-path`
+               if [ -n ${_var_dir} ]; then
+                       var_dir=${_var_dir}
+               fi
+       fi
+
+       # Get current perl path
+       if [ -r "$config_dir/perl-path" ]; then
+               _perl=`cat $config_dir/perl-path`
+               if [ -n ${_perl} ]; then
+                       perl=${_perl}
+               fi
+       fi
+
+       # Get old os name and version
+       os_type=`grep "^os_type=" $config_dir/config | sed -e 's/os_type=//g'`
+       os_version=`grep "^os_version=" $config_dir/config | sed -e 's/os_version=//g'`
+       real_os_type=`grep "^real_os_type=" $config_dir/config | sed -e 's/real_os_type=//g'`
+       real_os_version=`grep "^real_os_version=" $config_dir/config | sed -e 's/real_os_version=//g'`
+
+       # Get port, ssl, no_ssl2, no_ssl3, ssl_redirect, no_sslcompression, ssl_honorcipherorder, no_tls1, no_tls1_1 and keyfile
+       port=`grep "^port=" $config_dir/miniserv.conf | sed -e 's/port=//g'`
+       ssl=`grep "^ssl=" $config_dir/miniserv.conf | sed -e 's/ssl=//g'`
+       no_ssl2=`grep "^no_ssl2=" $config_dir/miniserv.conf | sed -e 's/no_ssl2=//g'`
+       no_ssl3=`grep "^no_ssl3=" $config_dir/miniserv.conf | sed -e 's/no_ssl3=//g'`
+       ssl_redirect=`grep "^ssl_redirect=" $config_dir/miniserv.conf | sed -e 's/ssl_redirect=//g'`
+       ssl_honorcipherorder=`grep "^ssl_honorcipherorder=" $config_dir/miniserv.conf | sed -e 's/ssl_honorcipherorder=//g'`
+       no_sslcompression=`grep "^no_sslcompression=" $config_dir/miniserv.conf | sed -e 's/no_sslcompression=//g'`
+       no_tls1=`grep "^no_tls1=" $config_dir/miniserv.conf | sed -e 's/no_tls1=//g'`
+       no_tls1_1=`grep "^no_tls1_1=" $config_dir/miniserv.conf | sed -e 's/no_tls1_1=//g'`
+       keyfile=`grep "^keyfile=" $config_dir/miniserv.conf | sed -e 's/keyfile=//g'`
+
+       # Update ACLs
+       $perl "$wadir/newmods.pl" $config_dir $allmods
+
+       # Update miniserv.conf with new root directory, mime types file and server info
+       grep -v "^root=" $config_dir/miniserv.conf | grep -v "^mimetypes=" | grep -v "^server=" >$tempdir/$$.miniserv.conf
+       mv $tempdir/$$.miniserv.conf $config_dir/miniserv.conf
+       echo "root=$wadir" >> $config_dir/miniserv.conf
+       echo "mimetypes=$wadir/mime.types" >> $config_dir/miniserv.conf
+       echo "server=MiniServ/$ver" >> $config_dir/miniserv.conf
+       grep logout= $config_dir/miniserv.conf >/dev/null
+       if [ $? != "0" ]; then
+               echo "logout=$config_dir/logout-flag" >> $config_dir/miniserv.conf
+       fi
+
+       # Remove old cache of module infos
+       rm -f $config_dir/module.infos.cache
+       echo "..done"
+       echo ""
+else
+       # Create webserver's new config files
+       echo "Creating Webmin's new config files.."
+
+       echo $perl > $config_dir/perl-path
+       echo $var_dir > $config_dir/var-path
+
+       # Create a totally new conf file
+       cfile=$config_dir/miniserv.conf
+       echo "port=$port" > $cfile
+       echo "root=$wadir" >> $cfile
+       echo "mimetypes=$wadir/mime.types" >> $cfile
+       echo "addtype_cgi=internal/cgi" >> $cfile
+       echo "realm=Webmin Server" >> $cfile
+       echo "logfile=$var_dir/miniserv.log" >> $cfile
+       echo "errorlog=$var_dir/miniserv.error" >> $cfile
+       echo "pidfile=$pidfile" >> $cfile
+       echo "logtime=168" >> $cfile
+       echo "ppath=$ppath" >> $cfile
+       echo "ssl=$ssl" >> $cfile
+       echo "no_ssl2=$no_ssl2" >> $cfile
+       echo "no_ssl3=$no_ssl3" >> $cfile
+       echo "ssl_redirect=$ssl_redirect" >> $cfile
+       echo "ssl_honorcipherorder=$ssl_honorcipherorder" >> $cfile
+       echo "no_sslcompression=$no_sslcompression" >> $cfile
+       echo "no_tls1=$no_tls1" >> $cfile
+       echo "no_tls1_1=$no_tls1_1" >> $cfile
+       echo "keyfile=$keyfile" >> $cfile
+       echo "env_WEBMIN_CONFIG=$config_dir" >> $cfile
+       echo "env_WEBMIN_VAR=$var_dir" >> $cfile
+       echo "atboot=$atboot" >> $cfile
+       echo "logout=$config_dir/logout-flag" >> $cfile
+       echo "listen=10000" >> $cfile
+       echo "denyfile=\\.pl\$" >> $cfile
+       echo "log=1" >> $cfile
+       echo "blockhost_failures=5" >> $cfile
+       echo "blockhost_time=60" >> $cfile
+       echo "syslog=1" >> $cfile
+       echo "session=1" >> $cfile
+       echo "premodules=WebminCore" >> $cfile
+       echo "server=MiniServ/$ver" >> $cfile
+
+       # Append package-specific info to config file.
+       # miniserv-conf can be created by upstream or by us in src_install phase (see there).
+       if [ -f "$wadir/miniserv-conf" ]; then
+               cat "$wadir/miniserv-conf" >>$cfile
+       fi
+
+       # Create the default user allowed to login - root only
+       login="root"
+
+       if [ -r /etc/shadow ]; then
+               #crypt=`grep "^root:" /etc/shadow | cut -f 2 -d :`
+               crypt=x
+       else
+               crypt=`grep "^root:" /etc/passwd | cut -f 2 -d :`
+       fi
+
+       ufile=$config_dir/miniserv.users
+       echo "$login:$crypt:0" > $ufile
+       chmod 600 $ufile
+
+
+       echo "userfile=$ufile" >> $cfile
+       chmod 600 $cfile
+       echo "..done"
+       echo ""
+
+       echo "Creating access control file.."
+       afile=$config_dir/webmin.acl
+       echo "$login: $allmods" > $afile
+       chmod 600 $afile
+       echo "..done"
+       echo ""
+fi
+
+
+# Create start, stop, restart and reload Gentoo compliant Webmin scripts
+# We use sys-apps/openrc functions which is already pulled by sys-apps/baselayout
+# or systemctl if we run under systemd
+echo "Creating start and stop scripts.."
+rm -f $config_dir/{start,stop,restart,reload}
+
+# The start script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/start"
+#!/bin/sh
+
+if [ ! -f "${pidfile}" ]; then
+       if [[ -d /run/systemd/system ]] ; then
+               systemctl start webmin.service
+       else
+               rc-service --ifexists -- webmin start
+       fi
+fi
+END
+
+# The stop script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/stop"
+#!/bin/sh
+
+if [[ -d /run/systemd/system ]] ; then
+       systemctl stop webmin.service
+else
+       rc-service --ifexists -- webmin --ifstarted stop
+fi
+END
+
+# The restart script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/restart"
+#!/bin/sh
+
+if [[ -d /run/systemd/system ]] ; then
+       systemctl try-restart webmin.service
+else
+       rc-service --ifexists -- webmin --ifstarted restart
+fi
+END
+
+# The reload script in /etc/webmin (Gentoo compliant)
+cat <<END >>"$config_dir/reload"
+#!/bin/sh
+
+if [[ -d /run/systemd/system ]] ; then
+       systemctl reload-or-try-restart webmin.service
+else
+       rc-service --ifexists -- webmin --ifstarted reload
+fi
+END
+
+chmod 755 $config_dir/{start,stop,restart,reload}
+echo "..done"
+echo ""
+
+
+if [ "$upgrading" = 1 ]; then
+       echo "Updating other config files.."
+else
+       echo "Copying other config files.."
+fi
+
+# This just copies and merges the Webmin's release config files, with user's in the /etc/webmin folder
+newmods=`$perl "$wadir/copyconfig.pl" "$os_type/$real_os_type" "$os_version/$real_os_version" "$wadir" $config_dir "" $allmods`
+if [ "$upgrading" != 1 ]; then
+       # Store the OS and version
+       echo "os_type=$os_type" >> $config_dir/config
+       echo "os_version=$os_version" >> $config_dir/config
+       echo "real_os_type=$real_os_type" >> $config_dir/config
+       echo "real_os_version=$real_os_version" >> $config_dir/config
+
+       # Turn on logging by default
+       echo "log=1" >> $config_dir/config
+
+       # Disallow unknown referers by default
+       echo "referers_none=1" >>$config_dir/config
+else
+       # one-off hack to set log variable in config from miniserv.conf
+       grep log= $config_dir/config >/dev/null
+       if [ "$?" = "1" ]; then
+               grep log= $config_dir/miniserv.conf >> $config_dir/config
+               grep logtime= $config_dir/miniserv.conf >> $config_dir/config
+               grep logclear= $config_dir/miniserv.conf >> $config_dir/config
+       fi
+
+       # Disallow unknown referers if not set
+       grep referers_none= $config_dir/config >/dev/null
+       if [ "$?" != "0" ]; then
+               echo "referers_none=1" >>$config_dir/config
+       fi
+fi
+echo $ver > $config_dir/version
+echo "..done"
+echo ""
+
+# Set passwd_ fields in miniserv.conf from global config
+for field in passwd_file passwd_uindex passwd_pindex passwd_cindex passwd_mindex; do
+       grep $field= $config_dir/miniserv.conf >/dev/null
+       if [ "$?" != "0" ]; then
+               grep $field= $config_dir/config >> $config_dir/miniserv.conf
+       fi
+done
+grep passwd_mode= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo passwd_mode=0 >> $config_dir/miniserv.conf
+fi
+
+grep ssl_honorcipherorder= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo ssl_honorcipherorder=1 >> $config_dir/miniserv.conf
+fi
+
+# Disable SSL compression to defeat BEAST attack
+grep no_sslcompression= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo no_sslcompression=1 >> $config_dir/miniserv.conf
+fi
+
+# Tighten SSL security
+grep no_ssl2= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo no_ssl2=1 >> $config_dir/miniserv.conf
+fi
+
+grep no_ssl3= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo no_ssl3=1 >> $config_dir/miniserv.conf
+fi
+
+grep no_tls1= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+    echo no_tls1=1 >> $config_dir/miniserv.conf
+fi
+
+grep no_tls1_1= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+    echo no_tls1_1=1 >> $config_dir/miniserv.conf
+fi
+
+# Make Perl crypt MD5 the default
+grep md5pass= $config_dir/config >/dev/null
+if [ "$?" != "0" ]; then
+       echo md5pass=1 >> $config_dir/config
+fi
+
+# Set a special theme if none was set before
+if [ "$theme" = "" ]; then
+       theme=`cat "$wadir/defaulttheme" 2>/dev/null`
+fi
+oldthemeline=`grep "^theme=" $config_dir/config`
+oldtheme=`echo $oldthemeline | sed -e 's/theme=//g'`
+if [ "$theme" != "" ] && [ "$oldthemeline" = "" ] && [ -d "$wadir/$theme" ]; then
+       themelist=$theme
+fi
+
+# Set a special overlay if none was set before
+if [ "$overlay" = "" ]; then
+       overlay=`cat "$wadir/defaultoverlay" 2>/dev/null`
+fi
+if [ "$overlay" != "" ] && [ "$theme" != "" ] && [ -d "$wadir/$overlay" ]; then
+       themelist="$themelist $overlay"
+fi
+
+# Apply the theme and maybe overlay
+if [ "$themelist" != "" ]; then
+       echo "theme=$themelist" >> $config_dir/config
+       echo "preroot=$themelist" >> $config_dir/miniserv.conf
+fi
+
+# If the old blue-theme is still in use, change it (new in 1.730)
+oldtheme=`grep "^theme=" $config_dir/config | sed -e 's/theme=//g'`
+if [ "$oldtheme" = "blue-theme" ]; then
+   sed -i -e 's/theme=blue-theme/theme=gray-theme/g' $config_dir/config
+   sed -i -e 's/preroot=blue-theme/preroot=gray-theme/g' $config_dir/miniserv.conf
+fi
+
+# Set the product field in the global config
+grep product= $config_dir/config >/dev/null
+if [ "$?" != "0" ]; then
+       echo product=webmin >> $config_dir/config
+fi
+
+# If password delays are not specifically disabled, enable them
+grep passdelay= $config_dir/miniserv.conf >/dev/null
+if [ "$?" != "0" ]; then
+       echo passdelay=1 >> $config_dir/miniserv.conf
+fi
+
+
+echo "Changing ownership and permissions.."
+# Make all config dirs non-world-readable
+for m in $newmods; do
+       chown -R root:root $config_dir/$m
+       chmod -R og-rw $config_dir/$m
+done
+
+# Make miniserv config files non-world-readable
+for f in miniserv.conf miniserv.users; do
+       chown -R root:root $config_dir/$f
+       chmod -R og-rw $config_dir/$f
+done
+chmod +r $config_dir/version
+
+# Fix up bad permissions from some older installs
+for m in ldap-client ldap-server ldap-useradmin mailboxes mysql postgresql servers virtual-server; do
+       if [ -d "$config_dir/$m" ]; then
+               chown root:root $config_dir/$m
+               chmod og-rw $config_dir/$m
+               chmod og-rw $config_dir/$m/config 2>/dev/null
+       fi
+done
+echo "..done"
+echo ""
+
+
+# This executes all postinstall.pl for every module
+# If you do bump, you should look at the specific changes they do with this command in root folder:
+# find . -name postinstall.pl -exec cat {} \; -print
+# Generally they are safe to run 'cause they change only user's config in /etc/webmin
+# or setup some cron jobs
+if [ "$nopostinstall" = "" ]; then
+       echo "Running postinstall scripts.. (Please ignore any possible errors)"
+       (cd "$wadir" ; WEBMIN_CONFIG=$config_dir WEBMIN_VAR=$var_dir "$wadir/run-postinstalls.pl")
+       echo "..done"
+       echo ""
+fi
+
+# Enable background collection
+if [ "$upgrading" != 1 -a -r $config_dir/system-status/enable-collection.pl ]; then
+       echo "Enabling background status collection.. (Please ignore any possible errors)"
+       $config_dir/system-status/enable-collection.pl 5
+       echo "..done"
+       echo ""
+fi
diff --git a/app-admin/webmin/files/init.d.webmin b/app-admin/webmin/files/init.d.webmin
new file mode 100644 (file)
index 0000000..f32a01d
--- /dev/null
@@ -0,0 +1,88 @@
+#!/sbin/openrc-run
+# Copyright 1999-2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+
+# We do not give a choice to user for configuring these 'cause it will mess up
+# Webmin's configuration
+WEBMIN_EXE="%exe%"
+WEBMIN_PID="%pid%"
+WEBMIN_CONF="%conf%"
+WEBMIN_CONFIG="%config%"
+MYPORT="`grep port /etc/webmin/miniserv.conf | cut -c6-`"
+extra_started_commands="reload"
+
+depend() {
+       use net logger
+}
+
+checkconfig() {
+       # Check if Webmin setup has been done
+       if [ ! -f ${WEBMIN_CONFIG} ]; then
+               eerror "Error in Webmin's configuration. The ${WEBMIN_CONFIG} is not present."
+               eerror "Please run 'emerge --config app-admin/webmin' to fix this."
+               return 1
+       fi
+
+       # Check if ssl cert is present
+       local key ssl
+       key=`grep "^keyfile=" ${WEBMIN_CONF} | sed -e 's/keyfile=//g'`
+       ssl=`grep "^ssl=" ${WEBMIN_CONF} | sed -e 's/ssl=//g'`
+
+       if [ ! -f "${key}" ] ; then
+               if [ "${ssl}" = "0" ]; then
+                       ewarn "Your SSL certificate is not present."
+                       ewarn "Please either fix the path in the 'keyfile=' option of your ${WEBMIN_CONF}"
+                       ewarn "OR run 'emerge --config app-admin/webmin'"
+               else
+                       eerror "Error in Webmin's configuration. No SSL certificate is present."
+                       eerror "Please either fix the path in the 'keyfile=' option of your ${WEBMIN_CONF}"
+                       eerror "OR change the 'ssl=' option of your ${WEBMIN_CONF} to 'ssl=0'"
+                       eerror "OR run 'emerge --config app-admin/webmin'"
+                       return 1
+               fi
+       fi
+
+       return 0
+}
+
+reload() {
+       if [ ! -f "${WEBMIN_PID}" ]; then
+               eerror "Webmin is not running"
+               return 1
+       fi
+
+       checkconfig || return 1
+
+       ebegin "Reloading Webmin's configuration files"
+       start-stop-daemon --signal USR1 --pidfile "$WEBMIN_PID"
+       eend $?
+}
+
+start() {
+       checkconfig || return 1
+       ebegin "Starting Webmin"
+
+       start-stop-daemon --start --background --interpreted \
+               --env LANG= \
+               --env PERLLIB="%perllib%" \
+               --exec "$WEBMIN_EXE" \
+               --pidfile "$WEBMIN_PID" \
+               -- "$WEBMIN_CONF"
+       eend $?
+       # Leave time to spawn, so no stop is received while spawning
+       sleep 3
+       einfo "Webin is reachable under"
+       einfo "https://127.0.0.1:$MYPORT"
+}
+
+stop() {
+       ebegin "Stopping Webmin"
+       start-stop-daemon --stop  --interpreted --quiet \
+               --exec "$WEBMIN_EXE" \
+               --pidfile "$WEBMIN_PID"
+       eend $?
+       # Leave time to stop because of the scripts that use this
+       sleep 3
+}
+
diff --git a/app-admin/webmin/files/webmin.service b/app-admin/webmin/files/webmin.service
new file mode 100644 (file)
index 0000000..5bec85b
--- /dev/null
@@ -0,0 +1,18 @@
+[Unit]
+Description=Webmin Administration Tool
+After=network.target remote-fs.target nss-lookup.target
+ConditionFileNotEmpty=%config%
+ConditionFileNotEmpty=%conf%
+
+[Service]
+RemainAfterExit=yes
+KillMode=mixed
+# Webmin is exiting with 1 on SIGTERM
+SuccessExitStatus=1
+ExecStart=%exe% %conf%
+PIDFile=%pid%
+Environment="PERLLIB=%perllib%" LANG= 
+ExecReload=/bin/kill -USR1 $MAINPID
+
+[Install]
+WantedBy=multi-user.target
diff --git a/app-admin/webmin/webmin-1.881.ebuild b/app-admin/webmin/webmin-1.881.ebuild
new file mode 100644 (file)
index 0000000..2d44a52
--- /dev/null
@@ -0,0 +1,314 @@
+# Copyright 1999-2018 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+inherit pam ssl-cert systemd
+
+DESCRIPTION="A web-based Unix systems administration interface"
+HOMEPAGE="http://www.webmin.com/"
+SRC_URI="minimal? ( mirror://sourceforge/webadmin/${P}-minimal.tar.gz )
+       !minimal? ( mirror://sourceforge/webadmin/${P}.tar.gz )"
+
+LICENSE="BSD GPL-2"
+SLOT="0"
+
+KEYWORDS="~amd64 ~x86"
+
+# NOTE: The ssl flag auto added by ssl-cert eclass is not used actually
+# because openssl is forced by dev-perl/Net-SSLeay
+IUSE="minimal +ssl mysql postgres ldap"
+REQUIRED_USE="minimal? ( !mysql !postgres !ldap )"
+
+# All the required perl modules can be found easily using (in Webmin's root src dir):
+# find . -name cpan_modules.pl -exec grep "::" {} \;
+# NOTE: If Webmin doesn't find the required perl modules, it offers(runtime) the user
+# to install them using the in-built cpan module, and this will mess up perl on the system
+# That's why some modules are forced without a use flag
+# NOTE: pam, ssl and dnssec-tools deps are forced for security and Gentoo compliance installation reasons
+DEPEND="virtual/perl-MIME-Base64
+       virtual/perl-Socket
+       virtual/perl-Sys-Syslog
+       virtual/perl-Time-HiRes
+       virtual/perl-Time-Local
+       dev-perl/Authen-Libwrap
+       dev-perl/IO-Tty
+       dev-perl/MD5
+       dev-perl/Net-SSLeay
+       dev-perl/Authen-PAM
+       dev-perl/Sys-Hostname-Long
+       >=net-dns/dnssec-tools-1.13
+       !minimal? (
+               mysql? ( dev-perl/DBD-mysql )
+               postgres? ( dev-perl/DBD-Pg )
+               ldap? ( dev-perl/perl-ldap )
+               dev-perl/XML-Generator
+               dev-perl/XML-Parser
+       )
+"
+RDEPEND="${DEPEND}"
+
+src_prepare() {
+       default
+
+       local perl="$( which perl )"
+
+       # Remove the unnecessary and incompatible files
+       rm -rf acl/Authen-SolarisRBAC-0.1*
+       if ! use minimal ; then
+               rm -rf {format,{bsd,hpux,sgi}exports,zones,rbac}
+               rm -f mount/{free,net,open}bsd-mounts*
+               rm -f mount/macos-mounts*
+       fi
+
+       # For security reasons remove the SSL certificate that comes with Webmin
+       # We will create our own later
+       rm -f miniserv.pem
+
+       # Remove the Webmin setup scripts to avoid Webmin in runtime to mess up config
+       # We will use our own later
+       rm -f setup.{sh,pl}
+
+       # Set the installation type/mode to Gentoo
+       echo "gentoo" > install-type
+
+       # Fix the permissions of the install files
+       chmod -R og-w "${S}"
+
+       # Since we should not modify any files after install
+       # we set the perl path in all cgi and pl files here using Webmin's routines
+       # The pl file is Prefix safe and works only on provided input, no other filesystem files
+       ebegin "Fixing perl path in source files"
+       (find "${S}" -name '*.cgi' -print ; find "${S}" -name '*.pl' -print) | $perl "${S}"/perlpath.pl $perl -
+       eend $?
+}
+
+src_install() {
+       # Create config dir and keep
+       diropts -m0755
+       dodir /etc/webmin
+       keepdir /etc/webmin
+
+       # Create install dir
+       # Third party modules installed through Webmin go here too, so keep
+       dodir /usr/libexec/webmin
+       keepdir /usr/libexec/webmin
+
+       # Copy our own setup script to installation folder
+       insinto /usr/libexec/webmin
+       newins "${FILESDIR}"/gentoo-setup gentoo-setup.sh
+       fperms 0744 /usr/libexec/webmin/gentoo-setup.sh
+
+       # This is here if we ever want in future ebuilds to add some specific
+       # config values in the /etc/webmin/miniserv.conf
+       # The format of this file should be the same as the one of miniserv.conf:
+       # var=value
+       #
+       # Uncomment it if you use such file. Before that check if upstream
+       # has this file in root dir too.
+       #newins "${FILESDIR}/miniserv-conf" miniserv-conf
+
+       # Create the log dir and keep
+       diropts -m0700
+       dodir /var/log/webmin
+       keepdir /var/log/webmin
+
+       # Create the init.d file and put the neccessary variables there
+       newinitd "${FILESDIR}"/init.d.webmin webmin
+       sed -i \
+               -e "s:%exe%:${EROOT}usr/libexec/webmin/miniserv.pl:" \
+               -e "s:%pid%:${EROOT}var/run/webmin.pid:" \
+               -e "s:%conf%:${EROOT}etc/webmin/miniserv.conf:" \
+               -e "s:%config%:${EROOT}etc/webmin/config:" \
+               -e "s:%perllib%:${EROOT}usr/libexec/webmin:" \
+               "${ED}/etc/init.d/webmin" \
+               || die "Failed to patch the webmin init file"
+
+       # Create the systemd service file and put the neccessary variables there
+       systemd_newunit "${FILESDIR}"/webmin.service webmin.service
+       sed -i \
+               -e "s:%exe%:${EROOT}usr/libexec/webmin/miniserv.pl:" \
+               -e "s:%pid%:${EROOT}var/run/webmin.pid:" \
+               -e "s:%conf%:${EROOT}etc/webmin/miniserv.conf:" \
+               -e "s:%config%:${EROOT}etc/webmin/config:" \
+               -e "s:%perllib%:${EROOT}usr/libexec/webmin:" \
+               "${ED}/$(_systemd_get_systemunitdir)/webmin.service" \
+               || die "Failed to patch the webmin systemd service file"
+
+       # Setup pam
+       pamd_mimic system-auth webmin auth account session
+
+       # Copy files to installation folder
+       ebegin "Copying install files to destination"
+       cp -pPR "${S}"/* "${ED}/usr/libexec/webmin"
+       eend $?
+}
+
+pkg_preinst() {
+       # First stop service if running so Webmin to not messup our config
+       ebegin "Stopping any running Webmin instance prior merging"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+}
+
+pkg_postinst() {
+       # Run webmin_config first - non interactively
+       export INTERACTIVE="no"
+       webmin_config
+       # Every next time webmin_config should be interactive
+       INTERACTIVE="yes"
+
+       ewarn
+       ewarn "Bare in mind that not all Webmin modules are Gentoo tweaked and may have some issues."
+       ewarn "Always be careful when using modules that modify init entries, do update of webmin, install CPAN modules etc."
+       ewarn "To avoid problems, please before using any module, look at its configuration options first."
+       ewarn "(Usually there is a link at top in the right pane of Webmin for configuring the module.)"
+       ewarn
+       if systemd_is_booted ; then
+               elog "- To make Webmin start at boot time, run: 'systemctl enable webmin.service'"
+       else
+               elog "- To make Webmin start at boot time, run: 'rc-update add webmin default'"
+       fi
+       elog "- The default URL to connect to Webmin is: https://localhost:10000"
+       elog "- The default user that can login is: root"
+       elog "- To reconfigure Webmin in case of problems run 'emerge --config app-admin/webmin'"
+}
+
+pkg_prerm() {
+       # First stop service if running - we do not want Webmin to mess up config
+       ebegin "Stopping any running Webmin instance prior unmerging"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+}
+
+pkg_postrm() {
+       # If removing webmin completely, remind the user for the Webmin's own cron jobs.
+       if [[ ! ${REPLACED_BY_VERSION} ]]; then
+               ewarn
+               ewarn "You have uninstalled Webmin, so have in mind that all cron jobs scheduled"
+               ewarn "by Webmin for its own modules, are left active and they will fail when Webmin is missing."
+               ewarn "To fix this just disable them if you intend to use Webmin again,"
+               ewarn "OR delete them if not."
+               ewarn
+       fi
+}
+
+pkg_config(){
+       webmin_config
+}
+
+webmin_config(){
+       # First stop service if running
+       ebegin "Stopping any running Webmin instance"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+
+       # Next set the default reset variable to 'none'
+       # reset/_reset can be:
+       # 'none' - does not reset anything, just upgrades if a conf is present
+       #                  OR installs new conf if a conf is missing
+       # 'soft' - deletes only $config_dir/config file and thus resetting most
+       #                 conf values to their defaults. Keeps the specific Webmin cron jobs
+       # 'hard' - deletes all files in $config_dir (keeping the .keep_* Gentoo file)
+       #                 and thus resetting all Webmin. Deletes the specific Webmin cron jobs too.
+       local _reset="none"
+
+       # If in interactive mode ask user what should we do
+       if [[ "${INTERACTIVE}" = "yes" ]]; then
+               einfo
+               einfo "Please enter the number of the action you would like to perform?"
+               einfo
+               einfo "1. Update configuration"
+               einfo "   (keeps old config options and adds the new ones)"
+               einfo "2. Soft reset configuration"
+               einfo "   (keeps some old config options, the other options are set to default)"
+               ewarn "   All Webmin users will be reset"
+               einfo "3. Hard reset configuration"
+               einfo "   (all options including module options are set to default)"
+               ewarn "   You will lose all Webmin configuration options you have done till now"
+               einfo "4. Exit this configuration utility (default)"
+               while [ "$correct" != "true" ] ; do
+                       read answer
+                       if [[ "$answer" = "1" ]] ; then
+                               _reset="none"
+                               correct="true"
+                       elif [[ "$answer" = "2" ]] ; then
+                               _reset="soft"
+                               correct="true"
+                       elif  [[ "$answer" = "3" ]] ; then
+                               _reset="hard"
+                               correct="true"
+                       elif  [ "$answer" = "4" -o "$answer" = "" ] ; then
+                               die "User aborted configuration."
+                       else
+                               echo "Answer not recognized. Enter a number from 1 to 4"
+                       fi
+               done
+
+               if [[ "$_reset" = "hard" ]]; then
+                       while [ "$sure" != "true" ] ; do
+                               ewarn "You will lose all Webmin configuration options you have done till now."
+                               ewarn "Are you sure you want to do this? (y/n)"
+                               read answer
+                               if [[ $answer =~ ^[Yy]([Ee][Ss])?$ ]] ; then
+                                       sure="true"
+                               elif [[ $answer =~ ^[Nn]([Oo])?$ ]] ; then
+                                       die "User aborted configuration."
+                               else
+                                       echo "Answer not recognized. Enter 'y' or 'n'"
+                               fi
+                       done
+               fi
+       fi
+
+       export reset=$_reset
+
+       # Create ssl certificate for Webmin if there is not one in the proper place
+       if [[ ! -e "${EROOT}etc/ssl/webmin/server.pem" ]]; then
+               SSL_ORGANIZATION="${SSL_ORGANIZATION:-Webmin Server}"
+               SSL_COMMONNAME="${SSL_COMMONNAME:-*}"
+               install_cert "${EROOT}/etc/ssl/webmin/server"
+       fi
+
+       # Ensure all paths passed to the setup script use EROOT
+       export wadir="${EROOT}usr/libexec/webmin"
+       export config_dir="${EROOT}etc/webmin"
+       export var_dir="${EROOT}var/log/webmin"
+       export tempdir="${T}"
+       export pidfile="${EROOT}var/run/webmin.pid"
+       export perl="$( which perl )"
+       export os_type='gentoo-linux'
+       export os_version='*'
+       export real_os_type='Gentoo Linux'
+       export real_os_version='Any version'
+       # Forcing 'ssl', 'no_ssl2', 'no_ssl3', 'ssl_redirect', 'no_sslcompression',
+       # 'ssl_honorcipherorder', 'no_tls1' and 'no_tls1_1' for tightening security
+       export ssl=1
+       export no_ssl2=1
+       export no_ssl3=1
+       export ssl_redirect=1
+       export ssl_honorcipherorder=1
+       export no_sslcompression=1
+       export no_tls1=1
+       export no_tls1_1=1
+       export keyfile="${EROOT}etc/ssl/webmin/server.pem"
+       export port=10000
+
+       export atboot=0
+
+       einfo "Executing Webmin's configure script"
+       $wadir/gentoo-setup.sh
+
+       einfo "Configuration of Webmin done"
+}
diff --git a/app-admin/webmin/webmin-1.974.ebuild b/app-admin/webmin/webmin-1.974.ebuild
new file mode 100644 (file)
index 0000000..2d44a52
--- /dev/null
@@ -0,0 +1,314 @@
+# Copyright 1999-2018 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+inherit pam ssl-cert systemd
+
+DESCRIPTION="A web-based Unix systems administration interface"
+HOMEPAGE="http://www.webmin.com/"
+SRC_URI="minimal? ( mirror://sourceforge/webadmin/${P}-minimal.tar.gz )
+       !minimal? ( mirror://sourceforge/webadmin/${P}.tar.gz )"
+
+LICENSE="BSD GPL-2"
+SLOT="0"
+
+KEYWORDS="~amd64 ~x86"
+
+# NOTE: The ssl flag auto added by ssl-cert eclass is not used actually
+# because openssl is forced by dev-perl/Net-SSLeay
+IUSE="minimal +ssl mysql postgres ldap"
+REQUIRED_USE="minimal? ( !mysql !postgres !ldap )"
+
+# All the required perl modules can be found easily using (in Webmin's root src dir):
+# find . -name cpan_modules.pl -exec grep "::" {} \;
+# NOTE: If Webmin doesn't find the required perl modules, it offers(runtime) the user
+# to install them using the in-built cpan module, and this will mess up perl on the system
+# That's why some modules are forced without a use flag
+# NOTE: pam, ssl and dnssec-tools deps are forced for security and Gentoo compliance installation reasons
+DEPEND="virtual/perl-MIME-Base64
+       virtual/perl-Socket
+       virtual/perl-Sys-Syslog
+       virtual/perl-Time-HiRes
+       virtual/perl-Time-Local
+       dev-perl/Authen-Libwrap
+       dev-perl/IO-Tty
+       dev-perl/MD5
+       dev-perl/Net-SSLeay
+       dev-perl/Authen-PAM
+       dev-perl/Sys-Hostname-Long
+       >=net-dns/dnssec-tools-1.13
+       !minimal? (
+               mysql? ( dev-perl/DBD-mysql )
+               postgres? ( dev-perl/DBD-Pg )
+               ldap? ( dev-perl/perl-ldap )
+               dev-perl/XML-Generator
+               dev-perl/XML-Parser
+       )
+"
+RDEPEND="${DEPEND}"
+
+src_prepare() {
+       default
+
+       local perl="$( which perl )"
+
+       # Remove the unnecessary and incompatible files
+       rm -rf acl/Authen-SolarisRBAC-0.1*
+       if ! use minimal ; then
+               rm -rf {format,{bsd,hpux,sgi}exports,zones,rbac}
+               rm -f mount/{free,net,open}bsd-mounts*
+               rm -f mount/macos-mounts*
+       fi
+
+       # For security reasons remove the SSL certificate that comes with Webmin
+       # We will create our own later
+       rm -f miniserv.pem
+
+       # Remove the Webmin setup scripts to avoid Webmin in runtime to mess up config
+       # We will use our own later
+       rm -f setup.{sh,pl}
+
+       # Set the installation type/mode to Gentoo
+       echo "gentoo" > install-type
+
+       # Fix the permissions of the install files
+       chmod -R og-w "${S}"
+
+       # Since we should not modify any files after install
+       # we set the perl path in all cgi and pl files here using Webmin's routines
+       # The pl file is Prefix safe and works only on provided input, no other filesystem files
+       ebegin "Fixing perl path in source files"
+       (find "${S}" -name '*.cgi' -print ; find "${S}" -name '*.pl' -print) | $perl "${S}"/perlpath.pl $perl -
+       eend $?
+}
+
+src_install() {
+       # Create config dir and keep
+       diropts -m0755
+       dodir /etc/webmin
+       keepdir /etc/webmin
+
+       # Create install dir
+       # Third party modules installed through Webmin go here too, so keep
+       dodir /usr/libexec/webmin
+       keepdir /usr/libexec/webmin
+
+       # Copy our own setup script to installation folder
+       insinto /usr/libexec/webmin
+       newins "${FILESDIR}"/gentoo-setup gentoo-setup.sh
+       fperms 0744 /usr/libexec/webmin/gentoo-setup.sh
+
+       # This is here if we ever want in future ebuilds to add some specific
+       # config values in the /etc/webmin/miniserv.conf
+       # The format of this file should be the same as the one of miniserv.conf:
+       # var=value
+       #
+       # Uncomment it if you use such file. Before that check if upstream
+       # has this file in root dir too.
+       #newins "${FILESDIR}/miniserv-conf" miniserv-conf
+
+       # Create the log dir and keep
+       diropts -m0700
+       dodir /var/log/webmin
+       keepdir /var/log/webmin
+
+       # Create the init.d file and put the neccessary variables there
+       newinitd "${FILESDIR}"/init.d.webmin webmin
+       sed -i \
+               -e "s:%exe%:${EROOT}usr/libexec/webmin/miniserv.pl:" \
+               -e "s:%pid%:${EROOT}var/run/webmin.pid:" \
+               -e "s:%conf%:${EROOT}etc/webmin/miniserv.conf:" \
+               -e "s:%config%:${EROOT}etc/webmin/config:" \
+               -e "s:%perllib%:${EROOT}usr/libexec/webmin:" \
+               "${ED}/etc/init.d/webmin" \
+               || die "Failed to patch the webmin init file"
+
+       # Create the systemd service file and put the neccessary variables there
+       systemd_newunit "${FILESDIR}"/webmin.service webmin.service
+       sed -i \
+               -e "s:%exe%:${EROOT}usr/libexec/webmin/miniserv.pl:" \
+               -e "s:%pid%:${EROOT}var/run/webmin.pid:" \
+               -e "s:%conf%:${EROOT}etc/webmin/miniserv.conf:" \
+               -e "s:%config%:${EROOT}etc/webmin/config:" \
+               -e "s:%perllib%:${EROOT}usr/libexec/webmin:" \
+               "${ED}/$(_systemd_get_systemunitdir)/webmin.service" \
+               || die "Failed to patch the webmin systemd service file"
+
+       # Setup pam
+       pamd_mimic system-auth webmin auth account session
+
+       # Copy files to installation folder
+       ebegin "Copying install files to destination"
+       cp -pPR "${S}"/* "${ED}/usr/libexec/webmin"
+       eend $?
+}
+
+pkg_preinst() {
+       # First stop service if running so Webmin to not messup our config
+       ebegin "Stopping any running Webmin instance prior merging"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+}
+
+pkg_postinst() {
+       # Run webmin_config first - non interactively
+       export INTERACTIVE="no"
+       webmin_config
+       # Every next time webmin_config should be interactive
+       INTERACTIVE="yes"
+
+       ewarn
+       ewarn "Bare in mind that not all Webmin modules are Gentoo tweaked and may have some issues."
+       ewarn "Always be careful when using modules that modify init entries, do update of webmin, install CPAN modules etc."
+       ewarn "To avoid problems, please before using any module, look at its configuration options first."
+       ewarn "(Usually there is a link at top in the right pane of Webmin for configuring the module.)"
+       ewarn
+       if systemd_is_booted ; then
+               elog "- To make Webmin start at boot time, run: 'systemctl enable webmin.service'"
+       else
+               elog "- To make Webmin start at boot time, run: 'rc-update add webmin default'"
+       fi
+       elog "- The default URL to connect to Webmin is: https://localhost:10000"
+       elog "- The default user that can login is: root"
+       elog "- To reconfigure Webmin in case of problems run 'emerge --config app-admin/webmin'"
+}
+
+pkg_prerm() {
+       # First stop service if running - we do not want Webmin to mess up config
+       ebegin "Stopping any running Webmin instance prior unmerging"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+}
+
+pkg_postrm() {
+       # If removing webmin completely, remind the user for the Webmin's own cron jobs.
+       if [[ ! ${REPLACED_BY_VERSION} ]]; then
+               ewarn
+               ewarn "You have uninstalled Webmin, so have in mind that all cron jobs scheduled"
+               ewarn "by Webmin for its own modules, are left active and they will fail when Webmin is missing."
+               ewarn "To fix this just disable them if you intend to use Webmin again,"
+               ewarn "OR delete them if not."
+               ewarn
+       fi
+}
+
+pkg_config(){
+       webmin_config
+}
+
+webmin_config(){
+       # First stop service if running
+       ebegin "Stopping any running Webmin instance"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+
+       # Next set the default reset variable to 'none'
+       # reset/_reset can be:
+       # 'none' - does not reset anything, just upgrades if a conf is present
+       #                  OR installs new conf if a conf is missing
+       # 'soft' - deletes only $config_dir/config file and thus resetting most
+       #                 conf values to their defaults. Keeps the specific Webmin cron jobs
+       # 'hard' - deletes all files in $config_dir (keeping the .keep_* Gentoo file)
+       #                 and thus resetting all Webmin. Deletes the specific Webmin cron jobs too.
+       local _reset="none"
+
+       # If in interactive mode ask user what should we do
+       if [[ "${INTERACTIVE}" = "yes" ]]; then
+               einfo
+               einfo "Please enter the number of the action you would like to perform?"
+               einfo
+               einfo "1. Update configuration"
+               einfo "   (keeps old config options and adds the new ones)"
+               einfo "2. Soft reset configuration"
+               einfo "   (keeps some old config options, the other options are set to default)"
+               ewarn "   All Webmin users will be reset"
+               einfo "3. Hard reset configuration"
+               einfo "   (all options including module options are set to default)"
+               ewarn "   You will lose all Webmin configuration options you have done till now"
+               einfo "4. Exit this configuration utility (default)"
+               while [ "$correct" != "true" ] ; do
+                       read answer
+                       if [[ "$answer" = "1" ]] ; then
+                               _reset="none"
+                               correct="true"
+                       elif [[ "$answer" = "2" ]] ; then
+                               _reset="soft"
+                               correct="true"
+                       elif  [[ "$answer" = "3" ]] ; then
+                               _reset="hard"
+                               correct="true"
+                       elif  [ "$answer" = "4" -o "$answer" = "" ] ; then
+                               die "User aborted configuration."
+                       else
+                               echo "Answer not recognized. Enter a number from 1 to 4"
+                       fi
+               done
+
+               if [[ "$_reset" = "hard" ]]; then
+                       while [ "$sure" != "true" ] ; do
+                               ewarn "You will lose all Webmin configuration options you have done till now."
+                               ewarn "Are you sure you want to do this? (y/n)"
+                               read answer
+                               if [[ $answer =~ ^[Yy]([Ee][Ss])?$ ]] ; then
+                                       sure="true"
+                               elif [[ $answer =~ ^[Nn]([Oo])?$ ]] ; then
+                                       die "User aborted configuration."
+                               else
+                                       echo "Answer not recognized. Enter 'y' or 'n'"
+                               fi
+                       done
+               fi
+       fi
+
+       export reset=$_reset
+
+       # Create ssl certificate for Webmin if there is not one in the proper place
+       if [[ ! -e "${EROOT}etc/ssl/webmin/server.pem" ]]; then
+               SSL_ORGANIZATION="${SSL_ORGANIZATION:-Webmin Server}"
+               SSL_COMMONNAME="${SSL_COMMONNAME:-*}"
+               install_cert "${EROOT}/etc/ssl/webmin/server"
+       fi
+
+       # Ensure all paths passed to the setup script use EROOT
+       export wadir="${EROOT}usr/libexec/webmin"
+       export config_dir="${EROOT}etc/webmin"
+       export var_dir="${EROOT}var/log/webmin"
+       export tempdir="${T}"
+       export pidfile="${EROOT}var/run/webmin.pid"
+       export perl="$( which perl )"
+       export os_type='gentoo-linux'
+       export os_version='*'
+       export real_os_type='Gentoo Linux'
+       export real_os_version='Any version'
+       # Forcing 'ssl', 'no_ssl2', 'no_ssl3', 'ssl_redirect', 'no_sslcompression',
+       # 'ssl_honorcipherorder', 'no_tls1' and 'no_tls1_1' for tightening security
+       export ssl=1
+       export no_ssl2=1
+       export no_ssl3=1
+       export ssl_redirect=1
+       export ssl_honorcipherorder=1
+       export no_sslcompression=1
+       export no_tls1=1
+       export no_tls1_1=1
+       export keyfile="${EROOT}etc/ssl/webmin/server.pem"
+       export port=10000
+
+       export atboot=0
+
+       einfo "Executing Webmin's configure script"
+       $wadir/gentoo-setup.sh
+
+       einfo "Configuration of Webmin done"
+}
diff --git a/app-admin/webmin/webmin-1.974.ebuild.old b/app-admin/webmin/webmin-1.974.ebuild.old
new file mode 100644 (file)
index 0000000..eeb9d84
--- /dev/null
@@ -0,0 +1,82 @@
+# Copyright 2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+inherit pam systemd
+
+DESCRIPTION="A web-based Unix systems administration interface"
+HOMEPAGE="http://www.webmin.com/"
+SRC_URI="minimal? ( mirror://sourceforge/webadmin/${P}-minimal.tar.gz )
+       !minimal? ( mirror://sourceforge/webadmin/${P}.tar.gz )"
+
+LICENSE="BSD GPL-2"
+SLOT="0"
+
+KEYWORDS="amd64 x86"
+
+IUSE="minimal mysql postgres ldap"
+REQUIRED_USE="minimal? ( !mysql !postgres !ldap )"
+
+# All the required perl modules can be found easily using (in Webmin's root src dir):
+# find . -name cpan_modules.pl -exec grep "::" {} \;
+# NOTE: If Webmin doesn't find the required perl modules, it offers(runtime) the user
+# to install them using the in-built cpan module, and this will mess up perl on the system
+# That's why some modules are forced without a use flag
+# NOTE: pam, ssl and dnssec-tools deps are forced for security and Gentoo compliance installation reasons
+DEPEND="virtual/perl-MIME-Base64
+       virtual/perl-Socket
+       virtual/perl-Sys-Syslog
+       virtual/perl-Time-HiRes
+       virtual/perl-Time-Local
+       dev-perl/Authen-Libwrap
+       dev-perl/IO-Tty
+       dev-perl/MD5
+       dev-perl/Net-SSLeay
+       dev-perl/Authen-PAM
+       dev-perl/Sys-Hostname-Long
+       >=net-dns/dnssec-tools-1.13
+       !minimal? (
+               mysql? ( dev-perl/DBD-mysql )
+               postgres? ( dev-perl/DBD-Pg )
+               ldap? ( dev-perl/perl-ldap )
+               dev-perl/XML-Generator
+               dev-perl/XML-Parser
+       )
+"
+RDEPEND="${DEPEND}"
+
+src_prepare() {
+       default
+
+       local perl="$( which perl )"
+
+       # Remove the unnecessary and incompatible files
+       rm -rf acl/Authen-SolarisRBAC-0.1*
+       if ! use minimal ; then
+               rm -rf {format,{bsd,hpux,sgi}exports,zones,rbac}
+               rm -f mount/{free,net,open}bsd-mounts*
+               rm -f mount/macos-mounts*
+       fi
+
+       # For security reasons remove the SSL certificate that comes with Webmin
+       # We will create our own later
+       rm -f miniserv.pem
+
+       # Remove the Webmin setup scripts to avoid Webmin in runtime to mess up config
+       # We will use our own later
+       rm -f setup.{sh,pl}
+
+       # Set the installation type/mode to Gentoo
+       echo "gentoo" > install-type
+
+       # Fix the permissions of the install files
+       chmod -R og-w "${S}"
+
+       # Since we should not modify any files after install
+       # we set the perl path in all cgi and pl files here using Webmin's routines
+       # The pl file is Prefix safe and works only on provided input, no other filesystem files
+       ebegin "Fixing perl path in source files"
+       (find "${S}" -name '*.cgi' -print ; find "${S}" -name '*.pl' -print) | $perl "${S}"/perlpath.pl $perl -
+       eend $?
+}
+
diff --git a/app-admin/webmin/webmin-2.105.ebuild b/app-admin/webmin/webmin-2.105.ebuild
new file mode 100644 (file)
index 0000000..ecf2b25
--- /dev/null
@@ -0,0 +1,304 @@
+# Copyright 1999-2018 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+inherit pam ssl-cert systemd
+
+DESCRIPTION="A web-based Unix systems administration interface"
+HOMEPAGE="http://www.webmin.com/"
+SRC_URI="minimal? ( https://github.com/webmin/webmin/releases/download/${PV}/${P}-minimal.tar.gz )
+       !minimal? ( https://github.com/webmin/webmin/releases/download/${PV}//${P}.tar.gz )"
+
+LICENSE="BSD GPL-2"
+SLOT="0"
+
+KEYWORDS="amd64 x86"
+
+# NOTE: The ssl flag auto added by ssl-cert eclass is not used actually
+# because openssl is forced by dev-perl/Net-SSLeay
+IUSE="minimal +ssl mysql postgres ldap"
+REQUIRED_USE="minimal? ( !mysql !postgres !ldap )"
+
+# All the required perl modules can be found easily using (in Webmin's root src dir):
+# find . -name cpan_modules.pl -exec grep "::" {} \;
+# NOTE: If Webmin doesn't find the required perl modules, it offers(runtime) the user
+# to install them using the in-built cpan module, and this will mess up perl on the system
+# That's why some modules are forced without a use flag
+# NOTE: pam, ssl and dnssec-tools deps are forced for security and Gentoo compliance installation reasons
+DEPEND="virtual/perl-MIME-Base64
+       virtual/perl-Socket
+       virtual/perl-Sys-Syslog
+       virtual/perl-Time-HiRes
+       virtual/perl-Time-Local
+       dev-perl/Authen-Libwrap
+       dev-perl/IO-Tty
+       dev-perl/MD5
+       dev-perl/Net-SSLeay
+       dev-perl/Authen-PAM
+       dev-perl/Sys-Hostname-Long
+       >=net-dns/dnssec-tools-1.13
+       !minimal? (
+               mysql? ( dev-perl/DBD-mysql )
+               postgres? ( dev-perl/DBD-Pg )
+               ldap? ( dev-perl/perl-ldap )
+               dev-perl/XML-Generator
+               dev-perl/XML-Parser
+       )
+"
+RDEPEND="${DEPEND}"
+
+src_prepare() {
+       default
+
+       local perl="$( which perl )"
+
+       # Remove the unnecessary and incompatible files
+       rm -rf acl/Authen-SolarisRBAC-0.1*
+       if ! use minimal ; then
+               rm -rf {format,{bsd,hpux,sgi}exports,zones,rbac}
+               rm -f mount/{free,net,open}bsd-mounts*
+               rm -f mount/macos-mounts*
+       fi
+
+       # For security reasons remove the SSL certificate that comes with Webmin
+       # We will create our own later
+       rm -f miniserv.pem
+
+       # Remove the Webmin setup scripts to avoid Webmin in runtime to mess up config
+       # We will use our own later
+       rm -f setup.{sh,pl}
+
+       # Set the installation type/mode to Gentoo
+       echo "gentoo" > install-type
+
+       # Fix the permissions of the install files
+       chmod -R og-w "${S}"
+
+       # Since we should not modify any files after install
+       # we set the perl path in all cgi and pl files here using Webmin's routines
+       # The pl file is Prefix safe and works only on provided input, no other filesystem files
+       ln -s image imageetc
+       ebegin "Fixing perl path in source files"
+       (find "${S}" -name '*.cgi' -print ; find "${S}" -name '*.pl' -print) | $perl "${S}"/perlpath.pl $perl -
+       eend $?
+}
+
+src_install() {
+       # Create config dir and keep
+       diropts -m0755
+       dodir /etc/webmin
+       keepdir /etc/webmin
+
+       # Create install dir
+       # Third party modules installed through Webmin go here too, so keep
+       dodir /usr/libexec/webmin
+       keepdir /usr/libexec/webmin
+
+       # Copy our own setup script to installation folder
+       insinto /usr/libexec/webmin
+       newins "${FILESDIR}"/gentoo-setup gentoo-setup.sh
+       fperms 0744 /usr/libexec/webmin/gentoo-setup.sh
+
+       # This is here if we ever want in future ebuilds to add some specific
+       # config values in the /etc/webmin/miniserv.conf
+       # The format of this file should be the same as the one of miniserv.conf:
+       # var=value
+       #
+       # Uncomment it if you use such file. Before that check if upstream
+       # has this file in root dir too.
+       #newins "${FILESDIR}/miniserv-conf" miniserv-conf
+
+       # Create the log dir and keep
+       diropts -m0700
+       dodir /var/log/webmin
+       keepdir /var/log/webmin
+
+       # Create the init.d file and put the neccessary variables there
+       newinitd "${FILESDIR}"/init.d.webmin webmin
+       sed -i \
+               -e "s:%exe%:${EROOT}/usr/libexec/webmin/miniserv.pl:" \
+               -e "s:%pid%:${EROOT}/var/run/webmin.pid:" \
+               -e "s:%conf%:${EROOT}/etc/webmin/miniserv.conf:" \
+               -e "s:%config%:${EROOT}/etc/webmin/config:" \
+               -e "s:%perllib%:${EROOT}/usr/libexec/webmin:" \
+               "${ED}/etc/init.d/webmin" \
+               || die "Failed to patch the webmin init file"
+
+       # Setup pam
+       pamd_mimic system-auth webmin auth account session
+
+       # Copy files to installation folder
+       ebegin "Copying install files to destination"
+       cp -pPR "${S}"/* "${ED}/usr/libexec/webmin"
+       eend $?
+}
+
+pkg_preinst() {
+       # First stop service if running so Webmin to not messup our config
+       ebegin "Stopping any running Webmin instance prior merging"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+}
+
+pkg_postinst() {
+       # Run webmin_config first - non interactively
+       export INTERACTIVE="no"
+       webmin_config
+       # Every next time webmin_config should be interactive
+       INTERACTIVE="yes"
+
+       ewarn
+       ewarn "Bare in mind that not all Webmin modules are Gentoo tweaked and may have some issues."
+       ewarn "Always be careful when using modules that modify init entries, do update of webmin, install CPAN modules etc."
+       ewarn "To avoid problems, please before using any module, look at its configuration options first."
+       ewarn "(Usually there is a link at top in the right pane of Webmin for configuring the module.)"
+       ewarn
+       if systemd_is_booted ; then
+               elog "- To make Webmin start at boot time, run: 'systemctl enable webmin.service'"
+       else
+               elog "- To make Webmin start at boot time, run: 'rc-update add webmin default'"
+       fi
+       elog "- The default URL to connect to Webmin is: https://localhost:10000"
+       elog "- The default user that can login is: root"
+       elog "- To reconfigure Webmin in case of problems run 'emerge --config app-admin/webmin'"
+}
+
+pkg_prerm() {
+       # First stop service if running - we do not want Webmin to mess up config
+       ebegin "Stopping any running Webmin instance prior unmerging"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+}
+
+pkg_postrm() {
+       # If removing webmin completely, remind the user for the Webmin's own cron jobs.
+       if [[ ! ${REPLACED_BY_VERSION} ]]; then
+               ewarn
+               ewarn "You have uninstalled Webmin, so have in mind that all cron jobs scheduled"
+               ewarn "by Webmin for its own modules, are left active and they will fail when Webmin is missing."
+               ewarn "To fix this just disable them if you intend to use Webmin again,"
+               ewarn "OR delete them if not."
+               ewarn
+       fi
+}
+
+pkg_config(){
+       webmin_config
+}
+
+webmin_config(){
+       # First stop service if running
+       ebegin "Stopping any running Webmin instance"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+
+       # Next set the default reset variable to 'none'
+       # reset/_reset can be:
+       # 'none' - does not reset anything, just upgrades if a conf is present
+       #                  OR installs new conf if a conf is missing
+       # 'soft' - deletes only $config_dir/config file and thus resetting most
+       #                 conf values to their defaults. Keeps the specific Webmin cron jobs
+       # 'hard' - deletes all files in $config_dir (keeping the .keep_* Gentoo file)
+       #                 and thus resetting all Webmin. Deletes the specific Webmin cron jobs too.
+       local _reset="none"
+
+       # If in interactive mode ask user what should we do
+       if [[ "${INTERACTIVE}" = "yes" ]]; then
+               einfo
+               einfo "Please enter the number of the action you would like to perform?"
+               einfo
+               einfo "1. Update configuration"
+               einfo "   (keeps old config options and adds the new ones)"
+               einfo "2. Soft reset configuration"
+               einfo "   (keeps some old config options, the other options are set to default)"
+               ewarn "   All Webmin users will be reset"
+               einfo "3. Hard reset configuration"
+               einfo "   (all options including module options are set to default)"
+               ewarn "   You will lose all Webmin configuration options you have done till now"
+               einfo "4. Exit this configuration utility (default)"
+               while [ "$correct" != "true" ] ; do
+                       read answer
+                       if [[ "$answer" = "1" ]] ; then
+                               _reset="none"
+                               correct="true"
+                       elif [[ "$answer" = "2" ]] ; then
+                               _reset="soft"
+                               correct="true"
+                       elif  [[ "$answer" = "3" ]] ; then
+                               _reset="hard"
+                               correct="true"
+                       elif  [ "$answer" = "4" -o "$answer" = "" ] ; then
+                               die "User aborted configuration."
+                       else
+                               echo "Answer not recognized. Enter a number from 1 to 4"
+                       fi
+               done
+
+               if [[ "$_reset" = "hard" ]]; then
+                       while [ "$sure" != "true" ] ; do
+                               ewarn "You will lose all Webmin configuration options you have done till now."
+                               ewarn "Are you sure you want to do this? (y/n)"
+                               read answer
+                               if [[ $answer =~ ^[Yy]([Ee][Ss])?$ ]] ; then
+                                       sure="true"
+                               elif [[ $answer =~ ^[Nn]([Oo])?$ ]] ; then
+                                       die "User aborted configuration."
+                               else
+                                       echo "Answer not recognized. Enter 'y' or 'n'"
+                               fi
+                       done
+               fi
+       fi
+
+       export reset=$_reset
+
+       # Create ssl certificate for Webmin if there is not one in the proper place
+       if [[ ! -e "${EROOT}etc/ssl/webmin/server.pem" ]]; then
+               SSL_ORGANIZATION="${SSL_ORGANIZATION:-Webmin Server}"
+               SSL_COMMONNAME="${SSL_COMMONNAME:-*}"
+               install_cert "${EROOT}/etc/ssl/webmin/server"
+       fi
+
+       # Ensure all paths passed to the setup script use EROOT
+       export wadir="${EROOT}usr/libexec/webmin"
+       export config_dir="${EROOT}etc/webmin"
+       export var_dir="${EROOT}var/log/webmin"
+       export tempdir="${T}"
+       export pidfile="${EROOT}var/run/webmin.pid"
+       export perl="$( which perl )"
+       export os_type='gentoo-linux'
+       export os_version='*'
+       export real_os_type='Gentoo Linux'
+       export real_os_version='Any version'
+       # Forcing 'ssl', 'no_ssl2', 'no_ssl3', 'ssl_redirect', 'no_sslcompression',
+       # 'ssl_honorcipherorder', 'no_tls1' and 'no_tls1_1' for tightening security
+       export ssl=1
+       export no_ssl2=1
+       export no_ssl3=1
+       export ssl_redirect=1
+       export ssl_honorcipherorder=1
+       export no_sslcompression=1
+       export no_tls1=1
+       export no_tls1_1=1
+       export keyfile="${EROOT}etc/ssl/webmin/server.pem"
+       export port=10000
+
+       export atboot=0
+
+       einfo "Executing Webmin's configure script"
+       $wadir/gentoo-setup.sh
+
+       einfo "Configuration of Webmin done"
+}
diff --git a/app-admin/webmin/webmin-2.202.ebuild b/app-admin/webmin/webmin-2.202.ebuild
new file mode 100644 (file)
index 0000000..ecf2b25
--- /dev/null
@@ -0,0 +1,304 @@
+# Copyright 1999-2018 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+inherit pam ssl-cert systemd
+
+DESCRIPTION="A web-based Unix systems administration interface"
+HOMEPAGE="http://www.webmin.com/"
+SRC_URI="minimal? ( https://github.com/webmin/webmin/releases/download/${PV}/${P}-minimal.tar.gz )
+       !minimal? ( https://github.com/webmin/webmin/releases/download/${PV}//${P}.tar.gz )"
+
+LICENSE="BSD GPL-2"
+SLOT="0"
+
+KEYWORDS="amd64 x86"
+
+# NOTE: The ssl flag auto added by ssl-cert eclass is not used actually
+# because openssl is forced by dev-perl/Net-SSLeay
+IUSE="minimal +ssl mysql postgres ldap"
+REQUIRED_USE="minimal? ( !mysql !postgres !ldap )"
+
+# All the required perl modules can be found easily using (in Webmin's root src dir):
+# find . -name cpan_modules.pl -exec grep "::" {} \;
+# NOTE: If Webmin doesn't find the required perl modules, it offers(runtime) the user
+# to install them using the in-built cpan module, and this will mess up perl on the system
+# That's why some modules are forced without a use flag
+# NOTE: pam, ssl and dnssec-tools deps are forced for security and Gentoo compliance installation reasons
+DEPEND="virtual/perl-MIME-Base64
+       virtual/perl-Socket
+       virtual/perl-Sys-Syslog
+       virtual/perl-Time-HiRes
+       virtual/perl-Time-Local
+       dev-perl/Authen-Libwrap
+       dev-perl/IO-Tty
+       dev-perl/MD5
+       dev-perl/Net-SSLeay
+       dev-perl/Authen-PAM
+       dev-perl/Sys-Hostname-Long
+       >=net-dns/dnssec-tools-1.13
+       !minimal? (
+               mysql? ( dev-perl/DBD-mysql )
+               postgres? ( dev-perl/DBD-Pg )
+               ldap? ( dev-perl/perl-ldap )
+               dev-perl/XML-Generator
+               dev-perl/XML-Parser
+       )
+"
+RDEPEND="${DEPEND}"
+
+src_prepare() {
+       default
+
+       local perl="$( which perl )"
+
+       # Remove the unnecessary and incompatible files
+       rm -rf acl/Authen-SolarisRBAC-0.1*
+       if ! use minimal ; then
+               rm -rf {format,{bsd,hpux,sgi}exports,zones,rbac}
+               rm -f mount/{free,net,open}bsd-mounts*
+               rm -f mount/macos-mounts*
+       fi
+
+       # For security reasons remove the SSL certificate that comes with Webmin
+       # We will create our own later
+       rm -f miniserv.pem
+
+       # Remove the Webmin setup scripts to avoid Webmin in runtime to mess up config
+       # We will use our own later
+       rm -f setup.{sh,pl}
+
+       # Set the installation type/mode to Gentoo
+       echo "gentoo" > install-type
+
+       # Fix the permissions of the install files
+       chmod -R og-w "${S}"
+
+       # Since we should not modify any files after install
+       # we set the perl path in all cgi and pl files here using Webmin's routines
+       # The pl file is Prefix safe and works only on provided input, no other filesystem files
+       ln -s image imageetc
+       ebegin "Fixing perl path in source files"
+       (find "${S}" -name '*.cgi' -print ; find "${S}" -name '*.pl' -print) | $perl "${S}"/perlpath.pl $perl -
+       eend $?
+}
+
+src_install() {
+       # Create config dir and keep
+       diropts -m0755
+       dodir /etc/webmin
+       keepdir /etc/webmin
+
+       # Create install dir
+       # Third party modules installed through Webmin go here too, so keep
+       dodir /usr/libexec/webmin
+       keepdir /usr/libexec/webmin
+
+       # Copy our own setup script to installation folder
+       insinto /usr/libexec/webmin
+       newins "${FILESDIR}"/gentoo-setup gentoo-setup.sh
+       fperms 0744 /usr/libexec/webmin/gentoo-setup.sh
+
+       # This is here if we ever want in future ebuilds to add some specific
+       # config values in the /etc/webmin/miniserv.conf
+       # The format of this file should be the same as the one of miniserv.conf:
+       # var=value
+       #
+       # Uncomment it if you use such file. Before that check if upstream
+       # has this file in root dir too.
+       #newins "${FILESDIR}/miniserv-conf" miniserv-conf
+
+       # Create the log dir and keep
+       diropts -m0700
+       dodir /var/log/webmin
+       keepdir /var/log/webmin
+
+       # Create the init.d file and put the neccessary variables there
+       newinitd "${FILESDIR}"/init.d.webmin webmin
+       sed -i \
+               -e "s:%exe%:${EROOT}/usr/libexec/webmin/miniserv.pl:" \
+               -e "s:%pid%:${EROOT}/var/run/webmin.pid:" \
+               -e "s:%conf%:${EROOT}/etc/webmin/miniserv.conf:" \
+               -e "s:%config%:${EROOT}/etc/webmin/config:" \
+               -e "s:%perllib%:${EROOT}/usr/libexec/webmin:" \
+               "${ED}/etc/init.d/webmin" \
+               || die "Failed to patch the webmin init file"
+
+       # Setup pam
+       pamd_mimic system-auth webmin auth account session
+
+       # Copy files to installation folder
+       ebegin "Copying install files to destination"
+       cp -pPR "${S}"/* "${ED}/usr/libexec/webmin"
+       eend $?
+}
+
+pkg_preinst() {
+       # First stop service if running so Webmin to not messup our config
+       ebegin "Stopping any running Webmin instance prior merging"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+}
+
+pkg_postinst() {
+       # Run webmin_config first - non interactively
+       export INTERACTIVE="no"
+       webmin_config
+       # Every next time webmin_config should be interactive
+       INTERACTIVE="yes"
+
+       ewarn
+       ewarn "Bare in mind that not all Webmin modules are Gentoo tweaked and may have some issues."
+       ewarn "Always be careful when using modules that modify init entries, do update of webmin, install CPAN modules etc."
+       ewarn "To avoid problems, please before using any module, look at its configuration options first."
+       ewarn "(Usually there is a link at top in the right pane of Webmin for configuring the module.)"
+       ewarn
+       if systemd_is_booted ; then
+               elog "- To make Webmin start at boot time, run: 'systemctl enable webmin.service'"
+       else
+               elog "- To make Webmin start at boot time, run: 'rc-update add webmin default'"
+       fi
+       elog "- The default URL to connect to Webmin is: https://localhost:10000"
+       elog "- The default user that can login is: root"
+       elog "- To reconfigure Webmin in case of problems run 'emerge --config app-admin/webmin'"
+}
+
+pkg_prerm() {
+       # First stop service if running - we do not want Webmin to mess up config
+       ebegin "Stopping any running Webmin instance prior unmerging"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+}
+
+pkg_postrm() {
+       # If removing webmin completely, remind the user for the Webmin's own cron jobs.
+       if [[ ! ${REPLACED_BY_VERSION} ]]; then
+               ewarn
+               ewarn "You have uninstalled Webmin, so have in mind that all cron jobs scheduled"
+               ewarn "by Webmin for its own modules, are left active and they will fail when Webmin is missing."
+               ewarn "To fix this just disable them if you intend to use Webmin again,"
+               ewarn "OR delete them if not."
+               ewarn
+       fi
+}
+
+pkg_config(){
+       webmin_config
+}
+
+webmin_config(){
+       # First stop service if running
+       ebegin "Stopping any running Webmin instance"
+       if systemd_is_booted ; then
+               systemctl stop webmin.service 2>/dev/null
+       else
+               rc-service --ifexists -- webmin --ifstarted stop
+       fi
+       eend $?
+
+       # Next set the default reset variable to 'none'
+       # reset/_reset can be:
+       # 'none' - does not reset anything, just upgrades if a conf is present
+       #                  OR installs new conf if a conf is missing
+       # 'soft' - deletes only $config_dir/config file and thus resetting most
+       #                 conf values to their defaults. Keeps the specific Webmin cron jobs
+       # 'hard' - deletes all files in $config_dir (keeping the .keep_* Gentoo file)
+       #                 and thus resetting all Webmin. Deletes the specific Webmin cron jobs too.
+       local _reset="none"
+
+       # If in interactive mode ask user what should we do
+       if [[ "${INTERACTIVE}" = "yes" ]]; then
+               einfo
+               einfo "Please enter the number of the action you would like to perform?"
+               einfo
+               einfo "1. Update configuration"
+               einfo "   (keeps old config options and adds the new ones)"
+               einfo "2. Soft reset configuration"
+               einfo "   (keeps some old config options, the other options are set to default)"
+               ewarn "   All Webmin users will be reset"
+               einfo "3. Hard reset configuration"
+               einfo "   (all options including module options are set to default)"
+               ewarn "   You will lose all Webmin configuration options you have done till now"
+               einfo "4. Exit this configuration utility (default)"
+               while [ "$correct" != "true" ] ; do
+                       read answer
+                       if [[ "$answer" = "1" ]] ; then
+                               _reset="none"
+                               correct="true"
+                       elif [[ "$answer" = "2" ]] ; then
+                               _reset="soft"
+                               correct="true"
+                       elif  [[ "$answer" = "3" ]] ; then
+                               _reset="hard"
+                               correct="true"
+                       elif  [ "$answer" = "4" -o "$answer" = "" ] ; then
+                               die "User aborted configuration."
+                       else
+                               echo "Answer not recognized. Enter a number from 1 to 4"
+                       fi
+               done
+
+               if [[ "$_reset" = "hard" ]]; then
+                       while [ "$sure" != "true" ] ; do
+                               ewarn "You will lose all Webmin configuration options you have done till now."
+                               ewarn "Are you sure you want to do this? (y/n)"
+                               read answer
+                               if [[ $answer =~ ^[Yy]([Ee][Ss])?$ ]] ; then
+                                       sure="true"
+                               elif [[ $answer =~ ^[Nn]([Oo])?$ ]] ; then
+                                       die "User aborted configuration."
+                               else
+                                       echo "Answer not recognized. Enter 'y' or 'n'"
+                               fi
+                       done
+               fi
+       fi
+
+       export reset=$_reset
+
+       # Create ssl certificate for Webmin if there is not one in the proper place
+       if [[ ! -e "${EROOT}etc/ssl/webmin/server.pem" ]]; then
+               SSL_ORGANIZATION="${SSL_ORGANIZATION:-Webmin Server}"
+               SSL_COMMONNAME="${SSL_COMMONNAME:-*}"
+               install_cert "${EROOT}/etc/ssl/webmin/server"
+       fi
+
+       # Ensure all paths passed to the setup script use EROOT
+       export wadir="${EROOT}usr/libexec/webmin"
+       export config_dir="${EROOT}etc/webmin"
+       export var_dir="${EROOT}var/log/webmin"
+       export tempdir="${T}"
+       export pidfile="${EROOT}var/run/webmin.pid"
+       export perl="$( which perl )"
+       export os_type='gentoo-linux'
+       export os_version='*'
+       export real_os_type='Gentoo Linux'
+       export real_os_version='Any version'
+       # Forcing 'ssl', 'no_ssl2', 'no_ssl3', 'ssl_redirect', 'no_sslcompression',
+       # 'ssl_honorcipherorder', 'no_tls1' and 'no_tls1_1' for tightening security
+       export ssl=1
+       export no_ssl2=1
+       export no_ssl3=1
+       export ssl_redirect=1
+       export ssl_honorcipherorder=1
+       export no_sslcompression=1
+       export no_tls1=1
+       export no_tls1_1=1
+       export keyfile="${EROOT}etc/ssl/webmin/server.pem"
+       export port=10000
+
+       export atboot=0
+
+       einfo "Executing Webmin's configure script"
+       $wadir/gentoo-setup.sh
+
+       einfo "Configuration of Webmin done"
+}
diff --git a/app-mobilephone/scrcpy/Manifest b/app-mobilephone/scrcpy/Manifest
new file mode 100644 (file)
index 0000000..e9bafa2
--- /dev/null
@@ -0,0 +1,2 @@
+DIST scrcpy-server-v1.12.1 26202 BLAKE2B e3e5f5f18c02741654f1fcda9ff903fcc49631f4befc61a6d5b09b84544ea7cbfb181d2bf186089f4fe2cc430c8ad8ec1b2ef04f610f6f21140e72af79f492ee SHA512 375c929e8118b9c9d167781851b8f23c43c9ac157c1c62225b2babfc6acea0eb06ba684d0b836ad64071030bde5ad17464a01cb4288739bd6e2a6b425fff0d72
+EBUILD scrcpy-1.12.1.ebuild 923 BLAKE2B d821877099aa5df13d1783d7e8567c598034858b977c6dbded7eb21c784ede47f035cbc4cbe2979613b9dd2ca3c62292b8e0c3aab058da178706558830136714 SHA512 b74bf7b0d476fbc2813671fac2d88bf28cbc5278622c0f630a7989cffbd7d2389eca16d24d64301646ecf1231f0941b0412b8c8cd40d897f49654699a135b11e
diff --git a/app-mobilephone/scrcpy/scrcpy-1.12.1.ebuild b/app-mobilephone/scrcpy/scrcpy-1.12.1.ebuild
new file mode 100644 (file)
index 0000000..a234bf1
--- /dev/null
@@ -0,0 +1,44 @@
+# Copyright 1999-2018 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit meson ninja-utils git-r3
+
+EGIT_REPO_URI="https://github.com/Genymobile/scrcpy.git"
+
+if [[ ${PV} = 9999* ]]; then
+       MY_SERVER_PV="1.3"
+else
+       EGIT_COMMIT="v${PV}"
+       MY_SERVER_PV="${PV}"
+       KEYWORDS="~amd64"
+fi
+
+MY_SERVER_PN="scrcpy-server"
+MY_SERVER_P="${MY_SERVER_PN}-v${MY_SERVER_PV}"
+
+SRC_URI="https://github.com/Genymobile/${PN}/releases/download/v${MY_SERVER_PV}/${MY_SERVER_P}"
+
+DESCRIPTION="Display and control your Android device"
+HOMEPAGE="https://blog.rom1v.com/2018/03/introducing-scrcpy/"
+
+LICENSE="Apache-2.0"
+SLOT="0"
+IUSE=""
+
+RESTRICT="test"
+
+COMMON_DEPEND="media-libs/libsdl2
+       media-video/ffmpeg"
+DEPEND="${COMMON_DEPEND}"
+RDEPEND="${COMMON_DEPEND}"
+PDEPEND=""
+
+src_configure() {
+       local emesonargs=(
+               -Db_lto=true
+               -Dprebuilt_server="${DISTDIR}/${MY_SERVER_P}"
+       )
+       meson_src_configure
+}
diff --git a/app-office/libreoffice-l10n/Manifest b/app-office/libreoffice-l10n/Manifest
new file mode 100644 (file)
index 0000000..dcce688
--- /dev/null
@@ -0,0 +1,554 @@
+AUX lo_gen_langs.sh 1466 BLAKE2B 81a5c47dcdd23cfbb7d99d91db7d4dec9b89f0b28939dc7897e9ab94fe95d1800dc6b54aae5f608dcd669ea4fb8bc6141b5bda2a45b4a6aaa49feac4786ea504 SHA512 492250b1531a58f3ba22e405d8a6ce397b5fb7e06c74c7ecfcb4c9efaacb9d48f19ad05854891c0c6ec9ae558bc4595f061397e5a506c46a981e14502eeb8cff
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_am.tar.gz 4041482 BLAKE2B d0d7aadbdd2b0dbdaa676e391e27ae96cfca0526ba98779bcab23ff1fae4726026006435662cca48bf40175337b8c93053839fbdb57afa2b86e015b70e173ef3 SHA512 5ba2558ff629388bfbe6c87e00c030d0058ffdba3ff099239781a100bf902271248d40a8607399d3c56fc725e160a4e2d0c9c790fee59ec0095bfc4929ffa5d6
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ar.tar.gz 3521722 BLAKE2B 8a26a52b2041dc185eb8c139a834fb9bc60e5e859649f90870c1ea6b0b9f0adad1ffc8aa99d150f49307974aaaf5134b852c527e1565bb17c79466746d3a8090 SHA512 0218e90f2d88d2ff6bdfcd3871b56a9f50f1d4474d634ec3c1717a624d81aaaafe43f1f85b8e9dced854bd6e3bfca22646f6509707e05f11634295f9d33537f0
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ast.tar.gz 3760345 BLAKE2B f19f58a32b4a1fc81f2affd79665094412925aaccc1a557dce7245676eab18a5f4fcbc468c1b2a406649fb344a05587ad52bfa8da34b87ec9f3202f2e1f30b98 SHA512 d8cd954b6a1c772a549816a448fcddd304a14183edc30f97025329175f8b240e1b5704af4d4e96bb9b90aa4f7138136c6de1942012e2552998cf70446861490a
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_bg.tar.gz 4076059 BLAKE2B 6b485d61cf23a20e76a557cdd1a669b4b1de114ddcfbaefdfa4f8d190039cf05117696d9a26803bc0328c480e0fc9a1463061077d29013ce63d16076aa859fa2 SHA512 59e70ca8077d8d1418df2490f31ac7adc028279cf04197e5c0ff9316de09c062ee558e1638fda3d3e32889a6a1960c3260e2b1b2bc7db1b6c701369c0e4e4348
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_bn-IN.tar.gz 4227788 BLAKE2B 5a34d55890eb655aa830017b58da175eed6d9bc9a38db37344929e5f0badca9a303c0fcf7955d0b155b2e04be369225f8a24f26bfe9a9d65e0e563a841006e64 SHA512 fc92b26663995e98e32ccf3acab5b637abb8e018cb686ef103f7022d83fc564d05328640b51c02efe182128baf59acbd175a34d8827e05164381b26eb68080ae
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_bn.tar.gz 3907069 BLAKE2B 03183c0ebde2aef4e86ac403deb961062f37499ef38b51ef0da302734d736c2a45cf9fb255ba6f7480bd2c67e27489fd0b982945b4b70044b99f9a9b07c8bf0c SHA512 9264ca96f0a537b58ce25b764c00e1fa7e595d87a8f82d64e5fff68eaeb1f15de76a84f1f4cd01cb9d1a2418c3e56ea7b02f52a3b2fed7104e0c3c2e040e4644
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_bo.tar.gz 3915728 BLAKE2B 1e8377b437c2c727e8c080ad1463bf891ebb981186e2d495f5a05f2e3636ce774bd2a11d0c4de804fe158acdfcb9c625e097e3716006da83976ec4d66ec4a3ca SHA512 452996674b52e7b385317ac32ebb4a9ec95013307c7cda44b7dfeacdabdd6b49d79df5bd4f9149d64a09e1bf619d2493d72fe19c029ee037ec1c9cef4c3c42bc
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_bs.tar.gz 3646073 BLAKE2B 80463b2e561d2d288074d5ccaa6d1dac3a0b0b6a4d38576ad6fb36b38d8611f9675a9b66860068a3bbab2671dbf548ec0fcb465b648ed6ddec43d3d890f937db SHA512 6b753f4d547140af29272137b3a47145ffdd71bbfe79883102cd1f74ec5435bde68de884a04f388195ba3ec3f44162544c20984ad634ac1dcd7ffd7f7bb311e6
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ca-valencia.tar.gz 3781616 BLAKE2B 09c367a0078dec10944a15d8dbac65774c0b5543ec88f2bb788f9dfe727416f457e85dee9a8d3fa64d2061043688af1a6124ae35f658a501b421e04527f66d1c SHA512 659941b0943b5d4f9c053b5f95459faac4790db6fdc65d27e7011a744d515930c150106dd96aba6656dc5b88c251bd131b485a5cc83af5b56e08ea99ad960c1d
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ca.tar.gz 3772855 BLAKE2B 1ba16f6ece5658f6f3eca59587c65905dd849fb4f35ecccf3f8f68fb8ecd7b54fb5b63e98e2949f2e9e56f5566741604983e3c5d94acc6e9593ec0f2cbca1b27 SHA512 334c45d21511c547e019fdd445c9c71d0cb6bc51a70b6beb228946028034b08e460f1aaa890d7c52722a3af63bdc81fd21616280a2fac6599588122b54fad52c
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_cs.tar.gz 3800618 BLAKE2B f09a3b39b88ceca43c4e11dee6b5fb274fc9794052f97e1dd3d1ac43c9883e5956947bc672e9c33755e9d4053e9efadd562b6d7492bf15913f078e949a9888f8 SHA512 d8fd0bbc6afeece418592e029da282605b4f400151f0aac6aac4c9bafc29ffb9ce017ffccc25ae98065509ea3b6dcef067777ddbc89381728acd28f756ca880f
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_da.tar.gz 3703314 BLAKE2B ca4d493fd15314a6c6a609a2312941e0434fc082da83a510c0690922c8bf897f12b7676397056290b7b465fc1fd9287899e37374c2ea448ee63131ef254cdc23 SHA512 99830f583bfdf46daafb2b80e3f406921a22557e213df66b908e8a7b04977eda908a5e0bc868847fde8b87f7ff77e94cfafe59c4d50ddee9c8df6254cabc6975
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_de.tar.gz 3857453 BLAKE2B 5c7cae26929fc6a03a75744f9426a6eaccf6211280619c50c2122789a4de925c912c300ffdec89d4ae9e3624ef1188514dd9ce9fb68d53afb0dde1e6c2dac7cc SHA512 e52bfcf3f6d27a3a02c76e2ec8ec4ac67cc875f8dcf37bca231b7b05a721d0f1819fb150805bd58655758131e53ff5f9af4a8efdeed1869d3887ca5fe1d1aeee
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_dz.tar.gz 4062783 BLAKE2B e098191c38f74803bc77f4f388f1fa9694ac18bf123f2273742df4974b8a5ab1d5d454351a4325d6ccde220163898401af57893824b7b83dbca8545ef0b8571a SHA512 a0ef64e27b2b8d1a22133df80fee06284bf870ebdb9dca4e3689cd4981e73628293966016a7bf50f8bd3a3e25a184a795b7146c97b6b1b5d1e336e180cd96bb9
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_el.tar.gz 4498590 BLAKE2B 53ead632dc86ac5c98f31aa13a8915996db46a7d40cd73972d897a0c3e727923467e5a32806d6159682f5643676eed002ac0e39d91de0803f7f1fc6510250fc6 SHA512 828e1adb5f976c32ea0e1fa0515eb63a7e064acaba3475a7c2ddf85d77102cf1a2a638b90c15e7595d640640e1422c046a63d6e89d8f749de6270a3339428f3f
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_en-GB.tar.gz 3533842 BLAKE2B 26e044b9ab78addd043a0a49621a9bf087d007a6f4837a315322880a548c18cac8f1a6b15a395342918ccf60a354fd3401ae31a67c53435347a17fab7b4b8755 SHA512 c6718c6d317affcf2945a694cbe4d269ea39db29f7787e7b9685b2e34785690b6129aa29d3691889fade603ef6b2c8cd466c03fdab17d3a9d98356d35fbc9db2
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_en-US.tar.gz 2224697 BLAKE2B 9027c2f211cf16a3006298ca414fd4256728fb479dfe63ea0bebe34295a92fc1c62be33d3a5deef96401ebfa05cd7eb7656dee26f7ace46f14c42848bc596773 SHA512 bac811bfeb4f386710b30c4eb235747e5e5f606d9b19479c36d47616d6ca6e898d2f83faf1361fb697df2be3f175fe53b46c4101d4e63b835f3cd4660b7eb43c
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_en-ZA.tar.gz 3524853 BLAKE2B 99c5c457f87c28e34cfe167002c0c30f4b53de7bae60d0c14d8a66018854ddfdecc4146ff187dd2f4cb51e6746cfaece9a1e92ad19da88a1f766309604c7d4b5 SHA512 eb51e9bf61e8d8cdb1cc2fa65af4173210f9944021ef41838027116fb6566b8f049a2707e13c1edd2e67197b557f034642c34f52cabe5d8794f768508ee3162e
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_eo.tar.gz 3621267 BLAKE2B ed8dfeef63177de11dd2b2909cd26ef25130bb37a06657eb700df806c96b8114d73b15a1fd2efda0e7a221728e00dd0ba7fd7f7de59f8b10c7d021219727a4d9 SHA512 de4d29c2eb8fb906c371637c2e904895fe4d88780528946404ecf66caecbcfad0f317b4ec91ec6f27a1645bf9d4c11407821d2f97ba28f8dca38baf0f57ebd8b
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_es.tar.gz 3813210 BLAKE2B c70ed21afaad65a120f050049e4aab2a266074f6db6bccea85a1a5a184cfed3f1524de659e4694c5ad6dff0ad8e02ff6e779c9a24b43a5d6158a2b99935af776 SHA512 5c88f3054aeb2e665a62e0f5e2861320fb2bfbccbea6b7b26e7362c625b96421086fa1aa89d75016d0b45e0210fcf3fc4b13269ba133fbd675939f969903708b
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_et.tar.gz 3663707 BLAKE2B 5ba3d082b005c816910bf8715075bd48c7f6c126dcc8d629c4b22f5d5b866865d4cd7ac8cbbe120824ba0d38d5f82804f75be83a677602bc376ca5e566cdd30e SHA512 46b00174acfce4a71d17729395675b536366ac5f0b8db6c90b1bc0fe1fc508e3932c700b8358d03ff85fe3dca9d850ff6121511228e055cd3f6f481151897b2a
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_eu.tar.gz 3649761 BLAKE2B da417848de39a2155149d9a6908bdf27d25fb9af0f6a3a42ed3e9c66d838229e7871e150a9b549af7f209aa3a9f05593c5be9926444e7dd12710e923b9f16c72 SHA512 a81364e16e75dab5964dbbb1833336409d7a80b54899499931b36d0985ebb2f69d04270a517695f5ef010e97f4d154a2156e2e095d1172419b1945073ecd2804
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_fi.tar.gz 3674991 BLAKE2B 839ef1b342a5df02d44f2c34dbf5ecb56c7d25f8f9f2685ffe6fad13875f0154d2c13877ebe7341434aea9f9afa1672c713fcc578f873be441351ffb7320aadc SHA512 817ea3b4f9ec92a4dbf6a2d06d33513b9d4c92e110105954623bb66779da1da74007ad807419573b1a1684a6f496a1e020b9eafe45a4434fca2c793910441a28
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_fr.tar.gz 3796996 BLAKE2B 94413d7febaffee7df2d002e94bf6f25623c4e07f678dd0b25c7774db2d0d3bd276dfb38f3aaa81d819d66284221be676914c62918e1e7aed2d9e1396ea435af SHA512 3b4053ce1bbd6e614f62936d0bd740a5b5a987ef1ecb4447e3cafa828ac3f8d132a536a10cc52ccb5cd2757752696ae412466436e8e30c422d119b6acf520b51
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_gl.tar.gz 3759507 BLAKE2B d27530c61a2a19207b0244bce296c60d5cbc35631d50e6a3e354ae3ea6529e4785534c60e170033fbb5e22247e7339f48d2aea931d23e02d3079f5f39cf3e782 SHA512 46cf3f53d865142c56dca09f93080a45c1888f95dcae63b7b89157e07ccf9ec60be4eb5646bfd7fbad323f63798310a6d396738c8e52d31fb22f2fea5c7d74bc
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_gu.tar.gz 3614068 BLAKE2B 6a496ea5e1b3d0f08ee1a9c3cd354b56a02c77f3a0206e45f42630e738b89a5f511b4449e2ae89e0068c8357a5b3687c660bd624ab7615a92ece0d82bc1f2c94 SHA512 121b8d50ee0cf37dfc6712534ead68063548c04b36dd78fc173ab8c4b260f0a36ef601444dbbace6ea5bd156c4c6a41eea63580f21c6c8d6fd04a2c793ccb566
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_he.tar.gz 3385619 BLAKE2B 3edcc0ddbeb9fac57b14145ceb9ca2edf2e302d55b3eb8a63e8eb718063c1685e702286d1ac1f90ef951d70bbdbbbb397ac94b97ccf6d402d2ecbc54e1fdfcce SHA512 5f87d3f8d72dab3eae092c651f59a893b74c19aaf679f05ca677984077e2dcf8d73f72fe2fd91101400aac7ee696637c5fe1cca950eada8e50fd71d8acbd68c6
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_hi.tar.gz 3738449 BLAKE2B b8bb0d1b795a28651da0900975e751bce93a18a7c9f5210ab62a4dbe40718c9cab7e69f28ababebbd48aebcc38656ba8e49b60359c9913b7a913bd0420dc6e42 SHA512 7a869409bec1180d5f1fc4a799a0e233187f0e39af9676fbf0c11a43849ba5689f3feab98b457bd8e6ef4f4ab6ca90721e16bec345fab9efda92c02c980e3b06
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_hr.tar.gz 3652715 BLAKE2B e0f548bccf1170427d9efd681d8637cc0c907a457dc572ff0266264b12a48b1f5e9267127cd6599e8d74bfbef27811a440556105beee4d6d556d421b7473f2a0 SHA512 8d670d2f3ca5b6be89b50d68376312d561ba97018447579fcd9a4220bd88faaaa09fed468da17b4c99fd5e17efa2492f861780ae7be90236427f38d27166e821
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_hu.tar.gz 3921980 BLAKE2B 5ed6150b73373573e10e77415d9fb79fa072f123203a37c3e1d782cb07745b0dd7de7f76c3faad2d8106fe882c7bc9dd338bd68ab788ab299da13f9224769cce SHA512 cc904bc29339a7ac9ca07570f0f4dea6b175db9edab98b8caa27711aa78873bb86e44b7781748f3d24c0e988c7e29147d5a3df4e4bd9edd2fd533a9f7fb42371
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_id.tar.gz 3595878 BLAKE2B badd1ac9ba96d4e01f47206a45573497752f28a6ed9bdb709e2751717d1ad90901c994c7e299e892f445c68ab0b9171caf1ec7771037b1170ea96f30db1c017f SHA512 2d041173ae5f2e47495098df62a0a9115f18bd2ef888170ce2ffc1be62d42739bfc0f8b701f7a65d1da98cc49de54ccd9dcbd9560c25ff3b00a0ba2eb310fdca
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_is.tar.gz 3669744 BLAKE2B d08c890024739947a67ea2f6424e2e2808fa3a66494b138173517aab4b94afd5459acae91588f78a4dc8052b5f6028bd226c8d07a28fffa868653132edaa9367 SHA512 f5795b93c8097c8c6514754c663f1a9a93f6a8d1e3c4f034808763c71caf89c53dc86ec7ee913875aa21d56ec02bb108afa11b82eab61c799b71ac8174bc80dc
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_it.tar.gz 3725439 BLAKE2B 4b1c89373d207591c7265b5b22456660204da15b8218eadd4a685a2d6819c7ac59ae79dbd37ea4ce2dbe06e7ec50b7173d6ee45a798189ab8f84fa4b8df697b5 SHA512 94cfb41d64193b57d63e2df0c39a123355d5e85ae534aac2726b480adede97f98dc050e301646921d0029b459fbb781ed577354cb43e48b58b21e96201237cbe
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ja.tar.gz 4381787 BLAKE2B af83b703eb09aa9046034ba3f2e2cf8bf7519f92685f73420e4cfd5271c46bb30bd2afed28b193c3f22d9d43cc83ce49dc5307adfbc2237bfeb1ab9f96ef148f SHA512 108572e5ce5e9afa46a2a3d96643531cfe709e9c8d1f7535cb8e6bfb868064f7f8cf254c7c6a9ddb51864771f96f423971958fac5c4a8420d9c9b407cee69501
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ka.tar.gz 3857314 BLAKE2B 268085fa732de93747fed741cf8ae65fd05e3d82048c4bd5a6c10030e38175f3b3398dd7aa992e1fd491a759c07aa7f5627edb22225aa2d1e93fca32a652d1ab SHA512 ab85f6b77a08cf2f028433198195bb2f97e4439949bcf1e7432eb30189af563a79dd31951033d5c89e41418aefa767b3bde06e8c0b57dc14cde39c5960396ec5
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_km.tar.gz 4190501 BLAKE2B d44dd10c65633852d92cf3b8e3b7d67f4b2318156ee354b17fd46dd9110926eafb614ef9bf5970464d253724a87cbe10e3b62ec4b6d6c5cbfd5b4e646c1946ea SHA512 fdf3da8e9b98aee6d90f34c381cc1febb0d9842ee71648e0a7d7f0d4a9296baf63c80b800121c7600e4f009ad73aadbad8b13c78e97a7b263df36e701d432166
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ko.tar.gz 3884113 BLAKE2B 474cc94210ad24f8c6ff42f815b799fcd93c4681c66dbe5f716381abb295ec263a2c83c52e2632a4b757bc0175f834ec7a79c04d46cef45b8ab002ba1beb8122 SHA512 16459b473c491737ad3f61fa06497dfa5e71b86bb0b8dbe49d8d1018e4a24c07d944165cd4b77fb5e702466b4f0959607d619b21c7f3cfdee33eca94e43c0e58
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_lo.tar.gz 3610223 BLAKE2B df3bccdd5356ebd2269fddd9be3b635e2b7c7a12583751f53dc8fc08b728c4c372dc3ed9356bb966d7045d1a9b78dbda0154bc9a8acd41f08728e38c77a3e9b0 SHA512 dc3108e184278a2b3a4dcf5228cd2864f3c6b7f6d10145fd43857fe238a23cb3f1192d18f74aa183fd45f67632474ff18112f22a763aaab918269c3d6d15518d
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_lt.tar.gz 3819576 BLAKE2B f4404b6e1af820d64477afbbd37479df6c92cfb8de362bae99be30bdf9f3053644bf17bf2a4f16b74b852d59478c5fcbb44e6eade19716cd9128a846809af1f5 SHA512 4fb2393d3d32519e31a69485e38ee6f5b70b19cd26350b89186dc80601940f57248cbde591a057bbd0b37768083732229e9089b12614c0f362e6b532be23938b
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_lv.tar.gz 3666275 BLAKE2B 1be737394f9df414bfc1f0a4e181cd7fae62b7d9e6a57ad9304997edf2a5c7c8f5b2288d408f23f2060747fcaa3885e6db22ad8f098d075c4af7b5ea400bf4b7 SHA512 57a6af057dd76ab6d9e962403f623b578b01835661341314c1e90dc79a359391ad4a7b9b51361ab10943ac0f8704a1d300ed1581a4c0e69a6b1bcc379634ae64
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_mk.tar.gz 3706567 BLAKE2B a8563607c0f96104125c7856c3437a6851e242fc0e484c0e563475d8723d91ce36c5e0af7c1573f0bf82e01cf5f57d356b639b963d8b2d8cc3a3c0e44d7a50e4 SHA512 79fdd4cf9830eb2c0b517b6eb6718e7e115b55ddb26ae05e6802be6c1ad0718772b57cfc1857b00c54f76fde248aac9c7327138a1d412f36581a1a856a75f8f6
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_nb.tar.gz 3657335 BLAKE2B f5757e339f095b33770d5304ddb9f6cea13f07ef8b2eb9cb987fd5073b1d77f93e2034333ef5e24343b79580b040b550ba4da14dc70febb7b163dcebfcf7d41f SHA512 c5f3650034db9f6c89b79f04d628a956fd45f74bda6fd524790f1c4879fb61fe9e464b31a6d674688bc2bf5ceb181868120e7054cc937605ade810e39c021953
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ne.tar.gz 3944737 BLAKE2B deeb11bb878f4e21df2c50f1cd1fc51fd8c76b9317725e117dce42962336e1e5b38dc00da4ff90d7135b8b89e1829049b17ce0b2103c4ac720822341df6fae15 SHA512 5630fda14c7dcfd1337cc0c1b032bc3fa43eda8378e1283cc9fccbaf2b22cede99b8fad54e567c23f3bb816fbbf31443d12229a9cda4532ac1491e9571a10b07
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_nl.tar.gz 3768222 BLAKE2B 4678442b208b173c4d871fde8af6bad83f0b45f0c6f08fa03ae5534ff8f19e48791315caf58849322d88dcdc635b069421aaec93b662b775641afe0d93083c39 SHA512 b3e266d507adef4587c995e8a672e7874f5513b76f0c6b88831aaedf48b568452cad68c985fa883a88e19d0fd1b483631faae19e6c6f06ff4e8b6874e63f8793
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_nn.tar.gz 3813946 BLAKE2B 4970edfef467d7273db5cfa99f49f3c6dbd5cc2d1457075da7c99a06084ee420d46e154df521469671d69d06693c9b801687dbe4c6d69d037abba6be66592f9d SHA512 901afe66054c388cfc09e3a58685c2f356c33748662b94b37ef030fecc0bcf6008cbe76707e0e489a53c3f45c89c628a90d5779e377306212649ec3683c92e45
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_om.tar.gz 3712144 BLAKE2B 3943f3198479e55e520625d07fec55fc7b9be4412a8c085f09fa766a775b1900b6aba3d0832025014bb5caee329eebec081f693a716cb408d0b9ff0e6e270807 SHA512 ad3ffe282e32d8ecc37fe71df41311a0783a37cc178c063b08e4f5d1918972a8d5b36a1822dda7bd3336017a942c9a3b61e04a49939fb43b3ffaf01f2c215e52
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_pl.tar.gz 3955474 BLAKE2B a4f34c33ceee46c64b290d3cb4379ee16f339bae76e91e79aecf52c3647c594fc3e42cb79282514d28250133db91e8464e12c26cea1ee614d2cfcb545f137f66 SHA512 c38ecfe0a2480f3275427b4d8e342142e8b9689632aa07c4fcb42676989c683e9d5d67c2a4ebebd2e42fb65203825b75ada3560657b55d2cfb4eaf61aef0ca1b
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_pt-BR.tar.gz 3767039 BLAKE2B dfa77cebe0a67d2b10a4bb3abb80667ece5b380961c86683c897c5bfec78d5f3ad593b1ef28fc8d316e4bc148e570a49f0fe570377f537a256b183b1393e5c78 SHA512 a6b2f89575e944f3448e8d12fc6a9b64df403554963b5307a6f822d7f1096df0345cce33110a7bc1e10d9d7384e56e2c3a494104e5fe7e25848afade847588ad
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_pt.tar.gz 3744440 BLAKE2B 0d481ff9fa979ce7b783afdb22382f3979d9c64e44b51cb638576ad8e2e7c18cebe22ba5959be26d548690de7e0a852cf0a29a5721b947f811749a1d03d7bede SHA512 80a56781722913fbec4ef486442f747ab16123a3da75a8ea527474961d1a8e73fb821e31925dad380e09f4f5a15f7ac76ce0e56bf2282e02cbf2fb339c2af31f
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ro.tar.gz 3559775 BLAKE2B a411228dc3135175ad799c58a6d3a034ed97149decacba9868f3a4746117ffa870eef9369a5d55608f8b8096e4917db272dbcac6b3504b22cf4bbca6c72ae213 SHA512 239e162c65688beb32ad5727a2605177bed4e4981d9866aa9385578ef44b751bbbe001610a4464c0197f3288e6803a729caa1d58ff14f9b5831efeaba2a6a368
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ru.tar.gz 4107869 BLAKE2B 9848ffc75c6704a95994c5c87754e88fb921bfa5b5a28b4801018670a90cb057ec3aca65cdba55fdfccebd1e4001363f71198f88d4ffe0a83b62521bfda19e82 SHA512 4b18e9e1ca29aac6955886a0ca5279ac7fa1d1d2d5d46171e8d6a7bf4999e507d6ee4c385508855a15c600978299a15818448d76a0c29a801d8a5c7badfef925
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_si.tar.gz 3840108 BLAKE2B fd30eca25ff8246fb0a81a164ab27dffe6ff19f712156fbae44591170095221136e2b70a497f17193a7d66f3535032a077133935581906f774f9fc6ed563361d SHA512 dbffea4a7b0accf47f548c2d79003614f9fb09bfb51a6dfacc1e1a516c92a26f03db5bd29e87a2a42fadb6c4aff5be5e85e89a5e87480e63f4e986cfc4b71631
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_sid.tar.gz 3702017 BLAKE2B d273cefde492dd963667991dd9a7020373453c20f90a56373ccac4dad00dd6934542d12a046a5a738cb61dc5224c1d08178207f46b4a0363dca5cbc7ca020ed1 SHA512 1ddf0f0df7863bfd258df661fef4f05318a944dc46fc595f928cae9b903f7244a426983cbf6d286ae41c8384bdce7fd795c491a3422b4b445d6d5118fc549f13
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_sk.tar.gz 3861750 BLAKE2B 7f1db95d818f3801b3bb1507e5fa2c2c8ebca7e55eeff410036204575529e36e1a124cd179cc61d9984e43dec4595c3e79587d575e0fc1a71d68053e20fc8e80 SHA512 38e3c39c259f563c0803df9418b43daf3826afdd15fd751e02feb5a89d9f2a5f06afec957063fb8f5f9b4a265de4e8e08e34823921bb67730e1bb21d26e8424b
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_sl.tar.gz 3715191 BLAKE2B 538796a82d3f823eb6917d038a9c82865c21fe69aa6bdfe58c408e50664d17d77e01a7fb81444c7f7012a4d18d4d856f1bd4d075b47f23f39c8f1f9f42982de1 SHA512 0d913d17c77c8a3936c7bc1bf5d9c0e6072e74af0d47809eb0c9faa4c6da343caa2930b62702ea95814bb36c2e7d7ef2f2ec7de92fa74806a157bdcc1a19f9e4
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_sq.tar.gz 3623057 BLAKE2B 864bbe43d6947435890d45a145392bb68f7c5b7011a4db987ba25c567da00ea9fd893ebbb45fe4d4131fbe7ac89e0f858b88ba6cb5344a4d80790e615a0ee221 SHA512 79665259effc82e15831f9c67980950aa3fb0eeee236e250db100932857d450d55531d60e4dd0e031b6244d567814a292196d8c2ce63756044f6ace3aaa4bf92
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_sv.tar.gz 3704114 BLAKE2B ad0c00745e717a850c6af8e9b3a0d7b621c69c9055ff9167eb702ec8ed021a1344acc5b02bb570736dd313f37db75cfb5872d7b265c75b8f4f9476c82032e429 SHA512 e6d48d3871ec2dadf570a3ffde7cfec44a11a77768a97ec255c82ff97d990c786b9ee13dafe795a94a3e4c901e05409104d50928a455199b169693b366ca8ec0
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ta.tar.gz 4053823 BLAKE2B 3ddc170807c6e1bb94744ec503315aa530e9bcd39c7c9425ea522164f0c2c3adfa95da3a76adca715eafe907b6e58482b7a017cbcd33599260a17981b8f543c2 SHA512 e3982257908c013a2151fdef2d64b086212bf67dc160ebd24805026e35400ad67fa74f73c49879a97affe2bf492611cdaad545e86e293270175967564914e3d7
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_tg.tar.gz 3672052 BLAKE2B 6bd38f91e50514a0cf1d7fcfc01905ab25fdee3424dc2c2a54b9546244005b93b2219a479da960b035d51f208182f5a82ee1148b3bbdccc9a8661f9e1a381ad9 SHA512 7d1f3779256be832d2c8e477a8b01c2db1512d4a57b7c2c64d4b396bb799ef44b8183c9bc9ab103f71c27ba5263f1ae790fec2a63c757aa7767e9e5ff25373d3
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_tr.tar.gz 3763182 BLAKE2B 1732b0fae4d2d55cce89427c27774eb582d619c740ce9c4c28534739ec9868010b47cd0e12e31e4c99c8d2ed3752ab30bf894dc26501c85d23202e2356810174 SHA512 38e5aeea4990970039a568ac82645173cae427446d4f5450ec0de9860a385502614c264951c4b343759c4a346395a8bac1b537cc655ef2509fd944469be84ff8
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_ug.tar.gz 3782503 BLAKE2B a54ae41befc4c340e77fe84c17877c169ee46c8a225a58802c0628715700fc7dc241dc0d9eae8a786765afcf76f8b5e359f8eb4bc99111f49953f2f80bfd52ea SHA512 3b5e545323a4d094864b027de1a0f83e3978ea79c5a57f6e510d524f0e1f8abeb66cd759cfe129652c49ab3769faa3504ba772caf011d2eea7b4b5fc0b024a3a
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_uk.tar.gz 4088263 BLAKE2B 760f340ba739993f2a02f9acf5c43ad285a53a87725b07f68c13812292fdf946fab3026d778c1be2888c65e478e03495688ceef8a5b69dbe5c5db49162f021ba SHA512 2dbc7208e03bda87fff03ba642235cb7647d0129f530717eeac90a7e417f6edff46344861a49b7a60995fccc48a27a304a23500547c79bdaf4d27686f9cdac83
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_vi.tar.gz 3744598 BLAKE2B 850acce1b627550b83aca3fa2bef9617e5aa17c01c9b6dbf294da0a4d31dba7156aab352aa150de6311e425dc60d52879437339a73fdbaf80d4d9652f0bea33d SHA512 b0eb5a8543a33035fee40ed7691ff954b4955c42f8a86d3e29168493e48fed8b052f4567f6755b62c1bad086e5826ac9f110c4e56e52f487260ff11f32594ce8
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_zh-CN.tar.gz 3995067 BLAKE2B e8ebe6c04918456e2e33b6cc92332de76a1eee626bb018a047cf683432ad84c81385f8a17cefb17e0469ca688dbda76dc5b95cbd0bd963e9cd5137eab4a70b47 SHA512 2a0a3832bfa973a6ef3d84e26eda15e51bd4b6ce17178197560b31600e000d8408bec6f053e1a5a353e0a6c6be8636a273857127aae3f2e92c7aedbef70ab7b2
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_helppack_zh-TW.tar.gz 4127479 BLAKE2B 3ed02ddcb0eba3abf21f2efeb8cfb5537283b40bbbdf80de5c118d59489a6100261737c1f84a7162111b8b223bea9695dd6b7b37e5b837c2c4ba4faf71b3a478 SHA512 88cffb356b7ca85a5f509f509cf08c54aefc88c949997f97595ea79b329bec7bd811bc30d5ad79b67bf0fb33e2c91cde5e8940e1c8da3ad2e726153a27b17d80
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_af.tar.gz 1238887 BLAKE2B 2cf93f24aaf040528e1c743469008ff907d89254e9fede75e69b6244fd97a8dc585542634032eb2815b0e73794e83153295688078e49a5ea33099cad704c0e05 SHA512 e0cc00e19e0dbed874d0d12307af0fd31d60c61375b03af4ea20eb3a8cbcc7890f9e7f795ce9afc235291af0b2ff49effd2009615c52214f334f4854fa0f9498
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_am.tar.gz 762497 BLAKE2B 3f3dd76e81fab94aa1cebd745fc4653ef28b1a7ad08afbf105d42d0c05cd3d08b1e4dd59cd383b2b0227ef554921af8408861426f3062312f0c3f22d9d8ceccd SHA512 36482bf2057009511c5f9048b0f43590198e2d065e354a6bb31d549854ff3af70d942566b154b3c3226279dd8acad46167ba6115a4514e7591c39ce8827a212f
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ar.tar.gz 2419299 BLAKE2B 60aaeb5ea744b749518be4f4581e676077f6a6e8cce12b526c28adf842a0159f2082e068d8e3a888fcb449a2e807722882abd4c12d71d10ae849420ce8bf7a45 SHA512 52bcdded51c3d785a48bea9a51276c26ebeb1c8284abe811e99f9be613213a7a2394b96c587dcc9e376de6eddfa200da73b0afceefdd7e0e9b7a013c3584c8ea
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_as.tar.gz 524724 BLAKE2B 01dc30a65e8eb0805425aa3bbce6e8ead4015d337526a9f6e718732e292cd53bbf456305e99d3b3a915b3cf16d5f05c11d8ee5a662654723464c36e06a45500b SHA512 21a68d4b84a1824fbd4a6e9b46e7ca75d518b8e9a6065c2ca14facb81771b8f3472bd717e8dd35fb1bdefd55ff4c88c60ba26b70208582c5d44e672f52f524a2
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ast.tar.gz 491918 BLAKE2B 2fa3acaf9896b19a24262e98f7a1149bc1db7a761624c6d3c95fa42555ebb9e0c4fe51605e6b612078bbaa77ac6b0774b458ddd62ca441f61828029ead0f1c08 SHA512 c7cfae37e72b76768fa36db51da61bf21644fa14011bcc2d0c20d3ddcfc511c13c4cc50c188f844d061ccda90661c7bb0b2ec60bc0f2b4dae6c0be6f4590d688
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_be.tar.gz 1054969 BLAKE2B f1d4238fcf2a548e1f780036e33def52fa6be185eded66310668805ed53ca05a90648fa8bcd95bec6f3e3c4cc506da80dbc2f67bd335ee94d26c9f6407472224 SHA512 e1aed3cc9640dc2e4ba99e083893b91c1891bb701b3c08f0be38a2cd1052f4539932fcc8d4f30b6eff9bdcf815afeec959b65ff626ab6c82610a54f7f22a388e
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_bg.tar.gz 2490440 BLAKE2B bd077c66c8f05feda48f8d520797aac5e0016f6e476d233fa9da827da9630acb08fcd7b9a78b93c8d959925015b679e546edcb26f59910c3794b0e32754fc717 SHA512 62728efe59535a4a51a1b260c974dcc32cacfbbbbf2aeb1be38249b4948db597658b8e15a8e56445779cadf6929fb798519f1ec633213c976cbf437795fe2df1
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_bn-IN.tar.gz 635315 BLAKE2B 26e50047b17824026dd4282ad4b5092105df7041ee0d3c92781b5e07d0b232f1fd5a09e3ce4fd8ea985d6fa9553a73e24d8d08ece23110ba068ca86cfd662748 SHA512 1647d5a95314cd04e23f58b894a598fc18bd5a72bde6c97372b15079ae7d4d4939552d37b524e3822ef777366276352aaf1753e1c98f0df8b32c51f3f1138e19
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_bn.tar.gz 785888 BLAKE2B 3ce6ccfa9e22cb5ef35aeb989b7e56e2cf4ae0ccb048473e3bcd638d70c753b2a540516682d7a0a62f512cf5d83495f30d81bf5a3e18baefe4377d1d3b7dcfd4 SHA512 36aa2d18e7a0656716de32ce48501b675dde2960b54b6d456e39dcb91bd8b51e9f54f7a470ea488542c10a4f0f4798f8193d8aeef0583f3c2d363016fb82b741
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_bo.tar.gz 379206 BLAKE2B 7895843a9beb4f11aefbf92342fa25b12775682a223228ea742364454602bf795dda57a70002babc14c8fb47455fb974523fad65b213c01c5e7e17511912b049 SHA512 ec64ccccb17f1a62a975686b5b327fd68a095fef911c20b20555e8f5dc080d873b2fc5977cacd5c06e40e6407c2ddf20b26b41f060d2c3513db27b71255c9e91
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_br.tar.gz 1522773 BLAKE2B 622f61d4193ffcabbd483ca59534f35ebe584579183677269a38c415827b01799f5c441e5da8e91df7bd42ffa8013e88138e4e7cde4ce4c0dd0c31a1a4b4bdb1 SHA512 d263fc6228978412ce90c8143ff6567d7dffa49ce3e2aefa21ab133a66538a0f31893b41cf0d89757302c6535fd8515cdd2eed049495e4f7f69b2dea14a67b89
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_brx.tar.gz 336631 BLAKE2B 1aa8202de32cbe0d451a876fdaa1af2cf43397ce056ad14732b9e57ff9dd0901c2fe1bf1cb5b93a3b0d19dd53eecde4cd3794d853e7499dcebffef8779bf014e SHA512 f9f8cb548895fcca99bc26316ded06fb3ec2b045eefaeb23a851ae3f24d8ca923c9adcb531571179e71408f848ed55019df54afe3717e03bb1b12f75cee4c90c
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_bs.tar.gz 629067 BLAKE2B 74b7b73775ec5682b6c22b50bb1fe45780514798ecd09804bb364312d7db61e72ce967468d50e36aab405f3acddc499cf0a5e46d140391e5b958c9f49378ce34 SHA512 c3542335608ec0d4a4b0837bcf2fddef4aa853bdf2e260e6e4618e6cb4c32df0c8ae921d8adaac726a7c7d9e9d71c7b4359df91a337b731347c372d979cfd536
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ca-valencia.tar.gz 2480692 BLAKE2B e834c5db7f404acaf1cf8f271f78410034e1db022060af2472d94fd1edeb7ed040f22eb3267984cb1ed332096f8e2e73944196f908e9c1dc9fb44d1a4d2dbb48 SHA512 04e4e00a90488184b33ec2aa445790edd5c1c210362bba176fd7818b169a612d747da214d56367335746b9ac0a56666c449e976c6b632bad7d7455a7ac5eb74f
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ca.tar.gz 2481370 BLAKE2B 6d8990cfba90b7a0cdc164adcbb2ee90c475d7f6f25db5a56f7e45d5db271fdf1c1784403aa57031c61d31d1465c1c657bc6a50ce674517018b52089e3ca8513 SHA512 6dd4be1f7de389efc66c548ac73adc01dc3974101640061e018738366cadf2f02b1ea54e0d5daa4993e7412b693bb879db9822d1bbe29fb46862f702e29b8440
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ckb.tar.gz 366503 BLAKE2B 23de6c3cb0f675f038fca951b9e25fb7509129f2dd2eefe129a29d8ab5c049c813e3811b4e7502aedd81fa68fe412217fe5c4e20f685063376198d7d198c7e3e SHA512 e6f397447d5783e47e63c10b20b7068364568f22b57c3cc4634041615e4aadfed06ab56e74ac3b514047d5b1da5ba69c6b6b211559a1084c8ff1aaa5b4ec7d72
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_cs.tar.gz 3229881 BLAKE2B 29787d4490397f649c48982dd2b145a64e086dd06dc085e574f3ac27bec82524a6ddfe7d3c98c002feb65d923fc2f10870a956cfa223817ee5d96ce0eda3f931 SHA512 9243d041b1d57e7f5c2903495cfba58483d0ab8cb3b92de6d1e93a5b75f0548c11486524acad96e6c50e61f9fbbe2ca882374e52403e29b044b397a99c62eb31
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_cy.tar.gz 769544 BLAKE2B 509100060aa2cedc190a75ce3624966030175ae9325164e8e4f47f57aa2e9b1f1762f5f8d2ddd20c2ff7625b902d9ecb5620d579db31cef41281f8a816480a5f SHA512 791cafb7f0f028c5db8775ae23ca8608a8184d1e5cafd4eca9927bc95d573529ee549e4fe5bed21357cd45ea3c51f9188a591b90b99e47bb966f3e6419ab3007
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_da.tar.gz 2867449 BLAKE2B 0117701326b283589001b3ab5e7c7bbbc59585a89b81131ccbedbcd3297deedb8b3520bec639468ab0cba0d6e03176f08a0aebe6d8d50ef557ecb8118ea43825 SHA512 72f6e9eeb7b507a12ec250020e278a041febe1d6b3dcdf8b7826d56190efd72389a4c000608c975c5fd0ea8a0833b3dac0149f756e9b582fa66f1ef5b5a7a4cf
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_de.tar.gz 21797932 BLAKE2B fc001219a45ebf883d02b383007234e79da51f4231ede0e80bd0cb38e1b8f3d01dd5984899d216875d0d69bc950573c0f3cc5537a28acda35a994d077cff4adc SHA512 a03451286f51cd46c1272652fef03b1079b8d07af8534b1de9d05f35de3aead85f0f80254871650ad15780d174faaace79e940a330e5d96499ccf647b2298983
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_dgo.tar.gz 435846 BLAKE2B 47dab31264ece9496bad10a70816970a72affcdcd603a89b00a5222ccead96105207f9855979aee273303e936de6f7562cf631a9c6354020cd78d00bedf62573 SHA512 af30a85de2c77cbd4c27bf921deb2619852dbc3db5aedae94b99562c2bf285f8bafac8ef7c647c499aff3c432a904b590769db037891aec4b53b1916dc61ee9c
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_dsb.tar.gz 792238 BLAKE2B 50d82a06966693a0bf11c793f5d1572e5ed1858b1f0e4037da24427dc7cd028113e50e334412e29ff9a6c0b256980d06bbf4bb5b8e07380951eec0994df1ceb8 SHA512 4d82348b1a7199c6fd6b41f70faf412a5986ab91dbea700c71bd28d5618abe291977f1a47a5ff0ac5980319802656e4b633ed84864eeca1e8347ae017c6f46f3
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_dz.tar.gz 366605 BLAKE2B 35a5ae10daac7b7355e2fddb4b3f97579395e09a3bc665b4f54cb95e3f981b2b578476bf1560de2b2fed63cd61c5816b8ba072286e369eca23fcccd02af6ff70 SHA512 941f2624fe815b2387fd672244d261f490cbb10d5849ea603046044da3bba1b07b16d3cd5ad2ead2d609aeefee0f490ea9dc02a4ecd7523535ab8826dff9e274
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_el.tar.gz 2876894 BLAKE2B 580b79f23b3ac4ff3ee3fb812743ae9f3d112e9bed46da669ec2ca1986943050ed7c65c6de7e423bdf319c27d9f809f2efe7088dc90f7ed119165c4b8b0a6928 SHA512 715959fbf9e330bc6a6d9a75fd757b169e742a16d55ec6ea4c192883daa753b9dd797501284b69cafeb045fe12c7b415bf6f8b259ad26dd675deeaf3b96f00f0
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_en-GB.tar.gz 7390599 BLAKE2B 246510a18e9fbeb8da03c4a24c79d6dfbb8c6539b44cb68ed4b7f4bd7e8eba95787ff6774a4e00877cfb6c17c0a2e1f17776b3719552cf22efe84be378b1813e SHA512 a26046847e96bfd2cfb4efb89a598bc370268a90c9b6ab9a7fba024f19983aee5ba34cf874f9884b81175ec78fcdf6259e46abd6555f7998b8ab960ba682fbdc
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_en-ZA.tar.gz 6935767 BLAKE2B 712341a5d8b8667e13b836a909885378458f9fb710e3746b2996e43595fadddd626102444cc5debdfc11d0ba04fe36bad382ff701d4191e8aa457e532f7acc0f SHA512 4b595ed345e8c88bbb1a0652a431e987caf4c71a8cb597fc42ffcfa9938dca93fe71a01e9bbb30155aa30b10d01226f16ac779bcbf1ab5750bc67ce5ae27fb70
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_eo.tar.gz 765175 BLAKE2B 562deaae888f1bedb3301408b6273aff68c3025c29d304acd981da8626f77324136786b7f8e5ad388c470c992bae25bb4c8297f6f42834b17164644ebab047a9 SHA512 8e6b738b69c8bd4baaaa129b7a2cc3373ec87710cc9b858f95292ceef84e419f18de72e1fb76fdfe40a086fa0d1992f20b9f3c45fb4eb01ae8d5c879fb09ed49
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_es.tar.gz 2279842 BLAKE2B 9bb8b5a9f05b5d6b13e724f37cc44287aeb97f1d23491f20cc169ba9c2d8b64ea905f90324a86494109cea9e1027d749748a50e06f72f976c94d769fabc0b308 SHA512 d4223462bb364e9e6d22803ae75e2e1eabdbf1bc647b2cb57876701f3fbf2fa8f647cdd341cc785b02706aac5f112a332888ad037b3a84bc4ddfbff971cb4d33
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_et.tar.gz 1681545 BLAKE2B 4489be02729faf754dfb072b182c02aa943897829b34c5734d42395306b626bafcdb2c797d042e1ae093765acba25ca00f6eccaa7937a7edcee3ca164cb786f1 SHA512 65dd86a45d6a6a3f34fa150e15c4801523b0b7ce7748e712972a4c2de15546966c24b5e7c750a4dd2d6508385721b2ac1ba90fb729cd1a223faf01a2012d0de4
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_eu.tar.gz 774989 BLAKE2B 48c4e9b504efaf9e8535aa622e0b0bb1cfab6535bb8a80ac7a4c6ecf932ecd686b5d6f3b125f8c65614f342bf89cb0251a1fdf0c84f7ca54fd2591270bf734fb SHA512 da6368dc0223d1bad573a1f1b336e2b246b0c258ba9630c57df52978f04101ded78b148ef9902b0eb3e3c09658c8262c2c9247f239afeb7c6d59326f081f8678
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_fa.tar.gz 351757 BLAKE2B 2012b46b3fd00c53b4e7bf1cb61bc903c9f827e8146133019740a1a21f1fcdcc50f2a70f1957a08aae0016828f3ef2706da5241d0a8504c66212587fdb4e23ad SHA512 a4c99949dd151ca3dab3efd4f5bd0a0df606bfbb5afa7231b679d0ebf6d619d312d120abf5e7517b010a0f32e8fde34b52f74654827f9b2adca015b98fdb413d
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_fi.tar.gz 746794 BLAKE2B 603ca9361fe93cc710d46cc3e494fa0e2994d07ac848bced4217a5ab8da4819b7e6d7ef7f76dfb164ae122e412608934e41ad706dfce1e2dc9ff162bd3a601d2 SHA512 8721bd9adc6c04430b069e30bdea198f3fab6e1c3361ea34d206171247ed9b113e63d8e75776b988cc021267d78c2304a30647c36aa3550fb5192f822460fe19
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_fr.tar.gz 3077134 BLAKE2B 8772a7e5a294eb25751dd6060707151669633e450eb93c94fb1c02085e7895cb6faa70a5f0e99ca515888ea6cb3ccdc2e9b7ff07a8913d7a28760fe776384876 SHA512 c1a2007cdac9b45b6bc5984b9e1c791f228c059c8d4c79fa0260ae268767a437a7ee71c662817fe9d0aeb4359dffe9b8fbf8132aa32570e48febbf9008c1ef0b
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_fur.tar.gz 169546 BLAKE2B 6a7dfe421d77794ada02ce9750a5de1f62eef3aa72e42afb1791c0bd901c5b1234b011f21b112e38eb787a20a89207f44fca0c565d1aace18a1ac06dcfaebfac SHA512 a9e9d3f04fe8a2082413122d8ebb4217252f5a6af340d44933c27040901798dda26607c6846166fd98c8fff770eff62da34ba339626117457820f6c7deaffc65
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_fy.tar.gz 774299 BLAKE2B e287d32fe6d606ba19fa9b6b62d06b3ab382d461c996b292bc86d8b53b7fb1ef2cbe9c93c4e5f279bad82cf74e91c1e327d704b2faf6687d95ab1cfc0be23ce0 SHA512 c6ae8fe0d53857aa08cabbf5c2206bbc53c710bee686d2a56c6b4ada9f50b1c2490b2ccda28a47e8e2271dbd71897bcfb75e73af040f84abe388b9349f330441
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ga.tar.gz 729048 BLAKE2B 2cba27e4d7e0df15f9eb9d54a3f04107d3c636a1db0ba1232cf6c28a0a590c28d9c32358f94a96fdc277cff3782bd794503c449cc4bad616f6444ac64d874602 SHA512 033dc0c2fdf1e54a6ecb68f3717e13d3b362f58571064bdb2d40ace4027ee71f058385f0188bedc89726bd76c43c5ab335a7aca740832bcffc67ad08db6d9fd8
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_gd.tar.gz 1776077 BLAKE2B 8d5f08ab03e7bba9d1dfcac7b4484624646de49015b22ad9b8e6727df4209f7d4e615e49d3666d28af50a96f2ed09f3e12027f16f931a0a0ed6a9837e1afb097 SHA512 a99706465628106ab72fe12795a0630c8ca4562e3c8b350e6769878d8680ed4c6a9cf468c69a37ab3b731599f48e7d2e0b1269e3e73b074b30d0a607ab4f66e2
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_gl.tar.gz 2664940 BLAKE2B 199a2de420ffe84325cef194b01ce038779a8472e92038c5b2356194098f1c28fa75062502f1ef8e4d2401b455a614d55fd34d3a97ba8b43231d3df5510b21ad SHA512 8f13458fada1ad15442cf7f658c52057be905a300d495dfbe97843c4418471c7b0b201ff9b999de9725fd6408c4a78cdfb8124469ca39ebc54519bce628a0b5e
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_gu.tar.gz 1218176 BLAKE2B dd421cca78e07d06cf05d7e528ddb89c8a6921637114c2306517e13e3788c98ded1b11b44c04678bfd7909ad2abf35925c5d89af7cc42cb90744bb1ab5a63f16 SHA512 0ac9555450e531569ecb44ca402df9a2d169d1708df435126c23d4912dde468aecb1692d36a22ddecabb8f68ad61eeacf3867c06ddbb39cf2a20c236c9f04015
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_gug.tar.gz 513036 BLAKE2B 262c329f2a73e22a975dda883ee8dc2c395fa607a86eb13ef291f4f7987b25294fdd636a4f19216c4556c4e03a5161bc98f042fdf41e3f308e489d4f11d66056 SHA512 8235b15ff6ef5479962b4149d28fba826b9d0c94a7959df7ef4566172788cd0cb346d99c0673478ed800137e145159847d190ab66001715258cc0d7df09d6f36
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_he.tar.gz 1668424 BLAKE2B 868024ccdc9d2cf1f08e49e2e35c0a0e8a087dd7e9e3e71d62b5faffc8ebee6404db41e3fe89e618b0c8a05076a8efe6f2cbb6a57b907e36ad6ed9b735a999ca SHA512 639b3bc0de812059fbf30492218a7cb00f68eff0b78efeec280aae335922ecc99939d4af0d13be5cacd2fcd5af4c7e074d9a121b9a5d117997f5da11e9914c42
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_hi.tar.gz 563580 BLAKE2B f5d5590e6d99da9fddda8e36288c9649e30a4d4826beb3d5b22e94fc99988f7594b60f21c134efa978c852b137ae93c030566de8fa3a9303d0486584dd5ae2a5 SHA512 21bef46c42f4cb9f8c482c81317409fdb661fa131ee8fae91b7feb61c11c3c7cc7c5f8743b0f04c6723ec6d0a179f70eb047af4b00231a8d35561fa85a1168f8
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_hr.tar.gz 995294 BLAKE2B 4ab8c14297a54fd1ebf83d41fa1dbe75045ef6d5ef312390f8d5422831faad1256e161edc1a6d92c76940a73159f915eca1da3108ee044ad9aec91e8b66bbf87 SHA512 c804564cd2683c353f5d7490695c6baea50f79baacffd6f0d7842c5e2a1901ae134b77cfbd4969da319b627c2fc239b9c09331b7fe31adeb3dd6b2d32de26083
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_hsb.tar.gz 789912 BLAKE2B e6c863a5d596ab0cf2e936065d4f08bb0f2e4fdad150d09cdf03840dbb194676dbcf67de02701a3391fdf08acb726039e49ad99c2f401e914496813a7131fcc2 SHA512 51908124d531436765b22e993dcb8305759600348df2d0b1a2274ffc1a04d3fc46b39d1eda4dc2706fe36ed09819537d6e6157b816eada106ee2ab56bd14175b
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_hu.tar.gz 3060681 BLAKE2B 75f5415db7f6e195b3bb492b4a7e287f9255081338aa60859fad49039305add53b485d7650de83325963cba994a33afb5378ba6652e5f4486dc778b43a6e9c54 SHA512 a0a1bc313dcc8687ed9a21c96886454fd5b4e9bd56b5601265cf997db27b0264ad3fd6e6d5949036d727de46bfdd79ff14dc740ad008ac26cad1513cd47c7155
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_id.tar.gz 1632605 BLAKE2B b101632343d0823acf3fb13531e4a3e2a7cb5ef32a7af2a3e93d68790f9a8321b6eed76487dc4b590cbc2e0f5cb6d2063562404588484c134a532448b831ba33 SHA512 40ec4db03bb4ad09394e03ea1bf0b696f64bab90c79f1559a3c47c41be10ac785b01e4f8403301d52635313412034639522ecb4c810d6f5eb1a0cd99f35da411
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_is.tar.gz 1540205 BLAKE2B 66282c5694215a6f98a96d8508f042109d9e39ea5815da6f3bbff12d4cde0c93924e358df8826deaffc8a5c78716ba14cf99ad1946a5a80b48cb009e94f7bf45 SHA512 a4c2f015d16f92238aaff6a81f1be651b8d5319d101768057dea60bdd7ef32c714b11aaa8bb9851204cae5a4fc635804a5c12bc498fb61e07bc184d179c6199b
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_it.tar.gz 2106721 BLAKE2B 6d2cc92fb24619ec25314c51ae2db6d79360a8e842c9479245c044723328fffdc291cac47b4520a1a53c9d671c8f2a6188e6f9fff406c01fc91220018db17795 SHA512 ff7f1f7b50e63e6eb97cceac5c72e4a4d1ed79a86b2ea433e8891a200fc98e2977c4b74ecd52c250ce4017a55a2ea9924e709c756f29891874338b50bc9eaf1d
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ja.tar.gz 845856 BLAKE2B bddfe4f434f29268812d7e2a7b960435f88568284bbe7a2972e13d6777ca38eac28749571517be6d3d94b4de3a4b419418aca4ae0b3e5f7fbc0bcf2459c17594 SHA512 30458ed9865f736e5b9c29f6d48e1efc3a51084cd99e49a12bb71e4527e542e6499c59da161cdc4d62f5785dc1f298737522b8712f6aa44f8c2221a47022f0b1
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ka.tar.gz 357702 BLAKE2B eff2c59ba1b44057ea3e2419765fecbbd4bffdd47a27233b037ccb1ec484fb722f7f4e6bb9b37d26a878b309ee3e5660b26062a8bb12b2c0388b5308707eb1ca SHA512 0ddc93a5bf6db04e9db1819492641e8bb3f359060cbe3c751a8ca6ec140f2080013e0751127f0dcac5e69fefe3e2a1b95fcecb7544d406a3b839183669ab95ec
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_kab.tar.gz 635880 BLAKE2B b901dda33a8c27626b498e34d1b95418483e8c67df294675087d0ddcbda9a80563782061a0cacb55f6ae357868a87e9681078f8ab0c9ff95353c5308f3d78f55 SHA512 42524faa7c714af338adbf607b0cfb1e31c3ee0ae658392a0d922f06f8c19db2bbd71509da7a205c50e433d9a356c4da48ec0c5e0802e45cbfc708bdcb341628
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_kk.tar.gz 832224 BLAKE2B 2bc6db25752094e6de2a0080623c2ec6670fb67ba50b01a59be389a5245165cdd15380baabd5a16993596fd941bef99fc396648924f31d8597f939f2752169ac SHA512 6d3ac07ba26cdb55cae5b261596f8f1bfa03d83d2d4beb7fe560292e6be62505f2144abf4af7abd1d040076c9f6f96dd9860007798594849af28ede963866a41
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_km.tar.gz 669649 BLAKE2B 5a7e9157a00f288ecfc27ddc59f8dbe4456a986b2dfdddca583df4d0e21ce78bcb1fd45561eac82871c091844e68dea2645c2c307529b53477ee1eaeb4c3a547 SHA512 7089e3021206c459a91c0e392cb2d9606eb9fa69e04893b874627de425189c53dbd55290ec3205e1bc6d602bc8f710221562e7f242025f74cc0815bacdeb2a51
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_kmr-Latn.tar.gz 335553 BLAKE2B acb3b7892ea936ea32c3c39872bb767dd290959063409db7ba531b5ed2f393ba440e83b832d0b07cce1a57b42354f202191f5a518df5d710b51283086b52ea14 SHA512 280ca3df4578cd22d490dfa652e26c20f94633258494d170e36ec1cb2f1a941adb52c6b17a9f3151723c83be7088964c0b4509ef2f27c622e7b259e572ec0a18
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_kn.tar.gz 574926 BLAKE2B ae14336f1f93f0d1592a53911a4c2e777f3543a1791c6b1a08031efc4f22fba39df6f10a16e2dbf7dae501eca7fe93e405a0737a9d3f9c8205fec16855944d8d SHA512 ee96f31e5cce3ad43e75ea4241bc26954a84bac182d33f06439112aaf84f4c5c2e4a5c4b51225feed7063b69d2a87c6501bd836e03a8202315f71579ce1de1bc
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ko.tar.gz 796596 BLAKE2B fb535164662ec54731c56f5aa40843c5d62c32be1561e91a2393e8d8117161fc04aae768152bbe6ddb6d0b9068e23ff76ff9fc157a02add0310724a2c868bdd1 SHA512 9e0f28c14525bc7174b48cfa681dc5780585bc1a63cf9b065558ed857965114a1cdce70999d715e78df45da03811ae602d4fe4fc5917694d0d7c04e8337ab6a7
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_kok.tar.gz 409379 BLAKE2B d28000049ea348d4831edd6b2a6ae7e3549cf5a6e5d2b54835c524a7854f4066fd87e91792f0f8c4556fc82e4fdcc271408485e4b6ec9732d9f65fc1a8bf2a09 SHA512 986fb2cdedeb8cc958a0aaf60c7fb58466fc076c48f77d81dec0e3d0b4087cfd2f1c643ccab02c0e12bce42a9fbe9860f422aaa46afbd81225f06791c2ad281b
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ks.tar.gz 329816 BLAKE2B e47e688baff1e701d3cbed7c79e71652794da1c229ed14d8500639d82a905d5146f4944113ae6f90c1a1943035908a81b75af4d6aa0e050317234cada24162c4 SHA512 da58591fb5158c408eb74cbda61188da8e838828b72c3db7277fb206a2eb390c219a493101fc7517b8fac9b1823763ea2a05dce7be0e3cdae1d3288cdd64a160
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_lb.tar.gz 147726 BLAKE2B 0241a58f84391a47e4dc6a47b47064e0081c4e4dccf2829b0c984b22a0de644acba45a60e981ece4633eb432871154da5bf77fdd9ff8b9f023b8c5b19e937ed2 SHA512 ecdc72023c380783f1cc3a03a83bd75695b2c511c187447b987ac431bcab80c242636f8b3783d980d0545208524446468d412c0598e648e9d6e896fbc0b1facc
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_lo.tar.gz 433941 BLAKE2B 6a056c1a86e40d9543fce6ad1ceee446509fd014e1dfca097eeeda014b833d7159500d3265f62b8b6c89396b254616e1f1a8b329ff57371a05edf848c7f7c1e9 SHA512 dd577ee912e4f339215f91dc316493b514854dd465552a592260137e0f870f7017c7d15d435c090ff8ce1b2f69c707bbd5f8e0f90e8b314baba55fde722b2751
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_lt.tar.gz 1068025 BLAKE2B c70e8e87cabd1eeeafa06484b987eeec59bba52bdac2b2af05b3e841fb67a8599074d24ce599759dd7f93afd1c15125dde68f2b74c26bcab40cb0d767c0cb85e SHA512 ef536eef14bd90f012553048421932c94cd85053ea83cb39bf9a38da75e1681ae78a8f8e8bec5128d0069a39c9d305c721173b06683c835255076c97f4d9ef7a
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_lv.tar.gz 1164900 BLAKE2B 17fe83c40c051007392f204b5221cc80abc179503376b4988c9b7856f885d8b22b7375d5f392375e893d3241904245f827a50117f5d7dca7f848b4d7d3b8ce32 SHA512 c81a7ca5796ac6b88e79ea27a90f1c5b3d9f6c2f8f173b2c4cd72b7cc391e2cdec0848d24f5a5e888301237ef84cc3ba9efe88993c46a988fc66a2b7ab29f834
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_mai.tar.gz 331689 BLAKE2B b100de2fa0383b1af2572823064bb3ce609b8e2638d4d3668fdc0fa60a543f3b0409b6896674ec712bffcbb594d35d631bf0de9d1ca00a212e57899f69cb2b45 SHA512 aa99fdf85144bc8d386f9814fbd681759ff7bb23f8a73979d648e7eb3768707d2d197a6cc71c4e7c207dbd87aa614b65925812e0334f3ee25638b28697f9d6d8
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_mk.tar.gz 382021 BLAKE2B f408ff1b0bae59ed1068b1f32c376bdbd42260639bb8db50ee438bd86779717b7e88ed9cabf7b94125fb44584ad65cf78b5706d6c1e33ba1c47ad0157746e908 SHA512 e093156efedb5fc1b2b4dffa92c7598bc48c2762df20de0fd9e32e1c1248c2e35ebedc0cdd4c1f57b70ab0e9ec8441c1078b034f4085baf4c468f21edcb2b22d
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ml.tar.gz 533261 BLAKE2B c3756041c71f2a22afaeb447171a71388057c02dc35a45c98fb883b87a4a10c6241e412abdc15271b3fbe1aeaf723a0ce41f51144cae3671a989e56fac324920 SHA512 44a0a00af879e8f7d2fc91eeada832c42e6d37496b726b7d7fa53e0c8dbbfdaf80cf91ba05a5bf0f18dc29076938a7f2a79134b258f6cedbdca1ea2c5de90e46
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_mn.tar.gz 693521 BLAKE2B 3ea6967056aeea91a331fd72fbd916d51dd08d68e39917745ca090a346204a2e7c6453dcdd2b16367a594f70c835f20110ae1c9dd4d0828c308c5f0a7733d2ff SHA512 7dc4e14759518fc2b95181b43b13f8f7b51db64258d438ec95c74f4202efd0e38bd44752f7489a35d46e2847577a30f6cf2faba60a6d8c867128e4c2013221bf
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_mni.tar.gz 400143 BLAKE2B 529644a375a1bbffd00b6d0e492d7784becc6f2ed75b0c0fc39af47e6d85b657205a5e79b9aa958dca948247cd9d77cf09ee9ed219bc7ab72c7e33c6622c500f SHA512 75c9ba0d6c6b92ec027327f9cf68db10777497b8b20cb621f928f6d5d4a78f16eb3fe4f4c28967deee3b37208ba43bbd11b70cd3e19e32aff32d915255457cfa
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_mr.tar.gz 568689 BLAKE2B e97cb131b4b165041143c4c50186da34a6265eb79322114a441fb853661c26e8026434367270c38159555cbea5ee60a3db7a19e85047715f2e8eba6b63601e9f SHA512 680af022ca011f7d027eb45cfb55f62bdeafc853a9de4a9c6fc8867785c2d34b87d669c70a9eaf0520016650aa1256c11e889aa747efbf1808abf46b4cbd2c65
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_my.tar.gz 458979 BLAKE2B afbdc44b6764f43cf64a886f1f5c648df3828037203ddc96f0b6cd32b2954bb6042af4742fb51f9e79023120545682a3acbdd65d2791d4b0f3c4d3f1cde6281c SHA512 ec302ab17a953453ba05a51992d36f6555b3dc7ada4ec2039e937284adc132455737bd072317a3342ef6abab586a4b0e1fbe1b95b24bb84d4d752c90872fef5c
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_nb.tar.gz 4107252 BLAKE2B f8f5f4ad60c99f70deda826fba910a808b36e039f1108878902e1191fb6f88306303223fbe806cb2295ee1b7bcf5e994c5ee482faf205de35b86fad7dacaaab4 SHA512 bb2eccd08f63da987086eae735409cf6911d90aa269bc5314ee7f822415f972a01402d7840ddaf359f5ee8d6f735eb31e9888e493c513f4953569e5ec32e1846
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ne.tar.gz 840754 BLAKE2B d4e6f07e2301ea206676f03633bb5e88c6bf2d740c8ef124fcdc87c434111b0f24232c1caad4f923fab68084e4414165b563ba13015371630e31421c00fa00ae SHA512 ff76336f88c14919835a3f6c529e6dc4b2d0873bd831a5eb6650f0ee4c53d22a605f935e65b6a4ba70009baabbcd1ebc55174f636e2101d2ab4c1e6066d46dbd
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_nl.tar.gz 1564811 BLAKE2B 8a14f3c96f131b483037ccd899f407a7e11805a9c4c61c5fff52b8cb67c300d0fb36d41991b6f47b87648191dd9c57811257749c20ab0a9e7460afcf21f99353 SHA512 5a0c1b4f73c2cc95c90e41bc10580ae1441c0628e9017a8a5790c21f061ba4544f8ca7f42533c3dd28cb6e6cf7153917775bd2d73ababacb6e361903b70fe96d
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_nn.tar.gz 4111023 BLAKE2B 5bc77a222bfacd06726f02dcf559cc846a13d17dd91cf7c4f925e664c53ef00c3eac8e51e691e076d438755c69fcfab16eea49b9217b7b27399129c5f1596832 SHA512 6e67a280201a685a94e98e7cd003aa74a00c2d4425ccf7f83a03a793cb3f22ae4e113a532563f2a3506bff9eee6ccd16ded8d78f42a3dc7d23b66f6f5a6c047d
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_nr.tar.gz 279236 BLAKE2B 577cead278d7d6a7f513d22b76784a5b4ec2158a1fdcf3cc690101b4689af1cecf7f0e3007d10f083147ca41712c00e27afa3cca1cdcf98b6050f7884cf1cd3d SHA512 c07f34c5f6103d33db0fc74fdf4c720b52b5a92b52121a8886f9126659298eee51dba25481bb4076df075914d700acb2acfaa9556c5de86e8a640df76099508f
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_nso.tar.gz 321812 BLAKE2B d4cf4af8350aac2a1092b793dc7896575360abf85b063de56b2eb48180f5a2036a9410c94367224a685a587edd326bcc43e687facdc95f1968f8f274b972b8ab SHA512 95bf090ea542cdb0cf1cf5daa477a196b4b412e6e21646373a22cefc4ba4b8847b3b66e1e5224110ad76dbe70f98ce8b1d3d48dd0346bc4478584feff157aa86
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_oc.tar.gz 1314191 BLAKE2B 51199feef6fc8314b0db4f1aabf4f116316091f165b1d3fb839df1f99026b0ef2e6045c8a1aba122809131f56c339b2a60367a05189ebcabdf8cfa87657f7510 SHA512 ebe84f508516577fe7b75d255693f07f338edc07a786742bcbfe2dd98e774af99572f460166631c78b6c545851eb14c5f7740e1b143be1a75e80ec6a22104058
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_om.tar.gz 370303 BLAKE2B 9304fedad52e81acc296a13ea563e418d4941f71091985a44ef2c23e42358771cdff3ce071911c46ec27a1a9a431f70d24b2214210f7f4cec30cb0173d3f9c15 SHA512 3da5262f519d096af87a9a76d11e0a7011825dedc88eeb254299d46192056c740953e32c0e61ff519afccbb984999377accc2470e791b02792ad5d4bc0ee7a0a
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_or.tar.gz 591321 BLAKE2B e89f95674f624eb73b5f7254ae0d651dc71f0946790fbe36a8d74e01bb8542c2310b3c51b57d1aa2f1c64bec027c279e31413d84e3cf524c20d85719806bdf8b SHA512 3f5c4b816f57f8578b879264643c18f6c5381648ec01dc3f4a9bfe1c6c06d7b5665085eb3f1c58ed9dfe930a5e5982c014d2690e913a93bbe6464462b4d0754e
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_pa-IN.tar.gz 469668 BLAKE2B c493b1982af8aa7b13ce5bd7c6a75c2f913c44685f635b0ccb86fd7b95efec71ec7d784d02b4dcc7372ed38320d6e2b855076ee52c1a88e2ddf345a52afe7471 SHA512 6c3360f436fdbbbc5afff718dfb721d80653159183d47bf9b6a034174f69285e67882a9070322589d70d899eec3fe78f320cda43c2ca3212c7bf42135bbb9464
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_pl.tar.gz 3136176 BLAKE2B d7d39c9153510c88a3145d51a28b9bda8db1a85cd525783e51401682a2a3b2d7cc325000e206c80934fe3a3fe69ecabacdc2e221560baf7fd5ef42d7620ee305 SHA512 46cce52d799445c71d97ca091ebcda41b99511396da71b8364bd187516928b7833cf415ee5dbb3ab231e90e96e7c92a826281ccaec181a725ccfe551a1fce602
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_pt-BR.tar.gz 2855701 BLAKE2B 9cc9d36a77d1969be522e4b1748100fe40d281d6c817eb39b1ac798671a4c41455045a74060ec45630ad5ccd482dc1cc214efcfbb2c5a0dacb39bb7e6883939d SHA512 bb1e91f26ea2eaef203f65b10953649060c0c895abc5964fabea5d2aa7b929742d4b01e4047e07dc3ad2efd3d4b4314efe1f045acc9e511a629c735dbac02678
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_pt.tar.gz 2411044 BLAKE2B 160111f6b8ec1d5c27d298239e36f27078a7e965a3cfb42212b256dc2150f2a794e3c9fb74de884fb45b174ae6c519ac7af30fd1b241756d67f1abfbf5a0258d SHA512 ca408e12a7e08ed7b0021b45a1bbb1dfbb5e28ab0b7fc0a68d69744a0c21f19e16c4b8e0aae8aa2d7348379a97b985b0b16b58e7dd478810569e9f1a38c46676
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ro.tar.gz 2514221 BLAKE2B 814904d75da994f5479d29280ae6771d55f7cb089b0e56d0ebb7ee70d03224c3b1e1850b98c9bf94bb7857dc5472e8954426d6ed0e84b317255a5ad3b691a0c4 SHA512 6989580ffbf8f4153386fdef532d89cd6e2545cfb83536dc48eab003f4874c5d743728df116edc541c3e7565739bc2b6f960b761bd561178e574efc8b1e6efe2
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ru.tar.gz 2132398 BLAKE2B 7392179edf729c0ce367a997c4e2837f463ce192df66a2929240bf923e674b9cd405da174dce24c7702a48610b0c929f29ea17e113577cf7db57d939f0ebc9e9 SHA512 1a22cd1919eb211d76403d950eb848acfd03b0292cf707c585bfc364b27b4be16da69af6866d810c9b188d14445d7adf6eff24b413ad065a90219a1cd6d502b4
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_rw.tar.gz 346499 BLAKE2B 7e648c7622de9bd21eac0036a21321743fcd5ef5d1d01ec6ed0a70c2c26b31253c010f61d3fcd9e6e427dc0e313cb1e4cf61b6d62fe3002f1a56a81f3360eb90 SHA512 7349cc6773f9cc6ab4fb8022007cb1a3daa22ac62956190d5bb688e3c1089977ea634ed20d76c954e73e350234cf8b9383677c054306578047bacd56fd66b3c6
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_sa-IN.tar.gz 446216 BLAKE2B 2c4d43a62fbfff4d0c6e1ade4845c0b88ee3493d3111b1952f164097f2fe5e9843c5ea86fe2714fd22adfb709ca84f053901cc66607458b3ebe20a201c3fadf3 SHA512 1b7b2e0f6ed763b9a3eb2f7d695d34db25fce6b6549d8a82da44c32c81c0419af204e035a215d09d22f5d6bc21d1cdd089e10fa8d3a34f26783537d719586af7
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_sat.tar.gz 514302 BLAKE2B 521a4c62dac53cacf5e43f3014cffa3602a166bd0a9f91fb2452d7b31594344e4d907276ff3ca08a8534693462ff8b75f164d64d997613f9efd9dc97c33cafde SHA512 0c56f590d28217cd36fcf0c945d6e0ce654f4052ec8c46b6238600eebb140597abce1b56818d4cee3cfd58bbcf316404c902506c10a25da892ce1efb070c0f9d
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_sd.tar.gz 433404 BLAKE2B ab9f97196cac7192e820dd74be8923085278974b3f3d60f02bf964e30ab00ba793570c5a0f79dfb21b6f211d789822ecfe6dacc69262a4655398cf93a3d077c9 SHA512 b4dfa8d57d632d7b1279bf93337d61b68b4d6d087d5a5933f1a5ad98a1223d907372721d20d90659596ef53ee3612d95ef0b5e0d8080f2e5fe56c9c04cb65d7e
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_si.tar.gz 735593 BLAKE2B 9cb6787e6eb8d9708fb6dba686b37f7792cc6a652e110e3f00e788f23237d60e5114068291c548d78bdf2b0a3c01ce3541e0f1b6e859e28817bb61abd808597d SHA512 6a1ffb66acac7ad028bb710967beccfb09c47aa0976917893cfc56a88cf5e32182fce5f2e3899cd445a109be2872bf873e3e8cc34504e09f8cec331fa46eab40
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_sid.tar.gz 444964 BLAKE2B 87b25f1523618d8f684f477a56ea0ca2933597f19f93d861518f0abdbb407f2a13f61cb4d3b45716ca8120fcb852b6ea8069f17ace190da1b6f8c8fb9cadceff SHA512 302d066f4d117f8de7c04e2ede374fc139cbd18d988b45b63915d55a3f366681511f424d4365546ab18b42f13626d7bbacaa02cb632aea93aa68922a19eb0c32
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_sk.tar.gz 2116625 BLAKE2B cac8d7e8d73dd239eb2d3817efce4a89b62b74668beb1866fac799e6bfc9fff8a7b4f5233763ef051f142c533cbf73d545e62bf47db2e41da004e2c7ad87d0f8 SHA512 3deb26eaf99f14253a108de486d2c339c466e7e8c4b8302e2cc95f82ee5b833a05b0519d251eaf02be0c5df4cad935f74bd241ba9f604584839e3138604f2ef8
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_sl.tar.gz 2523108 BLAKE2B c77b688186edb6ae00631f811284d1d87e41af62ff5036209c67b2e4ae2fdbffdfe7c9695c13e9e0ac4a4d144f7f8cb48b6be10168f231f80631528f8e779191 SHA512 cb131b06545d0bb57dbb93ea9769c03946bc4bb2eab65468d0723239ea6072dfc1990ccc3c6f6f57a1d4a8d5b4a346ae5a066f0dd99b9ac244f3e22c495b257d
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_sq.tar.gz 1168092 BLAKE2B ceed1e136c98905a7400bd21ed6429aa48ed712aed537aa711a39378a9bdd7acd3c3700c3174bf657e982e4dba3744edddff500e031ab46a42fc4d1780486bf5 SHA512 6923d80e500696ec0fabd11e377c070b2515bb13679d2cb54517e311010e74cd5d77bab5599ff848e6e1a3e77d51563304094073a3b1dc5515e0f18a4c20c425
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_sr-Latn.tar.gz 2407284 BLAKE2B 6a8c020ef84ceb8616e6611950e655e78cc733e553956412aa669d5245d2e8168a0c98868af301b566dd119be7f80228860b42b1d68eb4615d809840c51ef0b0 SHA512 9b3221dc4e9a7f9221829a21b367b6abfa144a82ee46678e23411eb57bf801e524d37b86b0af033dc3d87f35740c4742e9be065a065f2d3a64fcbf44d192ed85
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_sr.tar.gz 2590723 BLAKE2B f97606e05eda3b3c688c9ea4b3ee60bbe3704bf7ed40ebc389080a2bdd2c814123903d2183b139c5848b5f32f43e6a5a9c184699c0dea51a23850551d56dffd3 SHA512 2733bae370950e64d281f8bba028965f44bfdcba432310d977faae50d0eb9adb9ed2b2e8bb9edd3f7fc262c2ef7a057242af5b77fbaf84b91d65589c6d90290c
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ss.tar.gz 286496 BLAKE2B bcfdc2c7e086aad7b9cc2e3945aecb2c321d0486a5b864ccd9d3a70313942c4021601a6b1d1b731e88b886d805696d21ff0c73064e2a368a81f1ee8f971e455e SHA512 117b24ed34d311071cdb03df8e82bae99ac2e914c0e0ddd50240f5dfccd97bfb130a0b4f6ffb10bfb3d8825b4bfbc89b67c8f82961614de9d9e7f1aaea0a5511
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_st.tar.gz 281526 BLAKE2B 51a86411256022d8ee3f40191178c4ba210045f943f33f3e58cfd7bf6cc8c0e36742f3ae78cbd139a28c2e6817ebefbea0a61d5fc0cb27ec57c6cd6fea393043 SHA512 6f7618445b20c879d79c1db1fb73a27889add3361967f2675a34412b9e8d08954262a8b0e064a9f1e02533c9561f37c6502f73ccfedd57223881bf5944216c28
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_sv.tar.gz 2650203 BLAKE2B 5b6fc74ba636369d2e0432c3a822f6be611b1b84a7f70724c061089c7240705dc0f1a7aa531c32bd73cf00c6b78349148e8a042066c0591cdd6ea95e83920cc8 SHA512 b7d9b9c6386dad138ccfd4391d136c8c589fbce1d7ee7bf8bd688401bc4892bdb311929119932de121c82d2fc27e87bdfc6053ac7d86f5ac2ec7ef36ee9fe397
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_sw-TZ.tar.gz 318870 BLAKE2B 1f1a48d0cab5d7ea037ea3b41ad1a5c1c613889cd36b3a7decf81f8f6040f5201cd87015b6ece006db8cec62faf93584405f96f019313fc434e612db93055c69 SHA512 f872fbd70e590ac295402a8d47ed3dc573c3c4157c6eccc222d1ab6a0e26b2d39e29fdba10d373cabfdbceee2e02fdfee9f927b2f25e25f2558ce126441161c4
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_szl.tar.gz 738496 BLAKE2B e1b6f269bbc071187d6e16a0cb2c821a59993f5b005764814aabb1fedd47e97d6d61e192e6160f85af3fc0acbc9b59afbab012c60794f1534214ef42bfcc735a SHA512 8bde39d9fcaea9f0e25b5f6d37df6aa35762fb1d12a12f0e31361cbb2264e4d32be296460c4fd428503b48f5cfe14165a2279d1038b6bc7da2cfaf5cff2e2203
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ta.tar.gz 669504 BLAKE2B 113bebaf837bd85917e9b830230a0982772a12c4ae88ff16551ec8f32cca05ca42d7abe060a6e28a6820c104ae997c97e672daf92176b49035154f082998a5c5 SHA512 149bac69e46cb1f698e7b031773ec6bf18b8e6def279cd2827920907e0b9307d60ba07d65dd3aa10659389af4c8feeb2c2602395d6c8ad5d7d3db17c263223f3
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_te.tar.gz 1078686 BLAKE2B f5c0584f3aecdbb60841c58efa1fa12fb850254d65b4fecea41c650c8c15d25609052de556505e3bcbcd6e26371cc4ea37f3b07a40718c381be0952010adf2ab SHA512 f577056d9f28b7c34db8b083f199dba0f546c219629d29c0d1db5aebb0f208ffeed357d5c6956941a3668bad1a3ccadd6dd9df728cdaad682510a33f38bdd573
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_tg.tar.gz 357815 BLAKE2B 5a4d13ea7a75806d8378573e09d430457591bbfbf028fce97327588937a9b922501a5b1c6e7aaec7772cc456a24945f4a194393e6a8f25bc822bbf9c6c376f50 SHA512 fc913f98981d1bbbfc5bcd48168d384949742b01e39e1dabb65fda9f5897c74e1845b6bbf66b9b0824e228b951705837491406c205d9b7eca58b8bcf344bc330
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_th.tar.gz 741781 BLAKE2B ec168f3e51f4e9f559389e1e0fb769b481b5c27caa6025ecf5318388ea84825ff90a289560e6aa3794b977556c3ed4017b5db1ede1c79e5d7fcfb910b657f126 SHA512 ebfe8f7d68a093cdd052a40b84a1f1fd41edab774dfe41f7a353d6c765c39f60aac219c6f8e780a5be6e1f1bd1cd37fdc8cbbdbecce39b76da0ae5c8fe2a4fbc
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_tn.tar.gz 261635 BLAKE2B 32d5f1f346160e14fad0e8054090c284e090781628d2b764c025c4c41e95786d19c341f160aa9b0c637d5d59bd20b8f255b7c24fd3ad763758816f06f48559fd SHA512 b6a19e32c769e17b60255b5df3e0a2e5d0ffab321cc00308b203f7ef592b1326b8d955989b9bb8b082ba072edbefad089471dbb879331a3b1b9ae6cb810e0649
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_tr.tar.gz 3091318 BLAKE2B fc5b81e86910162aa792ba7f9fd3242e64cddfd395901d88e1af7aac5b2596d2f309f5735f8a5282940efcf9797186b4e04f1789606fddee8571747c29bb7edf SHA512 65f30ac4edd5691f442c51e6868355da0306062fed7fad1a70426d2f032164cab058e7c8c126f03a4b7434cfd124f316ee86ed02d58e89cc83e756aa179dc449
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ts.tar.gz 279268 BLAKE2B 7f96db8f1de6c42aa3e591b30ac4a86e1e2bc15aa4885e7bc23944e50b0eedda1d1290e5ae52b9e8150414c651dfe1fda2e0cdf93b7a573b7ecc37589bba879f SHA512 2a58140ad20fae32ce7661b7d1c001d46dab57d4de43ee6eea1dde725e5cebf465f9cb82fee97b15ea32938a9c0fa78ae4f978243fd039c326ada2e26d48cc97
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_tt.tar.gz 187166 BLAKE2B 36ba6e9fd3727a3bb1760d4f9674829dbe37d35a76d096cad50e0cebcb25b37c16b69e1022a4fbd311e8c7095197366e0ac0135766951516dee8f68fb8783f31 SHA512 82a9a87220e74908e7c250b7c65a86ad15cc3f829c29660edbbdf9e76982a99875e114307713b53ae588b29cd5ca67f166b71063f11a118090b2b53a75b91a3d
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ug.tar.gz 538813 BLAKE2B 40328c24b3102425bba709fbd7da3f042aa654e3763d3b4db31bc86efdef891804c2d1a82ca7089409254bbce630abd95c23296238ec8ded862d5538c08a4721 SHA512 b10aad4f18504401739eb0966187334859e3467ace00aa58b9dd59bb1026acfc6215cbb35bbb55268a2c711fcc03090491a526a30b09ab0400189a409aef93eb
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_uk.tar.gz 1670839 BLAKE2B 8e446b739752fc93f3c4f50ac77765b69499ff4eceb43561b06b264c04a732bff0abd55c1f56cc4a2e8af6d433bc2e719d4c38b6cf3520841b2f3305e780a1ae SHA512 d65542357c2d94ce9ff8c5ec53c181e14621742c3844a6ea513a9f0db7359fd742863ac009f2c079d671f0a06fe9f9fcf4f4e7bd0cdd9ce67cb65484c88cc739
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_uz.tar.gz 314727 BLAKE2B c03ef42cd6a953e8bd8a4c647be8bd886659f6e3a721f6c347d03841ed40efc27a94d2d5db0dd28c1cc7801b24451fc4b68d9fee600be33ccb63b5df15efc632 SHA512 d35529cbd7238ae07511da08bddfdd261be7fe56bea4146170dcb3dc9185b4b8bab80955e1ed63dcf3f1eba2ff630d5dfc5260a6828c45d895da6ea146c8ee42
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_ve.tar.gz 283715 BLAKE2B be02a009b43621ee3984591e901b51ed78e39f1f2fc11f1eca6c3285638bac2aea626177e9d82ae92e1db4708ff555c69264a4a74907c98d993e0dc7b1301fb4 SHA512 190e7fee337ccc371b5e85de945493eb6ba8e8126fa1bb08a53bcaba752dfd7ce3c78fcb68988eaabae1f410dd4c5ce23aa750b05ceabf9148011563c55a7f02
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_vec.tar.gz 757459 BLAKE2B 7fda4e24855060a59f8167afd7235cddbb0650954498e9673fe1da4cbbdae0cf64c71c1a5dc22db0787e0a34108fd78cbaab8fa100d015675567bb6c107908ba SHA512 d44e5622c0155b35d847ea503f2dae2e6e3c47f47bb80911ff4bdfc41e2c1a0184fddd2f0a096f5fc6c593c267bce36f24ccc9b810e8d09879ae57b9d4736cd2
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_vi.tar.gz 454194 BLAKE2B a55af753995a7cc679acda6549d891c9dc6932d416bf6199eaf8cf5440f43cf9ec9c61933a2f619b81c25150535b44ff4986ecefb18bb9a3b1fb8b5177be54f0 SHA512 b6219e7974eac3e6be2e4379be8b2c979872651a4db49032fee66ce0617d1d2090fa4a567adc1d535b8896cb3f3041555e8e24afa829e1473ffb7aaaf5ba3f1f
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_xh.tar.gz 290174 BLAKE2B a4d5cfe536ed3ae134dc94bb73a23c6a03819c3bc885223415d293cb8a0d3db5e9fd4fda165f08cd937ba1bea0a42643dacfeebcc9898ccb30da0c747bc219eb SHA512 b7c4bc1ba4aac3be5d764637bc526964a3fd295f42c6c6b8e38e5055fc291a2356959432d1e6ac0ff3befe4a27a5b991ee93738c5b9c074396dc364f7639763f
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_zh-CN.tar.gz 847058 BLAKE2B 476085ee245374e710a4dbb2e07b20878aaee25fad2685821871ff7cd38e33ee73cbe0934045c1ebe037215b9af522cd657fd4174ab5fd3f1ea4d5c6b7af254c SHA512 8cd873a4028d17720f949fddaa4bce43ea85a8be31e6739fb486d79b353ac2b4f2cce2290a68606966cadabf10f103a72ba426fb341fbb73da24ab5f2d91861f
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_zh-TW.tar.gz 845317 BLAKE2B 639da56de02ebcb5674b28db3d9a498ec74668ea14f6bfeddd2dea4676f111f36da3b518630f64d4c8531c5d4bace1a3424af4c0b7cb4663c77fb31ffd18eaa1 SHA512 b5d8c70f3a9d70432a9080447e67acba2241b60c18e334b9bd5aadb14a4f335bdb621a696da96b521a6cbdaec1d5c92ec0486e19597129d3f9c82fb3f1ef4095
+DIST LibreOffice_7.0.6.2_Linux_x86-64_rpm_langpack_zu.tar.gz 320148 BLAKE2B 46a3a5ccc87aff0c7f3db03e04a5139283ae7a261a63c2f610006cf8d34978a4a11e927d7db42ff7aa87b77ce96bc2f2d77f32d2ee8c800a30afa705e9d25f28 SHA512 4e0dc08c3da2c8ab823bc129bef145b0849b20bd12a5d4d0e8e34e0a99a3f61bd6ed2ea3e7f137c3d33dbf8682eca52fdeba55b9a32b2d56d5c907038f898b87
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_am.tar.gz 4126875 BLAKE2B 901ca293d4ec9602d20e3eca053e38ba286b15c375e8dfca4d3c897224d80218b165fa9252d11f711a2eebe859504c14a71c630a2774a54d018d4319cb2331e5 SHA512 dbf2a7bf74f4d1eb09e439cc9ff910292229af70e41d573824e91d816dc41c394022fb92035b3b215edf265f70c8d4545e48c6b38b8181605b6e3f4060b9d234
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ar.tar.gz 3599063 BLAKE2B 8a3782ba3a3651f68003810f1280ce774f4c62ba1ff7596b7edd0ac3be3981febef1bcd400a61e053cdb5998dadfe085e9c5761bc09931ed1eccc9d6bf0d92e2 SHA512 cce4f514d5a98ca780acabcfec1f16d3572be09cd2f2326cc8cd0ea6fcdb4f8c56809c5ed7f289a0f50d7bb2aebc76f939e8d5ee10200bf1562cd1a092a5b497
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ast.tar.gz 3836994 BLAKE2B ea8c4fa98233f1473089644b23ffdde1f7a8a5c869d4dea9108533dae50d8e2cd5c549d1f560e8635632b1d6f8408f88c56c411901a43a334a9812472977b9bd SHA512 2697c347a5a51573f4868e5d62db39a73490a220eb5bb03497fb9328a6841d010a26ee55c4b34b344e8a8da6ad39b795bc2dbc3e51910d649f06eccd60ea9c87
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_bg.tar.gz 4167433 BLAKE2B 8691cb108dfaf1e13d5251c0e50e2d2016ad4caaee5ef2fd88f72cbbfa321eb8290c2197071f004c11a8c27e79245d168b5276d103cb23e7a572d2a12f18494e SHA512 0b9592852888b88eca46ce6656a0d3f8e41e14ff19ae733126e39ceaf7470ec0a85f153555b1b3d9473404af3b3181277918bc584293c7fdbac4686252316286
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_bn-IN.tar.gz 4303623 BLAKE2B e58b65793e9217bc8ad558cc3373b8571920d776f1b2f66dfef18b1526d7612521a8ce588b46ee92e9ab57fb5e92b280bbdf0205e0d9239e1b53d3c47b8c1a16 SHA512 35ee6b61e851b1d8f317199cf6ef442964245cb78fd554dee2d4e654f5f29ca0f9d90695da31d37b6fabd7c6de31e0bec58bd99f61f1fab09190a585b85af55e
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_bn.tar.gz 3981607 BLAKE2B f33db59612f3e6619dde4d06aabbc5a5e047ba95dd9e20aaf6a5dd42dc8a5e9cad271e7d669387e74d49c66d7808c3c0d3154b529885725bceeed2632e05c7c0 SHA512 7e60c9cf93d98a4959724ea4214808f386db61b79fcfeb5ee9cf4f4cec2a83edd0165f2f5bfe8d4da32790f5339d48d17cb3a34c56dfd8b024884c6cd1108778
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_bo.tar.gz 3989678 BLAKE2B d1c271bc7e1299b4e14151b11fb3b7f25ef422b698a2adff2e1ce02f85cabcff2dbda31884cd9b3b1775646744d3ba762b61c656c1f20339f4d023b663145ef6 SHA512 e0c72510acb3c98ff19d91e9917a86a15a73dfc08ca5feb5019d7c3aa462a5d40b79218a01c006f4227562bc62b05ec98447caac4d31c92ba22f27b86166a0ef
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_bs.tar.gz 3721375 BLAKE2B e0cbe0eb4e0ce81de6b01168c167164648d73c82c804c33f47145120f1d66a4780e01e55f69411435ccb2a2f6e0664d82e1c34f3ba2d82401c13e82fb2c8aa15 SHA512 787a214402091226591ccdd19666596988ed5e7c4a4c60de452f7726c6f87c807d880a99b9f6277467c81a45a2ab6bd64f6a690dd9d25e039c24d304a0a55d6f
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ca-valencia.tar.gz 3865983 BLAKE2B b28d5a6c4ae2ce0c4d2e0565152494893ea78ab03c1ccfd1b305a3b70dbb555dbcbd6c88600140c7b7beecb2a91d461bf403e9f6267214654f6598435587a077 SHA512 5779481c25dda5798df6397fce109485beaeb0f0a8dcfdd0aeec4e2331feaeb3075dca455e4dde9dd4e233dcacb6cdb08fed0092732c97a00a3a1f95e96fa8f5
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ca.tar.gz 3856899 BLAKE2B 85c5c07f6895ac77003cb10f72fdb0f565288328f198c392eb037776cec2618e79babde4709386a724c0c0d8191a7d2faed33fb396a99b612be86ce8b51e9ea2 SHA512 facbe563ecc74fd5b7ce22570bf5534dd0605a0c46258aacccab27428263b5fd2ca3f9fb5c7ac3cf5beea6510799114e59d9af42a7be625bdbb2b298eda808e6
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_cs.tar.gz 3879367 BLAKE2B 12e67c42b256659f20936c4539b7370b1ca2f3bb4d207f7600af6831efac248d0444825022139ce74b0d196332339e66d3b1d7b24de8c2c3b6996616dbe31f95 SHA512 4d177308e77be43a72abb9e4844fa05bbfee8f7ca5b2caecdc4a81c869869341881697abcdd56a2abff7f776841b56e417ba343e23940d76d883334277913c88
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_da.tar.gz 3784668 BLAKE2B 22091638188accca7f8f8a96628d8295da59a64c9d45a835b3f4774e38cba5a12fafbff384f39f18d065a6cdb6d0e130ebe0324d885e3954c4433d9cf5eb5dba SHA512 82ca8abd4cb31b386c078028f2bbe6390bfa690c4814e12111337dfe2b6300adf11e08ea00eeb7df7dd933910fd3887fbaf593e466e3cacf6fcb93cdb3ef8a38
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_de.tar.gz 3953710 BLAKE2B 4d8cf4126162f9f67b08c021c1e1f2c12a7969bc3ab935d21197023ae9995422cfc32f59ea5b1b933b1c958169a532798e8ff9b7d41d3e34823bbc43d3d2cd91 SHA512 d58b4a1cdec95b9f27a0e9ac10f81548987a628fb227770771f99f24a0e0832bdb573973d8fdffeb58cad45be39139e6155cb20350e04b2ff1267663c7fc1dd7
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_dz.tar.gz 4136939 BLAKE2B fa5191e29526ca3cce9b1cfd0d4db79e4e3f6d6839da9e7dfdb41bf26e40f5ab3e6bb990d586d55c27e3db882f27e82cf122a6a60fa9ad52b8072b3a1f8123d6 SHA512 b6b0ca8a1cc9eeb530eeb21b426c74b0fbc760f2bfb259a06951b8a44ae6cb835185a185501ece742f6815f3ed66a8f0e74b3b2b308aa024b4c94a6e756a879f
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_el.tar.gz 4591133 BLAKE2B 03c3cea9d440653c3be60e0ecfdb6cb8bd8a58a2c955520ca93d238d504a00d273935f0bb7195fe512eb921e76455201b900eba97caa031b33ab73dba6efe252 SHA512 b9ad8bde7a76432bc42ea3ab304f6fa0f17dd032f3ee699985274711ab951d88dc5f8d82c10984f2e65456737f1a353feba2c8ae4cd1432588349a4187f45688
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_en-GB.tar.gz 3607896 BLAKE2B 5c512df04dda038305d992aa743d6162b2a7c534ce9c2b00cae9e276b9a5931660602b3b203c610d420339c2997cca717e722bf397989a22252ad236f0abe33a SHA512 cf28eaae344c44532fc61092911570aa9909c8915f826d9ba4feab6eb737c44d316079e2996e1e4c2f457c3edacb423a284d6d20ec237034d58850202c3f3fe1
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_en-US.tar.gz 2286344 BLAKE2B acafddd6523f69471f0ef6bc28fd35e9fdd74d5285b2d7410f83348aef5c3b31c16433d55dc998154f1e251f2c8bfa01ada5546f13132ac1d372274b4e9a887a SHA512 0fa786844ccf3070d32858792eff470dc34d56c7c06a265399846e58b9a20536148cb72ff42daaab03940b40ebecded83ce09ace17fabab3b6c955d8ca193067
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_en-ZA.tar.gz 3599874 BLAKE2B fc338ccf64c52316e7769ae36e2ce6a0f306e822790693b691ed1eb834d27ef6e9411974f510ed3ccfe1a0240699c1466caae8906590c602b75218f8438955b9 SHA512 b175976f338807452f5904684b5cbefeedb729e812d35a657be43c9cffab9d55349142862a6fd628925fd02d5a3f61cbd9bb7d7a3ab2dd26a9caf410f0db73af
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_eo.tar.gz 3700736 BLAKE2B 7cce98d29417d0a378a7876e64b082bc731269cb3798ff4ea8570461dae14c4a9bcc340cb1dd26f476daed00499d92fec0aa47f5d0509c3ac66a3780da433c14 SHA512 9292c8e75ca1f45565fa89d42de831a9ac2dd529dc95a0e375dda02fe2dc27a02d549129a7335b8167489bcb782d8c736faaa01e83dc7739391b00cb1c4013ff
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_es.tar.gz 3898908 BLAKE2B 0b98424a6bf59eee6a7f6c59c32b4b55a39f74ffc4a3b4af591f71442c8a41cfa50e631e1525953ce6d89e1e3630d3493d499621fa29655db6ac22211bd044ac SHA512 ff7e3e62c4425c7eaf402927d38960245ffe460e046d4d17f6088b23dc0007605a8bc6426232407e9c38c333674997e2b36da0233bb12fd66c74ddd6fd1533b0
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_et.tar.gz 3745457 BLAKE2B a9dce8c0ca6262666dcb6fd43a256d1e967de5fa9c084aef299b4f62932cf6a237fbe1f5f717cdd40911f2493c75385101307fd6cd29d58a7123bd211817d0f9 SHA512 f710e619b31879e70ece2747daebac5a00751586449f3d9914803cc8ebaead8951b6f6bd82d348fe8f9ca3f753ad28c09340bc11f4f612afba6632eae6a3b350
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_eu.tar.gz 3728897 BLAKE2B e7aad5dce32a985ec239466de591df22e16044377cf075bf174cac2a65c8b4ca139533be97879d3866c5a0532b33e0b7437a8772683a53941349dca5383ba4ca SHA512 9fe09dff52f0f41e24cbc6bddbbf5f38e6bc4f562588e8f9b3be3f5d71473d574c549dacec3e7c009efb359115220b5689968bc05fcf8d5bec22358c152b47c6
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_fi.tar.gz 3749808 BLAKE2B 3d352f43cfd8750849a1f5219d27a9a7e121f3b72cbfce8a49ed986de68c457615621791be7d2028be982624a59bd6d6120f12e0341e4d6328b6e5e7f53997c3 SHA512 25fc175d7ba8e95b0701490928dd6efd9b885519108aaec95735f56aa9c7d8ffe95f447fd0143f167e1c62323b5fd8294cbf0f4072e5b058fe77e10a3dcc06d7
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_fr.tar.gz 3882049 BLAKE2B 4176c9fec2b1861968bdd4ea958e27fba798607b4a3ede1889a530c137ed23356634c6c11236c53d6b6118d8673f595dda184bb8d48261236078d19877fb9607 SHA512 157b61ec38dbbf1506ff8d3b980ff1a680971dc13696a52ec5054d5597e8bf841874cd0851f6de7f6e923b8d2059c55e1c52cee6c720ed5fc0f835d034035330
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_gl.tar.gz 3835152 BLAKE2B 5a3f2e3aaece6235cc5d4066a2191142300e82b906eb13b37d8bd63ab564b5bde0a9731e37b6366e298f403dbf3d7da92b33379aed195a6055f59fecf88d84e8 SHA512 944f62365a8f66831b1738bd48a3b286a6f7759e998b69bbd454dfd76aa78e0e2490ca195f6deb418ceb3853b84c427e600b05e7fbe7d4d58ab21e1777dd7e75
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_gu.tar.gz 3687521 BLAKE2B 08960d1dca796ecf08e0400e78f0e90abd6810bed41d5a5df79c3db00509076bcd57d88b4c9ee5663ddc8234dd60ff064f2ab8ce53f113c13564974491acb3d6 SHA512 3cc896c072f13d3eee7d0c131beb49e13f2cb0eef8a7e7ff77f8d4c645963364eef0bc7c01c9a7443392866e6cae472aa4bfca1c6027cc17d673e6b126a67c8a
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_he.tar.gz 3459943 BLAKE2B ba151b1a9e2553d53684078bcc27f1c78d4a9401efd59b7113464b02750868114517b3e538830e1519ac11a2fdb62d2566362e27881ca668ce55ebd3157003c2 SHA512 92ea04a1b00924e4ab14c13a090967ee13fe2ee4704fe9623d461ca82c01c57d00f2f30a6f972906d137eb6602cdfc0f584e53a22fe7e8e2884494a53175ffc6
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_hi.tar.gz 3815775 BLAKE2B bb3bb28ceaf2c652a931ab5b6b966f6db7cbf0cd1c6fb40fb6da943b091853f14e3ca90ad5290c8141d1783dd8dd61af331bf36f771865cbf99a7b4f4323cdbc SHA512 88f1e6c955cba5dceae2e65ce2b5378795936406041050fe587f47aceef0fe4ac589615e1c373269faf58e7f0965f1342cccf940431f5d17f665b48038284a01
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_hr.tar.gz 3726701 BLAKE2B a145d3146db073aee01ce2204de4bbd01524567f135deb71dce97830f691adbe8377c593ba8bff0837285bac91b5db7a97732fd005a8ee971ea2030510f60e61 SHA512 7823dd60a3cefbdb077ffc4092e67266ac5e172a19dfac718a82a80c2be839e5cf84e34bffead5b2fc22a8d6ae46fd952a572249a8982d46b4208a2483059232
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_hu.tar.gz 4004438 BLAKE2B d4682e88874e52b2dcea2bc166b9acacd8be1376aefc14d817e6d4beec00a20596a7b73b2bfee8971f034ce7ccdd709d62d9250a8cd3396a8999ab794028db6e SHA512 c35c96acc1acd5942cd755e63958649f04710db2ee45ed96a5f44aa25eb89d5fb1875d3e81cc67b6251655b183bb98fbdb1345dd2ee747bf7cb807c5f81bf294
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_id.tar.gz 3683745 BLAKE2B 80e60ff8f3fdb6f006f8dcd9f2d74946b668f954f9de33729051e609a4ad553f068b409f139e4b98cd200b6b6de3f7fe38f0fd2ecea7450d6d08c3064008e10f SHA512 b4fe926fcc217abc23d3cafacface30ef642a998bacd74da44f204b15b49d71761a51f454436bc4fb2de5d9fbb3c1c014a0ab84bba752a89c21c35dffd8c9a41
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_is.tar.gz 3744521 BLAKE2B f7a3ddb41fc409a19c0cfb84391db06a2ee39bc11a7d089ec646d9ea54bb374eb71f7eff5d61d03dc42fc1a1225a06e209bb56833df12af19c3672908b40af83 SHA512 e41cc2b9776faf071245fc40d953f7e94d24a88f0645c9fdc734dcaf8e812febad9f61069ad828e354158a8e221778a0ee68a9b7458fc877da3879d1dd0697c2
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_it.tar.gz 3805263 BLAKE2B 8a797782940c6bd17df38965b42be03b98742fa2f52043b8fbb51f50ba94e40058126ebb160ae68c98cadb1075d8a2c12a68299d0292d59cf47cf4a0cf97ccfc SHA512 a0c426fbffe2d98b88b68b21d80b830317ac9add6da838861a136526ae06b3e1210d7a43f3ba2df43c6b4f3b9e8bd15301a6aad71147e75b08fe68bd7d19cb0e
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ja.tar.gz 4462496 BLAKE2B 50046e39c197de05ae586db83943b7e20602facbc77738b2c172cf5b1fd48ab206081ba63d48400583252fb7dd799512ce34cc24cb015c1731d98b5d642a5b60 SHA512 877bbc19a19d353fdfda551a99c486c624041159fc27151c34385233b04b00570847f8a1e40d7480d7bf3cd2b483a2b831b09d5d8ce900d8a9f5f685b6ce26cc
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ka.tar.gz 3932266 BLAKE2B 523417a42b8d6fde2a4f4269c293121cabf74ee4c4abd464e68fb0df11202a0dfbb093b6cf06012702f20ed960d371f118b22f7577f3f410a6e650cf99f56d3b SHA512 30da8985c74450fdea01d7a549b958a521560d6372ecfddf1f1d88509f07d10ba50a2f846288b4ed49bbe6b9393907653e7e07537d87064ebaa103184fc41467
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_km.tar.gz 4268072 BLAKE2B ed388d87002096acde60f979c27335694e29d693d3c9e759ee89d4c39c898cd9601ad9161a01a9912831c7fa96cc17434de744ff436855fd5339b305dcee213b SHA512 eff51d8cc0e1f8e8a4c37bb234d2a0a91165000d7338b3310dd798a3f153ab94e02fd799ab5cee7ddc98ec324ffef16a63b0eb33dbcc1191bf971b8093dbcc8b
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ko.tar.gz 3964696 BLAKE2B b485b4a2219dc5ae88d2093b4cc91b4a3c50f83d2bdc4c2dfa8f4c034462b6ff68f6cfb36b6180ab4ffd4dc9a2bfcf4879b80f0afbc9da881b700b8d69adad3f SHA512 a63fe1f87bde671073eda22ab1ebe090355390c6f4ed2deec821e7da6c3c4bf3580ee7ac966c71b54c2a310f095dcc7b4cc23c562dc9ffc96e3005d7b94ecf27
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_lo.tar.gz 3685558 BLAKE2B 888d006a114e3d2bd33dcac002c5e9514b6a3cb271c3bbff4c5f61b2a4b061352f10fb2482e15d4936d03a115ae41361b802e3b12f2d92504d21912f4bf51850 SHA512 34b51f44f6867b946d464090dc8c1dea69a4e75de3f758c8f20048121f6d510982a5eed6a7d1e511e89b417a8849ba0db44cd39de1b1838530d9cd5338ced0af
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_lt.tar.gz 3903035 BLAKE2B c9c3e81d9ec92fcf51b002bf591904debaa1827d36bfed0020bdbaaa0cbd3cf1654ccb236f0bc3da67357220562be0309d97bdb1cd97c3b3c5d7f8be784b239f SHA512 8021d356a08afeb4e95d500ca3d5f51c806880e900c32e7e8b5e9408f98f6232a1a7127b302c7ce5dada3cc85c5f411f5370ba19cab83d352ffa4cbc36c428fb
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_lv.tar.gz 3738472 BLAKE2B 8e1a5f1307fc855adc10add83e51799019977b4827badf992314391a1ef1d2cf99b351e4e516a85b66da07432c8aea7c6c655599949b135dfed1e77bfffe178e SHA512 8ebca9cbf822f06d16a7cc299f49a089e90554ddcf565583e9b3a54cf4b48167c558492895694bba53905ba2e0fd4de60b19715b6767fc0861a7be6f9ebe75f9
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_mk.tar.gz 3779657 BLAKE2B e17991cbd8aad7c2c289c21bb292c7483481b9fe44330dde7af8958f1556d536c89b5d0d92259d513a079ca22680a41b381d031ebbb26fe71f93d581d61a55b2 SHA512 8622e5030d123fb618b3922c1cb668fc7742b71531a12010d0872de9df002b950a12dbf714925eea6d0ac4f3623fc62b52c0407db9748a9a5869b70098f1fb7c
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_nb.tar.gz 3743083 BLAKE2B b1b0de96b799ff7da465cb2cfed593b4f66f774faa0572c1e08926c8627dda4d1a3ab4ca932ec350be4124fc51a481e2ed8a2842478dc445e3b21d3120eb5afa SHA512 9e59c12c36d4c0df57b3d255879eaf2032412c14aa7eda3d3c1b7387da4a4c4582f3ed19d4b1e8aa0a93664c50cc839cc26ade1783ae33630cd697ed6b034573
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ne.tar.gz 4019722 BLAKE2B 5b025071da943e939ebf30ce5f370adb6d9a867c662afaa40c47d8f93325f52e119bdb8e77ea3814bf4d9c4ba18878856c61c7c496d43927557961b4e2274b96 SHA512 5d71731511ee49497114530ae62ce505f0108b26987675544d1d8c9c36b887bb307f3cb324e8d36f64dabde70e6fc376048fa08e6fc44e844feac8d9cee9abc1
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_nl.tar.gz 3849091 BLAKE2B 3f638b5d05cef3b501bb6d6af72018694863feb5098f8ebfaa9e5f565ccccc3935bac34b4973795f3ffc93560705816e79619b3ffac2658922c649eea455f384 SHA512 f78780f194f0583193c7eb76028a35732aa9dc8771d3bcc54d8c5c47518234d14d06673338ae34b5c9d7d3e3e8bf0bf258876fbe5c27c13987ffd6db7a86cd06
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_nn.tar.gz 3898666 BLAKE2B d633b3389e489101aa4a5f7f69a1f606c87d4363ffdccd15210d81de7013cdb165d3e19489b9c3793cc8b11f4a74c61fd2983b7ad106a61f5eb82f595ecec936 SHA512 d113c70b21eb9c930ddfaeeefa8dad2ba030cffaf8f2738ad1d5c337687b39c82b37396b9a8d7bf331d1edd0fd15cad5733526d617a633eb80c42964b3b67431
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_om.tar.gz 3791022 BLAKE2B a844dd08c98cee4584d1f40541c928e69ae9e4478849b8b02dcc56698b39acd3ddee6a981f348c89ef6015402dd0b867853377f05a0006dde81dfcd45f678c12 SHA512 8e4e9c2abdd1f1bcc5225d9b7d81a55ff8980db67332fcd427ccd98c05c47b90a7147e9d945f42b342564e9bd4bfa0ddda71549e6b2869d8e50efdcf010dd9c8
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_pl.tar.gz 4035403 BLAKE2B f38bb1f930a94a8e5ddfb426b0062b4e8f64b2560354cdf133b502901d2a7756fb65c89f515aa3c88467d0f022682d4faa0f075647b15bca53f30dea62aafec1 SHA512 cf2f8ebcd2ef96448670df249aac1d969714762424be520cc8530fcb983f6de3c262df69eb0e8d614bc066fabd0f2a6fd18370ca969b6419bdd6d07fe94eec42
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_pt-BR.tar.gz 3843471 BLAKE2B eae71aef9187afe6a1277bf10b2dbca31d38405d8044e637c9c03d2aaca4df4ae564977c10d137ed5820fd0b990f56e7ef7d4ea8051a5c7710f58fee7d3e874a SHA512 bb3d547652caa8910e6ee8ab80cd1c074b9e846b0185e8ebfa164f010ab01d78afb2ec53e20e8fd7d9aca61b5e7d24b79162858e9fdfe6429bd44c2d3caa28a7
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_pt.tar.gz 3829429 BLAKE2B 1e78e074d473856ffe7ecf2ce7aa737bd8f21300227681f9f71a5abd15eafa4dbb7e8152c64d0f3ccb0ca778d95e9f2d916edd768bc6d2aeb2ee0f0a04516b6c SHA512 245bda6bb712238faf090579f69b52b6ab970fb82aee3d263fbf53469376878a7509b603b205476c54f618a40d0f63d039b6b50a99224be86d6ab4ad741d9658
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ro.tar.gz 3634353 BLAKE2B 15b1352beec53d90b5ed3687621e7a1955b050eea797b92035afb0db5520a075621cce7f3a852b0cf85a72d8745e5a5a7d6ce57cafe6141c925e0c789d8855df SHA512 f17739ccf22ca02d8ea307d214bc44bf5645bf50baf1bb5ea68e7d82dfa308b7b3b19c81e6a2b8df26d70fb4e7d2b361a4b898387344c97e8546811d759b4da0
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ru.tar.gz 4185442 BLAKE2B ecb7a87340485fc0dc9a3441b7589fa216b5968e18467e01e40f3276052de73c072354a2f49adea5b21bc71d621bbd88d82743e25c5420b459296d425fe73129 SHA512 2ae10967495d3f729b24ed5552410010df254ec9479df575cb0d234b79635cfa69d6ce95fc17636dd55e8f062a2336ba50b47780bf25fa2cf1bcdfd57d55ed9a
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_si.tar.gz 3916224 BLAKE2B bf64a91c16d0c3662edc69e1de5c38b8ef1921b754a5522a614bc752bce3c0a870b4e43e0a8f2c21824252f6473ba1114428006e0fff396520f3d514c70726ce SHA512 261d5191c80603bdb34cda4959cc15ac47378fc80c5d133f504203b65170f5c84cf843af3048e3e15c1cd153914636d99aa8fd113eecd5e2cf54e8ea44bcc0f9
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_sid.tar.gz 3781138 BLAKE2B 40c15a4edc51d64e0ca0f8c43ad70e1d45f4d36fb9779690cf8f325d9e9089dfabec4886ce6f6c54580735a1ab97de76e19cf816a9c2cbd1cc8e60ddb4c484bf SHA512 b9afc3590bfe917dd38e7bfc6d26371842d59ae0b0dc46bcbcbb13381c3b68cbfc41b79b8005fda73e56b24c96194cd29a620af34804605b38f45037e9e58563
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_sk.tar.gz 3938974 BLAKE2B fe9f02f88b9a6b282f0cd29d99adbf89b123e396b648325d28416c15c727d1fd85f1ac9071bbcce44ce3e0c02c904f9fa6160f9f6e0186298b6bd8e9f882e8d0 SHA512 6ec3bfc8dd866179a172d696a223e4e327cc51df1d2bd00bf3e5fd79645db0208d12261be2c76a8ba3ef52662c50627bf3209461edc79edf0f070d03a839335a
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_sl.tar.gz 3794953 BLAKE2B 10298b4de45541bd699babe4317ce06bb2129126308336beb17de55e726e21d2bb59330faa35aa06af4f05b0b7b11cffbe509c8ab7d448f2e61bbba9f61c822f SHA512 3c99851d1d40d8c7024d03dd7c40cdc4946d4e80ae8e91f9458c059eb92d61c10c478978e3ba3e9ede93da30dafb1efbc30af0953f59f76c81afaf6f3cf80dc4
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_sq.tar.gz 3695975 BLAKE2B 86b650ee3846c561417c6274a9ccf3df510b4deb9f634f4c651ba09a5b1d7586122797374f0cf82ec21a45d00dea8af83aeb9894ac42bf0c43cb3c506c8a7d77 SHA512 5f6d8272976340d64b0c101000916b77d5b4183bf75948f50dada5a2c7c8c63d89c5599424bc00dd38da55fd1cfac525057844ed41309ea085413551a6b2682b
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_sv.tar.gz 3782378 BLAKE2B 2ecd59f325556abffc9f29960763201d01aeba0c364a00ea5f53d81431f78fe0bc8eb058c7614f4054032159cf6d431f0d5b2c1fdf80ab8f0d61a54c63cb1f72 SHA512 c2f361d0d86cb6fc372d1014f25bd9e47ec9217d8fe7b9d47cca0ece4415887ad199c57a7434ec66ab7c6bbeb03f6983e30be311fa6432d33f03b991e711ada7
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ta.tar.gz 4129178 BLAKE2B d6238eee9bf6f29821dededb2a70fcd60d3849a6fdf6c84c67742128e422d5c6f0ebcd054d027069b3346a2404f30adecbabedf5b8591786630269b4c2bdccfb SHA512 b9986ced273868ec1c88e6b533ae8a77e7db47cacbccc7a4656fa0ad2e6809aa6dd1ca389f5de21ffc61d3ea71691fb99896d3e5e4d0922a2d29c63e013a5ebf
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_tg.tar.gz 3749118 BLAKE2B de98b7d26af88b0a815abca01a3a99ea38f419fd1584ca092e352b795adcb15ed54722f11d2d846137ab00a0b2aa323680f38215ca2d861ba7128a2c126fcd02 SHA512 a156119861893533df7259db283889cc7dfc83a73797a101cc9fe1da43a664038eba52c5fe4136b78775fe4b14528a7024d148fe0db703c0e99d6ca79cf163a4
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_tr.tar.gz 3848336 BLAKE2B c83d79cf980fcf32fd2ffa5f2290ab7f2614c1ac1b211da2f180896ba998a0edf2ff8fba1f9975230032dff22aaa9e4199478cfbd64172e54601dc0f593ad4ff SHA512 fb0746f2850097fd9ccb95b056d55111586552b20c8d1161890b1c083a2cc0bebd8342f79a3d124c4e95a20d8d4830d0c41bbff113d76a4d7f0019389c1ca967
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_ug.tar.gz 3862184 BLAKE2B 2dd0586982801e15f94c790026f310090e3d206eda26faa11b4f1249ee90d5a32827eb68794c79bb08171ee05c85066695eeb37ed52b961a6e570a8d216fc16c SHA512 ae75366089e8a4c8cf7a58c06e94809381708766180814ad6541f4105c0cf0bc612112a574e22d3875b9121f638438461531ae932d5632d3a3804efd694a5ca5
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_uk.tar.gz 4171960 BLAKE2B 0e8f38da759588dc85ea0d6e58362989465ee8d64d0bfbd186f2cd06ebba4b1a89dac370b4bb94f6c98591d0c3a2d63e82fc1f86922cd168745b34af17331ca3 SHA512 8aee19b6d6df0629acd7f69fa95d5e73813d580922ec7946b3cd463e67baf36bb7b6eaee749460c791fafe2d445aea59ba8ea7e83b2260492bfdae0129363c77
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_vi.tar.gz 3823979 BLAKE2B a8dea81cce326757afc7c3e00fcd76fef31ebba1ce6ea8a62419486cc3352b2cf053f4aafe7462b011ac3a49ff1a44cc440a963053c1f81a34eea9464d41bf8c SHA512 f715aa3e43ace2f0612e309e811daf3bd37b1fd4613cf71f373ff81cdf4049ac65a539a1e3dae5ed9ca5ee0b99b9068490a5bbd648af4cc5fa3bc3ccfbe38e55
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_zh-CN.tar.gz 4090718 BLAKE2B 9b9a7e74efff68573f31a9d154b93c1e95a009c26da7af6d7d6ea8aeeeeb3166eeb8465af6c22d0855dcdd76b6831443705f42f0e96940c929946a5998e7a2fb SHA512 dd0baf1049ce8a3bfbb0d1d228e1905dea2520e92b4e28f68a600224bd63046bb86a42338ab14b698b6dcffc7222b535bee65d2a73b0bf57db7e4a9ccf17cf16
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_helppack_zh-TW.tar.gz 4208456 BLAKE2B e94d40534cf4ded5fd3af1c2e9947b98f86ecd4db86e2f7eddf0e183c843cae775da840aa9f65b7ef78802559353609e3dfac36e50735a24899de82de0042ca0 SHA512 771b10afedbc84da040c45aaa48dc6f64af5a5453e345a006a72f86c9c75324c8e7eaa76e143d6192783b9ba50c6428a339c572d2a9aee3119b0ffcf9cd9fbab
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_af.tar.gz 1486198 BLAKE2B 842200778a525414c380ec0dfc426790b929401ef44ab6473c8558d18e9eb589dbda2665ff43772a4c8f67abbfa77e9cc5d5633dc171910124b62f0a691310b0 SHA512 0c3725662920adf9fed20bb89212ce4c5e23db9bbf8eb83780f78467bd9e9eb8079f8b903bd011078834e96e14b07e92fabf4006600a92263ef836dd2833d440
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_am.tar.gz 960095 BLAKE2B d5fe4d59e7abbc9a71631502ae1053683d6c5c788efcd9821e84d9babfe3de0494fd4f3106e70a697334889b47d2ba029094ae4fe78c86ba833d75ea629629f3 SHA512 c00cd6aae859f245bead66dc116c06b053aa5e516ba2e061d388925681f835bc925d475dbe304d7c35e25d117858bf3d947d843f9bfa7b90104a323ca7f286e6
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ar.tar.gz 2444425 BLAKE2B ca7451c3a62ad69e860ae488294cd0caa1da49f99a1ba02cb7b0e1b9fca898eb65376a7d3ec3a8426c8837a303de5baee4ffe02979b82a4a96a89befa90837bb SHA512 e17b0c17aac2f6f8c39054d52a07965c358505c61e71195d102eab193bc1c7a266ab198e84d248b38a0492086496d5509a8eaa6a532372a963ec96667b8692ea
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_as.tar.gz 524195 BLAKE2B f19b3b6150d209c4c5d980c03315af599bead14f1c6794a3394555234cdb4ef46728d8040906014b53eea54d524ce73534573f2632666046262c545d03fc7f00 SHA512 ee8e1eb41479d772ff6d2956c7425eb48444f69920a4a52fe218dfe804324467bc4da773849e4c215f045c7b355edac110c5c7b59b960b04e0eea4e0e29d190f
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ast.tar.gz 571036 BLAKE2B 2042a3ccc26dd62a6d3f5f66c298a4e96ac7b17a093a67ff2c1729672dde794289126ecbbc34afc7fe867b71eb6a36e62782ba9ec645283bcba0686963eb773e SHA512 6a2f6db8cd3bd29ba3e7d97d0f614200ddc84ce6aa01487e01c82188e42a39a28ab4a1ef16d04d88831125cceefb7301802676e4fc3e7106fc0c7df16a83f009
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_be.tar.gz 1050733 BLAKE2B 8753d46a1a92297cf486ddf0c23a72ad35166ba7a9449bb5e76c08aee86434c1380ac46f54579489244fefe06b8b4e9475462c5050d4989d00ef431ec03d7bea SHA512 a25aa872bf7de5dd01c8353b3248508d9178c2b5b940fc8bd19235ab8e061718d7ced141d3e0d0fd8f78076137e194f836399711a42d53cf0b63a3e5d48e39db
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_bg.tar.gz 2749151 BLAKE2B 33a858c0ef8b1bc3036a6bc000dd61dbfbe62c80f2fc590ae06773daada9ce475867cbd5e17e2421e2c405221d8691200451e7833a9a2792effcd9197c4c218a SHA512 33ca6fd41de66223b479e8e1cf3cabd5ea33d82d9bf3e9ac192b77ac72db134161dbba2b41c7f6799999594bac81cbcd99c6e5fd44ff601dc731791843ca2c46
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_bn-IN.tar.gz 724479 BLAKE2B cdb2832e4546af9832fef7f2459875f8495d776f453a9012f83a3f3e5e24aa225580aa2f63dfa59cc82ff825150a97f22e2a9ec79c54d38d14dc385c804c33e1 SHA512 56b561799bd9bca93e3e441c81d505a6c84a131974197e5dd15efbdda668e2f1ce30e79720eb396811d537f8176d0b197ca2dfaadae78ac814aac020667bd453
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_bn.tar.gz 880491 BLAKE2B f475cc3c19f6176dc20afe46c0bbc0f2b5309534911d338f2efd0cb8c88a509d39076bc6d256c1ea842a2510b6a4b332394d834f8bb9e69024a280cb57a8131f SHA512 cc256f055ced2c0f87f76ecc1a477230c74cf329a132c6aeb9efe9b8af2dc1b85e468bc72c988bec6bcf852ce237e5438b78fea17313b0718b15c479e8e5de0a
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_bo.tar.gz 459196 BLAKE2B 28202757f9d7bf96a5aebd07b4cb8251c03e734e383168545e4ea1b020104b8f7799ea51f2a4e75e749113e97e4093038042599115c7a68eca83e4293ee923a3 SHA512 6a8a200b38a71d524067ff4f7c46328bc25d3c6c315e7d88143f22413cb0ff854d43371bc6040157c6ef0c12611427999f362ce09422d20410db894c47f562ec
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_br.tar.gz 1519279 BLAKE2B 40255292d10b276dc0ce0898c29d8e6b162142c300139b42164349cb175f88ac95549b6e7bfddd17b7167bd62c6856c77e0a9bbd75c5af138b83bfacc154602c SHA512 739d2f732886653058242e169a7f21b4f69579ece1f8bcb9cdf8a666990a43346bff2e76919dcf954a72bdab2f95bdabf2ac705a9661675c2d145d19e05627a6
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_brx.tar.gz 336708 BLAKE2B 88b9faa5a74d5a25c06372936b80e4a4228002786c0e4ca87d1ea52b59fd2c1157f5c175142dfd5907ea1536d8b2a3a84ddd799156466ae20dfd016e3fcfc5fd SHA512 d09aff9d14566ba9dbe92d1e09ef0eab16e893b1621d3c9f9187158f4ea24a35c7942646d7b0312aa8f80cd2569e1268fb3038bdf36ad4f94c19979813c8e029
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_bs.tar.gz 671927 BLAKE2B a9b3afac0f128f3167799adb46daf8856729d29aa42fc37b7762d1da3604a90d8174e522f11134b0c113220971f0615e78b468145982929e582d626d5787ec2d SHA512 eceadb7b29abdf2381a9732c270362262d97c10a0ec920eba1aa87e21df59ca1dfc7d73db5362692815602525afefbb12038bb2bf76e708c7f508c52bbc58d8c
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ca-valencia.tar.gz 2657133 BLAKE2B caa3aac73f25ed2761320b61089c1c254075491b3226f31f43a031945843e4b718afad566b85a5eb629d5675a3485ba7c70f3e00da2913a223d0ee48210fe720 SHA512 e6a9a03d6fc6dd61053516ae4eb60608baa9d532e8b6df6895f02a6e1827b554a45364b0102a44467fb5246246172732f7114e3f803201dda22a6318b99796b7
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ca.tar.gz 2724051 BLAKE2B 9e78305a601fb6f35735e0ea1c765da590b2a93be4248061491414efa56ba859f65a3fc93c031ac275801aadb2b199db6de21d79b42f6b82139f8bc8bf41477f SHA512 0709952a82bd814e1369099daa424e29caa203b8a6a19c0a1df0f1b5bee1b086a64f563dd1232ef0c2b4459c57b76dd816f3f8c883932afef5c30a4b4b4e680c
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ckb.tar.gz 365042 BLAKE2B 6e4657ad3b5e267691bec00281e798ff3627dcfb6ccc4766a556c09a694b289dc0011fbe6e52d7cd65dfd82e792d8e6121286cdbc439717e1fd133ede0d2cab0 SHA512 77eacbac4ce4d141d609dda7936d82c01a9c1d9a77a1c85101424af3b207c49122f48e96ea12574955c8b332368d704b649c29337e732b628918bc57f183226a
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_cs.tar.gz 3471265 BLAKE2B 9de13c95202f9865fb77eedc742fb4faa371fe8d0fe5f499698d9dd3259276053e70cafbd6e1105fa03618a25ee07106f7deef7f537239bf7a74cd42ea5e57af SHA512 09c60599b288588cfa7b4193653712a0859d4af7be679f2820e55a7f21e3a529a4e43c1e5640b96425f24fa74b4433e539f470d5c39264d6a311e74ad6f0fa1a
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_cy.tar.gz 1012171 BLAKE2B bfb8f8748f7a639d02ffaaff549e6ca31a433ad7d4870654ca7d859dd25150c6ade46633c15e61212d6a74a89c4527e6e6fb166f6f41795272ac13f8d9391217 SHA512 9b4d0bb9107424aebd5b190ef5a615ffac6ba36ecbf3a69249d27e46737a9f174e5f2527655e277ca7afe7ebd5603f5c77d0fc04850e639570621f307f6fce25
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_da.tar.gz 3112316 BLAKE2B 33ee280887fc32f563aee4a4afa929cf3d7fb8df0619bfbea63a70f81f942aad1217aa1ec9e427af148f204f61b11223a8a2ee9713cbe6ff200bfc07ba02d317 SHA512 8c5a00a11a4205a8fd68e6c7d62b7c129cec7876f5ed3b36311df11e98f7ebaed1e99a344a832b6a01f0795cd77181893654a2644f794e31f854103989b35ce9
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_de.tar.gz 22051233 BLAKE2B 46be0cec2b59fa6cbb5237666b50881b058656318ebdb68b74472b012df22ec5409a62ed39a30d0bff0b4b9f7613f581b6f0b860a6a5a64fac8559612b8c266c SHA512 ecacead1155c64407f01117116424328dae9ead8dfd7d486502ddb9b93d5c8e298f6fcc68cbee5955f18f6b78aa681cd907ea5f5417042bc51a1dd17432bd580
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_dgo.tar.gz 434777 BLAKE2B 18f0c0bb130dd4a0dce451f7627be7142562c2042ae681e7088dda293e0edb6e8098a8359306786b5ac4262e35f722da2307ca293a6ef430f11ba66277fd0068 SHA512 329ac886a697906a8a217e787fed41c8114c07fb4b53be913dc22a2edd65cc237274c3a812aa4d5a6ffa01371568c2dc0dfdc40a08955239d371661685dfb207
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_dsb.tar.gz 908096 BLAKE2B 14cd00dd2cf12e189bb9e0334e24d652b6e4e8ae3d7dbf5f82b5adbdde157ea378bd7c6ae221bbd657afc1f9a7e16a3716c50cb440c890a60755bdd7c2f31ecb SHA512 880c4fa332ed36f81fa40bdcbb3fefcf5c67f86e80fb301decc2428052ae3b45a145f89fb507850262abb8cdfc2b0f4cc29b424575f3a7fa239e29b75f82083f
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_dz.tar.gz 484837 BLAKE2B 8eacc15b34f720e4f08a4e6f85cfcb4d1b4b79730623aba60f85a8d17c52d6edbb1511b78f2ec7e3d586bf73c1ff4b959c0bfc7985bf5a7ee425560d633ddcc9 SHA512 43cafaf2766445aaa81e7bdc55eb29155015de6cdea33cd3602927074a946c6a13e3302e6da95068ddfbf428932e62b7c50f0aa9419ce3e096c5f73dc32526ad
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_el.tar.gz 3151274 BLAKE2B c3819bb800b76427aad78f0431f7c0563658df3f872256b1ac2e35d4f02f4ffca9be05d57d9a5f80ec9679d39a043b5c31f5f9e00b62133de059846fab4ac9c0 SHA512 cc2b741ed988080ac80210991a8a1ff29487f342c4caee349e2e7458e761705825bee7c2ce6fa5d5fa63bdf850604d4d23e6e6d1df126a0d81035d4431d7671d
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_en-GB.tar.gz 7621588 BLAKE2B 2025973abe849bca8d9d9c68cc8b30578b221e28a5d92ff09f037c1c1e5f0f6d392776092a2c5b9f9239b5dbc69394c945cfbbdf94958cdf186b9944c328b122 SHA512 b9797d2591da082562af38fcf802df23a817b40d9602ed25f14aa3adac754109f82ef345edc93fe0fb1119427270a602011337e99c711ca433f6db2b24c77dcd
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_en-ZA.tar.gz 7050336 BLAKE2B f4ba1864ec8b0731ee64b4c3ecc84af572024b200bbff2df6f2aac0ef9fad2983b7027751c5510daa9c2c512e2d9b3fa47bf888b7317458814c06c97d682cd5d SHA512 48932edb9df8ddaca9ee7bec87e6eb33fe1715170fc3870a12631d9bed02d5e79aa8d947e923e80b38a2c434a88e72521e3fbea81b034581305f430ecf40b582
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_eo.tar.gz 973569 BLAKE2B 11089c12b731246354d7a0e68035b009b92c77016de1ca381342b38c3a260a7b8f29b891512bd73cfb714ebb7daaac8433a5039694862838cb1ece23ba4179dc SHA512 fb0db855b6997431e55234d1b1e95acef3d47af4a516155194dddcd59968c2f9b072df163ec73dd85ab92a7310a6c08c82c24f3ade8c693b69539e56c3dd140a
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_es.tar.gz 7777231 BLAKE2B dfe20225a81a5ee61e27c73c6676b23b8f11dc8125170ba18746a2333dfc4706ad7e41de413197c1c881be9d3a3145372754e17e2455d7fd6f4311952e290866 SHA512 03d3e27d97b8fd47a279a6412523fef8ec56aecc7c99e60b662245dfb23f888c38cafb14a7da0a38604f4a453e2b3d57f54cca0f397b23574a9faefac1fa0388
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_et.tar.gz 1870496 BLAKE2B d04ec7850b6ca01eb11dcf91b7b8c01e49c053eca2b7a22b404409c104101bc3eecc6c04a529bff4a5a9a6092aa9145299ec7c83b487c90dd7949482b3469ea0 SHA512 3d836e73d0adaee7d0a58d35cefd551faa31f768cd3dcd1e67a143bba5a1a012cf7251d9d693141377d6ed2da32070556db741e34003f3ca17495fdd0c0f5d9d
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_eu.tar.gz 1014093 BLAKE2B 82335bd08ce4ae6e716e80437b61542484ddf80b846c34cf8db4a7b272d55ac7da47604607c9195433364e8b715e08971c616a39ff68d6be6b12b193e9169b97 SHA512 a65d346a655d454d8a7cdf7545cdf590cab733e8965e8f9f7798423d8c0c6dd5918544a259462d29593be4cf6c6601f4ffff3dc6f96bac5401bc9f45aa1b58ac
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_fa.tar.gz 352214 BLAKE2B fa8d6f0cf8611d8496af87105692518112eb3c41d8fbcd7fb7e2edb2cbb802adb1e460aa11bf3a97158da6d74be462fc44cb44b92d0d54601a9d85149b93b7e8 SHA512 65a69b6d8461684b9213bee77f7fd8cf17e7c9b9ff476a3a96297e879894b58c7954d93aef8d3f1ae4420a8c1a177554269352c693e2176fd928768d3689d76c
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_fi.tar.gz 883254 BLAKE2B 44398c9784315dd80340c06943da1dadceb0987d08111d0cb58d8913d561048a2ab7d14a188162e02b1f9c895ee4a39f7b316bd6590e34809c7da5ae1a41174c SHA512 5e7014fcbbfba8c0682775ff9788a09b2642a2459fff0d22c6b0c3e450d6520d603f9d25734ebcc8fccea42248d222391859ad02716fea60153ef8e591c07d3e
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_fr.tar.gz 3323217 BLAKE2B a575bb08a89319d2596ed4a1966fb6b0d8727a362119bf4d9fa04304ae2f676528e11a6ee1d4f6a951580813af83ba8ef51d9d7545b48fcc6ea7e21c47e20536 SHA512 930f4c24e10866e058e6075225508c1c286c048deac89e1e54ce7eb81f2b42c5da5cfcff7ae8d0e8f7066d4730899ca2b8ec7c8d14fa9e09024c18e46c871213
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_fur.tar.gz 188557 BLAKE2B 9743059e8a1b1fbd509d5e433ad959d5e86997b5b61e7c7fa2447819ed367976480b19c0db9316f980f0a9ab33adae81473f3090e823d7872d2312ce50968460 SHA512 6e4711d6d9cac00a849bdc48efe3b9fb975d5d6fd1e9e31078f73f7914b5dbf52fd8fe36d37b85ca1de2a9823800b1b370f5d9749c3e0af4ad509ac13ffa3724
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_fy.tar.gz 903051 BLAKE2B cc205208637501a6f486e44e7789b2a0fd6004bd08e6e8e4d005a62d3f70977d18fbdbb920c9e95a3033d7af9a58cc10ff6350c19abcd9d8ebc2f32b6d70fa45 SHA512 4fb79a4b1beefee0419e9147cca84ccc2e17ba300e110871a3f8d57a0b9933ab1ead0ec50464dc0d1615b0c4f011d45f34737f6192b855a23a17904a0b2f7d54
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ga.tar.gz 725196 BLAKE2B 9a135acdbf7bc27dc53130c8d99f5f8ae4c8d5c3598daeb2e056814097cbfbc63046ac18d9d9f2aadf9f565c627f0b216e4d9b30e6833bf492d56a54bcba0072 SHA512 2736ca6d622d4ecce3db889a0918728096aac3af98ffd0fbe4ae943c089d502782b982e11d46af5fe4f583af746fa14ae096cce533a333cbfc52eb2d556a1b53
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_gd.tar.gz 1771692 BLAKE2B 84161ca602c4a8e3abf058cd7bc2cea9bbace15e75903ea5b95d575f075b10e116a3205e0895818bd3dfc7ec61d4cf0a37ec471ac0e1b4cb3afb9f9abf267622 SHA512 8c998327d9c85678f846c1cd6a6bc61660519a4a6aef7c94ff5ef5b2b3db30e4041a3c91b82bf3b71913ec2d4b7f3cbec0a73102d410cc3396279c9af21a5125
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_gl.tar.gz 2907515 BLAKE2B 8760131229346e367ed9d9446b12c7e254a1c84e353a46a21ba2e651c914c782ec5fceeb73942358a67ff22bd86050875ab2e72cff517c7fb1a5c8b63b48f61f SHA512 89c190f45a9cd120d2a6506e29cfa2ef2a857bc76de2032061ed9b1787aa2444a96411726d04ef847df6d9933f297c5b3e3e2f49f71aa7a037663f5a5caeabed
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_gu.tar.gz 1304238 BLAKE2B 7cd6153642436c64bac401ca2399eb768ada4089f1c4e6032a27cb3bc7b281823976d9868aaf391cf64ec829f83a020f1edca9d9102077cc68404b7911ed30e2 SHA512 8f0d1a53bbbffbae610e8e17b294f71f9e3ec9fc22131d88ef207f963bfccd5b2b466609a7c59635a1ff881142c458e7136292135b6aaf45befda9d60fc03607
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_gug.tar.gz 511248 BLAKE2B a991d67d5d69a63d407158fdb8dbbe94eb6baa5e9bc0731424396b2ac80ec03025951bf290a8743b2689f4b48c637419c576568a7147bf3fa55e4aedb44b72cf SHA512 e08dd404e5277b776bef32f86e5d90ecab712da78be111e6404a8bbdaa893129e2f4a08ccd41bd0abcac8bbec86a789bbe6555d111be7354b497c0e208ae5978
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_he.tar.gz 1682530 BLAKE2B db7e34b442e6e03587a8fb2a75814c711c9e3f8a870d9c959882c22c26f6ba408643b44a9db6f97a0cb980dc5fbc8a40a53da71339c3578525bd8473f3f04c12 SHA512 6718123f6fdb622b9c40dddefafd282a35c599c0e2431945bc8d3b8d4069c39127e3436ecb2df8616ed2e2630a998e8b1a5cdafda7b6f7dd76f192fdb8820e29
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_hi.tar.gz 562671 BLAKE2B be7c931833e3529e30677825bffa135473eddd022b370073dab7463c2ca9d95bb7c3a4daa3ba47e2ca3988d8244a3c0d74b4a5711522c37ae30ef65dec1e5479 SHA512 cd3f96303c16f898f62e7978915e439af2b5a5c697fd3e71dd1dc30e3d6bc51aa2bc0cd168565bcd9f1bf3ea63f8b60c278a3afaa00e7cb66230be12e1374b20
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_hr.tar.gz 998107 BLAKE2B 3eb499de7ea081d1f26764bf113851ebdf6eafe9269f005c406fb5b74d6b7bc43197d4eff05de1ba3854a9b1013f856873c1cc3d7fd971ebca322d0ab710d2db SHA512 db4b754af30b7fd4b5b0520698f59aa3bb45a0a21a688f270306367be272b046c01efb66daafe0252f8f547724cf75731e0a1c352662874e54d5d41249fd2ce2
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_hsb.tar.gz 917856 BLAKE2B 3f58377931dd0af20c474e8edc7261b450ca889775b636ceb5ad6cfd4b97fd0b6fab9908ef31777a3b87ad18e58324fdaf2d224445681026067ab1e1ffc546fb SHA512 65701628039897e79d7c7c40af89a854e7ca46b7111f6789f570e2514ce64ed04d9cf91813fc95d4dde94ef8c565e4e56a95a40572d4a5459dfb74e2d5a18786
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_hu.tar.gz 3315084 BLAKE2B 5cd3c33f66aacf4b1474d6c418c025dde77667e59027916c0ace16281a85f7e14fa37e607f18ad94e1b2fd04e65e692998652f739ac0180fd27274254b3d92d9 SHA512 b45be281c8ea37d92236676f6d69e77874399412737d2cd4f13f876a39b70db2f61e94a58924bf52d30d8b59a94611d63de4b2e2378f607292c397f3729017be
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_id.tar.gz 1839332 BLAKE2B ab02b06899303d258d44159dcf68236292a7abc270c1e845dc12697449bcc745e6f917a6b1a09fa00a15ca367d5dcab39c8b9b53ba03971a2d690a4b07441d2c SHA512 2ac59977396f7afbc8471b6dc8ec4148ca9c3917918428989ce1be11f4cb72834575cd1a955f0a6cb699bdee5539bda02b71c4753f6771d074a42c83755da346
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_is.tar.gz 1540234 BLAKE2B b201bf3b428c562f4668805355628f84f7caf93e1cee04e7455ffe30ad3296ba06be3c7cd9951a3bae6f7474699d9bd8c014361b22dae595cd0ad93e5806853c SHA512 b44bf1019b8b452064f306727f448bc8dcd458a4de21fffc7c8677c1e286f71e13e8e1927b275f168686f3db8719f484b6ae862f213b8cba7728b513e374429f
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_it.tar.gz 2355262 BLAKE2B f2ebddf584ecf70d1f64815362d01568b7c074c84f57b06860480af699be5d2c4f4fa582bce1da18e07d2c1ebe72cd45b734dca9657b2f54668872f1831b99ed SHA512 69cb8303fa1be68910d5a33d014b0a139add6bf88f7d9c3029c7ef6c0626c29cc5d6597b382a225ec5c5faf63e40e25b21ec5bbe65e8cd725bd918e568c93be7
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ja.tar.gz 984861 BLAKE2B 885fdcc33c0e5d9b1d89877a9fed0ae1cd093dd4cd8e57742d44bb379af2901bfb63a224250eb42fc70750f9711f05cf80f1f502ecaa6d930198825fcc57d1e9 SHA512 7ccc8041697b1d7682a77ed6c8ec618dfeff241321c16ec94ea3960c6dae0fffbda5a242f5ff6ef9829a893cefa4c2a7f4b6395838c866a23f9a368c6e997f8c
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ka.tar.gz 402033 BLAKE2B a348dc762a043b8f4e34275875742b71eb9d015e6a2280f18d4e4e03c1f3bfd0f90b27ec91b0889944ea6f0bb1f0177ce181f02315fb7c3596f4fc36cacc1cc3 SHA512 3b7341c6a7be2da4e585c9af219b489ce7701db20f15e60c3fb6948657ac45e2481098cc3b95cef7af2dd429ab35926220844f1476d114dde628cafde16b3775
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_kab.tar.gz 638635 BLAKE2B 0f0092b48e40b0881edb50c9933610306e0626e2c36396084c7290d1065904ee90ea94d79be8c2b29e0803731f1cd665eea4ab281fa2d54d2ce73206ae99c1c5 SHA512 8854d8bac61e7be8580926f6b14d275a9760da4d4202847076b477eee278b07791aace7e81ac0a30fb44c82ffe31c7ad0de300efbadec2375244c3aec73e56fe
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_kk.tar.gz 832132 BLAKE2B b9a76f84df8bcc64c0e18cee45c01dbb9bd565b30737b36d114d7f075b3608605e47fa6bccd4e875239b9a7e83d86e370d58cbd2cf92484bbe1231ee79791347 SHA512 baadb91ef1aaf11313a60bbcdf8243c020fe48026ba935897356cbd57348d0b7202ded85999613d13806ccbc5a6739963a0c588f84b40c3ad79bbe7b997b2662
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_km.tar.gz 823801 BLAKE2B 8747d991d50abdcf5093c56ad4f39c51253ce7c1db7888dce786148b10700cad02b1e6437f541c2aa762ef0bc3eaa8af953e8a282de70d1914228b7503566b22 SHA512 33bcf89a9ff0d9452bd7c203968f09fb877d867ed34d8c67215b02d2fa0975faf08aa7435c5f92d8c99520acfa801b6b9ce9bedbff8d4acb2901eeb620aff9c5
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_kmr-Latn.tar.gz 335086 BLAKE2B e680ff18a7581bc3892980aa992a0c3a6b11b5f066c93e2e08b2610016769a3f6214352a763ff577769f91f1069fd7a2fe5623dc37c99e249c7f8f2c87d66c3c SHA512 f73c41e4d8706ad5936da83f2f7e7bdbfcb064ffc9bb7015686cdbda3950856b9b3be2151ac1bc1db7322fa6c5dc199a3744dd8308a318943267f5b0b7470f49
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_kn.tar.gz 572601 BLAKE2B ca3c0093c71eb65f96cc69bd1c9a558251b0775b5c2bbabdc53cabb19f2ead49db92eec44028d6668fda3478bc2c63f53c257ac8902fcfb3a95e5dd23c411323 SHA512 8eb799f90986bd7c0f12d76a60b20a4c199478915b4cb04b08f739b9aa0bdcedea7106cda3398a0d3aaf77a3cf9f56f11f6277681ea49380dfe41fad9b21d8bd
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ko.tar.gz 1700687 BLAKE2B ad3235cb0ac9be0b1d9de493ceb9b5603275ea2883f500660d36ee78ea3b5c0b7abc678e2a2e28b65bdea0a412caac10cadfaed24ed14a170d0fefa6aba20f54 SHA512 20c68556b3dd66cacf65294f51ea69e5c958359f6281542513ec204507af7e597e401d002b6ad9b09ce22dc696501e41fde2fec1955a0184b39abbdb0ae3600d
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_kok.tar.gz 409491 BLAKE2B 70e1bf0a9411459099ae80b2e012ccadbbb6fcf015d94d1099fed406317073332e13b48d3ccfa83a720346debcacc92e849dde076d07bce644fda26ade4c641d SHA512 85f1ea1d760b1669b2175bd3d08680ea4d43d3dc1c15afd4380fa7a065fd8a5c29f7863b6e2cd677e9214db7581a719f8865a4076a508ff3f3b389a54dd87340
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ks.tar.gz 329994 BLAKE2B 5df4e84ba28133bd1582c45d3ad18c8b01d84005ffc1896c3811ae345b6339cf81cd017dd8dbd3b517da7f501ad2662d0972de8eff3f9df9d6da792cd55ab1d0 SHA512 5d5a3218108b8c9080507f3c26cb600c32d3b8281a2bca59458ea952d5b8997869209266a5133e619432552fa17ce989eea3715260e8e51b66f74166f0ea9223
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_lb.tar.gz 147142 BLAKE2B 2adb6d09c2311346cd214bb4e469bb805d03db97814e8cc6006f80e19f650f777e6869beb597e0a9cfe022b2b0e6d4aca8d5588c07729f91859eb969e9e5ec3d SHA512 cb6c3430007dbb25b1e495c7ae7790bc358073709023df6b50d873b4bba233c487d3c2e713e5f392bbaa25e2ff8f51f3653fc2e6883186f9b77af8e4877d2eec
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_lo.tar.gz 432758 BLAKE2B 941c4528ec028e4ffa41ffdd4fdc98d0131e78f3b60c197a56fa83507e309d0d2d18037f35fa9ed07ef3368e4ade28f1805a20e81ea862bc01d6cd399a520c09 SHA512 f83e3db232ecdf14dc46744fc57f020e6c3ffd09b7c394e7dc35f6c42cfabee45454c898603d195f3e247fca41499845fe382fdf5593a56a3c38bcf727212184
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_lt.tar.gz 1247967 BLAKE2B d7ce1906de9a9bf34ce3e0cf12563c997d37350ec9a6d2e7a558a11fdfc853146dd45e6fb0f1cf8e8e6fbe70f05e8cc39ddb0eae60e71f719a668af321adf8ad SHA512 d4d5e21284b31b67cb260fe0bea4f427d2a2d9e848e892632ccd0031b8b81c85bc257c20e53034c636e0df3369c120b9cfcde1d4333042e871d2b228213bbd32
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_lv.tar.gz 1176839 BLAKE2B 10d1e960892a70b17320257dcf0ff75825be1e9a712b02dc4430bf956b2d55140fadb7d1098698be23a2c37fc2e7b7fd5278df4f5573e956411d5cb27d7335b8 SHA512 00960ac4c09b83be0789392279dc7e5a0042f8eccff510754c5924d32c3a033abc7d9d26b885492f0255c3f10cb34459ea686ddd7aca6a11d37c1331f39b3159
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_mai.tar.gz 331196 BLAKE2B 0bcfe8bbd588ceb919b6540f0b370a3f91af2a0704ba569be16b480495e8190a603e9e421d60670f7016a18f8858663b3889237059a9d8b345ec7677cae44260 SHA512 39d854f126eb9057b1b7e40260a6857e7d74cf29a5b9368f0d36fd1e3e8e9460c8d442f47c54c05c93bad3f4ed75d913b2d5bdc83b0d1b8e7e867ef287c49aae
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_mk.tar.gz 485470 BLAKE2B 9c094f10707639386dc4eaf788578a512efaa53e70e130d83b3520839b68c4e33c0180cba026fb0529d32016a641e795e6fdc2e49f5e25b8dbca7f5b997c806c SHA512 8fec654a18c3566ce946843e153da62387a057774b8b58817971cddfa974f402bbb8fe27cacfbc2ef58ea7b8638f723f75718487233ef6688b00ac85716e6855
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ml.tar.gz 533417 BLAKE2B f66fa300d4bcb8374785dfa3e82dc088dc75f81ec9ee4cf79ec9406ca1e2814e72c4501be06e8d38233288138f6512eeec8a75d2d89bdf7af0e328b63f8c79ff SHA512 0e044678ee0f19cf7e502c742d5f1d9a9595657c0d538a55eb5206dbb0a2fcb3e664608521582b5b5c783246116abf6bc12ae7cce477300587d435e6137cb9f4
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_mn.tar.gz 691365 BLAKE2B cfd0825a9b2415bced0e24fbe946bdfa0dd5584d830f404b6dc2f39d53808523b340eb7005e50172bc72a673ccf29c5b2351007f05ea31d1917117964180ca15 SHA512 7f93709879e168560588a4c8f6a2d70e8cee66195cef11c2f8cfcef4451b42009a91e230ca63a167fd38d480cf2226e05b4eefa284e22fe8c1925f8c5bf0b3ee
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_mni.tar.gz 399212 BLAKE2B 2eeae18e582519df88729ee02b381425aae4dec5ba7daced4b8277bca613ec2605e7048206a7491c169ba7c3a529299d826a46ce476bb61eeefa71cd84a9c3ae SHA512 4b7b2b7f3f2f2da5f40dbccd955d9de441d66093eb63c66d78133d5aaf57a3ba8b12814560c7a7db4a9b7a5282985da997f1b90bab9ce8825654c83adfbd013a
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_mr.tar.gz 567199 BLAKE2B 1058d3c3e190faf7515b52d81b33fe66c9fbb87e301d373b09685533f219ef11a8473c92a9c05d2dd3125f00f6cf1d8db7ce508b36308ec7729d1830aaaaa3aa SHA512 12b6a834f1db9c6ee37c29e436e1569a38d3cca8c0717af5fd1c64c75750e8c875e022ada8d79057acbea5e33e089958d23f62ae0abc0b2dd67fe806a6aaebb4
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_my.tar.gz 458160 BLAKE2B e79619d4a04b37efd921d80e002b449cbbb6709d356a8fd15b67db6375113562aed7461bf2c55e5e114a4541bc66261b4bf85e1c7cf47b6f4a9cd33de5d05582 SHA512 4190df52bc656e4f8cc9ece935f3ed0fcf86ff1dba0e47c28e7a92e45b1c4c37805006fa9dd49d6544eb3481c64b1ea53b427a8b3d91d889cc6c7d117adf2930
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_nb.tar.gz 4347699 BLAKE2B c21a050622f954a14be2390810f7ee38584f615d92a7e5b17f0729ba9dd650c07eb8e68d2a53e9dc6434d78cd46cb87f67f19f6b5a26bfb581c08b0938aa5830 SHA512 859a19356072f3c24e181375abfac25818edecbf43ead8c8f88fc968b597f347c6c7e289d3c28f0a5ab03302b342c0bbb17df70a1c2bcd04418be8b7ef56d187
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ne.tar.gz 948439 BLAKE2B 4a5e453a968608aa3f0dd969746e11a4d0111dcf7a98b2c63842d0d63c60c55640f2847e5f09b06ba19cf82afb1020ec5b72d05fa77788b7840763c4310782d2 SHA512 ed85e6d0900948a6c88cf16c9c31978ab3d3f75dab9e06b22ad24203259f932faac7ac82d28834170ed94758b776de796f82b4866ddae576b2fae4c6c7c3c994
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_nl.tar.gz 1811076 BLAKE2B b9e03aed5a4f4ca384845aa6424eb18f0e04b93240526ae26935bf0c8b45f19f7ae74d641fb326870ddb67f3b74c2f6b157bfd60c77318e05e56c5bf5edc39cb SHA512 3a52a389c7528250bff7cdf0c62b62dcd63dae5cd54caec33f5f49ea55cdb9cd3dee5d74f329f5878d5e5ec32c938ab0a669718a847e3d828385eacfabab385b
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_nn.tar.gz 4350294 BLAKE2B 0435bf3614a6e58d50a784f6755000b2e41aba09bb84241a73c76ebc2c616cbba95ac8d73d71e41d1e564adae72b22e832b12fe9072eb0a8ed54e86c63783328 SHA512 f43eba6ed77eacf266a83e5856971a59d3581f5c9e4a2ce75968b9361e881bce24d8182965ba7121fa08ed37ffc0ff00e2099e069c837e0367e3b664b7e0c946
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_nr.tar.gz 278948 BLAKE2B dd7cef02216403f4ca4e4ff513e8b19d0ae54bf70f6f40635e2cca13eac3e1989ab7c1b543fb23ae5a537c12363437792fffac56105d50a599d879c429433e5f SHA512 24ad44c9e95dd0d34bd6b2ab854467cd4c654b5bb12a3f4171dca8803cec1beb65f4ae2cb3f6d9fab602be49c2a1d1bbdebeb974fa4ea4f4ad9afc166533d72b
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_nso.tar.gz 321582 BLAKE2B f9d3ad0ae15ab70b04fc5026c4f47a6f1b7a0f4ac144306a1cf4ba26ef3382e3959ce581f8fd2b8fa8528f511abde91c10c8eac408ab0264c7b64d4ea04257ea SHA512 657085ce07178faeb2c5a381083abea6f6b0bcc8403c6039f79d93aa57978da927908ee6864d91e60cc0e14c1906b4e3e8c20a0c8c397df51039e1d9d54727cb
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_oc.tar.gz 1317698 BLAKE2B cd4f0b393ec8445e73c01c9d3ea5616726b4a5aab6db6563a91de4b2b0dbd2f0c6ebef7ec1cfff33aa9ac55b4231453aa9c28cb4aa41e091c5454e61134aecee SHA512 8da20bb8a46b6f04a201f8ad8df2b3b876be647c6b50c480ed737f53ed5566e972435e554627e42a82d5330640051562e56c71b8d047ca8143f5c6e3bab5eadf
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_om.tar.gz 486958 BLAKE2B f854d0db07c929023bc000575bde1f3a1c89c91b7eaf84684fb0ea67348aab11f8cdc86aa3e86f7b6ad6834cbd60857e8f4c3d29f5211053e83016ac0756614e SHA512 c5be4e0985099d5a81f00071f768c3972ea71120b994319d3e1965fe608676fdffc97ce0ce4a0600680a97e6f8c77604c6c7ad94acb1e527e1608417cfe9cda2
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_or.tar.gz 587619 BLAKE2B b0fb7d3d97fe37252f693a53db141839ccfe67fe565851c6baa2d460e9634572373d3bf38b66d70924237a045e369f95818fcd9780ab7aaca0937ad4ddb2ad2b SHA512 59c9d893c0f86a3a22334b397047d383cecc41005598d8afd3e78092fde5a0381926a6e5e3b14b1306a3f5d9f5efa912a5c18e8f207b41078773fd99038dceaf
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_pa-IN.tar.gz 469135 BLAKE2B 5c6379d48de4fb8317e12624a71f3cf00eed382c32bd673de5e623d4dac214adb6dba22d5ccb6a2f6d39400d772c4a84d1f874941950d8550032f8ae23598479 SHA512 95f3f9bc5d0ecf7e9925d21ae6539fe1609f93ec04bb0f2a4b6fe9c2e4435891ff3703d3afa7eedd8f605d954c2b651cb132ad85faba910018d14d88f42dc61f
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_pl.tar.gz 3381430 BLAKE2B 878bdff20786f7a8173c67900c7f1576c6cd77c34650c6ea312d75b97f5511b23565d0789cb9f51841e377e213af2b3c1ada116fb359cd1ca7a14dde755b125b SHA512 2ed8b1037addd2a1af51d029ced8c30c62ad03d1ecbef4c6255daef4482c8b22eace366100d3a343cdfe5f49767e875186feae578a48fe5581f3cbbaf7c78c7f
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_pt-BR.tar.gz 3095996 BLAKE2B 5a17237c6eba9004d96b9f4a56726ff3b152d4d3dec3f97d517ffcc1933cfecad1eccc8281e40ae2f3d5cced5e41e8c3e3f0b7f8acb43a968ff2284fc41985c7 SHA512 caaff3fb3416e7783d3afd14b678792512c6e69f56e6b56b0aa802fefb1956c0183d4268c67b75ee18f07a15084dcd92fa34d1b1510c1f17b76a8938b570f5f9
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_pt.tar.gz 2643033 BLAKE2B dede2ea0eb0a926c6cdb667b8b50ea58a873c0f2fae24b342e0f1ebfb5f7f341357b58054c920781168743a8048c1d79fe12f25672cbaa92a6e316332bc8aaf5 SHA512 d0e6a0d892ae2765cca1bbd3f2aa966c13d41fb2f98d59265cc7defa213422360cc9ce6f3de8859874d2fd6685e201d0b3b69f0d88443e426e0fa756c422305d
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ro.tar.gz 2511527 BLAKE2B 1cdf5bf51216925cfc1cb4ea6693ff29c5ce54dd782cf8639d20a70f9f6d9bcfaba92d6ea32185acd414d8d5201fe4f003b317dc9c5f290aafebbbb7131535b0 SHA512 af1bfc8195015e511e1bc0d062cc6a3aa775c986936cec717dad77142e3953b704a790315759d9338dec3d9f643ac2b10589515a24c0a0f9117b69fe3b5b8c48
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ru.tar.gz 2361915 BLAKE2B dba54959ac2093a7364aaad03bf8d33a0f180d15b735a2cfc1fc953b3b354a659977858b415dcacf7d6b1aa4c7689809a93720206faa7393a21d2858b066c496 SHA512 2997ae7eed5b171e0a72d5b3d9fb142597b9080f6d8d959fcae900c7a69f678fb36dd069e3fa67b71fac58fc5fbd235554a16327fc655e888a866d50d3d72dce
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_rw.tar.gz 346099 BLAKE2B c40b3c50b3ee4b2d867f52a4ab091ce1fac1599e593e9d5e356ff40abac221bcf381850e5f1fa74b6a38dd02940476b20e64c37ebe6636a076fb6ef83ec7703a SHA512 fb60e19ce19567f9ae300c7d1118c8eeae6d33296b02f128979dbfc6fc059f0498b69797cd0ee0acff54ff5fb2a819ad41eb5379ba6f27010992c74c61e5b70f
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_sa-IN.tar.gz 445796 BLAKE2B 2d107c87d0605fa43535c655f82f9ff2acb1dd1e40eb74087c6e0b3ade1c062aa71f534d6983281abe26853f62e62db75e3b644a0feddc6be694121051469a34 SHA512 edacaacac6fff159b79fc850d29e3170774ae152e78017b59767390c35a5f35d12cdafe22a8cb23d5c92d8f605f0a4e759488f14efbace2bed5db3843bfbe511
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_sat.tar.gz 512081 BLAKE2B edd64e4427ae125acb3d246e771b9cf40f5c0f9d924800f2b586a1513d153e2af6debc46d21a8cbf7c3e24135e6723be5d78b997c65257488b108144533f8c8f SHA512 3d9c28f0f11001a35653df5711bb2c29341c866788c04a57951d2243bf5146bb9b95f98f4ef645e613449c6497fe9a5b3247750b9bd0fc775b64934a46de5aee
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_sd.tar.gz 432980 BLAKE2B d6c9e4eba56bafbf448db6921244c1ffdce1339f17ad462258d05d025b577eaa6b3e3cd944f15ea3cf7a40a0ed7a0f625db64dc28eac81113aaac35376625ed0 SHA512 05177c660cdc16658f9e81ddf5c85ad6b2998b6d31f624c7ca9c8bb66c99aa1ade1a3772e9da564836916817f4b7b7f31a8d6043819f534a49bef627c83e165a
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_si.tar.gz 755166 BLAKE2B f3dcd7be3f5dc9878b884f36926a98a575d0cf98574a7a5ff400a713fad8add5c46259dc68435baf560c75f01df0659d56a75edfd87e896c69109c28f4775177 SHA512 fdfe68776efcb1677a66cb4617614b2f2c9149041103754539b45a7d84b9ce9ca5156cce543e2f93e22d467be0e15fbf4e9a137239418df7504501f85f37f469
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_sid.tar.gz 522878 BLAKE2B 7074ab28c6d72f7bb893026a1c3b1e294cbc058357cf47ec65712b02be31ee4ae83a3c485417143f66f34a1f9cff4a003ee956fdf05924f920b85ad40f2ba441 SHA512 213c0bb4087169b55ce9d31889951e377a5281b75bc9a4da13664ad59e9c313f4c51c369b0ad4bc9f6ab32b4981266e93a2795bf1d7ddcf548f3ed72a240f09e
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_sk.tar.gz 2359454 BLAKE2B dc85f2d3524d367be6a4ab0b6d65c131be26a59397b95525614d3bedab72911c040c1afc02039b87e446f2be909565a34ac5e1640ad681ea50f3d5bb8eed64b1 SHA512 71b2cacfc41668099416f3ebebf574a4c2ef69e1244315bf6b35e2e474421eb30a16ae128ce3ec58425674263b931ad93e56318184bd0abbc10093bc4125199c
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_sl.tar.gz 2764052 BLAKE2B bd394b778f2d7ccb95631118f27147d241d9eb135b73c25f384c16d2137c20217c9d5d9d1c1a80fd0d5c7d3ca5f6674cee1d69b57a6d6a2ccab7fe8935f2c0db SHA512 c890ebc3685fc41ecb6e73713f605ba11051816fd820ef58c11f4313d2b04366ed0dc50dda51d69027a384a1a722fd83ecd3a3f98b4e34b93e2215f6295e5534
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_sq.tar.gz 1165757 BLAKE2B e69632ab24c4ad738b59bc1c125679d13e2f26a0cc3a72fc419b066b30d16932b094dc87a9772a5a617aaf3be91254d38c670a3fa8fd3ac0bae7a52382df34bd SHA512 aae6ed475f424b0a674f79001666d5b5376c9dcf2e8773b6cd3c2a5636aa36e1806d1ac074c036b5a5981df3e68d5d15ef24753168d206a832b44b5e6ae3168c
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_sr-Latn.tar.gz 2406735 BLAKE2B 85522d52fbe0e67f9b05965fb68883d29ff0c50e23492375773b8718c49298ef4ffda0af704bd38ef805e98d7c0bd58a1b8451fbb0efbaee70a3b4c19b007dbc SHA512 80ef07f2c0f7f00fb319197516bbebe23c39a3a8e91414a1ef760e52b9da2009eb153cdb596962ba25cb6d7c7092feda1b160457b171b1f98ce746910f44d5cb
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_sr.tar.gz 2774179 BLAKE2B c705a4f3b30eeea423dbe8c3baf8769433b6a568b60ebbf1a75620996a8e04c66049277be22b6b5a9dd77d317b014f2865e29ebbc212a8ef93c0f2a79815c65d SHA512 2b164557b11f24861695a14abbcbdc47e683270b2dca2d14657247e7e4e08a90a1c36ce5df1571a6bbff8c1a8e8dc24fbbfc851c548cef0227e41542826fccc1
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ss.tar.gz 286862 BLAKE2B c5b84432fd5b1cba8c500004f8198d2eddd6b22e96a50d18192950a2d29823a55d4a0f7b8e440d99c8032da7890b19d6de6f08d48fec2796fb19d977ec151ba2 SHA512 8caa12a1d32e2fd4c5c5abc23dd17c1ed128fbfbfc89c51924137d10dbf588306823889cbb7b82fdd143523388d59fd9359498209ea5cdd50e0c7bddcb75cea5
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_st.tar.gz 280565 BLAKE2B 2e5dc7017f070d29c70e155e73ef1bc81c57f904aaabf2caee1db9b4edd8ad726881d133637a461765569f25214f4c1a57e553cb691790da84427ecfcf2dbf66 SHA512 891ce96a4bc09386bf5a9d091e14f94e3f07ce8b404e6395e4afd98e648608563a71269d59cbeb9aa36b78e2631f5f556263353b4390eb54c49748f3cce2482c
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_sv.tar.gz 2835355 BLAKE2B 25c85c30378b11fcabc108fb42d831c022e9ff13494fac63a1415603cf997cadb6dfed57614289a5604f72c1ce70b25358a02689559e10d2697f64846122280a SHA512 e1b9964beae41345c51ff5038afaa96d9fd8883db191b467f7c733695fb8f03d2068070c0fb9156ad69a851119cf5990bb5860c1d41c833c011d4e1aa131f8f7
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_sw-TZ.tar.gz 318456 BLAKE2B a4df916a40282f2327348278348822ba1daa4ab7caf9db7f89aa33c3a1d70274ea35c855272da751e5c5d8c0d138cca61a2d81a3a0f5626e48579337eae04dbf SHA512 40eb8096c9545ded476752a4d4357ad8518115d655144e9573d419652f868a53753bdd6d779836c96cacef3883310a6f8b9be5eb397ace91b850ecd17d7188a5
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_szl.tar.gz 734362 BLAKE2B 650434145312bf96a0ddf7c16ab8defece79ffd67e06cdc3555fa322f37c59f3449f5526fb99c6035646461462227d8d11534f50d891b48083dd088d16ec4683 SHA512 69c98c6f232e037b3c2796aa7c9457d079d86b1ae787903a5bfe80ee8d2ab8e5b6890100874668b46cdb65aa0e9b2f7d106c58831b9e75fb4fc8bc077d5bb9ec
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ta.tar.gz 731892 BLAKE2B 1b23e3091887189a34a274660aa4f1543335db10b2c12c510334f9505d7d2a944d2e1a5e726f3e38149024e6d990cfae46abcf78057028e598cd7cd6c8510a89 SHA512 1e0606644d91ff1c6ace30579ebf48c62d7bd8ef9267ecf30de496e808749371cdc972952366d121b3b6d15c93e482e6ad95224d8483914645342d6374b3413c
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_te.tar.gz 1076888 BLAKE2B 5e3c8d82bf1fd60ce3482bea0d0a7a26a7812532db9e5cec9c145c57267a4b52d9a1c43ada5c4ebc69541fcdfca6402e8b679da8622c036a9602cd7843664d7e SHA512 3ee387b8548a891b8323f1ae3bf58712e429f032877286215bf9a7177a3c9f9a9334579e029fd86d324589884a18929aa848ea93524ac3f9843153360a583027
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_tg.tar.gz 390955 BLAKE2B a9447cd3808c05210acf178e6523fd30a09ffe61a41da25f09637b5ae2b8cc619a3d06d671b56f2a79da47cebdd30cae6a68a359ea6413d79c1a273c87e4ae10 SHA512 91bee5f6d033f897b072b676e884775b78439fb780ec9e8f6a8a9a71ecd8d7ef70d0b275ad3b71b52c7b62aa74863ba5e901e980078e7330a5ab42774c4077ce
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_th.tar.gz 740516 BLAKE2B 3685be5676783810235cffa08e7c1d13690ab6c0640ce171b28ae821002aeb539d3be80262489732e2c287888ce8b777fe89acd3e6119bd6cba5dbd4ceae2ee8 SHA512 e947383a880ce509e0ecdf715fb824aa0d7b0a484d7b4e5eb33579dbf1e55fb2067d57de21f2f23faf8afe244843700387a119fe788ef9ee4aa293e3cb67dc02
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_tn.tar.gz 260601 BLAKE2B ce5ac903b726ef59e4c0651c48634b8a67dd068243a7ff79842300916e8fe0bbedecdf104b514d5cb4ddeaef2e69a159d883fb9231d69410dd9866b752e11c63 SHA512 0cc266642d921937cbced39a91cfbc576490f0f384d41116da1cb20559e9975b2fc8fecd9f04656b58178aa61fd1261e65785463a259941469062612d5380e78
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_tr.tar.gz 3325963 BLAKE2B b53497251243cb925314471e1c89acd04c6bdbe89c901134e2e28de8d0a43b974772ecc679ab91e14df8d663aa88ce936dd000d51814812a347ece3d3b06cb24 SHA512 174424719f5b4c47c4f88443c3bb26a10452e3f4ab609ab97a524f1586f51cacf8063c91fee64f16ff76a80a18d65694053b87535b6cb7178cafedc2bb6145da
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ts.tar.gz 278864 BLAKE2B 8d6f3a11a3053622c5e0244415b572ed56be921b10b1a0dc27d0cf564b4ae879870a44a619de9bcb7235822b839317ce6798d9daa582f6862569f5e1c6da7d2e SHA512 3984ebef36a370f35df71cc6ad20f9d4888ad9d374df412f6497b17047ce55a2fea48a4e5919ceb11d58cebea12a33240cedb238128a9529c57e915af1b3b2b8
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_tt.tar.gz 186555 BLAKE2B 00258784abca7ccf27228f81169c83ec444f2ce8dcd2542b78407e3fcbd20eb9e8c014f1b4bbf338bf0f6b8a92e0013f175a809f7bae48ea7802dc13fdf0b8d8 SHA512 e999112a5d3950de5cd5b59e8cd5edd667419a1f871a792514b3e1ae88501b922fb6f17a38f62d43ddc60fbfec016792efc72fdfabf8c774d734e18458421df4
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ug.tar.gz 540945 BLAKE2B db5c4512a4ee32102055e02f9ddb6ee64d94ffdc182ab50451473b540f1a3e41c969249f31a53632fa309fc1be4c547725debb95043ccf1784a851f3b280c34f SHA512 eb987d08462ce4ece85d537006456caefcea47c93323234ca3c5fe9c0dcc82e7b110afac8a9230ac6b8fd7fd6be2aefe5499932656456cee59f895478af0a94f
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_uk.tar.gz 1908366 BLAKE2B 31cec9f97298739b64f61adad97b48c6c5ab418afa5507dcc012fd60b6e8cc039550970b8763133b34cb42cbf3f4a9162f39cfc7898961b8c3251967ab1083f3 SHA512 807e1531ad20e7df511944ac04758401582ae17eea37d36bb75af38c16cba3bcb4c61a51ad4be097f9432dc490cfee10b9e45323f416bbff0cd383f02fe6f685
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_uz.tar.gz 313786 BLAKE2B 6c3beef47056690e558a9b47ed0c631dfa2382e4839f6d67bfad0d76163c4ba7b1b5fa25904ec9f5bc967fa65c70199b89d89a6d8b1cfa94ff3ef6a07e146484 SHA512 81b497740b1b69eaeacca7b810e95baff3d42676de8f7bf9bdf354ec7491f0aedb8dabdec7055d613020aa0ca13f2a2eccd420dd87529df4de0e2a706716dfd0
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_ve.tar.gz 283495 BLAKE2B 9d0d753ccf7b7a2b66693877b1391f728995e1ff671b784b18b7cce87f30d981d658bcbfbc3e2a7c1cf35fd9fa8fb655fc8e91593f8efd3f1ce2fc1b2b991280 SHA512 a9b330fba859feb508d0399a04dcaa98d0368543bdb3dd375251966f9f941ddbbde319ceba117da9fd9ffa0be88259370e2043c663bbc9b5e12bb62a0dd4e888
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_vec.tar.gz 756583 BLAKE2B faced5a6ba0945f84bf1bc920de027af0e9c1f26800e6b8ea212b022ec27517296fa4f1d8aa7ce2c66f8515dec786277e5039c8bb63b3f4a780c78ab9bbafa4d SHA512 f78578b47de556570df3ee1d85340e120b60e250b950836f99e53ec815e5ac32daf604ae014137c24b4037f8e0c30c2dd06880475327e0c96c8746d94cc8171f
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_vi.tar.gz 567248 BLAKE2B 12e79eccf81a22046a4019e7dfa083eb41c4c7270d0392d64313d777ce0b541945ec663e47ecc98343f306a78b32b5bb699082b3a0986c5407d57f64e8ae9cc8 SHA512 ae337586937dbf3b665d00b5a416d95e8e787dfd2562898252ac7021de2906aae578ae4e6356215b054d640bec0a6c16f981102528f804763f72c298da7fcf8f
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_xh.tar.gz 289680 BLAKE2B 75460c42a3de8b5b9db1a3b856723c7a3e5bbbcd07e59517b32f2ce2ef6e4d79fd0639ee9a1c88d76b958f16c92386b1d1a18ede0eb70f815e3d7c7000885a85 SHA512 42ebebad9c69709cc588c1e2fd6d25f300e9331e344ef220edce5621b621b079bf71d1cc3c24aa4cb62dbc772693d09f8a2686dfcfaa613164a79f168e5001f3
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_zh-CN.tar.gz 1048753 BLAKE2B 12946d48ce5a3525ff7738dfdd8aeec552c593aca890803aa17f68ab9331220ae3d7b89950881755e1b80035fc6b9f0c24aeb665720f8b0ee0f1118bc76dfee1 SHA512 a4d3f1e302105838736507bb0fd73ffc636350722636dd174f2fb69242053ac0717b20808cdf79b44e9b2458283be32e508b326a9cfb2732f249ccf4cad70785
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_zh-TW.tar.gz 974883 BLAKE2B deaf8359cd219bf7d9388a256d5c5a5e403623a14a46501c786251c4c72e90e2c25a51a5ff8c10fbe98ceb2c8bea925292e0ee5ca7747ec24947b82297d1e851 SHA512 22a84664caa0e2d156e5585ad67d1746f7e63fa10b01108baf0c02fa6ef2fe3e907c2c13effcb8c7cb6bffe499d485eb07bd72cd24762f5398ebb21f9e2398dc
+DIST LibreOffice_7.1.3.2_Linux_x86-64_rpm_langpack_zu.tar.gz 319472 BLAKE2B 4bd5a8b68f1bf6f9a0704207c4e8c00d560684f0539b0868531f9374f73ce9ae7c1eb2dedcd2822b328e5068cfc0da15f4d84d29c7fcbed53f0ed8c09ac9acf7 SHA512 18eae4a6ab4fddcf600a45b5e98bf5b74c203f31b81d4292f4fde4659e8e3cafd717ada160ea6da8ce859655e749651ef1dab2c804af8d9d48736df7650aa442
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_am.tar.gz 4126949 BLAKE2B 42c71c001fdccd041c6d72a7906998f413cda6341a9050f8662f42948b9f22786f4fafe9c3b783a17eab5cb380b03baff46c97be9fcba600f28314f15c11683c SHA512 fde17b27d9042fac59b9684515780805897c4f2bfdc9dca9f92337627be638fd886fa75ffe8b4c7f232ca2840e9b39c0d4fceb45cc26faf78528c55348df308a
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ar.tar.gz 3598466 BLAKE2B 71a91901c7e9278e881dc712c653f10f52a31bf6c50e3aea46cd6c65495ceb1e99db4bf71af1d0c0e4d8b856d77e19095298c66acc3dc579dc671e582b64ff5b SHA512 1267a1249474534e7b13014e778233658b516d781eec57d38a72501011a0bfbffd53386be864dc628f70d52adcef6889950ea2ae0fd663fe1ceba1cb2b8975e0
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ast.tar.gz 3837112 BLAKE2B 5f31fe2f8892e66a576feaf9ba515ce0a3abe365294b80b0554784c8fb91f5996edf1441d28a0c9b5d3dbc188af799479824ef1e3cec7db9d0fcca5bfe9846b8 SHA512 9d0b7776f22a8c66a54dcd59a86029968411e58328de492bdcf13529010266c9a0c050fb6fa8644f9f1d08b960f59a7f8983d566b85848147ef53e2b0430a17a
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_bg.tar.gz 4167486 BLAKE2B d85a0c86ee23deacaf6e6287a1d2725faa2fce1b43c0e38035e9459572bc5f9f2c5282c8652e5de28860c2cfd84ddb506a1c6adf7acb4918329cbebff9712198 SHA512 cc3875629591c5e83336ce1ec206b2eeb9703da83a5b2700fa6c250f2d82df32cd25380b4ab8cf80b22b5c9b67d407eaae17878a279cc629abffbeb3fc1508bc
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_bn-IN.tar.gz 4303274 BLAKE2B cbfd420e870500d1f5c069c05f315654d3f48b716c2611cc84363dfdfe8f6224e9202a26594e3b50231dec002ffc2e52cc6713a583c7c82cdd9f83b321d47330 SHA512 3aef15e70f16aacff0d80f34eec79b623c4ca5a8bc3b5e74a8e49c60ff201c85f66ccb04faf0e2fe70636be918d3120a6297ee137417298eb227b186c9cc81c0
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_bn.tar.gz 3980813 BLAKE2B c7da3972337ffe610a1e2be946ced8de88f63c1f6bd8c2b0f0a29d6111d969e945ead5af89f7ccae9f0584ba26ec6f0b69a23154d1f4dd5e1bd05d91089297e6 SHA512 9b51cd98f1de14282c0ee17e5d12c23c9a2a0f693d7b7689e0448a76cfcaa5422a11b3244f93a249c3a9fc87cdb3faaadeec9802d512acb39990d7079fafbd13
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_bo.tar.gz 3989839 BLAKE2B cb2213e6ac58d1a7e0bad2976d8e4790910e06e71a0b150716977184d4ac2b998a73ddb32cf21bc64c7e014d3707ddc93ca8f3fa234b8716a6488d48c24b9d51 SHA512 70b184129a1ae925f9bce154787fbf93c657e71e7eac9a430e3c2132ae1a5985b1e1390e4cae11865617b84d2428d60116659ae703281d1a4dc0d84711abb610
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_bs.tar.gz 3721217 BLAKE2B 3293a3fb57ec8697f57e89858148d8c339f181e29afbd6ddcfa3aaa3fc1c3406cf2b8bd9852ab2606d155cee4f51868b4874770e613968817a05cb4459c4835a SHA512 257f43917b3d595c7adce515a91d6c6c882e8cc55c0e3340950c86162709b278b0aa7d7d69257d441be37ed62b9f74ad5260684256ab6c7f028d61333527117f
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ca-valencia.tar.gz 3866204 BLAKE2B fd8db18cfa3ee5ad6c3449ce59bccd900d603c4a9fcea779671aee502d3ab3985420c4ed9a7becf1ac212804684cc3598ea10ef64c0e4ff04513ef918fa39341 SHA512 4f4a73a143ca47c07da22821cda8aec6407936d4a4e48d7114919bd9c67b5cecb2416ca2e9e36efa7c3056265b2a4ab088da04c81077bb37d174c06f2e0d457e
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ca.tar.gz 3856444 BLAKE2B 94a2521d3ece2216695101403e2e1961612e9c56b772d0468c9305bc0efb64e0939c4253e3ff2a5a3da9b5a70deb6bcd73fd26caa1d82eca61a2ac54f585ea6a SHA512 a410d1b6d34dc20fe82be7669d6643240e6ecdb2aa8c554af2e2e41638aed19f73c10ea2996e36d51f24ac13e87d73fb47a2e22205eb36d36ea5680d072e0214
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_cs.tar.gz 3880462 BLAKE2B 4a4d0d369cebfafd5914d6e223ed9610eb7d3bc277f8322a82df00558b9db621b20e23d36772a14d65ad540a9e4b80730d4155baa22abef0221de3edd6e4512c SHA512 1a93d8e95468e24802694718cf95cdfb451ed019e09724430758c30bcb19e0fd98a66cb1052095b1204f16a34306299b8fdfeae83f8e8477b7ea87008397e1b6
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_da.tar.gz 3784436 BLAKE2B 9b325e32d840bbdbe3ae9a553af8214071ffe21e171368452fd172c8aec9581fe5f381d712343c97932268c0726bab7ef2982a6739b7d2149213ec979cfaab86 SHA512 7074830b7ab252ba99da90146d2f2bb0771804323e070fbcdacff44363ae7b957401f2622b3ee72ab1beb8f0226f7971406cbaccca3fc146e1c76657b39e3a80
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_de.tar.gz 3952660 BLAKE2B 3287c681f2870359eea6aa23c3885a21fcbe939db2db51757cd1bb7cabe4667f274cada6ec4e8b07b868ff2af9e01c6099bd9ff00813cb4575df6e9b0bef9d9a SHA512 998e921e066a416259312c33da0ae9d555d0c85e1d68d46f8cafcf4b560332e65c44392bd3ba5412a0433e560980ceca77d5479657af2509f3d47e92d36b0b25
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_dz.tar.gz 4137317 BLAKE2B 306bae918500df431fba7f06ab73594aec0a169182497871edbda555a9b70bf8b453f711fd8be52dab690a9875a75a92dbf45f74189d01f0eda794c762245345 SHA512 a2f9b9459175aff72546e3cdc76224e9f0d4744b29360ed5908ff2aaad231ebd7cc1a7c73a868faa5b8cb3f4797073e4984f764312f9aab2675cc0899f976374
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_el.tar.gz 4591286 BLAKE2B 0e3a19d1e816676191806bbd360ac6067460321c624eea7930d309a428e11206b08a7bdac71cade6fbe0c0e32825b8c8b6581a6cb49d5eee2a8f0ff3b0183ca5 SHA512 c1f1844ff0ec56a6e24fbd9ad4bf451296db69b697b13089640adff62fcb0f41b8dbec406f25c8b57087c3d54b2d14074934749da4348595d9697cec5c680196
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_en-GB.tar.gz 3607686 BLAKE2B d2715788cfdfbf1b75ec50cee2fc0c52cd8fc75d3a317dac841ac11a1ca90eae5c9ed928baabeb430871bf9a3f347f460ba5688c29636025a0c720b92b9f9d56 SHA512 3246242cda5d5e28af2e96f00ed05fb9331e90345feaeadbbfcb223fd2a3f74dbf8e48f1d09df51d771847cad0323b977ec0c2fb490cd528e4a351b430e1aafd
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_en-US.tar.gz 2286755 BLAKE2B 857f84dbbdd153a8d82ac163a47fec884073bc2abc54a90f66a296b19b4088676756ef2ac114a0ca81d890bd113c9a95e4100a621f0a077ce30ea4f42b821e29 SHA512 8fa8487053014f6c73cc73fe401947fb14e4092c3d652795da7fad84f260b13ad0840b2b57d6f00949829505e0a4ee73f8f0e4495a4704144a3d5c22566bf9d2
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_en-ZA.tar.gz 3600130 BLAKE2B ec385b489ca446820683f60c27aec591dc7379869d0d8aad686aa4c12d568a400b2c134402b1c28c875c4ecc6f488ba8a7e94e38f24e0035fb4e3564cc693367 SHA512 6168321ee2fa62f34c9d5ec16efdcd878e71713eb56c4d7e08a93f2c4ddc824198cb2376a175ab6beaef7e82d2007b444530fb4901fc39c963408736ba941e58
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_eo.tar.gz 3701417 BLAKE2B 9b7350b0c1d8588855735251a2dac3bb10def03341fbd80326813d8b6cc402d1db2e6b39817fe71277519a73376963926ef765b7ec9d8b211fab58c8310fa78c SHA512 38f36938ab125c5cc16ad61389e539bab0e994ba20f3b9f1c8141a1126e185d3a4d33450c63ea77468171d142edb1b782e5ca1d47ceddcc365a044cdc4cf6997
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_es.tar.gz 3899143 BLAKE2B 414e52898f881c963c1d47f584b2585a8638a5f76785d85256233473b8a741eee0a2f6d31926cb23e3c94673437de3eb3ada4f545b009602720d26ac78f0cfa6 SHA512 71e9071115fd1cfa0be3cb8567ce2db2194799bb6c0b62ca13d9aa9f2a46d3fa221dab321fd47631c28f638e50243c3b6506abd84e5765cf3503207ff691ffcf
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_et.tar.gz 3744538 BLAKE2B 350eba3dab02ace022f24241923e308bf828e5710bcb11f0c96051bb731499a4069ced42388e60a3351e33d7bc81d1234d53d8202f1f14461533ee7fe0207afe SHA512 e6edef378b806081f0d52e44cff4dd6f05284bcb9a79b0b89cf22f06789d706208ecd46351c7ff97948398441b572df9af3e1d51c99c0cfb8e5fdd807560f5a3
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_eu.tar.gz 3727863 BLAKE2B e124c21d46048c1a1465be06a2f6c0a19aadf2f000a47ce1599fb0b8a8933418fa79a394aa8620a0f0e2bae577e5289bfa098eee431aa14f138e10f1a0d013a5 SHA512 b8e48946845ef108614ec4e0e531675b0de7d49f420f31601ba1216942245a9afae2168ac487eb4fc0df4f20dac5df8393f462bf36faa974e7c506676ec65f5c
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_fi.tar.gz 3750808 BLAKE2B d25b5acd9926f349ccc9f841a0c8538e7ce2ee6ff2879c6f26a31655bbcac3e8b65bc9f164e822a6342dc768a8ab21f39166256ef0619f6a569a17d0d1beb282 SHA512 a14158f036544d4f69023d177535926031d179a611ed4eef99ebb4cb2056a2c55bc819981035aa125f9e6d8884e32b44456f02706a307246df3afb9122dd5f18
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_fr.tar.gz 3883057 BLAKE2B 6573127798b4b00d8b148d142ee265c5114a3409088f0c95f8dd0f8285f5ed6e59f75717a206550df0362bf8d1515ff42291b8a06bf13fb0900d6cdc691efd52 SHA512 9368c46523ed82614dff23abfc1657920d78ca148c5f4a349a7bbb304f468cc569142566ba13a71155632874f4683e5fa233a9ae1d8eff7662934b49000b592e
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_gl.tar.gz 3835848 BLAKE2B 6c41866305f982706521e10ec05f8d26c979ac01960fe270cc85612981f20523b6e7065d772e1c6d8b78ab2400f1edc6409cb5d110a70a1e59d46a5427eadb6a SHA512 e352a4697392a2ee5ab51a7ef60ccac5bd7ef1dc0a91e62d6a2b438674933640342e9ae96f23ce205acae3451a246f1b8bf4e3a5f10e09a0a1bd6ce780ef753f
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_gu.tar.gz 3687764 BLAKE2B fb4d4e140c10909e6a863af143a09b7a17394e7775fea2c76ac4b538fcfdef24221417ed86b16a8c6d7cd77c351b0e487c7ec3e2f7353dbeba9ed6bafea3b254 SHA512 15cd5387bf41e68674450ad389326e6d40dcbd869dfae579ceff0a18a6a2004cb3d5456be60d53efc22e4a00ae283ef27b2d6f49c71670a21b769ff4e38c63a5
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_he.tar.gz 3460416 BLAKE2B 73e68b6a4ef33cd20775c738b1ac565c14a381d30b3ed92211cd5257b42c68bb0e2efc76f4e42f5460310da3c88fad8be282f4ba591545a8cf17c13709297d56 SHA512 3256deae1c48d8cc5a800c1b90616ba627024615b9c549f30d1b04d5e3a75be65da6ff2acce72d11300db8c1f453a4364ea68338563ba1ac2a45e1a8a85f0f7e
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_hi.tar.gz 3815810 BLAKE2B a93ced371a499a5275341a222b40dfa1fe2638f69778e65cd9d47e04c18bd99b83728a32c95f1fe7013fdb0a473bc7064779b2b6b79e0f0712c8c81e663adde0 SHA512 ebde14c014eb16e30d4d5310a261ed30f9a8109a764436e6acd2584f05a431236eabeb708fe1de0a96f9981d7f24ab745b417f997c251ee80d820de894b3c9f6
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_hr.tar.gz 3726551 BLAKE2B 4469c546550b8c6349c9ff7fb4fd0b67cb792eba18f00797f7314eee4b2bb499d9f5f19b2d2ca79a511f790591cb4030278fc773432f8c2ba0233c5cf4e86a92 SHA512 5bbb23b2dd97e2d093c3f6d072f9b3b6d86cff885edd883bc5c7baf900111c718f65c6fe30fd4c4130304c9390c8826c90e508a027fbdf4c2bb8ca2d303fada5
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_hu.tar.gz 4004434 BLAKE2B 3f47b1eb9a93c0e9c9e1338a160e7842778ec554f73f472e86b209bb91dd7c9abb2b5f553c3ee5478eeaadc0fbeb650024f9f674f35fc4c315305a935c7507b2 SHA512 0c190f0ecf0dbeb4b2f0378622343b565f654d638b2673597396579b2871a4b56ce3bc2d68e55de6690e2f3d2f0a825c8f633ef8ecadd1e8944702727209e8c1
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_id.tar.gz 3682184 BLAKE2B 7babf21894660f4963dcac8a603411a4dd910838db1a7a2c7c1a5e87d1141d41a64ad941acdffa03f5f6066acbf5d94c50be273445e8ce75ce21f2c26f8a5a01 SHA512 fbd203f0436853fd244310e6f3264cdf53f460efe4dec2f07bf87e2c2fa5ab967f3b8ea1b668aa7458d18e722343fe1dfa249fa59419feee4e1cfca3d3b9d73b
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_is.tar.gz 3744084 BLAKE2B 1795f3f5a03e7609b82e432d527d671b34e4619720812f7a632b80dfac2bc174fa1f082779d3512483353b695b42839cf508bebc676103988a1542a722db0f57 SHA512 336fd61701b5ad63249b4c422a007c73550d063fc02f3597a2546631a461639d9f1075fcb69cb320909556bd7db73b6a05cfa42472731654b0ba1ea56761ac63
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_it.tar.gz 3806210 BLAKE2B 31cd4a5c00e2407120aebbbfef28a16e5145f2d96b2224b3ad80905f5d215c75b4d2ef3b0b9a51e06570d0317898fdac829aae315c5155a21083d6de4686241b SHA512 b67b8c8e16a2f92f2bd6b029eb30cffebed376eac52927b9b77599f8266c61e6cd9dc84815a219161d8f14a0ac1943a0dcdcf963f7ae8f4626898a7c7c876e60
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ja.tar.gz 4462854 BLAKE2B d5d35dc794db555810a39e9a7b1130b305b8dcb659ed63e0c8cf9da7b07ef27b72a8c0e5b323117b28e33eb46b6c764e0e2df6d8d943f9eb1d86e28f8a9acafa SHA512 6f40622f9722969ff2bb67b08ea87108c5f2e7e04b9338f7c17c7a9d101691ac55c491ff585208dfc9fa5af89f725870e9e8ebb709f8416d50214bf175cde6ae
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ka.tar.gz 3932296 BLAKE2B 0642329dbea2d25dcfb3258f5affe705cf515da1fd3e6d682e83089a595267d0a4c612931c7d0867fb3701a6bc6dca6e809cbfb789b085080fb477aa2cc9c6d0 SHA512 ed48f406cef09e71ce7b54a585a7c6ca2af970f6242e23a0e6db67855d2a7e3b515fa0075b4df4e356dca412e6e256fa15d70e6b26b0c19832e384e92f79f943
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_km.tar.gz 4268969 BLAKE2B bffc6fc9cbf0c84afa4ef68bc0b39cb3d70e0f23bc9bd814a8ee14965508c3e299dca5e0c6c37ca8d09127d45a65ad191cd7dce5523d03ee41e7e7dace71eba2 SHA512 3568b1acaaa1bbd271a29493595d35bc2e8869635c90c231a6b899f77263b81713d8591d78a48ce44a4316c1c2883502bc998fee55611b3740844777ee1a2e2d
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ko.tar.gz 3964617 BLAKE2B 3f9996a0a52d56c33b18c00a36b25dd67a781e4fbf6b66534cebd036cfcff2fb1ef9cba07182cff84b438db233394a4b319f41315e92b6c6ef8ac5441556c2a9 SHA512 14a5744e7c6901bb72ce21d844ac6549fbe37a83607f0e221c64ff0d6af1c80f7a691fca5ee622a347f5b4f5d1cfb5df157d6ad4b334777bd8048872f49dc434
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_lo.tar.gz 3685593 BLAKE2B af8054e3c55261484e4bee2567db01eb28fd322861132cd2a905ce62c4bb58869163d09282338e8db75ceab2df61a1eb468e6c5109860be428f7763e984cb423 SHA512 26c239e2b018b73b916837ed47241a47aef20b97b21fac780e89214c6c98c68bc75d5a80f74150f3558c6a8b236881c4fc3db04a4ea6b53065b0541cbee0c163
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_lt.tar.gz 3902673 BLAKE2B ad203345c8bc6985e37e32aa489f956cae74e627747b75dddf38d74e78457396cf6e9570f3cd28ca7f1aaa5cafeefd96f0524f88184c77e392ecd9f020a15e28 SHA512 ac55e74e82f4e76d73158e6cdbd83a05ebb7ab8a30fb8f9fcb67bae9efe347dff04fd081fadecb6d6d927002eca62486a5314f6a09f4c846f8337bec1bdb77e1
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_lv.tar.gz 3738472 BLAKE2B f65f86bcf712fd462de9a6e4cb4d9755c51d8a370e02a9b232041611fd5dd4bf689c3820f539afc5f2ca762b2b8858b36a43501f2ef2531b53fa7ea3095084ba SHA512 a4da2aef46bb6a9c91f2898e50f1b31687ee0329463d8a8d8c19db4b1482613f064efafca2c71b374051db31ddd0baa8064b5be73bbbc3a6aacae227e69e91d3
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_mk.tar.gz 3780203 BLAKE2B abed3bde264e7de1a59572fb06ed57b8532ab1627e88cd35c0b08238dc5db78a115b42c94f53d9fcdb11378dbb93ff4cceaf60ea74b13392dd60fc372de76d00 SHA512 995a83cc32d5b2be77dfdce5658391c952ec38d6a71ecbafb729fca995400f810ebd2e9f7068802ca0fd440854c5c1432218dbe1c1473ed3cf57a6cd4a869d8d
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_nb.tar.gz 3742525 BLAKE2B 34da21671b3f9e3b6b9d39aae562fd3a1bc18e6e1ffa2595538e7399924065cbba9016e190c84b8804a35b930a380979c0a40257aedcd992b3f685ae3bd6418c SHA512 e5599263922c26663ed094e44dfdfae90deb9172b9f3ad9b5685ecbbcc41895d6568fb60ca61044b96553ca825030840a4058c4d812e7bd1faaaddcf7a3c331a
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ne.tar.gz 4019457 BLAKE2B 9e46944a9553a749fce18228770f00a889f7beffb0e9f101e6be5c41207353ae26294a368fea04172b6c64778802d457d0d3b0051a0d40b43b2be29bd36d03b5 SHA512 2841f1223d39ce2d2578748203fe37a744bb2b2c076083ada798e34370668d79072d220900b75f89aba87367c1fbd8ab83c534c8d5d5563ffa2333965e8e20f8
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_nl.tar.gz 3849602 BLAKE2B 5a96826a6ed57794f153da76d43c542cd8838db340268a41adbf357f1453a54cc6732e5b74d90dac285f54394a2ec1429382b1400726fc3dddcbb9f7c4331a86 SHA512 f7e70459c9e55d5a27e6c0a49b4589bf7c6b50e0fae788fcd5dfba090706482cc2c8b934ef81e32e782f617105436573b1855691c641f3d64bb9368ae1041279
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_nn.tar.gz 3895520 BLAKE2B a4a510cd444ddb3e89a735275aa038d54bd6183966f9d47b272f52a882b9191b446624e5d3a10f664d684c326fb2f0c9feb580dc1e3fc68992469b48da5d1187 SHA512 58fb560ea9483e8e3fc033828e9fc0efb9fba55a4baecf01b3fa525ff394f704a7265a1eddc6a441bb3c1f5b10c46d702c5f12ba71962f65dd36a38125b874d5
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_om.tar.gz 3791708 BLAKE2B f51117b57ad70caf088e0787cba21fb7272a5aafd6f6dc95a98d8db34af8e70b88afb73ae4ae5576d47658c9285597a728010d0bb5e804243a17f272e82f80d3 SHA512 440f9f5abcd0576bf59ede0d265bea28c8464f3eaa59fefb1d7c2c08559f3a1d4c2bf37ed98b36c7302a01e22d25368d9915455be4044e5359663a96cd67d4d2
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_pl.tar.gz 4034909 BLAKE2B 978382f10b998070cfba36a070b707cae517138ab613cac9273fa48b70601a3937228437705b1fcf0873305af309a09d9439bc9c804063468bbc17431f40f8aa SHA512 7bb6097f6d5c04be9b00159265eb3f6eca6917a88e48a034d7fdd2debeecc30a8dd9085fe6b1af9b4f153009828345d42bb2501a59ae00e5d6255fc8387106d4
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_pt-BR.tar.gz 3841985 BLAKE2B 7cd868b774fdb647dc63c706d76c782396418e5d47818b1c703da08c21124012cc03e829e51977dab3e5ed57b580b742bf4436a7aceca38afb3049d214dcf1a0 SHA512 7b43b62328b27b9049a9057453e6acb110259608a17166db740a3eee0db49b190a5504e3f31b0ecf7fc4fddb6ac2606d68ab03cb26c4f78298c7e042e9f8cdab
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_pt.tar.gz 3830145 BLAKE2B e9c16cb5fc9c17ed3e320b866c19d2f5e59679a497d8b3bed821aa13bf454df00e5b4a39c53a9c1a6b25ffd6f74323dea19ca4b55152ea9bfbabdb7a00ed189a SHA512 6ead2243fec56c2d7d10fe3811e0cf83a3ccb60cf69a490977e314c36849c89567bd4824e72c05b09fda7f49897398c07b1877b93b21b87d0aa75b1683e1c2ab
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ro.tar.gz 3634673 BLAKE2B ec93c797e15e4895f70dcc08101b79929297dcb2d528cbfe904738bae1eece9f3adee0339cfc31d79f853ff48ee7c4c19992edb1e6b5f2ae9fd0162812bd2122 SHA512 3f8e71bd0128f8686c8b31c8ac070581c97b7042638712532687dcc7bc9af52c8beeaf4e526ed9fd39328178e2726c1140df9a566c15d59f759622bb43b76db3
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ru.tar.gz 4185371 BLAKE2B 05190840180dc9dc24eb326b602267f25eeaa2965b6bc5f494b9718850dda6dde590bf96d4bc8d2dce4b8f0c165481afaf617be78d0aa5f28ce9a866bae4aef5 SHA512 302a77e0297d98a1ee3b721d0b8e4aeb12113708313f1e7848211aed5d4668659740077c0b02db578307c204e3431c82413b2d2ef884339399ef9552476a0f3c
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_si.tar.gz 3916639 BLAKE2B f295e9d3e000d0436abf0a1d122a4dd22c184d5a3a9ee3f8ceba7fa94fcd20196169d6454cde7c7d2f33b67d863b386c307ac360672d6ff64499f9a290922a14 SHA512 537dc0109ced52418073189858f4ae79c16f1b41cffd25def6a66344c7b317fbb204d37aa1cac49435d515ceacc2f452a69d9220fcfe54f97ee84a0ac9c2dd5d
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_sid.tar.gz 3780732 BLAKE2B 08aa53c6b8230c9bb39f852ce6b7058dab0c2a7f3171f099a5af0549f08144bc1d9a2bbba50ae311a0323a70163460838899b3bbf8d94eaa21339f1a0f52513b SHA512 c8e0ce887090698454e06b1c1721de053c69dd31e355e3a5041534b6e4c45b4eb22732df50676f75d001e1d733a21bef15e5272881ca60d3fed7005d5095f286
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_sk.tar.gz 3939265 BLAKE2B 9733ad69ef96e601125c87bea11c8adaa75d4e23c2557b0f3bf6b20c3b04002429138b70f4d68895a060cd076e06b2665eca28b839ee381d18f05a65987d17d1 SHA512 8021496fa04703ef3b58def2e5b6928dc231885590430ad0bd2080af59529678fb78361a3a431aaf757f55b9b2fe682c53f712ece6cd54e18b7ff11de284bdc9
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_sl.tar.gz 3795197 BLAKE2B e30562a483da372fda72c58fc4b407a118f04929965643a79170190fb0f5944740b16ede1e533a791e62d20f2bb7f2cd6d8d6d9ecdc164479292aca1673a0429 SHA512 1baf39fba1062ec21c5c3cec8878723854e184f01278a985b768112bf9c4f9910eb6724e729b68d36eae3121cff2652939e2e1046855b181fb9cf1c0db6fecba
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_sq.tar.gz 3695165 BLAKE2B 6440c512c205a60cbf9df94c3d93b5471e55abe437b9acbb1ec4bcf667a14335964adedd8aef00b5ce8022aeb075c138f2a7de5982a8d60aac31a6f1b5c695d1 SHA512 16a5bdab7d7e4b99c4b866dd09cc90216b65f0a15cb63804c448d17d1d87e597ef5390f80c3e8f97b380fb7d11d597224569bff1637dfaa53dc77a961df30791
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_sv.tar.gz 3782674 BLAKE2B 70c385f278a61e1f31e2ee53c31c2abe771f02fe16eab3bbee78317259a1dcb34e09a3aade229ed517406557dadddbb9ddb30fbf20de0ab8d33738ba16a4e9d0 SHA512 e6a7dfaed0cb08accbfb439e0019766c95883e1aa94c8fc12e2479830ab2c2cf358a62e045aaaa1c9c85a2645f575192fa4a537720a55afbf0bbe232f15e354f
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ta.tar.gz 4128995 BLAKE2B d018b7e44f6042194599e5c64d95b31c0cb08946d4400565dda12d1d784c81ad0dcc622420aef7ca266e8c111f9e48a747d6c92eddb04a9d4fb209f03986d0f5 SHA512 0fc8c47ae181c0222a46c8739031ef0e851823ad894ebebce7952c4dcc4019481f71c6a23550cded28884aef9e96f61a812fb1727dc9d481bec28464b3144fa4
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_tg.tar.gz 3750564 BLAKE2B 5309e3539e0d1c726ce4ff60413b7f0dd43fdaa569dd5ab14f2bc053ab5334121781d9a224e87b2554f92ebf8b83b747ca44b7ab5292ce7d3300bfb5904ff092 SHA512 909627162c526ac7752e75c720e362f8fecc508dfb0cec1d8aa51fdf6096683cddfbd2431c7eb19b34f3166cd00622cb63c9f9fca087e367eb284d995c3a0ab2
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_tr.tar.gz 3847950 BLAKE2B 5ae5181589167bbbf8f15b2c5a34baeaf0215a0d5a384b26c51e9c1d19ef6725da664348affd96df66cd1cf939b9479b22139ffaa2481d331faa129e882353f4 SHA512 b3c1ffcb12d18bf4facf4c8b83125aa729c7f702a0f48741f16f6dc8f2d180cd172fd9065bfb0c8d4eb41719278a906832b029811c77af84cac7909b53881670
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_ug.tar.gz 3862480 BLAKE2B 90b2bbdda19cc71c64a26e76de0331497718c70bf7751fb83f6524f8f64650db3a9c087e22cdb41ae0f776de420c30a5531bc1b11de211c30758ef43d284a16d SHA512 d716f6aff824c3cfbbecc7341990282d27da35dd7c6f67d4f19b6b7ee1c9fd7648bfa6ae360b65668a1a1db37b2ee5045bcc925531351ddcf1b58a1e4de5956c
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_uk.tar.gz 4173833 BLAKE2B cec60bac6d40c34e5f3932d8c943ccb14b24c7eec97a8433c724a549b901c1f3788f77701a1f7e145cfd0c28f04a83495483f00656c14e871de1deff1288e4d9 SHA512 f270ea6e6350df9392a2f97df859b5dac84bf53d8162f0878dddeb09ee7f93d3788e3eae8fa428dc45c811ac0577918b2bab6d1346bc6dc8295beeb882cf0e37
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_vi.tar.gz 3824361 BLAKE2B fb0bedd3aa0496d64e44fb8ced4d123625c2be0878e559bd80002f15c7af6645844b4a6de000247806982b4af098dd2743a34f7ef57d85053f408d386cf857cf SHA512 7166a5fbbb31b115d577e8ecfaf05d590a78b01064871971600bcd0386697560af58f135a78ef54bd1d076e798b2588878f783132147c4f30d22cb5417d46693
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_zh-CN.tar.gz 4091429 BLAKE2B 7f297dc6e9f8acbc8c2a153745ffe4a352a9b1dc9c37d22b346ba070852833a5ed1203b5be7961072f06a8162776e8d71ae1bb9fd926db7a722bef7b278b7283 SHA512 6915a60debce07e2dcb622c968c4c16e751e1977bf449470d23d55d6117e2c34935db6ac47c442a730f5039758d9052f968bd992d99ec52cdcd8d6d63633ea88
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_helppack_zh-TW.tar.gz 4208143 BLAKE2B 99f720c3da43c9f91d40214f174ce4367e0444f9b218ed9e3734b6ccb9f6bbce12a52af48aa2f04bbd80ce1d074367b75824a3cea0b3eecd868dedd6d13d762f SHA512 b3aaf69ee647a52a2aa742ec84217642d5914f9b2a6623348a3819d4fd1855304a19805ef88e3b7e076f4ce129670b6814f6ca758090fe1a25ccabf376680a8d
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_af.tar.gz 1487025 BLAKE2B 5bf90b27276452b20ffc37f9aece8a0d5581847ac448dbb5b5ba897071543d2203b5c64d2f3ce0f8926200599625a4f9d93529c873fa4d26fb8003da63c87984 SHA512 c4b8d82adb200a2560571dc5fdd3b717a992fe4132b69ea72d3ae4700bf969a84a526a8527706ccbf63696e8b169d584d0e188a2370d2ba759b865075ededfa8
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_am.tar.gz 959518 BLAKE2B 02bccbc537de3db468260788c13dd380ac1c4d46815edaaf076dc36f3779425f6377b13a7e0aa2ad027f0e3deaf25f7080808cab8c71b68405679ea2e5ad8327 SHA512 c90663f7e3808d31a488052942b65dee7c2b75c51f3e35ab9cc26f1684b153c2cba17c07e8e11dcd6881738a861b3d0f462be28f31b8752142a936c29ec5f3d0
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ar.tar.gz 2445374 BLAKE2B a676386b2dc1f29cbcc342a6ba81efdb55a444a70dcd36ebf67f4d44316e034c1feace1aafb74ac077bd4186e198a464ce8dd58bfd38f042642f7ba8b7f416f6 SHA512 7bc1643dd6f95f4fefa1233638db2c29e404624f74c1a9fd0a99f600319f32f1caaff6b907b26339d78eb9fbca2b3a193f44bd4482ce77803df23e3ee731e05a
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_as.tar.gz 524195 BLAKE2B e296ce817cb6ac7715504b09e1dbe6d24f45352287eff1cfd1db1aa76dbd290b937c7cae4e9e6ec6e7f0a47a28113b43abec21e019e4aac24f8dbdf4c840e142 SHA512 73a6eb9200d30805a3d795c2c1acf984e3d1c092f3dd990e253b1571260a7864a442f5d42113b305a2f00c4bc1a605cdf3f49f2aee35518c040aa71b29e0ea96
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ast.tar.gz 573383 BLAKE2B 66855ffcea4b4a7b2ceb3f3485d1988a22e94059e956d5ec1023ee5d9c5794e78e93bfb93be4c9cb174c8452aa20e7b5db5e604fe92a747d740bb343b6fe19de SHA512 d79cd833f8a5fd1e8a1b1692d08e3615813e08bdf2d1f8b582942f5ed16e7c1cfb445f667bcef30b97162b0b24ff28fbd18954d50d40fdf3488e4c0eed8849ec
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_be.tar.gz 1051569 BLAKE2B d4ba30f8f6774edc65c85ef4ddaf008c41b7dfe83584c6223a37f060809fe1f085b6858a947efc62ccc9f2103f9c78a9045c7fdc04b626481f831e2601e06186 SHA512 ee1ed14f290416c64261164154130b644f1f59fbd6c0bc1146a766e203ccd20fb3a2f3ca7b4430b9e96c859003d8efc0793fe1ceb89ced4dec92d88efe4189cd
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_bg.tar.gz 2749202 BLAKE2B 57f8ccd57c4abe48be6463520922f556eea3b6c1548a020f457f1a712af82d2634fddebb15fe71455590a28cbe5ea6d81a8438ae6fe68f28c08ad9bec0c98ad1 SHA512 66647195a55bda65e16f7e075b81543233526b8de7866b3ee37a8bc3d46b60e3176b102fc33a8fa3173e68d93e15dc26abef8017e71a2354ac01da74eabc3331
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_bn-IN.tar.gz 724981 BLAKE2B 894be8deb0970ce4e6b0af6a9170a0e907410936f0c279a3dddedbd7713496f93c3cb81c4ef54f4d9310b7cf4b51e29fe432b42bf0617ce452d710c7d7b71c7e SHA512 6f203ac3fe08351a0661ae9cd65f0f240f220445efdf521cf73980fce8d75ecdf9923ae624beb5a85568e55d2fa644f97a7a99c376b6127497f1108e04035120
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_bn.tar.gz 879965 BLAKE2B b73b4384fb45ad1977287e5a7bc98eead59d13caea1aa9410633285f5641ac615b613b3627c71b1651f6845b4930a9bd179e55c0507f946b6b7969b685acc141 SHA512 f74145dd36746fcd5006b783760eb1d378a4fa43e342ee1aff3b5e3936fa514dca697f0e4d45a24f6465e4a3f775245f89164ebab3a3bb5774c682f67d437f2c
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_bo.tar.gz 458438 BLAKE2B 6f16c037697d8cc6340d96a515a705288b6ad146e048c16755b5508e85811d7ce5f463ec417b628e6680e60045a364aa99ca235be7406b786643683f845ebd04 SHA512 20d591aea84360366fcfa0c525ff5ed931fec9d43e41a887b540f21d3b06c6b888cfcbbd3ef5726ad77a2ad4b81434d8e6299d54aa22dbdd188a44ef82b13a00
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_br.tar.gz 1519561 BLAKE2B 4545ba076a4a043845446516e836aed9b3954ed015e98acf6f3de2f5da81b24758cbdea771c0d0654b6bbf59d5dcb41659c192fc0cc6e84300c7cac642728d68 SHA512 d165a0a7531b72ce1af0abfddf99a937e91447e0952ff153ed9bb3ee56a0751ec795ab003fd4c04971e730aec005cd07e7928dd2684d0f3871334ca63d435dd9
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_brx.tar.gz 336042 BLAKE2B 69167a75e2b00d5a5b65525beda054c7f5bf9d8ccb6aa9bc99b6f9930da792d8f005f8e3d5f311e8455bc4c34b7b86db6349016afbb34be6444792eb4fa4973c SHA512 f7e386e15e7268ade99eae124201a2e0420d672077fabeb8719cd84cdfbc1535e38e4a22a9fdf8e1c8fbd54917479614bf916bd0c3f725acdce0c3c5f56ec040
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_bs.tar.gz 672656 BLAKE2B 39e1321878223e8eeddb5d16295ef3f8d774daffe6fe07a14e6a1f00f0353cb8959f6414ea95204b46cc30954ffc2ca7cb00679a9cbc88762728134e63e37a76 SHA512 a52e0b2c9a809b7d9ec53dabe60f90807d6f8fc72537efbe27fcd02b1805959643371ca0624502c4de1e1ebd09253ee2c95a16d220213e4e8739e2910ef50456
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ca-valencia.tar.gz 2656963 BLAKE2B d2e98132d089bcf8358659d867e8fa67253612132802e1d4e947c981d773973055daee7a2c0bc3ae89dd2677311480b554efb3a81a6fcf3299f6385e38216d1b SHA512 27f05486092a950a18e5d83c9130fd9a2d64f6a0607ed79ff179d4c9d539bfb2667a15742ebaf2811dc9871c6b36bc197bda61fede0a99106cb9fa921c190f8e
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ca.tar.gz 2724865 BLAKE2B c0b5d3e99530ab0af4d71060f57d07da2878ad4f27b2a070482072c41354b9859458a6b250439ccf2e66f391a20af3638aa4ead74fe0103fd706711525eb81c6 SHA512 a8017f7cc7717ab046ad7d348501ccb3e88c9fcc220c24e10622b6924f4ec8591eecf58d62377c55ff25c721b6fed048760c9d981d7084af25024e6d4f8e18f6
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ckb.tar.gz 365042 BLAKE2B eb5e92c39448c425e2774bf8e6515e2102bd82da41a81631e5514a7e01a3724c455c80d19c6793b6190714a5b0fbc0ed359f6d320de1b8cbc9273bc9d636fdc8 SHA512 f88f83c3e212ed9527e4b66331bd43da7b072f69d911c9ffbf6757ea0b2053a1aa092c55f9d9bc2ed08e1cf9f1954c3436edd7879f043ccf3ef5ee1c61920762
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_cs.tar.gz 3471406 BLAKE2B fdff54769ea1ffb0a0015199a653b5bcb3321170bd054f9b72775d9b169e2325aa0d07c4e3e0446ee0c31174e6c89076864b1fc32a74837d7b64035aaf608310 SHA512 5af3abc47edd19aaf8cbe352342c1d730ec32f29ca52e2dfba8c481c2f64b40d38d8dcb2cbf19e2fd1c7be11abb2e8da00311f9ebbaa79c27ee46378665f9f1b
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_cy.tar.gz 1013060 BLAKE2B eef94079fcc32d67a324ff42e5bd56875d2d29c28f0979e81b359a1e32ef222f770aadc74bc3f4aeea6d2ec7466dcdb159d4acb052e1ba426cb20f820962311b SHA512 b56e8b79ce207766099421b25a03c8194e365f591eec33572f09834722891bda0cbef4698a626a61543811d6b8358afa7088dbf0d2eeffa80e383d434aa70eb2
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_da.tar.gz 3112209 BLAKE2B f3970b732888ebb114fc8cba863fc04d5bd2653b24e130e5839ecb4e25decf895a084fbec4e70bca115f7745fb0a58b7f4f48c5d061d72e1a4dd5cffc9f44134 SHA512 214b5a83f9e4ffdc8bdc075b871df66eb92fcc656927698d2cb70e60a6295d661a708610b9d3af92b0878d7d639f791c9fd2bcf27aa67efbccbdaabc5c8e84c2
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_de.tar.gz 22051297 BLAKE2B ece37eb7a931f823023df261d14f08ff10bd335107ccd01fc9bfb49c53b6af134d20abe10c9f2817a016f17d88b7b8dd5b3481d285bb2250df20062be5438847 SHA512 aa5ec0b351028cc51a0f781f30cdf739b8b7c19dcab053541eca3e212714c740099922cbd8f3a6869274e3319ad6516dcf6f56735c2131f790322e50fdd1994b
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_dgo.tar.gz 435414 BLAKE2B 3756059a815289a0982403317a73d24e2b453f43e46b5977132f91937a438564be45d1038ed303f046f4cf936a3e7577ff8b5b58c16a28184d725059701a2a2e SHA512 70f2ee961fdb305edeac26ba2c80c61b629eb88b79e16f7bbfc4b328d8f7130de8c3759c1e8618faf048316c3eeae32a4f81590febeb2fe81debd134d2267edf
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_dsb.tar.gz 908561 BLAKE2B cbf014c9f243a92f0ab37a6aef4bcdf269ebde59f20a365b29c1a5c401038cbb943b9acea6427e41bd4d4cf0bbe1e511774d3b176bc0ecd74d9305353216c1cb SHA512 0d46474a39b9878f74c0efbc175245fd2815542ca0503096ab8d9de6db86f5a4181ddebb9fe6d7190407b42388c6e7312fdeaa7eb74a8545ad26e8b3c733db76
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_dz.tar.gz 484810 BLAKE2B 20589af253029937564067ea5a4324e1695ba83cc561ef946c695be685e5cff3250fddc1dad8f6186475f5c978c6da61f8552dad3abc12125cf1cb00d1740dc3 SHA512 9017e731ec150a15103f7e0180ab6dbb78bc2453a49f9998d131b474c0721c37f155bd6ab38ab713eb433eed9d83caa7e5f02ec6412c58f46224d5728af5f8af
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_el.tar.gz 3151810 BLAKE2B 70eb656b97006eb5ab1d2c7520d6c6a67972060ec52fd107e04e642624d8a2d2b088ab77c645394842180fab1e8d3e4eccda053868deb1d3a5fa38838252362f SHA512 6280c315aab8788eb6c7b234b1dbb484e8f27e0630bb9c3bee5991b0605c6d310286da363886c8e2716c2065a03f3e36f81bf4348c3b6912a5c270d19bac96e1
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_en-GB.tar.gz 7620668 BLAKE2B 8b7840550b81402c21dceca6025dfc280cf06f18d293fe1f0fff0e0e93f21f11c62a3aaf65194516d7ba5397a52705e348adcb100e433079c4d8527f6f1342b3 SHA512 7a2185c273ca01e7d73f9c02525107892b8053826273cdfa9d42bf763b00e2bdd6031cca255fd6de219974f6648071e352cef70b6b1a9bb85f61197eb55661f4
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_en-ZA.tar.gz 7050257 BLAKE2B e120a6037e9e9979635ebd5da207b559f5c7e2b05e5bd23fb6445de6b3f30a888a538b4a26c3988365b939bdf77b314ce7c679476f65eb2fc56772ed1b5cf6c3 SHA512 88bf7e85a04d150a3f5987abab760f1b2e52973277a3c28e360a0509c7be73467c5027aff104810fe3a70dbb147ae4bcdb9ac5248c92552b0bdda04eb374317d
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_eo.tar.gz 974346 BLAKE2B e8ed35f88aea05ef9c0ea634fb6d1a72162e2c41269f32f87f9b05afb7773e9a57d23601fc5eb23d5040de32843224a3dad6d89b6b9ad8fb9f86c6ce3f8351d3 SHA512 c084df9a55cd28799a107fc870cb671146eb9f783d06a518b33019a39fe649cb095fe4e9576e9f8cdad5cf8ae6ca0b7c2846fbd0d650b302728e6192b74eb96b
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_es.tar.gz 7780579 BLAKE2B a55af9a8490090d1ad0034e31a3090ab4b4245d6de40fb2cf27172b498720f04ef1008123162af1a65ceed3f1f24185e78d256677f43fefc94ef289bf60a10d7 SHA512 c08ef4ccdf3f94dc1adef1305bfcbfca3187c4545e7f6c6f787c4b91d9c3111154b25afa998af48c83558ad356b9f4c5c2ffa79d7a3e50a4993a3e0bd1a97dd1
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_et.tar.gz 1869554 BLAKE2B 68885a49d55a4d57753ad74c85fa1060814c95988842324bfe3fbe6a9883dea57558fcc840381827135ababc08bc4c9a6817514b91c80552a1a787806c05e293 SHA512 4e30e303f33fd30dde1d32f6f4aabb1d19ccf63594ac6409f124b6b78bd70238762107e0038d77445cef0ad3d130bfcb6578735abb76a6dd448214982ac3e858
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_eu.tar.gz 1013435 BLAKE2B 1e1523447b9960c75443c185547ca47e19568b8fe1a94924d47dd0494d05e97ce840e2a902c4441e49346af4616465ad09ddfaeb61f2ff938381c0e23ce06187 SHA512 f106ffb2d6254dac0dd32189d0c413d006077e6306b9a9d3b4b6dd062ea9f27f2044a58e85869df969cead042774bc5220a33e4517477e8f7b978e591ebadc7e
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_fa.tar.gz 352216 BLAKE2B dfe14943ed7b959b17aa60773ac0dbbc5b25f1464e66d74f8efcf044900d55d08b458722dfe66e4a3f64d7fd00653751167de2d3ca6e2909b9447b5e0acfcdf1 SHA512 f855140c5cae9c549395f9a9db33ab3092bf9079a5fef2995688f8b74d5429e3aaebee916166f1bb327c9e948791927d8b0e5a3c688f2a3e6796c22e06b836db
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_fi.tar.gz 882657 BLAKE2B 35ca1118dd861a922aae770026d79d03799ef2f8f3c3b7e52d0de3ac1aaa5c744335d90f34f3c2c892a55f3b3e597700395df63bd7ac15d0f6feb5d3034773d2 SHA512 904f67bb92b9fb26c436f26a9a4cde01997cf6df4d94765c8ad3e486a2603c42e0aec6df2a903c44f7a0f17fbf3c6be4fc18208a1efc4bead27873c8cd6fe25b
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_fr.tar.gz 3323160 BLAKE2B bbbe9b619d1a0dc8c12524e771da2b76d3d4cc269fcf80b0b714fe0cc6bf5f72ab1f8c631e549c211c96e590d81fc5aec1fb356a2b87ce9ec289f618cefa9eae SHA512 897d6b34fdbabc54a8c7834f31521715c929bd047d0e025862619a43044f57281ffd4098dc282f6a5f7697dfff19ba4477732565ae2f017c40a9a332ecbc4953
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_fur.tar.gz 188568 BLAKE2B a253d61c1276eb8f8aab63036b1e96b5b79ebc914d8d8ca84829855aa55d19774adf8464dace53b77b83516b3a3c3d6be927561e6389cd711e9174f7fd08db23 SHA512 ad5371ef73672eeb6a18dddbd4e8ff25ce71ba7e49d42afdf055d28aa20722694f2afdce2922c9662d7e213928da38c28cb1b0e6e018a5ee93b046fa6b13e7f0
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_fy.tar.gz 904666 BLAKE2B f5ec4278223523a5f1f00847cb01b217e7b4f063b6b0d3505210f1f24d72c37d1c59187cc125cf981a4857b745840f06599b50a3df0b0d55d3c8307fbf6fdfe7 SHA512 62f146537d057b183a149d08d029e7418911471e2b994e22f13ebcfc5b0dabd00a37838dc579926cd07d05206e778b3153fc24771184a0bbb968a62622311de1
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ga.tar.gz 725833 BLAKE2B c7f51c05132f0f1abbf8948fd20f674cd424e2bba41aa0836c4c337f033d642899d24c60ed3b398d1ff4bd075b8c05af6cb683398d6cfbf7befb2c9388af4691 SHA512 ced8894cbce07d927462f9c7018997a32e18ff2b240f2a074069c421cac67eb5045e89abc686046de07747769f43aba841960e69a2c5c8e935ad59911ebbfa5b
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_gd.tar.gz 1771717 BLAKE2B 03cbf9c78af684581a6e884feb444dd22ca4e8ff8e72a7621180d16892b1c662cb79f891a8088df827ab3a17a807e0ed4e2f23ab8f9a61e3e5eb78b4bf1ac5f4 SHA512 2011cdcf2a3370261141f45104311ad2c41c9a634ba2ea4ee931df2de631a40a2898b0d4c3174197f7cc26425de0e022fb531b9b5062a05f288bd6e5d54f72d9
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_gl.tar.gz 2907239 BLAKE2B 49de35e70da17b893d6d0cadca01500c9e8ad09468b5ef011c5968d739ead5d40dc19dc5d53483819a1a418c7e3d99fd11987a3a8aa66feab9f90d3088df9bb4 SHA512 7e2a55ce14827d7ed799c8179ef02e9a2af320cb29fbe59dec1819ddfe4ec0e2a24878c90b13d5114d8c0c2e7241e2f36da93aec604bdb052e89cd703b43530a
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_gu.tar.gz 1304710 BLAKE2B b6fb5023cc41d145e930b5f2f6bef566424c87e43480e15333996bb46e2a61d61a14c8d5c7779aa9f8e1bd14c526ebb7261033777b00e93853b667d03228bb7d SHA512 4b2b5d7ab25a0fa898fbc4c5027c3c5866a7410820ae8f0519707056f2e9b509b21980129cc75cb12e1e3f13ff7a3a1093027201b05183be7b6336c448f7b2a2
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_gug.tar.gz 511838 BLAKE2B cd9b587bd8ea161e632b0af7483a9b0b7f0e8267f16a7b3922458214c633b3911ae8f6c8f6b604c1d795e34f6e84cf0d300dc95ec4b4e6f4084ccc0e8cd8abce SHA512 8388d407f712bbde13783fea32c7d955337906ceaa013bf176e31f49d3b55feb9d6e462c212c6c8ab79029fb3ea3d015630c300c81f63cd70d87da7d7843faef
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_he.tar.gz 1683927 BLAKE2B 94fc7a1e6e97797d64978b4e1919d81de4ce20119f944aecec921b288e2be3ce8b8961a8784a33410f2e65ea378bf32b612fe5befeb74762a72bae2c4d970955 SHA512 0acb88ae57d8c5839c6b4762433fb7e1a4e9bba71b33b7189db7a90400a810243ee253e5250955cecf9a4a0af69190c6aaec217e66aab7e7126b5ae4e07d3b54
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_hi.tar.gz 563365 BLAKE2B b0c75c141281ffed33f6faa494f613f5f0b45e86090ff77365b7a9ffeabfcd48f824f456310754745f150d33c698d1f748bd1a9713e550067a31cab12b4dab0b SHA512 2bac6ea3a7305c6d08cec07c09f3d1b29d4d36499932649fb2fdadaf1162e740b0478be595788d7395b0aea98fa7ee17b5c047f819867d509c614f042ccddbf8
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_hr.tar.gz 997802 BLAKE2B 97f2bb803aa476d1e51951f5d59fc92b9d0c0ece8778098e78a0208b61a135257092d3755a0f8d104de9f1f93bf94c8561136048154cd9abbe125349ff91f1cf SHA512 1ba209c6b4078c7414851362114a5bd4f596427d0004be2e056d03fd8dd61c75d8086cd2606d277a295e45a72cee0cf1936f18021d236e0ed9ece8ea073e099d
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_hsb.tar.gz 917832 BLAKE2B 3867f03461d1442b3707dd7cfb622c5973b2ebba995c50937b51701789435776439f214b06ad4433cdbabe406e10fa4db37029f308e7adace84a798eaf66f924 SHA512 47c6f22fec632ee235bf15943dc58fb66d3e660ef10b444e38fea59414269ecbff19b50c0462d8f33b9bfd87cce8ebd6f11ad0cccfd69ee9ee7c12f847ae9618
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_hu.tar.gz 3314597 BLAKE2B b7ec83f08e36ba6af83e40365eda6f9c58d73067ae498dd92f233a50edfd05c16dd6aa83b2cbf343ec9682ab1427788e2a143868f8b863e5722e8f0564f4b4ff SHA512 9e46829c22a9560f92e66fd708b1b2c139ebec752413163de3fd826c225fad4d51cbb39d642c3f810b0b127882e941c43280b6e315ab71a43e484889975877d1
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_id.tar.gz 1858506 BLAKE2B 06ca4f78233d0f3754c9c5b04ea0811029d5fb2cbe3bfadddecc0ebb08147b321d340ac53ec5d63224964921d66f539b0c931cd8160c1fa4038a164bdb160df4 SHA512 016ff727dd16b3063dfbe56fedfff7d0506df8efeb7553a7e1f2abeef407c5988c98333e5c500b7c1bb2b1e58159fdee4726f80c1f724659bd80016629e90243
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_is.tar.gz 1540159 BLAKE2B 3ec57498a2f464d526cac08164ed46b76764b2a83b14eb17497b0ac38cdcd121de079620d4af5fed5ea8db11730cda531e13fb70e3f21deb028c174ba2c8a0c1 SHA512 4d4ddbf9a7c6a6818db8f09f1a26fd5ad53d32df53cd56a8b7a87c5f4f29bdf43ebaa044d570031673e0ce2091aa5ceb2cf3d01201e369514e86b81678b69f47
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_it.tar.gz 2354904 BLAKE2B 9e9d061b34b03fab013c6c18b0aa4915ebdc21701a2de40e268ff577c90c592ad7250829de9d3d2bf6093903c95149c0df1315174af48b1d30a63621e2e6fee0 SHA512 8a23a6d9eecb452f12e2dbf97e8a45445609181d586927f21157dc44bc4b3ff2e86632f7b0a2ffee3928b770b343b0c03f2530bf3ba82722fed1d8fa1f0f47a4
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ja.tar.gz 1008058 BLAKE2B 6b5ba598ab02c5bd2d6c40bdde0fcb31c26fc0fe7868772987aa64017a062ad4ae9b8ca0a621b5c597d5fa01861d7148640905d7f57c30609dcfcfab6c1f0b94 SHA512 4dc2716e06c1ad33643bb965e059eae87bed714301d19dac4dd113518014c5a508d91991fda66e386a3a9c223ec2d73eb4b0803204ab3fb692a867c868cf8a0c
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ka.tar.gz 401392 BLAKE2B a8adf73d48fbb8ec837a56088fa5a05f1b01a553f442247c61ec355d764bc096389a839346b57c241db109d5d05e98cd5d3f32e6f1510eb1fcd0bef83e41e23b SHA512 8a7c6ea483dab0384735827740692fa42aad8a2dfb1928877f1cc35f260369dce50d6c654b09953f9abdcd2f729caf33d09fa860d4e5f09be8c3b1adfd0eeba8
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_kab.tar.gz 638645 BLAKE2B 0bf33e9659a25c98da7efa1b8afd5d84f9aba6bc2f645e2e4de7b0ec5d10fa56e2fb9542494fe6b6cc229a3afacfe1fafb2bbe2debbee75aa5e50cc5c5b66b1e SHA512 163913a8815d5e5b4a80bf2c90270680ba1022aa253d26cebcf0b16bb22ca0884d83beee413d419e36e8c97cf45f234f359f3ed9b9426de9609df7d8c65cdd53
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_kk.tar.gz 831970 BLAKE2B 1a55c254051c54af71b6147c4eb6282232c765c0a4acb8c744fdd97f95666500a8a31378604d6fe304e8f1348161ca8aecce3cc028da1283b24ed540e2615f03 SHA512 e2112056671ecfc65eff73a08e7acb93911f53db06e0e54b6f1b817bca4d37b6f763614efa019e953e076e37a5493a543679317cc6aa15f6c44361bad1b23238
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_km.tar.gz 823803 BLAKE2B 327039a616d30fd0df7ee9b318baf29e94f31d42d2dd2840b019268a95f1bb2db9d1f1d96a5b9108ca39ef8e2ddce039b05d97fc51905e8a481d87afad5e1baf SHA512 757ada172d541e6e1cad70a90e9bace0e9609f8dce883ae89ac28b187ba64d797ebbf1eb9c55bf0b3b7bbc9c65b8377801bbc97d9ebde258a88ee281ded29d26
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_kmr-Latn.tar.gz 335414 BLAKE2B b3dd2d96db187d956689e34007c3a42ba7613463a0bd0921a2b29de8568d7137e1af16bafe2d998a1657520803868f27da9597453aacd3cf8d502ab150b51199 SHA512 dd94dbbe2a974532623d3432765ff0e7aa4d6aec2f20aabe73018d2b4d6fefbf6bef95a748ded0a2bf4454b08f4519c1de8b04561b816ad438b2e9c64ec6c92a
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_kn.tar.gz 573081 BLAKE2B b826ef306da47a1f74d8da133f83a554cc53e4da5f632efc582bd8e2befb36b4280656edd113aee47e8c17fed715c09aef68946006933b9ccf6bc0f08b352ed2 SHA512 1bed92495abc2c9fb45d91c0bbb18cf885337d8fe874f3658c2a7146adb637ab7dd3168029eb6b4edd5d954ec6c26eb40fe11764758661e1528db5567404426d
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ko.tar.gz 1701905 BLAKE2B 8688b0c470445d55ffa3d93e373b587561dd8db8c2363de938e123446434fc8f2dd6d8b77df0bd5887adaed5ab43c16fd9e5e9f116549117ec09c7e2bf4efe42 SHA512 30eccd8ff209f1ff4f13276cbb5dfd643bb810dee4f962614030ecf1b07be009f612d2aff0b0468bfb3d44127d33429619b1661609ff62a210f2fcb8691b94c1
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_kok.tar.gz 408917 BLAKE2B 16f2a760cec8e04b0ce9a2d362536a2e07d6aa8a286fedc4394dfd8ecd9920edebbf719c29ee73eb6f1d9b91891b66a6c3aff1445868f04ccde0f4a9bd529e41 SHA512 8854e03fa72369ef9d4dd2131c0b9f4f44c5e43dc461aed91e65ec17f7037466962afc11c0eb954a0b743c16ee9218e9de7023f266efce891d5b7a225cfd64fd
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ks.tar.gz 329318 BLAKE2B e53206c99b49c5d54e078f7503734aad5dc4e6e7fef2232f407478323b44540d184242349c43ca81a2ca093f0ecf02a9d2db7433090d25cdbbb58b124c42ce95 SHA512 743fff0c6f88d17aa5247e58553f0d587e9ea4e1b9b37fde08fa7685063338a72dd5c3c11ada9905be2a481a700f8d747c9d194056342ddf745f4c2f76f1c26b
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_lb.tar.gz 147750 BLAKE2B 4872aebf7dadc436594a7c84f467145ac8c13c457a6ef334a5c7a28d787bcc78a5741bb70636cf83be6d03a7ddfa5e20ed1d75816e8f4a3b9c599b721f87f5c6 SHA512 07f03e430a14ae04cf68ea10b3a05401b995663c202829e25e7c2d61f2004cdc1275471f60c002e8e9cea7a6fd86f4350daf3024d327c668ff7ac29dcac04571
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_lo.tar.gz 432760 BLAKE2B cd4ea6ce9fbc7bcd8664dd1c725bd311077a730dec28f3348d3abbb68ffaac3283ebfe071beda734b23686e6fe5ab6b5f3154aae1f8e32eebd472ae4d9f31a9d SHA512 4c9a24d39797e011c2312be4d77ab49e84d31862ee1158beec8c8a2378b19cb3fc6f50266c67ea8e5be23b8c17ea0ddbbda72991e634ad35b4daacc3168e010e
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_lt.tar.gz 1247928 BLAKE2B 0b8062cf3a5ba8c67d2653560258442ff25d166ed51315ee5cbaf4d4534f0621c771976d77e3bcabd0f2da5c64b011735b82850c120112bfafce7fdb427bb122 SHA512 946580a69b383d770773cc95a774a99c63424260fdec2eef6e6b1e54d0ea540abb22d8c92827573253ea7b19631dcf64375cca1cbccc11b34d2b2ab25e05c89d
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_lv.tar.gz 1176231 BLAKE2B 360e818c548a36455d09dc81faa0f9449669850f59bace51408eeab202e8ed3af7da7882e9893517a1aea68a1200aa77b8c8e3237c120a62f5b5716b6e74eee2 SHA512 7a2e5c5a796a63d4e90e29cdf157970a4de620f191477b2e708695b21cc0ac308f12d8f3c40cd401076f4b15bab36ca523b83361a1eb16de2c4800e853c17127
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_mai.tar.gz 331212 BLAKE2B 69492a075086a2fca935da7f23ed99f8a1885d72e9be57fe9f96886e40d92b0b5bd9881ebba47cdd6510f17cf15e34a772c69bb97eebadd064fdab00f2ac031a SHA512 961d5bf5c1ad721e7eaa9b9a5053941d2719cb8e3cdc61ba2f32891d81517d58098d7df8b7964c94e9cd41dde1d452ee1acfa9097748394ac1fd4c096ba6abf9
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_mk.tar.gz 486142 BLAKE2B 6aa1d5b290c6fd039f6c4f037c4cfe92e3ba0dbd5d3e2a08a84ac4b65afb48745f7d5328b627283f99f32d19d79d7ff46023080b85a888d2a44caf8896461b8c SHA512 a8ab8ca3fbdafa4e7f6d783da020bdcba2f135b27560ca3ce11296441dc22b4a8fd57f053cb2da57a8f6d8973299d8b8612c511e81b690449f232a818937fded
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ml.tar.gz 533477 BLAKE2B 653b97ac7c1e7ba47424f0d6cfc15cc9ec39432aa214f91fc44b3f419d734d3cd8367bc540446c0cc40cd0c99cfd33bf39ddaaf31c5fa548b1d8e371fe086974 SHA512 893b48e666cbd05c85c0f25a07847b31bce001fe182c2833c8fdca2bafe961406f962b90f8de870565f9777f34c2f869132c9ad2ff3523201544b7f5607ca4f8
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_mn.tar.gz 691864 BLAKE2B 7b34609f35074e489f7300d29e4cc6327e2e221290874a99ad2132653a9b6b075f17ffd1336fd4f7cfd57936a1f7325d0121d509e0f301f87ef2e1ce83f2c622 SHA512 b591db04a408be2b32119bc79e58d0dc82fdc6a67c524513761f775ce8d6b54afd43ce773d0ee2a4a5d8a7b2c7b953e66b08fbc298bc1dd175150bc305c24ce9
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_mni.tar.gz 399274 BLAKE2B 6019eba2c0eed9d2b98ef481f18fd6658b03781adff9e825f02e0d234b37349c43a0ff0b7c5ea2eca8f129b4322336951c2410169f0ad4d8441bee88bb7f67a9 SHA512 4238e792b3284840a778fb3fb445cc4309308e4e535d6125aca4d1560ab6a7ad9d8179407535673cff9da49f52b6fbdd3e9fa41784dbd13511e2e515eb1bf377
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_mr.tar.gz 567865 BLAKE2B 1a6dcf952df2e2c8110a8c218e499d17a1a20d2f30ee7fdea4729e4046fc84c03858bdb98f0536926b04a4ee0111ecc5a5c342272d9a5e1c3b68ac9948b8e8f6 SHA512 0984cbc6a5bda4ce05172e6d861269f415bab9cbd2a273a1ca3b702b8d1ec711eb676ffe96c593bd91aa363fea8c8f04df8fd3f544c799b4145942e4a721e4b2
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_my.tar.gz 458185 BLAKE2B c03c5316362c9c40d3acd41764adaaec0d46ee049e9936eb16c696e65bb2436f8a208eac60b250228c2c1d79cdd21a46c5de43e591237f10bda0d0aed7aee948 SHA512 157b8f97f588ae606b289438a4cc17e71e80e0bcb544854eaab673cc2128781cb6b74403012c2d5dd18959d143e7b1a234f1d92a1b118f1c74150aa5151f9ed8
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_nb.tar.gz 4347641 BLAKE2B e9b31bc29066642b373809c0ddb0227b68eccce1b7c97f23497445d8f24bb6cb695588432e39cb817022923e3c5f624cb91a437c045849b0fcede1ff44b52f3d SHA512 9f35c52dc37cd887d635a966aab5fcee23a46ac4c64c9935c3afc99d88fea5af486cd52e3d90f131bd7c38e1978b65810c447703ed7a0f05261a133e161539ad
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ne.tar.gz 948423 BLAKE2B 2fb2d42344a350cddec47da0e81314453300a2f029f60f54a2d941510706c02b09eeee9389a15c92c0c79ffbb423d66c1f323fe91dc5843043675641c4b43e07 SHA512 d0825a126232c1ad133feee3643dc8dfd44822f4d6115ac07f2e9758ae11591faff9af0f181f87bc8d72038ef9385e3cf33a2c4376761766ca518ccbb1803053
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_nl.tar.gz 1811126 BLAKE2B 3a14157fa6f0aba358f0d19f9eca4ed497922bb9aa6d1bba7f6624c380201a7dcec5f00b0c94d72a19dd7b0e04739782cfe76b31e89956c8cf7dc5710e64de00 SHA512 9a2c082653183e71be641b0252f06d082ffaa7329bc27d60489c97ea88ef16a16417b87b8340ea3c0b19c9c5fc231530c657b812be3f38642318153b31ce5d61
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_nn.tar.gz 4350466 BLAKE2B bff9c948d2ed11b383914d6e306f2cf77da269db82cb23c341cd6e96a4eacbb20fc6fe4edaaa72def1c565af2716ec9911b8a64aa2d0ff77d3c47a6d17ec75e7 SHA512 5b627a1b8e808501fbe75d0d1d2f982ee7636d26c8bf8d7197d5d4b254968a34ad5a687f1b0f50f24d60cd985425babd88fedcc86ee4027f5fddbde4000b733a
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_nr.tar.gz 278958 BLAKE2B 54565745dfbb4654d5557595f0e7a6f43fc93a352eeb68d5f6630883d6a5dfb2fde74fd045c68843099f819bfc90347049b948a696dd08fe690e7585a8a43fdc SHA512 37f2da11552a8b318bb25796509dd9a9e49802e5cc191811716f6d8cb5a765efada82a491717a257684d67a67ea3e17c986da9ec608906c1bbcb44bcfea87971
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_nso.tar.gz 321594 BLAKE2B 893c25d81d9b8c6230acc331bb6fdd41208ac0515ead79a8bf421df88c75bb587b92f03b0c377a9f4e44dc0638015acd67db3aa93a491f3753e5bf53e07fa373 SHA512 1427cb766677c392ca2eec341c651d770f992ed76c06416ae89449c420910018d5def733f54b7ca7830f777d1beaf8ba5839157c95febe30cf95d16c097ccaa4
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_oc.tar.gz 1322263 BLAKE2B 924b35b1b0129e136cafebc55394238955668e5a48bef9402b4598fabf0bf940fcb11e395edd17892e5afed6b90d6c377ecfa815bd7bd0a75b98f6ae6850a559 SHA512 d77f524d0371dd2c2e4f6c7736495b9e69f2dd7d15df5d2938b9b719503a96151450d06cfbd51e8ec22cee985047b9a7136d52824cf5df008dc8393e808683ec
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_om.tar.gz 486383 BLAKE2B 7779944ab6ebd7101cabc1fbb723c3e9f6afb18f0b599056517280b7556dd5901f3e25792a2453e15010bc64324a9fc2d2c0e325a6730b9e4eb8b4877ce509ad SHA512 18934d59ea0654220ece09ef49f9f28fa74691d193397dd4847f57cd12fc26b940dc312f0720e0f1beeaea1f693c7e054b452fed60cbe9e43d4a18793e562539
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_or.tar.gz 588172 BLAKE2B 2c6f10c4a5b5836553297707c3228b5a28d737f7c43471005836729bd1d32a156a189511128d480168165a2f9d6ac3e126b6081110c747615d8ac409f96e999d SHA512 45cb4eb036254c1cdd7e4e1071a1c7cbaf3b593ada6d9e38f9413d4b9d7e776bf45b9bb0e33d2ea490724d7f106115c5981c9d79eb861f68684b3d16769c0201
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_pa-IN.tar.gz 482274 BLAKE2B 4a7b742cf1fc959966439f411e7f735ff72e405bc69eff0f194562baa4c7df69ef18dd9593da291f804dd856e8a00b3a3dbdab0a43457711fddd9accf9372b71 SHA512 e8b9c70c64f503743db4c92efbc1ecf6b22c2f1e77b9dc6353500def02b69909727eeed21c1afa7f5e8316c233846f6b50218b755efe72afabee46ddf23c1873
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_pl.tar.gz 3381826 BLAKE2B 2766008c4347dc987d2e38ee19c827fe3e7612b62dff36105fb24ccc21fd47d6c1d4f362c674c67bae4878197a77e38bb2fec6cd6774c0c11fb3d4cb010cb1aa SHA512 6b2a53d2d4c4a5424be6ad3aeb3d925b7e764025ccf43f5f083a491d3b1061d9a8bdb6ed0833da5e0c1091b36a3017d2bbecb77cb577a312eb217babd117c4ce
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_pt-BR.tar.gz 3096185 BLAKE2B 489645e65822bc395abc6804bdd1b7868fe30c31d6f69b821c6644d1af52c07d5ac6378a8b5d6cd0a5d78ba24901aa7829857bd3d840f359157be6e7bdd5bda5 SHA512 35d98d15dae8501ef3abbe0700218c329c82ffea9b0978c3872152c66c34d2a0bb15ae3ed8aafdf0add4b58c4d55ae28865289336a97319c1c9b49a1300d0010
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_pt.tar.gz 2643057 BLAKE2B 0071880d2753cfef290ab6ef405070a12bed8cb3c66afca24bfd4e681114d043daf731b3d411e3868c5ea2a35560770b5d4f6c1c4b503eea2c05a4dc850e4d14 SHA512 88b05f8abc0f240954bcff76684b1545e424edebd53af9b907fe3cc1739e73b073160d403f5abd653141554c98f2cfc4989857f2aa17b130f5674e1485c554d8
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ro.tar.gz 2510703 BLAKE2B b3a7dfac99f2fa086ff54623cad5b032c7ef48f017bd7e440f30b317fb3866bce48f04e7d92a59482a600bfcd032e1693dfe4270c00a534181568f68f06f9e71 SHA512 66f01f86199fd5f48986bd4826a62cbc114a113a8411fb25e8e4a27c7e4d8500e923fc4825c283df97f66c9557c8a9ebdb78d319a51f29d1ce81e520b5ae4611
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ru.tar.gz 2361481 BLAKE2B 21d4c1f966412a87e23578719c91b191d30583cfb8e2893bf78e2fed9e90b431e0a6752a20ff83886168b6602b1abe515d13bacb1b890806fbb5f59f6db526ee SHA512 7f20a4985a536c59deab93ef237e405d8de64595987acaf51d877544b081e187f3a71b4d6ec8e9458df188bf3cd575f6b983ff540cc9ddd9960e81559d304416
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_rw.tar.gz 346101 BLAKE2B 4c106b1e827a2882abb543f8fcf553aa45df2a0370c7b870bfcc58ee7c63f3a78ff251481a1e264509ca08bec5e4944b3f5d597d210153a67877ae04f6a40331 SHA512 5f37afaf6075e87c98450883758bc25f0aaf708ee6a28c08f142883f06065478e279464b456768c9796eb17507081577c0c323fa267fefd7339ff948c0fbad33
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_sa-IN.tar.gz 445194 BLAKE2B 48deb163326b13a952d22edce5959f021b5b280639d99480c1a24988d3ec5fab48cce80f29e39bf7fe67172ba74f4436e59086ca2b27781b9834fcb5f5d79759 SHA512 958e4cea01c13d5ef17c665a5a6bf9763ff66d1dfba1eba3333e56b0b992ff3328a1ac4c089af36e539fecbb0d717262b0b3984fea05e9d494f0eac5a71ad6c5
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_sat.tar.gz 512557 BLAKE2B c35c76b16a230d9d5d2779b363d8c40d40be9e57a20c5910183f243effe8e2135744bbd065ec0d0cee9c6e91728f1da673084f1722c437d32e0c19c31e57d012 SHA512 09ed45a42335dcf1b276a5ccff383f308504ccccccb9ef12d032ffd8306d2d48a9127c01894078cfe05bcf027004c03696bdf2cd7b43d0e6656f06e78ead2b2c
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_sd.tar.gz 432985 BLAKE2B 5d212bb190a850ac940a169dac4fa6377eefe9500fb4a27f3ea2664d106ae457d315470e84f7662ca08b4a1f6471385ce05d62dccb2a0df9577dd8a4bea7de34 SHA512 54c7b0b649524963c0de6d5fb0610a76f9fddfa6fec6a125d6ba4e9652822e1e717bf75cceb74f1c6b849f8b6b0953e04e6e08cc5af727fe8724ee519d697e24
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_si.tar.gz 754523 BLAKE2B 8dccf62b32c5fb021dad6ed18647eeb03369f706f44318a8585c2a21b46e4abf42c527fb88ea2041acc38e7eb63673d2c1a37a9f20932880bf2ca2a960e8f9d0 SHA512 0008ca9832899391a1ca454d2718c1ba4231e17d9eaf2461bad02d5fdd3da78198b47d54d29dde99371b959829d657ae4a5a345a40e763a6cc0a7df5649c9941
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_sid.tar.gz 522874 BLAKE2B f219ce27f1d2a62db1cbf42d0fbc2775dd0ea41aab1876d2a694cbb4838838e0df7af1a72617a36089cb9f0fbabdf037d914fafb37172f4398c5e0d0f50c49a4 SHA512 d83b9d5374c133ab0bbaf2d96b8b921dd7cc21cddecd58e416c0ca16a1f3573ed883e1edcb2eff4d27243c277a67e02e2636e76eefc3a85310517f9bd49e71be
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_sk.tar.gz 2358924 BLAKE2B 997311eb21b8b4ba573bca0fa2c87cbc8e018efdce0f90f67354516fa8d43b10e277b2a99db345912bcf46742a4457f2328f2fb7f60bce6cb8264b1cba3a8a27 SHA512 ef3aa25a3ab5dec0a4a6e38a9d4c5ee03ce699e2e2dabd8273d8a61c202d71023b3317141d28359493721ffb80b6eb740beb2c1e79182b3b956c75c889e140b2
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_sl.tar.gz 2763925 BLAKE2B a395f9b6e55ebcea9c6013542774fc078a7ead06a444233426300597718c2e727e4d875f557eb1c65f6f165f052c5fb99c40a734d605820688508a1d3fead491 SHA512 8fe606f4c90998c6a47abb30ec4feff0722a8acbe0edb5162cde9a6c336ec38965211bdf7a593da6cfadabbcf837ba0a36db6de28f8f0a977139ddaa94b98c40
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_sq.tar.gz 1165730 BLAKE2B 9dafddb17a4ce57e18f07668b242a54b7551f446aa8aa7f4a50bb1a1846b5c8be20fc8b2539a9a709cff292be1b08ca4c28ac2b4663615b5ffdd0aecdb5c1fe2 SHA512 932b7c6f8955c60bb9349cb38bef15666e0691d490d2e944f6347e63788f26cef8902aedf905675a8ab4d467828931b2e5566f28de06738843ff0053822e8b62
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_sr-Latn.tar.gz 2406792 BLAKE2B 50c610710746fb9eaf0cb65dcbba3ed2ddeb187fbf2eaa899d7c792e8b8a108596017cd4fdd41cb13bebdae6a50078862532fe8e4bccd7ed0e775e8079021609 SHA512 7710786b4635ec09430866cacc998a0ad4d368d203c4fd3aaac24a51b87c74f9e3fb21e38ef01499bd5343f85a38d00a5f4dd2e532f3d480768668d58f9fab82
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_sr.tar.gz 2775477 BLAKE2B 400c1b7ace6a83ea5d3588469abf47f463004632b0fe6120d8e768c910d8a5b13d9cc4381e30e6a15dfad08673abd7a65f81716427b310b943f1660efa5c02a3 SHA512 7584a4e77dd16b587dcb150f2de0ca1ec1bf7a0921e95ca698e858b967546def69a1cfbd07e33bc699a3fe6dea98e276264a866e09fcec48c1543f9ac55f9bfa
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ss.tar.gz 286855 BLAKE2B 873f5fd7e75f08b3c04ce49a62e9d35f03defe7eb38409cba9dee177ba5422f1cf9eb00454602bb281d160f3e1c410f16f59fec1280ce22dc299fae00bb44ffd SHA512 a00f67d30576956220a3fbc99ef4e0b61f373d5290ea27e7f53afcdedd3d45dcc2ac05b0f24f1cd125da9e9d4f44139ccd353e28decc182781762ddfb2a976f7
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_st.tar.gz 281174 BLAKE2B 0f30a5c19d3236e2a5833a940c38992a5bb843e99516c27aebb1d23a40b77d87c6cf774eedc738bbfe56dbf8853db70f10a4f09f5f2af33d7684598ed5366da6 SHA512 bedc61d663ce5536a9eb6b1381f3d8632b21e9db0df00feb5f9c3dfbde0324040149119f60fabd50add999b2f20ad3ee5bd8222ab880101d4b16cc4609b83341
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_sv.tar.gz 2836538 BLAKE2B e6a0c968c212b94c653138d4e73388e556feab7be5e71f0f0da07d1ad14e5a15294fa925d77b0a0fac24f4a5b711f7d7131eba359cd1e1c3bea5a6aacb79fd3e SHA512 ec890c757ccbaebf78527f26ba1ae3747a1fe6d22c2e7dcef3f892b98dc7b8e6bc0b51e6d89439316c5a1b369c37875a0bd85af97410420a53415e1545850110
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_sw-TZ.tar.gz 317817 BLAKE2B 4c87dbbde1c7338208b63836ab5f6cf04542ff6fb27b7d763011fe4394304c6c9b595a35de1cadcebd7320c3d3ac0038bd47fb96fc7261ae1b39a78cb5c71b78 SHA512 ff3711a2f34bf25c6df43a13814a849b45a33722f8d77d210ac2c8e83c732b77d239698bbbe3e174d1212c31719d5c59d2148bf931895b84f622150d52adadea
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_szl.tar.gz 733827 BLAKE2B 68f7d23a95ad7fcfe260c7ff5b27b9fb7867e3ac2a76e51475afafad0d7a0dc18d0884726c5688c641a30ecb7a4a1e5923233e3feb6cb3937eb61b32e5f77119 SHA512 869337f8941bd4b326feb7863e6bb6efb2988de78c83d28ac920f8e7ea5bcc9713bdf42212b14b236d23eaed87974f0554633015fb897a22f15f41a39df966e6
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ta.tar.gz 731905 BLAKE2B 097547cf630346e3c01c434d72e36a5f474d681965819b6297611a11d885754cfb778bb56ebc497ecc46b8fcf9861a762b5be6cbc17ffa9d8aec0335b393bab6 SHA512 ab07d4073799d455a4ed2e935aad589357842bbd3ff5b51899fff6ba7d0e594dde30628c852922bc064080fba520e8b03c4595b3edb615771a7db09fc32c8bf6
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_te.tar.gz 1077579 BLAKE2B 34fd5631821443d6ba85ba32741ba868bef89560be94619d1f3c1d720110743b070c991bd1d75181bb36194443335d40ac5d515541b16921d78cb697f9bef58d SHA512 5e790428c11abfd9170013241b4a537a3d8cc9985ac06299ed410f3b3fa7ac032612a897e14081cf26a93f2d95aa4c871dae75cf2c92218095329ff50aec6de0
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_tg.tar.gz 390323 BLAKE2B 7fea8135a13b142a79fd43cae31efce261693e8c332863a575e7fdcb2e752c6556d947ecbfa72d1e466c44c387a55ba7eca5c8cd4f7ac03f1c935fa397ebf238 SHA512 ce4447fe1d72adf6363eada4631ca5317c7f1f2ac213a43248f8c073b02d4910fa7e5efaeeb370b2f382d79e27302a48d3ad5c3559b80c5e6ce66110c4aff0d1
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_th.tar.gz 741070 BLAKE2B 43570b5b12a57b3b261aca12ca74064151312144242c8a3f85fdf13e6b6d4274a34ba6da4e9b3ed42a731aa94bf21162713ca37f1dbe80ac824c0a8590d1a028 SHA512 18ce9702e46164232510432187aeb507902a081a836778a571520e678a21407381964f6710d7aae1331b8f37c309471cfeeb074bf11f80d18cd04a2727037497
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_tn.tar.gz 260612 BLAKE2B ad8e5c72a0cd4c5b11cf9978e3ed0f6603c35d2f3e643677f43c325830257c716ee54662aae19ec589e5a60bd63dbd16985b5f312c9e9baadd0f1e7528818cfd SHA512 1c65e6422694f70e3e83526854de71095effff5ec8b396c4a70cd7341dbb027e5f6c394e6001c37f89557c3e36369c8cc94c576d8439212f927aaeecb4a0c9b3
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_tr.tar.gz 3331588 BLAKE2B d49659034744e3af6a69cd57417978a561ad2e92bc2556a05876998c72ccd53ed31ba803a48fa1c3de8f2462d525916ba07ac99a07973e1a74782f74685bd4c0 SHA512 ec691996fd81d436acd519401f839c2a73f298d5fe82dc2958193bd6998fb54407dab49d1b2173518cfbb564d1aa722bdab9662720bc9f056a4075301efebacc
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ts.tar.gz 278246 BLAKE2B 632d3f85050afcfe7de2f59482d08c2ed6874e84a7ffb7b50dbe49cd6ae44139af365eccac4a1b78c5b27a9ecb8c68387795bfc2d89071b806d02dcd20798d17 SHA512 61ad174b2134aa8632b4976700acb5dd9c1f981f26be3845d4363eada02974d943097126a9a0a43d49191b42c22c26f99fd9a0f11ea07b01114edc02b45bcd14
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_tt.tar.gz 187146 BLAKE2B d5d708e0ea073847ac28d3bea1dd9d68f147a19e3900942da183fdb3362368bf2c4ac824dd99361e07f367885bcb8377d2c9610c1b62d1279e79160d07c6ca7b SHA512 7462d4cc3cc329fefc4ace6556e6e7f99cb166df3223f9c238ec13af49fff3d22fdcedf3f1710d79560a78ab8bd975e8cabf27eb73e691ab346d1f837608ebb1
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ug.tar.gz 540373 BLAKE2B 5f4135938eac894c5fd60aedd84ba6e99af2fe2839afb897f02f3b3813c5508d7d4194af07ea85db6607fc103a1dbc3adec143420f323c6f08789b6f4c69444e SHA512 6f897f8ac312f69c31b03d409d03128f30265e055ff3e32a13a5e697b6b72e28bb0e9fd77ba926ae1dbf2d1cd21546a6b9a1cc059f4ba42fcc2cac624573deb1
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_uk.tar.gz 1910533 BLAKE2B 9ebdfe49140d793109b0045d0c54ce22d1bffb765c0eaa18af00c13b9be05a7ab172f7aaace6e3ae267c66999c4732dccbf40112151a24a0f6c88d0019560d6e SHA512 11fff247c4abc2879bda821a70e533c215f9dddfcd3f006dd24ba59f37528ee0edcc9abca8c8f082eed36576923bd094f32685bc16524cf76cdcb4e87fdeb525
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_uz.tar.gz 313782 BLAKE2B a0b9729311f227d150eeb74fde2eae8e405c257b8f8b686df8689458fffcec788912fb42586b66297ccdb851f10edba2b3f5acb56b9af45dcae5ee68a79a124e SHA512 73b5b9b88909652929230beb4005beccb6a554f745fa884f6ba25bbffbf2b37c291ed5a17946d638ecfa4d46c97d4c3b632785251afe1d578cffcfd9b9878b13
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_ve.tar.gz 283503 BLAKE2B ce110182c3bd88713b5f32c1d1fca3d253f6032ce6c692bef2ae2660ca7da9e8ea759d9d1bc61db9ac3bb51f5f2b8839813c6048a22add79d5bd8f76f58f6c18 SHA512 3bea5694ccb9630d17f6cbb3bf1c9a1813ef839982a6e8ce04e757c3654d612d60e0ea133949729575086a291a8d3fd5d648ec285f43228c796e3cd0a3f8f1ac
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_vec.tar.gz 755918 BLAKE2B 8e23a98d07f97d921990564ce87c7af0dfa148919755a8145c446daffaf6ff9903e14a9aff842683bc96533218e5faf39594d9ba6371adfca86084c2f1016eb4 SHA512 249dfdadac6586ae1e6813774b8d489334b1109fb8196bea4a2516777cf38f51b30c5c55f1c2546fecaf8e866786a6ebeed3f24e1a8b1575747c5bbf0705fbbc
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_vi.tar.gz 567255 BLAKE2B c57a7196264ddef8b8138b8559bbf38a28ec5d3b7350eae97118a381670a12d1f7603cc56806f68bf7a472cd7ec4778b0e6949fb0518a65c9c01dd8fb3b041ee SHA512 0b82d36da2236bdd8a952dc98e76defd3a0294736c95aaaf04bc68d874dc6ea411e203e2995931aeebb8a4be6c4179ed82113670f47ada31fed3c63aec7292ae
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_xh.tar.gz 290349 BLAKE2B 503a39b6a3c7882d631c2a5f03db0ab54905f9049ee6004542882215f3c6310aab4c8a2cf1a9d7da8fea08148782c441581b9fc5ff8cac8d0bdb1679e3bdf42b SHA512 c648b54f39f59d9c70627630c436002567b469d754f48a3abbb0f6417541173343b1bdcdff90b5e2d0447a6d675f6b5563b3ca00525c48ad311b033c21f95c61
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_zh-CN.tar.gz 1049341 BLAKE2B cdce93c542342e56864980e052c78e4d1bfd0b1939ea27511e66a88a821dc83318729f85258adb47943d41b3440e5561a56e57dc4268d93c6ddaaf21a4a4eae9 SHA512 80e69367d6cade76997cce796d94fd49f944e4dcbb232fd097185b64c9d15409dbb550c91af8afcba8a4488947abeb67a86da42e4cf85d773be7dd94e1dba00f
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_zh-TW.tar.gz 984558 BLAKE2B a2883925b36cda669f1737cd196a9c0457718c76ca50aaf7c847e3bb8cb3349b8a84d91169234324af80e396806a9619127abccdda72ff5f225ebff0ce6f60a5 SHA512 24f08efcb7831fb0516be389d5ddfe33a4299b2a7057714c457589c2f90dc84fd94333e0c3bc024f803ff44d97979a49b7811122d2baead5e4cfb1a9b075ffe7
+DIST LibreOffice_7.1.4.2_Linux_x86-64_rpm_langpack_zu.tar.gz 320136 BLAKE2B 71c261a3a66819c65be221001a7f4a9c1356e3980cd030f0e785e5e478ff6ddd8ba277c1d9dd55f37331f439f7971b83aedb7f5738e73503d84b25483bd5b567 SHA512 3966db55370f59f2f4f1fdd1981b7102ef7852b461fcb84484c8d319733261138f4004d38c84f4584cef60e1248e8ae19d474b2e1a664fec08bab7c30ec4257a
+EBUILD libreoffice-l10n-7.0.6.2.ebuild 3686 BLAKE2B 92110978a07882d8a24f9ea24f30c0fb5109bda02508e5b8f93f3f2d440177519da9e28b392b7beaad2498dffb32982974317ba8bd8c68527b25e1ad9de93866 SHA512 a28a7b8109c8d863daba8f9cb3d7662fab4ef06b428cae0bb0567c6e13e8fdf7c76380f5b96aeb9d069593abf984c357f60fdf4ab65b8c17b51b5c305aee7a68
+EBUILD libreoffice-l10n-7.1.3.2.ebuild 3686 BLAKE2B 92110978a07882d8a24f9ea24f30c0fb5109bda02508e5b8f93f3f2d440177519da9e28b392b7beaad2498dffb32982974317ba8bd8c68527b25e1ad9de93866 SHA512 a28a7b8109c8d863daba8f9cb3d7662fab4ef06b428cae0bb0567c6e13e8fdf7c76380f5b96aeb9d069593abf984c357f60fdf4ab65b8c17b51b5c305aee7a68
+EBUILD libreoffice-l10n-7.1.4.2.ebuild 3688 BLAKE2B ecd55ba287977b5d1a1e5b7f5b5f4337834da81bb08a4f7b490fdf5fe77d5810276234daaae0b7b52350d308fa71efc6b915af114c9c59d1b090aaf3d1187928 SHA512 84a8c639fdc7dde3cf1440c6f56188919ef34aa4cb7e549d9826ec52c5e0553b24cc9590b7a6d16534b2fd0cd72cdfe2fc1ee4d5390573439754b3062632a83d
+MISC metadata.xml 369 BLAKE2B 7629064f409fe8ba7f0daa435ff56eaf0870f70b45961c635119725e9a78ca40bbdf77a39e70f83a31103944f579b13db5fb07f8dc9e7ecb77491d36220370e9 SHA512 8cc7592062150a5472a5b8cf4106d0c3fd7270c7e6d0d566852bbc6670a90be2c73e6c04f085e32b41f40dd1adf9800a53a1af8df5cb297c20394c55e3df45c6
diff --git a/app-office/libreoffice-l10n/files/lo_gen_langs.sh b/app-office/libreoffice-l10n/files/lo_gen_langs.sh
new file mode 100644 (file)
index 0000000..57f71ce
--- /dev/null
@@ -0,0 +1,65 @@
+#!/bin/bash
+# Licensed under the GNU General Public License, v2
+
+#
+# Author: Ralph Sennhauser
+#
+# Find l10n packs for libreoffice and format it for use in ebuilds.
+#
+
+VERSION=${1:-4.1.5}
+BASE_SRC_URI="http://download.documentfoundation.org/libreoffice/stable/${VERSION}/rpm/x86_64"
+
+# needs lxml
+print_available_tarballs() {
+       python << EOL
+import sys, urllib.request
+from xml.dom.minidom import parseString
+from bs4 import BeautifulSoup
+
+with urllib.request.urlopen("${BASE_SRC_URI}") as url:
+       html = url.read()
+
+# broken html, try to sanitize
+html = BeautifulSoup(html).prettify()
+
+dom = parseString(html)
+for elem in dom.getElementsByTagName('a'):
+       attr = elem.getAttribute("href")
+       if attr.endswith('tar.gz'): 
+               if "install" in attr: continue
+               print(attr)
+EOL
+}
+
+tarballs=( $(print_available_tarballs) )
+help_packs=()
+lang_packs=()
+lang_packs_reduced=()
+
+for tb in "${tarballs[@]}"; do
+       pack=${tb%.tar.gz}
+       pack=${pack##*rpm_}
+       pack=${pack/en-US/en}
+       pack=${pack/-/_}
+       pack=${pack/en-US/en}
+       if [[ ${tb} =~ helppack ]]; then
+               pack=${pack/helppack_/}
+               help_packs+=( ${pack} )
+       elif [[ ${tb} =~ langpack ]]; then
+               pack=${pack/langpack_/}
+               lang_packs+=( ${pack} )
+       fi
+done
+
+for lpack in "${lang_packs[@]}"; do
+       for hpack in "${help_packs[@]}"; do
+               if [[ ${hpack} == ${lpack} ]]; then
+                       continue 2
+               fi
+       done
+       lang_packs_reduced+=( ${lpack} )
+done
+
+echo "LANGUAGES_HELP=\" ${help_packs[@]} \""
+echo "LANGUAGES=\"\${LANGUAGES_HELP}${lang_packs_reduced[@]} \""
diff --git a/app-office/libreoffice-l10n/libreoffice-l10n-7.0.6.2.ebuild b/app-office/libreoffice-l10n/libreoffice-l10n-7.0.6.2.ebuild
new file mode 100644 (file)
index 0000000..e929e7e
--- /dev/null
@@ -0,0 +1,91 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit rpm
+
+BASE_PV=$(ver_cut 1-3)
+MY_PV="${PV/_alpha/.alpha}"
+MY_PV="${MY_PV/_beta/.beta}"
+[[ ${PV} == *alpha* || ${PV} == *beta* ]] && PN_DEV="Dev"
+
+DESCRIPTION="Translations for the Libreoffice suite"
+HOMEPAGE="https://www.libreoffice.org"
+BASE_SRC_URI_TESTING="https://download.documentfoundation.org/${PN/-l10n/}/testing/${BASE_PV}/rpm"
+BASE_SRC_URI_STABLE="https://download.documentfoundation.org/${PN/-l10n/}/stable/${BASE_PV}/rpm"
+
+LICENSE="|| ( LGPL-3 MPL-1.1 )"
+SLOT="0"
+KEYWORDS="amd64 ~arm ~arm64 ~ppc64 x86 ~amd64-linux"
+IUSE="offlinehelp"
+
+#
+# when changing the language lists, please be careful to preserve the spaces (bug 491728)
+#
+# "en:en-US" for mapping from Gentoo "en" to upstream "en-US" etc.
+LANGUAGES_HELP=" am ar ast bg bn-IN bn bo bs ca-valencia ca cs da de dz el en-GB en:en-US en-ZA eo es et eu fi fr gl gu he hi hr hu id is it ja ka km ko lo lt lv mk nb ne nl nn om pl pt-BR pt ro ru si sid sk sl sq sv ta tg tr ug uk vi zh-CN zh-TW "
+LANGUAGES="${LANGUAGES_HELP}af as be br brx ckb cy dgo dsb fa fur fy ga gd gug hsb kab kk kmr-Latn kn kok ks lb mai ml mn mni mr my nr nso oc or pa:pa-IN rw sa:sa-IN sat sd sr-Latn sr ss st sw-TZ szl te th tn ts tt uz ve vec xh zu "
+
+for lang in ${LANGUAGES_HELP}; do
+       helppack="offlinehelp? ( ${BASE_SRC_URI_STABLE}/x86_64/LibreOffice${PN_DEV}_${BASE_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz ${BASE_SRC_URI_TESTING}/x86_64/LibreOffice${PN_DEV}_${MY_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz )"
+       SRC_URI+=" l10n_${lang%:*}? ( ${helppack} )"
+done
+for lang in ${LANGUAGES}; do
+       if [[ ${lang%:*} != en ]]; then
+               langpack="${BASE_SRC_URI_STABLE}/x86_64/LibreOffice${PN_DEV}_${BASE_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz ${BASE_SRC_URI_TESTING}/x86_64/LibreOffice${PN_DEV}_${MY_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz"
+               SRC_URI+=" l10n_${lang%:*}? ( ${langpack} )"
+       fi
+       IUSE+=" l10n_${lang%:*}"
+done
+unset lang helppack langpack
+
+RDEPEND+="app-text/hunspell"
+
+RESTRICT="strip"
+
+S="${WORKDIR}"
+
+src_prepare() {
+       default
+
+       local lang dir rpmdir
+
+       # First remove dictionaries, we want to use system ones.
+       find "${S}" -name *dict*.rpm -delete || die "Failed to remove dictionaries"
+
+       for lang in ${LANGUAGES}; do
+               # break away if not enabled
+               use l10n_${lang%:*} || continue
+
+               dir=${lang#*:}
+
+               # for english we provide just helppack, as translation is always there
+               if [[ ${lang%:*} != en ]]; then
+                       rpmdir="LibreOffice_${MY_PV}_Linux_x86-64_rpm_langpack_${dir}/RPMS/"
+                       [[ -d ${rpmdir} ]] || die "Missing directory: ${rpmdir}"
+                       rpm_unpack ./${rpmdir}/*.rpm
+               fi
+               if [[ "${LANGUAGES_HELP}" =~ " ${lang} " ]] && use offlinehelp; then
+                       rpmdir="LibreOffice_${MY_PV}_Linux_x86-64_rpm_helppack_${dir}/RPMS/"
+                       [[ -d ${rpmdir} ]] || die "Missing directory: ${rpmdir}"
+                       rpm_unpack ./${rpmdir}/*.rpm
+               fi
+       done
+}
+
+src_configure() { :; }
+src_compile() { :; }
+
+src_install() {
+       local dir="${S}"/opt/${PN/-l10n/}$(ver_cut 1-2)/
+       # Condition required for people who do not install anything e.g. no l10n
+       # or just english with no offlinehelp.
+       if [[ -d "${dir}" ]] ; then
+               insinto /usr/$(get_libdir)/${PN/-l10n/}/
+               doins -r "${dir}"/*
+       fi
+       # remove extensions that are in l10n for some weird reason
+       rm -rf "${ED}"/usr/$(get_libdir)/${PN/-l10n/}/share/extensions/ || \
+               die "Failed to remove extensions"
+}
diff --git a/app-office/libreoffice-l10n/libreoffice-l10n-7.1.3.2.ebuild b/app-office/libreoffice-l10n/libreoffice-l10n-7.1.3.2.ebuild
new file mode 100644 (file)
index 0000000..e929e7e
--- /dev/null
@@ -0,0 +1,91 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit rpm
+
+BASE_PV=$(ver_cut 1-3)
+MY_PV="${PV/_alpha/.alpha}"
+MY_PV="${MY_PV/_beta/.beta}"
+[[ ${PV} == *alpha* || ${PV} == *beta* ]] && PN_DEV="Dev"
+
+DESCRIPTION="Translations for the Libreoffice suite"
+HOMEPAGE="https://www.libreoffice.org"
+BASE_SRC_URI_TESTING="https://download.documentfoundation.org/${PN/-l10n/}/testing/${BASE_PV}/rpm"
+BASE_SRC_URI_STABLE="https://download.documentfoundation.org/${PN/-l10n/}/stable/${BASE_PV}/rpm"
+
+LICENSE="|| ( LGPL-3 MPL-1.1 )"
+SLOT="0"
+KEYWORDS="amd64 ~arm ~arm64 ~ppc64 x86 ~amd64-linux"
+IUSE="offlinehelp"
+
+#
+# when changing the language lists, please be careful to preserve the spaces (bug 491728)
+#
+# "en:en-US" for mapping from Gentoo "en" to upstream "en-US" etc.
+LANGUAGES_HELP=" am ar ast bg bn-IN bn bo bs ca-valencia ca cs da de dz el en-GB en:en-US en-ZA eo es et eu fi fr gl gu he hi hr hu id is it ja ka km ko lo lt lv mk nb ne nl nn om pl pt-BR pt ro ru si sid sk sl sq sv ta tg tr ug uk vi zh-CN zh-TW "
+LANGUAGES="${LANGUAGES_HELP}af as be br brx ckb cy dgo dsb fa fur fy ga gd gug hsb kab kk kmr-Latn kn kok ks lb mai ml mn mni mr my nr nso oc or pa:pa-IN rw sa:sa-IN sat sd sr-Latn sr ss st sw-TZ szl te th tn ts tt uz ve vec xh zu "
+
+for lang in ${LANGUAGES_HELP}; do
+       helppack="offlinehelp? ( ${BASE_SRC_URI_STABLE}/x86_64/LibreOffice${PN_DEV}_${BASE_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz ${BASE_SRC_URI_TESTING}/x86_64/LibreOffice${PN_DEV}_${MY_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz )"
+       SRC_URI+=" l10n_${lang%:*}? ( ${helppack} )"
+done
+for lang in ${LANGUAGES}; do
+       if [[ ${lang%:*} != en ]]; then
+               langpack="${BASE_SRC_URI_STABLE}/x86_64/LibreOffice${PN_DEV}_${BASE_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz ${BASE_SRC_URI_TESTING}/x86_64/LibreOffice${PN_DEV}_${MY_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz"
+               SRC_URI+=" l10n_${lang%:*}? ( ${langpack} )"
+       fi
+       IUSE+=" l10n_${lang%:*}"
+done
+unset lang helppack langpack
+
+RDEPEND+="app-text/hunspell"
+
+RESTRICT="strip"
+
+S="${WORKDIR}"
+
+src_prepare() {
+       default
+
+       local lang dir rpmdir
+
+       # First remove dictionaries, we want to use system ones.
+       find "${S}" -name *dict*.rpm -delete || die "Failed to remove dictionaries"
+
+       for lang in ${LANGUAGES}; do
+               # break away if not enabled
+               use l10n_${lang%:*} || continue
+
+               dir=${lang#*:}
+
+               # for english we provide just helppack, as translation is always there
+               if [[ ${lang%:*} != en ]]; then
+                       rpmdir="LibreOffice_${MY_PV}_Linux_x86-64_rpm_langpack_${dir}/RPMS/"
+                       [[ -d ${rpmdir} ]] || die "Missing directory: ${rpmdir}"
+                       rpm_unpack ./${rpmdir}/*.rpm
+               fi
+               if [[ "${LANGUAGES_HELP}" =~ " ${lang} " ]] && use offlinehelp; then
+                       rpmdir="LibreOffice_${MY_PV}_Linux_x86-64_rpm_helppack_${dir}/RPMS/"
+                       [[ -d ${rpmdir} ]] || die "Missing directory: ${rpmdir}"
+                       rpm_unpack ./${rpmdir}/*.rpm
+               fi
+       done
+}
+
+src_configure() { :; }
+src_compile() { :; }
+
+src_install() {
+       local dir="${S}"/opt/${PN/-l10n/}$(ver_cut 1-2)/
+       # Condition required for people who do not install anything e.g. no l10n
+       # or just english with no offlinehelp.
+       if [[ -d "${dir}" ]] ; then
+               insinto /usr/$(get_libdir)/${PN/-l10n/}/
+               doins -r "${dir}"/*
+       fi
+       # remove extensions that are in l10n for some weird reason
+       rm -rf "${ED}"/usr/$(get_libdir)/${PN/-l10n/}/share/extensions/ || \
+               die "Failed to remove extensions"
+}
diff --git a/app-office/libreoffice-l10n/libreoffice-l10n-7.1.4.2.ebuild b/app-office/libreoffice-l10n/libreoffice-l10n-7.1.4.2.ebuild
new file mode 100644 (file)
index 0000000..5356be4
--- /dev/null
@@ -0,0 +1,91 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit rpm
+
+BASE_PV=$(ver_cut 1-3)
+MY_PV="${PV/_alpha/.alpha}"
+MY_PV="${MY_PV/_beta/.beta}"
+[[ ${PV} == *alpha* || ${PV} == *beta* ]] && PN_DEV="Dev"
+
+DESCRIPTION="Translations for the Libreoffice suite"
+HOMEPAGE="https://www.libreoffice.org"
+BASE_SRC_URI_TESTING="https://download.documentfoundation.org/${PN/-l10n/}/testing/${BASE_PV}/rpm"
+BASE_SRC_URI_STABLE="https://download.documentfoundation.org/${PN/-l10n/}/stable/${BASE_PV}/rpm"
+
+LICENSE="|| ( LGPL-3 MPL-1.1 )"
+SLOT="0"
+KEYWORDS="~amd64 ~arm ~arm64 ~ppc64 ~x86 ~amd64-linux"
+IUSE="offlinehelp"
+
+#
+# when changing the language lists, please be careful to preserve the spaces (bug 491728)
+#
+# "en:en-US" for mapping from Gentoo "en" to upstream "en-US" etc.
+LANGUAGES_HELP=" am ar ast bg bn-IN bn bo bs ca-valencia ca cs da de dz el en-GB en:en-US en-ZA eo es et eu fi fr gl gu he hi hr hu id is it ja ka km ko lo lt lv mk nb ne nl nn om pl pt-BR pt ro ru si sid sk sl sq sv ta tg tr ug uk vi zh-CN zh-TW "
+LANGUAGES="${LANGUAGES_HELP}af as be br brx ckb cy dgo dsb fa fur fy ga gd gug hsb kab kk kmr-Latn kn kok ks lb mai ml mn mni mr my nr nso oc or pa:pa-IN rw sa:sa-IN sat sd sr-Latn sr ss st sw-TZ szl te th tn ts tt uz ve vec xh zu "
+
+for lang in ${LANGUAGES_HELP}; do
+       helppack="offlinehelp? ( ${BASE_SRC_URI_STABLE}/x86_64/LibreOffice${PN_DEV}_${BASE_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz ${BASE_SRC_URI_TESTING}/x86_64/LibreOffice${PN_DEV}_${MY_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_helppack_${lang#*:}.tar.gz )"
+       SRC_URI+=" l10n_${lang%:*}? ( ${helppack} )"
+done
+for lang in ${LANGUAGES}; do
+       if [[ ${lang%:*} != en ]]; then
+               langpack="${BASE_SRC_URI_STABLE}/x86_64/LibreOffice${PN_DEV}_${BASE_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz ${BASE_SRC_URI_TESTING}/x86_64/LibreOffice${PN_DEV}_${MY_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz -> LibreOffice_${MY_PV}_Linux_x86-64_rpm_langpack_${lang#*:}.tar.gz"
+               SRC_URI+=" l10n_${lang%:*}? ( ${langpack} )"
+       fi
+       IUSE+=" l10n_${lang%:*}"
+done
+unset lang helppack langpack
+
+RDEPEND+="app-text/hunspell"
+
+RESTRICT="strip"
+
+S="${WORKDIR}"
+
+src_prepare() {
+       default
+
+       local lang dir rpmdir
+
+       # First remove dictionaries, we want to use system ones.
+       find "${S}" -name *dict*.rpm -delete || die "Failed to remove dictionaries"
+
+       for lang in ${LANGUAGES}; do
+               # break away if not enabled
+               use l10n_${lang%:*} || continue
+
+               dir=${lang#*:}
+
+               # for english we provide just helppack, as translation is always there
+               if [[ ${lang%:*} != en ]]; then
+                       rpmdir="LibreOffice_${MY_PV}_Linux_x86-64_rpm_langpack_${dir}/RPMS/"
+                       [[ -d ${rpmdir} ]] || die "Missing directory: ${rpmdir}"
+                       rpm_unpack ./${rpmdir}/*.rpm
+               fi
+               if [[ "${LANGUAGES_HELP}" =~ " ${lang} " ]] && use offlinehelp; then
+                       rpmdir="LibreOffice_${MY_PV}_Linux_x86-64_rpm_helppack_${dir}/RPMS/"
+                       [[ -d ${rpmdir} ]] || die "Missing directory: ${rpmdir}"
+                       rpm_unpack ./${rpmdir}/*.rpm
+               fi
+       done
+}
+
+src_configure() { :; }
+src_compile() { :; }
+
+src_install() {
+       local dir="${S}"/opt/${PN/-l10n/}$(ver_cut 1-2)/
+       # Condition required for people who do not install anything e.g. no l10n
+       # or just english with no offlinehelp.
+       if [[ -d "${dir}" ]] ; then
+               insinto /usr/$(get_libdir)/${PN/-l10n/}/
+               doins -r "${dir}"/*
+       fi
+       # remove extensions that are in l10n for some weird reason
+       rm -rf "${ED}"/usr/$(get_libdir)/${PN/-l10n/}/share/extensions/ || \
+               die "Failed to remove extensions"
+}
diff --git a/app-office/libreoffice-l10n/metadata.xml b/app-office/libreoffice-l10n/metadata.xml
new file mode 100644 (file)
index 0000000..4dee5db
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+       <maintainer type="project">
+               <email>office@gentoo.org</email>
+               <name>Gentoo Office project</name>
+       </maintainer>
+       <use>
+               <flag name="offlinehelp">Install help files locally instead of using the LibreOffice Wiki</flag>
+       </use>
+</pkgmetadata>
diff --git a/dev-libs/boost/Manifest b/dev-libs/boost/Manifest
new file mode 100644 (file)
index 0000000..be2cec0
--- /dev/null
@@ -0,0 +1,10 @@
+AUX boost-1.71.0-build-auto_index-tool.patch 265 BLAKE2B 05e52ca716522db7bb11b481576a08138be826f7383a689a6c0725d491a244dc8697fc39fac1a79e4639ba51b3a3eb7ee2f2e11a20883de0ecd3dd3c2fc2c9cd SHA512 28952e7cd791678be0963beb0a29e3e40b54a8c3618c66a8b8d21ab63c414771cfa1e9961f08c0b3818bd4c311c122e777109e15002a71230b0c3c9dbc4d6075
+AUX boost-1.71.0-context-x32.patch 1116 BLAKE2B 16b6ddbdc47d72d5afd39e61441f9f094dff8db46bd7fa4e04e5a8b132c8894c51db506d20356c352022f42d5b9a9923f23c5db2b0f9fa1c64ceeb4e50e16be1 SHA512 cf76691d4adbc4b43f468c587fea23c43e1b337ba7eebff2c856b0403bf32b78826f483faca25a4459c1d47eabbd5b67c65863a4d44407990178022433f718bf
+AUX boost-1.71.0-disable_icu_rpath.patch 1077 BLAKE2B c4549b7a706cd934392bdafb44ee89987534d5cca48060b955a4b998f0ac6c8a96b5c0d6f5d46476a0225ba6e66fabc095ec12c0f0c43a60c7147ef922e8a2ae SHA512 7095d94def1ee04f009f0c2e84d0450705211793f6d18ac4a3e0fb673a36127282f31172a7f571ed89f4128b6ffbc38d850e6105a5ad5224d42749557db41ee0
+AUX boost-1.73-boost-mpi-python-PEP-328.patch 396 BLAKE2B 5f08ce2eab46f2d108166afef086382dc9cd9a5305435cf437fa3ae505736979664357aa23cc51b2a74bee6aae46d94a671056037578562846e900fd2c7e65e8 SHA512 fa55d1da17bd110db2c9a16dce4da267a62ef10c13a6dc3aa6afd3b33e9a18499266b4411d292533b1c691e3bf0309fa1aab8ec19e7775a7835d89275183e6f2
+AUX boost-1.73-property-tree-include.patch 1832 BLAKE2B 7488cf768209bde32af608f366ad0d9a392bb36e6b9e4c7ac13a262eedea668fb58667f41cd089c91f43fee4a6a68e442c2e627ffa2341c44274b4f4f7f644db SHA512 a18fa18388b74371aa3d3826621df90e8c8f6d2c6b9cf25bc9f7761e98817cc9252ccd43fa5a374136f257e9a0c1f927eb9912d0715bb1de94b3e92af957d84a
+AUX boost-1.74-CVE-2012-2677.patch 4965 BLAKE2B 74cef075cd0aa4d4425e75d437a59c19e20325cc33c9c8fb206bdcf87efbafa6d28c6ebcd8b70f88f12e32b68b492ac6b985ccef703c61439661a194983b9ad9 SHA512 c8e6758840b58358b676226ef9f498b9e72cbeedee83cd6c8ea0608a6bc1466bedeba5b7a92d1a608c3a2788cb3c0444203e70995e3b3123198bf68081b477b9
+AUX boost-1.76-boost-numpy.patch 910 BLAKE2B 6f0b8fdf908e7be43556ba61301d0465f0b8464120d342b6ddbd053eecc432bf2c4a60e84eced622bd3fe0da468c5941fa2d5b9592490c453193ef3eaf239a8a SHA512 245cb97c493e85eae3567a720eebac7eb53d1691d22015edc27f7a56e379c9f59f5a89c49889149ec203c28ede2ed1b9853c742e604fa4b60f7a83f8b2698fba
+AUX boost-1.76-sparc-define.patch 1026 BLAKE2B ad88b1c5231c0cbbd6bfb1f01d050ff20fbee145a656a439b2920f23f116693e6a999dce9db6bb0cac94ad2f98580f0669198d026b28c05fe7a82b5887fbadff SHA512 62d63bc3db7352daf6ad47a25bbeef2bed3405e4e43650d4c34ad8535a96ae13f875837b727082c8a5b7671c35a67a20978baf44d59f15a57053308a31827373
+DIST boost_1_76_0.tar.bz2 110073117 BLAKE2B 45445e6a9725cb99131e0b831b2fac0840d083692c13887b41adeac5cb8b3732026db3641d6be20591a676b78a87fcf363eb9b1508f87ed26039bba6a1ced533 SHA512 5d68bed98c57e03b4cb2420d9b856e5f0669561a6142a4b0c9c8a58dc5b6b28e16ccbb16ac559c3a3198c45769a246bf996b96cb7b6a019dd15f05c2270e9429
+EBUILD boost-1.76.0-r1.ebuild 10967 BLAKE2B 3ef87a872fad7945d82e1392013ea4bb2ab7526d816034df3e5b9e2f44412cdc4ebc5a6e7376631876b3f876ecc9593651d5407cabf703720e953b7ae05e883b SHA512 0fe6a80c702416eb1be54199e2c479478d57813f2114e1b5f90f6377081b872e25aff166872c7a009be328072dc97e89118d605d8318843e056fc19505c56a0c
diff --git a/dev-libs/boost/files/boost-1.71.0-build-auto_index-tool.patch b/dev-libs/boost/files/boost-1.71.0-build-auto_index-tool.patch
new file mode 100644 (file)
index 0000000..ca793b9
--- /dev/null
@@ -0,0 +1,13 @@
+Build auto_index tool with USE="tools"
+See also: https://bugs.gentoo.org/529066
+
+--- a/tools/Jamfile.v2
++++ b/tools/Jamfile.v2
+@@ -18,6 +18,7 @@
+     ;
+ TOOLS =
++    auto_index/build//auto_index
+     bcp//bcp
+     inspect/build//inspect
+     quickbook//quickbook
diff --git a/dev-libs/boost/files/boost-1.71.0-context-x32.patch b/dev-libs/boost/files/boost-1.71.0-context-x32.patch
new file mode 100644 (file)
index 0000000..9ee3d54
--- /dev/null
@@ -0,0 +1,38 @@
+--- a/libs/context/src/asm/jump_i386_sysv_elf_gas.S
++++ b/libs/context/src/asm/jump_i386_sysv_elf_gas.S
+@@ -24,6 +24,10 @@
+  *                                                                                      *
+  ****************************************************************************************/
++#ifdef __x86_64__
++#include "jump_x86_64_sysv_elf_gas.S"
++#else
++
+ .file "jump_i386_sysv_elf_gas.S"
+ .text
+ .globl jump_fcontext
+@@ -81,3 +85,5 @@
+ /* Mark that we don't need executable stack.  */
+ .section .note.GNU-stack,"",%progbits
++
++#endif
+--- a/libs/context/src/asm/make_i386_sysv_elf_gas.S
++++ b/libs/context/src/asm/make_i386_sysv_elf_gas.S
+@@ -24,6 +24,10 @@
+  *                                                                                      *
+  ****************************************************************************************/
++#ifdef __x86_64__
++#include "make_x86_64_sysv_elf_gas.S"
++#else
++
+ .file "make_i386_sysv_elf_gas.S"
+ .text
+ .globl make_fcontext
+@@ -105,3 +109,5 @@
+ /* Mark that we don't need executable stack.  */
+ .section .note.GNU-stack,"",%progbits
++
++#endif
diff --git a/dev-libs/boost/files/boost-1.71.0-disable_icu_rpath.patch b/dev-libs/boost/files/boost-1.71.0-disable_icu_rpath.patch
new file mode 100644 (file)
index 0000000..32faf8d
--- /dev/null
@@ -0,0 +1,29 @@
+--- a/libs/locale/build/Jamfile.v2
++++ b/libs/locale/build/Jamfile.v2
+@@ -65,8 +65,8 @@
+ if $(ICU_LINK)
+ {
+-    ICU_OPTS = <include>$(ICU_PATH)/include <linkflags>$(ICU_LINK) <dll-path>$(ICU_PATH)/bin <runtime-link>shared ;
+-    ICU64_OPTS = <include>$(ICU_PATH)/include <linkflags>$(ICU_LINK) <dll-path>$(ICU_PATH)/bin64 <runtime-link>shared ;
++    ICU_OPTS = <include>$(ICU_PATH)/include <linkflags>$(ICU_LINK) <runtime-link>shared ;
++    ICU64_OPTS = <include>$(ICU_PATH)/include <linkflags>$(ICU_LINK) <runtime-link>shared ;
+ }
+ else
+ {
+@@ -124,7 +124,6 @@
+       <library>icuuc/<link>shared/<runtime-link>shared 
+       <library>icudt/<link>shared/<runtime-link>shared 
+       <library>icuin/<link>shared/<runtime-link>shared
+-      <dll-path>$(ICU_PATH)/bin
+         <runtime-link>shared ;
+@@ -183,7 +182,6 @@
+       <library>icuuc_64/<link>shared/<runtime-link>shared 
+       <library>icudt_64/<link>shared/<runtime-link>shared 
+       <library>icuin_64/<link>shared/<runtime-link>shared
+-      <dll-path>$(ICU_PATH)/bin64
+         <runtime-link>shared ;
+  
+     
diff --git a/dev-libs/boost/files/boost-1.73-boost-mpi-python-PEP-328.patch b/dev-libs/boost/files/boost-1.73-boost-mpi-python-PEP-328.patch
new file mode 100644 (file)
index 0000000..444db2b
--- /dev/null
@@ -0,0 +1,17 @@
+--- a/libs/mpi/build/__init__.py
++++ b/libs/mpi/build/__init__.py
+@@ -1,10 +1,12 @@
++from __future__ import absolute_import
++
+ import sys
+ if sys.platform == 'linux2':
+     import DLFCN as dl
+     flags = sys.getdlopenflags()
+     sys.setdlopenflags(dl.RTLD_NOW|dl.RTLD_GLOBAL)
+-    import mpi
++    from . import mpi
+     sys.setdlopenflags(flags)
+ else:
+-    import mpi
++    from . import mpi
diff --git a/dev-libs/boost/files/boost-1.73-property-tree-include.patch b/dev-libs/boost/files/boost-1.73-property-tree-include.patch
new file mode 100644 (file)
index 0000000..5393882
--- /dev/null
@@ -0,0 +1,45 @@
+From d1c8825a45a0717e1ad79583d3283b0e5e32831e Mon Sep 17 00:00:00 2001
+From: Andrey Semashev <Lastique@users.noreply.github.com>
+Date: Tue, 28 Apr 2020 22:03:04 +0300
+Subject: [PATCH] Fix usage of deprecated Boost.Bind features
+
+This fixes deprecation warnings generated by boost/bind.hpp.
+
+Also, use a more actual include path for ref.hpp.
+---
+ boost/property_tree/json_parser/detail/parser.hpp | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/boost/property_tree/json_parser/detail/parser.hpp b/boost/property_tree/json_parser/detail/parser.hpp
+index 5554990fb..6cf636394 100644
+--- a/boost/property_tree/json_parser/detail/parser.hpp
++++ b/boost/property_tree/json_parser/detail/parser.hpp
+@@ -3,8 +3,8 @@
+ #include <boost/property_tree/json_parser/error.hpp>
+-#include <boost/ref.hpp>
+-#include <boost/bind.hpp>
++#include <boost/core/ref.hpp>
++#include <boost/bind/bind.hpp>
+ #include <boost/format.hpp>
+ #include <iterator>
+@@ -214,7 +214,7 @@ namespace boost { namespace property_tree {
+         void process_codepoint(Sentinel end, EncodingErrorFn error_fn) {
+             encoding.transcode_codepoint(cur, end,
+                 boost::bind(&Callbacks::on_code_unit,
+-                            boost::ref(callbacks), _1),
++                            boost::ref(callbacks), boost::placeholders::_1),
+                 error_fn);
+         }
+@@ -517,7 +517,7 @@ namespace boost { namespace property_tree {
+         void feed(unsigned codepoint) {
+             encoding.feed_codepoint(codepoint,
+                                     boost::bind(&Callbacks::on_code_unit,
+-                                                boost::ref(callbacks), _1));
++                                                boost::ref(callbacks), boost::placeholders::_1));
+         }
+         Callbacks& callbacks;
diff --git a/dev-libs/boost/files/boost-1.74-CVE-2012-2677.patch b/dev-libs/boost/files/boost-1.74-CVE-2012-2677.patch
new file mode 100644 (file)
index 0000000..ff947f7
--- /dev/null
@@ -0,0 +1,125 @@
+https://src.fedoraproject.org/rpms/boost/raw/master/f/boost-1.58.0-pool.patch
+https://bugzilla.redhat.com/show_bug.cgi?id=828856
+https://bugs.gentoo.org/620468
+https://svn.boost.org/trac10/ticket/6701
+
+Index: boost/pool/pool.hpp
+===================================================================
+--- a/boost/pool/pool.hpp      (revision 78317)
++++ b/boost/pool/pool.hpp      (revision 78326)
+@@ -27,4 +27,6 @@
+ #include <boost/pool/poolfwd.hpp>
++// std::numeric_limits
++#include <boost/limits.hpp>
+ // boost::integer::static_lcm
+ #include <boost/integer/common_factor_ct.hpp>
+@@ -358,4 +360,11 @@
+     }
++    size_type max_chunks() const
++    { //! Calculated maximum number of memory chunks that can be allocated in a single call by this Pool.
++      size_type partition_size = alloc_size();
++      size_type POD_size = integer::static_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type);
++      return (std::numeric_limits<size_type>::max() - POD_size) / alloc_size();
++    }
++
+     static void * & nextof(void * const ptr)
+     { //! \returns Pointer dereferenced.
+@@ -377,5 +388,7 @@
+       //!   the first time that object needs to allocate system memory.
+       //!   The default is 32. This parameter may not be 0.
+-      //! \param nmax_size is the maximum number of chunks to allocate in one block.
++      //! \param nmax_size is the maximum number of chunks to allocate in one block.                  
++      set_next_size(nnext_size);
++      set_max_size(nmax_size);
+     }
+@@ -400,7 +413,7 @@
+     }
+     void set_next_size(const size_type nnext_size)
+-    { //! Set number of chunks to request from the system the next time that object needs to allocate system memory. This value should never be set to 0.
+-      //! \returns nnext_size.
+-      next_size = start_size = nnext_size;
++    { //! Set number of chunks to request from the system the next time that object needs to allocate system memory. This value should never be set to 0.     
++      BOOST_USING_STD_MIN();
++      next_size = start_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(nnext_size, max_chunks());
+     }
+     size_type get_max_size() const
+@@ -410,5 +423,6 @@
+     void set_max_size(const size_type nmax_size)
+     { //! Set max_size.
+-      max_size = nmax_size;
++      BOOST_USING_STD_MIN();
++      max_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(nmax_size, max_chunks());
+     }
+     size_type get_requested_size() const
+@@ -713,7 +727,7 @@
+   BOOST_USING_STD_MIN();
+   if(!max_size)
+-    next_size <<= 1;
++    set_next_size(next_size << 1);
+   else if( next_size*partition_size/requested_size < max_size)
+-    next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size);
++    set_next_size(min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size * requested_size / partition_size));
+   //  initialize it,
+@@ -753,7 +767,7 @@
+   BOOST_USING_STD_MIN();
+   if(!max_size)
+-    next_size <<= 1;
++    set_next_size(next_size << 1);
+   else if( next_size*partition_size/requested_size < max_size)
+-    next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size);
++    set_next_size(min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size * requested_size / partition_size));
+   //  initialize it,
+@@ -797,4 +811,6 @@
+   //! \returns Address of chunk n if allocated ok.
+   //! \returns 0 if not enough memory for n chunks.
++  if (n > max_chunks())
++    return 0;
+   const size_type partition_size = alloc_size();
+@@ -845,7 +861,7 @@
+   BOOST_USING_STD_MIN();
+   if(!max_size)
+-    next_size <<= 1;
++    set_next_size(next_size << 1);
+   else if( next_size*partition_size/requested_size < max_size)
+-    next_size = min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size*requested_size/ partition_size);
++    set_next_size(min BOOST_PREVENT_MACRO_SUBSTITUTION(next_size << 1, max_size * requested_size / partition_size));
+   //  insert it into the list,
+Index: libs/pool/test/test_bug_6701.cpp
+===================================================================
+--- a/libs/pool/test/test_bug_6701.cpp (revision 78326)
++++ b/libs/pool/test/test_bug_6701.cpp (revision 78326)
+@@ -0,0 +1,27 @@
++/* Copyright (C) 2012 Étienne Dupuis
++* 
++* Use, modification and distribution is subject to the 
++* Boost Software License, Version 1.0. (See accompanying
++* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
++*/
++
++// Test of bug #6701 (https://svn.boost.org/trac/boost/ticket/6701)
++
++#include <boost/pool/object_pool.hpp>
++#include <boost/limits.hpp>
++
++int main()
++{
++  boost::pool<> p(1024, std::numeric_limits<size_t>::max() / 768);
++
++  void *x = p.malloc();
++  BOOST_ASSERT(!x);
++  
++  BOOST_ASSERT(std::numeric_limits<size_t>::max() / 1024 >= p.get_next_size());
++  BOOST_ASSERT(std::numeric_limits<size_t>::max() / 1024 >= p.get_max_size());
++
++  void *y = p.ordered_malloc(std::numeric_limits<size_t>::max() / 768);
++  BOOST_ASSERT(!y);
++
++  return 0;
++}
diff --git a/dev-libs/boost/files/boost-1.76-boost-numpy.patch b/dev-libs/boost/files/boost-1.76-boost-numpy.patch
new file mode 100644 (file)
index 0000000..d9af132
--- /dev/null
@@ -0,0 +1,23 @@
+From 0796305c863804a2b31610507c531da5c0408422 Mon Sep 17 00:00:00 2001
+From: Peter Dimov <pdimov@gmail.com>
+Date: Mon, 24 May 2021 22:14:55 +0300
+Subject: [PATCH] Use the /python//numpy target instead of [ numpy.include ]
+ (fixes #361)
+
+---
+ libs/python/build/Jamfile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libs/python/build/Jamfile b/libs/python/build/Jamfile
+index dbc9fb203..03b69a25d 100644
+--- a/libs/python/build/Jamfile
++++ b/libs/python/build/Jamfile
+@@ -117,7 +117,7 @@ lib boost_numpy
+         <define>BOOST_NUMPY_SOURCE
+         [ cond [ python.numpy ] : <library>/python//python_for_extensions ]
+         [ unless [ python.numpy ] : <build>no ]
+-        <include>$(numpy-include)
++        <library>/python//numpy
+         <library>boost_python
+         <python-debugging>on:<define>BOOST_DEBUG_PYTHON
+         -<tag>@$(BOOST_JAMROOT_MODULE)%$(BOOST_JAMROOT_MODULE).tag
diff --git a/dev-libs/boost/files/boost-1.76-sparc-define.patch b/dev-libs/boost/files/boost-1.76-sparc-define.patch
new file mode 100644 (file)
index 0000000..b3909ee
--- /dev/null
@@ -0,0 +1,21 @@
+https://github.com/boostorg/predef/commit/1be0e4a2d8db15a405f64a6f65507b87c1be7e1a.patch
+
+From 1be0e4a2d8db15a405f64a6f65507b87c1be7e1a Mon Sep 17 00:00:00 2001
+From: tkoecker <tkoecker@gmx.net>
+Date: Fri, 21 May 2021 16:31:11 +0200
+Subject: [PATCH] added missing brackets (#118)
+--- a/boost/predef/architecture/sparc.h
++++ b/boost/predef/architecture/sparc.h
+@@ -34,10 +34,10 @@ Distributed under the Boost Software License, Version 1.0.
+ #if defined(__sparc__) || defined(__sparc)
+ #   undef BOOST_ARCH_SPARC
+-#   if !defined(BOOST_ARCH_SPARC) && (defined(__sparcv9) || defined(__sparc_v9__)
++#   if !defined(BOOST_ARCH_SPARC) && (defined(__sparcv9) || defined(__sparc_v9__))
+ #       define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(9,0,0)
+ #   endif
+-#   if !defined(BOOST_ARCH_SPARC) && (defined(__sparcv8) || defined(__sparc_v8__)
++#   if !defined(BOOST_ARCH_SPARC) && (defined(__sparcv8) || defined(__sparc_v8__))
+ #       define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(8,0,0)
+ #   endif
+ #   if !defined(BOOST_ARCH_SPARC)
diff --git a/dev-libs/supercop/Manifest b/dev-libs/supercop/Manifest
new file mode 100644 (file)
index 0000000..e84e0ab
--- /dev/null
@@ -0,0 +1,2 @@
+DIST supercop-633500ad8c8759995049ccd022107d1fa8a1bbc9.tar.gz 346604 BLAKE2B 10e48076acb2e5de5acb2efee61b2fac40fdfec3bc4037a94199d56ee2446466126e1b9dade56ee69598f4bd3c64b45d86d0810f24f461f6e09fb84c87e1ef93 SHA512 06cca8d1def31aa11bf5aa42d861c4a027786f7cc494fa3ab53a2bc4bd9d1f55b2389020ba5fd1816ed277b6e4320ad8edbb3117dcf4981fc7fba655c4bbe648
+EBUILD supercop-0_p20200827.ebuild 620 BLAKE2B 216a660b2e79757f9745d5142c1043ca6423409931f9f21f909aab75ac7becf260c338a08dae5202645e649b902e5323d6d38d3459e8e89b0a497ddd14a07918 SHA512 4109eca90ca239f271357309a0fa0d16cfe3b77174f3a88b9ec4f4a6a963e93579eddb40265951cae212d288601dfb14d783fccc90b2f70efea9b96c30686e64
diff --git a/dev-libs/supercop/supercop-0_p20200827.ebuild b/dev-libs/supercop/supercop-0_p20200827.ebuild
new file mode 100644 (file)
index 0000000..297941f
--- /dev/null
@@ -0,0 +1,26 @@
+# Copyright 1999-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit cmake flag-o-matic
+
+MY_REV="633500ad8c8759995049ccd022107d1fa8a1bbc9"
+
+DESCRIPTION="Fast cryyptographic operations for Monero wallets"
+HOMEPAGE="https://github.com/monero-project/supercop"
+SRC_URI="https://github.com/monero-project/supercop/archive/${MY_REV}.tar.gz -> ${PN}-${MY_REV}.tar.gz"
+
+LICENSE="BSD"
+SLOT="0"
+KEYWORDS="amd64 ~arm64 ~x86"
+
+DEPEND="dev-lang/nasm"
+
+S="${WORKDIR}"/${PN}-${MY_REV}
+
+src_configure() {
+       append-flags -fPIC
+       append-ldflags -Wl,-z,noexecstack
+       cmake_src_configure
+}
diff --git a/dev-perl/Data-Entropy/Data-Entropy-0.007.0.ebuild b/dev-perl/Data-Entropy/Data-Entropy-0.007.0.ebuild
new file mode 100644 (file)
index 0000000..474267b
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DIST_AUTHOR=ZEFRAM
+DIST_VERSION=0.007
+
+inherit perl-module
+
+DESCRIPTION="Data::Entropy - entropy (randomness) management"
+
+SLOT="0"
+KEYWORDS="amd64 ~hppa sparc x86"
+
+RDEPEND="
+       dev-perl/Crypt-Eksblowfish
+       dev-perl/Crypt-Rijndael
+       "
+BDEPEND="${RDEPEND}
+       virtual/perl-ExtUtils-MakeMaker
+       test? (
+               virtual/perl-File-Spec
+               >=virtual/perl-Test-Simple-1.302.15
+               dev-perl/Test2-Suite
+       )
+"
diff --git a/dev-perl/Data-Entropy/Manifest b/dev-perl/Data-Entropy/Manifest
new file mode 100644 (file)
index 0000000..3f7b7ed
--- /dev/null
@@ -0,0 +1,2 @@
+DIST Data-Entropy-0.007.tar.gz 43667 BLAKE2B 1ea01b75582b8191df4bc7d8e353cf2593a05f1ada14e58d07e57bd66c9e680c23b8b3e9fbb3f3206d79b2f52e483325d9b27c2f9820afcdfba94a68f95e1758 SHA512 f845fabcac67ab16d44f8bbefa0fc09df171efd6cd9ae2f2ee7e189cbb707cf074705763a022941cbfdda5ab4e03b85eacdb7942a504644a40970c42b5a7e0b9
+EBUILD Data-Entropy-0.007.0.ebuild 498 BLAKE2B e9259f74a462ce50b9f980b823073f1bce3d693a5d0fcbd031c7ad4bde1b10667266f73e2d9fab07bb825a0b3542a9a9be5876cbae18e525c3541e688aa9396e SHA512 31f1c2efb70156e78d95fb923dfee8a043147a96bdcc965ded49a645dfe486dece1651e190d96ac93b29fa79ce7501d8e7f7b21eb0e52e19022384f2b5204957
diff --git a/dev-perl/HTTP-Lite/HTTP-Lite-2.44.ebuild b/dev-perl/HTTP-Lite/HTTP-Lite-2.44.ebuild
new file mode 100644 (file)
index 0000000..327556c
--- /dev/null
@@ -0,0 +1,25 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DIST_AUTHOR=NEILB
+DIST_VERSION=2.44
+
+inherit perl-module
+
+DESCRIPTION="HTTP::Lite - Lightweight HTTP implementation"
+
+SLOT="0"
+KEYWORDS="amd64 ~hppa sparc x86"
+
+RDEPEND=""
+
+BDEPEND="${RDEPEND}
+       virtual/perl-ExtUtils-MakeMaker
+       test? (
+               virtual/perl-File-Spec
+               >=virtual/perl-Test-Simple-1.302.15
+               dev-perl/Test2-Suite
+       )
+"
diff --git a/dev-perl/HTTP-Lite/Manifest b/dev-perl/HTTP-Lite/Manifest
new file mode 100644 (file)
index 0000000..1bd97d7
--- /dev/null
@@ -0,0 +1,2 @@
+DIST HTTP-Lite-2.44.tar.gz 287819 BLAKE2B 0d5ff72132c8bc42e01fa38579a7b502708ca89d6cff1f6fb65a4a94926b87dc34d90a99dacaba2326b402c1b7a1643ecde67cf02ad05acb01fc14b6886999ca SHA512 a30dbcdd3af404117f626502e3c591e073bbf9f113b137e6be0f2fca44948c04c1816064091f1a8bed4bfc1635efb02e57a1830f1f577eadc748b6b08e4e5e0f
+EBUILD HTTP-Lite-2.44.ebuild 439 BLAKE2B 8382a81853026f7273f0a8431da2a13023b29a72594a9f94ef23e43607e04c03e7dbc6030007d1e08979c85f10f237064e9c38a453108fd47a2dd540ae19219d SHA512 f28381bac9f65ebea22accd5925eabf09001d152e7239f94f3940afef87f7b459e6cddadee33a34e98c4d1d7fc1751cc22c4a7510c2526d5eaf000c52010285a
diff --git a/eclass/palemoon-5.eclass b/eclass/palemoon-5.eclass
new file mode 100644 (file)
index 0000000..62547c0
--- /dev/null
@@ -0,0 +1,156 @@
+inherit check-reqs gnome2-utils toolchain-funcs xdg-utils
+
+EXPORT_FUNCTIONS pkg_pretend pkg_preinst pkg_postinst pkg_postrm pkg_setup
+
+
+###
+# Package
+###
+
+palemoon-5_pkg_pretend() {
+       # Ensure that we have enough disk space to compile:
+       CHECKREQS_DISK_BUILD=${REQUIRED_BUILDSPACE}
+       check-reqs_pkg_setup
+
+       # Ensure that we are on a supported compiler profile:
+       einfo "Checking compiler profile..."
+       if [[ $PALEMOON_ENABLE_UNSUPPORTED_COMPILERS == 1 ]]; then
+               unsupported_compiler_warning $(tc-get-compiler-type)
+       else
+               if ! [[ tc-is-gcc && "$GCC_SUPPORTED_VERSIONS" =~ (^| )"$(gcc-version)"($| ) ]]; then
+                       unsupported_compiler_error $(tc-get-compiler-type)
+                       die
+               fi
+       fi
+}
+
+palemoon-5_pkg_preinst() {
+       gnome2_icon_savelist
+}
+
+palemoon-5_pkg_postinst() {
+       # Update mimedb for the new .desktop file:
+       xdg_desktop_database_update
+       gnome2_icon_cache_update
+}
+
+palemoon-5_pkg_postrm() {
+       gnome2_icon_cache_update
+}
+
+palemoon-5_pkg_setup() {
+       # Nested configure scripts in mozilla products generate unrecognized
+       # options false positives when toplevel configure passes downwards:
+       export QA_CONFIGURE_OPTIONS=".*"
+}
+
+
+###
+# Messages
+###
+
+official-branding_warning() {
+       elog "You are enabling the official branding. You may not redistribute this build"
+       elog "to any users on your network or the internet. Doing so puts yourself into"
+       elog "a legal problem with Moonchild Productions."
+       elog "You can disable the official branding by emerging ${PN} _without_"
+       elog "the official-branding USE flag."
+}
+
+unsupported_compiler_warning() {
+       ewarn "Building Pale Moon with a compiler other than a supported gcc version"
+       ewarn "may result in an unstable build."
+       ewarn "Be aware that building Pale Moon with an unsupported compiler"
+       ewarn "means that the official support channels may refuse to offer any"
+       ewarn "kind of help in case the build fails or the browser behaves incorrectly."
+       ewarn "Supported GCC versions: ${GCC_SUPPORTED_VERSIONS// /, }"
+       if [[ "$1" == "gcc" ]]; then
+               ewarn "Selected GCC version: $(gcc-version)"
+       else
+               ewarn "Unsupported compiler selected: $1"
+       fi
+       ewarn "To disable this warning unset the PALEMOON_ENABLE_UNSUPPORTED_COMPILERS"
+       ewarn "environment variable."
+}
+
+unsupported_compiler_error() {
+       eerror "Building Pale Moon with a compiler other than a supported gcc version"
+       eerror "may result in an unstable build."
+       eerror "You can use gcc-config to change your compiler profile, just remember"
+       eerror "to change it back afterwards."
+       eerror "You need to have the appropriate versions of gcc installed for them"
+       eerror "to be shown in gcc-config."
+       eerror "Alternatively, you can set the PALEMOON_ENABLE_UNSUPPORTED_COMPILERS"
+       eerror "environment variable to 1 either by exporting it from the current shell"
+       eerror "or by adding it to your make.conf file."
+       eerror "Be aware though that building Pale Moon with an unsupported compiler"
+       eerror "means that the official support channels may refuse to offer any"
+       eerror "kind of help in case the build fails or the browser behaves incorrectly."
+       eerror "Supported GCC versions: ${GCC_SUPPORTED_VERSIONS// /, }"
+       if [[ "$1" == "gcc" ]]; then
+               eerror "Selected GCC version: $(gcc-version)"
+       else
+               eerror "Unsupported compiler selected: $1"
+       fi
+}
+
+
+###
+# Configuration
+###
+
+mozconfig_init() {
+       echo "ac_add_options --enable-application=palemoon" > "${S}/.mozconfig"
+}
+
+mozconfig_enable() {
+       for option in "$@"; do
+               echo "ac_add_options --enable-${option}" >> "${S}/.mozconfig"
+       done
+}
+
+mozconfig_disable() {
+       for option in "$@"; do
+               echo "ac_add_options --disable-${option}" >> "${S}/.mozconfig"
+       done
+}
+
+mozconfig_with() {
+       for option in "$@"; do
+               echo "ac_add_options --with-${option}" >> "${S}/.mozconfig"
+       done
+}
+
+mozconfig_var() {
+       echo "mk_add_options $1=$2" >> "${S}/.mozconfig"
+}
+
+set_pref() {
+       echo "pref(\"$1\", $2);" >> "${S}/${obj_dir}/dist/bin/browser/defaults/preferences/palemoon.js"
+}
+
+
+###
+# Branding
+###
+
+install_branding_files() {
+       cp -rL "${S}/${obj_dir}/dist/branding" "${extracted_dir}/"
+       local size sizes icon_path icon name
+       sizes="16 32 48"
+       icon_path="${extracted_dir}/branding"
+       icon="${PN}"
+       name="Pale Moon"
+       for size in ${sizes}; do
+               insinto "/usr/share/icons/hicolor/${size}x${size}/apps"
+               newins "${icon_path}/default${size}.png" "${icon}.png"
+       done
+       # The 128x128 icon has a different name:
+       insinto "/usr/share/icons/hicolor/128x128/apps"
+       newins "${icon_path}/mozicon128.png" "${icon}.png"
+       # Install a 48x48 icon into /usr/share/pixmaps for legacy DEs:
+       newicon "${icon_path}/default48.png" "${icon}.png"
+       newmenu "${FILESDIR}/icon/${PN}.desktop" "${PN}.desktop"
+       sed -i -e "s:@NAME@:${name}:" -e "s:@ICON@:${icon}:" \
+               "${ED}/usr/share/applications/${PN}.desktop" || die
+}
diff --git a/eclass/palemoon-bin-0.eclass b/eclass/palemoon-bin-0.eclass
new file mode 100644 (file)
index 0000000..4dd3ffa
--- /dev/null
@@ -0,0 +1,15 @@
+inherit gnome2-utils xdg-utils
+
+pkg_preinst() {
+       gnome2_icon_savelist
+}
+
+pkg_postinst() {
+       # Update mimedb for the new .desktop file:
+       xdg_desktop_database_update
+       gnome2_icon_cache_update
+}
+
+pkg_postrm() {
+       gnome2_icon_cache_update
+}
diff --git a/games-util/mangohud/Manifest b/games-util/mangohud/Manifest
new file mode 100644 (file)
index 0000000..69be168
--- /dev/null
@@ -0,0 +1,4 @@
+DIST mangohud-0.7.2.tar.gz 14906751 BLAKE2B a88e6497d8a8bcd899fc41d555dec429a69c864a10476c1d549acead58a7fc7c5f5d14d901b75bd2aed1d8c8088a027417a74480b89501d947333d665d0567c0 SHA512 edc3e380f9f58b65ae04c970e84eec9ff3458eafb2d89b2208c0afa6978a745a634aab6b0e025996175981e80c66475ef92ffe326d31a67055895b8fd1213e63
+DIST vulkan-headers-1.2.158-2-meson-wrap.zip 1107 BLAKE2B 35e4bb1f7410a009243fe7d4a4ba6cede7f01e0b56ad6ff72ad30c00c2452bd6d2a4fb44ab92c296147e2506a92acc6de1f817cb5433b96d66652cbcd8885595 SHA512 30cbbb90580399839e1bba8881b9b8cc33fdeead93f37d5f3398c9d53fb3ab050ca2562fd68f376fa4ee0825ee3787f560d70d55a170c780dd575ff2eeb66efd
+DIST vulkan-headers-1.2.158.tar.gz 831647 BLAKE2B 792d7e895e27c4a8fbc93fc4d9c9e696d2ceb946e745709c050c0693b77afbeb6411a4267fc59508ddeb58167d469349fedc1c5d4b4a7415b590c97248b244bc SHA512 f7aa9222f9deb1316d22deacc2c6cd85c409f0f2b2d37ecd55e0fc8466d381bbe3bed287881b993a01c5f33736e1607014f820980b7a54a3721fab6980960c91
+EBUILD mangohud-0.7.2.ebuild 4381 BLAKE2B 39617093bfd2785c655083e8ff278efe69dc1c4b5e10da7fb6c747127afa07ee30d7afeb9ace5d5e19f4987c6e2bf85d9ccbff8134f9701320fc5a58580f3ad3 SHA512 aad1745a9b38d9387af88b0acfbcece570395f8de50afca69e9570405f106ad8e3a9a902eca17a02fe345c74e994a6fcea0b70348e3e6cee7e8c597af7ff7f45
diff --git a/games-util/mangohud/mangohud-0.7.2.ebuild b/games-util/mangohud/mangohud-0.7.2.ebuild
new file mode 100644 (file)
index 0000000..122f285
--- /dev/null
@@ -0,0 +1,146 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+PYTHON_COMPAT=( python3_{10..12} )
+
+inherit flag-o-matic python-single-r1 meson-multilib
+
+MY_PV=$(ver_cut 1-3)
+[[ -n "$(ver_cut 4)" ]] && MY_PV_REV="-$(ver_cut 4)"
+
+DESCRIPTION="Vulkan and OpenGL overlay for monitoring FPS, sensors, system load and more"
+HOMEPAGE="https://github.com/flightlessmango/MangoHud"
+
+VK_HEADERS_VER="1.2.158"
+VK_HEADERS_MESON_WRAP_VER="2"
+
+SRC_URI="
+       https://github.com/KhronosGroup/Vulkan-Headers/archive/v${VK_HEADERS_VER}.tar.gz
+               -> vulkan-headers-${VK_HEADERS_VER}.tar.gz
+       https://wrapdb.mesonbuild.com/v2/vulkan-headers_${VK_HEADERS_VER}-${VK_HEADERS_MESON_WRAP_VER}/get_patch
+               -> vulkan-headers-${VK_HEADERS_VER}-${VK_HEADERS_MESON_WRAP_VER}-meson-wrap.zip
+"
+
+if [[ ${PV} == 9999 ]]; then
+       inherit git-r3
+       EGIT_REPO_URI="https://github.com/flightlessmango/MangoHud.git"
+else
+       SRC_URI+="
+               https://github.com/flightlessmango/MangoHud/archive/v${MY_PV}${MY_PV_REV}.tar.gz
+                       -> ${P}.tar.gz
+       "
+       KEYWORDS="~amd64"
+       S="${WORKDIR}/MangoHud-${PV}"
+fi
+
+LICENSE="MIT"
+SLOT="0"
+IUSE="+dbus debug +X xnvctrl wayland mangoapp mangohudctl mangoplot video_cards_nvidia video_cards_amdgpu test"
+RESTRICT="!test? ( test )"
+
+REQUIRED_USE="
+       ${PYTHON_REQUIRED_USE}
+       || ( X wayland )
+       xnvctrl? ( video_cards_nvidia )
+"
+
+BDEPEND="
+       app-arch/unzip
+       >=dev-util/vulkan-headers-1.2.158
+       test? ( dev-util/cmocka )
+       $(python_gen_cond_dep 'dev-python/mako[${PYTHON_USEDEP}]')
+"
+
+RDEPEND="
+       ${PYTHON_DEPS}
+       =media-libs/imgui-1.89.9*[opengl,vulkan,${MULTILIB_USEDEP}]
+       =media-libs/implot-0.16*[${MULTILIB_USEDEP}]
+       dev-libs/spdlog[${MULTILIB_USEDEP}]
+       dev-libs/libfmt[${MULTILIB_USEDEP}]
+       dev-cpp/nlohmann_json
+       dev-util/glslang
+       media-fonts/lato
+       media-libs/vulkan-loader[${MULTILIB_USEDEP}]
+       media-libs/libglvnd[${MULTILIB_USEDEP}]
+       x11-libs/libdrm[${MULTILIB_USEDEP}]
+       dbus? ( sys-apps/dbus[${MULTILIB_USEDEP}] )
+       X? ( x11-libs/libX11[${MULTILIB_USEDEP}] )
+       video_cards_nvidia? (
+               x11-drivers/nvidia-drivers[${MULTILIB_USEDEP}]
+               xnvctrl? ( x11-drivers/nvidia-drivers[static-libs] )
+       )
+       wayland? ( dev-libs/wayland[${MULTILIB_USEDEP}] )
+       mangoapp? (
+               =media-libs/imgui-1.89.9*[glfw]
+               media-libs/glfw[X(+)]
+               media-libs/glew
+       )
+       mangoplot? ( $(python_gen_cond_dep '
+               || (
+                       dev-python/matplotlib[gtk3,${PYTHON_USEDEP}]
+                       dev-python/matplotlib[qt5,${PYTHON_USEDEP}]
+                       dev-python/matplotlib[wxwidgets,${PYTHON_USEDEP}]
+               )
+       ') )
+"
+
+src_unpack() {
+
+       default
+
+       [[ -n "${MY_PV_REV}" ]] && ( mv "${WORKDIR}/MangoHud-${MY_PV}${MY_PV_REV}" "${WORKDIR}/MangoHud-${PV}" || die )
+
+       if [[ $PV == 9999 ]]; then
+               git-r3_src_unpack
+       fi
+
+       unpack vulkan-headers-${VK_HEADERS_VER}.tar.gz
+       unpack vulkan-headers-${VK_HEADERS_VER}-${VK_HEADERS_MESON_WRAP_VER}-meson-wrap.zip
+       mv "${WORKDIR}/Vulkan-Headers-${VK_HEADERS_VER}" "${S}/subprojects/" || die
+}
+
+src_prepare() {
+       default
+       # replace all occurences of "#include <imgui.h>" to "#include <imgui/imgui.h>"
+       find . -type f -exec sed -i 's|<imgui.h>|<imgui/imgui.h>|g' {} \; || die
+       find . -type f -exec sed -i 's|"imgui.h"|<imgui/imgui.h>|g' {} \; || die
+       find . -type f -exec sed -i 's|<imgui_internal.h>|<imgui/imgui_internal.h>|g' {} \; || die
+       find . -type f -exec sed -i 's|"imgui_internal.h"|<imgui/imgui_internal.h>|g' {} \; || die
+       find . -type f -exec sed -i 's|"imgui_impl_glfw.h"|<imgui/imgui_impl_glfw.h>|g' {} \; || die
+       find . -type f -exec sed -i 's|"imgui_impl_opengl3.h"|<imgui/imgui_impl_opengl3.h>|g' {} \; || die
+}
+
+multilib_src_configure() {
+       # workaround for lld
+       # https://github.com/flightlessmango/MangoHud/issues/1240
+       append-ldflags $(test-flags-CCLD -Wl,--undefined-version)
+
+       local emesonargs=(
+               -Dappend_libdir_mangohud=false
+               -Dinclude_doc=false
+               -Duse_system_spdlog=enabled
+               $(meson_feature video_cards_nvidia with_nvml)
+               $(meson_feature xnvctrl with_xnvctrl)
+               $(meson_feature X with_x11)
+               $(meson_feature wayland with_wayland)
+               $(meson_feature dbus with_dbus)
+               $(meson_use mangoapp mangoapp)
+               $(meson_use mangoapp mangoapp_layer)
+               $(meson_use mangohudctl mangohudctl)
+               $(meson_feature mangoplot mangoplot)
+       )
+       meson_src_configure
+}
+
+pkg_postinst() {
+       if ! use xnvctrl; then
+               einfo ""
+               einfo "If mangohud can't get GPU load, or other GPU information,"
+               einfo "and you have an older Nvidia device."
+               einfo ""
+               einfo "Try enabling the 'xnvctrl' useflag."
+               einfo ""
+       fi
+}
diff --git a/games-util/oversteer/Manifest b/games-util/oversteer/Manifest
new file mode 100644 (file)
index 0000000..1e93da3
--- /dev/null
@@ -0,0 +1,4 @@
+DIST oversteer-0.5.2.tar.gz 50101 BLAKE2B a4b0b78e4cd26eabb43eee5346c6322249ee2d59afd4b8b0b5498679cfc129ce9222d951dd696fd7e0bc2f2e677bbcbf9e9ebc14aaac24c6c04ff9026cf6e346 SHA512 8a6229766699f56e1b3122de145ce18918f3a19626bcc7bde983512dba6d0c88a31002a1fcb2d9a6be8b454a7b01d765c12cb92dd575a6024d73c355bdb96f9e
+DIST oversteer-0.8.0.tar.gz 97611 BLAKE2B 6ee283a92d14c41940a6e6bec6b003f23772c4449c849ba1cbc49ab944988fb6c61b64765f0f4f72a62764ec77a81b8f4284ba3271c1148b5c3d06fe15963f44 SHA512 f490edc9a084d2120f2bf8fbc6ad18a2a82b613f12946df5cd3fc72a5d50c78c330de42eb1bcb41d6c4ded96d40a300f26d49571ebb1ce7ca4fdc712220c619b
+EBUILD oversteer-0.5.2.ebuild 719 BLAKE2B ab56335e3ea83df25e7fc44c2982e6571d4a837bdac2c9d755abcab421245211705900746d29f36e84af5f03c7bbddaf8ab022097c342ef0d4b6130cdc58219c SHA512 642433539c608fe7cba0e3ff0bceb78a9176bbc3d81f01082089fb0d28c8db8642635b96e44738603ced847efd4c8140379236ca4bd89f01ca39a2530de4af94
+EBUILD oversteer-0.8.0.ebuild 719 BLAKE2B ab56335e3ea83df25e7fc44c2982e6571d4a837bdac2c9d755abcab421245211705900746d29f36e84af5f03c7bbddaf8ab022097c342ef0d4b6130cdc58219c SHA512 642433539c608fe7cba0e3ff0bceb78a9176bbc3d81f01082089fb0d28c8db8642635b96e44738603ced847efd4c8140379236ca4bd89f01ca39a2530de4af94
diff --git a/games-util/oversteer/oversteer-0.5.2.ebuild b/games-util/oversteer/oversteer-0.5.2.ebuild
new file mode 100644 (file)
index 0000000..c12aa69
--- /dev/null
@@ -0,0 +1,34 @@
+EAPI=7
+PYTHON_COMPAT=( python3_{6,7} )
+DESCRIPTION="Graphical application to configure Logitech Wheels"
+HOMEPAGE="https://github.com/berarma/oversteer"
+SRC_URI="https://github.com/berarma/oversteer/archive/${PV}.tar.gz -> ${P}.tar.gz"
+LICENSE="GPL-3"
+SLOT="0"
+KEYWORDS="amd64 x86"
+
+BDEPEND="dev-util/meson"
+
+RDEPEND="dev-python/pygobject
+                dev-python/pyudev
+                dev-python/python-evdev
+                dev-python/pyxdg
+                sys-devel/gettext
+                dev-libs/appstream-glib
+                dev-util/desktop-file-utils
+                x11-libs/gtk+"
+
+src_prepare() {
+       eapply_user
+       sed -i 's/Utility;//' data/org.berarma.Oversteer.desktop.in
+}
+
+src_compile() {
+       meson build --prefix="/usr"
+       ninja -C build
+}
+
+src_install() {
+       DESTDIR="${D}" ninja -C build install
+}
+
diff --git a/games-util/oversteer/oversteer-0.8.0.ebuild b/games-util/oversteer/oversteer-0.8.0.ebuild
new file mode 100644 (file)
index 0000000..c12aa69
--- /dev/null
@@ -0,0 +1,34 @@
+EAPI=7
+PYTHON_COMPAT=( python3_{6,7} )
+DESCRIPTION="Graphical application to configure Logitech Wheels"
+HOMEPAGE="https://github.com/berarma/oversteer"
+SRC_URI="https://github.com/berarma/oversteer/archive/${PV}.tar.gz -> ${P}.tar.gz"
+LICENSE="GPL-3"
+SLOT="0"
+KEYWORDS="amd64 x86"
+
+BDEPEND="dev-util/meson"
+
+RDEPEND="dev-python/pygobject
+                dev-python/pyudev
+                dev-python/python-evdev
+                dev-python/pyxdg
+                sys-devel/gettext
+                dev-libs/appstream-glib
+                dev-util/desktop-file-utils
+                x11-libs/gtk+"
+
+src_prepare() {
+       eapply_user
+       sed -i 's/Utility;//' data/org.berarma.Oversteer.desktop.in
+}
+
+src_compile() {
+       meson build --prefix="/usr"
+       ninja -C build
+}
+
+src_install() {
+       DESTDIR="${D}" ninja -C build install
+}
+
diff --git a/games-util/simulationcraft/Manifest b/games-util/simulationcraft/Manifest
new file mode 100644 (file)
index 0000000..99e66ec
--- /dev/null
@@ -0,0 +1 @@
+EBUILD simulationcraft-9999.ebuild 894 BLAKE2B c49a475a575e4f31e0876047196066d270a666072867a0016620678e45b53dbc0617852af4aa181564b9ae0c3b1a8091b17aca03f624db87a422869b5cdce777 SHA512 77b655e8e8253a8b016ebd20b542fb4d953746b3810a84315d42715b0edd23d7cc41901e12d0808fa0da21f91de742dbdaf024758272c5bfd59bb08efd543886
diff --git a/games-util/simulationcraft/simulationcraft-9999.ebuild b/games-util/simulationcraft/simulationcraft-9999.ebuild
new file mode 100644 (file)
index 0000000..37ddd66
--- /dev/null
@@ -0,0 +1,50 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit cmake
+
+DESCRIPTION="SimulationCraft is a tool to explore combat mechanics in World of Warcraft"
+HOMEPAGE="https://simulationcraft.org"
+
+if [[ ${PV} == 9999 ]]; then
+       inherit git-r3
+       EGIT_REPO_URI="https://github.com/simulationcraft/simc"
+       EGIT_SUBMODULES=()
+else
+       SRC_URI="https://github.com/simulationcraft/simc/archive/v${PV}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="~amd64 ~arm64 ~x86"
+fi
+
+LICENSE="GPL-3"
+SLOT="0"
+IUSE=""
+REQUIRED_USE=""
+RESTRICT=""
+
+DEPEND="
+       dev-libs/rapidjson
+       dev-libs/libfmt
+"
+RDEPEND="${DEPEND}"
+BDEPEND=""
+
+src_configure() {
+       local mycmakeargs=(
+        -DBUILD_SHARED_LIBS=OFF
+        -DCMAKE_BUILD_TYPE=Release
+        #-DSC_NO_NETWORKING=ON
+        )
+       cmake_src_configure
+}
+
+src_compile() {
+       cmake_build
+}
+
+src_install() {
+    cmake_src_install
+}
+
+
diff --git a/kde-apps/kdeutils-meta/Manifest b/kde-apps/kdeutils-meta/Manifest
new file mode 100644 (file)
index 0000000..28d4b11
--- /dev/null
@@ -0,0 +1 @@
+EBUILD kdeutils-meta-22.04.3.ebuild 1289 BLAKE2B f8c7367a173b2b0ed797182b45e6f6a32a1b97d4b0d6963d3ab9dc9ab0b1715fb6b4b63082ebb432a37efb10ba5a435eb2fbcce447b4c72985d30b682656fd13 SHA512 40a52b42961eac39c4027bc46e6b7313c8306bb0108a85b85f641ca8e0c4a3aebe49358a519eab1894bfd6c50fe1dcbcb8c8bfc8273ed0d03b4a59e2191f26d5
diff --git a/kde-apps/kdeutils-meta/kdeutils-meta-22.04.3.ebuild b/kde-apps/kdeutils-meta/kdeutils-meta-22.04.3.ebuild
new file mode 100644 (file)
index 0000000..1e88dcf
--- /dev/null
@@ -0,0 +1,44 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="kdeutils - merge this to pull in all kdeutils-derived packages"
+HOMEPAGE="https://apps.kde.org/utilities/ https://utils.kde.org"
+
+LICENSE="metapackage"
+SLOT="5"
+KEYWORDS="amd64 arm64 ~ppc64 x86"
+IUSE="7zip cups floppy gpg lrz rar +webengine"
+
+RDEPEND="
+       >=app-cdr/dolphin-plugins-mountiso-${PV}:${SLOT}
+       >=kde-apps/ark-${PV}:${SLOT}
+       >=kde-apps/filelight-${PV}:${SLOT}
+       >=kde-apps/kate-${PV}:${SLOT}
+       >=kde-apps/kbackup-${PV}:${SLOT}
+       >=kde-apps/kcalc-${PV}:${SLOT}
+       >=kde-apps/kcharselect-${PV}:${SLOT}
+       >=kde-apps/kdebugsettings-${PV}:${SLOT}
+       >=kde-apps/kdf-${PV}:${SLOT}
+       >=kde-apps/kteatime-${PV}:${SLOT}
+       >=kde-apps/ktimer-${PV}:${SLOT}
+       >=kde-apps/kwalletmanager-${PV}:${SLOT}
+       >=kde-apps/sweeper-${PV}:${SLOT}
+       >=kde-apps/yakuake-${PV}:${SLOT}
+       >=kde-misc/markdownpart-${PV}:${SLOT}
+       cups? ( >=kde-apps/print-manager-${PV}:${SLOT} )
+       floppy? ( >=kde-apps/kfloppy-${PV}:${SLOT} )
+       gpg? ( >=kde-apps/kgpg-${PV}:${SLOT} )
+       webengine? ( >=kde-apps/kimagemapeditor-${PV}:${SLOT} )
+"
+# Optional runtime deps: kde-apps/ark
+RDEPEND="${RDEPEND}
+       7zip? ( app-arch/p7zip )
+       lrz? ( app-arch/lrzip )
+       rar? ( || (
+               app-arch/rar
+               app-arch/unrar
+               app-arch/unar
+       ) )
+"
diff --git a/kde-apps/konsole/Manifest b/kde-apps/konsole/Manifest
new file mode 100644 (file)
index 0000000..c96f4bc
--- /dev/null
@@ -0,0 +1,3 @@
+AUX konsole-24.05.2-cmake.patch 4607 BLAKE2B e0ac57c4901a8374625ec368b37f05b86a0be33321902d39138c2e6067043c43be2bd40dfda79f8a2f20fb868e9607e25ee72558154be09f0bdbcb6538ca0a70 SHA512 da8387a5ba1beaffaa42b8b18b2892f16dc5bd60f7a3b4f87285d84992c1c12d8f80b983860b6dd8e12d4cbce50e7c4ccf13d913a8b87d247f82671a3dfda9e7
+DIST konsole-24.05.2.tar.xz 1770568 BLAKE2B feda024d6ee3c4ac0f2e84c9a4825829c63167cfbc86b6506dd0fefcc6ea28075a5b5685d474dfb746daee0cefeac6adef7227808f0da9a3d47bb941d82b2e2c SHA512 47b2fdfc4b79b1e8cef72aed9d77858347c0c89e7b0cd4106a2f0d362ea72a2d54b79385deb8525654a5b0da0fb19c8e1db370618a6f0ae2d8e1aab41e7261f3
+EBUILD konsole-24.05.2-r2.ebuild 1875 BLAKE2B 4206480ffe29e0105fd7a84947686cc61d663a587d07bb14aae872d01a53a83076efb86b7a0823500dfc011b662d3f2f86cca9c1ae2911143de90583ccb12eea SHA512 1308560503507073c5381f52d06c84d2cb9b650877d5f1f90b77d3f5463b6c68482208116d77d1aac1bc42ea13a538eae0cf16c20ce956f35dab3fc77b3bb708
diff --git a/kde-apps/konsole/files/konsole-24.05.2-cmake.patch b/kde-apps/konsole/files/konsole-24.05.2-cmake.patch
new file mode 100644 (file)
index 0000000..19064a3
--- /dev/null
@@ -0,0 +1,136 @@
+From 3800a40653355dd165fe68f80611228fa94656ee Mon Sep 17 00:00:00 2001
+From: Andreas Sturmlechner <asturm@gentoo.org>
+Date: Sun, 7 Jul 2024 23:27:32 +0200
+Subject: [PATCH] Drop faux X11 dependency and switch WITHOUT_X11 option to
+ WITH_X11
+
+X11 is nowhere needed in the codebase. Follow-up to 2f116f9fb2438a6e66b6702b3cc2ace9d0205f96
+
+Signed-off-by: Andreas Sturmlechner <asturm@gentoo.org>
+(cherry picked from commit c5f2315c9df05ca069de25ab741d9fc38a6de21a)
+---
+ CMakeLists.txt             | 7 +------
+ src/MainWindow.cpp         | 8 ++++----
+ src/WindowSystemInfo.cpp   | 4 ++--
+ src/config-konsole.h.cmake | 2 +-
+ src/main.cpp               | 4 ++--
+ 5 files changed, 10 insertions(+), 15 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index bd30a9888..0f00be8f3 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -95,12 +95,7 @@ set_package_properties(KF6DocTools PROPERTIES DESCRIPTION
+ find_package(ICU 61.0 COMPONENTS uc i18n REQUIRED)
+ if(NOT APPLE)
+-    option(WITHOUT_X11 "Build without X11 integration (skips finding X11)" OFF)
+-    if (NOT WITHOUT_X11)
+-        find_package(X11)
+-        set_package_properties(X11 PROPERTIES TYPE OPTIONAL)
+-        set(HAVE_X11 ${X11_FOUND})
+-    endif()
++    option(WITH_X11 "Build with X11 integration" ON)
+ endif()
+ # Check for function GETPWUID
+diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
+index c034288df..163105357 100644
+--- a/src/MainWindow.cpp
++++ b/src/MainWindow.cpp
+@@ -35,7 +35,7 @@
+ #include <KWindowSystem>
+ #include <KXMLGUIFactory>
+-#if HAVE_X11
++#if WITH_X11
+ #include <KX11Extras>
+ #endif
+@@ -156,7 +156,7 @@ void MainWindow::activationRequest(const QString &xdgActivationToken)
+     KWindowSystem::setCurrentXdgActivationToken(xdgActivationToken);
+     if (KWindowSystem::isPlatformX11()) {
+-#if HAVE_X11
++#if WITH_X11
+         KX11Extras::forceActiveWindow(winId());
+ #endif
+     } else {
+@@ -713,7 +713,7 @@ bool MainWindow::queryClose()
+     // NOTE: Some, if not all, of the below KWindowSystem calls are only
+     //       implemented under x11 (KDE4.8 kdelibs/kdeui/windowmanagement).
+-#if HAVE_X11
++#if WITH_X11
+     // make sure the window is shown on current desktop and is not minimized
+     KX11Extras::setOnDesktop(winId(), KX11Extras::currentDesktop());
+ #endif
+@@ -1022,7 +1022,7 @@ void MainWindow::setRemoveWindowTitleBarAndFrame(bool frameless)
+         }
+         if (KWindowSystem::isPlatformX11()) {
+-#if HAVE_X11
++#if WITH_X11
+             const auto oldGeometry = saveGeometry();
+             // This happens for every Konsole window. It depends on
+             // the fact that every window is processed in single thread
+diff --git a/src/WindowSystemInfo.cpp b/src/WindowSystemInfo.cpp
+index d6cad5f68..28cc3bd6c 100644
+--- a/src/WindowSystemInfo.cpp
++++ b/src/WindowSystemInfo.cpp
+@@ -11,7 +11,7 @@
+ #include <QtGlobal>
+-#if HAVE_X11
++#if WITH_X11
+ #include <KWindowSystem>
+ #include <KX11Extras>
+ #endif
+@@ -22,7 +22,7 @@ bool WindowSystemInfo::HAVE_TRANSPARENCY = false;
+ bool WindowSystemInfo::compositingActive()
+ {
+-#if HAVE_X11
++#if WITH_X11
+     return !KWindowSystem::isPlatformX11() || KX11Extras::compositingActive();
+ #else
+     return true;
+diff --git a/src/config-konsole.h.cmake b/src/config-konsole.h.cmake
+index b860764d3..b9fac1e56 100644
+--- a/src/config-konsole.h.cmake
++++ b/src/config-konsole.h.cmake
+@@ -3,7 +3,7 @@
+ /* Defined if on DragonFly BSD */
+ #cmakedefine01 HAVE_OS_DRAGONFLYBSD
+-#cmakedefine01 HAVE_X11
++#cmakedefine01 WITH_X11
+ /* If defined, remove public access to dbus sendInput/runCommand */
+ #cmakedefine01 REMOVE_SENDTEXT_RUNCOMMAND_DBUS_METHODS
+diff --git a/src/main.cpp b/src/main.cpp
+index 9f3b88286..b05877f3d 100644
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -284,7 +284,7 @@ bool shouldUseNewProcess(int argc, char *argv[])
+     QStringList qtProblematicOptions;
+     qtProblematicOptions << QStringLiteral("--session") << QStringLiteral("--name") << QStringLiteral("--reverse") << QStringLiteral("--stylesheet")
+                          << QStringLiteral("--graphicssystem");
+-#if HAVE_X11
++#if WITH_X11
+     qtProblematicOptions << QStringLiteral("--display") << QStringLiteral("--visual");
+ #endif
+     for (const QString &option : std::as_const(qtProblematicOptions)) {
+@@ -296,7 +296,7 @@ bool shouldUseNewProcess(int argc, char *argv[])
+     // take KDE options into consideration
+     QStringList kdeProblematicOptions;
+     kdeProblematicOptions << QStringLiteral("--config") << QStringLiteral("--style");
+-#if HAVE_X11
++#if WITH_X11
+     kdeProblematicOptions << QStringLiteral("--waitforwm");
+ #endif
+-- 
+2.45.2
+
diff --git a/kde-apps/konsole/konsole-24.05.2-r2.ebuild b/kde-apps/konsole/konsole-24.05.2-r2.ebuild
new file mode 100644 (file)
index 0000000..f4c22d5
--- /dev/null
@@ -0,0 +1,69 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+ECM_HANDBOOK="optional"
+ECM_TEST="true"
+KFMIN=6.3.0
+QTMIN=6.6.2
+inherit ecm gear.kde.org
+
+DESCRIPTION="KDE's terminal emulator"
+HOMEPAGE="https://apps.kde.org/konsole/ https://konsole.kde.org"
+
+LICENSE="GPL-2" # TODO: CHECK
+SLOT="6"
+KEYWORDS="amd64 arm64 ~ppc64 ~riscv ~x86"
+IUSE="X"
+
+DEPEND="
+       dev-libs/icu:=
+       >=dev-qt/qtbase-${QTMIN}:6[dbus,gui,network,widgets,xml]
+       >=dev-qt/qt5compat-${QTMIN}:6
+       >=dev-qt/qtmultimedia-${QTMIN}:6
+       >=kde-frameworks/kbookmarks-${KFMIN}:6
+       >=kde-frameworks/kconfig-${KFMIN}:6
+       >=kde-frameworks/kconfigwidgets-${KFMIN}:6
+       >=kde-frameworks/kcoreaddons-${KFMIN}:6
+       >=kde-frameworks/kcrash-${KFMIN}:6
+       >=kde-frameworks/kdbusaddons-${KFMIN}:6
+       >=kde-frameworks/kglobalaccel-${KFMIN}:6
+       >=kde-frameworks/kguiaddons-${KFMIN}:6
+       >=kde-frameworks/ki18n-${KFMIN}:6
+       >=kde-frameworks/kiconthemes-${KFMIN}:6
+       >=kde-frameworks/kio-${KFMIN}:6
+       >=kde-frameworks/kjobwidgets-${KFMIN}:6
+       >=kde-frameworks/knewstuff-${KFMIN}:6
+       >=kde-frameworks/knotifications-${KFMIN}:6
+       >=kde-frameworks/knotifyconfig-${KFMIN}:6
+       >=kde-frameworks/kparts-${KFMIN}:6
+       >=kde-frameworks/kpty-${KFMIN}:6
+       >=kde-frameworks/kservice-${KFMIN}:6
+       >=kde-frameworks/ktextwidgets-${KFMIN}:6
+       >=kde-frameworks/kwidgetsaddons-${KFMIN}:6
+       >=kde-frameworks/kwindowsystem-${KFMIN}:6[X?]
+       >=kde-frameworks/kxmlgui-${KFMIN}:6
+"
+RDEPEND="${DEPEND}"
+
+PATCHES=( "${FILESDIR}/${P}-cmake.patch" ) # fixed in 24.08
+
+src_configure() {
+       local mycmakeargs=(
+               -DWITH_X11=$(usex X)
+               -DENABLE_PLUGIN_SSHMANAGER=0
+               -DENABLE_PLUGIN_QUICKCOMMANDS=0
+       )
+       ecm_src_configure
+}
+
+src_test() {
+       # DBusTest: drkonqi process interferes. bug 702690
+       # TerminalInterfaceTest: unbelievably flaky, bug 862594 and bug 662756
+       local myctestargs=(
+               -E "(DBusTest|TerminalInterfaceTest)"
+       )
+
+       ecm_src_test
+}
diff --git a/kde-frameworks/oxygen-icons/Manifest b/kde-frameworks/oxygen-icons/Manifest
new file mode 100644 (file)
index 0000000..914dcf9
--- /dev/null
@@ -0,0 +1,3 @@
+DIST oxygen-icons-5.116.0.tar.xz 238635868 BLAKE2B a4b5400c61d780c8bcdcfd4426bbaa6daa4b15ba5e90cd3106b6941571b10801c3c8312968647e115a1b73e34f926238132d160a862b8ed9222eaecbbf0b08c9 SHA512 d02599b95fcf7c7a38a65a7a422eba59748cdd0d6b3542721a789847b550757bc4162ab5d9c3b4bd1267f5ff0ae6d39c8041b65b895eb5553522645cf260670a
+EBUILD oxygen-icons-5.116.0.ebuild 748 BLAKE2B 0faef89059b04141357828e08021726236df617e7c8e08ae686dc531a413c505bb9b885b95c3c102ff136a047cf265787b345bffabe93edd6949b1a1e6dceb02 SHA512 3ba732c0db77fe8fec758223d62df9cd3f4d567506fd1fc02b24c35501e9bbc19be23940606dd130e22edbef47de04e442803951c93d67ddaaebac3af5fc411d
+MISC metadata.xml 456 BLAKE2B 4392b1cc6f304778d71236d5eb557dfbbd530143eea5cad9a3c3034e3e8b22c835f6c7f980124a21cefd35a2dd1efd5110adc0a5342170f88dfd7418b12bee99 SHA512 7ba65331cad434e2dceee012a5458d268eb2a04e0f7276b265c15644e6db5209bc7eee7d9695aa0038c435711e0f6f0dc53c7bae9d773b48f01e22a22e4dbb80
diff --git a/kde-frameworks/oxygen-icons/metadata.xml b/kde-frameworks/oxygen-icons/metadata.xml
new file mode 100644 (file)
index 0000000..506ecf6
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+       <maintainer type="project">
+               <email>kde@gentoo.org</email>
+               <name>Gentoo KDE Project</name>
+       </maintainer>
+       <upstream>
+               <bugs-to>https://bugs.kde.org/</bugs-to>
+       </upstream>
+       <slots>
+               <subslots>
+                       Must only be used by packages that are known to use private parts of the Frameworks API.
+               </subslots>
+       </slots>
+</pkgmetadata>
diff --git a/kde-frameworks/oxygen-icons/oxygen-icons-5.116.0.ebuild b/kde-frameworks/oxygen-icons/oxygen-icons-5.116.0.ebuild
new file mode 100644 (file)
index 0000000..4344e68
--- /dev/null
@@ -0,0 +1,41 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+PVCUT=$(ver_cut 1-2)
+QTMIN=5.15.9
+inherit cmake frameworks.kde.org xdg-utils
+
+DESCRIPTION="Oxygen SVG icon theme"
+HOMEPAGE="https://develop.kde.org/frameworks/oxygen-icons/"
+
+LICENSE="LGPL-3"
+KEYWORDS="amd64 ~arm arm64 ~loong ~ppc ppc64 ~riscv x86"
+IUSE="test"
+
+RESTRICT="!test? ( test )"
+
+DEPEND="
+       test? (
+               >=dev-qt/qtcore-${QTMIN}:5
+               >=dev-qt/qttest-${QTMIN}:5
+       )
+"
+BDEPEND="
+       >=kde-frameworks/extra-cmake-modules-${PVCUT}:0
+       test? ( app-misc/fdupes )
+"
+
+src_prepare() {
+       cmake_src_prepare
+       use test || cmake_comment_add_subdirectory autotests
+}
+
+pkg_postinst() {
+       xdg_icon_cache_update
+}
+
+pkg_postrm() {
+       xdg_icon_cache_update
+}
diff --git a/kde-plasma/plasma-meta/Manifest b/kde-plasma/plasma-meta/Manifest
new file mode 100644 (file)
index 0000000..a96105b
--- /dev/null
@@ -0,0 +1 @@
+EBUILD plasma-meta-5.24.6-r1.ebuild 4098 BLAKE2B 6ec77d4a08752fcd86ae70e50659390ef7a5f5c82ae95a577b445107f7b029c3032c7e403dbd01af15dcc82fe47ef79d5c50f8704c261ec409c165727134c89d SHA512 a10f43d274f713a598ec7b3f6c29c0aea14de7a2f0af2798a4e1e646e08eefb8f5468d4e9005efcd468ff6701e5c18ce369a062253cd81e331be154cc6cee9e3
diff --git a/kde-plasma/plasma-meta/plasma-meta-5.24.6-r1.ebuild b/kde-plasma/plasma-meta/plasma-meta-5.24.6-r1.ebuild
new file mode 100644 (file)
index 0000000..e375167
--- /dev/null
@@ -0,0 +1,112 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DESCRIPTION="Merge this to pull in all Plasma 5 packages"
+HOMEPAGE="https://kde.org/plasma-desktop/"
+
+LICENSE="metapackage"
+SLOT="5"
+KEYWORDS="amd64 ~arm ~arm64 ~loong ~ppc64 ~riscv x86"
+IUSE="accessibility bluetooth +browser-integration colord +crash-handler crypt
++desktop-portal discover +display-manager +elogind +firewall grub gtk +handbook
++kwallet +legacy-systray +networkmanager plymouth pulseaudio +sddm sdk +smart
+systemd thunderbolt +wallpapers"
+
+#REQUIRED_USE="^^ ( elogind systemd )"
+
+RDEPEND="
+       >=kde-plasma/breeze-${PV}:${SLOT}
+       >=kde-plasma/kactivitymanagerd-${PV}:${SLOT}
+       >=kde-plasma/kde-cli-tools-${PV}:${SLOT}
+       >=kde-plasma/kdecoration-${PV}:${SLOT}
+       >=kde-plasma/kdeplasma-addons-${PV}:${SLOT}
+       >=kde-plasma/kgamma-${PV}:${SLOT}
+       >=kde-plasma/khotkeys-${PV}:${SLOT}
+       >=kde-plasma/kinfocenter-${PV}:${SLOT}
+       >=kde-plasma/kmenuedit-${PV}:${SLOT}
+       >=kde-plasma/kscreen-${PV}:${SLOT}
+       >=kde-plasma/kscreenlocker-${PV}:${SLOT}
+       >=kde-plasma/ksshaskpass-${PV}:${SLOT}
+       >=kde-plasma/ksystemstats-${PV}:${SLOT}
+       >=kde-plasma/kwayland-integration-${PV}:${SLOT}
+       >=kde-plasma/kwayland-server-${PV}:${SLOT}
+       >=kde-plasma/kwin-${PV}:${SLOT}
+       >=kde-plasma/kwrited-${PV}:${SLOT}
+       >=kde-plasma/layer-shell-qt-${PV}:${SLOT}
+       >=kde-plasma/libkscreen-${PV}:${SLOT}
+       >=kde-plasma/libksysguard-${PV}:${SLOT}
+       >=kde-plasma/milou-${PV}:${SLOT}
+       >=kde-plasma/oxygen-${PV}:${SLOT}
+       >=kde-plasma/plasma-desktop-${PV}:${SLOT}
+       >=kde-plasma/plasma-integration-${PV}:${SLOT}
+       >=kde-plasma/plasma-systemmonitor-${PV}:${SLOT}
+       >=kde-plasma/plasma-workspace-${PV}:${SLOT}
+       >=kde-plasma/powerdevil-${PV}:${SLOT}
+       >=kde-plasma/systemsettings-${PV}:${SLOT}
+       sys-apps/dbus[elogind?,systemd?]
+       sys-fs/udisks:2[elogind?,systemd?]
+       bluetooth? ( >=kde-plasma/bluedevil-${PV}:${SLOT} )
+       browser-integration? ( >=kde-plasma/plasma-browser-integration-${PV}:${SLOT} )
+       colord? ( x11-misc/colord )
+       crash-handler? ( >=kde-plasma/drkonqi-${PV}:${SLOT} )
+       crypt? ( >=kde-plasma/plasma-vault-${PV}:${SLOT} )
+       desktop-portal? ( >=kde-plasma/xdg-desktop-portal-kde-${PV}:${SLOT} )
+       discover? ( >=kde-plasma/discover-${PV}:${SLOT} )
+       display-manager? (
+               sddm? (
+                       >=kde-plasma/sddm-kcm-${PV}:${SLOT}
+                       x11-misc/sddm[elogind?,systemd?]
+               )
+               !sddm? ( x11-misc/lightdm )
+       )
+       elogind? ( sys-auth/elogind[pam] )
+       grub? ( >=kde-plasma/breeze-grub-${PV}:${SLOT} )
+       gtk? (
+               >=kde-plasma/breeze-gtk-${PV}:${SLOT}
+               >=kde-plasma/kde-gtk-config-${PV}:${SLOT}
+               x11-misc/appmenu-gtk-module
+       )
+       handbook? ( kde-apps/khelpcenter:5 )
+       kwallet? ( >=kde-plasma/kwallet-pam-${PV}:${SLOT} )
+       legacy-systray? ( >=kde-plasma/xembed-sni-proxy-${PV}:${SLOT} )
+       networkmanager? (
+               >=kde-plasma/plasma-nm-${PV}:${SLOT}
+               net-misc/networkmanager[elogind?,systemd?]
+       )
+       plymouth? (
+               >=kde-plasma/breeze-plymouth-${PV}:${SLOT}
+               >=kde-plasma/plymouth-kcm-${PV}:${SLOT}
+       )
+       pulseaudio? (
+               >=kde-plasma/plasma-pa-${PV}:${SLOT}
+               || (
+                       media-video/pipewire[sound-server(+)]
+                       media-sound/pulseaudio-daemon
+                       media-sound/pulseaudio[daemon(+)]
+               )
+       )
+       sdk? ( >=kde-plasma/plasma-sdk-${PV}:${SLOT} )
+       smart? ( >=kde-plasma/plasma-disks-${PV}:${SLOT} )
+       systemd? (
+               sys-apps/systemd[pam]
+               firewall? ( >=kde-plasma/plasma-firewall-${PV}:${SLOT} )
+       )
+       thunderbolt? ( >=kde-plasma/plasma-thunderbolt-${PV}:${SLOT} )
+       wallpapers? ( >=kde-plasma/plasma-workspace-wallpapers-${PV}:${SLOT} )
+"
+# Optional runtime deps: kde-plasma/plasma-desktop
+RDEPEND="${RDEPEND}
+       accessibility? ( app-accessibility/orca )
+"
+
+pkg_postinst() {
+       has_version sys-auth/consolekit || return
+       ewarn "An existing installation of sys-auth/consolekit was detected even though"
+       ewarn "${PN} was configured with USE $(usex elogind elogind systemd)."
+       ewarn "There can only be one session manager at runtime, otherwise random issues"
+       ewarn "may occur. Please make sure USE consolekit is nowhere enabled in make.conf"
+       ewarn "or package.use and remove sys-auth/consolekit before raising bugs."
+       ewarn "For more information, visit https://wiki.gentoo.org/wiki/KDE"
+}
diff --git a/kde-plasma/powerdevil/Manifest b/kde-plasma/powerdevil/Manifest
new file mode 100644 (file)
index 0000000..6572834
--- /dev/null
@@ -0,0 +1,2 @@
+DIST powerdevil-5.24.6.tar.xz 633104 BLAKE2B 6247c9327bbd72973844983e13d54166f3a38425b7c7024a1a8a1a138ed62e47641d203d929bd3f3e86e5f8bc1b23b9c46c2b2f418f68f01d2a6fb8adc2ef164 SHA512 b1a4c597b31706ec4749466018662443fea8a77c02f323066874df8d5cd5353a363f7ba8cc75301988e7a35afd9fbf654f24580e2254dec2f65d8c30dbeb4025
+EBUILD powerdevil-5.24.6.ebuild 1995 BLAKE2B e10ab5b4d778807de567b4c7c8beff7bb3f468789063ed58766569572bc736d1a0db1ce89f1067ec2315c0db6773ce4edfc8c01d3df042e57ce5d8259741b760 SHA512 25e9a58d42d5618ae73afdfc3cdee4aebaeccc11bd7fc8dab25d4d6dd0a5bfb7fdcd51df0c9f1b82ff7e1f0b44c3ac0d79bbbbcc6fa97e218dd70003beda482f
diff --git a/kde-plasma/powerdevil/powerdevil-5.24.6.ebuild b/kde-plasma/powerdevil/powerdevil-5.24.6.ebuild
new file mode 100644 (file)
index 0000000..507d336
--- /dev/null
@@ -0,0 +1,70 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+ECM_HANDBOOK="forceoptional"
+KFMIN=5.92.0
+PVCUT=$(ver_cut 1-3)
+QTMIN=5.15.4
+inherit ecm plasma.kde.org
+
+DESCRIPTION="Power management for KDE Plasma Shell"
+HOMEPAGE="https://invent.kde.org/plasma/powerdevil"
+
+LICENSE="GPL-2" # TODO: CHECK
+SLOT="5"
+KEYWORDS="amd64 ~arm ~arm64 ~loong ~ppc64 ~riscv x86"
+IUSE="brightness-control caps +wireless"
+
+DEPEND="
+       >=dev-qt/qtdbus-${QTMIN}:5
+       >=dev-qt/qtgui-${QTMIN}:5
+       >=dev-qt/qtwidgets-${QTMIN}:5
+       >=dev-qt/qtx11extras-${QTMIN}:5
+       >=kde-frameworks/kactivities-${KFMIN}:5
+       >=kde-frameworks/kauth-${KFMIN}:5
+       >=kde-frameworks/kcompletion-${KFMIN}:5
+       >=kde-frameworks/kconfig-${KFMIN}:5
+       >=kde-frameworks/kconfigwidgets-${KFMIN}:5
+       >=kde-frameworks/kcoreaddons-${KFMIN}:5
+       >=kde-frameworks/kcrash-${KFMIN}:5
+       >=kde-frameworks/kdbusaddons-${KFMIN}:5
+       >=kde-frameworks/kglobalaccel-${KFMIN}:5
+       >=kde-frameworks/ki18n-${KFMIN}:5
+       >=kde-frameworks/kidletime-${KFMIN}:5
+       >=kde-frameworks/kio-${KFMIN}:5
+       >=kde-frameworks/kirigami-${KFMIN}:5
+       >=kde-frameworks/knotifications-${KFMIN}:5
+       >=kde-frameworks/knotifyconfig-${KFMIN}:5
+       >=kde-frameworks/kservice-${KFMIN}:5
+       >=kde-frameworks/kwayland-${KFMIN}:5
+       >=kde-frameworks/kwidgetsaddons-${KFMIN}:5
+       >=kde-frameworks/kxmlgui-${KFMIN}:5
+       >=kde-frameworks/solid-${KFMIN}:5
+       >=kde-plasma/libkscreen-${PVCUT}:5
+       >=kde-plasma/libkworkspace-${PVCUT}:5
+       virtual/libudev:=
+       x11-libs/libxcb
+       brightness-control? ( app-misc/ddcutil:= )
+       caps? ( sys-libs/libcap )
+       wireless? (
+               >=kde-frameworks/bluez-qt-${KFMIN}:5
+               >=kde-frameworks/networkmanager-qt-${KFMIN}:5
+       )
+"
+RDEPEND="${DEPEND}
+       >=kde-plasma/kde-cli-tools-${PVCUT}:5
+       >=sys-power/upower-0.9.23
+"
+
+src_configure() {
+       local mycmakeargs=(
+               -DHAVE_DDCUTIL=$(usex brightness-control)
+               $(cmake_use_find_package caps Libcap)
+               $(cmake_use_find_package wireless KF5BluezQt)
+               $(cmake_use_find_package wireless KF5NetworkManagerQt)
+       )
+
+       ecm_src_configure
+}
diff --git a/layout.conf b/layout.conf
new file mode 100644 (file)
index 0000000..f8d67d2
--- /dev/null
@@ -0,0 +1,2 @@
+masters = gentoo
+#
diff --git a/lxde-base/lxsession-0.5.5-dir.tar.gz b/lxde-base/lxsession-0.5.5-dir.tar.gz
new file mode 100644 (file)
index 0000000..e9dadaf
Binary files /dev/null and b/lxde-base/lxsession-0.5.5-dir.tar.gz differ
diff --git a/lxde-base/lxsession.dir.tar.gz b/lxde-base/lxsession.dir.tar.gz
new file mode 100644 (file)
index 0000000..efef5d7
Binary files /dev/null and b/lxde-base/lxsession.dir.tar.gz differ
diff --git a/lxde-base/lxsession/Manifest b/lxde-base/lxsession/Manifest
new file mode 100644 (file)
index 0000000..2fd6401
--- /dev/null
@@ -0,0 +1,6 @@
+AUX lxsession-0.5.5-no-polkit-pt2.patch 48159 BLAKE2B 034f81abaa46fe7b2e332d8fcf44a22c5402aecc8440a5d12b40ea984d6d59d16c07373f9f32360f6a1c2f7370300c115594eb12af21c4892d7caf0b001ebc15 SHA512 f84cbd167ba4123a197b8936db5b460fe0c75ec6e6d1ecbabc4faed024f70bd7c3f422f2e11d1c8d7b25da6f569ac16a5877bc3f7f47d13e4bccf71179c67124
+AUX lxsession-0.5.5-no-polkit.patch 14475 BLAKE2B 08a8b4d6955856ddf8f23792ff8114fac42f1ece3b0260f54df1f5b85d60b6eefd2c42d01ca0702d774347b3a668d49fe3dd4f5f18e2c12434731d45ff5cb8af SHA512 36e0385dc5ef7b92de7ac8475914528a8f83a948e04663e8f3de6e6ea49bb04a96ba270c516f08824dfbe476ff14b244bfcb11695a302e901ae040da515fcb07
+AUX lxsession-0.5.5-notify-daemon-default.patch 775 BLAKE2B 0e98086d877481bd25d1bbdcfc762654524b7be1cfbd4b475053e425c09fc4c11ff6d75b8b49a9bdb9c59c1eb9fe6d5c034b10012865db8eda911b64a0ff4e57 SHA512 5d329e30c12b0e20c46d38c200de2f43ee6461828bfb0d229624c18626213458e2d6d7e389720bdbc86e27f12e7edc9ac2033508611cee171fb9e99e2bc14c1b
+AUX lxsession-0.5.5-reload.patch 1343 BLAKE2B f9498e50661b1261488b0504dc456ab99447740756b86e757c6fa31c5eb8ee84208b5ce5aafe2a0fb8795afd0f4c7a0aa729021d1eec3c83ee2825cac76651c6 SHA512 b5de54c295890fc3a06d465450630ec98b73599b00ad60ed9189f9983e0feaf6c9eaf1fa0cccf084aa2590f99f099e1f85576ba1d1cb53646abd9045d932976f
+DIST lxsession-0.5.5.tar.xz 422564 BLAKE2B 27910f84ecd8df8af06649235d33604eb83e8203f6a485a7450a91887de691d161acf8f51d8c1786f8d073966ba88d20296275adc131b9fa1c670c0f9e3ecdef SHA512 12e25214485cf855b380a5aa91eb536f31536c98f5a50a1115cb4bf8ff884c7cdcd40c69a1502eeb9f4d3e6169e0607d6488ef3152ee184662fee39fe7a04d54
+EBUILD lxsession-0.5.5-r1.ebuild 1309 BLAKE2B 867783c4249f446eb659eb85ad91860a194e8fe097affb01a55822b1256aee5a66cc60f9e01df42d00dcfb175f12e6c04279b14533c6d51b31aca412b7bbc4e9 SHA512 dc76403d4ac0fbc5533c25b14f77b8d12fb5e8e23ffceac8837e22a7b3ffc5a3e06546bdc2bead54686bb4bfaa351aaf4eb5ba596cb2f89ae16064d522113ee1
diff --git a/lxde-base/lxsession/files/lxsession-0.5.5-no-polkit-pt2.patch b/lxde-base/lxsession/files/lxsession-0.5.5-no-polkit-pt2.patch
new file mode 100644 (file)
index 0000000..2243a9a
--- /dev/null
@@ -0,0 +1,1096 @@
+diff -ur a/data/desktop.conf.example b/data/desktop.conf.example
+--- a/data/desktop.conf.example        2021-06-24 23:29:50.425230975 +0100
++++ b/data/desktop.conf.example        2021-06-24 23:58:30.490951701 +0100
+@@ -32,9 +32,6 @@
+ desktop_manager/command=
+ desktop_manager/wallpaper=
+-# Polkit agent (use lxpolkit to use build-in support if enable at build time)
+-polkit/command=lxpolkit
+-
+ # Network GUI manager (auto to try to guess the best choice)
+ network_gui/command=
+diff -ur a/data/lxpolkit.desktop b/data/lxpolkit.desktop
+--- a/data/lxpolkit.desktop    2021-06-24 23:29:50.425230975 +0100
++++ b/data/lxpolkit.desktop    2021-06-24 23:58:30.489951700 +0100
+@@ -1,36 +1,8 @@
+ [Desktop Entry]
+ Type=Application
+-Name=LXPolKit
+-Name[ca]=LXPolKit
+-Name[cs]=LXPolKit
+-Name[da]=LXPolKit
+-Name[el]=LXPolKit
+-Name[es]=LXPolKit
+-Name[et]=LXPolKit
+-Name[eu]=LXPolKit
+-Name[fi]=LXPolKit
+-Name[fr]=LXPolKit
+-Name[gl]=LXPolKit
+-Name[he]=LXPolKit
+-Name[id]=LXPolKit
+-Name[is]=LXPolKit
+-Name[ja]=LXpolkit
+-Name[kk]=LXPolKit
+-Name[ko]=LXPolKit
+-Name[lt]=LXPolKit
+-Name[nl]=LXPolKit
+-Name[pl]=Zestaw polityk LXPolKit
+-Name[pt]=LXPolKit
+-Name[pt_BR]=LXPolKit
+-Name[ru]=LXPolKit
+-Name[sk]=LXPolKit
+ Name[sr]=ЛИкс-Пол-Кит
+ Name[sr@latin]=LIks-Pol-Kit
+-Name[sv]=LXPolKit
+ Name[te]=ఎల్ఎక్స్‌పోల్‌కిట్
+-Name[tr]=LXPolKit
+-Name[uk]=LXPolKit
+-Name[zh_CN]=LXPolKit
+ Comment=Policykit Authentication Agent
+ Comment[ar]=وكيل الاستيثاق Policykit
+ Comment[ca]=Agent d'autenticació de Policykit
+@@ -63,8 +35,6 @@
+ Comment[uk]=Агент авторизації Policykit
+ Comment[zh_CN]=Policykit 认证代理
+ Comment[zh_TW]=Policykit 身分核對代理程式
+-Exec=lxpolkit
+-TryExec=lxpolkit
+ Icon=gtk-dialog-authentication
+ NotShowIn=GNOME;KDE;MATE;
+ Hidden=true
+diff -ur a/data/Makefile.am b/data/Makefile.am
+--- a/data/Makefile.am 2021-06-24 23:29:50.425230975 +0100
++++ b/data/Makefile.am 2021-06-24 23:58:30.489951700 +0100
+@@ -11,13 +11,11 @@
+       $(NULL)
+ desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+ autostartdir = $(sysconfdir)/xdg/autostart
+-autostart_in_files = lxpolkit.desktop.in
+ autostart_DATA = $(autostart_in_files:.desktop.in=.desktop)
+ @INTLTOOL_DESKTOP_RULE@
+ DISTCLEANFILES = \
+       lxsession-default-apps.desktop \
+       lxsession-edit.desktop \
+-      lxpolkit.desktop \
+       $(NULL)
+ imagedir=$(datadir)/lxsession/images
+diff -ur a/data/Makefile.in b/data/Makefile.in
+--- a/data/Makefile.in 2021-06-24 23:29:50.426230976 +0100
++++ b/data/Makefile.in 2021-06-24 23:58:30.490951701 +0100
+@@ -361,12 +361,10 @@
+ desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+ autostartdir = $(sysconfdir)/xdg/autostart
+-autostart_in_files = lxpolkit.desktop.in
+ autostart_DATA = $(autostart_in_files:.desktop.in=.desktop)
+ DISTCLEANFILES = \
+       lxsession-default-apps.desktop \
+       lxsession-edit.desktop \
+-      lxpolkit.desktop \
+       $(NULL)
+ imagedir = $(datadir)/lxsession/images
+diff -ur a/data/ui/lxsession-default-apps.ui b/data/ui/lxsession-default-apps.ui
+--- a/data/ui/lxsession-default-apps.ui        2021-06-24 23:29:50.425230975 +0100
++++ b/data/ui/lxsession-default-apps.ui        2021-06-24 23:58:30.489951700 +0100
+@@ -3411,7 +3411,7 @@
+                                 <property name="bottom_attach">7</property>
+                               </packing>
+                             </child>
+-                            <child>
++<!--                            <child>
+                               <object class="GtkLabel" id="polkit_label">
+                                 <property name="visible">True</property>
+                                 <property name="can_focus">False</property>
+@@ -3485,7 +3485,7 @@
+                                 <property name="bottom_attach">8</property>
+                               </packing>
+                             </child>
+-                            <child>
++                            <child>-->
+                               <object class="GtkLabel" id="network_gui_label">
+                                 <property name="visible">True</property>
+                                 <property name="can_focus">False</property>
+diff -ur a/data/ui/Makefile.am b/data/ui/Makefile.am
+--- a/data/ui/Makefile.am      2021-06-24 23:29:50.425230975 +0100
++++ b/data/ui/Makefile.am      2021-06-24 23:58:30.489951700 +0100
+@@ -3,7 +3,6 @@
+ # GtkBuilder UI definition files
+ uidir=$(datadir)/lxsession/ui
+ ui_DATA= \
+-      lxpolkit.ui \
+       lxsession-default-apps.ui \
+       lxsession-edit.ui \
+       $(NULL)
+diff -ur a/data/ui/Makefile.in b/data/ui/Makefile.in
+--- a/data/ui/Makefile.in      2021-06-24 23:29:50.425230975 +0100
++++ b/data/ui/Makefile.in      2021-06-24 23:58:30.489951700 +0100
+@@ -292,7 +292,6 @@
+ # GtkBuilder UI definition files
+ uidir = $(datadir)/lxsession/ui
+ ui_DATA = \
+-      lxpolkit.ui \
+       lxsession-default-apps.ui \
+       lxsession-edit.ui \
+       $(NULL)
+diff -ur a/lxsession/app.c b/lxsession/app.c
+--- a/lxsession/app.c  2021-06-24 23:29:50.428230979 +0100
++++ b/lxsession/app.c  2021-06-24 23:58:30.491951702 +0100
+@@ -187,17 +187,6 @@
+ typedef struct _LxsessionDesktopAppPrivate LxsessionDesktopAppPrivate;
+ #define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
+-#define LXSESSION_TYPE_POLKIT_APP (lxsession_polkit_app_get_type ())
+-#define LXSESSION_POLKIT_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LXSESSION_TYPE_POLKIT_APP, LxsessionPolkitApp))
+-#define LXSESSION_POLKIT_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LXSESSION_TYPE_POLKIT_APP, LxsessionPolkitAppClass))
+-#define LXSESSION_IS_POLKIT_APP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LXSESSION_TYPE_POLKIT_APP))
+-#define LXSESSION_IS_POLKIT_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LXSESSION_TYPE_POLKIT_APP))
+-#define LXSESSION_POLKIT_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LXSESSION_TYPE_POLKIT_APP, LxsessionPolkitAppClass))
+-
+-typedef struct _LxsessionPolkitApp LxsessionPolkitApp;
+-typedef struct _LxsessionPolkitAppClass LxsessionPolkitAppClass;
+-typedef struct _LxsessionPolkitAppPrivate LxsessionPolkitAppPrivate;
+-
+ #define LXSESSION_TYPE_NETWORK_GUI_APP (lxsession_network_gui_app_get_type ())
+ #define LXSESSION_NETWORK_GUI_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LXSESSION_TYPE_NETWORK_GUI_APP, LxsessionNetworkGuiApp))
+ #define LXSESSION_NETWORK_GUI_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LXSESSION_TYPE_NETWORK_GUI_APP, LxsessionNetworkGuiAppClass))
+@@ -540,19 +529,6 @@
+       gchar* desktop_wallpaper;
+ };
+-struct _LxsessionPolkitApp {
+-      LxsessionSimpleAppObject parent_instance;
+-      LxsessionPolkitAppPrivate * priv;
+-};
+-
+-struct _LxsessionPolkitAppClass {
+-      LxsessionSimpleAppObjectClass parent_class;
+-};
+-
+-struct _LxsessionPolkitAppPrivate {
+-      gchar* polkit_command;
+-};
+-
+ struct _LxsessionNetworkGuiApp {
+       LxsessionSimpleAppObject parent_instance;
+       LxsessionNetworkGuiAppPrivate * priv;
+@@ -786,7 +762,6 @@
+ static gpointer lxsession_file_manager_app_parent_class = NULL;
+ static gpointer lxsession_desktop_app_parent_class = NULL;
+ extern LxsessionFileManagerApp* lxsession_global_file_manager;
+-static gpointer lxsession_polkit_app_parent_class = NULL;
+ static gpointer lxsession_network_gui_app_parent_class = NULL;
+ static gpointer lxsession_audio_manager_app_parent_class = NULL;
+ static gpointer lxsession_quit_manager_app_parent_class = NULL;
+@@ -943,16 +918,7 @@
+ void lxsession_desktop_app_launch_settings (LxsessionDesktopApp* self);
+ static gchar** _vala_array_dup2 (gchar** self, int length);
+ static void lxsession_desktop_app_finalize (GObject* obj);
+-GType lxsession_polkit_app_get_type (void) G_GNUC_CONST;
+-#define LXSESSION_POLKIT_APP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LXSESSION_TYPE_POLKIT_APP, LxsessionPolkitAppPrivate))
+-enum  {
+-      LXSESSION_POLKIT_APP_DUMMY_PROPERTY
+-};
+-LxsessionPolkitApp* lxsession_polkit_app_new (void);
+-LxsessionPolkitApp* lxsession_polkit_app_construct (GType object_type);
+-static void lxsession_polkit_app_real_read_settings (LxsessionAppObject* base);
+-void lxsession_polkit_app_deactivate (LxsessionPolkitApp* self);
+-static void lxsession_polkit_app_finalize (GObject* obj);
++
+ GType lxsession_network_gui_app_get_type (void) G_GNUC_CONST;
+ #define LXSESSION_NETWORK_GUI_APP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LXSESSION_TYPE_NETWORK_GUI_APP, LxsessionNetworkGuiAppPrivate))
+ enum  {
+@@ -3729,154 +3695,6 @@
+       return lxsession_desktop_app_type_id__volatile;
+ }
+-
+-LxsessionPolkitApp* lxsession_polkit_app_construct (GType object_type) {
+-      LxsessionPolkitApp * self = NULL;
+-      self = (LxsessionPolkitApp*) lxsession_simple_app_object_construct (object_type);
+-      lxsession_app_object_init ((LxsessionAppObject*) self);
+-      return self;
+-}
+-
+-
+-LxsessionPolkitApp* lxsession_polkit_app_new (void) {
+-      return lxsession_polkit_app_construct (LXSESSION_TYPE_POLKIT_APP);
+-}
+-
+-
+-static void lxsession_polkit_app_real_read_settings (LxsessionAppObject* base) {
+-      LxsessionPolkitApp * self;
+-      LxsessionLxsessionConfigKeyFile* _tmp0_ = NULL;
+-      gchar* _tmp1_ = NULL;
+-      const gchar* _tmp2_ = NULL;
+-      const gchar* _tmp3_ = NULL;
+-      GQuark _tmp5_ = 0U;
+-      static GQuark _tmp4_label0 = 0;
+-      static GQuark _tmp4_label1 = 0;
+-      static GQuark _tmp4_label2 = 0;
+-      self = (LxsessionPolkitApp*) base;
+-      _tmp0_ = lxsession_global_settings;
+-      _tmp1_ = lxsession_lxsession_config_get_item_string ((LxsessionLxsessionConfig*) _tmp0_, "Session", "polkit", "command");
+-      _g_free0 (self->priv->polkit_command);
+-      self->priv->polkit_command = _tmp1_;
+-      _tmp2_ = self->priv->polkit_command;
+-      _tmp3_ = _tmp2_;
+-      _tmp5_ = (NULL == _tmp3_) ? 0 : g_quark_from_string (_tmp3_);
+-      if (_tmp5_ == ((0 != _tmp4_label0) ? _tmp4_label0 : (_tmp4_label0 = g_quark_from_static_string ("gnome")))) {
+-              switch (0) {
+-                      default:
+-                      {
+-                              gchar* create_command = NULL;
+-                              gchar* _tmp6_ = NULL;
+-                              const gchar* _tmp7_ = NULL;
+-                              gchar** _tmp8_ = NULL;
+-                              gchar** _tmp9_ = NULL;
+-                              gchar** _tmp10_ = NULL;
+-                              gint _tmp10__length1 = 0;
+-                              lxsession_app_object_set_name ((LxsessionAppObject*) self, "polkit-gnome-authentication-agent-1");
+-                              _tmp6_ = g_strdup ("/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1");
+-                              create_command = _tmp6_;
+-                              _tmp7_ = create_command;
+-                              _tmp9_ = _tmp8_ = g_strsplit_set (_tmp7_, " ", 0);
+-                              _tmp10_ = _tmp9_;
+-                              _tmp10__length1 = _vala_array_length (_tmp8_);
+-                              lxsession_app_object_set_command ((LxsessionAppObject*) self, _tmp10_, _vala_array_length (_tmp8_));
+-                              _tmp10_ = (_vala_array_free (_tmp10_, _tmp10__length1, (GDestroyNotify) g_free), NULL);
+-                              _g_free0 (create_command);
+-                              break;
+-                      }
+-              }
+-      } else if (_tmp5_ == ((0 != _tmp4_label1) ? _tmp4_label1 : (_tmp4_label1 = g_quark_from_static_string ("razorqt")))) {
+-              switch (0) {
+-                      default:
+-                      {
+-                              gchar* create_command = NULL;
+-                              gchar* _tmp11_ = NULL;
+-                              const gchar* _tmp12_ = NULL;
+-                              gchar** _tmp13_ = NULL;
+-                              gchar** _tmp14_ = NULL;
+-                              gchar** _tmp15_ = NULL;
+-                              gint _tmp15__length1 = 0;
+-                              lxsession_app_object_set_name ((LxsessionAppObject*) self, "razor-policykit-agent");
+-                              _tmp11_ = g_strdup ("/usr/bin/razor-policykit-agent");
+-                              create_command = _tmp11_;
+-                              _tmp12_ = create_command;
+-                              _tmp14_ = _tmp13_ = g_strsplit_set (_tmp12_, " ", 0);
+-                              _tmp15_ = _tmp14_;
+-                              _tmp15__length1 = _vala_array_length (_tmp13_);
+-                              lxsession_app_object_set_command ((LxsessionAppObject*) self, _tmp15_, _vala_array_length (_tmp13_));
+-                              _tmp15_ = (_vala_array_free (_tmp15_, _tmp15__length1, (GDestroyNotify) g_free), NULL);
+-                              _g_free0 (create_command);
+-                              break;
+-                      }
+-              }
+-      } else if (_tmp5_ == ((0 != _tmp4_label2) ? _tmp4_label2 : (_tmp4_label2 = g_quark_from_static_string ("lxpolkit")))) {
+-              switch (0) {
+-                      default:
+-                      {
+-                              gchar* create_command = NULL;
+-                              gchar* _tmp16_ = NULL;
+-                              const gchar* _tmp17_ = NULL;
+-                              gchar** _tmp18_ = NULL;
+-                              gchar** _tmp19_ = NULL;
+-                              gchar** _tmp20_ = NULL;
+-                              gint _tmp20__length1 = 0;
+-                              g_message ("app.vala:721: polkit separate");
+-                              lxsession_app_object_set_name ((LxsessionAppObject*) self, "lxpolkit");
+-                              _tmp16_ = g_strdup ("lxpolkit");
+-                              create_command = _tmp16_;
+-                              _tmp17_ = create_command;
+-                              _tmp19_ = _tmp18_ = g_strsplit_set (_tmp17_, " ", 0);
+-                              _tmp20_ = _tmp19_;
+-                              _tmp20__length1 = _vala_array_length (_tmp18_);
+-                              lxsession_app_object_set_command ((LxsessionAppObject*) self, _tmp20_, _vala_array_length (_tmp18_));
+-                              _tmp20_ = (_vala_array_free (_tmp20_, _tmp20__length1, (GDestroyNotify) g_free), NULL);
+-                              _g_free0 (create_command);
+-                              break;
+-                      }
+-              }
+-      }
+-      lxsession_app_object_set_guard ((LxsessionAppObject*) self, TRUE);
+-}
+-
+-
+-void lxsession_polkit_app_deactivate (LxsessionPolkitApp* self) {
+-      g_return_if_fail (self != NULL);
+-}
+-
+-
+-static void lxsession_polkit_app_class_init (LxsessionPolkitAppClass * klass) {
+-      lxsession_polkit_app_parent_class = g_type_class_peek_parent (klass);
+-      g_type_class_add_private (klass, sizeof (LxsessionPolkitAppPrivate));
+-      ((LxsessionAppObjectClass *) klass)->read_settings = (void (*)(LxsessionAppObject*)) lxsession_polkit_app_real_read_settings;
+-      G_OBJECT_CLASS (klass)->finalize = lxsession_polkit_app_finalize;
+-}
+-
+-
+-static void lxsession_polkit_app_instance_init (LxsessionPolkitApp * self) {
+-      self->priv = LXSESSION_POLKIT_APP_GET_PRIVATE (self);
+-}
+-
+-
+-static void lxsession_polkit_app_finalize (GObject* obj) {
+-      LxsessionPolkitApp * self;
+-      self = G_TYPE_CHECK_INSTANCE_CAST (obj, LXSESSION_TYPE_POLKIT_APP, LxsessionPolkitApp);
+-      _g_free0 (self->priv->polkit_command);
+-      G_OBJECT_CLASS (lxsession_polkit_app_parent_class)->finalize (obj);
+-}
+-
+-
+-GType lxsession_polkit_app_get_type (void) {
+-      static volatile gsize lxsession_polkit_app_type_id__volatile = 0;
+-      if (g_once_init_enter (&lxsession_polkit_app_type_id__volatile)) {
+-              static const GTypeInfo g_define_type_info = { sizeof (LxsessionPolkitAppClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) lxsession_polkit_app_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (LxsessionPolkitApp), 0, (GInstanceInitFunc) lxsession_polkit_app_instance_init, NULL };
+-              GType lxsession_polkit_app_type_id;
+-              lxsession_polkit_app_type_id = g_type_register_static (LXSESSION_TYPE_SIMPLE_APP_OBJECT, "LxsessionPolkitApp", &g_define_type_info, 0);
+-              g_once_init_leave (&lxsession_polkit_app_type_id__volatile, lxsession_polkit_app_type_id);
+-      }
+-      return lxsession_polkit_app_type_id__volatile;
+-}
+-
+-
+ LxsessionNetworkGuiApp* lxsession_network_gui_app_construct (GType object_type) {
+       LxsessionNetworkGuiApp * self = NULL;
+       self = (LxsessionNetworkGuiApp*) lxsession_simple_app_object_construct (object_type);
+diff -ur a/lxsession/app.vala b/lxsession/app.vala
+--- a/lxsession/app.vala       2021-06-24 23:29:50.428230979 +0100
++++ b/lxsession/app.vala       2021-06-24 23:58:30.492951704 +0100
+@@ -692,56 +692,6 @@
+ }
+-public class PolkitApp: SimpleAppObject
+-{
+-    string polkit_command;
+-
+-    public PolkitApp ()
+-    {
+-        init();
+-    }
+-
+-    public override void read_settings()
+-    {
+-        polkit_command = global_settings.get_item_string("Session", "polkit", "command");
+-
+-        switch (polkit_command) 
+-        {
+-            case "gnome":
+-                this.name = "polkit-gnome-authentication-agent-1";
+-                string create_command = "/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1";
+-                this.command = create_command.split_set(" ",0);
+-                break;
+-            case "razorqt":
+-                this.name = "razor-policykit-agent";
+-                string create_command = "/usr/bin/razor-policykit-agent";
+-                this.command = create_command.split_set(" ",0);
+-                break;
+-            case "lxpolkit":
+-                message("polkit separate");
+-                this.name = "lxpolkit";
+-                string create_command = "lxpolkit";
+-                this.command = create_command.split_set(" ",0);
+-                break;
+-        }
+-        this.guard = true;
+-
+-    }
+-
+-#if BUILDIN_POLKIT
+-    public new void launch ()
+-    {
+-        policykit_agent_init();
+-    }
+-#endif
+-
+-    public void deactivate ()
+-    {
+-#if BUILDIN_POLKIT
+-        policykit_agent_finalize();
+-#endif
+-    }
+-}
+ public class NetworkGuiApp: SimpleAppObject
+ {
+diff -ur a/lxsession/dbus-lxde-session.c b/lxsession/dbus-lxde-session.c
+--- a/lxsession/dbus-lxde-session.c    2021-06-24 23:29:50.428230979 +0100
++++ b/lxsession/dbus-lxde-session.c    2021-06-24 23:58:30.491951702 +0100
+@@ -332,16 +332,6 @@
+ typedef struct _LxsessionPowerManagerApp LxsessionPowerManagerApp;
+ typedef struct _LxsessionPowerManagerAppClass LxsessionPowerManagerAppClass;
+-#define LXSESSION_TYPE_POLKIT_APP (lxsession_polkit_app_get_type ())
+-#define LXSESSION_POLKIT_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LXSESSION_TYPE_POLKIT_APP, LxsessionPolkitApp))
+-#define LXSESSION_POLKIT_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LXSESSION_TYPE_POLKIT_APP, LxsessionPolkitAppClass))
+-#define LXSESSION_IS_POLKIT_APP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LXSESSION_TYPE_POLKIT_APP))
+-#define LXSESSION_IS_POLKIT_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LXSESSION_TYPE_POLKIT_APP))
+-#define LXSESSION_POLKIT_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LXSESSION_TYPE_POLKIT_APP, LxsessionPolkitAppClass))
+-
+-typedef struct _LxsessionPolkitApp LxsessionPolkitApp;
+-typedef struct _LxsessionPolkitAppClass LxsessionPolkitAppClass;
+-
+ #define LXSESSION_TYPE_NETWORK_GUI_APP (lxsession_network_gui_app_get_type ())
+ #define LXSESSION_NETWORK_GUI_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LXSESSION_TYPE_NETWORK_GUI_APP, LxsessionNetworkGuiApp))
+ #define LXSESSION_NETWORK_GUI_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LXSESSION_TYPE_NETWORK_GUI_APP, LxsessionNetworkGuiAppClass))
+@@ -439,7 +429,6 @@
+ extern LxsessionDesktopApp* lxsession_global_desktop;
+ extern LxsessionScreensaverApp* lxsession_global_screensaver;
+ extern LxsessionPowerManagerApp* lxsession_global_power_manager;
+-extern LxsessionPolkitApp* lxsession_global_polkit;
+ extern LxsessionNetworkGuiApp* lxsession_global_network_gui;
+ extern LxsessionGenericSimpleApp* lxsession_global_message_manager;
+ extern LxsessionClipboardOption* lxsession_global_clipboard;
+@@ -526,7 +515,6 @@
+ static void lxsession_lxde_session_server_DesktopReload (LxsessionLxdeSessionServer* self);
+ static void lxsession_lxde_session_server_ScreensaverReload (LxsessionLxdeSessionServer* self);
+ static void lxsession_lxde_session_server_PowerManagerReload (LxsessionLxdeSessionServer* self);
+-static void lxsession_lxde_session_server_PolkitReload (LxsessionLxdeSessionServer* self);
+ static void lxsession_lxde_session_server_NetworkGuiReload (LxsessionLxdeSessionServer* self);
+ static void lxsession_lxde_session_server_MessageManagerLaunch (LxsessionLxdeSessionServer* self);
+ static void lxsession_lxde_session_server_ClipboardActivate (LxsessionLxdeSessionServer* self);
+@@ -619,9 +607,6 @@
+ GType lxsession_power_manager_app_get_type (void) G_GNUC_CONST;
+ LxsessionPowerManagerApp* lxsession_power_manager_app_new (void);
+ LxsessionPowerManagerApp* lxsession_power_manager_app_construct (GType object_type);
+-GType lxsession_polkit_app_get_type (void) G_GNUC_CONST;
+-LxsessionPolkitApp* lxsession_polkit_app_new (void);
+-LxsessionPolkitApp* lxsession_polkit_app_construct (GType object_type);
+ GType lxsession_network_gui_app_get_type (void) G_GNUC_CONST;
+ LxsessionNetworkGuiApp* lxsession_network_gui_app_new (void);
+ LxsessionNetworkGuiApp* lxsession_network_gui_app_construct (GType object_type);
+@@ -2022,14 +2007,6 @@
+                                       break;
+                               }
+                       }
+-              } else if (_tmp8_ == ((0 != _tmp7_label14) ? _tmp7_label14 : (_tmp7_label14 = g_quark_from_static_string ("polkit")))) {
+-                      switch (0) {
+-                              default:
+-                              {
+-                                      lxsession_lxde_session_server_PolkitReload (self);
+-                                      break;
+-                              }
+-                      }
+               } else if (_tmp8_ == ((0 != _tmp7_label15) ? _tmp7_label15 : (_tmp7_label15 = g_quark_from_static_string ("network_gui")))) {
+                       switch (0) {
+                               default:
+@@ -3333,48 +3310,6 @@
+ }
+-static void lxsession_lxde_session_server_PolkitReload (LxsessionLxdeSessionServer* self) {
+-      LxsessionLxsessionConfigKeyFile* _tmp0_ = NULL;
+-      gchar* _tmp1_ = NULL;
+-      gchar* _tmp2_ = NULL;
+-      gboolean _tmp3_ = FALSE;
+-      g_return_if_fail (self != NULL);
+-      g_message ("dbus-lxde-session.vala:1044: Reload polkit");
+-      _tmp0_ = lxsession_global_settings;
+-      _tmp1_ = lxsession_lxsession_config_get_item_string ((LxsessionLxsessionConfig*) _tmp0_, "Session", "polkit", "command");
+-      _tmp2_ = _tmp1_;
+-      _tmp3_ = _tmp2_ == NULL;
+-      _g_free0 (_tmp2_);
+-      if (_tmp3_) {
+-              g_warning ("dbus-lxde-session.vala:1047: Polkit command not set");
+-      } else {
+-              LxsessionPolkitApp* _tmp4_ = NULL;
+-              _tmp4_ = lxsession_global_polkit;
+-              if (_tmp4_ == NULL) {
+-                      LxsessionPolkitApp* polkit = NULL;
+-                      LxsessionPolkitApp* _tmp5_ = NULL;
+-                      LxsessionPolkitApp* _tmp6_ = NULL;
+-                      LxsessionPolkitApp* _tmp7_ = NULL;
+-                      LxsessionPolkitApp* _tmp8_ = NULL;
+-                      g_message ("dbus-lxde-session.vala:1051: Polkit doesn't exist, creating it");
+-                      _tmp5_ = lxsession_polkit_app_new ();
+-                      polkit = _tmp5_;
+-                      _tmp6_ = polkit;
+-                      _tmp7_ = _g_object_ref0 (_tmp6_);
+-                      _g_object_unref0 (lxsession_global_polkit);
+-                      lxsession_global_polkit = _tmp7_;
+-                      _tmp8_ = lxsession_global_polkit;
+-                      lxsession_app_object_launch ((LxsessionAppObject*) _tmp8_);
+-                      _g_object_unref0 (polkit);
+-              } else {
+-                      LxsessionPolkitApp* _tmp9_ = NULL;
+-                      g_message ("dbus-lxde-session.vala:1058: Reload existing polkit");
+-                      _tmp9_ = lxsession_global_polkit;
+-                      lxsession_app_object_reload ((LxsessionAppObject*) _tmp9_);
+-              }
+-      }
+-}
+-
+ static void lxsession_lxde_session_server_NetworkGuiReload (LxsessionLxdeSessionServer* self) {
+       LxsessionLxsessionConfigKeyFile* _tmp0_ = NULL;
+diff -ur a/lxsession/dbus-lxde-session.vala b/lxsession/dbus-lxde-session.vala
+--- a/lxsession/dbus-lxde-session.vala 2021-06-24 23:29:50.428230979 +0100
++++ b/lxsession/dbus-lxde-session.vala 2021-06-24 23:58:30.491951702 +0100
+@@ -393,10 +393,6 @@
+                         PowerManagerReload();
+                         break;
+-                    case "polkit":
+-                        PolkitReload();
+-                        break;
+-
+                     case "network_gui":
+                         NetworkGuiReload();
+                         break;
+@@ -1038,28 +1034,6 @@
+             }
+         }
+-        /* Polkit */
+-        private void PolkitReload()
+-        {
+-            message("Reload polkit");
+-            if (global_settings.get_item_string("Session", "polkit", "command") == null)
+-            {
+-                warning("Polkit command not set");
+-            }
+-            else if (global_polkit == null)
+-            {
+-                message("Polkit doesn't exist, creating it");
+-                var polkit = new PolkitApp();
+-                global_polkit = polkit;
+-                global_polkit.launch();
+-            }
+-            else
+-            {
+-                message("Reload existing polkit");
+-                global_polkit.reload();
+-            }
+-        }
+-
+         /* Network GUI */
+         private void NetworkGuiReload()
+         {
+diff -ur a/lxsession/main.c b/lxsession/main.c
+--- a/lxsession/main.c 2021-06-24 23:29:50.428230979 +0100
++++ b/lxsession/main.c 2021-06-24 23:58:30.492951704 +0100
+@@ -133,16 +133,6 @@
+ typedef struct _LxsessionDesktopApp LxsessionDesktopApp;
+ typedef struct _LxsessionDesktopAppClass LxsessionDesktopAppClass;
+-#define LXSESSION_TYPE_POLKIT_APP (lxsession_polkit_app_get_type ())
+-#define LXSESSION_POLKIT_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LXSESSION_TYPE_POLKIT_APP, LxsessionPolkitApp))
+-#define LXSESSION_POLKIT_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LXSESSION_TYPE_POLKIT_APP, LxsessionPolkitAppClass))
+-#define LXSESSION_IS_POLKIT_APP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LXSESSION_TYPE_POLKIT_APP))
+-#define LXSESSION_IS_POLKIT_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LXSESSION_TYPE_POLKIT_APP))
+-#define LXSESSION_POLKIT_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LXSESSION_TYPE_POLKIT_APP, LxsessionPolkitAppClass))
+-
+-typedef struct _LxsessionPolkitApp LxsessionPolkitApp;
+-typedef struct _LxsessionPolkitAppClass LxsessionPolkitAppClass;
+-
+ #define LXSESSION_TYPE_SCREENSAVER_APP (lxsession_screensaver_app_get_type ())
+ #define LXSESSION_SCREENSAVER_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LXSESSION_TYPE_SCREENSAVER_APP, LxsessionScreensaverApp))
+ #define LXSESSION_SCREENSAVER_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LXSESSION_TYPE_SCREENSAVER_APP, LxsessionScreensaverAppClass))
+@@ -433,8 +423,6 @@
+ LxsessionFileManagerApp* lxsession_global_file_manager = NULL;
+ extern LxsessionDesktopApp* lxsession_global_desktop;
+ LxsessionDesktopApp* lxsession_global_desktop = NULL;
+-extern LxsessionPolkitApp* lxsession_global_polkit;
+-LxsessionPolkitApp* lxsession_global_polkit = NULL;
+ extern LxsessionScreensaverApp* lxsession_global_screensaver;
+ LxsessionScreensaverApp* lxsession_global_screensaver = NULL;
+ extern LxsessionPowerManagerApp* lxsession_global_power_manager;
+@@ -515,7 +503,6 @@
+ GType lxsession_windows_manager_app_get_type (void) G_GNUC_CONST;
+ GType lxsession_file_manager_app_get_type (void) G_GNUC_CONST;
+ GType lxsession_desktop_app_get_type (void) G_GNUC_CONST;
+-GType lxsession_polkit_app_get_type (void) G_GNUC_CONST;
+ GType lxsession_screensaver_app_get_type (void) G_GNUC_CONST;
+ GType lxsession_power_manager_app_get_type (void) G_GNUC_CONST;
+ GType lxsession_network_gui_app_get_type (void) G_GNUC_CONST;
+@@ -584,8 +571,6 @@
+ LxsessionDesktopApp* lxsession_desktop_app_construct (GType object_type);
+ LxsessionGenericSimpleApp* lxsession_generic_simple_app_new (const gchar* argument);
+ LxsessionGenericSimpleApp* lxsession_generic_simple_app_construct (GType object_type, const gchar* argument);
+-LxsessionPolkitApp* lxsession_polkit_app_new (void);
+-LxsessionPolkitApp* lxsession_polkit_app_construct (GType object_type);
+ LxsessionLauncherManagerApp* lxsession_launcher_manager_app_new (void);
+ LxsessionLauncherManagerApp* lxsession_launcher_manager_app_construct (GType object_type);
+ void lxsession_launcher_manager_app_autostart_launch (LxsessionLauncherManagerApp* self);
+@@ -627,7 +612,6 @@
+ static void ___lambda18_ (void);
+ static void ____lambda18__gbus_name_lost_callback (GDBusConnection* connection, const gchar* name, gpointer self);
+ void lxsession_clipboard_option_desactivate (LxsessionClipboardOption* self);
+-void lxsession_polkit_app_deactivate (LxsessionPolkitApp* self);
+ void lxsession_app_object_stop (LxsessionAppObject* self);
+ LxsessionMain* lxsession_main_new (void);
+ LxsessionMain* lxsession_main_construct (GType object_type);
+@@ -800,7 +784,6 @@
+       LxsessionDockApp* _tmp403_ = NULL;
+       LxsessionWindowsManagerApp* _tmp405_ = NULL;
+       LxsessionDesktopApp* _tmp407_ = NULL;
+-      LxsessionPolkitApp* _tmp409_ = NULL;
+       LxsessionScreensaverApp* _tmp411_ = NULL;
+       LxsessionPowerManagerApp* _tmp413_ = NULL;
+       LxsessionNetworkGuiApp* _tmp415_ = NULL;
+@@ -1418,27 +1401,6 @@
+                               _g_object_unref0 (compositemanager);
+                       }
+               }
+-              _tmp182_ = lxsession_global_settings;
+-              _tmp183_ = lxsession_lxsession_config_get_item_string ((LxsessionLxsessionConfig*) _tmp182_, "Session", "polkit", "command");
+-              _tmp184_ = _tmp183_;
+-              _tmp185_ = _tmp184_ != NULL;
+-              _g_free0 (_tmp184_);
+-              if (_tmp185_) {
+-                      LxsessionPolkitApp* securitypolkit = NULL;
+-                      LxsessionPolkitApp* _tmp186_ = NULL;
+-                      LxsessionPolkitApp* _tmp187_ = NULL;
+-                      LxsessionPolkitApp* _tmp188_ = NULL;
+-                      LxsessionPolkitApp* _tmp189_ = NULL;
+-                      _tmp186_ = lxsession_polkit_app_new ();
+-                      securitypolkit = _tmp186_;
+-                      _tmp187_ = securitypolkit;
+-                      _tmp188_ = _g_object_ref0 (_tmp187_);
+-                      _g_object_unref0 (lxsession_global_polkit);
+-                      lxsession_global_polkit = _tmp188_;
+-                      _tmp189_ = lxsession_global_polkit;
+-                      lxsession_app_object_launch ((LxsessionAppObject*) _tmp189_);
+-                      _g_object_unref0 (securitypolkit);
+-              }
+               _tmp190_ = lxsession_global_settings;
+               _tmp191_ = lxsession_lxsession_config_get_item_string ((LxsessionLxsessionConfig*) _tmp190_, "Session", "launcher_manager", "autostart");
+               _tmp192_ = _tmp191_;
+@@ -1963,18 +1925,6 @@
+               lxsession_clipboard_option_desactivate (_tmp394_);
+       }
+       _tmp395_ = lxsession_global_settings;
+-      _tmp396_ = lxsession_lxsession_config_get_item_string ((LxsessionLxsessionConfig*) _tmp395_, "Session", "polkit", "command");
+-      _tmp397_ = _tmp396_;
+-      _tmp398_ = _tmp397_ != NULL;
+-      _g_free0 (_tmp397_);
+-      if (_tmp398_) {
+-              LxsessionPolkitApp* _tmp399_ = NULL;
+-              LxsessionPolkitApp* _tmp400_ = NULL;
+-              _tmp399_ = lxsession_global_polkit;
+-              lxsession_polkit_app_deactivate (_tmp399_);
+-              _tmp400_ = lxsession_global_polkit;
+-              lxsession_app_object_stop ((LxsessionAppObject*) _tmp400_);
+-      }
+       _tmp401_ = lxsession_global_panel;
+       if (_tmp401_ != NULL) {
+               LxsessionPanelApp* _tmp402_ = NULL;
+@@ -1999,12 +1949,6 @@
+               _tmp408_ = lxsession_global_desktop;
+               lxsession_app_object_stop ((LxsessionAppObject*) _tmp408_);
+       }
+-      _tmp409_ = lxsession_global_polkit;
+-      if (_tmp409_ != NULL) {
+-              LxsessionPolkitApp* _tmp410_ = NULL;
+-              _tmp410_ = lxsession_global_polkit;
+-              lxsession_app_object_stop ((LxsessionAppObject*) _tmp410_);
+-      }
+       _tmp411_ = lxsession_global_screensaver;
+       if (_tmp411_ != NULL) {
+               LxsessionScreensaverApp* _tmp412_ = NULL;
+diff -ur a/lxsession/main.vala b/lxsession/main.vala
+--- a/lxsession/main.vala      2021-06-24 23:29:50.428230979 +0100
++++ b/lxsession/main.vala      2021-06-24 23:58:30.492951704 +0100
+@@ -36,7 +36,6 @@
+     WindowsManagerApp global_windows_manager;
+     FileManagerApp global_file_manager;
+     DesktopApp global_desktop;
+-    PolkitApp global_polkit;
+     ScreensaverApp global_screensaver;
+     PowerManagerApp global_power_manager;
+     NetworkGuiApp global_network_gui;
+@@ -347,15 +346,6 @@
+                 }
+             }
+-            if (global_settings.get_item_string("Session", "polkit", "command") != null)
+-            {
+-                var securitypolkit = new PolkitApp();
+-                global_polkit = securitypolkit;
+-                global_polkit.launch();
+-            }
+-
+-
+-
+             if (global_settings.get_item_string("Session", "launcher_manager", "autostart") == "true")
+             {
+                 if (global_settings.get_item_string("Session", "launcher_manager", "command") != null)
+@@ -536,12 +526,6 @@
+             global_clipboard.desactivate();
+         }
+-        if (global_settings.get_item_string("Session", "polkit", "command") != null)
+-        {
+-            global_polkit.deactivate();
+-            global_polkit.stop();
+-        }
+-
+         if (global_panel != null)
+         {
+             global_panel.stop();
+@@ -562,11 +546,6 @@
+             global_desktop.stop();
+         }
+-        if (global_polkit != null)
+-        {
+-            global_polkit.stop();
+-        }
+-
+         if (global_screensaver != null)
+         {
+             global_screensaver.stop();
+diff -ur a/lxsession/settings.c b/lxsession/settings.c
+--- a/lxsession/settings.c     2021-06-24 23:29:50.428230979 +0100
++++ b/lxsession/settings.c     2021-06-24 23:58:30.492951704 +0100
+@@ -1121,7 +1121,6 @@
+               lxsession_lxsession_config_set_generic_default (self, "Session", "windows_manager", "session", "string", "LXDE");
+       }
+       lxsession_lxsession_config_set_generic_default (self, "Session", "disable_autostart", NULL, "string", "no");
+-      lxsession_lxsession_config_set_generic_default (self, "Session", "polkit", "command", "string", "lxpolkit");
+       lxsession_lxsession_config_set_generic_default (self, "Session", "clipboard", "command", "string", "lxclipboard");
+       lxsession_lxsession_config_set_generic_default (self, "Session", "xsettings_manager", "command", "string", "build-in");
+       lxsession_lxsession_config_set_generic_default (self, "Session", "proxy_manager", "command", "string", "build-in");
+@@ -2720,8 +2719,6 @@
+       lxsession_lxsession_config_key_file_read_key_value (self, _tmp87_, "Session", "screensaver", "command", "string");
+       _tmp88_ = self->kf;
+       lxsession_lxsession_config_key_file_read_key_value (self, _tmp88_, "Session", "power_manager", "command", "string");
+-      _tmp89_ = self->kf;
+-      lxsession_lxsession_config_key_file_read_key_value (self, _tmp89_, "Session", "polkit", "command", "string");
+       _tmp90_ = self->kf;
+       lxsession_lxsession_config_key_file_read_key_value (self, _tmp90_, "Session", "audio_manager", "command", "string");
+       _tmp91_ = self->kf;
+@@ -4025,10 +4022,6 @@
+       if (_tmp8_) {
+               lxsession_lxsession_config_set_config_item_value ((LxsessionLxsessionConfig*) self, "Session", "launcher_manager", "autostart", "string", "true");
+       }
+-      _tmp9_ = ((LxsessionLxsessionConfigKeyFile*) self)->kf;
+-      lxsession_razor_qt_config_key_file_read_razor_key_value (self, _tmp9_, "Session", "polkit", "command", "string", "modules", "razor-policykit-agent", NULL);
+-      _tmp10_ = self->session_razor_config_path;
+-      _tmp11_ = lxsession_load_keyfile (_tmp10_);
+       _g_key_file_unref0 (self->kf_conf);
+       self->kf_conf = _tmp11_;
+       _tmp12_ = self->kf_conf;
+@@ -4258,10 +4251,6 @@
+               _tmp21_ = self->kf_session;
+               g_key_file_set_value (_tmp21_, "modules", "razor-runner", "false");
+       }
+-      _tmp22_ = lxsession_lxsession_config_get_item_string ((LxsessionLxsessionConfig*) self, "Session", "polkit", "command");
+-      _tmp23_ = _tmp22_;
+-      _tmp24_ = g_strcmp0 (_tmp23_, "razor-policykit-agent") == 0;
+-      _g_free0 (_tmp23_);
+       if (_tmp24_) {
+               GKeyFile* _tmp25_ = NULL;
+               _tmp25_ = self->kf_session;
+diff -ur a/lxsession/settings.vala b/lxsession/settings.vala
+--- a/lxsession/settings.vala  2021-06-24 23:29:50.428230979 +0100
++++ b/lxsession/settings.vala  2021-06-24 23:58:30.492951704 +0100
+@@ -265,7 +265,6 @@
+             /* Keep old behavior for autostarted application if this option is not specify */
+             set_generic_default("Session", "disable_autostart", null, "string", "no");
+-            set_generic_default("Session", "polkit", "command", "string", "lxpolkit");
+             set_generic_default("Session", "clipboard", "command", "string", "lxclipboard");
+             set_generic_default("Session", "xsettings_manager", "command", "string", "build-in");
+             set_generic_default("Session", "proxy_manager", "command", "string", "build-in");
+@@ -774,7 +773,6 @@
+         /* Other session applications */
+         read_key_value(kf, "Session", "screensaver", "command", "string");
+         read_key_value(kf, "Session", "power_manager", "command", "string");
+-        read_key_value(kf, "Session", "polkit", "command", "string");
+         read_key_value(kf, "Session", "audio_manager", "command", "string");
+         read_key_value(kf, "Session", "quit_manager", "command", "string");
+@@ -1184,7 +1182,6 @@
+             set_config_item_value("Session", "launcher_manager", "autostart", "string", "true");
+         }
+-        read_razor_key_value(kf, "Session", "polkit", "command", "string", "modules", "razor-policykit-agent", null);
+         /* TODO Convert this config on file to lxsession config
+         razor-appswitcher=false
+@@ -1272,15 +1269,6 @@
+             kf_session.set_value ("modules", "razor-runner", "false");
+         }
+-        if (get_item_string("Session", "polkit", "command") == "razor-policykit-agent")
+-        {
+-            kf_session.set_value ("modules", "razor-policykit-agent", "true");
+-        }
+-        else
+-        {
+-            kf_session.set_value ("modules", "razor-policykit-agent", "false");
+-        }
+-
+         /* TODO Convert this config on file to lxsession config
+         razor-appswitcher=false
+         */
+diff -ur a/lxsession-db/desktop-files-backend.c b/lxsession-db/desktop-files-backend.c
+--- a/lxsession-db/desktop-files-backend.c     2021-06-24 23:29:50.427230977 +0100
++++ b/lxsession-db/desktop-files-backend.c     2021-06-24 23:58:30.491951702 +0100
+@@ -69,9 +69,6 @@
+       gchar* power_manager_blacklist;
+       GList* power_manager_installed;
+       GList* power_manager_available;
+-      gchar* polkit_blacklist;
+-      GList* polkit_installed;
+-      GList* polkit_available;
+       gchar* im_blacklist;
+       GList* im_installed;
+       GList* im_available;
+@@ -323,9 +320,6 @@
+       _tmp6_ = g_strdup ("");
+       _g_free0 (self->power_manager_blacklist);
+       self->power_manager_blacklist = _tmp6_;
+-      _tmp7_ = g_strdup ("");
+-      _g_free0 (self->polkit_blacklist);
+-      self->polkit_blacklist = _tmp7_;
+       _tmp8_ = g_strdup ("");
+       _g_free0 (self->im_blacklist);
+       self->im_blacklist = _tmp8_;
+@@ -1569,46 +1563,6 @@
+                                       _g_free0 (new_entry);
+                               }
+                       }
+-                      _tmp93_ = string_contains (categories, "Polkit");
+-                      if (_tmp93_) {
+-                              const gchar* _tmp94_ = NULL;
+-                              const gchar* _tmp95_ = NULL;
+-                              gboolean _tmp96_ = FALSE;
+-                              _tmp94_ = self->polkit_blacklist;
+-                              _tmp95_ = name;
+-                              _tmp96_ = string_contains (_tmp94_, _tmp95_);
+-                              if (_tmp96_) {
+-                              } else {
+-                                      gchar* new_entry = NULL;
+-                                      GKeyFile* _tmp97_ = NULL;
+-                                      const gchar* _tmp98_ = NULL;
+-                                      gchar* _tmp99_ = NULL;
+-                                      const gchar* _tmp100_ = NULL;
+-                                      _tmp97_ = kf;
+-                                      _tmp98_ = desktop_path;
+-                                      _tmp99_ = lxsession_db_default_apps_create_entry (self, _tmp97_, _tmp98_);
+-                                      new_entry = _tmp99_;
+-                                      _tmp100_ = mode;
+-                                      if (g_strcmp0 (_tmp100_, "installed") == 0) {
+-                                              const gchar* _tmp101_ = NULL;
+-                                              gchar* _tmp102_ = NULL;
+-                                              _tmp101_ = new_entry;
+-                                              _tmp102_ = g_strdup (_tmp101_);
+-                                              self->polkit_installed = g_list_append (self->polkit_installed, _tmp102_);
+-                                      } else {
+-                                              const gchar* _tmp103_ = NULL;
+-                                              _tmp103_ = mode;
+-                                              if (g_strcmp0 (_tmp103_, "available") == 0) {
+-                                                      const gchar* _tmp104_ = NULL;
+-                                                      gchar* _tmp105_ = NULL;
+-                                                      _tmp104_ = new_entry;
+-                                                      _tmp105_ = g_strdup (_tmp104_);
+-                                                      self->polkit_available = g_list_append (self->polkit_available, _tmp105_);
+-                                              }
+-                                      }
+-                                      _g_free0 (new_entry);
+-                              }
+-                      }
+                       _tmp106_ = string_contains (categories, "InstantMessaging");
+                       if (_tmp106_) {
+                               const gchar* _tmp107_ = NULL;
+@@ -2370,9 +2324,6 @@
+       _tmp12_ = self->priv->kf;
+       _tmp13_ = self->power_manager_installed;
+       lxsession_db_default_apps_keyfile_set_list_string (self, _tmp12_, "Mime", "power_manager/installed", _tmp13_);
+-      _tmp14_ = self->priv->kf;
+-      _tmp15_ = self->polkit_installed;
+-      lxsession_db_default_apps_keyfile_set_list_string (self, _tmp14_, "Mime", "polkit/installed", _tmp15_);
+       _tmp16_ = self->priv->kf;
+       _tmp17_ = self->im_installed;
+       lxsession_db_default_apps_keyfile_set_list_string (self, _tmp16_, "Mime", "im/installed", _tmp17_);
+@@ -2486,9 +2437,6 @@
+       _tmp12_ = self->priv->kf;
+       _tmp13_ = self->power_manager_available;
+       lxsession_db_default_apps_keyfile_set_list_string (self, _tmp12_, "Mime", "power_manager/available", _tmp13_);
+-      _tmp14_ = self->priv->kf;
+-      _tmp15_ = self->polkit_available;
+-      lxsession_db_default_apps_keyfile_set_list_string (self, _tmp14_, "Mime", "polkit/available", _tmp15_);
+       _tmp16_ = self->priv->kf;
+       _tmp17_ = self->im_available;
+       lxsession_db_default_apps_keyfile_set_list_string (self, _tmp16_, "Mime", "im/available", _tmp17_);
+@@ -2683,8 +2631,6 @@
+       self->desktop_manager_available = NULL;
+       self->power_manager_installed = NULL;
+       self->power_manager_available = NULL;
+-      self->polkit_installed = NULL;
+-      self->polkit_available = NULL;
+       self->im_installed = NULL;
+       self->im_available = NULL;
+       self->widget_installed = NULL;
+@@ -2754,9 +2700,6 @@
+       _g_free0 (self->power_manager_blacklist);
+       __g_list_free__g_free0_0 (self->power_manager_installed);
+       __g_list_free__g_free0_0 (self->power_manager_available);
+-      _g_free0 (self->polkit_blacklist);
+-      __g_list_free__g_free0_0 (self->polkit_installed);
+-      __g_list_free__g_free0_0 (self->polkit_available);
+       _g_free0 (self->im_blacklist);
+       __g_list_free__g_free0_0 (self->im_installed);
+       __g_list_free__g_free0_0 (self->im_available);
+diff -ur a/lxsession-db/desktop-files-backend.vala b/lxsession-db/desktop-files-backend.vala
+--- a/lxsession-db/desktop-files-backend.vala  2021-06-24 23:29:50.427230977 +0100
++++ b/lxsession-db/desktop-files-backend.vala  2021-06-24 23:58:30.491951702 +0100
+@@ -47,10 +47,6 @@
+         public List<string> power_manager_installed = new List<string> ();
+         public List<string> power_manager_available = new List<string> ();
+-        public string polkit_blacklist;
+-        public List<string> polkit_installed = new List<string> ();
+-        public List<string> polkit_available = new List<string> ();
+-
+         public string im_blacklist;
+         public List<string> im_installed = new List<string> ();
+         public List<string> im_available = new List<string> ();
+@@ -148,7 +144,6 @@
+             composite_manager_blacklist = "";
+             desktop_manager_blacklist = "";
+             power_manager_blacklist = "";
+-            polkit_blacklist = "";
+             im_blacklist = "";
+             widget_blacklist = "";
+             terminal_manager_blacklist = "";
+@@ -548,25 +543,6 @@
+                         }
+                     }
+-                    if ("Polkit" in categories)
+-                    {
+-                        if (name in polkit_blacklist)
+-                        {
+-                            /* Blacklisted, pass */
+-                        }
+-                        else
+-                        {
+-                            string new_entry = create_entry(kf, desktop_path);
+-                            if (mode == "installed")
+-                            {
+-                                polkit_installed.append(new_entry);
+-                            }
+-                            else if (mode == "available")
+-                            {
+-                                polkit_available.append(new_entry);
+-                            }
+-                        }
+-                    }
+                     if ("InstantMessaging" in categories)
+                     {
+                         if (name in im_blacklist)
+@@ -897,7 +873,6 @@
+             keyfile_set_list_string(kf, "Mime", "composite_manager/installed", composite_manager_installed);
+             keyfile_set_list_string(kf, "Mime", "desktop_manager/installed", desktop_manager_installed);
+             keyfile_set_list_string(kf, "Mime", "power_manager/installed", power_manager_installed);
+-            keyfile_set_list_string(kf, "Mime", "polkit/installed", polkit_installed);
+             keyfile_set_list_string(kf, "Mime", "im/installed", im_installed);
+             keyfile_set_list_string(kf, "Mime", "widget/installed", widget_installed);
+             keyfile_set_list_string(kf, "Mime", "terminal_manager/installed", terminal_manager_installed);
+@@ -925,7 +900,6 @@
+             keyfile_set_list_string(kf, "Mime", "composite_manager/available", composite_manager_available);
+             keyfile_set_list_string(kf, "Mime", "desktop_manager/available", desktop_manager_available);
+             keyfile_set_list_string(kf, "Mime", "power_manager/available", power_manager_available);
+-            keyfile_set_list_string(kf, "Mime", "polkit/available", polkit_available);
+             keyfile_set_list_string(kf, "Mime", "im/available", im_available);
+             keyfile_set_list_string(kf, "Mime", "widget/available", widget_available);
+             keyfile_set_list_string(kf, "Mime", "terminal_manager/available", terminal_manager_available);
+diff -ur a/lxsession-default-apps/main.c b/lxsession-default-apps/main.c
+--- a/lxsession-default-apps/main.c    2021-06-24 23:29:50.426230976 +0100
++++ b/lxsession-default-apps/main.c    2021-06-24 23:58:30.490951701 +0100
+@@ -837,15 +837,10 @@
+       gchar** _tmp161_ = NULL;
+       gint _tmp161__length1 = 0;
+       const gchar* _tmp162_ = NULL;
+-      gchar* polkit_help_message = NULL;
+       const gchar* _tmp163_ = NULL;
+       gchar* _tmp164_ = NULL;
+-      gchar** polkit_more = NULL;
+       gchar* _tmp165_ = NULL;
+       gchar** _tmp166_ = NULL;
+-      gint polkit_more_length1 = 0;
+-      gint _polkit_more_size_ = 0;
+-      gchar* polkit_more_help_message = NULL;
+       gchar* _tmp167_ = NULL;
+       GtkBuilder* _tmp168_ = NULL;
+       GKeyFile* _tmp169_ = NULL;
+@@ -2161,26 +2156,6 @@
+       _tmp161__length1 = power_manager_more_length1;
+       _tmp162_ = power_manager_more_help_message;
+       ldefault_apps_init_application (_tmp157_, _tmp158_, _tmp159_, "power_manager", "", _tmp160_, _tmp161_, _tmp161__length1, _tmp162_, NULL);
+-      _tmp163_ = _ ("Polkit agent provides authorisations to use some actions, like suspend" \
+-", hibernate, using Consolekit ... It's not advised to make it blank.");
+-      _tmp164_ = g_strdup (_tmp163_);
+-      polkit_help_message = _tmp164_;
+-      _tmp165_ = g_strdup ("");
+-      _tmp166_ = g_new0 (gchar*, 1 + 1);
+-      _tmp166_[0] = _tmp165_;
+-      polkit_more = _tmp166_;
+-      polkit_more_length1 = 1;
+-      _polkit_more_size_ = polkit_more_length1;
+-      _tmp167_ = g_strdup ("");
+-      polkit_more_help_message = _tmp167_;
+-      _tmp168_ = builder;
+-      _tmp169_ = kf;
+-      _tmp170_ = _data4_->dbus_backend;
+-      _tmp171_ = polkit_help_message;
+-      _tmp172_ = polkit_more;
+-      _tmp172__length1 = polkit_more_length1;
+-      _tmp173_ = polkit_more_help_message;
+-      ldefault_apps_init_application (_tmp168_, _tmp169_, _tmp170_, "polkit", "", _tmp171_, _tmp172_, _tmp172__length1, _tmp173_, NULL);
+       _tmp174_ = _ ("Set an utility to manager connections, such as nm-applet");
+       _tmp175_ = g_strdup (_tmp174_);
+       network_gui_help_message = _tmp175_;
+@@ -3426,9 +3401,6 @@
+       _g_free0 (network_gui_more_help_message);
+       network_gui_more = (_vala_array_free (network_gui_more, network_gui_more_length1, (GDestroyNotify) g_free), NULL);
+       _g_free0 (network_gui_help_message);
+-      _g_free0 (polkit_more_help_message);
+-      polkit_more = (_vala_array_free (polkit_more, polkit_more_length1, (GDestroyNotify) g_free), NULL);
+-      _g_free0 (polkit_help_message);
+       _g_free0 (power_manager_more_help_message);
+       power_manager_more = (_vala_array_free (power_manager_more, power_manager_more_length1, (GDestroyNotify) g_free), NULL);
+       _g_free0 (power_manager_help_message);
+diff -ur a/lxsession-default-apps/main.vala b/lxsession-default-apps/main.vala
+--- a/lxsession-default-apps/main.vala 2021-06-24 23:29:50.426230976 +0100
++++ b/lxsession-default-apps/main.vala 2021-06-24 23:58:30.490951701 +0100
+@@ -205,11 +205,6 @@
+             string power_manager_more_help_message = "";
+             init_application(builder, kf, dbus_backend, "power_manager", "", power_manager_help_message, power_manager_more, power_manager_more_help_message, null);
+-            string polkit_help_message = _("Polkit agent provides authorisations to use some actions, like suspend, hibernate, using Consolekit ... It's not advised to make it blank.");
+-            string[] polkit_more = {""};
+-            string polkit_more_help_message = "";
+-            init_application(builder, kf, dbus_backend, "polkit", "", polkit_help_message, polkit_more, polkit_more_help_message, null);
+-
+             string network_gui_help_message = _("Set an utility to manager connections, such as nm-applet");
+             string[] network_gui_more = {""};
+             string network_gui_more_help_message = "";
+diff -ur a/README b/README
+--- a/README   2021-06-24 23:29:50.428230979 +0100
++++ b/README   2021-06-24 23:58:30.491951702 +0100
+@@ -73,7 +73,6 @@
+ * "--enable-more-warnings" : Enable more compilation warning at build time
+ * "--enable-gtk3" : Compile with GTK3 when the component is compatible (incomplete)
+ * "--enable-buildin-clipboard" : Add a build-in support for clipboard functionalities, using GTK2
+-* "--enable-buildin-polkit" : Add a build-in support for a polkit agent (based on GTK)
+ * "--enable-debug" : Enable more debug
+ * "--enable-gtk" : Enable GTK+ programs and compilation. Pass --disable-gtk to build without any GTK+ component (useful if you want lxsession on a Qt environnement).
+@@ -140,7 +139,6 @@
+ == Applications and binaries ==
+ * lxclipboard : Application to enable a clipboard support, using GTK.
+ * lxlock : Application to lock the screen, using external applications
+-* lxpolkit : Polkit agent
+ * lxsession-default : Wrapper around Dbus method to launch applications defined in lxsession configuration file.
+ * lxsession-default-apps : Configuration application for lxsession (mostly for debugging purposes).
+ * lxsession-edit : Old configuration application for lxsession
+
diff --git a/lxde-base/lxsession/files/lxsession-0.5.5-no-polkit.patch b/lxde-base/lxsession/files/lxsession-0.5.5-no-polkit.patch
new file mode 100644 (file)
index 0000000..302bbbc
--- /dev/null
@@ -0,0 +1,468 @@
+diff -ur a/configure b/configure
+--- a/configure        2021-06-24 22:27:05.581883135 +0100
++++ b/configure        2021-06-24 22:44:58.160750794 +0100
+@@ -704,7 +704,6 @@
+ CPP
+ GETTEXT_PACKAGE
+ VALAC
+-HIDE_LXPOLKIT_AUTOSTART
+ LIBNOTIFY_LIBS
+ LIBNOTIFY_CFLAGS
+ INDICATORS_LIBS
+@@ -713,12 +712,8 @@
+ USE_ADVANCED_NOTIFICATIONS_TRUE
+ USE_GTK3_FALSE
+ USE_GTK3_TRUE
+-USE_BUILDIN_POLKIT_FALSE
+-USE_BUILDIN_POLKIT_TRUE
+ USE_BUILDIN_CLIPBOARD_FALSE
+ USE_BUILDIN_CLIPBOARD_TRUE
+-POLKIT_LIBS
+-POLKIT_CFLAGS
+ VALA_GTK_LIBS
+ GTK_LIBS
+ GTK_CFLAGS
+@@ -863,7 +858,6 @@
+ enable_gtk
+ enable_gtk3
+ enable_buildin_clipboard
+-enable_buildin_polkit
+ enable_advanced_notifications
+ enable_debug
+ with_xml_catalog
+@@ -887,8 +881,6 @@
+ GIO_LIBS
+ GTK_CFLAGS
+ GTK_LIBS
+-POLKIT_CFLAGS
+-POLKIT_LIBS
+ INDICATORS_CFLAGS
+ INDICATORS_LIBS
+ LIBNOTIFY_CFLAGS
+@@ -1532,8 +1524,6 @@
+   --enable-gtk3           enable to use gtk-3.0 instead of gtk-2.0
+   --enable-buildin-clipboard
+                           Build with build-in clipboard support (default: no)
+-  --enable-buildin-polkit Build with build-in polkit-agent support (default:
+-                          no)
+   --enable-advanced-notifications
+                           Build with advanced notification using indicators
+                           and libnotify (default: no)
+@@ -1566,9 +1556,6 @@
+   GIO_LIBS    linker flags for GIO, overriding pkg-config
+   GTK_CFLAGS  C compiler flags for GTK, overriding pkg-config
+   GTK_LIBS    linker flags for GTK, overriding pkg-config
+-  POLKIT_CFLAGS
+-              C compiler flags for POLKIT, overriding pkg-config
+-  POLKIT_LIBS linker flags for POLKIT, overriding pkg-config
+   INDICATORS_CFLAGS
+               C compiler flags for INDICATORS, overriding pkg-config
+   INDICATORS_LIBS
+@@ -5347,7 +5334,6 @@
+ if test "x$use_gtk" = "xno" ; then
+   enable_gtk3="no"
+   use_buildin_clipboard="no"
+-  use_buildin_polkit="no"
+ else
+   # Check whether --enable-gtk3 was given.
+ if test "${enable_gtk3+set}" = set; then :
+@@ -5458,105 +5444,6 @@
+ fi
+-
+-
+-
+-
+-  polkit_modules="polkit-agent-1"
+-
+-pkg_failed=no
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for POLKIT" >&5
+-$as_echo_n "checking for POLKIT... " >&6; }
+-
+-if test -n "$POLKIT_CFLAGS"; then
+-    pkg_cv_POLKIT_CFLAGS="$POLKIT_CFLAGS"
+- elif test -n "$PKG_CONFIG"; then
+-    if test -n "$PKG_CONFIG" && \
+-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$polkit_modules\""; } >&5
+-  ($PKG_CONFIG --exists --print-errors "$polkit_modules") 2>&5
+-  ac_status=$?
+-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+-  test $ac_status = 0; }; then
+-  pkg_cv_POLKIT_CFLAGS=`$PKG_CONFIG --cflags "$polkit_modules" 2>/dev/null`
+-                    test "x$?" != "x0" && pkg_failed=yes
+-else
+-  pkg_failed=yes
+-fi
+- else
+-    pkg_failed=untried
+-fi
+-if test -n "$POLKIT_LIBS"; then
+-    pkg_cv_POLKIT_LIBS="$POLKIT_LIBS"
+- elif test -n "$PKG_CONFIG"; then
+-    if test -n "$PKG_CONFIG" && \
+-    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$polkit_modules\""; } >&5
+-  ($PKG_CONFIG --exists --print-errors "$polkit_modules") 2>&5
+-  ac_status=$?
+-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+-  test $ac_status = 0; }; then
+-  pkg_cv_POLKIT_LIBS=`$PKG_CONFIG --libs "$polkit_modules" 2>/dev/null`
+-                    test "x$?" != "x0" && pkg_failed=yes
+-else
+-  pkg_failed=yes
+-fi
+- else
+-    pkg_failed=untried
+-fi
+-
+-
+-
+-if test $pkg_failed = yes; then
+-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
+-
+-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+-        _pkg_short_errors_supported=yes
+-else
+-        _pkg_short_errors_supported=no
+-fi
+-        if test $_pkg_short_errors_supported = yes; then
+-              POLKIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$polkit_modules" 2>&1`
+-        else
+-              POLKIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$polkit_modules" 2>&1`
+-        fi
+-      # Put the nasty error message in config.log where it belongs
+-      echo "$POLKIT_PKG_ERRORS" >&5
+-
+-      as_fn_error $? "Package requirements ($polkit_modules) were not met:
+-
+-$POLKIT_PKG_ERRORS
+-
+-Consider adjusting the PKG_CONFIG_PATH environment variable if you
+-installed software in a non-standard prefix.
+-
+-Alternatively, you may set the environment variables POLKIT_CFLAGS
+-and POLKIT_LIBS to avoid the need to call pkg-config.
+-See the pkg-config man page for more details." "$LINENO" 5
+-elif test $pkg_failed = untried; then
+-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
+-      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+-as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
+-is in your PATH or set the PKG_CONFIG environment variable to the full
+-path to pkg-config.
+-
+-Alternatively, you may set the environment variables POLKIT_CFLAGS
+-and POLKIT_LIBS to avoid the need to call pkg-config.
+-See the pkg-config man page for more details.
+-
+-To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+-See \`config.log' for more details" "$LINENO" 5; }
+-else
+-      POLKIT_CFLAGS=$pkg_cv_POLKIT_CFLAGS
+-      POLKIT_LIBS=$pkg_cv_POLKIT_LIBS
+-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
+-
+-fi
+-
+-
+-
+   # Check whether --enable-buildin-clipboard was given.
+ if test "${enable_buildin_clipboard+set}" = set; then :
+   enableval=$enable_buildin_clipboard; use_buildin_clipboard=$enableval
+@@ -5564,15 +5451,6 @@
+   use_buildin_clipboard="no"
+ fi
+-
+-  # Check whether --enable-buildin-polkit was given.
+-if test "${enable_buildin_polkit+set}" = set; then :
+-  enableval=$enable_buildin_polkit; use_buildin_polkit=$enableval
+-else
+-  use_buildin_polkit="no"
+-fi
+-
+-
+   # Check whether --enable-advanced-notifications was given.
+ if test "${enable_advanced_notifications+set}" = set; then :
+   enableval=$enable_advanced_notifications; use_advanced_notifications=$enableval
+@@ -5591,13 +5469,6 @@
+   USE_BUILDIN_CLIPBOARD_FALSE=
+ fi
+- if test "$use_buildin_polkit" = "yes"; then
+-  USE_BUILDIN_POLKIT_TRUE=
+-  USE_BUILDIN_POLKIT_FALSE='#'
+-else
+-  USE_BUILDIN_POLKIT_TRUE='#'
+-  USE_BUILDIN_POLKIT_FALSE=
+-fi
+  if test "$enable_gtk3" = "yes"; then
+   USE_GTK3_TRUE=
+@@ -5806,12 +5677,6 @@
+ fi
+-if test "$use_buildin_polkit" = "yes"; then
+-  HIDE_LXPOLKIT_AUTOSTART=true
+-else
+-  HIDE_LXPOLKIT_AUTOSTART=false
+-fi
+-
+ # Extract the first word of "valac", so it can be a program name with args.
+ set dummy valac; ac_word=$2
+@@ -7199,7 +7064,7 @@
+     sysconfdir=/etc
+ fi
+-ac_config_files="$ac_config_files Makefile data/Makefile data/ui/Makefile data/lxpolkit.desktop.in man/Makefile po/Makefile.in"
++ac_config_files="$ac_config_files Makefile data/Makefile data/ui/Makefile man/Makefile po/Makefile.in"
+ cat >confcache <<\_ACEOF
+ # This file is a shell script that caches the results of configure
+@@ -7346,10 +7211,6 @@
+   as_fn_error $? "conditional \"USE_BUILDIN_CLIPBOARD\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+ fi
+-if test -z "${USE_BUILDIN_POLKIT_TRUE}" && test -z "${USE_BUILDIN_POLKIT_FALSE}"; then
+-  as_fn_error $? "conditional \"USE_BUILDIN_POLKIT\" was never defined.
+-Usually this means the macro was only invoked conditionally." "$LINENO" 5
+-fi
+ if test -z "${USE_GTK3_TRUE}" && test -z "${USE_GTK3_FALSE}"; then
+   as_fn_error $? "conditional \"USE_GTK3\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+@@ -7961,7 +7822,6 @@
+     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+     "data/Makefile") CONFIG_FILES="$CONFIG_FILES data/Makefile" ;;
+     "data/ui/Makefile") CONFIG_FILES="$CONFIG_FILES data/ui/Makefile" ;;
+-    "data/lxpolkit.desktop.in") CONFIG_FILES="$CONFIG_FILES data/lxpolkit.desktop.in" ;;
+     "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
+     "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;;
+     "po/stamp-it") CONFIG_COMMANDS="$CONFIG_COMMANDS po/stamp-it" ;;
+@@ -8722,7 +8582,6 @@
+ echo Sysconfdir................................... : $sysconfdir
+ echo GTK support.................................. : $use_gtk
+ echo GTK Cliboard build-in suport................. : $use_buildin_clipboard
+-echo GTK Polkit-agent build-in suport............. : $use_buildin_polkit
+ echo Enable GTK3 support.......................... : $enable_gtk3
+ echo Enable debug................................. : $enable_debug
+ echo Man pages generation support................. : $enable_man
+Only in b: configure~
+diff -ur a/configure.ac b/configure.ac
+--- a/configure.ac     2021-06-24 22:27:05.581883135 +0100
++++ b/configure.ac     2021-06-24 22:44:58.160750794 +0100
+@@ -64,7 +64,6 @@
+ if test "x$use_gtk" = "xno" ; then
+   enable_gtk3="no"
+   use_buildin_clipboard="no"
+-  use_buildin_polkit="no"
+ else
+   AC_ARG_ENABLE([gtk3],
+       AS_HELP_STRING([--enable-gtk3],
+@@ -86,11 +85,6 @@
+   AC_SUBST(VALA_GTK_LIBS)
+-  polkit_modules="polkit-agent-1"
+-  PKG_CHECK_MODULES(POLKIT, [$polkit_modules])
+-  AC_SUBST(POLKIT_CFLAGS)
+-  AC_SUBST(POLKIT_LIBS)
+-
+   AC_ARG_ENABLE(
+       [buildin-clipboard],
+       AS_HELP_STRING([--enable-buildin-clipboard],
+@@ -98,12 +92,6 @@
+       use_buildin_clipboard=$enableval, use_buildin_clipboard="no")
+   AC_ARG_ENABLE(
+-      [buildin-polkit],
+-      AS_HELP_STRING([--enable-buildin-polkit],
+-                     [Build with build-in polkit-agent support (default: no)]),
+-      use_buildin_polkit=$enableval, use_buildin_polkit="no")
+-
+-  AC_ARG_ENABLE(
+       [advanced-notifications],
+       AS_HELP_STRING([--enable-advanced-notifications],
+                      [Build with advanced notification using indicators and libnotify (default: no)]),
+@@ -112,7 +100,6 @@
+ fi
+ AM_CONDITIONAL(USE_BUILDIN_CLIPBOARD, test "$use_buildin_clipboard" = "yes")
+-AM_CONDITIONAL(USE_BUILDIN_POLKIT, test "$use_buildin_polkit" = "yes")
+ AM_CONDITIONAL(USE_GTK3, test "$enable_gtk3" = "yes")
+ AM_CONDITIONAL(USE_ADVANCED_NOTIFICATIONS, test "$use_advanced_notifications" = "yes")
+@@ -126,13 +113,6 @@
+   AC_SUBST(LIBNOTIFY_LIBS)
+ fi
+-if test "$use_buildin_polkit" = "yes"; then
+-  HIDE_LXPOLKIT_AUTOSTART=true
+-else
+-  HIDE_LXPOLKIT_AUTOSTART=false
+-fi
+-AC_SUBST(HIDE_LXPOLKIT_AUTOSTART)
+-
+ AM_PROG_VALAC([0.16.0])
+ if test "x$VALAC" = "x"; then
+   AC_MSG_ERROR([You need Vala compiler])
+@@ -192,7 +172,6 @@
+   Makefile
+   data/Makefile
+   data/ui/Makefile
+-  data/lxpolkit.desktop.in
+   man/Makefile
+   po/Makefile.in
+ ])
+@@ -205,7 +184,6 @@
+ echo Sysconfdir................................... : $sysconfdir
+ echo GTK support.................................. : $use_gtk
+ echo GTK Cliboard build-in suport................. : $use_buildin_clipboard
+-echo GTK Polkit-agent build-in suport............. : $use_buildin_polkit
+ echo Enable GTK3 support.......................... : $enable_gtk3
+ echo Enable debug................................. : $enable_debug
+ echo Man pages generation support................. : $enable_man
+Only in b: configure.ac~
+diff -ur a/Makefile.am b/Makefile.am
+--- a/Makefile.am      2021-06-24 22:27:05.582883136 +0100
++++ b/Makefile.am      2021-06-24 22:44:58.161750795 +0100
+@@ -29,7 +29,6 @@
+ noinst_DATA = \
+     vapi/config.vapi \
+     vapi/lxclipboard.vapi \
+-    vapi/lxpolkit.vapi \
+     vapi/lxsession-edit.vapi \
+     vapi/lxsettings-daemon.vapi \
+     vapi/xdg-autostart.vapi \
+@@ -46,7 +45,6 @@
+ if USE_GTK
+ bin_PROGRAMS += \
+-    lxpolkit/lxpolkit \
+     lxsession-db/lxsession-db \
+     lxsession-edit/lxsession-edit \
+     lxsession-logout/lxsession-logout \
+@@ -92,50 +90,6 @@
+ lxclipboard_lxclipboard_VALAFLAGS += --define USE_GTK2
+ endif
+-lxpolkit_lxpolkit_vala_SOURCES = \
+-    lxpolkit/main.vala \
+-    $(NULL)
+-
+-CLEANFILES += lxpolkit/main.c \
+-    lxpolkit_lxpolkit_vala.stamp \
+-    $(NULL)
+-
+-lxpolkit_lxpolkit_SOURCES = \
+-    $(lxpolkit_lxpolkit_vala_SOURCES) \
+-    lxpolkit/lxpolkit.c \
+-    lxpolkit/lxpolkit-listener.c \
+-    $(NULL)
+-
+-lxpolkit_lxpolkit_VALAFLAGS = \
+-    --vapidir=$(srcdir)/vapi \
+-    --pkg @VALA_GTK_LIBS@ \
+-    --pkg lxpolkit \
+-    $(NULL)
+-
+-lxpolkit_lxpolkit_CPPFLAGS = \
+-    $(GTK_CFLAGS) \
+-    $(GLIB_CFLAGS) \
+-    $(POLKIT_CFLAGS) \
+-    $(ADDITIONAL_FLAGS) \
+-    -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
+-    -DPACKAGE_DATA_DIR="\"$(datadir)"\" \
+-    -DPACKAGE_UI_DIR="\"$(datadir)/lxsession/ui"\" \
+-    -include config.h -w \
+-    $(NULL)
+-
+-lxpolkit_lxpolkit_LDADD = \
+-    $(GTK_LIBS) \
+-    $(GLIB_LIBS) \
+-    $(POLKIT_LIBS) \
+-    $(X11_LIBS) \
+-    $(NULL)
+-
+-if USE_GTK3
+-lxpolkit_lxpolkit_VALAFLAGS += --define USE_GTK3
+-else
+-lxpolkit_lxpolkit_VALAFLAGS += --define USE_GTK2
+-endif
+-
+ lxsession_db_lxsession_db_SOURCES = \
+     lxsession-db/main.vala \
+     lxsession-db/desktop-files-backend.vala \
+@@ -254,26 +208,6 @@
+     $(NULL)
+ endif
+-if USE_BUILDIN_POLKIT
+-buildinpolkit_SOURCES = \
+-    lxpolkit/lxpolkit.c \
+-    lxpolkit/lxpolkit-listener.c \
+-    $(NULL)
+-
+-buildinpolkit_VALAFLAGS = \
+-    --pkg lxpolkit \
+-    -D BUILDIN_POLKIT \
+-    $(NULL)
+-
+-buildinpolkit_CFLAGS = \
+-    $(POLKIT_CFLAGS) \
+-    $(NULL)
+-
+-buildinpolkit_LDADD = \
+-    $(POLKIT_LIBS) \
+-    $(NULL)
+-endif
+-
+ lxsession_logout_lxsession_logout_CPPFLAGS = \
+     $(GTK_CFLAGS) \
+     $(SM_CFLAGS) \
+@@ -407,7 +341,6 @@
+     $(lxsession_lxsession_vala_SOURCES) \
+     $(lxsettings_daemon_lxsettings_daemon_commun_SOURCES) \
+     $(buildinclip_SOURCES) \
+-    $(buildinpolkit_SOURCES) \
+     $(NULL)
+ lxsession_lxsession_VALAFLAGS = \
+@@ -418,7 +351,6 @@
+     --pkg lxsettings-daemon \
+     --pkg xevent \
+     $(buildinclip_VALAFLAGS) \
+-    $(buildinpolkit_VALAFLAGS) \
+     $(lxsession_gtk_lxsession_VALAFLAGS) \
+     $(NULL)
+@@ -433,7 +365,6 @@
+     $(DBUSGLIB_CFLAGS) \
+     $(ADDITIONAL_FLAGS) \
+     $(buildinclip_CFLAGS) \
+-    $(buildinpolkit_CFLAGS) \
+     $(lxsession_gtk_lxsession_CFLAGS) \
+     -include config.h -w \
+     $(NULL)
+@@ -444,7 +375,6 @@
+     $(DBUSGLIB_LIBS) \
+     $(X11_LIBS) \
+     $(buildinclip_LDADD) \
+-    $(buildinpolkit_LDADD) \
+     $(lxsession_gtk_lxsession_LDADD) \
+     $(NULL)
+@@ -478,8 +408,6 @@
+ EXTRA_DIST += \
+     autogen.sh \
+     lxclipboard/clipboard.h \
+-    lxpolkit/lxpolkit.h \
+-    lxpolkit/lxpolkit-listener.h \
+     lxsettings-daemon/settings-daemon.h \
+     lxsettings-daemon/xevent.h \
+     lxsettings-daemon/xsettings-common.h \
+Only in b: Makefile.am~
diff --git a/lxde-base/lxsession/files/lxsession-0.5.5-notify-daemon-default.patch b/lxde-base/lxsession/files/lxsession-0.5.5-notify-daemon-default.patch
new file mode 100644 (file)
index 0000000..24a5cbe
--- /dev/null
@@ -0,0 +1,15 @@
+diff -ur a/lxsession/settings.vala b/lxsession/settings.vala
+--- a/lxsession/settings.vala  2021-06-24 22:25:02.816797162 +0100
++++ b/lxsession/settings.vala  2021-06-24 22:25:33.345818567 +0100
+@@ -271,6 +271,10 @@
+             set_generic_default("Session", "proxy_manager", "command", "string", "build-in");
+             set_generic_default("Session", "keyring", "command", "string", "ssh-agent");
++            set_generic_default("Session", "notification", "command", "string", "/usr/libexec/notification-daemon");
++            set_generic_default("Session", "notification", "autostart", "string", "true");
++
++
+             /* Set Xsettings default */
+             set_generic_default("GTK", "iXft", "Antialias", "string", "1");
+Only in b/lxsession: settings.vala.orig
diff --git a/lxde-base/lxsession/files/lxsession-0.5.5-reload.patch b/lxde-base/lxsession/files/lxsession-0.5.5-reload.patch
new file mode 100644 (file)
index 0000000..43d3d90
--- /dev/null
@@ -0,0 +1,45 @@
+diff -ur a/lxsession/main.vala b/lxsession/main.vala
+--- a/lxsession/main.vala      2021-06-24 22:25:02.815797161 +0100
++++ b/lxsession/main.vala      2021-06-24 22:27:05.582883136 +0100
+@@ -99,6 +99,17 @@
+             return -1;
+         }
++              if (xevent_init() == false)
++              {
++                      return 1;
++              }
++
++              if (reload == true)
++              {
++                      send_internal_command(LXS_CMD.RELOAD);
++                      return 0;
++              }
++
+         message ("Session is %s",session);
+         message ("DE is %s", desktop_environnement);
+diff -ur a/Makefile.am b/Makefile.am
+--- a/Makefile.am      2021-06-24 22:25:02.813797160 +0100
++++ b/Makefile.am      2021-06-24 22:27:05.582883136 +0100
+@@ -416,6 +416,7 @@
+     --pkg gio-2.0 \
+     --pkg posix \
+     --pkg lxsettings-daemon \
++    --pkg xevent \
+     $(buildinclip_VALAFLAGS) \
+     $(buildinpolkit_VALAFLAGS) \
+     $(lxsession_gtk_lxsession_VALAFLAGS) \
+--- a/vapi/xevent.vapi 2021-06-24 22:25:02.813797144 +0100
++++ b/vapi/xevent.vapi 2021-06-24 22:27:05.582883246 +0100
+@@ -0,0 +1,10 @@
++[CCode (cprefix = "LxsessionXEvent", cheader_filename = "lxsettings-daemon/xevent.h")]
++    public static void send_internal_command( int cmd );
++    public static bool xevent_init();
++
++[CCode (cname = "int", cprefix = "LXS_", cheader_filename = "lxsettings-daemon/xevent.h", has_type_id = false)]
++      public enum LXS_CMD {
++              RELOAD,
++              EXIT,
++              LAST_CMD
++      }
diff --git a/lxde-base/lxsession/lxsession-0.5.5-r1.ebuild b/lxde-base/lxsession/lxsession-0.5.5-r1.ebuild
new file mode 100644 (file)
index 0000000..91c740d
--- /dev/null
@@ -0,0 +1,64 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit vala autotools
+
+DESCRIPTION="LXDE session manager"
+HOMEPAGE="https://wiki.lxde.org/en/LXSession"
+SRC_URI="mirror://sourceforge/lxde/${P}.tar.xz"
+
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~ppc ~x86 ~x86-linux"
+IUSE="nls upower"
+
+COMMON_DEPEND="
+       dev-libs/dbus-glib
+       dev-libs/glib:2
+       >=lxde-base/lxde-common-0.99.2-r1
+       sys-apps/dbus
+       x11-libs/cairo
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+"
+RDEPEND="${COMMON_DEPEND}
+       !lxde-base/lxsession-edit
+       sys-apps/lsb-release
+       upower? ( sys-power/upower )
+"
+DEPEND="${COMMON_DEPEND}
+       x11-base/xorg-proto
+"
+BDEPEND="
+       $(vala_depend)
+       dev-util/intltool
+       sys-devel/gettext
+       virtual/pkgconfig
+"
+
+PATCHES=(
+       # Fedora patches
+       "${FILESDIR}"/${PN}-0.5.5-reload.patch
+       "${FILESDIR}"/${PN}-0.5.5-notify-daemon-default.patch
+    "${FILESDIR}"/${PN}-0.5.5-no-polkit.patch
+    "${FILESDIR}"/${PN}-0.5.5-no-polkit-pt2.patch
+)
+
+src_prepare() {
+       rm *.stamp || die
+       rm "${WORKDIR}/${P}/vapi/lxpolkit.vapi"
+       rm -rf "${WORKDIR}/${P}/lxpolkit"
+       vala_src_prepare
+       default
+       eautoreconf
+}
+
+src_configure() {
+       # dbus is used for restart/shutdown (logind), and suspend/hibernate (UPower)
+       econf \
+               $(use_enable nls) \
+               --enable-gtk3
+}
diff --git a/mail-filter/libmilter/Manifest b/mail-filter/libmilter/Manifest
new file mode 100644 (file)
index 0000000..19c58af
--- /dev/null
@@ -0,0 +1,2 @@
+DIST sendmail.8.16.1.tar.gz 2236402 BLAKE2B 80a9c2f1d04719099703e55f0a0c54fd638cf69b72839d358ae6863c95c9e0965d1b7fdd5b1807bec1ffdf87bca0c7c9ba91060962e6de5da5bf14422f6279ea SHA512 d7d4aac3c6d7505782abdb166204901b8b51cac000d610dfe40eda9eef7441a073af9e8e0b14c8719b07b445f55a1e2c28ac63d663d0daa7f1eafc5a101788b2
+EBUILD libmilter-1.0.2_p1-r1.ebuild 2138 BLAKE2B c229508fd86552f4824ab063826af45ad5cc282e9fef9ef7c498de531a54558f4c3312ae1ffebc8a7b96fa810acb7889e0dfedf1dcaeb078a13f71fac162c42c SHA512 e1cdc3be3fd6b85d1cb65eecf9a9d6e11da4416a3011a2fbae4d7fe0deb08250560699f6a2f92dd8452591a47c6f0754bb3a7d023647b0198fdb4efed81488f1
diff --git a/mail-filter/libmilter/libmilter-1.0.2_p1-r1.ebuild b/mail-filter/libmilter/libmilter-1.0.2_p1-r1.ebuild
new file mode 100644 (file)
index 0000000..4783e84
--- /dev/null
@@ -0,0 +1,75 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit toolchain-funcs
+
+# This library is part of sendmail, but it does not share the version number with it.
+# In order to find the right libmilter version number, check SMFI_VERSION definition
+# that can be found in ${S}/include/libmilter/mfapi.h (see also SM_LM_VRS_* defines).
+# For example, version 1.0.1 has a SMFI_VERSION of 0x01000001.
+SENDMAIL_VER=8.16.1
+
+DESCRIPTION="The Sendmail Filter API (Milter)"
+HOMEPAGE="http://www.sendmail.org/"
+SRC_URI="ftp://ftp.sendmail.org/pub/sendmail/sendmail.${SENDMAIL_VER}.tar.gz"
+S="${WORKDIR}/sendmail-${SENDMAIL_VER}"
+
+LICENSE="Sendmail"
+SLOT="0/${PV}"
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~ppc ~ppc64 ~sparc ~x86"
+IUSE="ipv6 poll"
+
+# build system patch copied from sendmail ebuild
+PATCHES=(
+       "${FILESDIR}/sendmail-8.16.1-build-system.patch"
+       "${FILESDIR}/${PN}-sharedlib.patch"
+)
+
+src_prepare() {
+       default
+
+       local CC="$(tc-getCC)"
+       local ENVDEF="-DNETUNIX -DNETINET -DHAS_GETHOSTBYNAME2=1"
+
+       use ipv6 && ENVDEF="${ENVDEF} -DNETINET6"
+       use poll && ENVDEF="${ENVDEF} -DSM_CONF_POLL=1"
+
+       if use elibc_musl; then
+               use ipv6 && ENVDEF="${ENVDEF} -DNEEDSGETIPNODE"
+
+               eapply "${FILESDIR}/${PN}-musl-stack-size.patch"
+               eapply "${FILESDIR}/${PN}-musl-disable-cdefs.patch"
+       fi
+
+       sed -e "s|@@CFLAGS@@|${CFLAGS}|" \
+               -e "s|@@LDFLAGS@@|${LDFLAGS}|" \
+               -e "s|@@CC@@|${CC}|" \
+               -e "s|@@ENVDEF@@|${ENVDEF}|" \
+               "${FILESDIR}/gentoo.config.m4" > "${S}/devtools/Site/site.config.m4" \
+               || die "failed to generate site.config.m4"
+}
+
+src_compile() {
+       pushd libmilter
+       emake -j1 MILTER_SOVER=${PV}
+       popd
+}
+
+src_install() {
+       local MY_LIBDIR=/usr/$(get_libdir)
+       dodir "${MY_LIBDIR}"
+       emake DESTDIR="${D}" LIBDIR="${MY_LIBDIR}" MANROOT=/usr/share/man/man \
+               SBINOWN=root SBINGRP=0 UBINOWN=root UBINGRP=0 \
+               LIBOWN=root LIBGRP=0 GBINOWN=root GBINGRP=0 \
+               MANOWN=root MANGRP=0 INCOWN=root INCGRP=0 \
+               MSPQOWN=root CFOWN=root CFGRP=0 \
+               MILTER_SOVER=${PV} \
+               install -C obj.*/libmilter
+
+       dodoc libmilter/README
+       dodoc libmilter/docs/*
+
+       find "${ED}" -name '*.a' -delete || die
+}
diff --git a/mail-mta/sendmail/Manifest b/mail-mta/sendmail/Manifest
new file mode 100644 (file)
index 0000000..5c76a60
--- /dev/null
@@ -0,0 +1,2 @@
+DIST sendmail.8.16.1.tar.gz 2236402 BLAKE2B 80a9c2f1d04719099703e55f0a0c54fd638cf69b72839d358ae6863c95c9e0965d1b7fdd5b1807bec1ffdf87bca0c7c9ba91060962e6de5da5bf14422f6279ea SHA512 d7d4aac3c6d7505782abdb166204901b8b51cac000d610dfe40eda9eef7441a073af9e8e0b14c8719b07b445f55a1e2c28ac63d663d0daa7f1eafc5a101788b2
+EBUILD sendmail-8.16.1.ebuild 6479 BLAKE2B 9879fdfb95aaaec13ab524c03e449435a71cd774758ec3cdc32592f4286b238b94689f110e1c524d7ca839f37f047554968dc0ab97a490c83536e556cb4cbec3 SHA512 2bb04dcd56571da76976b22a9c542d53664311ce7f5499620511d1c5d07a3c243a433b649594913628f001fecf96648e633aca5f1d4e82f889d8e473b97e9daa
diff --git a/mail-mta/sendmail/sendmail-8.16.1.ebuild b/mail-mta/sendmail/sendmail-8.16.1.ebuild
new file mode 100644 (file)
index 0000000..1501759
--- /dev/null
@@ -0,0 +1,209 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit multilib systemd toolchain-funcs
+
+DESCRIPTION="Widely-used Mail Transport Agent (MTA)"
+HOMEPAGE="https://www.sendmail.org/"
+SRC_URI="ftp://ftp.sendmail.org/pub/${PN}/${PN}.${PV}.tar.gz"
+
+LICENSE="Sendmail GPL-2" # GPL-2 is here for initscript
+SLOT="0"
+KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~mips ~ppc ~ppc64 ~s390 ~sparc ~x86"
+IUSE="ipv6 ldap mbox nis sasl sockets ssl tcpd"
+
+BDEPEND="sys-devel/m4"
+DEPEND="net-mail/mailbase
+       sasl? ( >=dev-libs/cyrus-sasl-2.1.10 )
+       tcpd? ( sys-apps/tcp-wrappers )
+       ssl? (
+               dev-libs/openssl:0=
+       )
+       ldap? ( net-nds/openldap )
+       >=sys-libs/db-3.2:=
+       !net-mail/vacation"
+RDEPEND="${DEPEND}
+       acct-group/smmsp
+       acct-user/smmsp
+       >=net-mail/mailbase-0.00
+       >=mail-filter/libmilter-1.0.2_p1-r1
+       !mail-mta/courier
+       !mail-mta/esmtp
+       !mail-mta/exim
+       !mail-mta/mini-qmail
+       !mail-mta/msmtp[mta]
+       !mail-mta/netqmail
+       !mail-mta/nullmailer
+       !mail-mta/postfix
+       !mail-mta/opensmtpd
+       !mail-mta/qmail-ldap
+       !>=mail-mta/ssmtp-2.64-r2[mta]"
+
+PDEPEND="!mbox? ( mail-filter/procmail )"
+
+src_prepare() {
+       eapply "${FILESDIR}"/"${PN}"-8.16.1-build-system.patch
+       eapply -p0 "${FILESDIR}"/sendmail-delivered_hdr.patch
+
+       local confCC="$(tc-getCC)"
+       local confCCOPTS="${CFLAGS}"
+       local confLDOPTS="${LDFLAGS}"
+       local confMAPDEF="-DMAP_REGEX"
+       local confENVDEF="-DMAXDAEMONS=64"
+       local conf_sendmail_LIBS=""
+
+       confENVDEF="${confLIBS} -DHAS_GETHOSTBYNAME2=1"
+
+       use sasl && confLIBS="${confLIBS} -lsasl2"  \
+               && confENVDEF="${confENVDEF} -DSASL=2" \
+               && confCCOPTS="${confCCOPTS} -I/usr/include/sasl" \
+               && conf_sendmail_LIBS="${conf_sendmail_LIBS} -lsasl2"
+
+       use tcpd && confENVDEF="${confENVDEF} -DTCPWRAPPERS" \
+               && confLIBS="${confLIBS} -lwrap"
+
+       # Bug #542370 - lets add support for modern crypto (PFS)
+       use ssl && confENVDEF="${confENVDEF} -DSTARTTLS -D_FFR_DEAL_WITH_ERROR_SSL" \
+               && confENVDEF="${confENVDEF} -D_FFR_TLS_1 -D_FFR_TLS_EC" \
+               && confLIBS="${confLIBS} -lssl -lcrypto" \
+               && conf_sendmail_LIBS="${conf_sendmail_LIBS} -lssl -lcrypto"
+
+       use ldap && confMAPDEF="${confMAPDEF} -DLDAPMAP" \
+               && confLIBS="${confLIBS} -lldap -llber"
+
+       use ipv6 && confENVDEF="${confENVDEF} -DNETINET6"
+
+       use nis && confENVDEF="${confENVDEF} -DNIS"
+
+       use sockets && confENVDEF="${confENVDEF} -DSOCKETMAP"
+
+       sed -e "s:@@confCCOPTS@@:${confCCOPTS}:" \
+               -e "s/@@confLDOPTS@@/${confLDOPTS}/" \
+               -e "s/@@confCC@@/${confCC}/" \
+               -e "s/@@confMAPDEF@@/${confMAPDEF}/" \
+               -e "s/@@confENVDEF@@/${confENVDEF}/" \
+               -e "s/@@confLIBS@@/${confLIBS}/" \
+               -e "s/@@conf_sendmail_LIBS@@/${conf_sendmail_LIBS}/" \
+               "${FILESDIR}"/site.config.m4 > devtools/Site/site.config.m4 || die "sed failed"
+
+       echo "APPENDDEF(\`confLIBDIRS', \`-L${EPREFIX}/usr/$(get_libdir)')" >> devtools/Site/site.config.m4 || die "echo failed"
+
+       eapply_user
+}
+
+src_compile() {
+       sh Build AR="$(tc-getAR)" RANLIB="$(tc-getRANLIB)" || die "compilation failed in main build script"
+}
+
+src_install() {
+       local MY_LIBDIR=/usr/$(get_libdir)
+       local MY_OBJDIR="obj.`uname -s`.`uname -r`.`uname -m`"
+
+       dodir /usr/bin ${MY_LIBDIR}
+       dodir /usr/share/man/man{1,5,8} /usr/sbin /usr/share/sendmail-cf
+       dodir /var/spool/{mqueue,clientmqueue} /etc/conf.d
+
+       keepdir /var/spool/{clientmqueue,mqueue}
+
+       for dir in libsmutil sendmail mailstats praliases smrsh makemap vacation editmap
+       do
+               make DESTDIR="${D}" LIBDIR="${MY_LIBDIR}" MANROOT=/usr/share/man/man \
+                       SBINOWN=root SBINGRP=root UBINOWN=root UBINGRP=root \
+                       MANOWN=root MANGRP=root INCOWN=root INCGRP=root \
+                       LIBOWN=root LIBGRP=root GBINOWN=root GBINGRP=root \
+                       MSPQOWN=root CFOWN=root CFGRP=root \
+                       install -C "${MY_OBJDIR}/${dir}" \
+                       || die "install 1 failed"
+       done
+
+       for dir in rmail mail.local
+       do
+               make DESTDIR="${D}" LIBDIR="${MY_LIBDIR}" MANROOT=/usr/share/man/man \
+                       SBINOWN=root SBINGRP=root UBINOWN=root UBINGRP=root \
+                       MANOWN=root MANGRP=root INCOWN=root INCGRP=root \
+                       LIBOWN=root LIBGRP=root GBINOWN=root GBINGRP=root \
+                       MSPQOWN=root CFOWN=root CFGRP=root \
+                       force-install -C "${MY_OBJDIR}/${dir}" \
+                       || die "install 2 failed"
+       done
+
+       fowners root:smmsp /usr/sbin/sendmail
+       fperms 2555 /usr/sbin/sendmail
+       fowners smmsp:smmsp /var/spool/clientmqueue
+       fperms 770 /var/spool/clientmqueue
+       fperms 700 /var/spool/mqueue
+       dosym ../sbin/makemap /usr/bin/makemap
+       dodoc FAQ KNOWNBUGS README RELEASE_NOTES doc/op/op.ps
+
+       newdoc sendmail/README README.sendmail
+       newdoc sendmail/SECURITY SECURITY
+       newdoc sendmail/TUNING TUNING
+       newdoc smrsh/README README.smrsh
+
+       newdoc cf/README README.cf
+       newdoc cf/cf/README README.install-cf
+
+       cp -pPR cf/* "${ED}"/usr/share/sendmail-cf || die "copy failed"
+
+       docinto contrib
+       dodoc contrib/*
+
+       insinto /etc/mail
+
+       if use mbox; then
+               newins "${FILESDIR}"/sendmail.mc-r1 sendmail.mc
+       else
+               newins "${FILESDIR}"/sendmail-procmail.mc sendmail.mc
+       fi
+
+       # See discussion on bug #730890
+       m4 "${ED}"/usr/share/sendmail-cf/m4/cf.m4 \
+               <(grep -v "${EPREFIX}"/usr/share/sendmail-cf/m4/cf.m4 "${ED}"/etc/mail/sendmail.mc) \
+               > "${ED}"/etc/mail/sendmail.cf || die "cf.m4 failed"
+
+       echo "include(\`/usr/share/sendmail-cf/m4/cf.m4')dnl" \
+               > "${ED}"/etc/mail/submit.mc || die "echo failed"
+
+       cat "${ED}"/usr/share/sendmail-cf/cf/submit.mc >> "${ED}"/etc/mail/submit.mc || die "submit.mc cat failed"
+
+       echo "# local-host-names - include all aliases for your machine here" \
+               > "${D}"/etc/mail/local-host-names || die "local-host-names echo failed"
+
+       cat <<- EOF > "${ED}"/etc/mail/trusted-users
+               # trusted-users - users that can send mail as others without a warning
+               # apache, mailman, majordomo, uucp are good candidates
+       EOF
+
+       cat <<- EOF > "${ED}"/etc/mail/access
+               # Check the /usr/share/doc/sendmail/README.cf file for a description
+               # of the format of this file. (search for access_db in that file)
+               # The /usr/share/doc/sendmail/README.cf is part of the sendmail-doc
+               # package.
+               #
+
+       EOF
+
+       cat <<- EOF > "${ED}"/etc/conf.d/sendmail
+               # Config file for /etc/init.d/sendmail
+               # add start-up options here
+               SENDMAIL_OPTS="-bd -q30m -L sm-mta" # default daemon mode
+               CLIENTMQUEUE_OPTS="-Ac -q30m -L sm-cm" # clientmqueue
+               KILL_OPTS="" # add -9/-15/your favorite evil SIG level here
+
+       EOF
+
+       if use sasl; then
+               dodir /etc/sasl2
+               cat <<- EOF > "${ED}"/etc/sasl2/Sendmail.conf
+               pwcheck_method: saslauthd
+               mech_list: PLAIN LOGIN
+
+               EOF
+       fi
+
+       doinitd "${FILESDIR}"/sendmail
+       systemd_dounit "${FILESDIR}"/sendmail.service
+       systemd_dounit "${FILESDIR}"/sm-client.service
+}
diff --git a/media-libs/libsdl2/Manifest b/media-libs/libsdl2/Manifest
new file mode 100644 (file)
index 0000000..ba07265
--- /dev/null
@@ -0,0 +1,3 @@
+AUX libsdl2-2.0.14-static-libs.patch 1820 BLAKE2B 54a6e92a2fd52c54ae25a1b859502cc403fa9bfcb6e2f3b83ca90fa125ff98c5ed0478cf786d6f1142968187230efbc994a57f706ae1a90bd1fe21eeada1673a SHA512 cf3762b03600c80f26e72f8828b4c0d6ac3c32ae00e1e0f5c9ab46fb4de178f4b045dcfd68f5d371c835235c96c5f1762e5966377d2a95874a012008eb2b13b9
+DIST SDL2-2.0.14.tar.gz 6089974 BLAKE2B 5982c66430f8ae62094dbc216781efafd3a07c50efd16bc8307d5048227011d4710d5af1b15be01a55fa6f3ae41eedf9c2df67bafd98042e3b2978a05e7ffd27 SHA512 ebc482585bd565bf3003fbcedd91058b2183e333b9ea566d2f386da0298ff970645d9d25c1aa4459c7c96e9ea839fd1c5f2da0242a56892865b2e456cdd027ee
+EBUILD libsdl2-2.0.14-r1.ebuild 6108 BLAKE2B d1a8a04620eb029a13acd0ff326a2c34ec50df069d8f6b8c5fe28a5fae15757a66eb7c8eac98874afa9b38c43628f08e3c0e4b57913423e9f9700c709695ed7d SHA512 6302422aef737c4c19ffcbfa074f54353d12c2efcbea572087c995c6ff2632a69657c3dd9b2cd4803a9a3d804dce097e9d6e5522797848c83744ca638381792a
diff --git a/media-libs/libsdl2/files/libsdl2-2.0.14-static-libs.patch b/media-libs/libsdl2/files/libsdl2-2.0.14-static-libs.patch
new file mode 100644 (file)
index 0000000..01b9c51
--- /dev/null
@@ -0,0 +1,34 @@
+Fix --disable-static.
+
+Bug: https://bugzilla.libsdl.org/show_bug.cgi?id=1431
+
+--- SDL2-2.0.14/configure.ac
++++ SDL2-2.0.14/configure.ac
+@@ -3863,7 +3863,7 @@
+         if test -f /lib/w32api/libuuid.a; then
+             LIBUUID=/lib/w32api/libuuid.a
+         else
+-            LIBUUID=-luuid
++            LIBUUID=-Wl,-luuid
+         fi
+         EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion $LIBUUID -static-libgcc"
+         # The Windows platform requires special setup
+--- SDL2-2.0.14/Makefile.in
++++ SDL2-2.0.14/Makefile.in
+@@ -151,13 +151,13 @@
+ .PHONY: all update-revision install install-bin install-hdrs install-lib install-data uninstall uninstall-bin uninstall-hdrs uninstall-lib uninstall-data clean distclean dist $(OBJECTS:.lo=.d)
+ $(objects)/$(TARGET): $(GEN_HEADERS) $(GEN_OBJECTS) $(OBJECTS) $(VERSION_OBJECTS)
+-      $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(OBJECTS) $(GEN_OBJECTS) $(VERSION_OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS)
++      $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS)
+ $(objects)/$(SDLMAIN_TARGET): $(SDLMAIN_OBJECTS)
+-      $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -static -o $@ $(SDLMAIN_OBJECTS) -rpath $(libdir)
++      $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS) -all-static
+ $(objects)/$(SDLTEST_TARGET): $(SDLTEST_OBJECTS)
+-      $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -static -o $@ $(SDLTEST_OBJECTS) -rpath $(libdir)
++      $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS) -all-static
+ install: all install-bin install-hdrs install-lib install-data
+ install-bin:
diff --git a/media-libs/libsdl2/libsdl2-2.0.14-r1.ebuild b/media-libs/libsdl2/libsdl2-2.0.14-r1.ebuild
new file mode 100644 (file)
index 0000000..d08ad24
--- /dev/null
@@ -0,0 +1,210 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit autotools flag-o-matic toolchain-funcs multilib-minimal
+
+MY_P="SDL2-${PV}"
+DESCRIPTION="Simple Direct Media Layer"
+HOMEPAGE="https://www.libsdl.org/"
+SRC_URI="https://www.libsdl.org/release/${MY_P}.tar.gz"
+
+LICENSE="ZLIB"
+SLOT="0"
+KEYWORDS="~alpha amd64 ~arm ~arm64 ~hppa ~ia64 ~ppc ~ppc64 ~riscv ~sparc ~x86"
+
+IUSE="alsa aqua cpu_flags_ppc_altivec cpu_flags_x86_3dnow cpu_flags_x86_mmx cpu_flags_x86_sse cpu_flags_x86_sse2 custom-cflags dbus fcitx4 gles1 gles2 haptic ibus jack +joystick kms libsamplerate nas opengl oss pulseaudio sndio +sound static-libs +threads udev +video video_cards_vc4 vulkan wayland X xinerama xscreensaver"
+REQUIRED_USE="
+       alsa? ( sound )
+       fcitx4? ( dbus )
+       gles1? ( video )
+       gles2? ( video )
+       ibus? ( dbus )
+       jack? ( sound )
+       nas? ( sound )
+       opengl? ( video )
+       pulseaudio? ( sound )
+       sndio? ( sound )
+       vulkan? ( video )
+       wayland? ( gles2 )
+       xinerama? ( X )
+       xscreensaver? ( X )"
+
+CDEPEND="
+       alsa? ( >=media-libs/alsa-lib-1.0.27.2[${MULTILIB_USEDEP}] )
+       dbus? ( >=sys-apps/dbus-1.6.18-r1[${MULTILIB_USEDEP}] )
+       fcitx4? ( app-i18n/fcitx:4 )
+       gles1? ( media-libs/mesa[${MULTILIB_USEDEP},gles1] )
+       gles2? ( >=media-libs/mesa-9.1.6[${MULTILIB_USEDEP},gles2] )
+       ibus? ( app-i18n/ibus )
+       jack? ( virtual/jack[${MULTILIB_USEDEP}] )
+       kms? (
+               >=x11-libs/libdrm-2.4.82[${MULTILIB_USEDEP}]
+               >=media-libs/mesa-9.0.0[${MULTILIB_USEDEP},gbm]
+       )
+       libsamplerate? ( media-libs/libsamplerate[${MULTILIB_USEDEP}] )
+       nas? (
+               >=media-libs/nas-1.9.4[${MULTILIB_USEDEP}]
+               >=x11-libs/libXt-1.1.4[${MULTILIB_USEDEP}]
+       )
+       opengl? (
+               >=virtual/opengl-7.0-r1[${MULTILIB_USEDEP}]
+               >=virtual/glu-9.0-r1[${MULTILIB_USEDEP}]
+       )
+       pulseaudio? ( >=media-sound/pulseaudio-2.1-r1[${MULTILIB_USEDEP}] )
+       sndio? ( media-sound/sndio:=[${MULTILIB_USEDEP}] )
+       udev? ( >=virtual/libudev-208:=[${MULTILIB_USEDEP}] )
+       wayland? (
+               >=dev-libs/wayland-1.0.6[${MULTILIB_USEDEP}]
+               >=media-libs/mesa-9.1.6[${MULTILIB_USEDEP},egl,gles2,wayland]
+               >=x11-libs/libxkbcommon-0.2.0[${MULTILIB_USEDEP}]
+       )
+       X? (
+               >=x11-libs/libX11-1.6.2[${MULTILIB_USEDEP}]
+               >=x11-libs/libXcursor-1.1.14[${MULTILIB_USEDEP}]
+               >=x11-libs/libXext-1.3.2[${MULTILIB_USEDEP}]
+               >=x11-libs/libXi-1.7.2[${MULTILIB_USEDEP}]
+               >=x11-libs/libXrandr-1.4.2[${MULTILIB_USEDEP}]
+               >=x11-libs/libXxf86vm-1.1.3[${MULTILIB_USEDEP}]
+               xinerama? ( >=x11-libs/libXinerama-1.1.3[${MULTILIB_USEDEP}] )
+               xscreensaver? ( >=x11-libs/libXScrnSaver-1.2.2-r1[${MULTILIB_USEDEP}] )
+       )"
+RDEPEND="${CDEPEND}
+       vulkan? ( media-libs/vulkan-loader )"
+DEPEND="${CDEPEND}
+       ibus? ( dev-libs/glib:2[${MULTILIB_USEDEP}] )
+       vulkan? ( dev-util/vulkan-headers )
+       X? ( x11-base/xorg-proto )
+"
+BDEPEND="
+       virtual/pkgconfig
+"
+
+MULTILIB_WRAPPED_HEADERS=(
+       /usr/include/SDL2/SDL_config.h
+       /usr/include/SDL2/SDL_platform.h
+       /usr/include/SDL2/begin_code.h
+       /usr/include/SDL2/close_code.h
+)
+
+PATCHES=(
+       "${FILESDIR}"/${PN}-2.0.14-static-libs.patch
+)
+
+S="${WORKDIR}/${MY_P}"
+
+src_prepare() {
+       default
+
+       # Unbundle some headers.
+       rm -r src/video/khronos || die
+       ln -s "${ESYSROOT}/usr/include" src/video/khronos || die
+
+       # SDL seems to customize SDL_config.h.in to remove macros like
+       # PACKAGE_NAME. Add AT_NOEAUTOHEADER="yes" to prevent those macros from
+       # being reintroduced.
+       # https://bugs.gentoo.org/764959
+       AT_NOEAUTOHEADER="yes" AT_M4DIR="/usr/share/aclocal acinclude" \
+               eautoreconf
+}
+
+multilib_src_configure() {
+       use custom-cflags || strip-flags
+
+       if use ibus; then
+               local -x IBUS_CFLAGS="-I${ESYSROOT}/usr/include/ibus-1.0 -I${ESYSROOT}/usr/include/glib-2.0 -I${ESYSROOT}/usr/$(get_libdir)/glib-2.0/include"
+       fi
+
+       # sorted by `./configure --help`
+       local myeconfargs=(
+               $(use_enable static-libs static)
+               --enable-atomic
+               $(use_enable sound audio)
+               $(use_enable video)
+               --enable-render
+               --enable-events
+               $(use_enable joystick)
+               $(use_enable haptic)
+               --enable-power
+               --enable-filesystem
+               $(use_enable threads)
+               --enable-timers
+               --enable-file
+               --enable-loadso
+               --enable-cpuinfo
+               --enable-assembly
+               $(use_enable cpu_flags_ppc_altivec altivec)
+               $(use_enable cpu_flags_x86_sse ssemath)
+               $(use_enable cpu_flags_x86_mmx mmx)
+               $(use_enable cpu_flags_x86_3dnow 3dnow)
+               $(use_enable cpu_flags_x86_sse sse)
+               $(use_enable cpu_flags_x86_sse2 sse2)
+               $(use_enable oss)
+               $(use_enable alsa)
+               --disable-alsa-shared
+               $(use_enable jack)
+               --disable-jack-shared
+               --disable-esd
+               $(use_enable pulseaudio)
+               --disable-pulseaudio-shared
+               --disable-arts
+               $(use_enable libsamplerate)
+               $(use_enable nas)
+               --disable-nas-shared
+               $(use_enable sndio)
+               --disable-sndio-shared
+               $(use_enable sound diskaudio)
+               $(use_enable sound dummyaudio)
+               $(use_enable wayland video-wayland)
+               --disable-wayland-shared
+               $(use_enable video_cards_vc4 video-rpi)
+               $(use_enable X video-x11)
+               --disable-x11-shared
+               $(use_enable X video-x11-xcursor)
+               $(use_enable X video-x11-xdbe)
+               $(use_enable xinerama video-x11-xinerama)
+               $(use_enable X video-x11-xinput)
+               $(use_enable X video-x11-xrandr)
+               $(use_enable xscreensaver video-x11-scrnsaver)
+               $(use_enable X video-x11-xshape)
+               $(use_enable X video-x11-vm)
+               $(use_enable aqua video-cocoa)
+               --disable-video-directfb
+               --disable-fusionsound
+               --disable-fusionsound-shared
+               $(use_enable kms video-kmsdrm)
+               --disable-kmsdrm-shared
+               $(use_enable video video-dummy)
+               $(use_enable opengl video-opengl)
+               $(use_enable gles1 video-opengles1)
+               $(use_enable gles2 video-opengles2)
+               $(use_enable vulkan video-vulkan)
+               $(use_enable udev libudev)
+               $(use_enable dbus)
+               $(use_enable fcitx4 fcitx)
+               $(use_enable ibus)
+               --disable-directx
+               --disable-rpath
+               --disable-render-d3d
+               $(use_with X x)
+       )
+
+       ECONF_SOURCE="${S}" \
+       econf "${myeconfargs[@]}"
+}
+
+multilib_src_compile() {
+       emake V=1
+}
+
+multilib_src_install() {
+       emake DESTDIR="${D}" install
+}
+
+multilib_src_install_all() {
+       # Do not delete the static .a libraries here as some are
+       # mandatory. They may be needed even when linking dynamically.
+       find "${ED}" -type f -name "*.la" -delete || die
+       dodoc {BUGS,CREDITS,README,README-SDL,TODO,WhatsNew}.txt docs/README*.md
+}
diff --git a/media-plugins/eq10q/Manifest b/media-plugins/eq10q/Manifest
new file mode 100644 (file)
index 0000000..437bf0a
--- /dev/null
@@ -0,0 +1,3 @@
+AUX eq10q-2.2_p1.patch 6249 BLAKE2B 0e736648e3e0f2ca403e1f84da1d861393b65878dee1cd2610615fac49757e47d8a3abcf7534f8c17b4ebe81642e39d58c3d1a4ca38d5d658f03d5c2001405fb SHA512 0192d672d61cfcbe78f6f9fbd3ebd694c177136f5aa469f1f347d2da7ac3f3773fbf659f216af16b176c025808c160ec7ad6c9c4cb29c819ae5ff017cbea553c
+DIST eq10q-2.2.tar.gz 797991 BLAKE2B 453cf8e0dcb330e92dfa6be65a83c63c05450956ea9dcef49206d83758c8ea0746cde7d26932e709116a44eb2ce30bb29fa5a4753f5597e71128767b462cb024 SHA512 4c6a79e9f1faeb431abd4e94b6bfa153b1ff5f55b3c2734d35a865ba23e3a7786ee45ee122cdcc26c9a8de915f1c4e2ec588a4c219ad6daf0ccf4a2b474b1e24
+EBUILD eq10q-2.2_p1.ebuild 592 BLAKE2B 14c8ff565d4afa3f673986fc3135d9a0a4b6b254232f875a67dd09d5fb21de4a8b2ecae8f8b0193240707aecdec8e63d86b862b688d518de2c86a5cf53aba182 SHA512 7d1db741084ef19fe26ae545ff8474865c6332e5fde5af1ea619eb6a03e7620c5c1b706b2aa7e2eda37f032270895b6a6d8028020f5d8de3e454075142dc0086
diff --git a/media-plugins/eq10q/eq10q-2.2_p1.ebuild b/media-plugins/eq10q/eq10q-2.2_p1.ebuild
new file mode 100644 (file)
index 0000000..7179d12
--- /dev/null
@@ -0,0 +1,26 @@
+EAPI=8
+
+inherit cmake
+
+DESCRIPTION="10-Band parametric equalizer with mono (M) and stereo (S) versions."
+HOMEPAGE="http://eq10q.sourceforge.net"
+SRC_URI="https://downloads.sourceforge.net/project/eq10q/eq10q-2.2.tar.gz"
+LICENSE="GPL2"
+SLOT="0"
+KEYWORDS="amd64"
+IUSE=""
+
+S="${WORKDIR}/${PN}-${PV%_*}"
+BDEPEND="      >=dev-build/cmake-2.8.2"
+RDEPEND="      >=sci-libs/fftw-3.0.0
+                       media-libs/lv2
+                       >=dev-cpp/gtkmm-2.4.0"
+DEPEND=${RDEPEND}
+
+PATCHES=("${FILESDIR}/${P}.patch")
+
+src_configure() {
+       LV2_PATH="/usr/lib64/lv2"
+       local mycmakeargs=(-DCMAKE_INSTALL_PREFIX="${LV2_PATH}")
+       cmake_src_configure
+}
diff --git a/media-plugins/eq10q/files/eq10q-2.2_p1.patch b/media-plugins/eq10q/files/eq10q-2.2_p1.patch
new file mode 100644 (file)
index 0000000..00ba280
--- /dev/null
@@ -0,0 +1,130 @@
+diff -ur a/gui/widgets/bandctl.cpp b/gui/widgets/bandctl.cpp
+--- a/gui/widgets/bandctl.cpp  2021-06-15 03:51:56.238939262 +0100
++++ b/gui/widgets/bandctl.cpp  2021-06-15 03:50:52.626945261 +0100
+@@ -949,7 +949,7 @@
+   if(str_k.length() > 0)
+   {
+     val_k = atof(str_k.c_str()) * 1e3;
+-    val *= pow10(3.0 - str.length());
++    val *= exp10(3.0 - str.length());
+     if(str.length() > 3)
+     {
+       //throw an error, imposible to match str > 3 with k
+@@ -960,7 +960,7 @@
+   }
+   if(str_d.length() > 0)
+   {
+-    val_d = atof(str_d.c_str())/ pow10((double)str_d.length());
++    val_d = atof(str_d.c_str())/ exp10((double)str_d.length());
+   }
+    
+   btn->value = val + val_k + val_d;
+diff -ur a/gui/widgets/bodeplot.cpp b/gui/widgets/bodeplot.cpp
+--- a/gui/widgets/bodeplot.cpp 2021-06-15 03:51:56.238939262 +0100
++++ b/gui/widgets/bodeplot.cpp 2021-06-15 03:50:52.627945261 +0100
+@@ -194,14 +194,14 @@
+ {
+   //Compute center and span for the full range spectrum
+   double sp = log10(MAX_FREQ/MIN_FREQ);
+-  double cn = MIN_FREQ * sqrt(pow10(sp));
++  double cn = MIN_FREQ * sqrt(exp10(sp));
+   setCenterSpan(cn, sp);
+ }
+ void PlotEQCurve::setCenterSpan(double center, double span)
+ { 
+-  m_minFreq = center / sqrt(pow10(span));
+-  m_maxFreq = center * sqrt(pow10(span));
++  m_minFreq = center / sqrt(exp10(span));
++  m_maxFreq = center * sqrt(exp10(span));
+     
+   //Initalize the grid
+   const double f_grid[GRID_VERTICAL_LINES] = {20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0,
+@@ -246,8 +246,8 @@
+ {
+   //Limit center to the possible range according the current span
+   double sp = log10(m_maxFreq/m_minFreq);
+-  double cmin = MIN_FREQ * sqrt(pow10(sp));
+-  double cmax = MAX_FREQ / sqrt(pow10(sp));
++  double cmin = MIN_FREQ * sqrt(exp10(sp));
++  double cmax = MAX_FREQ / sqrt(exp10(sp));
+   
+   double cn = center;
+   cn = cn > cmax ? cmax : cn;
+@@ -259,7 +259,7 @@
+ {
+   //Limit center to the possible range according the current span
+   double sp_act = log10(m_maxFreq/m_minFreq);
+-  double cn = m_minFreq * sqrt(pow10(sp_act));
++  double cn = m_minFreq * sqrt(exp10(sp_act));
+   double smax1 = 2.0*log10(cn/MIN_FREQ);
+   double smax2= 2.0*log10(MAX_FREQ/cn);
+   double smax = smax1 < smax2 ? smax1 : smax2;
+@@ -306,7 +306,7 @@
+   double fmax = MIN_FREQ*pow((MAX_FREQ/MIN_FREQ),((local_x2 + 3.5)/((double)m_zoom_surface_ptr->get_width())));
+   
+   double sp_act = log10(fmax/fmin);
+-  double cn = fmin * sqrt(pow10(sp_act));
++  double cn = fmin * sqrt(exp10(sp_act));
+   setCenter(cn);
+ }
+diff -ur a/gui/bassup_ui.cpp b/gui/bassup_ui.cpp
+--- a/gui/bassup_ui.cpp        2021-06-15 03:28:55.830627105 +0100
++++ b/gui/bassup_ui.cpp        2021-06-15 03:30:11.165675246 +0100
+@@ -38,7 +38,7 @@
+ #define BASSUP_GUI_URI "http://eq10q.sourceforge.net/bassup/gui"
+-static LV2UI_Handle instantiateBassUp_gui(const _LV2UI_Descriptor *descriptor, const char *plugin_uri, const char *bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget *widget, const LV2_Feature *const *features)
++static LV2UI_Handle instantiateBassUp_gui(const LV2UI_Descriptor *descriptor, const char *plugin_uri, const char *bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget *widget, const LV2_Feature *const *features)
+ {
+   #ifdef TESTING_EQ10Q
+   cout<<"instantiateEq10q_gui Entring... ";
+diff -ur a/gui/dyn_ui.cpp b/gui/dyn_ui.cpp
+--- a/gui/dyn_ui.cpp   2021-06-15 03:28:55.829627105 +0100
++++ b/gui/dyn_ui.cpp   2021-06-15 03:30:11.165675246 +0100
+@@ -37,7 +37,7 @@
+ using namespace std;
+ #endif
+-static LV2UI_Handle instantiateDyn_gui(const _LV2UI_Descriptor *descriptor, const char *plugin_uri, const char *bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget *widget, const LV2_Feature *const *features)
++static LV2UI_Handle instantiateDyn_gui(const LV2UI_Descriptor *descriptor, const char *plugin_uri, const char *bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget *widget, const LV2_Feature *const *features)
+ {
+   #ifdef TESTING_EQ10Q
+   cout<<"instantiateDyn_gui Entring... ";
+diff -ur a/gui/eq10q_ui.cpp b/gui/eq10q_ui.cpp
+--- a/gui/eq10q_ui.cpp 2021-06-15 03:28:55.829627105 +0100
++++ b/gui/eq10q_ui.cpp 2021-06-15 03:30:11.165675246 +0100
+@@ -38,7 +38,7 @@
+ #endif
+-static LV2UI_Handle instantiateEq10q_gui(const _LV2UI_Descriptor *descriptor, const char *plugin_uri, const char *bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget *widget, const LV2_Feature *const *features)
++static LV2UI_Handle instantiateEq10q_gui(const LV2UI_Descriptor *descriptor, const char *plugin_uri, const char *bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget *widget, const LV2_Feature *const *features)
+ {
+   #ifdef TESTING_EQ10Q
+   cout<<"instantiateEq10q_gui Entring... ";
+diff -ur a/gui/midside_ui.cpp b/gui/midside_ui.cpp
+--- a/gui/midside_ui.cpp       2021-06-15 03:28:55.830627105 +0100
++++ b/gui/midside_ui.cpp       2021-06-15 03:30:11.165675246 +0100
+@@ -37,7 +37,7 @@
+ using namespace std;
+ #endif
+-static LV2UI_Handle instantiateMidSide_gui(const _LV2UI_Descriptor *descriptor, const char *plugin_uri, const char *bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget *widget, const LV2_Feature *const *features)
++static LV2UI_Handle instantiateMidSide_gui(const LV2UI_Descriptor *descriptor, const char *plugin_uri, const char *bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget *widget, const LV2_Feature *const *features)
+ {
+   #ifdef TESTING_EQ10Q
+   cout<<"instantiateEq10q_gui Entring... ";
+diff -ur a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt    2022-08-03 02:51:28.641759147 +0100
++++ b/CMakeLists.txt    2022-08-03 02:54:47.613817334 +0100
+@@ -14,7 +14,7 @@
+ #Set Install prefix
+ #_cmake_modify_IGNORE set (CMAKE_INSTALL_PREFIX  "/usr/local/lib/lv2") #Install prefix
+ #set (CMAKE_INSTALL_PREFIX  "$ENV{HOME}/.lv2") #Install prefix
+-set (LV2_BUNDLE "sapistaEQv2.lv2") #LV2 Bundel dir
++set (LV2_BUNDLE "eq10q.lv2") #LV2 Bundel dir
+ set(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/bin")
+ set(LIBRARY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/bin")
diff --git a/media-sound/audacity/Manifest b/media-sound/audacity/Manifest
new file mode 100644 (file)
index 0000000..dbcaade
--- /dev/null
@@ -0,0 +1,12 @@
+AUX audacity-3.0.2-disable-ccache.patch 517 BLAKE2B 68905209219fda1a30ed7cd7d5b305ccb5dd76f0ddde5edf832405ba54f72e8630385619c0600cbfefb3e01638cc399c190bc4e005ca2ba24ce8b884e437a5a6 SHA512 0059a8cfcc60bd868e08196941e4ae2e8733d9cad99179c89033108f003eb2e75395e81ac32f3f4b9684404effc632af8107caed044c8ba39d70aa9ce164bbd7
+AUX audacity-3.0.2-fix-gettimeofday.patch 311 BLAKE2B 1461b57759c42cc9b1b505a8454041bb83bfc70584e472ddf7c466acfb88bdd2a722fd4e0a54e89f3235f4af2ccb7e896ebf79271fe0825b798d42a2c5be3948 SHA512 468cdf4edc4b0ba08f4525226ece7c383a0e2264615977c4b94063396c8d26e1321c4973a41540eed34d358fcb8151046bf2c05d07e968cbfa91d35ec8f03f7d
+AUX audacity-3.0.2-fix-jack_support.patch 485 BLAKE2B 9c5c06f741e43e6e8c1fad7a62c8ed298ddebc4ca9fefd790afdae8de882f815470adc1f82078295afc922da002e2fe196dfdb5e8f994a214f421766c90905d1 SHA512 22c3557847bedd6cd8e36b039bcce67f269c49caf204bb820ec7f66b8aecbea6aec624e89f9309fa2808a5bb3f7f04d964a230c96736d7992103ca8b07166d8a
+AUX audacity-3.0.2-fix-metainfo.patch 485 BLAKE2B 8272a5ed9530e53e65498f324cde9e2b62fa7eddb3bbeda701c9c3bb04fa96bbb1ab43aed86e63fe6eeee8fe54477567afc13bc06931320c192d216a1424db58 SHA512 8ba35601db82f9490c89ccb138faf476d437b94b329fdcb4320d61ca74c48e312d2d6e513314a827b6bf88c723a4a265ddd115d61b3183806a258983f9b6254c
+AUX audacity-3.0.2-gentoo-wx-build.patch 1278 BLAKE2B 684a3585da98af5958a5e20e698130ec75401849790dc15f7c49c34ec590398c9b4177db437f7e38f208d1484d037023bbe0db1a4344760d06035620b5d583da SHA512 4e64e665b8a8d1d3b8b0fc36c64312407e3ca7190e0380129a98cc3af6f8007b3981d910dde3305da6b1f0ef9d2af89025731e273e888d5187e428261b521d24
+DIST audacity-minsrc-3.0.2.tar.xz 13330160 BLAKE2B a29d1d2dc661c240242e01f3a393b5437b364d527341562ebb644e8753c00097f9c73083c14b177517e38d76c613f7582b97f9a15ab99f01bcbbff7817f54868 SHA512 9fb57b218ff9fdedc21a18feae7a7cac68db4ddcf92b4292ff11e516528f58e9a3c52cccb55b6e40af1e03f1eba0315ea97f77312709cce8d17eb43771a896aa
+DIST audacity-wxwidgets-3.1.3.tar.gz 116271058 BLAKE2B 0ddcd4703b435c1b6ad40d4c91e339e92845947f289d564e29b863552473d307c9aa082a21603755e5e44d4b6815e6868de211691c99fcd8d0357b7236daba91 SHA512 ff9248fc2a51540b521853ba856f4421191a4267cf3934b3a02ca595ede2c13f705376f8e4a00c3a2d0e8cbe5060ec1ef281f65e87ed56e876844f791a22ffa5
+DIST master.zip 23496012 BLAKE2B 61f1cc6aa6e9dfdb5d1d215629571fe80452b0e350b74daa4f7c92c8dd84adf109f93d775f063ea84845c24583289a3327ddeaf34be5ec03e20698fbf85e0b54 SHA512 e53d22592d1d666c277d33a0046874a3c88fe9ce0e9f11c05826ba6a560bd47d272c926d54362d8117f6f3717d11a6dd73cfad37d8bbd4a7483a7fb1a978d74a
+DIST v3.1.3-audacity.tar.gz 20459376 BLAKE2B 1851c0dc4fa1455a80821667c366847b831af587512f321f2d81f4d4f65cc2db0bb84c39d78c135bd40ac62016935f9428f681b993f5b8f2b04403dc463483e5 SHA512 6d613e652236ac34cfb4a56d932f2d6da7254bca6d9e7e8889e331e338e297ea2c09b18df075cef9fb02a789b443fc4455054c566b87c0b356b41e0831d8cb91
+EBUILD audacity-3.0.2-r1.ebuild 4074 BLAKE2B 0b4061d474a198880fd0dac982033013fa483fc1f8064d15aabcc9545c477bffbb362b1882d28023f791c830cb0b7c93e3f0ef4af6ba32af1bde436956de9ffd SHA512 d5d3de4f577e2026474f13e7917f9e1a5c6eaf4f1f8dd820aa7f1c0ec479bfdc530c75a74ae5907f5263ebaccfd92812da50748e7519ab619ec86f59b39b1aab
+EBUILD audacity-3.0.2.ebuild 3954 BLAKE2B a98efabdeca5c1d9f7a9cd91985297bb6b28d9b327dd6ac366da2629317d5b9451a2454245ebfca7e52b83a0627cdb663a4e126bb8ddb439adc4d6ff15e4336e SHA512 5285d4b5bbc24eebe4f3c444d0c66565bb57a533d5563a24c1a28744e978b5007ca5bd57fc6640e4856fe671bbd0c45439dd4977a78aabbceefc4f472b91ec56
+MISC metadata.xml 1202 BLAKE2B 2d3da00c349554901026197a6c383b16138b4295c113affdcd6d83cc370fc3d5f3c5010971dc7feda71942d998a0043e3a216e646b6a72c2eb6f61bb06ccc178 SHA512 999f3fa992af333d1b64fb558c44e43ac6978f779975bc929a3c615c43c831e5db4c83b4e39240ac1dade66a2d2afade7b8e5828b88cd75de8ddb0a2284121ad
diff --git a/media-sound/audacity/audacity-3.0.2-r1.ebuild b/media-sound/audacity/audacity-3.0.2-r1.ebuild
new file mode 100644 (file)
index 0000000..70aa620
--- /dev/null
@@ -0,0 +1,126 @@
+# Copyright 1999-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+WID_VER="3.1.3"
+WX_GTK_VER="3.0-gtk3"
+
+inherit cmake flag-o-matic xdg wxwidgets
+
+MY_P="Audacity-${PV}"
+DOC_PV="${PV}"
+DESCRIPTION="Free crossplatform audio editor"
+HOMEPAGE="https://web.audacityteam.org/"
+SRC_URI="      https://github.com/${PN}/${PN}/releases/download/${P^}/${PN}-minsrc-${PV}.tar.xz
+                       https://github.com/${PN}/wxWidgets/archive/refs/tags/v${WID_VER}-${PN}.tar.gz
+doc? (         https://github.com/${PN}/${PN}-manual/archive/refs/heads/master.zip )"
+
+S="${WORKDIR}/${PN}-minsrc-${PV}"
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="~amd64 ~arm64 ~mips ~ppc ~ppc64 ~x86"
+IUSE="alsa doc ffmpeg flac id3tag jack ladspa lv2 mad ogg oss pch portmidi portmixer portsmf sbsms soundtouch expat lame sndfile soxr sqlite twolame vamp vorbis vst"
+RESTRICT="test"
+RDEPEND="
+       "x11-libs/wxGTK:${WX_GTK_VER}"
+       expat? ( >=dev-libs/expat-2.1.0 )
+       lame? ( >=media-sound/lame-3.100 )
+       sndfile? ( >=media-libs/libsndfile-1.0.28 )
+       soxr? ( >=media-libs/soxr-0.1.1 )
+       sqlite? ( >=dev-db/sqlite-3.32.0:3 )
+
+       ffmpeg? ( media-video/ffmpeg )
+       id3tag? ( >=media-libs/libid3tag-0.15.1b )
+       mad? ( >=media-libs/libmad-0.15.1b )
+       vamp? ( >=media-libs/vamp-plugin-sdk-2.5 )
+       ogg? ( >=media-libs/libogg-1.3.1 )
+       vorbis? ( >=media-libs/libvorbis-1.3.3 )
+       flac? ( >=media-libs/flac-1.3.1[cxx] )
+       lv2? (
+               >=media-libs/lilv-0.24.6
+               >=media-libs/lv2-1.16.0
+               >=dev-libs/serd-0.30.2
+               >=dev-libs/sord-0.16.4
+               >=media-libs/sratom-0.6.4
+               >=media-libs/suil-0.10.6
+       )
+       portmidi? ( >=media-libs/portmidi-0.1 )
+       soundtouch? ( >=media-libs/libsoundtouch-1.7.1 )
+       twolame? ( >=media-sound/twolame-0.3.13 )
+
+       alsa? ( media-libs/alsa-lib )
+       jack? ( virtual/jack )
+"
+       #sbsms? ( >=media-libs/libsbsms-2.2.0 ) #can't use yet, not in the tree.
+
+DEPEND="${RDEPEND}"
+BDEPEND="app-arch/unzip
+       sys-devel/gettext
+       virtual/pkgconfig
+"
+
+REQUIRED_USE="portmidi? ( portsmf )"
+
+PATCHES=(
+       "${FILESDIR}/${P}-fix-jack_support.patch"
+       "${FILESDIR}/${P}-fix-gettimeofday.patch"
+       "${FILESDIR}/${P}-fix-metainfo.patch"
+       "${FILESDIR}/${P}-disable-ccache.patch"
+       "${FILESDIR}/${P}-gentoo-wx-build.patch"
+)
+
+src_prepare() {
+       cmake_src_prepare
+       WID_SRC="${BUILD_DIR}/cmake-proxies/wxWidgets/wxwidgets"
+       mkdir "${WID_SRC%/*}" -p
+       mv "${WORKDIR}/wxWidgets-${WID_VER}-${PN}" "${WID_SRC}"
+}
+
+src_configure() {
+       append-cxxflags -std=gnu++14
+       # * always use system libraries if possible
+       # * options listed in the order that lists them
+       local mycmakeargs=(
+               -DCMAKE_BUILD_TYPE=Release
+               -Daudacity_lib_preference=system
+               -Daudacity_use_wxwidgets=gentoo
+               -Daudacity_use_pa_alsa=$(usex alsa system off)
+               -Daudacity_use_ffmpeg=$(usex ffmpeg loaded off)
+               -Daudacity_use_flac=$(usex flac system off)
+               -Daudacity_use_id3tag=$(usex id3tag system off)
+               -Daudacity_use_pa_jack=$(usex jack loaded off)
+               -Daudacity_use_ladspa=$(usex ladspa)
+               -Daudacity_use_lv2=$(usex lv2 system off)
+               -Daudacity_use_mad=$(usex mad system off)
+               -Daudacity_use_midi=$(usex portmidi system off)
+               -Daudacity_use_ogg=$(usex ogg system off)
+               -Daudacity_use_portmixer=$(usex portmixer local off)
+               -Daudacity_use_portsmf=$(usex portsmf local off)
+               -Daudacity_use_sbsms=$(usex sbsms local off)
+               ## ^^ fix when suitable version is in portage ^^ ##
+               -Daudacity_use_soundtouch=$(usex soundtouch system off)
+               -Daudacity_use_expat=$(usex expat system local)
+               -Daudacity_use_lame=$(usex lame system local)
+               -Daudacity_use_sndfile=$(usex sndfile system local)
+               -Daudacity_use_soxr=$(usex soxr system local)
+               -Daudacity_use_sqlite=$(usex sqlite system local)
+               -Daudacity_use_vamp=$(usex vamp system off)
+               -Daudacity_use_vorbis=$(usex vorbis system off)
+               -Daudacity_use_vst=$(usex vst)
+       )
+       cmake_src_configure
+}
+
+src_install() {
+       cmake_src_install
+
+        Remove bad doc install
+       rm -r "${ED}"/usr/share/doc || die
+
+       if use doc ; then
+               docinto html
+               dodoc -r "${WORKDIR}"/audacity-manual-master/manual/{m,man}
+               dodoc "${WORKDIR}"/audacity-manual-master/manual/{favicon.ico,index.html,quick_help.html}
+               dosym ../../doc/${PF}/html /usr/share/${PN}/help/manual
+       fi
+}
diff --git a/media-sound/audacity/audacity-3.0.2.ebuild b/media-sound/audacity/audacity-3.0.2.ebuild
new file mode 100644 (file)
index 0000000..757d424
--- /dev/null
@@ -0,0 +1,124 @@
+# Copyright 1999-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+WX_VER="3.1.3"
+WX_GTK_VER="3.0-gtk3"
+
+inherit cmake flag-o-matic xdg wxwidgets
+
+MY_P="Audacity-${PV}"
+DOC_PV="${PV}"
+DESCRIPTION="Free crossplatform audio editor"
+HOMEPAGE="https://web.audacityteam.org/"
+SRC_URI="      https://github.com/${PN}/${PN}/releases/download/${P^}/${PN}-minsrc-${PV}.tar.xz
+                       https://liquid.me.uk/${PN}-wxwidgets-${WX_VER}.tar.gz
+doc? (         https://github.com/${PN}/${PN}-manual/archive/refs/heads/master.zip )"
+
+S="${WORKDIR}/${PN}-minsrc-${PV}"
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="~amd64 ~arm64 ~mips ~ppc ~ppc64 ~x86"
+IUSE="alsa doc ffmpeg flac id3tag jack ladspa lv2 mad ogg oss pch portmidi portmixer portsmf sbsms soundtouch expat lame sndfile soxr sqlite twolame vamp vorbis vst"
+RESTRICT="test"
+RDEPEND="
+       "x11-libs/wxGTK:${WX_GTK_VER}"
+       expat? ( >=dev-libs/expat-2.1.0 )
+       lame? ( >=media-sound/lame-3.100 )
+       sndfile? ( >=media-libs/libsndfile-1.0.28 )
+       soxr? ( >=media-libs/soxr-0.1.1 )
+       sqlite? ( >=dev-db/sqlite-3.32.0:3 )
+
+       ffmpeg? ( media-video/ffmpeg )
+       id3tag? ( >=media-libs/libid3tag-0.15.1b )
+       mad? ( >=media-libs/libmad-0.15.1b )
+       vamp? ( >=media-libs/vamp-plugin-sdk-2.5 )
+       ogg? ( >=media-libs/libogg-1.3.1 )
+       vorbis? ( >=media-libs/libvorbis-1.3.3 )
+       flac? ( >=media-libs/flac-1.3.1[cxx] )
+       lv2? (
+               >=media-libs/lilv-0.24.6
+               >=media-libs/lv2-1.16.0
+               >=dev-libs/serd-0.30.2
+               >=dev-libs/sord-0.16.4
+               >=media-libs/sratom-0.6.4
+               >=media-libs/suil-0.10.6
+       )
+       portmidi? ( >=media-libs/portmidi-0.1 )
+       soundtouch? ( >=media-libs/libsoundtouch-1.7.1 )
+       twolame? ( >=media-sound/twolame-0.3.13 )
+
+       alsa? ( media-libs/alsa-lib )
+       jack? ( virtual/jack )
+"
+       #sbsms? ( >=media-libs/libsbsms-2.2.0 ) #can't use yet, not in the tree.
+
+DEPEND="${RDEPEND}"
+BDEPEND="app-arch/unzip
+       sys-devel/gettext
+       virtual/pkgconfig
+"
+
+REQUIRED_USE="portmidi? ( portsmf )"
+
+PATCHES=(
+       "${FILESDIR}/${P}-fix-jack_support.patch"
+       "${FILESDIR}/${P}-fix-gettimeofday.patch"
+       "${FILESDIR}/${P}-fix-metainfo.patch"
+       "${FILESDIR}/${P}-disable-ccache.patch"
+       "${FILESDIR}/${P}-gentoo-wx-build.patch"
+)
+
+src_prepare() {
+       cmake_src_prepare
+       mv "${WORKDIR}/cmake-proxies" "${BUILD_DIR}"
+}
+
+src_configure() {
+       append-cxxflags -std=gnu++14
+       # * always use system libraries if possible
+       # * options listed in the order that lists them
+       local mycmakeargs=(
+               -DCMAKE_BUILD_TYPE=Release
+               -Daudacity_lib_preference=system
+               -Daudacity_use_wxwidgets=gentoo
+               -Daudacity_use_pa_alsa=$(usex alsa system off)
+               -Daudacity_use_ffmpeg=$(usex ffmpeg loaded off)
+               -Daudacity_use_flac=$(usex flac system off)
+               -Daudacity_use_id3tag=$(usex id3tag system off)
+               -Daudacity_use_pa_jack=$(usex jack loaded off)
+               -Daudacity_use_ladspa=$(usex ladspa)
+               -Daudacity_use_lv2=$(usex lv2 system off)
+               -Daudacity_use_mad=$(usex mad system off)
+               -Daudacity_use_midi=$(usex portmidi system off)
+               -Daudacity_use_ogg=$(usex ogg system off)
+               -Daudacity_use_portmixer=$(usex portmixer local off)
+               -Daudacity_use_portsmf=$(usex portsmf local off)
+               -Daudacity_use_sbsms=$(usex sbsms local off)
+               ## ^^ fix when suitable version is in portage ^^ ##
+               -Daudacity_use_soundtouch=$(usex soundtouch system off)
+               -Daudacity_use_expat=$(usex expat system local)
+               -Daudacity_use_lame=$(usex lame system local)
+               -Daudacity_use_sndfile=$(usex sndfile system local)
+               -Daudacity_use_soxr=$(usex soxr system local)
+               -Daudacity_use_sqlite=$(usex sqlite system local)
+               -Daudacity_use_vamp=$(usex vamp system off)
+               -Daudacity_use_vorbis=$(usex vorbis system off)
+               -Daudacity_use_vst=$(usex vst)
+       )
+       cmake_src_configure
+}
+
+src_install() {
+       cmake_src_install
+
+        Remove bad doc install
+       rm -r "${ED}"/usr/share/doc || die
+
+       if use doc ; then
+               docinto html
+               dodoc -r "${WORKDIR}"/audacity-manual-master/manual/{m,man}
+               dodoc "${WORKDIR}"/audacity-manual-master/manual/{favicon.ico,index.html,quick_help.html}
+               dosym ../../doc/${PF}/html /usr/share/${PN}/help/manual
+       fi
+}
diff --git a/media-sound/audacity/files/audacity-3.0.2-disable-ccache.patch b/media-sound/audacity/files/audacity-3.0.2-disable-ccache.patch
new file mode 100644 (file)
index 0000000..3c7b126
--- /dev/null
@@ -0,0 +1,17 @@
+diff -ur a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt    2021-06-16 19:27:39.958424889 +0100
++++ b/CMakeLists.txt    2021-06-16 19:28:31.819492780 +0100
+@@ -74,14 +74,6 @@
+ set( CMAKE_CXX_STANDARD 14 )
+ set( CMAKE_CXX_STANDARD_REQUIRED ON )
+-# Use ccache if available
+-find_program( CCACHE_PROGRAM ccache )
+-mark_as_advanced( FORCE CCACHE_PROGRAM )
+-
+-if( CCACHE_PROGRAM )
+-   set_property( GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}" )
+-endif()
+-
+ # Our very own project
+ project( Audacity )
diff --git a/media-sound/audacity/files/audacity-3.0.2-fix-gettimeofday.patch b/media-sound/audacity/files/audacity-3.0.2-fix-gettimeofday.patch
new file mode 100644 (file)
index 0000000..4f9fe98
--- /dev/null
@@ -0,0 +1,11 @@
+diff -ur a/src/AudioIO.cpp b/src/AudioIO.cpp
+--- a/src/AudioIO.cpp   2021-06-16 19:12:33.010241391 +0100
++++ b/src/AudioIO.cpp   2021-06-16 19:11:22.813162783 +0100
+@@ -427,6 +427,7 @@
+ #include <math.h>
+ #include <stdlib.h>
+ #include <algorithm>
++#include <sys/time.h>
+ #ifdef __WXMSW__
+ #include <malloc.h>
diff --git a/media-sound/audacity/files/audacity-3.0.2-fix-jack_support.patch b/media-sound/audacity/files/audacity-3.0.2-fix-jack_support.patch
new file mode 100644 (file)
index 0000000..037e8ac
--- /dev/null
@@ -0,0 +1,12 @@
+diff -ur a/cmake-proxies/portaudio-v19/CMakeLists.txt b/cmake-proxies/portaudio-v19/CMakeLists.txt
+--- a/cmake-proxies/portaudio-v19/CMakeLists.txt       2021-06-16 22:38:35.187099781 +0100
++++ b/cmake-proxies/portaudio-v19/CMakeLists.txt       2021-06-16 22:39:54.212204914 +0100
+@@ -88,7 +88,7 @@
+ if( NOT ${_OPT}use_pa_jack STREQUAL "off" )
+    # Find it
+-   find_package( jack )
++   find_package( Jack )
+    if( NOT JACK_FOUND)
+       set_cache_value( ${_OPT}use_pa_jack "off" )
+    endif()
diff --git a/media-sound/audacity/files/audacity-3.0.2-fix-metainfo.patch b/media-sound/audacity/files/audacity-3.0.2-fix-metainfo.patch
new file mode 100644 (file)
index 0000000..b0fa690
--- /dev/null
@@ -0,0 +1,12 @@
+diff -ur a/help/CMakeLists.txt b/help/CMakeLists.txt
+--- a/help/CMakeLists.txt       2021-06-16 19:15:42.501459678 +0100
++++ b/help/CMakeLists.txt       2021-06-16 19:17:13.109584392 +0100
+@@ -41,7 +41,7 @@
+       install( FILES "${_SRCDIR}/audacity.1"
+                DESTINATION "${_MANDIR}/man1" )
+       install( FILES "${_SRCDIR}/audacity.appdata.xml"
+-               DESTINATION "${_DATADIR}/appdata" )
++               DESTINATION "${_DATADIR}/metainfo" )
+    endif()
+ endif()
diff --git a/media-sound/audacity/files/audacity-3.0.2-gentoo-wx-build.patch b/media-sound/audacity/files/audacity-3.0.2-gentoo-wx-build.patch
new file mode 100644 (file)
index 0000000..d485f8b
--- /dev/null
@@ -0,0 +1,34 @@
+diff -ur a/cmake-proxies/wxWidgets/CMakeLists.txt b/cmake-proxies/wxWidgets/CMakeLists.txt
+--- a/cmake-proxies/wxWidgets/CMakeLists.txt   2021-06-17 01:50:25.976610830 +0100
++++ b/cmake-proxies/wxWidgets/CMakeLists.txt   2021-06-17 01:53:09.771826826 +0100
+@@ -9,7 +9,7 @@
+ cmd_option( ${_OPT}use_wxwidgets
+             "Use ${name} library [system (if available), local]"
+             "${audacity_lib_preference}"
+-            STRINGS "system" "local"
++            STRINGS "system" "local" "gentoo"
+ )
+ if( ${_OPT}use_wxwidgets STREQUAL "system" )
+@@ -74,15 +74,18 @@
+    set( toolkit "${wxWidgets_LIBRARIES}" )
+ else()
+-   message( STATUS "Using local '${name}' library" )
+-
++   if( ${_OPT}use_wxwidgets STREQUAL "gentoo" )
++      message( STATUS "Using gentoo local '${name}' library" )
++   else()
++      message( STATUS "Using local '${name}' library" )
++   endif()
+    set( WXWIN $ENV{WXWIN} )
+    if( "${WXWIN}" STREQUAL "" )
+       # XXX: Look into importing instead of adding to this project
+       set( WXWIN "${_INTDIR}/wxwidgets" )
+    endif()
+-   if( NOT EXISTS "${WXWIN}" )
++   if( NOT EXISTS "${WXWIN}" AND NOT ${_OPT}use_wxwidgets STREQUAL "gentoo" )
+       if( NOT GIT_FOUND )
+          message( FATAL_ERROR "Git is needed to clone wxWidgets" )
+       endif()
diff --git a/media-sound/audacity/metadata.xml b/media-sound/audacity/metadata.xml
new file mode 100644 (file)
index 0000000..65e44eb
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+  <maintainer type="project">
+    <email>proaudio@gentoo.org</email>
+    <name>Gentoo ProAudio Project</name>
+  </maintainer>
+  <maintainer type="person" proxied="yes">
+    <email>richard@audacityteam.org</email>
+    <name>Richard Ash</name>
+    <description>Upstream - please CC on bugs that concerns upstream</description>
+  </maintainer>
+  <use>
+    <flag name="id3tag">Enables ID3 tagging with id3tag library</flag>
+    <flag name="lv2">Add support for Ladspa V2</flag>
+    <flag name="portmidi">Enable support for MIDI via media-libs/portmidi</flag>
+    <flag name="portmixer">Enable the internal portmixer feature</flag>
+    <flag name="portsmf">Enable support for Portable Standard Midi File Library</flag>
+    <flag name="sbsms">Enables sbsms library support for slower, more accurate
+      pitch and tempo changing</flag>
+    <flag name="twolame">Enables twolame support (MPEG Audio Layer 2 encoder)</flag>
+    <flag name="vamp">Enables vamp plugins support (Audio analysing plugins)</flag>
+    <flag name="vst">Enable VST plugin support</flag>
+  </use>
+</pkgmetadata>
diff --git a/media-sound/jack2/Manifest b/media-sound/jack2/Manifest
new file mode 100644 (file)
index 0000000..730e688
--- /dev/null
@@ -0,0 +1,4 @@
+DIST jack2-1.9.18.tar.gz 987166 BLAKE2B e1684d50c26ce45b36133b5e9632e916cd5bdf2a2ffba9257d7d6018d9fab8ade87f2de4c837d3cc3cb37bdda296fbcd8c2da6468676a3a4c74563fb42397879 SHA512 7b9116b8002db88d9df746acf99e523cf9103c1a7955e8174912c8538b2c53bc8e7c34a64d0df4dc1f212e35035392814fdfcfe78597e26bd08ec028876bcb98
+DIST jack2-1.9.19.tar.gz 988780 BLAKE2B 37536e23f97ea8a3bf62fe77e35a4a40c5d88cea1197a2f72c4ab31cbbc689fcf99a1d51bb0ee96122c618464eefe1ca8479dc53ab7de9e6570cb4009cf2a7a1 SHA512 d8d5fe17e2984959546af3c53f044aa4648860e19ff8ffd54452e87fa6cdfd111f825c57e3df17cb8ed95de8392b6f354b12ded41e3e021a37f07b99a89ba18d
+EBUILD jack2-1.9.18.ebuild 2399 BLAKE2B 86e5f0ab5115cee946ce94003aaf90171b6867f91c4ee051fd57c8246e90e952450c20182ea871bea170fa01fbdc4cdcb5f2cf390adfdd2c01562092d3c1bae8 SHA512 ba5bb433a77a7fb0059b348cdb0a4519e98de0d88b7709ec8a8323f85f46f44796be264571f5c1f47800cf3747d44754cb396c4942ec7a6126b6c78803b43023
+EBUILD jack2-1.9.19.ebuild 2399 BLAKE2B 86e5f0ab5115cee946ce94003aaf90171b6867f91c4ee051fd57c8246e90e952450c20182ea871bea170fa01fbdc4cdcb5f2cf390adfdd2c01562092d3c1bae8 SHA512 ba5bb433a77a7fb0059b348cdb0a4519e98de0d88b7709ec8a8323f85f46f44796be264571f5c1f47800cf3747d44754cb396c4942ec7a6126b6c78803b43023
diff --git a/media-sound/jack2/jack2-1.9.18.ebuild b/media-sound/jack2/jack2-1.9.18.ebuild
new file mode 100644 (file)
index 0000000..502d34d
--- /dev/null
@@ -0,0 +1,97 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+PYTHON_COMPAT=( python3_{8,9,10} )
+PYTHON_REQ_USE="threads(+)"
+inherit python-single-r1 waf-utils multilib-minimal
+
+DESCRIPTION="Jackdmp jack implemention for multi-processor machine"
+HOMEPAGE="https://jackaudio.org/"
+
+if [[ "${PV}" = "9999" ]]; then
+       inherit git-r3
+       EGIT_REPO_URI="https://github.com/jackaudio/${PN}.git"
+else
+       MY_PV="${PV/_rc/-RC}"
+       MY_P="${PN}-${MY_PV}"
+       S="${WORKDIR}/${MY_P}"
+       SRC_URI="https://github.com/jackaudio/jack2/archive/v${MY_PV}/v${MY_PV}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="amd64 arm arm64 ppc ppc64 ~riscv x86"
+fi
+
+LICENSE="GPL-2"
+SLOT="2"
+IUSE="alsa +classic dbus doc ieee1394 libsamplerate metadata opus pam readline sndfile"
+
+REQUIRED_USE="
+       ${PYTHON_REQUIRED_USE}
+       || ( classic dbus )"
+
+BDEPEND="
+       virtual/pkgconfig
+       doc? ( app-doc/doxygen )
+"
+DEPEND="${PYTHON_DEPS}
+       media-libs/libsamplerate
+       media-libs/libsndfile
+       sys-libs/readline:0=
+       alsa? ( media-libs/alsa-lib[${MULTILIB_USEDEP}] )
+       dbus? (
+               dev-libs/expat[${MULTILIB_USEDEP}]
+               sys-apps/dbus[${MULTILIB_USEDEP}]
+       )
+       ieee1394? ( media-libs/libffado:=[${MULTILIB_USEDEP}] )
+       metadata? ( sys-libs/db:* )
+       opus? ( media-libs/opus[custom-modes,${MULTILIB_USEDEP}] )"
+RDEPEND="${DEPEND}
+       dbus? (
+               $(python_gen_cond_dep '
+                       dev-python/dbus-python[${PYTHON_USEDEP}]
+               ')
+       )
+       pam? ( sys-auth/realtime-base )
+       !media-sound/jack-audio-connection-kit:0"
+
+DOCS=( AUTHORS.rst ChangeLog.rst README.rst README_NETJACK2 )
+
+src_prepare() {
+       default
+       python_fix_shebang waf
+       multilib_copy_sources
+}
+
+multilib_src_configure() {
+       local mywafconfargs=(
+               --htmldir=/usr/share/doc/${PF}/html
+               $(usex dbus --dbus "")
+               $(usex classic --classic "")
+               --alsa=$(usex alsa yes no)
+               --celt=no
+               --db=$(usex metadata yes no)
+               --doxygen=$(multilib_native_usex doc yes no)
+               --firewire=$(usex ieee1394 yes no)
+               --iio=no
+               --opus=$(usex opus yes no)
+               --portaudio=no
+               --readline=$(multilib_native_usex readline yes no)
+               --samplerate=$(multilib_native_usex libsamplerate yes no)
+               --sndfile=$(multilib_native_usex sndfile yes no)
+               --winmme=no
+       )
+
+       waf-utils_src_configure ${mywafconfargs[@]}
+}
+
+multilib_src_compile() {
+       WAF_BINARY="${BUILD_DIR}"/waf waf-utils_src_compile
+}
+
+multilib_src_install() {
+       WAF_BINARY="${BUILD_DIR}"/waf waf-utils_src_install
+}
+
+multilib_src_install_all() {
+       python_fix_shebang "${ED}"
+}
diff --git a/media-video/pipewire/Manifest b/media-video/pipewire/Manifest
new file mode 100644 (file)
index 0000000..64066a4
--- /dev/null
@@ -0,0 +1,9 @@
+AUX pipewire-0.3.25-enable-failed-mlock-warning.patch 704 BLAKE2B dc0732b89b57a258ea6dc54941899134259469675f92ae93aebda09a796c73ace8bc4ed0ab2aef4ea1bcaa30c1bea8c3304288168421ce8f9939ec993c8aa438 SHA512 7456a24276b7b766ff5799acf5b80ef5f85ee7a78fc5b52adff3206c0b0aa1985a0bf72634aacf7818c90136c09bcc11cb0fecec291d961c8b3585c897869f65
+AUX pipewire-0.3.25-fix-docdir-path.patch 1231 BLAKE2B 7e361262d4ccc6f21159dfce6b7e93c3e332b90ca75fb90f1a8a3edd8b4a813d78d5c4c61d89452f626c32206de9c6be075dc66e95c5cfc0e147bd08ace4db2e SHA512 8a4e0ebfc6e3776ca4e5b43f4b16828f72983053aa957368a36aa9dec12ebac32275261f67b5e4e63b7ad4580d61a6ee78327e08146ecc67ce84a493d49400bc
+AUX pipewire-0.3.25-non-systemd-integration.patch 822 BLAKE2B e80245300313151c01ec56a9be74590d6ee9211a78d9c16180ef1bfb1938a8ad9f8e00f2086d220ca6f8ad2d1c55508cfcc3c240467ed66239808f76029fdcae SHA512 0a7570e0dadd9119ba81b91fc0831ad511ed793f2f10f304547152448e0cf079118c595944e22f31cea94a92a0819524aad26c3fc2d17e73b622b43637cdf06a
+AUX pipewire-0.3.28-revert-openaptx-restriction.patch 955 BLAKE2B 17b6adc21205fd47a8759103d680976fff64ca4f5bb02a0ebbf5dba2115036710798dce5ca3b0964848c047eaf1790ab68e0c4e884544b9fea66cffea05aad0b SHA512 4b8e3330deac02ff5788fc26b63e19b2f6ecc82f156981321e6abc397c9b6e7111c5bff8107dc455d9246bf25fc9ed3b2d674335dda396d20c6387e1623dbcc7
+AUX pipewire-0.3.29-revert-openaptx-restriction.patch 1228 BLAKE2B a282cd6f678ecd5fd27076cd945b86a8139caf644fae5f6420f45e47cfa1f1ef7edacb6e5c6c0ae860bfaa016de902accb916159f90a85bddb0b26b73658e3ff SHA512 cadfe7c54eec23d2619faf274d2c5c95b4f430525c7fc0b84e667e3f90775d27dbb6682d200d3af5d48475a2b37ab0ff2dd6e8be4f2d69bead68f6f1efb7a7ad
+AUX pipewire-launcher.sh 149 BLAKE2B 42a9fd174e8216f9941ec72bc50581d539453dd0430ac61712582039f1cfe17cafa050bd87fcb90b9c16ffd891fd9f9c5dfec99b2be8c66eaed0128af180508e SHA512 7f50287565fa44e2296a7b294e8fd3dd64938d2de15c6ff5674d85a6e7bbccbc334c0fb9e28321104aff5335894b3c5a21171f385465e37b422ef53988dbfe4b
+AUX pipewire.desktop 322 BLAKE2B 0299b9054cf881a5cbbdb128a5e8a51308cf0b5a98260dca756e704504ef057e403b2fb4aa2d58f52dde4be59e416c95d8fce21bc3ca6b6447ecab58263a3f21 SHA512 c13ea531cfdd3798f8d6cd20f5fa8c0a5040c27a6ef3850fdd41102a3bf0bcb73176e3300845af77804a98842fb736841223bc9ac1c92eb2034e9d46e41fc344
+DIST pipewire-0.3.22.tar.gz 1263844 BLAKE2B 3fb90c0b1c17ed108e8c390873f5c4527e1ff9241d1c5964ad5b7c01fbfefda901ef1228f178cf3c9899e6e8e75969a470f8fba63473ff203cba612c6c0553ca SHA512 a6587e0afd5c90be1733ecf62c6fc68e735ab3b84f2cbbf844bbe1be93e7a23dee07b041ed6b273cab6ab207d2388ae6f2027d0380928555a0155a7cc9ca4a7e
+EBUILD pipewire-0.3.22.ebuild 3194 BLAKE2B cb239c46a6fcdb0ae86de6d2b82751e3f081c2ade159b12b67e0809eab03f6eeece86923c96208f4660abc20620acce2c6e150c6d5ec387275e89032e2b47c9a SHA512 a7d6fbb7ecf4dcc7e934fa40be118abb92cc139a07e37c612b90ee8704c62a217e6e2b968b93c20bbc200131bea572dc69ca8ab667c8864882f6a49c869be2a8
diff --git a/media-video/pipewire/files/pipewire-0.3.25-enable-failed-mlock-warning.patch b/media-video/pipewire/files/pipewire-0.3.25-enable-failed-mlock-warning.patch
new file mode 100644 (file)
index 0000000..bdb43fe
--- /dev/null
@@ -0,0 +1,12 @@
+diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in
+--- a/src/daemon/pipewire.conf.in
++++ b/src/daemon/pipewire.conf.in
+@@ -6,7 +6,7 @@ context.properties = {
+     #support.dbus                          = true
+     #link.max-buffers                      = 64
+     link.max-buffers                       = 16                       # version < 3 clients can't handle more
+-    #mem.warn-mlock                        = false
++    mem.warn-mlock                         = true                     # Gentoo should have good RLIMITs now
+     #mem.allow-mlock                       = true
+     #mem.mlock-all                         = false
+     #clock.power-of-two-quantum            = true
diff --git a/media-video/pipewire/files/pipewire-0.3.25-fix-docdir-path.patch b/media-video/pipewire/files/pipewire-0.3.25-fix-docdir-path.patch
new file mode 100644 (file)
index 0000000..9c7a55c
--- /dev/null
@@ -0,0 +1,32 @@
+diff --git a/doc/meson.build b/doc/meson.build
+index 05c7ed35..ce9b52ea 100644
+--- a/doc/meson.build
++++ b/doc/meson.build
+@@ -24,11 +24,14 @@ doxyfile = configure_file(input: 'Doxyfile.in',
+                           output: 'Doxyfile',
+                           configuration: doxyfile_conf)
+-docdir = join_paths(pipewire_datadir, 'doc')
++docdir = get_option('docdir')
++if docdir == ''
++  docdir = join_paths(pipewire_datadir, 'doc', meson.project_name())
++endif
+ html_target = custom_target('pipewire-docs',
+                             input: [ doxyfile ],
+                             output: [ 'html' ],
+                             command: [ doxygen, doxyfile ],
+                             install: true,
+-                            install_dir: join_paths(docdir, 'pipewire'))
++                            install_dir: docdir)
+diff --git a/meson_options.txt b/meson_options.txt
+index 858283f2..d51e693f 100644
+--- a/meson_options.txt
++++ b/meson_options.txt
+@@ -1,3 +1,6 @@
++option('docdir',
++      type : 'string',
++      description : 'Directory for installing documentation to (defaults to pipewire_datadir/doc/meson.project_name() )')
+ option('docs',
+        description: 'Build documentation',
+        type: 'feature',
diff --git a/media-video/pipewire/files/pipewire-0.3.25-non-systemd-integration.patch b/media-video/pipewire/files/pipewire-0.3.25-non-systemd-integration.patch
new file mode 100644 (file)
index 0000000..51455a3
--- /dev/null
@@ -0,0 +1,18 @@
+diff --git a/src/daemon/pipewire.conf.in b/src/daemon/pipewire.conf.in
+--- a/src/daemon/pipewire.conf.in
++++ b/src/daemon/pipewire.conf.in
+@@ -204,12 +204,12 @@ context.exec = [
+     # but it is better to start it as a systemd service.
+     # Run the session manager with -h for options.
+     #
+-    @comment@{ path = "@media_session_path@"  args = "" }
++    { path = "@media_session_path@"  args = "" }
+     #
+     # You can optionally start the pulseaudio-server here as well
+     # but it is better to start it as a systemd service.
+     # It can be interesting to start another daemon here that listens
+     # on another address with the -a option (eg. -a tcp:4713).
+     #
+-    @comment@{ path = "@pipewire_path@" args = "-c pipewire-pulse.conf" }
++    { path = "@pipewire_path@" args = "-c pipewire-pulse.conf" }
+ ]
diff --git a/media-video/pipewire/files/pipewire-0.3.28-revert-openaptx-restriction.patch b/media-video/pipewire/files/pipewire-0.3.28-revert-openaptx-restriction.patch
new file mode 100644 (file)
index 0000000..f624191
--- /dev/null
@@ -0,0 +1,20 @@
+Revert "openaptx: Blacklist >= 0.2.1 due to license change"
+
+This reverts commit d08b6fac6bec0d334ee9fc785d551a67832f95fe.
+
+Doesn't apply to us.
+
+Bug: https://bugs.gentoo.org/785634
+
+--- a/spa/meson.build
++++ b/spa/meson.build
+@@ -22,7 +22,7 @@ if not get_option('spa-plugins').disabled()
+   sbc_dep = dependency('sbc', required: get_option('bluez5'))
+   ldac_dep = dependency('ldacBT-enc', required : get_option('bluez5-codec-ldac'))
+   ldac_abr_dep = dependency('ldacBT-abr', required : get_option('bluez5-codec-ldac'))
+-  aptx_dep = dependency('libopenaptx', version : '< 0.2.1', required : get_option('bluez5-codec-aptx'))
++  aptx_dep = dependency('libopenaptx', required : get_option('bluez5-codec-aptx'))
+   fdk_aac_dep = dependency('fdk-aac', required : get_option('bluez5-codec-aac'))
+   avcodec_dep = dependency('libavcodec', required: get_option('ffmpeg'))
+   jack_dep = dependency('jack', version : '>= 1.9.10', required: get_option('jack'))
diff --git a/media-video/pipewire/files/pipewire-0.3.29-revert-openaptx-restriction.patch b/media-video/pipewire/files/pipewire-0.3.29-revert-openaptx-restriction.patch
new file mode 100644 (file)
index 0000000..9da495f
--- /dev/null
@@ -0,0 +1,30 @@
+From 6d2e45a67cadd9498b24e8e4ea7adc6cf627333d Mon Sep 17 00:00:00 2001
+From: Thomas Deutschmann <whissi@gentoo.org>
+Date: Thu, 3 Jun 2021 14:15:44 +0200
+Subject: [PATCH] Revert "openaptx: Blacklist >= 0.2.1 due to license change"
+
+This reverts commit d08b6fac6bec0d334ee9fc785d551a67832f95fe.
+
+Doesn't apply to us.
+
+Bug: https://bugs.gentoo.org/785634
+---
+ spa/meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/spa/meson.build b/spa/meson.build
+index 263af4c2..7671c74b 100644
+--- a/spa/meson.build
++++ b/spa/meson.build
+@@ -23,7 +23,7 @@ if not get_option('spa-plugins').disabled()
+     sbc_dep = dependency('sbc', required: get_option('bluez5'))
+     ldac_dep = dependency('ldacBT-enc', required : get_option('bluez5-codec-ldac'))
+     ldac_abr_dep = dependency('ldacBT-abr', required : get_option('bluez5-codec-ldac'))
+-    aptx_dep = dependency('libopenaptx', version : '< 0.2.1', required : get_option('bluez5-codec-aptx'))
++    aptx_dep = dependency('libopenaptx', required : get_option('bluez5-codec-aptx'))
+     fdk_aac_dep = dependency('fdk-aac', required : get_option('bluez5-codec-aac'))
+   endif
+   avcodec_dep = dependency('libavcodec', required: get_option('ffmpeg'))
+-- 
+2.32.0.rc3
+
diff --git a/media-video/pipewire/files/pipewire-launcher.sh b/media-video/pipewire/files/pipewire-launcher.sh
new file mode 100644 (file)
index 0000000..ecff3e7
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# We need to kill any existing pipewire instance to restore sound
+pkill -u "${USER}" -x pipewire 1>/dev/null 2>&1
+
+exec /usr/bin/pipewire
diff --git a/media-video/pipewire/files/pipewire.desktop b/media-video/pipewire/files/pipewire.desktop
new file mode 100644 (file)
index 0000000..d3786e7
--- /dev/null
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Version=1.0
+Name[de]=PipeWire Mediensystem
+Name=PipeWire Media System
+Comment[de]=Das PipeWire Mediensystem starten
+Comment=Start the PipeWire Media System
+Exec=/usr/libexec/pipewire-launcher
+Terminal=false
+Type=Application
+X-GNOME-HiddenUnderSystemd=true
+X-KDE-HiddenUnderSystemd=true
+X-systemd-skip=true
diff --git a/media-video/pipewire/pipewire-0.3.22.ebuild-borked b/media-video/pipewire/pipewire-0.3.22.ebuild-borked
new file mode 100644 (file)
index 0000000..fc2dba1
--- /dev/null
@@ -0,0 +1,128 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit meson multilib-minimal
+
+if [[ ${PV} == 9999 ]]; then
+       EGIT_REPO_URI="https://github.com/PipeWire/pipewire.git"
+       EGIT_BRANCH="work"
+       inherit git-r3
+else
+       SRC_URI="https://github.com/PipeWire/${PN}/archive/${PV}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="amd64 arm arm64 ppc ~ppc64 x86"
+fi
+
+DESCRIPTION="Multimedia processing graphs"
+HOMEPAGE="https://pipewire.org/"
+
+LICENSE="LGPL-2.1+"
+SLOT="0/0.3"
+IUSE="bluetooth debug doc ffmpeg gstreamer jack sdl sndfile systemd test vulkan X"
+
+BDEPEND="
+       app-doc/xmltoman
+       doc? (
+               app-doc/doxygen
+               media-gfx/graphviz
+       )
+"
+RDEPEND="
+       >=media-libs/alsa-lib-1.1.7
+       sys-apps/dbus
+       virtual/libudev
+       bluetooth? (
+               media-libs/sbc
+               net-wireless/bluez:=
+       )
+       ffmpeg? ( media-video/ffmpeg:= )
+       gstreamer? (
+               >=dev-libs/glib-2.32.0:2
+               >=media-libs/gstreamer-1.10.0:1.0
+               media-libs/gst-plugins-base:1.0
+       )
+       jack? ( >=media-sound/jack2-1.9.10:2 )
+       sdl? ( media-libs/libsdl2 )
+       sndfile? ( >=media-libs/libsndfile-1.0.20 )
+       systemd? ( sys-apps/systemd )
+       vulkan? ( media-libs/vulkan-loader )
+       X? ( x11-libs/libX11 )
+"
+DEPEND="${RDEPEND}
+       vulkan? ( dev-util/vulkan-headers )
+"
+
+DOCS=( {README,INSTALL}.md NEWS )
+
+RESTRICT="!test? ( test )"
+
+src_prepare() {
+       spa_use() {
+               if ! in_iuse ${1} || ! use ${1}; then
+                       sed -e "/^add-spa-lib.*${1}/s/^/#${2-$1}-disabled-by-USE-no-${1}\:/" \
+                               -e "/^load-module.*${1}/s/^/#${2-$1}-disabled-by-USE-no-${1}\:/" \
+                               -i src/daemon/pipewire.conf.in || die
+               fi
+       }
+
+       default
+       spa_use libcamera
+       spa_use rtkit
+       spa_use bluetooth bluez5
+       spa_use jack
+       spa_use vulkan
+}
+
+src_configure() {
+       local emesonargs=(
+               -Dexamples=true # contains required pipewire-media-session
+               -Dman=true
+               -Dspa-plugins=true
+               --buildtype=$(usex debug debugoptimized plain)
+               # alsa plugin and jack emulation
+               -Dpipewire-alsa=true
+               $(meson_use jack pipewire-jack)
+               # spa-plugins
+               # we install alsa support unconditionally
+               $(meson_use bluetooth bluez5)
+               $(meson_use ffmpeg)
+               $(meson_use jack)
+               $(meson_use vulkan)
+               # libcamera is not packaged
+               # misc
+               $(meson_use doc docs)
+               $(meson_use gstreamer)
+               $(meson_use gstreamer gstreamer-device-provider)
+               $(meson_feature sdl sdl2)
+               $(meson_feature sndfile)
+               $(meson_use systemd)
+               $(meson_use test test)
+               $(meson_use test tests)
+       )
+       meson_src_configure
+}
+
+src_install() {
+       meson_src_install
+
+       dosym ../../../usr/share/alsa/alsa.conf.d/50-pipewire.conf /etc/alsa/conf.d/50-pipewire.conf
+
+#      # TODO: this breaks alsa users
+#      if use alsa; then
+#              dosym ../../../usr/share/alsa/alsa.conf.d/99-pipewire-default.conf /etc/alsa/conf.d/99-pipewire-default.conf
+#      fi
+}
+
+pkg_postinst() {
+       elog "Package has optional sys-auth/rtkit RUNTIME support that may be disabled"
+       elog "by setting DISABLE_RTKIT env var."
+       elog "To enable rtkit, uncomment the load-module line in /etc/pipewire/pipewire.conf"
+       elog
+       if use jack; then
+               elog "Please note that even though the libraries for JACK emulation have"
+               elog "been installed, this ebuild is not yet wired up to replace a JACK server."
+               elog
+       fi
+       elog "Read INSTALL.md for information about ALSA plugin or JACK/PulseAudio emulation."
+}
diff --git a/metadata/layout.conf b/metadata/layout.conf
new file mode 100644 (file)
index 0000000..d43e61c
--- /dev/null
@@ -0,0 +1 @@
+masters = gentoo
diff --git a/metadata/md5-cache/media-sound/audacity-3.0.2 b/metadata/md5-cache/media-sound/audacity-3.0.2
new file mode 100644 (file)
index 0000000..57b3d17
--- /dev/null
@@ -0,0 +1,17 @@
+BDEPEND=app-arch/unzip sys-devel/gettext virtual/pkgconfig dev-util/ninja dev-util/cmake
+DEFINED_PHASES=compile configure install postinst postrm preinst prepare test
+DEPEND=x11-libs/wxGTK:3.0-gtk3 expat? ( >=dev-libs/expat-2.1.0 ) lame? ( >=media-sound/lame-3.100 ) sndfile? ( >=media-libs/libsndfile-1.0.28 ) soxr? ( >=media-libs/soxr-0.1.1 ) sqlite? ( >=dev-db/sqlite-3.32.0:3 ) ffmpeg? ( media-video/ffmpeg ) id3tag? ( >=media-libs/libid3tag-0.15.1b ) mad? ( >=media-libs/libmad-0.15.1b ) vamp? ( >=media-libs/vamp-plugin-sdk-2.5 ) ogg? ( >=media-libs/libogg-1.3.1 ) vorbis? ( >=media-libs/libvorbis-1.3.3 ) flac? ( >=media-libs/flac-1.3.1[cxx] ) lv2? ( >=media-libs/lilv-0.24.6 >=media-libs/lv2-1.16.0 >=dev-libs/serd-0.30.2 >=dev-libs/sord-0.16.4 >=media-libs/sratom-0.6.4 >=media-libs/suil-0.10.6 ) portmidi? ( >=media-libs/portmidi-0.1 ) soundtouch? ( >=media-libs/libsoundtouch-1.7.1 ) twolame? ( >=media-sound/twolame-0.3.13 ) alsa? ( media-libs/alsa-lib ) jack? ( virtual/jack ) dev-util/desktop-file-utils x11-misc/shared-mime-info
+DESCRIPTION=Free crossplatform audio editor
+EAPI=7
+HOMEPAGE=https://web.audacityteam.org/
+INHERIT=cmake flag-o-matic xdg wxwidgets
+IUSE=alsa doc ffmpeg flac id3tag jack ladspa lv2 mad ogg oss pch portmidi portmixer portsmf sbsms soundtouch expat lame sndfile soxr sqlite twolame vamp vorbis vst
+KEYWORDS=~amd64 ~arm64 ~mips ~ppc ~ppc64 ~x86
+LICENSE=GPL-2
+RDEPEND=x11-libs/wxGTK:3.0-gtk3 expat? ( >=dev-libs/expat-2.1.0 ) lame? ( >=media-sound/lame-3.100 ) sndfile? ( >=media-libs/libsndfile-1.0.28 ) soxr? ( >=media-libs/soxr-0.1.1 ) sqlite? ( >=dev-db/sqlite-3.32.0:3 ) ffmpeg? ( media-video/ffmpeg ) id3tag? ( >=media-libs/libid3tag-0.15.1b ) mad? ( >=media-libs/libmad-0.15.1b ) vamp? ( >=media-libs/vamp-plugin-sdk-2.5 ) ogg? ( >=media-libs/libogg-1.3.1 ) vorbis? ( >=media-libs/libvorbis-1.3.3 ) flac? ( >=media-libs/flac-1.3.1[cxx] ) lv2? ( >=media-libs/lilv-0.24.6 >=media-libs/lv2-1.16.0 >=dev-libs/serd-0.30.2 >=dev-libs/sord-0.16.4 >=media-libs/sratom-0.6.4 >=media-libs/suil-0.10.6 ) portmidi? ( >=media-libs/portmidi-0.1 ) soundtouch? ( >=media-libs/libsoundtouch-1.7.1 ) twolame? ( >=media-sound/twolame-0.3.13 ) alsa? ( media-libs/alsa-lib ) jack? ( virtual/jack )
+REQUIRED_USE=portmidi? ( portsmf )
+RESTRICT=test
+SLOT=0
+SRC_URI=https://github.com/audacity/audacity/releases/download/Audacity-3.0.2/audacity-minsrc-3.0.2.tar.xz https://liquid.me.uk/audacity-wxwidgets-3.1.3.tar.gz doc? ( https://github.com/audacity/audacity-manual/archive/refs/heads/master.zip )
+_eclasses_=toolchain-funcs     24921b57d6561d87cbef4916a296ada4        multilib        ebdbaed22e873a5abe6205f41349b479        multiprocessing cac3169468f893670dac3e7cb940e045        ninja-utils     132cbb376048d079b5a012f5467c4e7f        edos2unix       33e347e171066657f91f8b0c72ec8773        l10n    8cdd85e169b835d518bc2fd59f780d8e        wrapper 4251d4c84c25f59094fd557e0063a974        eutils  2d5b3f4b315094768576b6799e4f926e        flag-o-matic    bc2e7662a4a9a8643be851982a837ddc        xdg-utils       ff2ff954e6b17929574eee4efc5152ba        cmake   518e4c9a6a38dfd7afc54b6a7c5de3da        xdg     c7ba313ea1eaf266f95cc6235f7d6a07        wxwidgets       41fd66c54c0faced4c91afc0ef1cc050
+_md5_=66a27c4e97b0cdb40817994a8358385b
diff --git a/net-im/discord-bin/Manifest b/net-im/discord-bin/Manifest
new file mode 100644 (file)
index 0000000..ccd6767
--- /dev/null
@@ -0,0 +1,9 @@
+DIST discord-0.0.19.tar.gz 77400663 BLAKE2B 2bfbc32739d7af69f437a54fe75140451cdac68453d8554ccf76b1e12e7118b163465742c8c4e8743d4c7de4e493fcbd313c7cff316514b78e8b7288d5fe3a8c SHA512 5b73f0f968ce61f5a844940e1525da80e7b2ce3779cf2050ca3c2b0b7dbee20f16e2bf203f0673d1e275d1e55075b83eb63700731be8324587b3c58c64d3a0e8
+DIST discord-0.0.22.tar.gz 77553233 BLAKE2B c0c9a5a9b088a3f619f498c345f46f5e43712c353f723427a1ffd95a2a66817e8d5e5298a8290d88df807251cc156db0e26ec1403ed4b3cba241b624d436346b SHA512 96c8486577bee7ae165bf96aab50c0733d83a2d9435357d9a4d9a3e9f3225ae6a7bf46e1a7d8b419ecc7ab4e270755332621a4f786ddb89a842379f5da40b271
+DIST discord-0.0.23.tar.gz 82116322 BLAKE2B 5ed0d4d20d20a5bdb2e5bfc31b0a9c47baeaca976ee0f0861fdb436d89eccd4f5d50df9bd366f996cdbc767ce6d06bddf5992574329c7b5c01b47a9c154a37c4 SHA512 d03b27180c95ca74c93323090ce5c1e4351577d27184cfbf5525439052505ba198fafbd4b1489f97ce4c103bc35d1cfb4cdb1c32fc9c80bc55e2373b7a894a39
+DIST discord-0.0.24.tar.gz 77551317 BLAKE2B 2a0ff44eac145aeadeeebe21ac03a756e5e088cc130ccfcb6a6a7b8040bf7507de49b788047e04cc6c9b1fb799ada6fc0b47a1804c5c910bbf4db362e1b5cb6e SHA512 9e1aa15bc1b1d8ebd2819ba88e7c012c47966d7f150264e732c849d4f15023729f8de4e5a5eb999603fa6102a02313dbf7d178b33cfacca58018dcd214ed4e40
+EBUILD discord-bin-0.0.19.ebuild 3216 BLAKE2B 557715d894b490d4409316877c45c3b04c3e3a5b15306e83a123e5bb4a13fa01c5d67cb3f6152d21e8ebbcd13f3afdf9b0d311c66c9eb5131343e12259fa2b43 SHA512 102f70a49d60bf71add56aae6b857f72b5aec6f76ef83d715ba9bf7363cdd4a77798d549cd53b726f39de478ab9ad5be32de34e1b3b855deee17ddf8c4448951
+EBUILD discord-bin-0.0.22.ebuild 3815 BLAKE2B f80d35014beec420549387e8816846018e76c405208eca94b00321488c08e40e5d77c2023a7eef9964a2de947233be48633cebe62c134b960c347ce8e2edf005 SHA512 ea6e13c461190262108c9e2c974b1dd6da814bdb198791996d94aa821b31054c0fb42b80d0aa68e18da98b9901e82bdab5da7c219c46c1c0a9a7bb1dbdef898e
+EBUILD discord-bin-0.0.23.ebuild 3815 BLAKE2B f80d35014beec420549387e8816846018e76c405208eca94b00321488c08e40e5d77c2023a7eef9964a2de947233be48633cebe62c134b960c347ce8e2edf005 SHA512 ea6e13c461190262108c9e2c974b1dd6da814bdb198791996d94aa821b31054c0fb42b80d0aa68e18da98b9901e82bdab5da7c219c46c1c0a9a7bb1dbdef898e
+EBUILD discord-bin-0.0.24.ebuild 3815 BLAKE2B f80d35014beec420549387e8816846018e76c405208eca94b00321488c08e40e5d77c2023a7eef9964a2de947233be48633cebe62c134b960c347ce8e2edf005 SHA512 ea6e13c461190262108c9e2c974b1dd6da814bdb198791996d94aa821b31054c0fb42b80d0aa68e18da98b9901e82bdab5da7c219c46c1c0a9a7bb1dbdef898e
+MISC metadata.xml 401 BLAKE2B bfadde60f5ced8839f9268c03217b5908e6f5cf4ecf3069cbca236b1d8f7c56a3a887655a4afebc74f18cc11584079620828ebe15b9e2ee6879730d90fc603e7 SHA512 77bc1c0db6255f39790b7a9a87dabcec7352142f341b9d7a41c7e073118a7613948e63f65dad9ec672f6ed5026188cdbf1b09cb4073ff67c49ddac3fff2301dd
diff --git a/net-im/discord-bin/discord-bin-0.0.19.ebuild b/net-im/discord-bin/discord-bin-0.0.19.ebuild
new file mode 100644 (file)
index 0000000..7a89768
--- /dev/null
@@ -0,0 +1,131 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin}"
+MY_PV="${PV/-r*}"
+
+CHROMIUM_LANGS="
+       am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discordapp.com"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+
+# libXScrnSaver is used through dlopen (bug #825370)
+RDEPEND="
+       app-accessibility/at-spi2-atk:2
+       app-accessibility/at-spi2-core:2
+       dev-libs/atk
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libdrm
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+"
+
+RESTRICT="bindist mirror strip test"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="
+       ${DESTDIR#/}/${MY_PN^}
+       ${DESTDIR#/}/chrome-sandbox
+       ${DESTDIR#/}/libffmpeg.so
+       ${DESTDIR#/}/libvk_swiftshader.so
+       ${DESTDIR#/}/libvulkan.so
+       ${DESTDIR#/}/libEGL.so
+       ${DESTDIR#/}/libGLESv2.so
+       ${DESTDIR#/}/libVkICD_mock_icd.so
+       ${DESTDIR#/}/swiftshader/libEGL.so
+       ${DESTDIR#/}/swiftshader/libGLESv2.so
+       ${DESTDIR#/}/swiftshader/libvk_swiftshader.so
+"
+
+CONFIG_CHECK="~USER_NS"
+
+S="${WORKDIR}/${MY_PN^}"
+
+pkg_pretend() {
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       chromium_suid_sandbox_check_kernel_config
+
+       default
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd || die "location reset for language cleanup failed"
+       # fix .desktop exec location
+       sed -i -e "s:/usr/share/discord/Discord:${DESTDIR}/${MY_PN^}:" ${MY_PN}.desktop || die "fixing of exec location on .desktop failed"
+}
+
+src_install() {
+       doicon -s 256 ${MY_PN}.png
+
+       # install .desktop file
+       domenu ${MY_PN}.desktop
+
+       exeinto "${DESTDIR}"
+       doexe ${MY_PN^} chrome-sandbox libEGL.so libffmpeg.so libGLESv2.so libvk_swiftshader.so
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources swiftshader
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fperms 4755 "${DESTDIR}"/chrome-sandbox
+
+       dosym "${DESTDIR}"/${MY_PN^} /usr/bin/${MY_PN}
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "system tray support" dev-libs/libappindicator
+}
diff --git a/net-im/discord-bin/discord-bin-0.0.22.ebuild b/net-im/discord-bin/discord-bin-0.0.22.ebuild
new file mode 100644 (file)
index 0000000..e006e6c
--- /dev/null
@@ -0,0 +1,151 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_LANGS="
+       am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discordapp.com"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+RESTRICT="bindist mirror strip test"
+IUSE="+seccomp system-ffmpeg"
+
+RDEPEND="
+               || (
+                       >=app-accessibility/at-spi2-core-2.46.0:2
+                       ( app-accessibility/at-spi2-atk dev-libs/atk )
+               )
+       app-crypt/libsecret
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+       system-ffmpeg? ( media-video/ffmpeg[chromium] )
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="
+       ${DESTDIR#/}/${MY_PN^}
+       ${DESTDIR#/}/chrome-sandbox
+       ${DESTDIR#/}/libffmpeg.so
+       ${DESTDIR#/}/libvk_swiftshader.so
+       ${DESTDIR#/}/libvulkan.so
+       ${DESTDIR#/}/libEGL.so
+       ${DESTDIR#/}/libGLESv2.so
+       ${DESTDIR#/}/libVkICD_mock_icd.so
+       ${DESTDIR#/}/swiftshader/libEGL.so
+       ${DESTDIR#/}/swiftshader/libGLESv2.so
+       ${DESTDIR#/}/swiftshader/libvk_swiftshader.so
+"
+
+CONFIG_CHECK="~USER_NS"
+
+S="${WORKDIR}/${MY_PN^}"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+       # fix .desktop exec location
+       sed -i "/Exec/s:/usr/share/discord/Discord:${DESTDIR}/${MY_PN^}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+       # USE seccomp
+       if ! use seccomp; then
+               sed -i '/Exec/s/Discord/Discord --disable-seccomp-filter-sandbox/' \
+                       "${MY_PN}.desktop" ||
+                       die "sed failed for seccomp"
+       fi
+       # USE system-ffmpeg
+       if use system-ffmpeg; then
+               rm libffmpeg.so || die
+               elog "Using system ffmpeg. This is experimental and may lead to crashes."
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libGLESv2.so libvk_swiftshader.so
+
+       if use system-ffmpeg; then
+               dosym "../../usr/$(get_libdir)/chromium/libffmpeg.so" "${DESTDIR}/libffmpeg.so" || die
+       else
+               doexe libffmpeg.so
+       fi
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources swiftshader
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       dosym "${DESTDIR}/${MY_PN^}" "/usr/bin/${MY_PN}"
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "system tray support" dev-libs/libappindicator
+}
diff --git a/net-im/discord-bin/discord-bin-0.0.23.ebuild b/net-im/discord-bin/discord-bin-0.0.23.ebuild
new file mode 100644 (file)
index 0000000..e006e6c
--- /dev/null
@@ -0,0 +1,151 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_LANGS="
+       am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discordapp.com"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+RESTRICT="bindist mirror strip test"
+IUSE="+seccomp system-ffmpeg"
+
+RDEPEND="
+               || (
+                       >=app-accessibility/at-spi2-core-2.46.0:2
+                       ( app-accessibility/at-spi2-atk dev-libs/atk )
+               )
+       app-crypt/libsecret
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+       system-ffmpeg? ( media-video/ffmpeg[chromium] )
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="
+       ${DESTDIR#/}/${MY_PN^}
+       ${DESTDIR#/}/chrome-sandbox
+       ${DESTDIR#/}/libffmpeg.so
+       ${DESTDIR#/}/libvk_swiftshader.so
+       ${DESTDIR#/}/libvulkan.so
+       ${DESTDIR#/}/libEGL.so
+       ${DESTDIR#/}/libGLESv2.so
+       ${DESTDIR#/}/libVkICD_mock_icd.so
+       ${DESTDIR#/}/swiftshader/libEGL.so
+       ${DESTDIR#/}/swiftshader/libGLESv2.so
+       ${DESTDIR#/}/swiftshader/libvk_swiftshader.so
+"
+
+CONFIG_CHECK="~USER_NS"
+
+S="${WORKDIR}/${MY_PN^}"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+       # fix .desktop exec location
+       sed -i "/Exec/s:/usr/share/discord/Discord:${DESTDIR}/${MY_PN^}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+       # USE seccomp
+       if ! use seccomp; then
+               sed -i '/Exec/s/Discord/Discord --disable-seccomp-filter-sandbox/' \
+                       "${MY_PN}.desktop" ||
+                       die "sed failed for seccomp"
+       fi
+       # USE system-ffmpeg
+       if use system-ffmpeg; then
+               rm libffmpeg.so || die
+               elog "Using system ffmpeg. This is experimental and may lead to crashes."
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libGLESv2.so libvk_swiftshader.so
+
+       if use system-ffmpeg; then
+               dosym "../../usr/$(get_libdir)/chromium/libffmpeg.so" "${DESTDIR}/libffmpeg.so" || die
+       else
+               doexe libffmpeg.so
+       fi
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources swiftshader
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       dosym "${DESTDIR}/${MY_PN^}" "/usr/bin/${MY_PN}"
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "system tray support" dev-libs/libappindicator
+}
diff --git a/net-im/discord-bin/discord-bin-0.0.24.ebuild b/net-im/discord-bin/discord-bin-0.0.24.ebuild
new file mode 100644 (file)
index 0000000..e006e6c
--- /dev/null
@@ -0,0 +1,151 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_LANGS="
+       am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discordapp.com"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+RESTRICT="bindist mirror strip test"
+IUSE="+seccomp system-ffmpeg"
+
+RDEPEND="
+               || (
+                       >=app-accessibility/at-spi2-core-2.46.0:2
+                       ( app-accessibility/at-spi2-atk dev-libs/atk )
+               )
+       app-crypt/libsecret
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+       system-ffmpeg? ( media-video/ffmpeg[chromium] )
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="
+       ${DESTDIR#/}/${MY_PN^}
+       ${DESTDIR#/}/chrome-sandbox
+       ${DESTDIR#/}/libffmpeg.so
+       ${DESTDIR#/}/libvk_swiftshader.so
+       ${DESTDIR#/}/libvulkan.so
+       ${DESTDIR#/}/libEGL.so
+       ${DESTDIR#/}/libGLESv2.so
+       ${DESTDIR#/}/libVkICD_mock_icd.so
+       ${DESTDIR#/}/swiftshader/libEGL.so
+       ${DESTDIR#/}/swiftshader/libGLESv2.so
+       ${DESTDIR#/}/swiftshader/libvk_swiftshader.so
+"
+
+CONFIG_CHECK="~USER_NS"
+
+S="${WORKDIR}/${MY_PN^}"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+       # fix .desktop exec location
+       sed -i "/Exec/s:/usr/share/discord/Discord:${DESTDIR}/${MY_PN^}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+       # USE seccomp
+       if ! use seccomp; then
+               sed -i '/Exec/s/Discord/Discord --disable-seccomp-filter-sandbox/' \
+                       "${MY_PN}.desktop" ||
+                       die "sed failed for seccomp"
+       fi
+       # USE system-ffmpeg
+       if use system-ffmpeg; then
+               rm libffmpeg.so || die
+               elog "Using system ffmpeg. This is experimental and may lead to crashes."
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libGLESv2.so libvk_swiftshader.so
+
+       if use system-ffmpeg; then
+               dosym "../../usr/$(get_libdir)/chromium/libffmpeg.so" "${DESTDIR}/libffmpeg.so" || die
+       else
+               doexe libffmpeg.so
+       fi
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources swiftshader
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       dosym "${DESTDIR}/${MY_PN^}" "/usr/bin/${MY_PN}"
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "system tray support" dev-libs/libappindicator
+}
diff --git a/net-im/discord-bin/metadata.xml b/net-im/discord-bin/metadata.xml
new file mode 100644 (file)
index 0000000..f485c45
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+       <maintainer type="person" proxied="yes">
+               <email>ran.dall@icloud.com</email>
+               <name>Randall T. Vasquez</name>
+       </maintainer>
+       <maintainer type="project" proxied="proxy">
+               <email>proxy-maint@gentoo.org</email>
+               <name>Proxy Maintainers</name>
+       </maintainer>
+</pkgmetadata>
diff --git a/net-im/discord/Manifest b/net-im/discord/Manifest
new file mode 100644 (file)
index 0000000..ed227d3
--- /dev/null
@@ -0,0 +1,19 @@
+AUX launcher.sh 456 BLAKE2B ae091128ef8841bb257ac586f6800fdd749cd8c9c08b9f1c5244f315c7dfa85d7686cae654e27c07ab1ce6481d7b86ab5adfbf8d8c5e477d3e0b172d6d85bc39 SHA512 e658f93725f72c7ae6f75e0633fd35b96f6d09f8c23a6918a70ade0396a822dded24a1d5d82bc5a3ea9fb08bea5aeb89abd4ad35a28997ec667a85d55d6755dc
+DIST discord-0.0.25.tar.gz 77709937 BLAKE2B 48617283675866b3ec8e8e7000800897fc8532ced4329a59561826d1eb018106ff4d499b5a3620ab3d557970f066f0e973211f9eb32f2566130298bd41abff57 SHA512 21a3e6dff2fd33fe0cd5b1c9c340cbeebc6fd214d9f0be8c05ac9faad2f287d17726bd45bebb4ecebe90533da20f501ad1156ac8097318d7545f78811ebe1224
+DIST discord-0.0.46.tar.gz 92983040 BLAKE2B 1d1fb9823808eafee6c41336bc1b82c5b803c5203abe0d65c62ac70444b8cd5c3f7926c2ed75215e16e2ee6c3fb6701ac4b2af3713fe9380b6a23b03aa8e5c90 SHA512 7f88a1f5281beb5bcdb9741ae4d984ec71c09931f31c4265e15f63b5710baff0124b38421971e45e217e20d7de14e4b5ab9e0b7da6afc3eb8ff3456643f692e8
+DIST discord-0.0.64.tar.gz 103547165 BLAKE2B c0ef2ab2f5296a7ba29f7d5a53f0d26fd6984579b32a9641fa2b49c3a5fa6ab7a371dcebdb97481e7843e179c6f0cf1fb55775659639727b72220a50dffa8d17 SHA512 835a1a1ac6c583e41d7c3521b5cbdafaf669d18b5ba1521109c3a3554d10015ef1198aba3697a149bdebb3cd747de4534dd923d448138891be661af96fbee26f
+DIST discord-0.0.65.tar.gz 103550088 BLAKE2B 291e1f9c8d4020a883cac4d0e7e16c1a2d5f83cb3efa4beaf0122627237690483378743e3c945802f9ea63d98703b606dfa31d75edebac4e09aa5f6cb1956daa SHA512 48a6d9d4939babe7b7243ae465e592baac357ed6a79513be3e78a78bbc7c5ce4b22bdb6edae31d43f2adb3e578d9a7ecb9b4fb62aed63da84d20e1daede4fc8e
+DIST discord-0.0.66.tar.gz 103548096 BLAKE2B 0016fca8c62e20848f9d65f9ca4c8b36d6bcd1c035f097db98a9c73187b2c1cd60887215b7c4403e85bb49dbedde8aaa680cbd2b470464db686621e885b722d2 SHA512 e521af930bf68d8da4fa9db1d86be84d17ad661213ba20a29eb05a67042625630d9d2ce5d8147146276b5c1356e07a0beba9312b0b558eb5cc5861244418e32b
+DIST discord-0.0.69.tar.gz 103541511 BLAKE2B 840c24703a92a1dad3ef8c23b679f23a273a2388b35f42d3b2c1eadb9642fd50a4e6bbc2ad53a08fa24b36adc111650dcfcb68e0a4834d89c8e28fa840e13f7f SHA512 b91cf295f7571ed0378f3759932e0144823ab0996ace1716169bb77fff0f8bdcb473b51c9eef7a1b93fc94d135cb7108441ec6a2fa7e718d0cd104670fac7d31
+DIST discord-0.0.70.tar.gz 106989783 BLAKE2B 3a9f6d71cbc416fa598a83367c80c69e3a981bb1522f03433a5a8578941a662282a8189db8785a2d7b5853435357c5057f9e44644051feb9b87679475675580b SHA512 78aa941ce759345c0f2dc5fc3f741462e9ae8d756ecfcd492a42b9e4a16168c4772e4f732e838fd06a305348c4923a6c601450eb80bf4bd3db6f4468ae803e17
+DIST discord-0.0.71.tar.gz 106984232 BLAKE2B 77c9b17c3b74de293a3937977a30282f1dd7537706fc0455b0f0a615d987db5dfa835c6f5b4c94ac439b476de4092db47aeb8358fe240e7c0b9ea5696a22647c SHA512 c4042a56e8ad170901367ed562831d0f8933d8f0babf246639f8b5b17d7b437b58d6cf696f3c3d6a30674c041567115d0419a3e4c00de7064db58a4c77a61a93
+DIST discord-0.0.72.tar.gz 106993954 BLAKE2B 0b9e83812cd1b29eb71d6916fa747b0908f563cc46900d1ecd8204c6b18155480d9b010c90e156907b8460ea7e9412de219f6b0473e5703b8a513d18d9d79bb8 SHA512 ddb791e1a92a30f2cab24fd7a686b621be33d51c2a7c0a0eed3293b4edd05f814ea850cbf43c9910f4576b17dc9e9c1367960f3d1536e7ec1ede372904c6c424
+EBUILD discord-0.0.25.ebuild 3135 BLAKE2B 3846812d50c2dd8e14be01e5ed085bc31fcfe4eefa397210ab0d392bc86ad8ed1535d4d6ea0c92ccc23c89358ae2340a74e5a2f0dd9418037cc8e5375eeb76af SHA512 d2d5936dde95bad9d3ed31b5afc987f812cd8c85429392be3cecc6ccc4d622965b6e8efa69234262add2a7a96e6014020aefb1dd3db46ea8cab634ee62239ec8
+EBUILD discord-0.0.46.ebuild 3517 BLAKE2B f38d871f1bb8e7285468fb828779aad07ede1e0ad60ca343ff09f6f377620011fded733c8deddf8e25d4bfde43289682ab2c443e0a568a898c0c670569891edf SHA512 4ca6c99208ab670f8e2c7c74554d7a6c97617f3c6c2d25d3528827acad1221ad13f324da4ebd5b8e8915b8e1f308cb51525c216153d903420d23a2539a4e6c2a
+EBUILD discord-0.0.64.ebuild 3953 BLAKE2B 5108ee5a095f59114ad00d853f9d146ef0919aa802be7a84c3d61f134021e942c8abf699dbd066c82b310992629a80fd2764dc326b37fd0c6ad879ddfe8e5c9d SHA512 7d9a6560cf066d77301a87d83bcf54619f0291eabdd831911a7ead97eb5b4cecbc5db4b5f0adacbdba244c3c7ebdce4fb3fbc319964ca6c7b251e38697f1d92c
+EBUILD discord-0.0.65.ebuild 3953 BLAKE2B 5108ee5a095f59114ad00d853f9d146ef0919aa802be7a84c3d61f134021e942c8abf699dbd066c82b310992629a80fd2764dc326b37fd0c6ad879ddfe8e5c9d SHA512 7d9a6560cf066d77301a87d83bcf54619f0291eabdd831911a7ead97eb5b4cecbc5db4b5f0adacbdba244c3c7ebdce4fb3fbc319964ca6c7b251e38697f1d92c
+EBUILD discord-0.0.66.ebuild 3953 BLAKE2B 5108ee5a095f59114ad00d853f9d146ef0919aa802be7a84c3d61f134021e942c8abf699dbd066c82b310992629a80fd2764dc326b37fd0c6ad879ddfe8e5c9d SHA512 7d9a6560cf066d77301a87d83bcf54619f0291eabdd831911a7ead97eb5b4cecbc5db4b5f0adacbdba244c3c7ebdce4fb3fbc319964ca6c7b251e38697f1d92c
+EBUILD discord-0.0.69.ebuild 3932 BLAKE2B f23fb91524730f3c3e350d26799e715c811a1fe6e33f07f608860ce57d565b3e3a667c3f6219da18a101eafabedbecfda505d2f560e7f78b97eb871c8744b468 SHA512 6f5828bcfa52b777e29b58b267d8be95fc2ddb83891779f390ebff203daacdde4faa95b796ec77b38ee66713f617dffaf90222f857dd4b065553205d7f405569
+EBUILD discord-0.0.70.ebuild 3932 BLAKE2B f23fb91524730f3c3e350d26799e715c811a1fe6e33f07f608860ce57d565b3e3a667c3f6219da18a101eafabedbecfda505d2f560e7f78b97eb871c8744b468 SHA512 6f5828bcfa52b777e29b58b267d8be95fc2ddb83891779f390ebff203daacdde4faa95b796ec77b38ee66713f617dffaf90222f857dd4b065553205d7f405569
+EBUILD discord-0.0.71.ebuild 3932 BLAKE2B f23fb91524730f3c3e350d26799e715c811a1fe6e33f07f608860ce57d565b3e3a667c3f6219da18a101eafabedbecfda505d2f560e7f78b97eb871c8744b468 SHA512 6f5828bcfa52b777e29b58b267d8be95fc2ddb83891779f390ebff203daacdde4faa95b796ec77b38ee66713f617dffaf90222f857dd4b065553205d7f405569
+EBUILD discord-0.0.72.ebuild 3932 BLAKE2B f23fb91524730f3c3e350d26799e715c811a1fe6e33f07f608860ce57d565b3e3a667c3f6219da18a101eafabedbecfda505d2f560e7f78b97eb871c8744b468 SHA512 6f5828bcfa52b777e29b58b267d8be95fc2ddb83891779f390ebff203daacdde4faa95b796ec77b38ee66713f617dffaf90222f857dd4b065553205d7f405569
diff --git a/net-im/discord/discord-0.0.25.ebuild b/net-im/discord/discord-0.0.25.ebuild
new file mode 100644 (file)
index 0000000..65e97d3
--- /dev/null
@@ -0,0 +1,128 @@
+# Copyright 1999-2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_VERSION="102"
+CHROMIUM_LANGS="
+       am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discordapp.com"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+RESTRICT="bindist mirror strip test"
+IUSE="+seccomp"
+
+RDEPEND="
+               || (
+                       >=app-accessibility/at-spi2-core-2.46.0:2
+                       ( app-accessibility/at-spi2-atk dev-libs/atk )
+               )
+       app-crypt/libsecret
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="*"
+
+CONFIG_CHECK="~USER_NS"
+
+S="${WORKDIR}/${MY_PN^}"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+       # fix .desktop exec location
+       sed -i "/Exec/s:/usr/share/discord/Discord:${DESTDIR}/${MY_PN^}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+       # USE seccomp
+       if ! use seccomp; then
+               sed -i '/Exec/s/Discord/Discord --disable-seccomp-filter-sandbox/' \
+                       "${MY_PN}.desktop" ||
+                       die "sed failed for seccomp"
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libffmpeg.so libGLESv2.so libvk_swiftshader.so
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources swiftshader
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       dosym "${DESTDIR}/${MY_PN^}" "/usr/bin/${MY_PN}"
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "system tray support" dev-libs/libappindicator
+}
diff --git a/net-im/discord/discord-0.0.46.ebuild b/net-im/discord/discord-0.0.46.ebuild
new file mode 100644 (file)
index 0000000..e6f47c6
--- /dev/null
@@ -0,0 +1,135 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_LANGS="
+       af am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk ur vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discordapp.com"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+RESTRICT="bindist mirror strip test"
+IUSE="appindicator +seccomp"
+
+RDEPEND="
+       >=app-accessibility/at-spi2-core-2.46.0:2
+       app-crypt/libsecret
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+       appindicator? ( dev-libs/libayatana-appindicator )
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="*"
+
+CONFIG_CHECK="~USER_NS"
+
+S="${WORKDIR}/${MY_PN^}"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+       # fix .desktop exec location
+       sed -i "/Exec/s:/usr/share/discord/Discord:${DESTDIR}/${MY_PN^}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+       # USE seccomp
+       if ! use seccomp; then
+               sed -i '/Exec/s/Discord/Discord --disable-seccomp-filter-sandbox/' \
+                       "${MY_PN}.desktop" ||
+                       die "sed failed for seccomp"
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libffmpeg.so libGLESv2.so libvk_swiftshader.so
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       # Crashpad is included in the package once in a while and when it does, it must be installed.
+       # See #903616 and #890595
+       [[ -x chrome_crashpad_handler ]] && doins chrome_crashpad_handler
+
+       dosym "${DESTDIR}/${MY_PN^}" "/usr/bin/${MY_PN}"
+
+       # https://bugs.gentoo.org/898912
+       if use appindicator; then
+               dosym ../../usr/lib64/libayatana-appindicator3.so /opt/discord/libappindicator3.so
+       fi
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature_header "Install the following packages for additional support:"
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "emoji support" media-fonts/noto-emoji
+}
diff --git a/net-im/discord/discord-0.0.64.ebuild b/net-im/discord/discord-0.0.64.ebuild
new file mode 100644 (file)
index 0000000..9c133ac
--- /dev/null
@@ -0,0 +1,147 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_LANGS="
+       af am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk ur vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discord.com/"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+S="${WORKDIR}/${MY_PN^}"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+
+IUSE="appindicator +seccomp wayland"
+RESTRICT="bindist mirror strip test"
+
+RDEPEND="
+       >=app-accessibility/at-spi2-core-2.46.0:2
+       app-crypt/libsecret
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+       appindicator? ( dev-libs/libayatana-appindicator )
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="*"
+
+CONFIG_CHECK="~USER_NS"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+
+       # fix .desktop exec location
+       sed --in-place --expression "/^Exec=/s:/usr/share/discord/Discord:/usr/bin/${MY_PN}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+
+       # Update exec location in launcher
+       sed --expression "s:@@DESTDIR@@:${DESTDIR}:" \
+               "${FILESDIR}/launcher.sh" > "${T}/launcher.sh" || die "updating of exec location in launcher failed"
+
+       # USE seccomp in launcher
+       if use seccomp; then
+               sed --in-place --expression '/^EBUILD_SECCOMP=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for seccomp"
+       fi
+
+       # USE wayland in launcher
+       if use wayland; then
+               sed --in-place --expression '/^EBUILD_WAYLAND=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for wayland"
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libffmpeg.so libGLESv2.so libvk_swiftshader.so
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       # Crashpad is included in the package once in a while and when it does, it must be installed.
+       # See #903616 and #890595
+       [[ -x chrome_crashpad_handler ]] && doins chrome_crashpad_handler
+
+       exeinto "/usr/bin"
+       newexe "${T}/launcher.sh" "discord" || die "failing to install launcher"
+
+       # https://bugs.gentoo.org/898912
+       if use appindicator; then
+               dosym ../../usr/lib64/libayatana-appindicator3.so /opt/discord/libappindicator3.so
+       fi
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature_header "Install the following packages for additional support:"
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "emoji support" media-fonts/noto-emoji
+}
diff --git a/net-im/discord/discord-0.0.65.ebuild b/net-im/discord/discord-0.0.65.ebuild
new file mode 100644 (file)
index 0000000..9c133ac
--- /dev/null
@@ -0,0 +1,147 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_LANGS="
+       af am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk ur vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discord.com/"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+S="${WORKDIR}/${MY_PN^}"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+
+IUSE="appindicator +seccomp wayland"
+RESTRICT="bindist mirror strip test"
+
+RDEPEND="
+       >=app-accessibility/at-spi2-core-2.46.0:2
+       app-crypt/libsecret
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+       appindicator? ( dev-libs/libayatana-appindicator )
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="*"
+
+CONFIG_CHECK="~USER_NS"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+
+       # fix .desktop exec location
+       sed --in-place --expression "/^Exec=/s:/usr/share/discord/Discord:/usr/bin/${MY_PN}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+
+       # Update exec location in launcher
+       sed --expression "s:@@DESTDIR@@:${DESTDIR}:" \
+               "${FILESDIR}/launcher.sh" > "${T}/launcher.sh" || die "updating of exec location in launcher failed"
+
+       # USE seccomp in launcher
+       if use seccomp; then
+               sed --in-place --expression '/^EBUILD_SECCOMP=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for seccomp"
+       fi
+
+       # USE wayland in launcher
+       if use wayland; then
+               sed --in-place --expression '/^EBUILD_WAYLAND=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for wayland"
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libffmpeg.so libGLESv2.so libvk_swiftshader.so
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       # Crashpad is included in the package once in a while and when it does, it must be installed.
+       # See #903616 and #890595
+       [[ -x chrome_crashpad_handler ]] && doins chrome_crashpad_handler
+
+       exeinto "/usr/bin"
+       newexe "${T}/launcher.sh" "discord" || die "failing to install launcher"
+
+       # https://bugs.gentoo.org/898912
+       if use appindicator; then
+               dosym ../../usr/lib64/libayatana-appindicator3.so /opt/discord/libappindicator3.so
+       fi
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature_header "Install the following packages for additional support:"
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "emoji support" media-fonts/noto-emoji
+}
diff --git a/net-im/discord/discord-0.0.66.ebuild b/net-im/discord/discord-0.0.66.ebuild
new file mode 100644 (file)
index 0000000..9c133ac
--- /dev/null
@@ -0,0 +1,147 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_LANGS="
+       af am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk ur vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discord.com/"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+S="${WORKDIR}/${MY_PN^}"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+
+IUSE="appindicator +seccomp wayland"
+RESTRICT="bindist mirror strip test"
+
+RDEPEND="
+       >=app-accessibility/at-spi2-core-2.46.0:2
+       app-crypt/libsecret
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+       appindicator? ( dev-libs/libayatana-appindicator )
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="*"
+
+CONFIG_CHECK="~USER_NS"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+
+       # fix .desktop exec location
+       sed --in-place --expression "/^Exec=/s:/usr/share/discord/Discord:/usr/bin/${MY_PN}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+
+       # Update exec location in launcher
+       sed --expression "s:@@DESTDIR@@:${DESTDIR}:" \
+               "${FILESDIR}/launcher.sh" > "${T}/launcher.sh" || die "updating of exec location in launcher failed"
+
+       # USE seccomp in launcher
+       if use seccomp; then
+               sed --in-place --expression '/^EBUILD_SECCOMP=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for seccomp"
+       fi
+
+       # USE wayland in launcher
+       if use wayland; then
+               sed --in-place --expression '/^EBUILD_WAYLAND=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for wayland"
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libffmpeg.so libGLESv2.so libvk_swiftshader.so
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       # Crashpad is included in the package once in a while and when it does, it must be installed.
+       # See #903616 and #890595
+       [[ -x chrome_crashpad_handler ]] && doins chrome_crashpad_handler
+
+       exeinto "/usr/bin"
+       newexe "${T}/launcher.sh" "discord" || die "failing to install launcher"
+
+       # https://bugs.gentoo.org/898912
+       if use appindicator; then
+               dosym ../../usr/lib64/libayatana-appindicator3.so /opt/discord/libappindicator3.so
+       fi
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature_header "Install the following packages for additional support:"
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "emoji support" media-fonts/noto-emoji
+}
diff --git a/net-im/discord/discord-0.0.69.ebuild b/net-im/discord/discord-0.0.69.ebuild
new file mode 100644 (file)
index 0000000..1af3700
--- /dev/null
@@ -0,0 +1,146 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_LANGS="
+       af am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk ur vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discord.com/"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+S="${WORKDIR}/${MY_PN^}"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+
+IUSE="appindicator +seccomp wayland"
+RESTRICT="bindist mirror strip test"
+
+RDEPEND="
+       >=app-accessibility/at-spi2-core-2.46.0:2
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+       appindicator? ( dev-libs/libayatana-appindicator )
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="*"
+
+CONFIG_CHECK="~USER_NS"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+
+       # fix .desktop exec location
+       sed --in-place --expression "/^Exec=/s:/usr/share/discord/Discord:/usr/bin/${MY_PN}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+
+       # Update exec location in launcher
+       sed --expression "s:@@DESTDIR@@:${DESTDIR}:" \
+               "${FILESDIR}/launcher.sh" > "${T}/launcher.sh" || die "updating of exec location in launcher failed"
+
+       # USE seccomp in launcher
+       if use seccomp; then
+               sed --in-place --expression '/^EBUILD_SECCOMP=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for seccomp"
+       fi
+
+       # USE wayland in launcher
+       if use wayland; then
+               sed --in-place --expression '/^EBUILD_WAYLAND=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for wayland"
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libffmpeg.so libGLESv2.so libvk_swiftshader.so
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       # Crashpad is included in the package once in a while and when it does, it must be installed.
+       # See #903616 and #890595
+       [[ -x chrome_crashpad_handler ]] && doins chrome_crashpad_handler
+
+       exeinto "/usr/bin"
+       newexe "${T}/launcher.sh" "discord" || die "failing to install launcher"
+
+       # https://bugs.gentoo.org/898912
+       if use appindicator; then
+               dosym ../../usr/lib64/libayatana-appindicator3.so /opt/discord/libappindicator3.so
+       fi
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature_header "Install the following packages for additional support:"
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "emoji support" media-fonts/noto-emoji
+}
diff --git a/net-im/discord/discord-0.0.70.ebuild b/net-im/discord/discord-0.0.70.ebuild
new file mode 100644 (file)
index 0000000..1af3700
--- /dev/null
@@ -0,0 +1,146 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_LANGS="
+       af am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk ur vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discord.com/"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+S="${WORKDIR}/${MY_PN^}"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+
+IUSE="appindicator +seccomp wayland"
+RESTRICT="bindist mirror strip test"
+
+RDEPEND="
+       >=app-accessibility/at-spi2-core-2.46.0:2
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+       appindicator? ( dev-libs/libayatana-appindicator )
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="*"
+
+CONFIG_CHECK="~USER_NS"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+
+       # fix .desktop exec location
+       sed --in-place --expression "/^Exec=/s:/usr/share/discord/Discord:/usr/bin/${MY_PN}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+
+       # Update exec location in launcher
+       sed --expression "s:@@DESTDIR@@:${DESTDIR}:" \
+               "${FILESDIR}/launcher.sh" > "${T}/launcher.sh" || die "updating of exec location in launcher failed"
+
+       # USE seccomp in launcher
+       if use seccomp; then
+               sed --in-place --expression '/^EBUILD_SECCOMP=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for seccomp"
+       fi
+
+       # USE wayland in launcher
+       if use wayland; then
+               sed --in-place --expression '/^EBUILD_WAYLAND=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for wayland"
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libffmpeg.so libGLESv2.so libvk_swiftshader.so
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       # Crashpad is included in the package once in a while and when it does, it must be installed.
+       # See #903616 and #890595
+       [[ -x chrome_crashpad_handler ]] && doins chrome_crashpad_handler
+
+       exeinto "/usr/bin"
+       newexe "${T}/launcher.sh" "discord" || die "failing to install launcher"
+
+       # https://bugs.gentoo.org/898912
+       if use appindicator; then
+               dosym ../../usr/lib64/libayatana-appindicator3.so /opt/discord/libappindicator3.so
+       fi
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature_header "Install the following packages for additional support:"
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "emoji support" media-fonts/noto-emoji
+}
diff --git a/net-im/discord/discord-0.0.71.ebuild b/net-im/discord/discord-0.0.71.ebuild
new file mode 100644 (file)
index 0000000..1af3700
--- /dev/null
@@ -0,0 +1,146 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_LANGS="
+       af am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk ur vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discord.com/"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+S="${WORKDIR}/${MY_PN^}"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+
+IUSE="appindicator +seccomp wayland"
+RESTRICT="bindist mirror strip test"
+
+RDEPEND="
+       >=app-accessibility/at-spi2-core-2.46.0:2
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+       appindicator? ( dev-libs/libayatana-appindicator )
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="*"
+
+CONFIG_CHECK="~USER_NS"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+
+       # fix .desktop exec location
+       sed --in-place --expression "/^Exec=/s:/usr/share/discord/Discord:/usr/bin/${MY_PN}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+
+       # Update exec location in launcher
+       sed --expression "s:@@DESTDIR@@:${DESTDIR}:" \
+               "${FILESDIR}/launcher.sh" > "${T}/launcher.sh" || die "updating of exec location in launcher failed"
+
+       # USE seccomp in launcher
+       if use seccomp; then
+               sed --in-place --expression '/^EBUILD_SECCOMP=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for seccomp"
+       fi
+
+       # USE wayland in launcher
+       if use wayland; then
+               sed --in-place --expression '/^EBUILD_WAYLAND=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for wayland"
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libffmpeg.so libGLESv2.so libvk_swiftshader.so
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       # Crashpad is included in the package once in a while and when it does, it must be installed.
+       # See #903616 and #890595
+       [[ -x chrome_crashpad_handler ]] && doins chrome_crashpad_handler
+
+       exeinto "/usr/bin"
+       newexe "${T}/launcher.sh" "discord" || die "failing to install launcher"
+
+       # https://bugs.gentoo.org/898912
+       if use appindicator; then
+               dosym ../../usr/lib64/libayatana-appindicator3.so /opt/discord/libappindicator3.so
+       fi
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature_header "Install the following packages for additional support:"
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "emoji support" media-fonts/noto-emoji
+}
diff --git a/net-im/discord/discord-0.0.72.ebuild b/net-im/discord/discord-0.0.72.ebuild
new file mode 100644 (file)
index 0000000..1af3700
--- /dev/null
@@ -0,0 +1,146 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+MY_PN="${PN/-bin/}"
+MY_PV="${PV/-r*/}"
+
+CHROMIUM_LANGS="
+       af am ar bg bn ca cs da de el en-GB en-US es es-419 et fa fi fil fr gu he hi
+       hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv
+       sw ta te th tr uk ur vi zh-CN zh-TW
+"
+
+inherit chromium-2 desktop linux-info optfeature unpacker xdg
+
+DESCRIPTION="All-in-one voice and text chat for gamers"
+HOMEPAGE="https://discord.com/"
+SRC_URI="https://dl.discordapp.net/apps/linux/${MY_PV}/${MY_PN}-${MY_PV}.tar.gz"
+S="${WORKDIR}/${MY_PN^}"
+
+LICENSE="all-rights-reserved"
+SLOT="0"
+KEYWORDS="amd64"
+
+IUSE="appindicator +seccomp wayland"
+RESTRICT="bindist mirror strip test"
+
+RDEPEND="
+       >=app-accessibility/at-spi2-core-2.46.0:2
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/fontconfig
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       sys-apps/util-linux
+       sys-libs/glibc
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/gdk-pixbuf:2
+       x11-libs/gtk+:3
+       x11-libs/libX11
+       x11-libs/libXScrnSaver
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libXrandr
+       x11-libs/libxcb
+       x11-libs/libxkbcommon
+       x11-libs/libxshmfence
+       x11-libs/pango
+       appindicator? ( dev-libs/libayatana-appindicator )
+"
+
+DESTDIR="/opt/${MY_PN}"
+
+QA_PREBUILT="*"
+
+CONFIG_CHECK="~USER_NS"
+
+src_unpack() {
+       unpack ${MY_PN}-${MY_PV}.tar.gz
+}
+
+src_configure() {
+       default
+       chromium_suid_sandbox_check_kernel_config
+}
+
+src_prepare() {
+       default
+       # remove post-install script
+       rm postinst.sh || die "the removal of the unneeded post-install script failed"
+       # cleanup languages
+       pushd "locales/" >/dev/null || die "location change for language cleanup failed"
+       chromium_remove_language_paks
+       popd >/dev/null || die "location reset for language cleanup failed"
+
+       # fix .desktop exec location
+       sed --in-place --expression "/^Exec=/s:/usr/share/discord/Discord:/usr/bin/${MY_PN}:" \
+               "${MY_PN}.desktop" ||
+               die "fixing of exec location on .desktop failed"
+
+       # Update exec location in launcher
+       sed --expression "s:@@DESTDIR@@:${DESTDIR}:" \
+               "${FILESDIR}/launcher.sh" > "${T}/launcher.sh" || die "updating of exec location in launcher failed"
+
+       # USE seccomp in launcher
+       if use seccomp; then
+               sed --in-place --expression '/^EBUILD_SECCOMP=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for seccomp"
+       fi
+
+       # USE wayland in launcher
+       if use wayland; then
+               sed --in-place --expression '/^EBUILD_WAYLAND=/s/false/true/' \
+                       "${T}/launcher.sh" || die "sed failed for wayland"
+       fi
+}
+
+src_install() {
+       doicon -s 256 "${MY_PN}.png"
+
+       # install .desktop file
+       domenu "${MY_PN}.desktop"
+
+       exeinto "${DESTDIR}"
+
+       doexe "${MY_PN^}" chrome-sandbox libEGL.so libffmpeg.so libGLESv2.so libvk_swiftshader.so
+
+       insinto "${DESTDIR}"
+       doins chrome_100_percent.pak chrome_200_percent.pak icudtl.dat resources.pak snapshot_blob.bin v8_context_snapshot.bin
+       insopts -m0755
+       doins -r locales resources
+
+       # Chrome-sandbox requires the setuid bit to be specifically set.
+       # see https://github.com/electron/electron/issues/17972
+       fowners root "${DESTDIR}/chrome-sandbox"
+       fperms 4711 "${DESTDIR}/chrome-sandbox"
+
+       # Crashpad is included in the package once in a while and when it does, it must be installed.
+       # See #903616 and #890595
+       [[ -x chrome_crashpad_handler ]] && doins chrome_crashpad_handler
+
+       exeinto "/usr/bin"
+       newexe "${T}/launcher.sh" "discord" || die "failing to install launcher"
+
+       # https://bugs.gentoo.org/898912
+       if use appindicator; then
+               dosym ../../usr/lib64/libayatana-appindicator3.so /opt/discord/libappindicator3.so
+       fi
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+
+       optfeature_header "Install the following packages for additional support:"
+       optfeature "sound support" \
+               media-sound/pulseaudio media-sound/apulse[sdk] media-video/pipewire
+       optfeature "emoji support" media-fonts/noto-emoji
+}
diff --git a/net-im/discord/files/launcher.sh b/net-im/discord/files/launcher.sh
new file mode 100644 (file)
index 0000000..31c2cc3
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+# coding: UTF-8
+
+
+declare -a discord_parameters
+
+# Variables set during ebuild configuration
+EBUILD_SECCOMP=false
+EBUILD_WAYLAND=false
+
+"${EBUILD_SECCOMP}" || discord_parameters+=( --disable-seccomp-filter-sandbox )
+
+"${EBUILD_WAYLAND}" && \
+[[ -n "${WAYLAND_DISPLAY}" ]] && discord_parameters+=(
+       --enable-features=UseOzonePlatform
+       --ozone-platform=wayland
+       --enable-wayland-ime
+)
+
+@@DESTDIR@@/Discord "${discord_parameters[@]}" "$@"
diff --git a/net-misc/xmrig/Manifest b/net-misc/xmrig/Manifest
new file mode 100644 (file)
index 0000000..13ab201
--- /dev/null
@@ -0,0 +1,12 @@
+AUX logrotated 648 BLAKE2B d3a0551f9263f64f43d5d32e45050a1bb2c9f9498c2a57fad7c1ddaec920b2cee6c83010e08b255c2f612b38e33688eaa2cb9e5cc42cda2204b8da455eeaf73a SHA512 f8fae0b59ead03c67e833d8d387613a7e8a5a487d4f73df63de0b5e5ec540cbdb342b97b4faba09eede23b66c98b883f04de71402aa0a1129729db7db2f5837f
+AUX xmrig-6.12.2-nonotls.patch 578 BLAKE2B 4d71c8d35be47fd12a019d7b8cb6e1b8787e153ab543b9b1e4079c911671ff886042d90cd439552bf364208d9a4afcc7fe088b50598bbc20e347b532dfc92a2d SHA512 fea6041879c414a4fc6006a413b217801d674f7b5d849d95c119d07e191c5d7a5e99fb959d89974b68be9df132ff480f8492645ba6821b369444b102596b06f3
+AUX xmrig.initd 637 BLAKE2B 9835422fca1e73ae27a20264aaaf825de31539202c4be5af292f2daa8948c76694c42f10a9c7c6096b683b443e92040605fa2bb2bc1b3d18bc95a3870bfc004e SHA512 151c2474090bb2ea5e5a301279a042de4467a72d721fd1a35b055d55929a06e71b3aa0042f08e8cbefd1d9972f45cda606a26da6d8445a57f777b84334770809
+AUX xmrig.service 946 BLAKE2B 1f3b28f8229183da528ac2b4279dd64b5c6f752720c6bdfe90fa9e127108623e4a577a274527249ee7a13969be97e9b1a4348f7c3e0798839d0ed3ee67b16188 SHA512 77da620627272113e7c77a090536b04cb5a89f4010060ffb21ea1c9edc50e0743f913a70e4fb612c23aeea2b8f1a3f9ce024a434076cf9498cce0b5f801faafa
+AUX xmrigd.1.initd 745 BLAKE2B b1fb0abdd38363f59466e0ea6e6dd63a804f3c00c3ab20daa54c60438d66ac1806f541d36403997f915e95ef039b274558dedb6135793c4f5fdc2287ff99f222 SHA512 e5372505efa523f5d511562dcaae61f4fbf2947fcf2d4a40bf4d7db620b5714a1a7afc54e6c3aa1c5656659bc4a64796c5ee7c21d41a833e9530fe24f003da09
+AUX xmrigd.confd 102 BLAKE2B 17210027a083f4c608140a47f02ce510b0b1c9ef5395ba52fe2853eae3cfa07dd8b2a3aff252a1b967f5499bd3b62acc643fc43f04da3161d847e111106e21b0 SHA512 3692ed6210c450d44ff6203df45a3a4b9084915c4b3ddf1aa0372beca0bd2f9051eaf4c06833c90be4779908e75c6212d3eea55b504eac4839ff1c2380dcdf40
+DIST xmrig-6.21.1.tar.gz 2416545 BLAKE2B 72ecdfc8c999aee91aef4f540211c5d5a6f1992c76211162a623e89391cedfcc2d5540f291d9915ee4180b83f58ef7f2eb1e3aff8dee49c72f41f90878d7ef62 SHA512 a9267708e61084db7116381adb2256a04c30eba0c84b571764cc73ccafc9276f55b6665529eb7b9c1785d582d0d280ced6ee7ca88a5e98f9bbdef2a9176a9794
+DIST xmrig-6.22.2.tar.gz 2435360 BLAKE2B c9b81ee93a008639709751b3924461d29216f8daa4beb3db96d983812efa5083926624aaea14d20692c3a3740a1ca178383b8b7cce0c1ad78a16f0299f891561 SHA512 4e25364737456711b09d5ed68e0d26b74cc2f4f4408ff5d02e0063bf67d6f38db5fe9af5d099dc4fd4b3f668baf2023cb816c049d38588ba1b54a8a2c0393269
+EBUILD xmrig-6.21.1.ebuild 2114 BLAKE2B 179c107f4c4143dcedd6b7b67e4fe1347621162079b7a0c5f2211dfcbf6511a3b8539c139b45c852b16c007596a8b4952fa6d0e2be2397eb107d1a86b8ead504 SHA512 95382a0021017d70cf7b07e63f7bd34f34bfa9bb6455fe8a85af642618372a912be0daaff7845ce1ee29ea65331ecc4e1f2a0a57866f7e1987b32ae5f96c1eca
+EBUILD xmrig-6.22.2-r1.ebuild 1986 BLAKE2B 1a6f024dd5aa1fed5952a8b54342a626083378616b29567d745f13a7bdc25ca0097b5d791889d7c1e8dcaa28cada06025d1e0f1ac701475260511629889b9be0 SHA512 94ead70250245f0c344264797c047aebe90694505fb76d0d4c9610e897ab2981b9bc4bdaa8b959723bdd87275e45fef1d16c1bd5428e9b0c9c5ba29807344130
+EBUILD xmrig-6.22.2.ebuild 1968 BLAKE2B f87028b760272cde89188bf59d448a55ad5c23d75f6ef38a5ba78d71c6709ceb3b630fe29292b946d4c3479355c81140d975175b43f99885a2111aed44222aaa SHA512 2d4f49e2ab0d2291b075f1bf91245b8881887e2acc1e5d1e4ada6c3597336fc8864a93512e4236cc85f3ace49a6d5e76bc0ac779773781647c6da460220bdb2a
+MISC xmrig-6.22.2.ebuild.save 1340 BLAKE2B 5161c77d9100a6b6020af9903d52f517c795dccc4032a5507af5f6542a7e41e3db3ddfa09daf8e419c8b5d4dfc09ec289b2c36e7182258230bb8d5fb501095f9 SHA512 17ae9d96b393edf923cc14c43167981e7cbb03a29744436e161056bcacbfa9aae5d740af50c9f2f9f9e7c7e6c832cca43f42a896542b7442a26d82c5e04d8650
diff --git a/net-misc/xmrig/files/logrotated b/net-misc/xmrig/files/logrotated
new file mode 100644 (file)
index 0000000..8ee1443
--- /dev/null
@@ -0,0 +1,9 @@
+# xmrig logrotate snipet for Gentoo Linux
+
+/var/log/xmrig.log {
+  rotate 7                                                                                                                                                                                                                                                                    
+  daily                                                                                                                                                                                                                                                                       
+  missingok
+  notifempty
+  copytruncate
+}
diff --git a/net-misc/xmrig/files/xmrig-6.12.2-nonotls.patch b/net-misc/xmrig/files/xmrig-6.12.2-nonotls.patch
new file mode 100644 (file)
index 0000000..f58c7e2
--- /dev/null
@@ -0,0 +1,23 @@
+From ee98bfe01a94d021d81ed4c2bb11ec91c0bd81c8 Mon Sep 17 00:00:00 2001
+From: Matt Smith <matt@offtopica.uk>
+Date: Sun, 7 Jun 2020 13:20:04 +0100
+Subject: [PATCH] Don't suffix binary with -notls
+
+---
+ cmake/OpenSSL.cmake | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/cmake/OpenSSL.cmake b/cmake/OpenSSL.cmake
+index 89805301..c01c940a 100644
+--- a/cmake/OpenSSL.cmake
++++ b/cmake/OpenSSL.cmake
+@@ -54,6 +54,4 @@ else()
+             src/base/net/http/HttpServer.h
+             )
+     endif()
+-
+-    set(CMAKE_PROJECT_NAME "${CMAKE_PROJECT_NAME}-notls")
+ endif()
+-- 
+2.27.0
+
diff --git a/net-misc/xmrig/files/xmrig.initd b/net-misc/xmrig/files/xmrig.initd
new file mode 100755 (executable)
index 0000000..ea1c4db
--- /dev/null
@@ -0,0 +1,30 @@
+#!/sbin/openrc-run
+
+depend() {
+       need net
+       need xmrigdaemon
+}
+
+start() {
+       ebegin "Starting XMRig Virtual Service"
+       eend $?
+}
+
+stop() {
+       ebegin "Stopping XMRig Virtual Service"
+       #einfo "Looking for any XMRig daemons to stop"
+    for file in /etc/init.d/xmrigd.*;do rc-service $basename ${file} --nodeps stop 2>/dev/null;done
+       #einfo "All XMRig daemons stopped"
+       echo
+    eend $?
+}
+
+start_pre() {
+       [[ -e /etc/init.d/${RC_SVCNAME}d.$(nproc) ]] && exit
+       ewarn "${RC_SVCNAME}d.$(nproc) does not exist"
+       einfo "Preparing xmrigd service files"
+       for x in $(seq 2 $(nproc));do
+               ln -s /etc/init.d/xmrigd.1 /etc/init.d/xmrigd.${x}
+       done
+       eend $?
+}
diff --git a/net-misc/xmrig/files/xmrig.service b/net-misc/xmrig/files/xmrig.service
new file mode 100644 (file)
index 0000000..5b5c4c3
--- /dev/null
@@ -0,0 +1,35 @@
+[Unit]
+Description=XMRig Monero Miner
+After=network-online.target
+AssertFileNotEmpty=/etc/xmrig/config.json
+
+[Service]
+ExecStartPre=+/usr/bin/randomx_boost.sh
+ExecStartPre=+/usr/bin/enable_1gb_pages.sh
+ExecStartPre=/usr/bin/xmrig --config=/etc/xmrig/config.json --dry-run
+ExecStart=/usr/bin/xmrig --config=/etc/xmrig/config.json
+StandardOutput=journal
+StandardError=journal
+DynamicUser=true
+Nice=19
+CPUSchedulingPolicy=idle
+PrivateTmp=true
+ProtectHome=true
+ProtectSystem=strict
+NoNewPrivileges=true
+# PrivateDevices=true # https://github.com/systemd/systemd/issues/13857
+CapabilityBoundingSet=
+#ProtectClock=true # https://github.com/systemd/systemd/issues/20835
+ProtectKernelModules=true
+ProtectKernelTunables=true
+ProtectKernelLogs=true
+ProtectControlGroups=true
+RestrictRealtime=true
+RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
+RestrictNamespaces=true
+PrivateUsers=true
+ConfigurationDirectory=xmrig
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/net-misc/xmrig/files/xmrigd.1.initd b/net-misc/xmrig/files/xmrigd.1.initd
new file mode 100755 (executable)
index 0000000..d27b48f
--- /dev/null
@@ -0,0 +1,27 @@
+#!/sbin/openrc-run
+
+name="${RC_SVCNAME/xmr/XMR} Cypto Miner Daemon"
+description="Mines crypto curreny"
+pidfile="/var/run/xmrig.pid"
+command=/usr/bin/xmrig
+command_args="${XMRIG_ARGS} ${RC_SVCNAME/xmrigd./--threads=}"
+supervisor=supervise-daemon
+command_user="${XMRIG_USR}:${XMRIG_GRP}"
+respawn_max="3"
+respawn_period="40"
+
+depend() {
+       need net
+       provide xmrigdaemon
+}
+
+start_pre() {
+    #einfo "Looking for any other XMRig daemons to stop"
+    for file in /etc/init.d/xmrigd.*;do [[ $RC_SVCNAME != $(basename $file) ]] && rc-service $basename ${file} stop --nodeps 2>/dev/null;done
+    #einfo "All other XMRig daemons stoped"
+    echo
+}
+
+stop_post() {
+       echo "stopped stopped  miner    speed 10s/60s/15m 0 0 0 H/s max 0 H/s">>/var/log/xmrig.log
+}
diff --git a/net-misc/xmrig/files/xmrigd.confd b/net-misc/xmrig/files/xmrigd.confd
new file mode 100644 (file)
index 0000000..1f43c2c
--- /dev/null
@@ -0,0 +1,3 @@
+XMRIG_ARGS="-o 10.0.0.254:3333 --log-file=/var/log/xmrig.log --verbose"
+XMRIG_USR=root
+XMRIG_GRP=root
diff --git a/net-misc/xmrig/xmrig-6.21.1.ebuild b/net-misc/xmrig/xmrig-6.21.1.ebuild
new file mode 100644 (file)
index 0000000..f935a20
--- /dev/null
@@ -0,0 +1,86 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit cmake flag-o-matic systemd toolchain-funcs
+
+DESCRIPTION="RandomX, CryptoNight, KawPow, AstroBWT, and Argon2 CPU/GPU miner"
+HOMEPAGE="https://xmrig.com https://github.com/xmrig/xmrig"
+
+if [[ ${PV} == *9999 ]] ; then
+       EGIT_REPO_URI="https://github.com/${PN}/${PN}.git"
+       inherit git-r3
+else
+       SRC_URI="https://github.com/xmrig/xmrig/archive/v${PV}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="amd64 arm64"
+fi
+
+LICENSE="Apache-2.0 GPL-3+ MIT"
+SLOT="0"
+IUSE="cpu_flags_x86_sse4_1 donate hwloc opencl +ssl"
+
+DEPEND="
+       dev-libs/libuv:=
+       hwloc? ( >=sys-apps/hwloc-2.5.0:= )
+       opencl? ( virtual/opencl )
+       ssl? ( dev-libs/openssl:= )
+"
+RDEPEND="
+       ${DEPEND}
+       !arm64? ( sys-apps/msr-tools )
+"
+
+PATCHES=(
+       "${FILESDIR}"/${PN}-6.12.2-nonotls.patch
+)
+
+src_prepare() {
+       if ! use donate ; then
+               sed -i 's/1;/0;/g' src/donate.h || die
+       fi
+
+       cmake_src_prepare
+}
+
+src_configure() {
+       # JIT broken with FORTIFY_SOURCE=3
+       # Bug #913420
+       if tc-enables-fortify-source; then
+               filter-flags -D_FORTIFY_SOURCE=3
+               append-cppflags -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
+       fi
+
+       local mycmakeargs=(
+               -DWITH_SSE4_1=$(usex cpu_flags_x86_sse4_1)
+               -DWITH_HWLOC=$(usex hwloc)
+               -DWITH_TLS=$(usex ssl)
+               -DWITH_OPENCL=$(usex opencl)
+               -DWITH_CUDA=OFF
+       )
+
+       cmake_src_configure
+}
+
+src_install() {
+       default
+       keepdir /etc/xmrig
+       systemd_dounit "${FILESDIR}"/xmrig.service
+    newconfd "${FILESDIR}/xmrigd.confd" ${PN}d
+    newinitd "${FILESDIR}/xmrigd.1.initd" ${PN}d.1
+    newinitd "${FILESDIR}/xmrig.initd" ${PN}
+       dobin "${BUILD_DIR}/xmrig"
+       dobin "${S}/scripts/enable_1gb_pages.sh"
+       dobin "${S}/scripts/randomx_boost.sh"
+}
+
+pkg_postinst() {
+    #Some stuff about the openrc service files
+    ewarn "XMRig is now installed."
+    ewarn "Update /etc/conf.d/xmrigd to your perference"
+    ewarn ""
+    ewarn "Once configured and started, xmrig will create and start an xmrigd.X service"
+    ewarn "An xmrigd.X service will be created for 1 to nproc cores"
+    ewarn "Starting xmrigd.X will start a daemonzsed xmrig using X threads"
+    ewarn ""
+}
diff --git a/net-misc/xmrig/xmrig-6.22.2-r1.ebuild b/net-misc/xmrig/xmrig-6.22.2-r1.ebuild
new file mode 100644 (file)
index 0000000..a5cfdcc
--- /dev/null
@@ -0,0 +1,81 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit cmake systemd
+
+DESCRIPTION="RandomX, CryptoNight, KawPow, AstroBWT, and Argon2 CPU/GPU miner"
+HOMEPAGE="https://xmrig.com https://github.com/xmrig/xmrig"
+
+if [[ ${PV} == *9999 ]] ; then
+       EGIT_REPO_URI="https://github.com/${PN}/${PN}.git"
+       inherit git-r3
+else
+       SRC_URI="https://github.com/xmrig/xmrig/archive/v${PV}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="amd64 ~arm64"
+fi
+
+LICENSE="Apache-2.0 GPL-3+ MIT"
+SLOT="0"
+IUSE="cpu_flags_x86_sse4_1 donate hwloc opencl +ssl"
+
+DEPEND="
+       dev-libs/libuv:=
+       hwloc? ( >=sys-apps/hwloc-2.5.0:= )
+       opencl? ( virtual/opencl )
+       ssl? ( dev-libs/openssl:= )
+"
+RDEPEND="
+       ${DEPEND}
+       !arm64? ( sys-apps/msr-tools )
+"
+
+PATCHES=(
+       "${FILESDIR}"/${PN}-6.12.2-nonotls.patch
+)
+
+src_prepare() {
+       if ! use donate ; then
+               sed -i 's/1;/0;/g' src/donate.h || die
+       fi
+
+       cmake_src_prepare
+}
+
+src_configure() {
+       local mycmakeargs=(
+               -DWITH_SSE4_1=$(usex cpu_flags_x86_sse4_1)
+               -DWITH_HWLOC=$(usex hwloc)
+               -DWITH_TLS=$(usex ssl)
+               -DWITH_OPENCL=$(usex opencl)
+               -DWITH_CUDA=OFF
+       )
+
+       cmake_src_configure
+}
+
+src_install() {
+    default
+    keepdir /etc/xmrig
+    systemd_dounit "${FILESDIR}"/xmrig.service
+    newconfd "${FILESDIR}/xmrigd.confd" xmrigd
+    newinitd "${FILESDIR}/xmrigd.1.initd" xmrigd.1
+    newinitd "${FILESDIR}/xmrig.initd" xmrig
+       insinto /etc/logrotate.d
+       newins "${FILESDIR}/logrotated" xmrig
+    dobin "${BUILD_DIR}/xmrig"
+    dobin "${S}/scripts/enable_1gb_pages.sh"
+    dobin "${S}/scripts/randomx_boost.sh"
+}
+
+pkg_postinst() {
+    #Some stuff about the openrc service files
+    ewarn "XMRig is now installed."
+    ewarn "Update /etc/conf.d/xmrigd to your perference"
+    ewarn ""
+    ewarn "Once configured and started, xmrig will create and start an xmrigd.X service"
+    ewarn "An xmrigd.X service will be created for 1 to nproc cores"
+    ewarn "Starting xmrigd.X will start a daemonzsed xmrig using X threads"
+    ewarn ""
+}
diff --git a/net-misc/xmrig/xmrig-6.22.2.ebuild b/net-misc/xmrig/xmrig-6.22.2.ebuild
new file mode 100644 (file)
index 0000000..4be5d9a
--- /dev/null
@@ -0,0 +1,80 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit cmake systemd
+
+DESCRIPTION="RandomX, CryptoNight, KawPow, AstroBWT, and Argon2 CPU/GPU miner"
+HOMEPAGE="https://xmrig.com https://github.com/xmrig/xmrig"
+
+if [[ ${PV} == *9999 ]] ; then
+       EGIT_REPO_URI="https://github.com/${PN}/${PN}.git"
+       inherit git-r3
+else
+       SRC_URI="https://github.com/xmrig/xmrig/archive/v${PV}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="amd64 ~arm64"
+fi
+
+LICENSE="Apache-2.0 GPL-3+ MIT"
+SLOT="0"
+IUSE="cpu_flags_x86_sse4_1 donate hwloc opencl +ssl"
+
+DEPEND="
+       dev-libs/libuv:=
+       hwloc? ( >=sys-apps/hwloc-2.5.0:= )
+       opencl? ( virtual/opencl )
+       ssl? ( dev-libs/openssl:= )
+"
+RDEPEND="
+       ${DEPEND}
+       !arm64? ( sys-apps/msr-tools )
+"
+
+PATCHES=(
+       "${FILESDIR}"/${PN}-6.12.2-nonotls.patch
+)
+
+src_prepare() {
+       if ! use donate ; then
+               sed -i 's/1;/0;/g' src/donate.h || die
+       fi
+
+       cmake_src_prepare
+}
+
+src_configure() {
+       local mycmakeargs=(
+               -DWITH_SSE4_1=$(usex cpu_flags_x86_sse4_1)
+               -DWITH_HWLOC=$(usex hwloc)
+               -DWITH_TLS=$(usex ssl)
+               -DWITH_OPENCL=$(usex opencl)
+               -DWITH_CUDA=OFF
+       )
+
+       cmake_src_configure
+}
+
+src_install() {
+    default
+    keepdir /etc/xmrig
+    systemd_dounit "${FILESDIR}"/xmrig.service
+    newconfd "${FILESDIR}/xmrigd.confd" "${PN}d"
+    newinitd "${FILESDIR}/xmrigd.1.initd" "${PN}d.1"
+    newinitd "${FILESDIR}/xmrig.initd" "${PN}"
+       newins "${FILESDIR}/logrotated" "${PN}"
+    dobin "${BUILD_DIR}/xmrig"
+    dobin "${S}/scripts/enable_1gb_pages.sh"
+    dobin "${S}/scripts/randomx_boost.sh"
+}
+
+pkg_postinst() {
+    #Some stuff about the openrc service files
+    ewarn "XMRig is now installed."
+    ewarn "Update /etc/conf.d/xmrigd to your perference"
+    ewarn ""
+    ewarn "Once configured and started, xmrig will create and start an xmrigd.X service"
+    ewarn "An xmrigd.X service will be created for 1 to nproc cores"
+    ewarn "Starting xmrigd.X will start a daemonzsed xmrig using X threads"
+    ewarn ""
+}
diff --git a/net-misc/xmrig/xmrig-6.22.2.ebuild.save b/net-misc/xmrig/xmrig-6.22.2.ebuild.save
new file mode 100644 (file)
index 0000000..b58e587
--- /dev/null
@@ -0,0 +1,65 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit cmake systemd
+
+DESCRIPTION="RandomX, CryptoNight, KawPow, AstroBWT, and Argon2 CPU/GPU miner"
+HOMEPAGE="https://xmrig.com https://github.com/xmrig/xmrig"
+
+if [[ ${PV} == *9999 ]] ; then
+       EGIT_REPO_URI="https://github.com/${PN}/${PN}.git"
+       inherit git-r3
+else
+       SRC_URI="https://github.com/xmrig/xmrig/archive/v${PV}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="amd64 ~arm64"
+fi
+
+LICENSE="Apache-2.0 GPL-3+ MIT"
+SLOT="0"
+IUSE="cpu_flags_x86_sse4_1 donate hwloc opencl +ssl"
+
+DEPEND="
+       dev-libs/libuv:=
+       hwloc? ( >=sys-apps/hwloc-2.5.0:= )
+       opencl? ( virtual/opencl )
+       ssl? ( dev-libs/openssl:= )
+"
+RDEPEND="
+       ${DEPEND}
+       !arm64? ( sys-apps/msr-tools )
+"
+
+PATCHES=(
+       "${FILESDIR}"/${PN}-6.12.2-nonotls.patch
+)
+
+src_prepare() {
+       if ! use donate ; then
+               sed -i 's/1;/0;/g' src/donate.h || die
+       fi
+
+       cmake_src_prepare
+}
+
+src_configure() {
+       local mycmakeargs=(
+               -DWITH_SSE4_1=$(usex cpu_flags_x86_sse4_1)
+               -DWITH_HWLOC=$(usex hwloc)
+               -DWITH_TLS=$(usex ssl)
+               -DWITH_OPENCL=$(usex opencl)
+               -DWITH_CUDA=OFF
+       )
+
+       cmake_src_configure
+}
+
+src_install() {
+       default
+       keepdir /etc/xmrig
+       systemd_dounit "${FILESDIR}"/xmrig.service
+       dobin "${BUILD_DIR}/xmrig"
+       dobin "${S}/scripts/enable_1gb_pages.sh"
+       dobin "${S}/scripts/randomx_boost.sh"
+}
diff --git a/net-p2p/monero/Manifest b/net-p2p/monero/Manifest
new file mode 100644 (file)
index 0000000..20558da
--- /dev/null
@@ -0,0 +1,16 @@
+AUX logrotated 135 BLAKE2B 04f1945f32ac4f3f3078dfc13c49aa8c4d50d4f89c5224d7976674a21efb3fb1d1ff2e1ec97af28d35aa0dbdb49b6e67312a1ab183b5a6093ee8959b6fd813b2 SHA512 05b33bf5c5ed1be0c14f5df8da078d45925b8e01a97e5f695e5900f2a6a90175d652896fe5e55b4b50ce724b023c860e0f3cdeda4b0b0d815a4a9ed99feae22d
+AUX monero-0.17.3.2-unbundle-dependencies.patch 3809 BLAKE2B bc629c1061fad475ec26d040aef3615dab3a01bc4fc6c4f9e34834d61abce0e1cca4e61cd7a55884ced5c803c50035d7657d58a53803c0bd3bbd0ef0da10dd56 SHA512 cddd5e831ecea0ce1a0bb863431fa3853b8fd8235e1368c1b1db2751bf66d6850cdfd48f45a98d87a0b7192021297837f82c64386ef7a1393b711820c7de4714
+AUX monero-0.18.3.3-miniupnp-api-18.patch 1141 BLAKE2B 4011addc3b5336ae748a0d6f8e85143153c6ab92685334ca03ca4a5dcec9e4bfa30f5a5a8098e6797e9be1abcf4b2c25da8b7da97e3f109590ce8f321cf78147 SHA512 f02b555c0b6d9055b6e5167984c2dc3d3b4d9878b9d069a0b253f9f4d0ccf27fd5b8d58b8b5f12df9662fac3fc1fb84260038da6866db6d1f507884fb86dcf07
+AUX monero-0.18.3.3-unbundle-dependencies.patch 3251 BLAKE2B e30193a12401a449632f3315b63d43f1d79be0850b3b90ce6126b906b57e2d2c2060a91858cf30a5ae2be09f09f0187e04f8c67cdbd8c9cb5e719eaa88d6baf8 SHA512 df0b223ad6b3da15af2d92d15e30c3b2314b49afe39b5ff977bf1959f7cb66a21f5857bbc393fbf80558c0ac9f9e4865d9fd5b3e7a28d71a1faf4bc74b5b7708
+AUX monero-0.18.3.4-boost-1.85.patch 34765 BLAKE2B e6461c31b24e6216dfa532d0b96d6efa45f84136c238a565123cbc35b2fdf8be3ee6fbc6f0345acb44a8080a2ab65211149f3ed13b5e6d76e5eabbdc75ec035a SHA512 43935ae2a1fc69a4a26a1909626bc3240139784a405a34cb2b69ed6eb576bc11988f3e5dbc449620bb223b56d92ed57f64eef48ed0efe0e6f6e32fcd97c10d3b
+AUX monero-0.18.4.0-unbundle-dependencies.patch 3327 BLAKE2B 4482b25d6e24957508adee551d6a95426ad699bc2995bf826717363eba747a75fd73a490262f1b07403898a37d2a81e6e2f2fb3977000b394a0f150cfc9267c9 SHA512 613b0754dcde5dba4735b5dc7960c8653a2a774bdbecb6f8a5a1f8ef908331d466ff9e1b5bbe69c6a69a50009c1b2e518a2191e98a03249a4bedee8a9ea91cda
+AUX monerod.conf 13206 BLAKE2B a4b011d3cbbc1c3ff3602d7c363ed9edc66db211909f930a2b86be746afd1ce244a2b314af5150599082216f769ef3149fc791100c391c302d150ebd927cadfb SHA512 0468feecf1d8283e74c4d998f954d5a63a073ed5b6faa432087c1b9f14910180a59dcbfb6fa1ed69c8e391f2a062dab9e43c80fd450238aa15b100017812bf0e
+AUX monerod.confd 498 BLAKE2B 96ff2761152b8cb9987253f68caf2e93c40065467877047c7074150a2359025cd20578c3dad1c4cca5c13a0c3f808fce8ec74485744e2cedb8c0537e854d5c31 SHA512 596bebabd0f4338bb9d1d6d465b2a7db60c2e73148497dfe2abc925bb05c3c85b4d260a8a392b8d9879d3e2b97dd60d91b93c25b5ca6fc97691cdc1bd500d22f
+AUX monerod.initd 1285 BLAKE2B ee373039b0db81e9d20e6bdcf54765e9151832ce71ef19d97aa4ac17d08976f2c449e0050acd71e6199d235af1fd04564005297cea347551eb811a6c96de7a42 SHA512 57e528baf2eb49fd9bd182fb73a679ac5f4b9a59271640e2f543ead0ed2a96b41b28f00c07c326bc2a1c3b9ccfbcd6568e01de335eac4b1dfa7a860bb5f0ec0f
+AUX monerod.service 329 BLAKE2B e4390612e1e37cb47164967cc086eb32b1dac61ceba621d376ae87220245284d83dd0895e786daf1652ff40c0161f713cd4f124ae7b2d57306208d5886c8aeb3 SHA512 38eb172bcd46c98a5aaa8f7c0d8bf011c183fd4d09f9d38c14679a4a0ee628d58c6dde6cce181745b053576e3b8907038d75ec3bcb3b0bb03e62c606573038b3
+DIST monero-0.18.3.4.tar.gz 14039924 BLAKE2B cb60f1db4f482bac3b3f5fa606bf1c78103b14f927d4636e5fda4aa96dcc08a9f990355ceb1cdc8c253245a0a2a1c98cf4fd7101d13d78ac6e7d1450192fc2db SHA512 f2708bf7698410c1509ae41148c298e352b3401e1df900b7152c25cb5ceb2f5bde68274fd37b1a328e932be50bdf93fe364561c520a15e3df7de2cdbd20d1be8
+DIST monero-0.18.4.0.tar.gz 14083573 BLAKE2B 6edd37cf89305dabddf04aa454a605f578276a924f703025b906612438de9dce12c854127b851ae0a71eb4b7aac6c9aa1bb7beb0d6ed311a55c19387117c2ba0 SHA512 6d17654a37d1a3aec37f641a58026a5f602e13836bdc50223ce6bf82ad9be9db2cf5abadd6b7bc963f4bfc0e18aa76298d89050686f6563d0567d2745e0512eb
+EBUILD monero-0.18.3.4-r1.ebuild 3205 BLAKE2B e617b505f5b6b8dbdc887344cd4ad7bc936c3f2347cc7a1e789f414b8f168c4a239354df41856c1bf73b77891860612a905ac626cb4aafb8aea549c6323c0e99 SHA512 3d19f4717a9aa2792ab2fdba10e667c6bd84dd4cade344c74cb6311ea10bdd74e486b26a21a2004b0ac41aa882d1ef2c0958dd6160f1897556902f18cf156415
+EBUILD monero-0.18.3.4-r2.ebuild 3232 BLAKE2B 7f7f5819bd804351a79546be58a1f54b740570fd73026bc0233273a1d5dbd825b04c9cf295ca3b6b3f16243fe0bf337dcf29afe8c0cf3bb6d3ebb2366bf13a77 SHA512 82f1c58103a367667c908806344161e28ab005a5a8b21cb47af54bd60793dcd9cdbf3faba7f49f982e0a899115e1644244fa0b64c6751f6e1ef7324e0d40ccf3
+EBUILD monero-0.18.4.0-r1.ebuild 3179 BLAKE2B 151c126b2b24c7c7e3b452cc099f7f674876d8697d5f55361864d290458d4160dbd4393c1b5d7ab88a14bd13f92a28a9711e7d7f228652bbb3bcd0a5182a37c9 SHA512 55b3481f9ee4e7a3c29062cd94b5a39e0af964feedf0b829419b4662d22d4178b536413ca8aebbdae6bca837b5ad017bb6ac67890f415416cd7172a6230a9eb6
+MISC metadata.xml 1105 BLAKE2B 50be9f62972c9524bd9c8b9875bf690f908f8f291b8def8d5f3757f6736ea6de2b020cf18da1803a7c4c52af7925eefb7206232180f0b77782a43253961b14cc SHA512 00f3820dac346aa3365b24eafa179224b4465be56fbb559b3b0691076ec23a4dd288c7fbfc88f7d4064b771d5e5ad18b7085830aa9e0929433ad2dcdbc7f1b78
diff --git a/net-p2p/monero/files/logrotated b/net-p2p/monero/files/logrotated
new file mode 100644 (file)
index 0000000..2bc4859
--- /dev/null
@@ -0,0 +1,9 @@
+# monerod logrotate snipet for Gentoo Linux
+
+/var/log/monero/monero*log {
+  rotate 7
+  daily
+  missingok
+  notifempty
+  copytruncate
+}
diff --git a/net-p2p/monero/files/monero-0.17.3.2-unbundle-dependencies.patch b/net-p2p/monero/files/monero-0.17.3.2-unbundle-dependencies.patch
new file mode 100644 (file)
index 0000000..ec03bf5
--- /dev/null
@@ -0,0 +1,114 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 41f82e26c..3eb2b2e78 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -382,7 +382,7 @@
+ # elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*")
+ #   set(BSDI TRUE)
+-include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include)
++include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external )
+ if(APPLE)
+   include_directories(SYSTEM /usr/include/malloc)
+@@ -1082,7 +1082,6 @@
+   set(ZMQ_LIB "${ZMQ_LIB};${SODIUM_LIBRARY}")
+ endif()
+-include(external/supercop/functions.cmake) # place after setting flags and before src directory inclusion
+ add_subdirectory(contrib)
+ add_subdirectory(src)
+
+diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
+index a8916a7d0..05ab35c82 100644
+--- a/external/CMakeLists.txt
++++ b/external/CMakeLists.txt
+@@ -37,21 +37,7 @@
+ find_package(Miniupnpc REQUIRED)
+-message(STATUS "Using in-tree miniupnpc")
+-set(UPNPC_NO_INSTALL TRUE CACHE BOOL "Disable miniupnp installation" FORCE)
+-add_subdirectory(miniupnp/miniupnpc)
+-set_property(TARGET libminiupnpc-static PROPERTY FOLDER "external")
+-set_property(TARGET libminiupnpc-static PROPERTY POSITION_INDEPENDENT_CODE ON)
+-if(MSVC)
+-  set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
+-elseif(NOT MSVC)
+-  set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-unused-result -Wno-unused-value")
+-endif()
+-if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
+-      set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -D_NETBSD_SOURCE")
+-endif()
+-
+-set(UPNP_LIBRARIES "libminiupnpc-static" PARENT_SCOPE)
++set(UPNP_LIBRARIES "miniupnpc" PARENT_SCOPE)
+ find_package(Unbound)
+@@ -83,4 +69,3 @@
+ add_subdirectory(db_drivers)
+ add_subdirectory(easylogging++)
+ add_subdirectory(qrcodegen)
+-add_subdirectory(randomx EXCLUDE_FROM_ALL)
+diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
+index 3b33fe90a..ba354a0e8 100644
+--- a/src/crypto/CMakeLists.txt
++++ b/src/crypto/CMakeLists.txt
+@@ -55,6 +55,7 @@ list(APPEND crypto_sources CryptonightR_template.S)
+ endif()
+ include_directories(${RANDOMX_INCLUDE})
++include_directories(SYSTEM /usr/include/monero)
+ set(crypto_headers)
+@@ -116,6 +117,3 @@ endif()
+ # cheat because cmake and ccache hate each other
+ set_property(SOURCE CryptonightR_template.S PROPERTY LANGUAGE C)
+-
+-# Must be done last, because it references libraries in this directory
+-add_subdirectory(wallet)
+diff --git a/src/crypto/wallet/crypto.h b/src/crypto/wallet/crypto.h
+index a4c5d5a07..5c6b96cd8 100644
+--- a/src/crypto/wallet/crypto.h
++++ b/src/crypto/wallet/crypto.h
+@@ -29,7 +29,6 @@
+ #pragma once
+ #include <cstddef>
+-#include "crypto/wallet/ops.h"
+ namespace crypto {
+   namespace wallet {
+diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt
+index ff2afba4b..26b0f4523 100644
+--- a/src/device/CMakeLists.txt
++++ b/src/device/CMakeLists.txt
+@@ -73,7 +73,7 @@
+     cncrypto
+     cryptonote_format_utils_basic
+     ringct_basic
+-    wallet-crypto
++    monero-crypto
+     ${OPENSSL_CRYPTO_LIBRARIES}
+     ${Boost_SERIALIZATION_LIBRARY}
+   PRIVATE
+diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
+index 65db2615c..3ace310f6 100644
+--- a/src/p2p/net_node.inl
++++ b/src/p2p/net_node.inl
+@@ -61,9 +61,9 @@
+ #include "cryptonote_core/cryptonote_core.h"
+ #include "net/parse.h"
+-#include <miniupnp/miniupnpc/miniupnpc.h>
+-#include <miniupnp/miniupnpc/upnpcommands.h>
+-#include <miniupnp/miniupnpc/upnperrors.h>
++#include <miniupnpc/miniupnpc.h>
++#include <miniupnpc/upnpcommands.h>
++#include <miniupnpc/upnperrors.h>
+ #undef MONERO_DEFAULT_LOG_CATEGORY
+ #define MONERO_DEFAULT_LOG_CATEGORY "net.p2p"
diff --git a/net-p2p/monero/files/monero-0.18.3.3-miniupnp-api-18.patch b/net-p2p/monero/files/monero-0.18.3.3-miniupnp-api-18.patch
new file mode 100644 (file)
index 0000000..d281f60
--- /dev/null
@@ -0,0 +1,30 @@
+diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl\r
+index 30e3d31b9..c49783e1c 100644\r
+--- a/src/p2p/net_node.inl\r
++++ b/src/p2p/net_node.inl\r
+@@ -2989,7 +2989,12 @@ namespace nodetool\r
+     UPNPUrls urls;\r
+     IGDdatas igdData;\r
+     char lanAddress[64];\r
++#if MINIUPNPC_API_VERSION > 17\r
++    char wanAddress[64];\r
++    result = UPNP_GetValidIGD(deviceList, &urls, &igdData, lanAddress, sizeof lanAddress, wanAddress, sizeof(wanAddress));\r
++#else\r
+     result = UPNP_GetValidIGD(deviceList, &urls, &igdData, lanAddress, sizeof lanAddress);\r
++#endif\r
+     freeUPNPDevlist(deviceList);\r
+     if (result > 0) {\r
+       if (result == 1) {\r
+@@ -3057,7 +3062,12 @@ namespace nodetool\r
+     UPNPUrls urls;\r
+     IGDdatas igdData;\r
+     char lanAddress[64];\r
++#if MINIUPNPC_API_VERSION > 17\r
++    char wanAddress[64];\r
++    result = UPNP_GetValidIGD(deviceList, &urls, &igdData, lanAddress, sizeof lanAddress, wanAddress, sizeof(wanAddress));\r
++#else\r
+     result = UPNP_GetValidIGD(deviceList, &urls, &igdData, lanAddress, sizeof lanAddress);\r
++#endif\r
+     freeUPNPDevlist(deviceList);\r
+     if (result > 0) {\r
+       if (result == 1) {\r
diff --git a/net-p2p/monero/files/monero-0.18.3.3-unbundle-dependencies.patch b/net-p2p/monero/files/monero-0.18.3.3-unbundle-dependencies.patch
new file mode 100644 (file)
index 0000000..6cd7e7c
--- /dev/null
@@ -0,0 +1,102 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -458,7 +458,7 @@
+ # elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*")
+ #   set(BSDI TRUE)
+-include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include)
++include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external )
+ if(APPLE)
+   cmake_policy(SET CMP0042 NEW)
+@@ -1201,7 +1201,6 @@
+   set(ZMQ_LIB "${ZMQ_LIB};${SODIUM_LIBRARY}")
+ endif()
+-include(external/supercop/functions.cmake) # place after setting flags and before src directory inclusion
+ add_subdirectory(contrib)
+ add_subdirectory(src)
+--- a/external/CMakeLists.txt
++++ b/external/CMakeLists.txt
+@@ -37,21 +37,7 @@
+ find_package(Miniupnpc REQUIRED)
+-message(STATUS "Using in-tree miniupnpc")
+-set(UPNPC_NO_INSTALL TRUE CACHE BOOL "Disable miniupnp installation" FORCE)
+-add_subdirectory(miniupnp/miniupnpc)
+-set_property(TARGET libminiupnpc-static PROPERTY FOLDER "external")
+-set_property(TARGET libminiupnpc-static PROPERTY POSITION_INDEPENDENT_CODE ON)
+-if(MSVC)
+-  set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
+-elseif(NOT MSVC)
+-  set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-unused-result -Wno-unused-value")
+-endif()
+-if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
+-      set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -D_NETBSD_SOURCE")
+-endif()
+-
+-set(UPNP_LIBRARIES "libminiupnpc-static" PARENT_SCOPE)
++set(UPNP_LIBRARIES "miniupnpc" PARENT_SCOPE)
+ find_package(Unbound)
+@@ -69,4 +55,3 @@
+ add_subdirectory(db_drivers)
+ add_subdirectory(easylogging++)
+ add_subdirectory(qrcodegen)
+-add_subdirectory(randomx EXCLUDE_FROM_ALL)
+--- a/src/crypto/CMakeLists.txt
++++ b/src/crypto/CMakeLists.txt
+@@ -55,6 +55,7 @@
+ endif()
+ include_directories(${RANDOMX_INCLUDE})
++include_directories(SYSTEM /usr/include/monero)
+ set(crypto_headers)
+@@ -97,6 +98,3 @@
+ # cheat because cmake and ccache hate each other
+ set_property(SOURCE CryptonightR_template.S PROPERTY LANGUAGE C)
+ set_property(SOURCE CryptonightR_template.S PROPERTY XCODE_EXPLICIT_FILE_TYPE sourcecode.asm)
+-
+-# Must be done last, because it references libraries in this directory
+-add_subdirectory(wallet)
+--- a/src/crypto/wallet/crypto.h
++++ b/src/crypto/wallet/crypto.h
+@@ -30,7 +30,6 @@
+ #pragma once
+ #include <cstddef>
+-#include "crypto/wallet/ops.h"
+ namespace crypto {
+   namespace wallet {
+--- a/src/device/CMakeLists.txt
++++ b/src/device/CMakeLists.txt
+@@ -73,7 +73,7 @@
+     cncrypto
+     cryptonote_format_utils_basic
+     ringct_basic
+-    wallet-crypto
++    monero-crypto
+     ${OPENSSL_CRYPTO_LIBRARIES}
+     ${Boost_SERIALIZATION_LIBRARY}
+   PRIVATE
+--- a/src/p2p/net_node.inl
++++ b/src/p2p/net_node.inl
+@@ -60,9 +60,9 @@
+ #include "cryptonote_core/cryptonote_core.h"
+ #include "net/parse.h"
+-#include <miniupnp/miniupnpc/miniupnpc.h>
+-#include <miniupnp/miniupnpc/upnpcommands.h>
+-#include <miniupnp/miniupnpc/upnperrors.h>
++#include <miniupnpc/miniupnpc.h>
++#include <miniupnpc/upnpcommands.h>
++#include <miniupnpc/upnperrors.h>
+ #undef MONERO_DEFAULT_LOG_CATEGORY
+ #define MONERO_DEFAULT_LOG_CATEGORY "net.p2p"
diff --git a/net-p2p/monero/files/monero-0.18.3.4-boost-1.85.patch b/net-p2p/monero/files/monero-0.18.3.4-boost-1.85.patch
new file mode 100644 (file)
index 0000000..1e4793b
--- /dev/null
@@ -0,0 +1,585 @@
+From 65568d3a884857ce08d1170f5801a6891a5c187c Mon Sep 17 00:00:00 2001
+From: jeffro256 <jeffro256@tutanota.com>
+Date: Fri, 23 Aug 2024 12:15:17 -0500
+Subject: [PATCH] build: fix build with Boost 1.85 and remove instances of
+ viewkey logging [RELEASE]
+
+1. Use std::is_standard_layout and std::is_trivially_copyable instead of std::is_pod for KV byte-wise serialization, which fixes compile issue for Boost UUIDs
+2. Removed reimplementation of std::hash for boost::uuids::uuid
+3. Removed << operator overload for crypto::secret_key
+4. Removed instances in code where private view key was dumped to the log in plaintext
+
+Release version of #9450, containing C++14 modified assertions
+---
+ CMakeLists.txt                                |  2 ++
+ .../serialization/keyvalue_serialization.h    | 18 ++++++++-------
+ contrib/epee/include/span.h                   | 23 +++++++++++--------
+ contrib/epee/include/string_tools.h           |  3 +++
+ src/crypto/crypto.h                           | 14 ++++++++---
+ .../cryptonote_format_utils.cpp               |  4 ++--
+ src/cryptonote_core/cryptonote_tx_utils.cpp   |  4 ++--
+ src/cryptonote_protocol/block_queue.cpp       | 13 ++---------
+ src/device/device_default.cpp                 |  8 ++++---
+ src/lmdb/util.h                               |  4 ++--
+ src/simplewallet/simplewallet.cpp             |  6 ++---
+ src/wallet/api/wallet.cpp                     |  8 +++----
+ src/wallet/wallet2.cpp                        | 18 +++++++--------
+ src/wallet/wallet_rpc_server.cpp              |  4 ++--
+ tests/benchmark.cpp                           |  2 +-
+ tests/core_tests/multisig.cpp                 | 10 ++++----
+ tests/functional_tests/make_test_signature.cc |  2 +-
+ tests/unit_tests/crypto.cpp                   |  2 +-
+ tests/unit_tests/multisig.cpp                 |  2 +-
+ tests/unit_tests/serialization.cpp            |  2 +-
+ 20 files changed, 80 insertions(+), 69 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 8fb03ba1ff..7b77c37393 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1077,6 +1077,8 @@ if(STATIC)
+ endif()
+ find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization program_options locale)
+ add_definitions(-DBOOST_ASIO_ENABLE_SEQUENTIAL_STRAND_ALLOCATION)
++add_definitions(-DBOOST_NO_AUTO_PTR)
++add_definitions(-DBOOST_UUID_DISABLE_ALIGNMENT) # This restores UUID's std::has_unique_object_representations property
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_LIB_SUFFIXES})
+ if(NOT Boost_FOUND)
+diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h
+index 06d74329f1..fbbddc7d2f 100644
+--- a/contrib/epee/include/serialization/keyvalue_serialization.h
++++ b/contrib/epee/include/serialization/keyvalue_serialization.h
+@@ -98,16 +98,18 @@ public: \
+ #define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name) \
+   epee::serialization::selector<is_store>::serialize_t_val_as_blob(this_ref.varialble, stg, hparent_section, val_name); 
+-#define KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, val_name) \
+-  static_assert(std::is_pod<decltype(this_ref.varialble)>::value, "t_type must be a POD type."); \
+-  KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name)
++#define KV_SERIALIZE_VAL_POD_AS_BLOB_N(variable, val_name) \
++  static_assert(std::is_trivially_copyable<decltype(this_ref.variable)>(), "t_type must be a trivially copyable type."); \
++  static_assert(std::is_standard_layout<decltype(this_ref.variable)>(), "t_type must be a standard layout type."); \
++  KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(variable, val_name)
+-#define KV_SERIALIZE_VAL_POD_AS_BLOB_OPT_N(varialble, val_name, default_value) \
++#define KV_SERIALIZE_VAL_POD_AS_BLOB_OPT_N(variable, val_name, default_value) \
+   do { \
+-    static_assert(std::is_pod<decltype(this_ref.varialble)>::value, "t_type must be a POD type."); \
+-    bool ret = KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name); \
++    static_assert(std::is_trivially_copyable<decltype(this_ref.variable)>(), "t_type must be a trivially copyable type."); \
++    static_assert(std::is_standard_layout<decltype(this_ref.variable)>(), "t_type must be a standard layout type."); \
++    bool ret = KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(variable, val_name) \
+     if (!ret) \
+-      epee::serialize_default(this_ref.varialble, default_value); \
++      epee::serialize_default(this_ref.variable, default_value); \
+   } while(0);
+ #define KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, val_name) \
+@@ -118,7 +120,7 @@ public: \
+ #define KV_SERIALIZE(varialble)                           KV_SERIALIZE_N(varialble, #varialble)
+ #define KV_SERIALIZE_VAL_POD_AS_BLOB(varialble)           KV_SERIALIZE_VAL_POD_AS_BLOB_N(varialble, #varialble)
+ #define KV_SERIALIZE_VAL_POD_AS_BLOB_OPT(varialble, def)  KV_SERIALIZE_VAL_POD_AS_BLOB_OPT_N(varialble, #varialble, def)
+-#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble)     KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_pod compile time check
++#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE(varialble)     KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, #varialble) //skip is_trivially_copyable and is_standard_layout compile time check
+ #define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble)     KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble)
+ #define KV_SERIALIZE_OPT(variable,default_value)          KV_SERIALIZE_OPT_N(variable, #variable, default_value)
+diff --git a/contrib/epee/include/span.h b/contrib/epee/include/span.h
+index 23bd51f8c2..01dc387d6d 100644
+--- a/contrib/epee/include/span.h
++++ b/contrib/epee/include/span.h
+@@ -133,17 +133,14 @@ namespace epee
+     return {src.data(), src.size()};
+   }
+-  template<typename T>
+-  constexpr bool has_padding() noexcept
+-  {
+-    return !std::is_standard_layout<T>() || alignof(T) != 1;
+-  }
+-
+   //! \return Cast data from `src` as `span<const std::uint8_t>`.
+   template<typename T>
+   span<const std::uint8_t> to_byte_span(const span<const T> src) noexcept
+   {
+-    static_assert(!has_padding<T>(), "source type may have padding");
++    static_assert(!std::is_empty<T>(), "empty value types will not work -> sizeof == 1");
++    static_assert(std::is_standard_layout<T>(), "type must have standard layout");
++    static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
++    static_assert(alignof(T) == 1, "type may have padding");
+     return {reinterpret_cast<const std::uint8_t*>(src.data()), src.size_bytes()}; 
+   }
+@@ -153,7 +150,9 @@ namespace epee
+   {
+     using value_type = typename T::value_type;
+     static_assert(!std::is_empty<value_type>(), "empty value types will not work -> sizeof == 1");
+-    static_assert(!has_padding<value_type>(), "source value type may have padding");
++    static_assert(std::is_standard_layout<value_type>(), "value type must have standard layout");
++    static_assert(std::is_trivially_copyable<value_type>(), "value type must be trivially copyable");
++    static_assert(alignof(value_type) == 1, "value type may have padding");
+     return {reinterpret_cast<std::uint8_t*>(src.data()), src.size() * sizeof(value_type)};
+   }
+@@ -162,7 +161,9 @@ namespace epee
+   span<const std::uint8_t> as_byte_span(const T& src) noexcept
+   {
+     static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
+-    static_assert(!has_padding<T>(), "source type may have padding");
++    static_assert(std::is_standard_layout<T>(), "type must have standard layout");
++    static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
++    static_assert(alignof(T) == 1, "type may have padding");
+     return {reinterpret_cast<const std::uint8_t*>(std::addressof(src)), sizeof(T)};
+   }
+@@ -171,7 +172,9 @@ namespace epee
+   span<std::uint8_t> as_mut_byte_span(T& src) noexcept
+   {
+     static_assert(!std::is_empty<T>(), "empty types will not work -> sizeof == 1");
+-    static_assert(!has_padding<T>(), "source type may have padding");
++    static_assert(std::is_standard_layout<T>(), "type must have standard layout");
++    static_assert(std::is_trivially_copyable<T>(), "type must be trivially copyable");
++    static_assert(alignof(T) == 1, "type may have padding");
+     return {reinterpret_cast<std::uint8_t*>(std::addressof(src)), sizeof(T)};
+   }
+diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/string_tools.h
+index 31c55b97ba..7de73cbf5a 100644
+--- a/contrib/epee/include/string_tools.h
++++ b/contrib/epee/include/string_tools.h
+@@ -91,6 +91,7 @@ namespace string_tools
+   std::string pod_to_hex(const t_pod_type& s)
+   {
+     static_assert(std::is_standard_layout<t_pod_type>(), "expected standard layout type");
++    static_assert(alignof(t_pod_type) == 1, "type may have padding");
+     return to_hex::string(as_byte_span(s));
+   }
+   //----------------------------------------------------------------------------
+@@ -98,6 +99,8 @@ namespace string_tools
+   bool hex_to_pod(const boost::string_ref hex_str, t_pod_type& s)
+   {
+     static_assert(std::is_standard_layout<t_pod_type>(), "expected standard layout type");
++    static_assert(alignof(t_pod_type) == 1, "type may have padding");
++    static_assert(std::is_trivially_copyable<t_pod_type>(), "type must be trivially copyable");
+     return from_hex::to_buffer(as_mut_byte_span(s), hex_str);
+   }
+   //----------------------------------------------------------------------------
+diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
+index d8cd6c6a01..ee1cac04a6 100644
+--- a/src/crypto/crypto.h
++++ b/src/crypto/crypto.h
+@@ -171,7 +171,9 @@ namespace crypto {
+   /* Generate a value filled with random bytes.
+    */
+   template<typename T>
+-  typename std::enable_if<std::is_pod<T>::value, T>::type rand() {
++  T rand() {
++    static_assert(std::is_standard_layout<T>(), "cannot write random bytes into non-standard layout type");
++    static_assert(std::is_trivially_copyable<T>(), "cannot write random bytes into non-trivially copyable type");
+     typename std::remove_cv<T>::type res;
+     generate_random_bytes_thread_safe(sizeof(T), (uint8_t*)&res);
+     return res;
+@@ -314,8 +316,14 @@ namespace crypto {
+   inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) {
+     epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
+   }
+-  inline std::ostream &operator <<(std::ostream &o, const crypto::secret_key &v) {
+-    epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
++  /* Do NOT overload the << operator for crypto::secret_key here. Use secret_key_explicit_print_ref
++   * instead to prevent accidental implicit dumping of secret key material to the logs (which has
++   * happened before). For the same reason, do not overload it for crypto::ec_scalar either since
++   * crypto::secret_key is a subclass. I'm not sorry that it's obtuse; that's the point, bozo.
++   */
++  struct secret_key_explicit_print_ref { const crypto::secret_key &sk; };
++  inline std::ostream &operator <<(std::ostream &o, const secret_key_explicit_print_ref v) {
++    epee::to_hex::formatted(o, epee::as_byte_span(unwrap(unwrap(v.sk)))); return o;
+   }
+   inline std::ostream &operator <<(std::ostream &o, const crypto::key_derivation &v) {
+     epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
+diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp
+index 8be23583b5..e6e424c719 100644
+--- a/src/cryptonote_basic/cryptonote_format_utils.cpp
++++ b/src/cryptonote_basic/cryptonote_format_utils.cpp
+@@ -292,7 +292,7 @@ namespace cryptonote
+     bool r = hwdev.generate_key_derivation(tx_public_key, ack.m_view_secret_key, recv_derivation);
+     if (!r)
+     {
+-      MWARNING("key image helper: failed to generate_key_derivation(" << tx_public_key << ", " << ack.m_view_secret_key << ")");
++      MWARNING("key image helper: failed to generate_key_derivation(" << tx_public_key << ", <viewkey>)");
+       memcpy(&recv_derivation, rct::identity().bytes, sizeof(recv_derivation));
+     }
+@@ -303,7 +303,7 @@ namespace cryptonote
+       r = hwdev.generate_key_derivation(additional_tx_public_keys[i], ack.m_view_secret_key, additional_recv_derivation);
+       if (!r)
+       {
+-        MWARNING("key image helper: failed to generate_key_derivation(" << additional_tx_public_keys[i] << ", " << ack.m_view_secret_key << ")");
++        MWARNING("key image helper: failed to generate_key_derivation(" << additional_tx_public_keys[i] << ", <viewkey>)");
+       }
+       else
+       {
+diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp
+index dc9d6612f6..8f044154b1 100644
+--- a/src/cryptonote_core/cryptonote_tx_utils.cpp
++++ b/src/cryptonote_core/cryptonote_tx_utils.cpp
+@@ -144,7 +144,7 @@ namespace cryptonote
+       crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);
+       crypto::public_key out_eph_public_key = AUTO_VAL_INIT(out_eph_public_key);
+       bool r = crypto::generate_key_derivation(miner_address.m_view_public_key, txkey.sec, derivation);
+-      CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to generate_key_derivation(" << miner_address.m_view_public_key << ", " << txkey.sec << ")");
++      CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to generate_key_derivation(" << miner_address.m_view_public_key << ", " << crypto::secret_key_explicit_print_ref{txkey.sec} << ")");
+       r = crypto::derive_public_key(derivation, no, miner_address.m_spend_public_key, out_eph_public_key);
+       CHECK_AND_ASSERT_MES(r, false, "while creating outs: failed to derive_public_key(" << derivation << ", " << no << ", "<< miner_address.m_spend_public_key << ")");
+@@ -484,7 +484,7 @@ namespace cryptonote
+           crypto::generate_ring_signature(tx_prefix_hash, boost::get<txin_to_key>(tx.vin[i]).k_image, keys_ptrs, in_contexts[i].in_ephemeral.sec, src_entr.real_output, sigs.data());
+         ss_ring_s << "signatures:" << ENDL;
+         std::for_each(sigs.begin(), sigs.end(), [&](const crypto::signature& s){ss_ring_s << s << ENDL;});
+-        ss_ring_s << "prefix_hash:" << tx_prefix_hash << ENDL << "in_ephemeral_key: " << in_contexts[i].in_ephemeral.sec << ENDL << "real_output: " << src_entr.real_output << ENDL;
++        ss_ring_s << "prefix_hash:" << tx_prefix_hash << ENDL << "in_ephemeral_key: " << crypto::secret_key_explicit_print_ref{in_contexts[i].in_ephemeral.sec} << ENDL << "real_output: " << src_entr.real_output << ENDL;
+         i++;
+       }
+diff --git a/src/cryptonote_protocol/block_queue.cpp b/src/cryptonote_protocol/block_queue.cpp
+index 4e65eafa4f..e5a4c0c99a 100644
+--- a/src/cryptonote_protocol/block_queue.cpp
++++ b/src/cryptonote_protocol/block_queue.cpp
+@@ -40,15 +40,6 @@
+ #undef MONERO_DEFAULT_LOG_CATEGORY
+ #define MONERO_DEFAULT_LOG_CATEGORY "cn.block_queue"
+-namespace std {
+-  static_assert(sizeof(size_t) <= sizeof(boost::uuids::uuid), "boost::uuids::uuid too small");
+-  template<> struct hash<boost::uuids::uuid> {
+-    std::size_t operator()(const boost::uuids::uuid &_v) const {
+-      return reinterpret_cast<const std::size_t &>(_v);
+-    }
+-  };
+-}
+-
+ namespace cryptonote
+ {
+@@ -472,7 +463,7 @@ bool block_queue::has_spans(const boost::uuids::uuid &connection_id) const
+ float block_queue::get_speed(const boost::uuids::uuid &connection_id) const
+ {
+   boost::unique_lock<boost::recursive_mutex> lock(mutex);
+-  std::unordered_map<boost::uuids::uuid, float> speeds;
++  std::unordered_map<boost::uuids::uuid, float, boost::hash<boost::uuids::uuid>> speeds;
+   for (const auto &span: blocks)
+   {
+     if (span.blocks.empty())
+@@ -480,7 +471,7 @@ float block_queue::get_speed(const boost::uuids::uuid &connection_id) const
+     // note that the average below does not average over the whole set, but over the
+     // previous pseudo average and the latest rate: this gives much more importance
+     // to the latest measurements, which is fine here
+-    std::unordered_map<boost::uuids::uuid, float>::iterator i = speeds.find(span.connection_id);
++    const auto i = speeds.find(span.connection_id);
+     if (i == speeds.end())
+       speeds.insert(std::make_pair(span.connection_id, span.rate));
+     else
+diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp
+index d70ece229c..c770a6e221 100644
+--- a/src/device/device_default.cpp
++++ b/src/device/device_default.cpp
+@@ -317,13 +317,15 @@ namespace hw {
+             {
+             // sending change to yourself; derivation = a*R
+                 r = generate_key_derivation(txkey_pub, sender_account_keys.m_view_secret_key, derivation);
+-                CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << txkey_pub << ", " << sender_account_keys.m_view_secret_key << ")");
++                CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << txkey_pub << ", <viewkey>)");
+             }
+             else
+             {
+             // sending to the recipient; derivation = r*A (or s*C in the subaddress scheme)
+-                r = generate_key_derivation(dst_entr.addr.m_view_public_key, dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key, derivation);
+-                CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << dst_entr.addr.m_view_public_key << ", " << (dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key) << ")");
++                const crypto::secret_key &tx_privkey{dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key};
++                r = generate_key_derivation(dst_entr.addr.m_view_public_key, tx_privkey, derivation);
++                CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation("
++                    << dst_entr.addr.m_view_public_key << ", " << crypto::secret_key_explicit_print_ref{tx_privkey} << ")");
+             }
+             if (need_additional_txkeys)
+diff --git a/src/lmdb/util.h b/src/lmdb/util.h
+index c6c75bc004..392ff20390 100644
+--- a/src/lmdb/util.h
++++ b/src/lmdb/util.h
+@@ -127,7 +127,7 @@ namespace lmdb
+     /*!
+         A LMDB comparison function that uses `std::memcmp`.
+-        \toaram T is `!epee::has_padding`
++        \toaram T has standard layout and an alignment of 1
+         \tparam offset to `T` within the value.
+         \return The result of `std::memcmp` over the value.
+@@ -135,7 +135,7 @@ namespace lmdb
+     template<typename T, std::size_t offset = 0>
+     inline int compare(MDB_val const* left, MDB_val const* right) noexcept
+     {
+-        static_assert(!epee::has_padding<T>(), "memcmp will not work");
++        static_assert(std::is_standard_layout<T>() && alignof(T) == 1, "memcmp will not work");
+         if (!left || !right || left->mv_size < sizeof(T) + offset || right->mv_size < sizeof(T) + offset)
+         {
+             assert("invalid use of custom comparison" == 0);
+diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
+index b9e30f9d94..011b1c7613 100644
+--- a/src/simplewallet/simplewallet.cpp
++++ b/src/simplewallet/simplewallet.cpp
+@@ -1979,7 +1979,7 @@ bool simple_wallet::rpc_payment_info(const std::vector<std::string> &args)
+     crypto::public_key pkey;
+     crypto::secret_key_to_public_key(m_wallet->get_rpc_client_secret_key(), pkey);
+     message_writer() << tr("RPC client ID: ") << pkey;
+-    message_writer() << tr("RPC client secret key: ") << m_wallet->get_rpc_client_secret_key();
++    message_writer() << tr("RPC client secret key: ") << crypto::secret_key_explicit_print_ref{m_wallet->get_rpc_client_secret_key()};
+     if (!m_wallet->get_rpc_payment_info(false, payment_required, credits, diff, credits_per_hash_found, hashing_blob, height, seed_height, seed_hash, next_seed_hash, cookie))
+     {
+       fail_msg_writer() << tr("Failed to query daemon");
+@@ -8026,9 +8026,9 @@ bool simple_wallet::submit_transfer(const std::vector<std::string> &args_)
+ std::string get_tx_key_stream(crypto::secret_key tx_key, std::vector<crypto::secret_key> additional_tx_keys)
+ {
+   ostringstream oss;
+-  oss << epee::string_tools::pod_to_hex(tx_key);
++  oss << epee::string_tools::pod_to_hex(unwrap(unwrap(tx_key)));
+   for (size_t i = 0; i < additional_tx_keys.size(); ++i)
+-    oss << epee::string_tools::pod_to_hex(additional_tx_keys[i]);
++    oss << epee::string_tools::pod_to_hex(unwrap(unwrap(additional_tx_keys[i])));
+   return oss.str();
+ }
+diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
+index fc4f891281..2ed14bfbd5 100644
+--- a/src/wallet/api/wallet.cpp
++++ b/src/wallet/api/wallet.cpp
+@@ -881,7 +881,7 @@ std::string WalletImpl::integratedAddress(const std::string &payment_id) const
+ std::string WalletImpl::secretViewKey() const
+ {
+-    return epee::string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key);
++    return epee::string_tools::pod_to_hex(unwrap(unwrap(m_wallet->get_account().get_keys().m_view_secret_key)));
+ }
+ std::string WalletImpl::publicViewKey() const
+@@ -891,7 +891,7 @@ std::string WalletImpl::publicViewKey() const
+ std::string WalletImpl::secretSpendKey() const
+ {
+-    return epee::string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_spend_secret_key);
++    return epee::string_tools::pod_to_hex(unwrap(unwrap(m_wallet->get_account().get_keys().m_spend_secret_key)));
+ }
+ std::string WalletImpl::publicSpendKey() const
+@@ -1878,9 +1878,9 @@ std::string WalletImpl::getTxKey(const std::string &txid_str) const
+         {
+             clearStatus();
+             std::ostringstream oss;
+-            oss << epee::string_tools::pod_to_hex(tx_key);
++            oss << epee::string_tools::pod_to_hex(unwrap(unwrap(tx_key)));
+             for (size_t i = 0; i < additional_tx_keys.size(); ++i)
+-                oss << epee::string_tools::pod_to_hex(additional_tx_keys[i]);
++                oss << epee::string_tools::pod_to_hex(unwrap(unwrap(additional_tx_keys[i])));
+             return oss.str();
+         }
+         else
+diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
+index ad8c361909..90b5731695 100644
+--- a/src/wallet/wallet2.cpp
++++ b/src/wallet/wallet2.cpp
+@@ -4613,7 +4613,7 @@ boost::optional<wallet2::keys_file_data> wallet2::get_keys_file_data(const epee:
+     original_address = get_account_address_as_str(m_nettype, false, m_original_address);
+     value.SetString(original_address.c_str(), original_address.length());
+     json.AddMember("original_address", value, json.GetAllocator());
+-    original_view_secret_key = epee::string_tools::pod_to_hex(m_original_view_secret_key);
++    original_view_secret_key = epee::string_tools::pod_to_hex(unwrap(unwrap(m_original_view_secret_key)));
+     value.SetString(original_view_secret_key.c_str(), original_view_secret_key.length());
+     json.AddMember("original_view_secret_key", value, json.GetAllocator());
+   }
+@@ -7077,7 +7077,7 @@ void wallet2::commit_tx(pending_tx& ptx)
+     cryptonote::COMMAND_RPC_SUBMIT_RAW_TX::request oreq;
+     cryptonote::COMMAND_RPC_SUBMIT_RAW_TX::response ores;
+     oreq.address = get_account().get_public_address_str(m_nettype);
+-    oreq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key);
++    oreq.view_key = string_tools::pod_to_hex(unwrap(unwrap(get_account().get_keys().m_view_secret_key)));
+     oreq.tx = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(ptx.tx));
+     {
+       const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex};
+@@ -10075,7 +10075,7 @@ bool wallet2::light_wallet_login(bool &new_address)
+   tools::COMMAND_RPC_LOGIN::request request;
+   tools::COMMAND_RPC_LOGIN::response response;
+   request.address = get_account().get_public_address_str(m_nettype);
+-  request.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key);
++  request.view_key = string_tools::pod_to_hex(unwrap(unwrap(get_account().get_keys().m_view_secret_key)));
+   // Always create account if it doesn't exist.
+   request.create_account = true;
+   m_daemon_rpc_mutex.lock();
+@@ -10102,7 +10102,7 @@ bool wallet2::light_wallet_import_wallet_request(tools::COMMAND_RPC_IMPORT_WALLE
+   MDEBUG("Light wallet import wallet request");
+   tools::COMMAND_RPC_IMPORT_WALLET_REQUEST::request oreq;
+   oreq.address = get_account().get_public_address_str(m_nettype);
+-  oreq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key);
++  oreq.view_key = string_tools::pod_to_hex(unwrap(unwrap(get_account().get_keys().m_view_secret_key)));
+   m_daemon_rpc_mutex.lock();
+   bool r = invoke_http_json("/import_wallet_request", oreq, response, rpc_timeout, "POST");
+   m_daemon_rpc_mutex.unlock();
+@@ -10121,7 +10121,7 @@ void wallet2::light_wallet_get_unspent_outs()
+   
+   oreq.amount = "0";
+   oreq.address = get_account().get_public_address_str(m_nettype);
+-  oreq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key);
++  oreq.view_key = string_tools::pod_to_hex(unwrap(unwrap(get_account().get_keys().m_view_secret_key)));
+   // openMonero specific
+   oreq.dust_threshold = boost::lexical_cast<std::string>(::config::DEFAULT_DUST_THRESHOLD);
+   // below are required by openMonero api - but are not used.
+@@ -10273,7 +10273,7 @@ bool wallet2::light_wallet_get_address_info(tools::COMMAND_RPC_GET_ADDRESS_INFO:
+   tools::COMMAND_RPC_GET_ADDRESS_INFO::request request;
+   
+   request.address = get_account().get_public_address_str(m_nettype);
+-  request.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key);
++  request.view_key = string_tools::pod_to_hex(unwrap(unwrap(get_account().get_keys().m_view_secret_key)));
+   m_daemon_rpc_mutex.lock();
+   bool r = invoke_http_json("/get_address_info", request, response, rpc_timeout, "POST");
+   m_daemon_rpc_mutex.unlock();
+@@ -10290,7 +10290,7 @@ void wallet2::light_wallet_get_address_txs()
+   tools::COMMAND_RPC_GET_ADDRESS_TXS::response ires;
+   
+   ireq.address = get_account().get_public_address_str(m_nettype);
+-  ireq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key);
++  ireq.view_key = string_tools::pod_to_hex(unwrap(unwrap(get_account().get_keys().m_view_secret_key)));
+   m_daemon_rpc_mutex.lock();
+   bool r = invoke_http_json("/get_address_txs", ireq, ires, rpc_timeout, "POST");
+   m_daemon_rpc_mutex.unlock();
+@@ -10520,7 +10520,7 @@ bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image,
+   const account_keys& ack = get_account().get_keys();
+   crypto::key_derivation derivation;
+   bool r = crypto::generate_key_derivation(tx_public_key, ack.m_view_secret_key, derivation);
+-  CHECK_AND_ASSERT_MES(r, false, "failed to generate_key_derivation(" << tx_public_key << ", " << ack.m_view_secret_key << ")");
++  CHECK_AND_ASSERT_MES(r, false, "failed to generate_key_derivation(" << tx_public_key << ", " << crypto::secret_key_explicit_print_ref{ack.m_view_secret_key} << ")");
+   r = crypto::derive_public_key(derivation, out_index, ack.m_account_address.m_spend_public_key, in_ephemeral.pub);
+   CHECK_AND_ASSERT_MES(r, false, "failed to derive_public_key (" << derivation << ", " << out_index << ", " << ack.m_account_address.m_spend_public_key << ")");
+@@ -10528,7 +10528,7 @@ bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image,
+   crypto::derive_secret_key(derivation, out_index, ack.m_spend_secret_key, in_ephemeral.sec);
+   crypto::public_key out_pkey_test;
+   r = crypto::secret_key_to_public_key(in_ephemeral.sec, out_pkey_test);
+-  CHECK_AND_ASSERT_MES(r, false, "failed to secret_key_to_public_key(" << in_ephemeral.sec << ")");
++  CHECK_AND_ASSERT_MES(r, false, "failed to secret_key_to_public_key(" << crypto::secret_key_explicit_print_ref{in_ephemeral.sec} << ")");
+   CHECK_AND_ASSERT_MES(in_ephemeral.pub == out_pkey_test, false, "derived secret key doesn't match derived public key");
+   crypto::generate_key_image(in_ephemeral.pub, in_ephemeral.sec, calculated_key_image);
+diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
+index b1419949f8..3c548de135 100644
+--- a/src/wallet/wallet_rpc_server.cpp
++++ b/src/wallet/wallet_rpc_server.cpp
+@@ -1247,9 +1247,9 @@ namespace tools
+       res.tx_hash_list.push_back(epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx.tx)));
+       if (req.get_tx_keys)
+       {
+-        res.tx_key_list.push_back(epee::string_tools::pod_to_hex(ptx.tx_key));
++        res.tx_key_list.push_back(epee::string_tools::pod_to_hex(unwrap(unwrap(ptx.tx_key))));
+         for (const crypto::secret_key& additional_tx_key : ptx.additional_tx_keys)
+-          res.tx_key_list.back() += epee::string_tools::pod_to_hex(additional_tx_key);
++          res.tx_key_list.back() += epee::string_tools::pod_to_hex(unwrap(unwrap(additional_tx_key)));
+       }
+     }
+diff --git a/tests/benchmark.cpp b/tests/benchmark.cpp
+index 6a845d61a4..660783dd91 100644
+--- a/tests/benchmark.cpp
++++ b/tests/benchmark.cpp
+@@ -109,7 +109,7 @@ namespace
+     template<typename T>
+     bool compare(const T& lhs, const T& rhs) noexcept
+     {
+-        static_assert(!epee::has_padding<T>(), "type might have padding");
++        static_assert(std::is_standard_layout<T>() && alignof(T) == 1, "type might have padding");
+         return std::memcmp(std::addressof(lhs), std::addressof(rhs), sizeof(T)) == 0;
+     }
+diff --git a/tests/core_tests/multisig.cpp b/tests/core_tests/multisig.cpp
+index 966c761163..1d3a6a3a10 100644
+--- a/tests/core_tests/multisig.cpp
++++ b/tests/core_tests/multisig.cpp
+@@ -227,13 +227,13 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
+         CHECK_AND_ASSERT_MES(r, false, "Failed to generate multisig export key image");
+       }
+       MDEBUG("Party " << msidx << ":");
+-      MDEBUG("spend: sec " << miner_account[msidx].get_keys().m_spend_secret_key << ", pub " << miner_account[msidx].get_keys().m_account_address.m_spend_public_key);
+-      MDEBUG("view: sec " << miner_account[msidx].get_keys().m_view_secret_key << ", pub " << miner_account[msidx].get_keys().m_account_address.m_view_public_key);
++      MDEBUG("spend: sec " << crypto::secret_key_explicit_print_ref{miner_account[msidx].get_keys().m_spend_secret_key} << ", pub " << miner_account[msidx].get_keys().m_account_address.m_spend_public_key);
++      MDEBUG("view: sec " << crypto::secret_key_explicit_print_ref{miner_account[msidx].get_keys().m_view_secret_key} << ", pub " << miner_account[msidx].get_keys().m_account_address.m_view_public_key);
+       for (const auto &k: miner_account[msidx].get_multisig_keys())
+-        MDEBUG("msk: " << k);
++        MDEBUG("msk: " << crypto::secret_key_explicit_print_ref{k});
+       for (size_t n = 0; n < account_k[msidx][tdidx].size(); ++n)
+       {
+-        MDEBUG("k: " << account_k[msidx][tdidx][n]);
++        MDEBUG("k: " << crypto::secret_key_explicit_print_ref{account_k[msidx][tdidx][n]});
+         MDEBUG("L: " << account_L[msidx][tdidx][n]);
+         MDEBUG("R: " << account_R[msidx][tdidx][n]);
+       }
+@@ -406,7 +406,7 @@ bool gen_multisig_tx_validation_base::generate_with(std::vector<test_event_entry
+       MDEBUG("signing with k " << k.back()[n]);
+     MDEBUG("signing with sk " << skey);
+     for (const auto &sk: used_keys)
+-      MDEBUG("  created with sk " << sk);
++      MDEBUG("  created with sk " << crypto::secret_key_explicit_print_ref{sk});
+     CHECK_AND_ASSERT_MES(signer_tx_builder.next_partial_sign(sig.total_alpha_G, sig.total_alpha_H, k, skey, sig.c_0, sig.s), false, "error: multisig::signing::tx_builder_ringct_t::next_partial_sign");
+     // in round-robin signing, the last signer finalizes the tx
+diff --git a/tests/functional_tests/make_test_signature.cc b/tests/functional_tests/make_test_signature.cc
+index e9dab8bd46..09a3f51c1a 100644
+--- a/tests/functional_tests/make_test_signature.cc
++++ b/tests/functional_tests/make_test_signature.cc
+@@ -48,7 +48,7 @@ int main(int argc, const char **argv)
+     crypto::public_key pkey;
+     crypto::random32_unbiased((unsigned char*)skey.data);
+     crypto::secret_key_to_public_key(skey, pkey);
+-    printf("%s %s\n", epee::string_tools::pod_to_hex(skey).c_str(), epee::string_tools::pod_to_hex(pkey).c_str());
++    printf("%s %s\n", epee::string_tools::pod_to_hex(unwrap(unwrap(skey))).c_str(), epee::string_tools::pod_to_hex(pkey).c_str());
+     return 0;
+   }
+diff --git a/tests/unit_tests/crypto.cpp b/tests/unit_tests/crypto.cpp
+index 7f926534a3..329992463c 100644
+--- a/tests/unit_tests/crypto.cpp
++++ b/tests/unit_tests/crypto.cpp
+@@ -72,10 +72,10 @@ TEST(Crypto, Ostream)
+   EXPECT_TRUE(is_formatted<crypto::hash8>());
+   EXPECT_TRUE(is_formatted<crypto::hash>());
+   EXPECT_TRUE(is_formatted<crypto::public_key>());
+-  EXPECT_TRUE(is_formatted<crypto::secret_key>());
+   EXPECT_TRUE(is_formatted<crypto::signature>());
+   EXPECT_TRUE(is_formatted<crypto::key_derivation>());
+   EXPECT_TRUE(is_formatted<crypto::key_image>());
++  EXPECT_TRUE(is_formatted<rct::key>());
+ }
+ TEST(Crypto, null_keys)
+diff --git a/tests/unit_tests/multisig.cpp b/tests/unit_tests/multisig.cpp
+index 3b3c4197c0..71416aaf33 100644
+--- a/tests/unit_tests/multisig.cpp
++++ b/tests/unit_tests/multisig.cpp
+@@ -80,7 +80,7 @@ static void make_wallet(unsigned int idx, tools::wallet2 &wallet)
+     wallet.generate("", "", spendkey, true, false);
+     ASSERT_TRUE(test_addresses[idx].address == wallet.get_account().get_public_address_str(cryptonote::TESTNET));
+     wallet.decrypt_keys("");
+-    ASSERT_TRUE(test_addresses[idx].spendkey == epee::string_tools::pod_to_hex(wallet.get_account().get_keys().m_spend_secret_key));
++    ASSERT_TRUE(test_addresses[idx].spendkey == epee::string_tools::pod_to_hex(unwrap(unwrap(wallet.get_account().get_keys().m_spend_secret_key))));
+     wallet.encrypt_keys("");
+   }
+   catch (const std::exception &e)
+diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp
+index 0fdd832856..fdf6032722 100644
+--- a/tests/unit_tests/serialization.cpp
++++ b/tests/unit_tests/serialization.cpp
+@@ -1103,7 +1103,7 @@ TEST(Serialization, portability_signed_tx)
+   ASSERT_TRUE(ptx.selected_transfers.front() == 2);
+   // ptx.{key_images, tx_key}
+   ASSERT_TRUE(ptx.key_images == "<6c3cd6af97c4070a7aef9b1344e7463e29c7cd245076fdb65da447a34da3ca76> ");
+-  ASSERT_TRUE(epee::string_tools::pod_to_hex(ptx.tx_key) == "0100000000000000000000000000000000000000000000000000000000000000");
++  ASSERT_TRUE(epee::string_tools::pod_to_hex(unwrap(unwrap(ptx.tx_key))) == "0100000000000000000000000000000000000000000000000000000000000000");
+   // ptx.dests
+   ASSERT_TRUE(ptx.dests.size() == 1);
+   ASSERT_TRUE(ptx.dests[0].amount == 1400000000000);
diff --git a/net-p2p/monero/files/monero-0.18.4.0-unbundle-dependencies.patch b/net-p2p/monero/files/monero-0.18.4.0-unbundle-dependencies.patch
new file mode 100644 (file)
index 0000000..744f2da
--- /dev/null
@@ -0,0 +1,103 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -458,7 +458,7 @@
+ # elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*")
+ #   set(BSDI TRUE)
+-include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include)
++include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external )
+ if(APPLE)
+   cmake_policy(SET CMP0042 NEW)
+@@ -1201,7 +1201,6 @@
+   set(ZMQ_LIB "${ZMQ_LIB};${SODIUM_LIBRARY}")
+ endif()
+-include(external/supercop/functions.cmake) # place after setting flags and before src directory inclusion
+ add_subdirectory(contrib)
+ add_subdirectory(src)
+--- a/external/CMakeLists.txt
++++ b/external/CMakeLists.txt
+@@ -37,22 +37,7 @@
+
+ find_package(Miniupnpc REQUIRED)
+
+-message(STATUS "Using in-tree miniupnpc")
+-set(UPNPC_NO_INSTALL TRUE CACHE BOOL "Disable miniupnp installation" FORCE)
+-set(UPNPC_BUILD_SHARED OFF CACHE BOOL "Disable building shared library" FORCE)
+-add_subdirectory(miniupnp/miniupnpc)
+-set_property(TARGET libminiupnpc-static PROPERTY FOLDER "external")
+-set_property(TARGET libminiupnpc-static PROPERTY POSITION_INDEPENDENT_CODE ON)
+-if(MSVC)
+-  set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
+-elseif(NOT MSVC)
+-  set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-unused-result -Wno-unused-value")
+-endif()
+-if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
+-      set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -D_NETBSD_SOURCE")
+-endif()
+-
+-set(UPNP_LIBRARIES "libminiupnpc-static" PARENT_SCOPE)
++set(UPNP_LIBRARIES "miniupnpc" PARENT_SCOPE)
+
+ find_package(Unbound)
+
+@@ -69,4 +55,3 @@
+ add_subdirectory(db_drivers)
+ add_subdirectory(easylogging++)
+ add_subdirectory(qrcodegen)
+-add_subdirectory(randomx EXCLUDE_FROM_ALL)
+--- a/src/crypto/CMakeLists.txt
++++ b/src/crypto/CMakeLists.txt
+@@ -55,6 +55,7 @@
+ endif()
+ include_directories(${RANDOMX_INCLUDE})
++include_directories(SYSTEM /usr/include/monero)
+ set(crypto_headers)
+@@ -97,6 +98,3 @@
+ # cheat because cmake and ccache hate each other
+ set_property(SOURCE CryptonightR_template.S PROPERTY LANGUAGE C)
+ set_property(SOURCE CryptonightR_template.S PROPERTY XCODE_EXPLICIT_FILE_TYPE sourcecode.asm)
+-
+-# Must be done last, because it references libraries in this directory
+-add_subdirectory(wallet)
+--- a/src/crypto/wallet/crypto.h
++++ b/src/crypto/wallet/crypto.h
+@@ -30,7 +30,6 @@
+ #pragma once
+ #include <cstddef>
+-#include "crypto/wallet/ops.h"
+ namespace crypto {
+   namespace wallet {
+--- a/src/device/CMakeLists.txt
++++ b/src/device/CMakeLists.txt
+@@ -73,7 +73,7 @@
+     cncrypto
+     cryptonote_format_utils_basic
+     ringct_basic
+-    wallet-crypto
++    monero-crypto
+     ${OPENSSL_CRYPTO_LIBRARIES}
+     ${Boost_SERIALIZATION_LIBRARY}
+   PRIVATE
+--- a/src/p2p/net_node.inl
++++ b/src/p2p/net_node.inl
+@@ -60,9 +60,9 @@
+ #include "cryptonote_core/cryptonote_core.h"
+ #include "net/parse.h"
+-#include <miniupnp/miniupnpc/miniupnpc.h>
+-#include <miniupnp/miniupnpc/upnpcommands.h>
+-#include <miniupnp/miniupnpc/upnperrors.h>
++#include <miniupnpc/miniupnpc.h>
++#include <miniupnpc/upnpcommands.h>
++#include <miniupnpc/upnperrors.h>
+ #undef MONERO_DEFAULT_LOG_CATEGORY
+ #define MONERO_DEFAULT_LOG_CATEGORY "net.p2p"
diff --git a/net-p2p/monero/files/monerod.conf b/net-p2p/monero/files/monerod.conf
new file mode 100644 (file)
index 0000000..a431e3a
--- /dev/null
@@ -0,0 +1,164 @@
+# Configuration for monerod
+# Syntax: any command line option may be specified as 'clioptionname=value'.
+#         Boolean options such as 'no-igd' are specified as 'no-igd=1'.
+# See 'monerod --help' for all available options.
+
+data-dir=/var/lib/monero
+#prune-blockchain=1
+
+## for p2pool
+zmq-pub=tcp://<private ip>:18083
+zmq-rpc-bind-ip=<private ip>
+
+## p2p settings
+p2p-bind-ip=0.0.0.0                             # Interface for p2p network protocol (IPv4)
+p2p-bind-port=18080                             # Port for p2p network protocol (IPv4)
+p2p-external-port=18080                         # External port for p2p network protocol (if port forwarding used with NAT)
+p2p-bind-ipv6-address=::                        # Interface for p2p network protocol (IPv6)
+p2p-bind-port-ipv6=18080                        # Port for p2p network protocol (IPv6)
+p2p-use-ipv6=1                                  # Enable IPv6 for p2p
+public-node=1                                   # Advertises the RPC-restricted port over p2p peer lists
+
+## rpc settings
+rpc-bind-ip=<private ip>                                          # Specify IP to bind RPC server
+rpc-bind-port=18081                                             # Port for RPC server               
+rpc-restricted-bind-ip=0.0.0.0                                  # Specify IP to bind restricted RPC server
+rpc-restricted-bind-port=18089                                  # Port for restricted RPC server
+rpc-bind-ipv6-address=<private/firewalled ipv6 addr>                   # Specify IPv6 address to bind RPC server
+rpc-restricted-bind-ipv6-address=::                             # Specify IPv6 address to bind restricted RPC server
+rpc-use-ipv6=1                                                  # Allow IPv6 for RPC
+confirm-external-bind=1                                         # Confirm rpc-bind-ip value when NOT a loopback IP
+
+## logging
+log-file=/dev/null                                                             # See /etc/conf.d/monerod for details
+#log-level=0,stacktrace:FATAL                    # Specify log level (& only log fatal stacktraces)
+max-log-file-size=104857600                     # Specify maximum log file size [B] (100M)
+max-log-files=5                                 # Specify maximum log file count
+
+## misc
+max-concurrency=2                               # Specify nproc threads for a parallel jobs
+prep-blocks-threads=2                           # Max number of threads to use preparing block hashes
+fast-block-sync=1                               # Sync up most of the way by using embedded, known block hashes.
+no-igd=1                                        # Disable UPnP port mapping
+
+## from the p2pool page
+add-priority-node=nodes.hashvault.pro:18080
+add-priority-node=p2pmd.xmrvsbeast.com:18080
+disable-dns-checkpoints=1
+enable-dns-blocklist=1
+out-peers=32
+in-peers=64
+
+limit-rate-up=4096                               # set limit-rate-up [kB/s]
+limit-rate-down=12288                            # set limit-rate-down [kB/s]
+
+
+
+#All Settings:
+#  --log-file arg                                               Specify log file
+#  --log-level arg                                              
+#  --max-log-file-size arg (=104850000)  Specify maximum log file size [B]
+#  --max-log-files arg (=50)             Specify maximum number of rotated log files to be saved (no limit by setting to 0)
+#  --max-concurrency arg (=0)            Max number of threads to use for a parallel job 
+#  --public-node                         Allow other users to use the node as a remote (restricted RPC mode, view-only commands) and advertise it over P2P
+#  --zmq-rpc-bind-ip arg (=127.0.0.1)    IP for ZMQ RPC server to listen on
+#  --zmq-rpc-bind-port arg                              Port for ZMQ RPC server to listen on
+#  --zmq-pub arg                         Address for ZMQ pub - tcp://ip:port or ipc://path
+#  --no-zmq                              Disable ZMQ RPC server
+#  --data-dir arg                                               Specify data directory
+#  --test-drop-download                  For net tests: in download, discard ALL blocks instead checking/saving them (very fast)
+#  --test-drop-download-height arg (=0)  Like test-drop-download but discards only after around certain height  
+#  --testnet                             Run on testnet. The wallet must be launched with --testnet flag.  
+#  --stagenet                            Run on stagenet. The wallet must be launched with --stagenet flag.
+#  --regtest                             Run in a regression testing mode.
+#  --keep-fakechain                      Don't delete any existing database when in fakechain mode.
+#  --fixed-difficulty arg (=0)           Fixed difficulty used for testing.
+#  --enforce-dns-checkpointing           checkpoints from DNS server will be enforced
+#  --prep-blocks-threads arg (=4)        Max number of threads to use when preparing block hashes in groups.
+#  --fast-block-sync arg (=1)            Sync up most of the way by using embedded, known block hashes.
+#  --show-time-stats arg (=0)            Show time-stats when processing blocks/txs and disk synchronization.   
+#  --block-sync-size arg (=0)            How many blocks to sync at once during chain synchronization (0 = adaptive).
+#  --check-updates arg (=notify)         Check for new versions of monero: [disabled|notify|download|update]
+#  --fluffy-blocks                       Relay blocks as fluffy blocks (obsolete, now default)
+#  --no-fluffy-blocks                    Relay blocks as normal blocks
+#  --test-dbg-lock-sleep arg (=0)        Sleep time in ms, defaults to 0 (off), used to debug before/after locking mutex. Values 100 to 1000 are good for tests.
+#  --offline                             Do not listen for peers, nor connect to any
+#  --disable-dns-checkpoints             Do not retrieve checkpoints from DNS 
+#  --block-download-max-size arg (=0)    Set maximum size of block download queue in bytes (0 for default)
+#  --sync-pruned-blocks                  Allow syncing from nodes with only pruned blocks
+#  --max-txpool-weight arg (=648000000)  Set maximum txpool weight in bytes.
+#  --block-notify arg                    Run a program for each new block, '%s' will be replaced by the block hash
+#  --prune-blockchain                    Prune blockchain
+#  --reorg-notify arg                    Run a program for each reorg, '%s' will be replaced by the split height, '%h' will be replaced by the new blockchain height, 
+#                                        '%n' will be replaced by the number of new blocks in the new chain, and '%d' will be replaced by the number of blocks discarded from the old chain
+#  --block-rate-notify arg               Run a program when the block rate undergoes large fluctuations. This might be a sign of large amounts of hash rate going on and off the Monero 
+#                                        network, and thus be of potential interest in predicting attacks. %t will be replaced by the number of minutes for the observation window, %b by the 
+#                                        number of blocks observed within that window, and %e by the number of blocks that was expected in that window. It is suggested that this notification is 
+#                                        used to automatically increase the number of confirmations required before a payment is acted upon.
+#  --keep-alt-blocks                     Keep alternative blocks on restart
+#  --extra-messages-file arg             Specify file for extra messages to include into coinbase transactions
+#  --start-mining arg                    Specify wallet address to mining for
+#  --mining-threads arg                  Specify mining threads count
+#  --bg-mining-enable                    enable background mining
+#  --bg-mining-ignore-battery            if true, assumes plugged in when unable to query system power status
+#  --bg-mining-min-idle-interval arg     Specify min lookback interval in seconds for determining idle state
+#  --bg-mining-idle-threshold arg        Specify minimum avg idle percentage over lookback interval
+#  --bg-mining-miner-target arg          Specify maximum percentage cpu use by miner(s)
+#  --db-sync-mode arg                                   Specify sync option, using format [safe|fast|fastest]:[sync|async]:[<nblocks_per_sync>[blocks]|<nbytes_per_sync>[bytes]].
+#  --db-salvage                          Try to salvage a blockchain database if it seems corrupted
+#  --p2p-bind-ip arg (=0.0.0.0)          Interface for p2p network protocol (IPv4)
+#  --p2p-bind-ipv6-address arg (=::)     Interface for p2p network protocol (IPv6)
+#  --p2p-bind-port arg                          Port for p2p network protocol (IPv4)
+#  --p2p-bind-port-ipv6 arg                     Port for p2p network protocol (IPv6)
+#  --p2p-use-ipv6                        Enable IPv6 for p2p
+#  --p2p-ignore-ipv4                     Ignore unsuccessful IPv4 bind for p2p
+#  --p2p-external-port arg (=0)          External port for p2p network protocol (if port forwarding used with NAT)
+#  --allow-local-ip                      Allow local ip add to peer list, mostly in debug purposes
+#  --add-peer arg                        Manually add peer to local peerlist
+#  --add-priority-node arg               Specify list of peers to connect to and attempt to keep the connection open
+#  --add-exclusive-node arg              Specify list of peers to connect to only. If this option is given the options add-priority-node and seed-node are ignored
+#  --seed-node arg                       Connect to a node to retrieve peer addresses, and disconnect
+#  --tx-proxy arg                        Send local txes through proxy: <network-type>,<socks-ip:port>[,max_connections][,disable_noise] i.e. "tor,127.0.0.1:9050,100,disable_noise"
+#  --anonymous-inbound arg               <hidden-service-address>,<[bind-ip:]port>[,max_connections] i.e. "x.onion,127.0.0.1:18083,100"
+#  --ban-list arg                        Specify ban list file, one IP address per line
+#  --hide-my-port                        Do not announce yourself as peerlist candidate
+#  --no-sync                             Don't synchronize the blockchain with other peers
+#  --enable-dns-blocklist                Apply realtime blocklist from DNS
+#  --no-igd                              Disable UPnP port mapping
+#  --igd arg (=delayed)                  UPnP port mapping (disabled, enabled, delayed)
+#  --out-peers arg (=-1)                 set max number of out peers
+#  --in-peers arg (=-1)                  set max number of in peers
+#  --tos-flag arg (=-1)                  set TOS flag
+#  --limit-rate-up arg (=2048)           set limit-rate-up [kB/s]
+#  --limit-rate-down arg (=8192)         set limit-rate-down [kB/s]
+#  --limit-rate arg (=-1)                set limit-rate [kB/s]
+#  --pad-transactions                    Pad relayed transactions to help defend against traffic volume analysis
+#  --rpc-bind-port arg                                          Port for RPC server
+#  --rpc-restricted-bind-port arg        Port for restricted RPC server
+#  --restricted-rpc                      Restrict RPC to view only commands and do not return privacy sensitive data in RPC calls
+#  --bootstrap-daemon-address arg        URL of a 'bootstrap' remote daemon that the connected wallets can use while this daemon is still not fully synced.
+#                                        Use 'auto' to enable automatic public nodes discovering and bootstrap daemon switching
+#  --bootstrap-daemon-login arg          Specify username:password for the bootstrap daemon login
+#  --rpc-bind-ip arg (=127.0.0.1)        Specify IP to bind RPC server
+#  --rpc-bind-ipv6-address arg (=::1)    Specify IPv6 address to bind RPC server
+#  --rpc-restricted-bind-ip arg                 Specify IP to bind restricted RPC server
+#  --rpc-restricted-bind-ipv6-address    Specify IPv6 address to bind restricted RPC server
+#  --rpc-use-ipv6                        Allow IPv6 for RPC
+#  --rpc-ignore-ipv4                     Ignore unsuccessful IPv4 bind for RPC
+#  --rpc-login arg                       Specify username[:password] required for RPC server
+#  --confirm-external-bind               Confirm rpc-bind-ip value is NOT a loopback (local) IP
+#  --rpc-access-control-origins arg      Specify a comma separated list of origins to allow cross origin resource sharing
+#  --rpc-ssl arg (=autodetect)           Enable SSL on RPC connections: enabled|disabled|autodetect
+#  --rpc-ssl-private-key arg             Path to a PEM format private key
+#  --rpc-ssl-certificate arg             Path to a PEM format certificate
+#  --rpc-ssl-ca-certificates arg         Path to file containing concatenated PEM format certificate(s) to replace system CA(s).
+#  --rpc-ssl-allowed-fingerprints arg    List of certificate fingerprints to allow
+#  --rpc-ssl-allow-chained               Allow user (via --rpc-ssl-certificates) chain certificates
+#  --disable-rpc-ban                     Do not ban hosts on RPC errors
+#  --rpc-ssl-allow-any-cert              Allow any peer certificate
+#  --rpc-payment-address arg             Restrict RPC to clients sending micropayment to this address
+#  --rpc-payment-difficulty arg (=1000)  Restrict RPC to clients sending micropayment at this difficulty
+#  --rpc-payment-credits arg (=100)      Restrict RPC to clients sending micropayment, yields that many credits per payment
+#  --rpc-payment-allow-free-loopback     Allow free access from the loopback address (ie, the local host)
+
+
diff --git a/net-p2p/monero/files/monerod.confd b/net-p2p/monero/files/monerod.confd
new file mode 100644 (file)
index 0000000..ba747c7
--- /dev/null
@@ -0,0 +1,12 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+
+MONEROD_CONFIG="/etc/monero/monerod.conf"
+monerod_args="--config-file ${MONEROD_CONFIG} --non-interactive"
+monerod_user=monero
+monerod_group=monero
+
+## We can use the coloured output from monerod to populate monerod.log and monerod_err.log instead of the default logfile as specified in /etc/monero/monerod.conf
+output_log="/var/log/monero/monerod.log"
+error_log="/var/log/monero/monerod_err.log"
diff --git a/net-p2p/monero/files/monerod.initd b/net-p2p/monero/files/monerod.initd
new file mode 100644 (file)
index 0000000..ce7796d
--- /dev/null
@@ -0,0 +1,40 @@
+#!/sbin/openrc-run
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+pidfile=/var/run/monerod.pid
+command=/usr/bin/monerod
+command_args="${monerod_args}"
+supervisor=supervise-daemon
+command_user="${monerod_user}:${monerod_group}"
+respawn_max="3"
+respawn_period="40"
+
+name="Monero P2P Daemon"
+description="Connects to the Monero P2P network"
+
+depend() {
+    need localmount
+    need net
+}
+
+start_pre() {
+       #set the defaults
+    data_dir="/var/lib/monero"
+    log_file="/var/log/monero/monero.log"
+       #attempt to update defaults from $MONEROD_CONFIG
+    grep -q "^data-dir=" "${MONEROD_CONFIG}" && data_dir=$(awk '/^data-dir=/{print$1}' "${MONEROD_CONFIG}"|sed 's/data-dir=//')
+    grep -q "^log-file=" "${MONEROD_CONFIG}" && log_file=$(awk '/^log-file=/{print$1}' "${MONEROD_CONFIG}"|sed 's/log-file=//')
+    checkpath -o ${monerod_user}:${monerod_group} -d ${data_dir}
+
+       if [ -c "${log_file}" ] ;then
+               checkpath -d $(dirname "${output_log}")
+               checkpath -d $(dirname "${error_log}")
+               checkpath -o ${monerod_user}:${monerod_group} -f "${output_log}"
+               checkpath -o ${monerod_user}:${monerod_group} -f "${error_log}"
+       else
+               checkpath -d $(dirname "${log_file}")
+       checkpath -o ${monerod_user}:${monerod_group} -f "${log_file}"
+       fi
+
+}
diff --git a/net-p2p/monero/files/monerod.service b/net-p2p/monero/files/monerod.service
new file mode 100644 (file)
index 0000000..3275604
--- /dev/null
@@ -0,0 +1,17 @@
+[Unit]
+Description=Monero P2P Daemon
+After=network.target
+
+[Service]
+User=monero
+Group=monero
+StateDirectory=monero
+LogsDirectory=monero
+Type=simple
+ExecStart=/usr/bin/monerod --config-file /etc/monero/monerod.conf --non-interactive
+Restart=on-failure
+StandardOutput=null
+StandardError=null
+
+[Install]
+WantedBy=multi-user.target
diff --git a/net-p2p/monero/metadata.xml b/net-p2p/monero/metadata.xml
new file mode 100644 (file)
index 0000000..29d5abe
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+  <maintainer type="person">
+    <email>efe.izbudak@metu.edu.tr</email>
+    <name>Efe İzbudak</name>
+  </maintainer>
+  <longdescription lang="en">
+    Monero is a private, secure, untraceable, decentralised digital
+    currency. You are your bank, you control your funds, and nobody
+    can trace your transfers unless you allow them to do so.
+  </longdescription>
+  <use>
+    <flag name="daemon">
+      Build the Monero daemon used to connect to the P2P network.
+    </flag>
+    <flag name="hw-wallet">
+      Enable Trezor hardware wallet support.
+    </flag>
+    <flag name="tools">
+      Build tools used to manipulate the blockchain as it is stored on
+      disk.
+    </flag>
+    <flag name="wallet-cli">
+      Build the command line wallet, monero-wallet-cli.
+    </flag>
+    <flag name="wallet-rpc">
+      Build the RPC wallet, monero-wallet-rpc.
+    </flag>
+  </use>
+  <upstream>
+    <remote-id type="github">monero-project/monero</remote-id>
+  </upstream>
+</pkgmetadata>
diff --git a/net-p2p/monero/monero-0.18.3.4-r1.ebuild b/net-p2p/monero/monero-0.18.3.4-r1.ebuild
new file mode 100644 (file)
index 0000000..5092a81
--- /dev/null
@@ -0,0 +1,127 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit cmake systemd
+
+DESCRIPTION="The secure, private, untraceable cryptocurrency"
+HOMEPAGE="https://github.com/monero-project/monero"
+
+if [[ ${PV} == 9999 ]]; then
+       inherit git-r3
+       EGIT_REPO_URI="https://github.com/monero-project/monero.git"
+       EGIT_SUBMODULES=()
+else
+       SRC_URI="https://github.com/monero-project/monero/archive/v${PV}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="amd64 ~arm64 ~x86"
+fi
+
+LICENSE="BSD MIT"
+SLOT="0"
+IUSE="+daemon hw-wallet readline +tools +wallet-cli +wallet-rpc"
+REQUIRED_USE="|| ( daemon tools wallet-cli wallet-rpc )"
+RESTRICT="test"
+
+DEPEND="
+       acct-group/monero
+       acct-user/monero
+       <dev-libs/boost-1.87:=[nls]
+       dev-libs/libsodium:=
+       dev-libs/openssl:=
+       dev-libs/randomx
+       dev-libs/rapidjson
+       dev-libs/supercop
+       net-dns/unbound:=[threads]
+       net-libs/czmq:=
+       net-libs/miniupnpc:=
+       readline? ( sys-libs/readline:0= )
+       hw-wallet? (
+               dev-libs/hidapi
+               dev-libs/protobuf:=
+               virtual/libusb:1
+       )
+"
+RDEPEND="${DEPEND}"
+BDEPEND="virtual/pkgconfig"
+
+PATCHES=(
+       "${FILESDIR}/${PN}-0.18.3.3-unbundle-dependencies.patch"
+       "${FILESDIR}/${PN}-0.18.3.3-miniupnp-api-18.patch"
+       "${FILESDIR}/${PN}-0.18.3.4-boost-1.85.patch"
+)
+
+src_configure() {
+       local mycmakeargs=(
+               # TODO: Update CMake to install built libraries (help wanted)
+               -DBUILD_SHARED_LIBS=OFF
+               -DMANUAL_SUBMODULES=ON
+               -DUSE_DEVICE_TREZOR=$(usex hw-wallet ON OFF)
+       )
+
+       use elibc_musl && mycmakeargs+=( -DSTACK_TRACE=OFF )
+
+       cmake_src_configure
+}
+
+src_compile() {
+       local targets=()
+       use daemon && targets+=(daemon)
+       use tools && targets+=(blockchain_{ancestry,blackball,db,depth,export,import,prune,prune_known_spent_data,stats,usage})
+       use wallet-cli && targets+=(simplewallet)
+       use wallet-rpc && targets+=(wallet_rpc_server)
+       cmake_build ${targets[@]}
+}
+
+src_install() {
+       einstalldocs
+
+       # Install all binaries.
+       find "${BUILD_DIR}/bin/" -type f -executable -print0 |
+               while IFS= read -r -d '' line; do
+                       dobin "$line"
+               done
+
+       if use daemon; then
+               dodoc utils/conf/monerod.conf
+
+               # data-dir
+               keepdir /var/lib/monero
+               fowners monero:monero /var/lib/monero
+               fperms 0755 /var/lib/monero
+
+               # log-file dir
+               keepdir /var/log/monero
+               fowners monero:monero /var/log/monero
+               fperms 0755 /var/log/monero
+
+               # /etc/monero/monerod.conf
+               insinto /etc/monero
+               doins "${FILESDIR}/monerod.conf"
+
+               # OpenRC
+               newconfd "${FILESDIR}/monerod.confd" monerod
+               newinitd "${FILESDIR}/monerod.initd" monerod
+
+               # Logrotate
+               newins "${FILESDIR}/logrotated" "${PN}"
+
+               # systemd
+               systemd_dounit "${FILESDIR}/monerod.service"
+       fi
+}
+
+pkg_postinst() {
+       if use daemon; then
+               elog "Start the Monero P2P daemon as a system service with"
+               elog "'rc-service monerod start'. Enable it at startup with"
+               elog "'rc-update add monerod default'."
+               elog
+               elog "Run monerod status as any user to get sync status and other stats."
+               elog
+               elog "The Monero blockchain can take up a lot of space (200 GiB) and is stored"
+               elog "in /var/lib/monero by default. You may want to enable pruning by adding"
+               elog "'prune-blockchain=1' to /etc/monero/monerod.conf to prune the blockchain"
+               elog "or move the data directory to another disk."
+       fi
+}
diff --git a/net-p2p/monero/monero-0.18.3.4-r2.ebuild b/net-p2p/monero/monero-0.18.3.4-r2.ebuild
new file mode 100644 (file)
index 0000000..20f8df0
--- /dev/null
@@ -0,0 +1,128 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit cmake systemd
+
+DESCRIPTION="The secure, private, untraceable cryptocurrency"
+HOMEPAGE="https://github.com/monero-project/monero"
+
+if [[ ${PV} == 9999 ]]; then
+       inherit git-r3
+       EGIT_REPO_URI="https://github.com/monero-project/monero.git"
+       EGIT_SUBMODULES=()
+else
+       SRC_URI="https://github.com/monero-project/monero/archive/v${PV}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="amd64 ~arm64 ~x86"
+fi
+
+LICENSE="BSD MIT"
+SLOT="0"
+IUSE="+daemon hw-wallet readline +tools +wallet-cli +wallet-rpc"
+REQUIRED_USE="|| ( daemon tools wallet-cli wallet-rpc )"
+RESTRICT="test"
+
+DEPEND="
+       acct-group/monero
+       acct-user/monero
+       <dev-libs/boost-1.87:=[nls]
+       dev-libs/libsodium:=
+       dev-libs/openssl:=
+       dev-libs/randomx
+       dev-libs/rapidjson
+       dev-libs/supercop
+       net-dns/unbound:=[threads]
+       net-libs/czmq:=
+       net-libs/miniupnpc:=
+       readline? ( sys-libs/readline:0= )
+       hw-wallet? (
+               dev-libs/hidapi
+               dev-libs/protobuf:=
+               virtual/libusb:1
+       )
+"
+RDEPEND="${DEPEND}"
+BDEPEND="virtual/pkgconfig"
+
+PATCHES=(
+       "${FILESDIR}/${PN}-0.18.3.3-unbundle-dependencies.patch"
+       "${FILESDIR}/${PN}-0.18.3.3-miniupnp-api-18.patch"
+       "${FILESDIR}/${PN}-0.18.3.4-boost-1.85.patch"
+)
+
+src_configure() {
+       local mycmakeargs=(
+               # TODO: Update CMake to install built libraries (help wanted)
+               -DBUILD_SHARED_LIBS=OFF
+               -DMANUAL_SUBMODULES=ON
+               -DUSE_DEVICE_TREZOR=$(usex hw-wallet ON OFF)
+       )
+
+       use elibc_musl && mycmakeargs+=( -DSTACK_TRACE=OFF )
+
+       cmake_src_configure
+}
+
+src_compile() {
+       local targets=()
+       use daemon && targets+=(daemon)
+       use tools && targets+=(blockchain_{ancestry,blackball,db,depth,export,import,prune,prune_known_spent_data,stats,usage})
+       use wallet-cli && targets+=(simplewallet)
+       use wallet-rpc && targets+=(wallet_rpc_server)
+       cmake_build ${targets[@]}
+}
+
+src_install() {
+       einstalldocs
+
+       # Install all binaries.
+       find "${BUILD_DIR}/bin/" -type f -executable -print0 |
+               while IFS= read -r -d '' line; do
+                       dobin "$line"
+               done
+
+       if use daemon; then
+               dodoc utils/conf/monerod.conf
+
+               # data-dir
+               keepdir /var/lib/monero
+               fowners monero:monero /var/lib/monero
+               fperms 0755 /var/lib/monero
+
+               # log-file dir
+               keepdir /var/log/monero
+               fowners monero:monero /var/log/monero
+               fperms 0755 /var/log/monero
+
+               # /etc/monero/monerod.conf
+               insinto /etc/monero
+               doins "${FILESDIR}/monerod.conf"
+
+               # OpenRC
+               newconfd "${FILESDIR}/monerod.confd" monerod
+               newinitd "${FILESDIR}/monerod.initd" monerod
+
+               # Logrotate
+               insinto /etc/logrotate.d
+               newins "${FILESDIR}/logrotated" "${PN}"
+
+               # systemd
+               systemd_dounit "${FILESDIR}/monerod.service"
+       fi
+}
+
+pkg_postinst() {
+       if use daemon; then
+               elog "Start the Monero P2P daemon as a system service with"
+               elog "'rc-service monerod start'. Enable it at startup with"
+               elog "'rc-update add monerod default'."
+               elog
+               elog "Run monerod status as any user to get sync status and other stats."
+               elog
+               elog "The Monero blockchain can take up a lot of space (200 GiB) and is stored"
+               elog "in /var/lib/monero by default. You may want to enable pruning by adding"
+               elog "'prune-blockchain=1' to /etc/monero/monerod.conf to prune the blockchain"
+               elog "or move the data directory to another disk."
+       fi
+}
diff --git a/net-p2p/monero/monero-0.18.4.0-r1.ebuild b/net-p2p/monero/monero-0.18.4.0-r1.ebuild
new file mode 100644 (file)
index 0000000..569d9cc
--- /dev/null
@@ -0,0 +1,127 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit cmake systemd
+
+DESCRIPTION="The secure, private, untraceable cryptocurrency"
+HOMEPAGE="https://github.com/monero-project/monero"
+
+if [[ ${PV} == 9999 ]]; then
+       inherit git-r3
+       EGIT_REPO_URI="https://github.com/monero-project/monero.git"
+       EGIT_SUBMODULES=()
+else
+       SRC_URI="https://github.com/monero-project/monero/archive/v${PV}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="amd64 ~arm64 ~x86"
+fi
+
+LICENSE="BSD MIT"
+SLOT="0"
+IUSE="+daemon hw-wallet readline +tools +wallet-cli +wallet-rpc"
+REQUIRED_USE="|| ( daemon tools wallet-cli wallet-rpc )"
+RESTRICT="test"
+
+DEPEND="
+       acct-group/monero
+       acct-user/monero
+       dev-libs/boost:=[nls]
+       dev-libs/libsodium:=
+       dev-libs/openssl:=
+       dev-libs/randomx
+       dev-libs/rapidjson
+       dev-libs/supercop
+       net-dns/unbound:=[threads]
+       net-libs/czmq:=
+       net-libs/miniupnpc:=
+       readline? ( sys-libs/readline:0= )
+       hw-wallet? (
+               dev-libs/hidapi
+               dev-libs/protobuf:=
+               virtual/libusb:1
+       )
+"
+RDEPEND="${DEPEND}"
+BDEPEND="virtual/pkgconfig"
+
+PATCHES=(
+       "${FILESDIR}/${PN}-0.18.4.0-unbundle-dependencies.patch"
+       "${FILESDIR}/${PN}-0.18.3.3-miniupnp-api-18.patch"
+)
+
+src_configure() {
+       local mycmakeargs=(
+               # TODO: Update CMake to install built libraries (help wanted)
+               -DBUILD_SHARED_LIBS=OFF
+               -DMANUAL_SUBMODULES=ON
+               -DUSE_DEVICE_TREZOR=$(usex hw-wallet ON OFF)
+       )
+
+       use elibc_musl && mycmakeargs+=( -DSTACK_TRACE=OFF )
+
+       cmake_src_configure
+}
+
+src_compile() {
+       local targets=()
+       use daemon && targets+=(daemon)
+       use tools && targets+=(blockchain_{ancestry,blackball,db,depth,export,import,prune,prune_known_spent_data,stats,usage})
+       use wallet-cli && targets+=(simplewallet)
+       use wallet-rpc && targets+=(wallet_rpc_server)
+       cmake_build ${targets[@]}
+}
+
+src_install() {
+       einstalldocs
+
+       # Install all binaries.
+       find "${BUILD_DIR}/bin/" -type f -executable -print0 |
+               while IFS= read -r -d '' line; do
+                       dobin "$line"
+               done
+
+       if use daemon; then
+               dodoc utils/conf/monerod.conf
+
+               # data-dir
+               keepdir /var/lib/monero
+               fowners monero:monero /var/lib/monero
+               fperms 0755 /var/lib/monero
+
+               # log-file dir
+               keepdir /var/log/monero
+               fowners monero:monero /var/log/monero
+               fperms 0755 /var/log/monero
+
+               # /etc/monero/monerod.conf
+               insinto /etc/monero
+               doins "${FILESDIR}/monerod.conf"
+
+               # OpenRC
+               newconfd "${FILESDIR}/monerod.confd" monerod
+               newinitd "${FILESDIR}/monerod.initd" monerod
+
+               # Logrotate
+               insinto /etc/logrotate.d
+               newins "${FILESDIR}/logrotated" "${PN}"
+
+               # systemd
+               systemd_dounit "${FILESDIR}/monerod.service"
+       fi
+}
+
+pkg_postinst() {
+       if use daemon; then
+               elog "Start the Monero P2P daemon as a system service with"
+               elog "'rc-service monerod start'. Enable it at startup with"
+               elog "'rc-update add monerod default'."
+               elog
+               elog "Run monerod status as any user to get sync status and other stats."
+               elog
+               elog "The Monero blockchain can take up a lot of space (250 GiB) and is stored"
+               elog "in /var/lib/monero by default. You may want to enable pruning by adding"
+               elog "'prune-blockchain=1' to /etc/monero/monerod.conf to prune the blockchain"
+               elog "or move the data directory to another disk."
+       fi
+}
diff --git a/net-p2p/p2pool/Manifest b/net-p2p/p2pool/Manifest
new file mode 100644 (file)
index 0000000..33dc0c2
--- /dev/null
@@ -0,0 +1,13 @@
+AUX SChernykh.asc 3139 BLAKE2B 97d27eea4ae8a7822acbf0b5c1470dc711d66c461a35b4d6ea7737cb173d706466e75262c97581222bbb218838070f048840274dd4dfdb400b64a7be45429855 SHA512 d7674c286dd628e0f4a3146cd2b16dab690752db89713630dd1be43febca159be18623b25cdef15273de4c8c0eb16b289203c0130ef7ac03f0371b3767bcd121
+AUX flags.cmake 1289 BLAKE2B 6ca1cf99b270d2284c46c619339b34675741d0d5ad9a5429030f67d5de22532809650ef620aa18a0840a849608e437244138b0e67bf0e6ebea0b82daf15100e2 SHA512 0c8aec7e861cbf0a6f32a3fb50ccc32aa560f54bb56df0a64f2bacb2db183765a71a4984f60188007a208c94cff4fdf6497761a2b37f063836e5d4fb122b96c6
+AUX logrotated 657 BLAKE2B f20f0a0c21406fccd47fbc6f9cc0a0c638e613e371e46b9ac695ee3a5c273eaed0d042c5b1d01d13480ecc566bb86a1a5d46f84530bca5a43823fd94d7429ebd SHA512 d63c0c7ca6512c3746ad231f7a4f2ae2e33f7e32bf58170d975694fade36a2b32217c64bae4d3ac437322ded715dcb2abfeb7e8246957109188346f644de4c84
+AUX p2pool.confd 4088 BLAKE2B fa81de21e328bbaa4f4ba7dc1fbbca2ffe070049099992c493cac4c6f8e28547416843c338c1388caae9d23376f50ca109d88e69e707fe7fe74976d855d66f66 SHA512 82b1bea3aa588b0344d177be970814ba7e849523d62189ceeec6d76a07b581405b3f4f2c58007872712335caeb51feaed15ceb4a98dd8ca93ca0c4da62385fbb
+AUX p2pool.initd 1134 BLAKE2B 5157e0fe4d34da614ed6d5a400680f518cf9f33912ae8382e87cf071f74dac0ecaf12626bcbb2d55ed33e54d1f10bef7a83c6db900fe1a6dcaf5eb80b85d7eaa SHA512 80d72e6bcccd7a71d15e59a859b92a38a3ff95e85964a67276dedf0d50117c73d620695d49692fd9bb990f5cb5562c6378e839e1709c87e4e7da51efc1bc034b
+DIST p2pool-4.3.tar.xz 121435168 BLAKE2B fe09dbf3239b3a3785dcdcddb768f2ae2cdd8e4c7c4e07c4521c9f03b2eb6755b83ddb4ecc46fc9a2d524e6689be83bebea8dc43667b4f187db61d9aa9671084 SHA512 d3a1d4bd1b757fbdc3f7fd91aaeb457e19ed4f72dc9b6adf2ffb2e2e70916036d08ed19ec5e4b0aa534ebabfe43fba8f6956cd6c408c04b609ad761b985d35e5
+DIST p2pool-4.3_shasums.asc 2007 BLAKE2B f772d5ed9f93ce54d90f1fc168af8e92f18872d1d274bdfadcf3444cc9a0d5e6a97ced411ec4150f819243cd7fbd373a6f9219b746f661e099f61ac21c6f566a SHA512 6e8ebc1cdcd3ad81ccabf29532d788662d89fab089166d038c53d5d5685b864c45bfe92c81cb39a69cea1bdd8f9bf94f69578d64e29cc093af4ccf4108865ea9
+DIST p2pool-4.4.tar.xz 117006468 BLAKE2B d9546b56c4085f176084d36ee56a84bb1c7e253e22864164705dd1a26cee35d68a4e30d74ed92e8bd3cb01ea929cbfbd35b5cb516aaf36e02c12b0e706baee02 SHA512 83e4f2f363511951a289eb7a12b55aa949c802ce29f5b7f0cf982fa37fe72d7551460d718ed3ef833685b6eef641a8e0ba997a6021fce6a01da2e650a68ec11d
+DIST p2pool-4.4_shasums.asc 2007 BLAKE2B 85d2263d673f26044ed89812a9b8aea5c383360ddf0ef6ddcdf832bd2a1245b6e2655d947e5854cb7323f9400a7afe91968cfa57faa7b32e8188d82e46e29983 SHA512 0c22da304c2a2744836af1a45908e7907dcc3ff26ea1885c1feb505b12a42f3fdf290788a3225405354e6291c656c2f85e55cac16b3a219b9e35d926c6b3d1b6
+EBUILD p2pool-4.3-r1.ebuild 2678 BLAKE2B e3564df9b4e6a2470bf30f8d20facbac62b51cce2f60916265eab7a2be77d049792c4c2b34f9c33c94a41c31a2e832d0a99a75692ce7bff4168c8f6a59455cbc SHA512 e3e7c6810c7e88af8e953c8914828fc979116c8d1dc8873b8361217f32af163faa81d8f7a2858de64ec9506c534fc4a32171ef15aaea2f15ce2a3c5e8fb69129
+EBUILD p2pool-4.3.ebuild 2652 BLAKE2B a00abf5075344171b5fc74ccff089689ec9ed73608cd4dde550a5dac2dfd1c991e2ffe6de5e13a5453579b321e8996baf7439bb293590bfa326a3e4b1b679aff SHA512 ae9143c7f7a3778ffad7f9d9e3430d7057d21f419d5406b260b27067dcc6f5217b3451ccd26b7f10f827bad0079a1fe1392fd4e98ca34c9b78d776a05a71f9af
+EBUILD p2pool-4.4.ebuild 2678 BLAKE2B e3564df9b4e6a2470bf30f8d20facbac62b51cce2f60916265eab7a2be77d049792c4c2b34f9c33c94a41c31a2e832d0a99a75692ce7bff4168c8f6a59455cbc SHA512 e3e7c6810c7e88af8e953c8914828fc979116c8d1dc8873b8361217f32af163faa81d8f7a2858de64ec9506c534fc4a32171ef15aaea2f15ce2a3c5e8fb69129
+MISC metadata.xml 336 BLAKE2B 4d9ea4073c6d386663ea867ccc4cf61ae38a9f751a339a22b7f19543efa09ec58e4776fcb791665b2399d2852524c4c715d8f531fca55f40095bf5598e85fcf3 SHA512 f00b827b1f2ff64ecbbf4352662cf9c7d116e0340d73f5b52506cc675a17b77f3c2ad9914c6948736d75db03930d19c86efe55f1d57a403cf2fd3aa4e2f31083
diff --git a/net-p2p/p2pool/files/SChernykh.asc b/net-p2p/p2pool/files/SChernykh.asc
new file mode 100644 (file)
index 0000000..e6e61ce
--- /dev/null
@@ -0,0 +1,52 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBGBwYcABEADd2hZKkoLqx3S+HifsDrnETw/9UccXsIo5WYyYLGEdIexc5JQ1
+8NkLyuZb+ilZoZo4TiXBqJBHjqwjbdhDFiQa1SK9XvWZDrY/NW8ZOmM5w5yxDedM
+pgmKZm6vbVP1FtKyRckAkTrci5+ndFu85QfHrOI67fx5YE/byMFO4mSJ6FwigmAu
+9bZiG1GAkIoCOyptHa+SlV2qjbtzaGpXz8HUC+BTrP5BYSUSOrot7EcL0H7LD9qk
+YttlEMAPcT8G/gzOUAcRer1uXYaj8hUSDZI92sT35olId930fM/lTayORs+hh2U+
+gFPnoDnt0HfcHTUT+fHJdf1Q4g69V9UbfsG2V1gp56rbVTjYhwsWlck2TH3OcAXu
+YRaAUtbFv+RKPngumz5ibg11i50Q4xxe7RCGmQO9E4Ufk8WSiEwQcJP2VIj2AvIF
+lMiez+6H2KhepCvI1Khoba60uBxajvuEfvxfP582imclLYK/DGcDr6ZjWpOc1vzb
+IGzDDjrYOUdlJVYUfdfSgx3LspERJ+74QruyZdFoYsZQsXkkC0cgAohFsgwGVjfD
+DCm+spmOZTpB4WGOXO70VLvMtiOXJ8FIyokIdFajAez48aoQdbk3+3vfeRv7JVMI
+neQgx1ko3IIOTXrPXqz1PUdcZGLfQc61IVFXrU726r5caa2xQMMLnifMBQARAQAB
+tCdTQ2hlcm55a2ggPHNlcmdleS52LmNoZXJueWtoQGdtYWlsLmNvbT6JAk4EEwEK
+ADgWIQQfyqtNPcMxDRbL1QjEf4K1Tah63wUCYHBhwAIbAwULCQgHAgYVCgkICwIE
+FgIDAQIeAQIXgAAKCRDEf4K1Tah6301vEADJsuk+Avwn6QQjMYjyYlo99ds4RrON
+lYYts+k8XqqFDj85hYFs1IgV1bn7ooLuIeyE7fEZM8uep6cU7aIZ2V9rL1m0Z3xA
++KMbmhmh9zQJOI9LDG/Ftnx7m5RSweCzccxmAAav4aZCRo1M8Kra2PDI9fe8Y9Ai
+1K34RD5i+BsWJecNAFWtWCKiyv21S86oZYIagLF4DB1XRjpK1btuX/U65MjqaEUX
+/eXuPxWe9QcguMeUySg5ixxkuO/JcmK+p4EvUY5F5b24NvoQexJstHp8iMowI6sz
+lhHdWkrzM0fEUUVWlM+zC7Yqp+96ZVCrv9jsq7u0joVAqVOhxRPAqXOYCWGrLTJk
+N616UbIGSWnRfvqJF20FPRMw1DLZoRW4IgHLUj3v2Ct6vECQzzhksTmddzIx+ZCM
+JWs64DlrriQoKIdE8KqzqIdhLOoEy07qlMc/WpZTc7ysd2i/au1p/mYAGJgw0/hY
+28IslI+c6W0dle3i9vAjU7wgrsTQeo1JZbAioLtQjk4SrWk+4LWBhwemEDV0j+HA
+iN54cqyLRqEwmpRVYcl18zrAQiPvWIb6BEEoeL290eT0TfiF5jZuVmZDTBa0HgCA
+k9QQtft7HT7rdOOlFqMKeqoQVDC+6eyCU8r3SOgzL6UYPiVXRM+lnX053aWEV9Rx
+h+Ib3iznP9/nALkCDQRgcGHAARAA0SiWBr3SjMrvQnbJipnRKQwpoWG8vtyJbvlU
+QEAMJbpy9T3/2u1hAs/cMh2VK1Y7Bn+ZQ51c1nmxVraj5PD0/BSD27MC3aZ6kp6j
+JFbsb63MKk4Y66RQbgDw5JWd9IgDQtc4M3XgC5xcCO7y3rvKgDQxYBpjAwjeOvS3
+03ZVPyivWV2O/43PI9QZ4DHObEfR8M06EeTqwkrsJnAuCtQlW0aCBRII5o/D1w6w
+1IZGfAwdUcVoefLRZC2bRaswA+IoOLvlH/vgirve8VYhJK9Wt+JWaNSb2vWUQXws
+fFmpo89IZcRiHh5WP5A//Jh9RR8f+7FLkGXoJwl7dCEfDZKkI9uZvy21J4tLM9M6
+2ygthkYPuJE/VnCZcM24sWbSMkN/fh4QHNsEXq9PZpimOTtQv0xpu9p4lkes91pg
+vQm8fPoxoMQEMBY/SHFh3X6r8zVL7RUPfOrRxfiYibbSIyRsmY/Mz+M0OilAw7L7
+zKMpX7SWS2M0/mEtUW+Xb4vGxj3YcQ65e3CJx/l9qeGjbi1GJ1D8jshI/k2AqP3C
+2hKSGeLjqtUUJOhOMySkELDdDNkSRUA9qZEW3dLsQOFD424l9RTjPpBSrYTsYxpe
+BRfRCejQ/PZL9VULRQsQZCbtBDrSeKQ0J2Dp5zJl6A+17lUUSv1FBLEeDt6MotAA
+2Mqm96kAEQEAAYkCNgQYAQoAIBYhBB/Kq009wzENFsvVCMR/grVNqHrfBQJgcGHA
+AhsMAAoJEMR/grVNqHrfQF0P/1udspDo+omDz9uWeWod/7shFpuX8CweI7j/4Efk
+cFTc2bQ0zAjqBLiVo67Zncrrikn4gBhQGmcj1kKXdUdFTaKwjfSk0MSA/VIo7vwh
+2iYTrEuYUvTmVoQ5SYg0ekKzwA/9BSow4NZvIL3NC06RNxbyeJ9gBhsWZfUPJ8BS
+wxTCcHQfbI9ZDkgVxI2CZf/DbBdsmqVB+VlDcq8uQj4jpRjTX+xWMRcy5WrfvH1r
+W5JpG7ULyEv5B5ocD3+Gbos0kxQzWoKqCZsu44W+0nPpwDe1CXkjrMmtoRtuNtJc
+mX1+zfjE4Xn4foOiunbpMVNFHahD1n9rk0/4sMQ79GpD1iwOBsMh6wq3gYqh+ycf
+vEOEHH7ERa9ryNWXVDeci6KLRuFI7vDxZez++4uospQ4LZW2n9hiLaj2rJHcYYEM
+x229L5SeRye0YFXX805mwtqcYxmrMitoaSreSKpnOKvF2i0gN/N0JXeHb5P3QQcY
+bocA9ZZvYIEovlpnsPVLtDIwjysI3668mEGDqNEikVqi/9btpYygS6CjTbiB6b3O
+m4sV4vlQtg8u6M863LyLuqaaj9b+vWVZy3K5esiLKaIsIARVqLnBeQDOIqtAFlcG
+AHSiuPpC49NkwV6YJNJw9XP2QknIXpE0fRdoSQune0rKRZgnbj7VOZX6nCkT34EA
+fo0a
+=YlLc
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/net-p2p/p2pool/files/flags.cmake b/net-p2p/p2pool/files/flags.cmake
new file mode 100644 (file)
index 0000000..367863e
--- /dev/null
@@ -0,0 +1,37 @@
+set(GENERAL_FLAGS "-pthread")
+if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
+       
+       if (ARMv8)
+               set(GENERAL_FLAGS "${GENERAL_FLAGS} -mfix-cortex-a53-835769 -mfix-cortex-a53-843419")
+       endif()
+       
+       set(WARNING_FLAGS "-Wall -Wextra -Wcast-qual -Wlogical-op -Wundef -Wformat=2 -Wpointer-arith -Werror")
+       if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.5.0)
+               set(WARNING_FLAGS "${WARNING_FLAGS} -Wstrict-overflow=2")
+       endif()
+       
+       if (STATIC_BINARY)
+               set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
+       else()
+               set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
+       endif()
+       
+elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
+       
+       if (ARMv8)
+               set(GENERAL_FLAGS "${GENERAL_FLAGS} -mfix-cortex-a53-835769")
+       endif()
+       
+       set(WARNING_FLAGS "-Wall -Wextra -Wno-undefined-internal -Wunreachable-code-aggressive -Wmissing-prototypes -Wmissing-variable-declarations -Werror")
+       
+endif()
+
+if (DISABLE_WARNINGS)
+       set(WARNING_FLAGS "-w")
+endif()
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GENERAL_FLAGS} ${WARNING_FLAGS}")
+set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${GENERAL_FLAGS} ${WARNING_FLAGS}")
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GENERAL_FLAGS} ${WARNING_FLAGS}")
+set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${GENERAL_FLAGS} ${WARNING_FLAGS}")
diff --git a/net-p2p/p2pool/files/logrotated b/net-p2p/p2pool/files/logrotated
new file mode 100644 (file)
index 0000000..1fffdbf
--- /dev/null
@@ -0,0 +1,9 @@
+# p2pool logrotate snipet for Gentoo Linux
+
+/var/log/monero/p2pool*log {
+  rotate 7                                                                                                                                                                                                                                                                    
+  daily                                                                                                                                                                                                                                                                       
+  missingok
+  notifempty
+  copytruncate
+}
diff --git a/net-p2p/p2pool/files/p2pool.confd b/net-p2p/p2pool/files/p2pool.confd
new file mode 100644 (file)
index 0000000..3763a07
--- /dev/null
@@ -0,0 +1,66 @@
+P2POOL_USR="monero"
+P2POOL_GRP="monero"
+P2POOL_DIR="/var/lib/p2pool" #see --data-dir below
+#Put your detinination wallet below.
+XMR_WALLET=""
+
+# Set output and error log for coloured logfiles
+output_log="/var/log/monero/p2pool.log"
+error_log="/var/log/monero/p2pool_err.log"
+
+# p2pool always logs to $P2POOL_DIR/p2pool.log
+# If P2POOL_LOGFILE is set, the init script will "checkpath" $P2POOL_LOGFILE then forcibly create a symlink at $P2POOL_DIR/p2pool.log pointing to $P2POOL_LOGFILE
+P2POOL_LOGFILE="/dev/null"
+
+# Connect to host/port
+ARGS="--host 10.0.0.254"
+ARGS="${ARGS} --zmq-port 18083"
+
+# Listen on ip:port
+# Enable only one of the below lines
+ARGS="${ARGS} --p2p 0.0.0.0:37889"
+#ARGS="${ARGS} --mini --p2p 0.0.0.0:37888"
+
+# Other config
+ARGS="${ARGS} --wallet ${XMR_WALLET}"
+ARGS="${ARGS} --data-dir ${P2POOL_DIR}"
+
+#CL args for p2pool daemon
+#Usage:
+
+#--wallet             Wallet address to mine to. Subaddresses and integrated addresses are not supported!
+#--host               IP address of your Monero node, default is 127.0.0.1
+#--rpc-port           monerod RPC API port number, default is 18081
+#--zmq-port           monerod ZMQ pub port number, default is 18083 (same port as in monerod's "--zmq-pub" command line parameter)
+#--stratum            Comma-separated list of IP:port for stratum server to listen on
+#--p2p                Comma-separated list of IP:port for p2p server to listen on
+#--addpeers           Comma-separated list of IP:port of other p2pool nodes to connect to
+#--light-mode         Don't allocate RandomX dataset, saves 2GB of RAM
+#--loglevel           Verbosity of the log, integer number between 0 and 6
+#--data-dir           Path to store general p2pool files (log, cache, peer data, etc.), default is current directory
+#--config             Deprecated, will be removed in the next version. Use --sidechain-config instead
+#--sidechain-config   Name of the p2pool sidechain parameters file (only use it if you run your own sidechain)
+#--data-api           Path to the p2pool JSON data (use it in tandem with an external web-server). Not affected by --data-dir setting!
+#--local-api          Enable /local/ path in api path for Stratum Server and built-in miner statistics
+#--stratum-api        An alias for --local-api
+#--no-cache           Disable p2pool.cache
+#--no-color           Disable colors in console output
+#--no-randomx         Disable internal RandomX hasher: p2pool will use RPC calls to monerod to check PoW hashes
+#--out-peers N        Maximum number of outgoing connections for p2p server (any value between 10 and 450)
+#--in-peers N         Maximum number of incoming connections for p2p server (any value between 10 and 450)
+#--start-mining N     Start built-in miner using N threads (any value between 1 and 64)
+#--mini               Connect to p2pool-mini sidechain. Note that it will also change default p2p port from 37889 to 37888
+#--no-autodiff        Disable automatic difficulty adjustment for miners connected to stratum (WARNING: incompatible with Nicehash and MRR)
+#--rpc-login          Specify username[:password] required for Monero RPC server
+#--socks5             Specify IP:port of a SOCKS5 proxy to use for outgoing connections
+#--no-dns             Disable DNS queries, use only IP addresses to connect to peers (seed node DNS will be unavailable too)
+#--p2p-external-port  Port number that your router uses for mapping to your local p2p port. Use it if you are behind a NAT and still want to accept incoming connections
+#--no-upnp            Disable UPnP port forwarding
+#--no-igd             An alias for --no-upnp
+#--upnp-stratum       Port forward Stratum port (it's not forwarded by default)
+#--merge-mine         IP:port and wallet address for another blockchain to merge mine with
+#--version            Print p2pool's version and build details
+#--tls-cert file      Load TLS certificate chain from "file" in the PEM format
+#--tls-cert-key file  Load TLS certificate private key from "file" in the PEM format
+#--no-stratum-http    Disable HTTP on Stratum ports
+#--help               Show this help message
diff --git a/net-p2p/p2pool/files/p2pool.initd b/net-p2p/p2pool/files/p2pool.initd
new file mode 100755 (executable)
index 0000000..a77a249
--- /dev/null
@@ -0,0 +1,38 @@
+#!/sbin/openrc-run
+
+name="P2Pool Daemon"
+description="Connects crypto mining apps to a Monero daemon"
+pidfile="/var/run/p2pool.pid"
+command=/usr/bin/p2pool
+command_args="${ARGS}"
+supervisor=supervise-daemon
+command_user="${P2POOL_USR}:${P2POOL_GRP}"
+directory="${P2POOL_DIR}"
+respawn_max="3"
+respawn_period="40"
+
+depend() {
+    need localmount
+    need net
+    after monerod
+}
+
+start_pre() {
+    checkpath -o ${P2POOL_USR}:${P2POOL_GRP} -d "${directory}"
+    if [ -n "${output_log}" ];then
+               checkpath -d $(dirname "${output_log}")
+       checkpath -o ${P2POOL_USR}:${P2POOL_GRP} -f "${output_log}"
+       fi
+       if [ -n "${error_log}" ];then
+               checkpath -d $(dirname "${error_log}")
+        checkpath -o ${P2POOL_USR}:${P2POOL_GRP} -f "${error_log}"
+       fi
+       if [ -n "${P2POOL_LOGFILE}" ];then
+               checkpath -d $(dirname "${P2POOL_LOGFILE}")
+               if ! ls -l "${directory}/p2pool.log" 2>/dev/null|awk '{print $11}'|grep -q "${P2POOL_LOGFILE}";then
+                       rm "${directory}/p2pool.log" 2>/dev/null
+                       ln -s "${P2POOL_LOGFILE}" "${directory}/p2pool.log"
+               fi
+               [ -c "${P2POOL_LOGFILE}" ] || checkpath -o ${P2POOL_USR}:${P2POOL_GRP} -f "${P2POOL_LOGFILE}"
+       fi
+}
diff --git a/net-p2p/p2pool/metadata.xml b/net-p2p/p2pool/metadata.xml
new file mode 100644 (file)
index 0000000..7fe8cbc
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+       <maintainer type="person">
+               <email>adam.pimentel46@gmail.com</email>
+               <name>Adam Pimentel</name>
+       </maintainer>
+       <upstream>
+               <remote-id type="github">SChernykh/p2pool</remote-id>
+       </upstream>
+</pkgmetadata>
diff --git a/net-p2p/p2pool/p2pool-4.3-r1.ebuild b/net-p2p/p2pool/p2pool-4.3-r1.ebuild
new file mode 100644 (file)
index 0000000..2d92b84
--- /dev/null
@@ -0,0 +1,85 @@
+# Copyright 2022-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+#TODO: enable/fix GRPC/TLS dependency and add it as USE flag (https://github.com/SChernykh/p2pool/issues/313)
+#      These features build fine in cmake outside of portage, I can't figure out how to link them here for the life of me.
+#      It's probably better to just re-write the CMakeLists.txt to dynamicially link with gRPC
+
+EAPI=8
+
+inherit cmake verify-sig
+
+DESCRIPTION="Decentralized pool for Monero mining"
+HOMEPAGE="https://p2pool.io"
+SRC_URI="
+       https://github.com/SChernykh/p2pool/releases/download/v${PV}/p2pool_source.tar.xz -> ${P}.tar.xz
+       verify-sig? ( https://github.com/SChernykh/p2pool/releases/download/v${PV}/sha256sums.txt.asc -> ${P}_shasums.asc )
+"
+
+LICENSE="BSD GPL-3+ ISC LGPL-3+ MIT"
+SLOT="0"
+KEYWORDS="amd64 ~arm64 ~x86"
+#IUSE="grpc tls"
+
+DEPEND="
+       dev-libs/openssl
+       net-libs/czmq
+       dev-libs/libuv
+       net-misc/curl
+"
+BDEPEND="
+       verify-sig? ( sec-keys/openpgp-keys-schernykh )
+"
+
+src_unpack() {
+       if use verify-sig; then
+               local VERIFY_SIG_OPENPGP_KEY_PATH="${BROOT}"/usr/share/openpgp-keys/SChernykh.asc
+               pushd "${DISTDIR}" > /dev/null || die
+               verify-sig_verify_message ${P}_shasums.asc - | \
+                       tr \\r \\n | \
+                       tr '[:upper:]' '[:lower:]' | \
+                       sed -n '/p2pool_source/,$p' | \
+                       grep -m 1 sha256: | \
+                       sed "s/sha256: \(.*\)/\1 ${P}.tar.xz/" | \
+                       verify-sig_verify_unsigned_checksums - sha256 ${P}.tar.xz
+               assert
+               popd || die
+       fi
+       unpack ${P}.tar.xz
+       mv -T "${WORKDIR}"/${PN} "${WORKDIR}"/${P} || die
+}
+
+src_configure() {
+       local mycmakeargs=(
+               -DSTATIC_BINARY=OFF
+               -DSTATIC_LIBS=OFF
+               -DWITH_GRPC=OFF #$(usex grpc)
+               -DWITH_TLS=OFF #$(usex tls)
+       )
+       cmake_src_configure
+}
+
+src_install(){
+       dobin "${BUILD_DIR}/p2pool"
+    # OpenRC
+    newconfd "${FILESDIR}/p2pool.confd" ${PN}
+    newinitd "${FILESDIR}/p2pool.initd" ${PN}
+       insinto /etc/logrotate.d
+    newins "${FILESDIR}/logrotated" "${PN}"
+}
+
+pkg_postinst() {
+       #Some important wisdom taken from P2Pool documentation
+       ewarn "P2Pool for Monero is now installed."
+       ewarn "Update /etc/conf.d/p2pool with yout primary wallet address and"
+       ewarn "the address of your monero node (e.g. monerod)"
+       ewarn ""
+       ewarn "Once configured and started, point your RandomX miner (e.g. XMRig) at p2pool"
+       ewarn "For example 'xmrig -o 127.0.0.1:3333'"
+       ewarn ""
+       ewarn "You MUST use your primary address when using p2pool, just like solo mining."
+       ewarn "If you want privacy, create a new mainnet wallet for P2Pool mining."
+       ewarn ""
+       ewarn "Rewards will not be visible unless you use a wallet that supports P2Pool."
+       ewarn "See https://p2pool.io/#help and https://github.com/SChernykh/p2pool for more information."
+}
diff --git a/net-p2p/p2pool/p2pool-4.3.ebuild b/net-p2p/p2pool/p2pool-4.3.ebuild
new file mode 100644 (file)
index 0000000..8fa47d5
--- /dev/null
@@ -0,0 +1,84 @@
+# Copyright 2022-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+#TODO: enable/fix GRPC/TLS dependency and add it as USE flag (https://github.com/SChernykh/p2pool/issues/313)
+#      These features build fine in cmake outside of portage, I can't figure out how to link them here for the life of me.
+#      It's probably better to just re-write the CMakeLists.txt to dynamicially link with gRPC
+
+EAPI=8
+
+inherit cmake verify-sig
+
+DESCRIPTION="Decentralized pool for Monero mining"
+HOMEPAGE="https://p2pool.io"
+SRC_URI="
+       https://github.com/SChernykh/p2pool/releases/download/v${PV}/p2pool_source.tar.xz -> ${P}.tar.xz
+       verify-sig? ( https://github.com/SChernykh/p2pool/releases/download/v${PV}/sha256sums.txt.asc -> ${P}_shasums.asc )
+"
+
+LICENSE="BSD GPL-3+ ISC LGPL-3+ MIT"
+SLOT="0"
+KEYWORDS="amd64 ~arm64 ~x86"
+#IUSE="grpc tls"
+
+DEPEND="
+       dev-libs/openssl
+       net-libs/czmq
+       dev-libs/libuv
+       net-misc/curl
+"
+BDEPEND="
+       verify-sig? ( sec-keys/openpgp-keys-schernykh )
+"
+
+src_unpack() {
+       if use verify-sig; then
+               local VERIFY_SIG_OPENPGP_KEY_PATH="${BROOT}"/usr/share/openpgp-keys/SChernykh.asc
+               pushd "${DISTDIR}" > /dev/null || die
+               verify-sig_verify_message ${P}_shasums.asc - | \
+                       tr \\r \\n | \
+                       tr '[:upper:]' '[:lower:]' | \
+                       sed -n '/p2pool_source/,$p' | \
+                       grep -m 1 sha256: | \
+                       sed "s/sha256: \(.*\)/\1 ${P}.tar.xz/" | \
+                       verify-sig_verify_unsigned_checksums - sha256 ${P}.tar.xz
+               assert
+               popd || die
+       fi
+       unpack ${P}.tar.xz
+       mv -T "${WORKDIR}"/${PN} "${WORKDIR}"/${P} || die
+}
+
+src_configure() {
+       local mycmakeargs=(
+               -DSTATIC_BINARY=OFF
+               -DSTATIC_LIBS=OFF
+               -DWITH_GRPC=OFF #$(usex grpc)
+               -DWITH_TLS=OFF #$(usex tls)
+       )
+       cmake_src_configure
+}
+
+src_install(){
+       dobin "${BUILD_DIR}/p2pool"
+    # OpenRC
+    newconfd "${FILESDIR}/p2pool.confd" ${PN}
+    newinitd "${FILESDIR}/p2pool.initd" ${PN}
+    newins "${FILESDIR}/logrotated" "${PN}"
+}
+
+pkg_postinst() {
+       #Some important wisdom taken from P2Pool documentation
+       ewarn "P2Pool for Monero is now installed."
+       ewarn "Update /etc/conf.d/p2pool with yout primary wallet address and"
+       ewarn "the address of your monero node (e.g. monerod)"
+       ewarn ""
+       ewarn "Once configured and started, point your RandomX miner (e.g. XMRig) at p2pool"
+       ewarn "For example 'xmrig -o 127.0.0.1:3333'"
+       ewarn ""
+       ewarn "You MUST use your primary address when using p2pool, just like solo mining."
+       ewarn "If you want privacy, create a new mainnet wallet for P2Pool mining."
+       ewarn ""
+       ewarn "Rewards will not be visible unless you use a wallet that supports P2Pool."
+       ewarn "See https://p2pool.io/#help and https://github.com/SChernykh/p2pool for more information."
+}
diff --git a/net-p2p/p2pool/p2pool-4.4.ebuild b/net-p2p/p2pool/p2pool-4.4.ebuild
new file mode 100644 (file)
index 0000000..2d92b84
--- /dev/null
@@ -0,0 +1,85 @@
+# Copyright 2022-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+#TODO: enable/fix GRPC/TLS dependency and add it as USE flag (https://github.com/SChernykh/p2pool/issues/313)
+#      These features build fine in cmake outside of portage, I can't figure out how to link them here for the life of me.
+#      It's probably better to just re-write the CMakeLists.txt to dynamicially link with gRPC
+
+EAPI=8
+
+inherit cmake verify-sig
+
+DESCRIPTION="Decentralized pool for Monero mining"
+HOMEPAGE="https://p2pool.io"
+SRC_URI="
+       https://github.com/SChernykh/p2pool/releases/download/v${PV}/p2pool_source.tar.xz -> ${P}.tar.xz
+       verify-sig? ( https://github.com/SChernykh/p2pool/releases/download/v${PV}/sha256sums.txt.asc -> ${P}_shasums.asc )
+"
+
+LICENSE="BSD GPL-3+ ISC LGPL-3+ MIT"
+SLOT="0"
+KEYWORDS="amd64 ~arm64 ~x86"
+#IUSE="grpc tls"
+
+DEPEND="
+       dev-libs/openssl
+       net-libs/czmq
+       dev-libs/libuv
+       net-misc/curl
+"
+BDEPEND="
+       verify-sig? ( sec-keys/openpgp-keys-schernykh )
+"
+
+src_unpack() {
+       if use verify-sig; then
+               local VERIFY_SIG_OPENPGP_KEY_PATH="${BROOT}"/usr/share/openpgp-keys/SChernykh.asc
+               pushd "${DISTDIR}" > /dev/null || die
+               verify-sig_verify_message ${P}_shasums.asc - | \
+                       tr \\r \\n | \
+                       tr '[:upper:]' '[:lower:]' | \
+                       sed -n '/p2pool_source/,$p' | \
+                       grep -m 1 sha256: | \
+                       sed "s/sha256: \(.*\)/\1 ${P}.tar.xz/" | \
+                       verify-sig_verify_unsigned_checksums - sha256 ${P}.tar.xz
+               assert
+               popd || die
+       fi
+       unpack ${P}.tar.xz
+       mv -T "${WORKDIR}"/${PN} "${WORKDIR}"/${P} || die
+}
+
+src_configure() {
+       local mycmakeargs=(
+               -DSTATIC_BINARY=OFF
+               -DSTATIC_LIBS=OFF
+               -DWITH_GRPC=OFF #$(usex grpc)
+               -DWITH_TLS=OFF #$(usex tls)
+       )
+       cmake_src_configure
+}
+
+src_install(){
+       dobin "${BUILD_DIR}/p2pool"
+    # OpenRC
+    newconfd "${FILESDIR}/p2pool.confd" ${PN}
+    newinitd "${FILESDIR}/p2pool.initd" ${PN}
+       insinto /etc/logrotate.d
+    newins "${FILESDIR}/logrotated" "${PN}"
+}
+
+pkg_postinst() {
+       #Some important wisdom taken from P2Pool documentation
+       ewarn "P2Pool for Monero is now installed."
+       ewarn "Update /etc/conf.d/p2pool with yout primary wallet address and"
+       ewarn "the address of your monero node (e.g. monerod)"
+       ewarn ""
+       ewarn "Once configured and started, point your RandomX miner (e.g. XMRig) at p2pool"
+       ewarn "For example 'xmrig -o 127.0.0.1:3333'"
+       ewarn ""
+       ewarn "You MUST use your primary address when using p2pool, just like solo mining."
+       ewarn "If you want privacy, create a new mainnet wallet for P2Pool mining."
+       ewarn ""
+       ewarn "Rewards will not be visible unless you use a wallet that supports P2Pool."
+       ewarn "See https://p2pool.io/#help and https://github.com/SChernykh/p2pool for more information."
+}
diff --git a/profiles/categories b/profiles/categories
new file mode 100644 (file)
index 0000000..48b5e3c
--- /dev/null
@@ -0,0 +1 @@
+cross-aarch64-unknown-linux-gnu
diff --git a/profiles/repo_name b/profiles/repo_name
new file mode 100644 (file)
index 0000000..4083037
--- /dev/null
@@ -0,0 +1 @@
+local
diff --git a/sci-libs/miopen/Manifest b/sci-libs/miopen/Manifest
new file mode 100644 (file)
index 0000000..7d3a348
--- /dev/null
@@ -0,0 +1,12 @@
+AUX miopen-4.2.0-disable-no-inline-boost.patch 447 BLAKE2B ed62e94b4a557c06654ec7ea35300d3d737d4caf8f2421d119a4963c0a13ea4ad2ddeb990f95764e1063872d1dd12fdeb9c917d1a6d0409d0533d78642e03dcb SHA512 32785237505bbc291df6fc7ecb2a9dbf4320f7a8f97ebb0296392d7b5404c5072c21e254d579720c27391930ebe4e779b9d1de344f47905a9210fe0b8e4b7b28
+AUX miopen-4.2.0-gcc11-numeric_limits.patch 461 BLAKE2B 4502c7dc41e0e4ebf4105076c4415ce36e56e596bf98672ecf3d77de4a984499be0990a762c2b05d5e395a06c7df511c9f7629362c7849b31a0d2868b45d99d0 SHA512 04ce10c55af9b979651ef0c345bd12156c850139809601f29ab9305235499b53034efe1928a6dbb77d04114ddf8d93c71d37cc7bef373b07620c2169f88aebc3
+AUX miopen-4.3.0-enable-test.patch 1046 BLAKE2B a9a103eee9b3b6890c02349f36dba7c4cc4459969ebe07915d0cccd3aecbd0edab21de8acbdaee17daae602733965ec1bdda60456f2e0c6bd91ae9795c24622e SHA512 cadc3844aaa32713f0d630ae3ffb9a947c303cf80410785339187ad0ee3cce8bac1b201c12134ba0241c54c296e2752a1076a3826735ccfe4d2cf5f15504f390
+AUX miopen-4.3.0-fix-interface-include-in-HIP_COMPILER_FLAGS.patch 954 BLAKE2B 11f260c1ab9dd1569cf25363626e6431615f8853f334b0123d82b0e3404dcdb1b4ecd9e26658e2f39e4fa6a15ba672cb6940b0279e0ef22535e46992721fd060 SHA512 28724e7e1c1de5cee2d18b6c3da76fa857f95aee64a286262c8426149787f62d07f4a3892472cef91d3c091ec53c7f474a70616ce63e5fbbb4c531ed2ab91a50
+AUX miopen-5.0.2-strip-xnack-in-flags.patch 1205 BLAKE2B d1ba065387050b51288dba37631adea42398b2f7cd8b604e5c305d3491fb661dce8c448e31db42c70f8b6e4dec84c4214ce869dd1419eb67c2ea4c33f18849b5 SHA512 ad32335831c7d1057b53469aa2d1f8f3366b23ccdc71cb7e9a4e7813e7da7e9bb73e62465f1086391653538ccbab2f662baf2446e10e8dbc0f0db631d7368a4d
+AUX miopen-5.1.3-avoid-metadata-error-for-vanilla-clang.patch 10748 BLAKE2B 582b362a54d9ee00c8f6062b4ec16bebdaea7734adadcd5f6201801cb8ce3a7ca64e8148a10f2f3ab682560ced1f037b217bdcd161869d80a8489f4d56bd5241 SHA512 08cd489d23a48d0b227dacc514e3f84999c1e9a0ac3dd5424d9376c77c4d745c65f48c0f470cb5e65c20e9dbbfcb457995301a74bfe27a81604bf89213a2f1d2
+AUX miopen-5.1.3-deprecate-clang-ocl.patch 2884 BLAKE2B 4f45f66d87dea51d9f87878f52520863b36defa1403055a580e5f33c18e3de08daad1b3d3d5fad06d7d3f16da4f0945390872f573f168d1893f5f635070f1463 SHA512 c4835559a4005ffd2aac7afb38213d06857ab1a8d4bc5bd5c150b82226671fb1d66c6ef1d4eab2106ad11c475007af441182ca26f659a3fd779cd7d4f5c90247
+AUX miopen-5.1.3-gfx1031.patch 19268 BLAKE2B b3d10c57601fd5f39ae431d101687863de34b149ee08df25c987d18ef0bd89d8419a4a18659a22060093eba1cf97c2774e92abf8a38449a202e8770070b29dbf SHA512 44fb3445065087a3952ac143fba88addb4cc634dbd13e15d85d234c64fabba9cf7b83d8161a361e847375a2bc92efc86489e12cfa23ecce1b035d2ccb028db56
+AUX miopen-5.1.3-include-array.patch 343 BLAKE2B 993a8f3e301f4c16088ca216b2d820b17ceb42eeda4550b4291a70e00592281f992bf184407d024a0f8b2207a26fef2d56c26ef95e7a452d3b97090e1335a404 SHA512 887ac13f25c1bfd524bb2a3be701bf688f002a95ef8218cb798e41feaeb0678dbbd2ffaf905c59070a125001093bf5ede1bb6a77fdfe6f7a4ff19cbccfdc6624
+AUX miopen-5.1.3-no-strip.patch 608 BLAKE2B 3173d95219542a48c6dcd2b87e7157dcf483ff714c3d1c1c47aab8fc8af7b1fd4f6ac52b9d8e892cc25bff973597f4a05426fa4714b0764733b810867af59cfe SHA512 201357718203ee9a4062362541c483e069321b825708c6aa0e8892cc7722bcd520808797307e320df34c4fbf0003198f7a46717d5ff3819b1e2c3a5a3a045725
+DIST MIOpen-5.7.1.tar.gz 100751593 BLAKE2B c5f847fe4374ab22737c281a65401125012328412d584fc09244b431ea6265d6d5028429115ee15fa8b04cbe0edd020e4e7ac8deb22561183ed76cb8c3d4d9d4 SHA512 3354b3b154f29a6337403abc5a71ec47c0b2558320c5a1b0cbfbbdb370c4fada2db12d4a19a312b5e30ca2e2302ee50ece3390603e84d132b2212a168e9523fa
+EBUILD miopen-5.7.1.ebuild 2887 BLAKE2B dc14414391e10e8b3e7fd55c8c01257cea393cddd4f72815d301c25d7cee500c0169c989de0430078015d0c151bdc6f55637f7d37533a1c6704d756c9e416d07 SHA512 1e8634694fe4c8ec09b9db8a9611e767bf1c1420efc302e9d9b34934b7751f1f66916e452903ce0380fd67eee388f790502bd760f1b6693805a602c8eecdac6f
diff --git a/sci-libs/miopen/files/miopen-4.2.0-disable-no-inline-boost.patch b/sci-libs/miopen/files/miopen-4.2.0-disable-no-inline-boost.patch
new file mode 100644 (file)
index 0000000..769217a
--- /dev/null
@@ -0,0 +1,14 @@
+This let MIOpen compatible with >boost-1.72, for example 1.76
+
+Suggested by: Michael Boone <mike@protagonistsystems.io>
+
+--- a/CMakeLists.txt   2021-07-23 01:26:15.377754243 -0700
++++ b/CMakeLists.txt   2021-07-23 01:29:23.925685190 -0700
+@@ -216,6 +216,7 @@
+ message(STATUS "Hip compiler flags: ${HIP_COMPILER_FLAGS}")
+ add_definitions("-DHIP_COMPILER_FLAGS=${HIP_COMPILER_FLAGS}")
++add_definitions("-DBOOST_CONTAINER_DISABLE_NOINLINE")
+ # HIP
diff --git a/sci-libs/miopen/files/miopen-4.2.0-gcc11-numeric_limits.patch b/sci-libs/miopen/files/miopen-4.2.0-gcc11-numeric_limits.patch
new file mode 100644 (file)
index 0000000..73997ce
--- /dev/null
@@ -0,0 +1,14 @@
+See: https://stackoverflow.com/questions/4798936/numeric-limits-was-not-declared-in-this-scope-no-matching-function-for-call-t
+
+https://www.gnu.org/software/gcc/gcc-11/porting_to.html#header-dep-changes
+
+--- MIOpen-rocm-4.2.0/src/include/miopen/float_equal.hpp
++++ MIOpen-rocm-4.2.0/src/include/miopen/float_equal.hpp
+@@ -29,6 +29,7 @@
+ #include <algorithm>
+ #include <cmath>
+ #include <numeric>
++#include <limits>
+ #ifdef _MSC_VER
+ #include <iso646.h>
+ #endif
diff --git a/sci-libs/miopen/files/miopen-4.3.0-enable-test.patch b/sci-libs/miopen/files/miopen-4.3.0-enable-test.patch
new file mode 100644 (file)
index 0000000..68d2f14
--- /dev/null
@@ -0,0 +1,31 @@
+This create option BUILD_TESTS for miopen, like other rocm math libs, and
+
+testing executables are always built if test enabled. The original behaviour, is
+
+always add test/CMakeLists.txt without adding test exes as targets, and compile them
+
+during test.
+--- orig/CMakeLists.txt
++++ MIOpen-rocm-4.3.0/CMakeLists.txt
+@@ -590,6 +590,9 @@ add_subdirectory(src)
+ if(MIOPEN_BUILD_DRIVER)
+     add_subdirectory(driver)
+ endif()
+-add_subdirectory(test)
++option(BUILD_TESTS "Build binaries for tests" OFF)
++if(BUILD_TESTS)
++      add_subdirectory(test)
++endif()
+ add_subdirectory(speedtests)
+ add_subdirectory(utils)
+--- orig/test/CMakeLists.txt
++++ MIOpen-rocm-4.3.0/test/CMakeLists.txt
+@@ -142,7 +142,7 @@ function(add_test_command NAME EXE)
+ endfunction()
+ function(add_test_executable TEST_NAME)
+-    add_executable (${TEST_NAME} EXCLUDE_FROM_ALL ${ARGN})
++    add_executable (${TEST_NAME} ${ARGN})
+     clang_tidy_check(${TEST_NAME})
+     target_link_libraries(${TEST_NAME} ${CMAKE_THREAD_LIBS_INIT})
+     # Cmake does not add flags correctly for gcc
diff --git a/sci-libs/miopen/files/miopen-4.3.0-fix-interface-include-in-HIP_COMPILER_FLAGS.patch b/sci-libs/miopen/files/miopen-4.3.0-fix-interface-include-in-HIP_COMPILER_FLAGS.patch
new file mode 100644 (file)
index 0000000..5c2762a
--- /dev/null
@@ -0,0 +1,17 @@
+The interface inlude directories of hip::device should be included using -I, not -isystem;
+
+otherwise compilation at MIOpen runtime will fail due to cstdlib cannot find <stdlib.h> or similar errors.
+
+Suggested-by: Yuyi Wang <Strawberry_Str@hotmail.com>
+Signed-off-by: Yiyang Wu <xgreenlandforwyy@gmail.com>
+--- orig/cmake/TargetFlags.cmake
++++ MIOpen-rocm-4.3.0/cmake/TargetFlags.cmake
+@@ -41,7 +41,7 @@ function(target_flags FLAGS TARGET)
+     set(_flags)
+     append_flags(_flags ${TARGET} "INTERFACE_COMPILE_OPTIONS" "")
+     append_flags(_flags ${TARGET} "INTERFACE_COMPILE_DEFINITIONS" "-D")
+-    append_flags(_flags ${TARGET} "INTERFACE_INCLUDE_DIRECTORIES" "-isystem ")
++      append_flags(_flags ${TARGET} "INTERFACE_INCLUDE_DIRECTORIES" "-I ")
+     append_flags(_flags ${TARGET} "INTERFACE_LINK_DIRECTORIES" "-L ")
+     append_flags(_flags ${TARGET} "INTERFACE_LINK_OPTIONS" "")
+     append_link_flags(_flags ${TARGET} "INTERFACE_LINK_LIBRARIES" "")
diff --git a/sci-libs/miopen/files/miopen-5.0.2-strip-xnack-in-flags.patch b/sci-libs/miopen/files/miopen-5.0.2-strip-xnack-in-flags.patch
new file mode 100644 (file)
index 0000000..14d2c5b
--- /dev/null
@@ -0,0 +1,20 @@
+if options like :xnack- exists in ${AMDGPU_TARGETS}, CMakeLists cannot handle HIP_COMPILER_FLAGS well
+
+the original regex replace should include :+- so xnack- is stripped as well. Otherwise clang complation at MIOpen runtime will fail.
+
+Signed-off-by: Yiyang Wu <xgreenlandforwyy@gmail.com>
+Index: MIOpen-rocm-5.0.2/CMakeLists.txt
+===================================================================
+--- MIOpen-rocm-5.0.2.orig/CMakeLists.txt
++++ MIOpen-rocm-5.0.2/CMakeLists.txt
+@@ -198,8 +198,8 @@ find_package(hip REQUIRED PATHS /opt/roc
+ message(STATUS "Build with HIP ${hip_VERSION}")
+ target_flags(HIP_COMPILER_FLAGS hip::device)
+ # Remove cuda arch flags
+-string(REGEX REPLACE --cuda-gpu-arch=[a-z0-9]+ "" HIP_COMPILER_FLAGS "${HIP_COMPILER_FLAGS}")
+-string(REGEX REPLACE --offload-arch=[a-z0-9]+ "" HIP_COMPILER_FLAGS "${HIP_COMPILER_FLAGS}")
++string(REGEX REPLACE --cuda-gpu-arch=[a-z0-9:+-]+ "" HIP_COMPILER_FLAGS "${HIP_COMPILER_FLAGS}")
++string(REGEX REPLACE --offload-arch=[a-z0-9:+-]+ "" HIP_COMPILER_FLAGS "${HIP_COMPILER_FLAGS}")
+ string(REPLACE "$<LINK_LANGUAGE:CXX>" "1" HIP_COMPILER_FLAGS "${HIP_COMPILER_FLAGS}")
+ string(REPLACE "SHELL:" "" HIP_COMPILER_FLAGS "${HIP_COMPILER_FLAGS}")
diff --git a/sci-libs/miopen/files/miopen-5.1.3-avoid-metadata-error-for-vanilla-clang.patch b/sci-libs/miopen/files/miopen-5.1.3-avoid-metadata-error-for-vanilla-clang.patch
new file mode 100644 (file)
index 0000000..3dca20f
--- /dev/null
@@ -0,0 +1,183 @@
+Together with find-sed command in 5.1.3 ebuild, this fixes
+https://github.com/ROCmSoftwarePlatform/MIOpen/issues/1731
+index 71b2cabf1..60e7fab6e 100644
+--- a/src/kernels/Conv_Winograd_v13_3_12_epilogue.inc
++++ b/src/kernels/Conv_Winograd_v13_3_12_epilogue.inc
+@@ -76,7 +76,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: N }
++    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: X }
+     - { .size: 4, .offset: 4,   .value_kind: by_value,      .value_type: i32, .name: C }
+     - { .size: 4, .offset: 8,   .value_kind: by_value,      .value_type: i32, .name: H }
+     - { .size: 4, .offset: 12,  .value_kind: by_value,      .value_type: i32, .name: W }
+diff --git a/src/kernels/Conv_Winograd_v16_5_0_epilogue.inc b/src/kernels/Conv_Winograd_v16_5_0_epilogue.inc
+index 36d47c862..f8f677ec6 100644
+--- a/src/kernels/Conv_Winograd_v16_5_0_epilogue.inc
++++ b/src/kernels/Conv_Winograd_v16_5_0_epilogue.inc
+@@ -76,7 +76,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: N }
++    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: X }
+     - { .size: 4, .offset: 4,   .value_kind: by_value,      .value_type: i32, .name: C }
+     - { .size: 4, .offset: 8,   .value_kind: by_value,      .value_type: i32, .name: H }
+     - { .size: 4, .offset: 12,  .value_kind: by_value,      .value_type: i32, .name: W }
+diff --git a/src/kernels/Conv_Winograd_v21_1_3_metadata.inc b/src/kernels/Conv_Winograd_v21_1_3_metadata.inc
+index deff81e84..ed47abea7 100644
+--- a/src/kernels/Conv_Winograd_v21_1_3_metadata.inc
++++ b/src/kernels/Conv_Winograd_v21_1_3_metadata.inc
+@@ -51,7 +51,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset:   0, .value_kind: by_value, .value_type: i32, .name: N }
++    - { .size: 4, .offset:   0, .value_kind: by_value, .value_type: i32, .name: X }
+     - { .size: 4, .offset:   4, .value_kind: by_value, .value_type: i32, .name: C }
+     - { .size: 4, .offset:   8, .value_kind: by_value, .value_type: i32, .name: H }
+     - { .size: 4, .offset:  12, .value_kind: by_value, .value_type: i32, .name: W }
+diff --git a/src/kernels/conv1x1u.s b/src/kernels/conv1x1u.s
+index 5dc213546..c890d45a4 100644
+--- a/src/kernels/conv1x1u.s
++++ b/src/kernels/conv1x1u.s
+@@ -1076,7 +1076,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset:  0, .value_kind: by_value, .value_type: i32, .name: N }
++    - { .size: 4, .offset:  0, .value_kind: by_value, .value_type: i32, .name: X }
+     - { .size: 4, .offset:  4, .value_kind: by_value, .value_type: i32, .name: C }
+     - { .size: 4, .offset:  8, .value_kind: by_value, .value_type: i32, .name: H }
+     - { .size: 4, .offset: 12, .value_kind: by_value, .value_type: i32, .name: W }
+diff --git a/src/kernels/conv1x1u_bias_activ.s b/src/kernels/conv1x1u_bias_activ.s
+index 1675e819a..6bbdd9936 100644
+--- a/src/kernels/conv1x1u_bias_activ.s
++++ b/src/kernels/conv1x1u_bias_activ.s
+@@ -1230,7 +1230,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset:  0, .value_kind: by_value, .value_type: i32, .name: N }
++    - { .size: 4, .offset:  0, .value_kind: by_value, .value_type: i32, .name: X }
+     - { .size: 4, .offset:  4, .value_kind: by_value, .value_type: i32, .name: C }
+     - { .size: 4, .offset:  8, .value_kind: by_value, .value_type: i32, .name: H }
+     - { .size: 4, .offset: 12, .value_kind: by_value, .value_type: i32, .name: W }
+diff --git a/src/kernels/conv1x1u_stride2.s b/src/kernels/conv1x1u_stride2.s
+index c5ea1e90c..6241edcf7 100644
+--- a/src/kernels/conv1x1u_stride2.s
++++ b/src/kernels/conv1x1u_stride2.s
+@@ -1162,7 +1162,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset:  0, .value_kind: by_value, .value_type: i32, .name: N }
++    - { .size: 4, .offset:  0, .value_kind: by_value, .value_type: i32, .name: X }
+     - { .size: 4, .offset:  4, .value_kind: by_value, .value_type: i32, .name: C }
+     - { .size: 4, .offset:  8, .value_kind: by_value, .value_type: i32, .name: H }
+     - { .size: 4, .offset: 12, .value_kind: by_value, .value_type: i32, .name: W }
+diff --git a/src/kernels/conv1x1wrw.s b/src/kernels/conv1x1wrw.s
+index b13b6ffa4..eb63f17c6 100644
+--- a/src/kernels/conv1x1wrw.s
++++ b/src/kernels/conv1x1wrw.s
+@@ -1243,7 +1243,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset:  0, .value_kind: by_value, .value_type: i32, .name: N }
++    - { .size: 4, .offset:  0, .value_kind: by_value, .value_type: i32, .name: X }
+     - { .size: 4, .offset:  4, .value_kind: by_value, .value_type: i32, .name: C }
+     - { .size: 4, .offset:  8, .value_kind: by_value, .value_type: i32, .name: H }
+     - { .size: 4, .offset: 12, .value_kind: by_value, .value_type: i32, .name: W }
+diff --git a/src/kernels/conv3x3wrw.s b/src/kernels/conv3x3wrw.s
+index a3f73aeae..b6fb1632c 100755
+--- a/src/kernels/conv3x3wrw.s
++++ b/src/kernels/conv3x3wrw.s
+@@ -1033,7 +1033,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset:  0, .value_kind: by_value, .value_type: i32, .name: N }
++    - { .size: 4, .offset:  0, .value_kind: by_value, .value_type: i32, .name: X }
+     - { .size: 4, .offset:  4, .value_kind: by_value, .value_type: i32, .name: C }
+     - { .size: 4, .offset:  8, .value_kind: by_value, .value_type: i32, .name: H }
+     - { .size: 4, .offset: 12, .value_kind: by_value, .value_type: i32, .name: W }
+diff --git a/src/kernels/conv_3x3_wheel_alpha_v3_0b_epilogue.inc b/src/kernels/conv_3x3_wheel_alpha_v3_0b_epilogue.inc
+index 358772e63..b27ad5284 100644
+--- a/src/kernels/conv_3x3_wheel_alpha_v3_0b_epilogue.inc
++++ b/src/kernels/conv_3x3_wheel_alpha_v3_0b_epilogue.inc
+@@ -76,7 +76,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: N }
++    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: X }
+     - { .size: 4, .offset: 4,   .value_kind: by_value,      .value_type: i32, .name: C }
+     - { .size: 4, .offset: 8,   .value_kind: by_value,      .value_type: i32, .name: H }
+     - { .size: 4, .offset: 12,  .value_kind: by_value,      .value_type: i32, .name: W }
+diff --git a/src/kernels/conv_3x3_wheel_alpha_v7_0_3b_epilogue.inc b/src/kernels/conv_3x3_wheel_alpha_v7_0_3b_epilogue.inc
+index d3296969a..f873ce153 100644
+--- a/src/kernels/conv_3x3_wheel_alpha_v7_0_3b_epilogue.inc
++++ b/src/kernels/conv_3x3_wheel_alpha_v7_0_3b_epilogue.inc
+@@ -76,7 +76,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: N }
++    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: X }
+     - { .size: 4, .offset: 4,   .value_kind: by_value,      .value_type: i32, .name: C }
+     - { .size: 4, .offset: 8,   .value_kind: by_value,      .value_type: i32, .name: H }
+     - { .size: 4, .offset: 12,  .value_kind: by_value,      .value_type: i32, .name: W }
+diff --git a/src/kernels/conv_3x3_wheel_alpha_v9_0_15_epilogue.inc b/src/kernels/conv_3x3_wheel_alpha_v9_0_15_epilogue.inc
+index a253cc0f9..1582d002c 100644
+--- a/src/kernels/conv_3x3_wheel_alpha_v9_0_15_epilogue.inc
++++ b/src/kernels/conv_3x3_wheel_alpha_v9_0_15_epilogue.inc
+@@ -76,7 +76,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: N }
++    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: X }
+     - { .size: 4, .offset: 4,   .value_kind: by_value,      .value_type: i32, .name: C }
+     - { .size: 4, .offset: 8,   .value_kind: by_value,      .value_type: i32, .name: H }
+     - { .size: 4, .offset: 12,  .value_kind: by_value,      .value_type: i32, .name: W }
+diff --git a/src/kernels/conv_3x3_wheel_alpha_v9_2_7_epilogue.inc b/src/kernels/conv_3x3_wheel_alpha_v9_2_7_epilogue.inc
+index e40ac1f60..78495e024 100644
+--- a/src/kernels/conv_3x3_wheel_alpha_v9_2_7_epilogue.inc
++++ b/src/kernels/conv_3x3_wheel_alpha_v9_2_7_epilogue.inc
+@@ -76,7 +76,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: N }
++    - { .size: 4, .offset: 0,   .value_kind: by_value,      .value_type: i32, .name: X }
+     - { .size: 4, .offset: 4,   .value_kind: by_value,      .value_type: i32, .name: C }
+     - { .size: 4, .offset: 8,   .value_kind: by_value,      .value_type: i32, .name: H }
+     - { .size: 4, .offset: 12,  .value_kind: by_value,      .value_type: i32, .name: W }
+diff --git a/src/kernels/xform_bidirect_winograd_code.inc b/src/kernels/xform_bidirect_winograd_code.inc
+index 724845f49..d03314ef5 100644
+--- a/src/kernels/xform_bidirect_winograd_code.inc
++++ b/src/kernels/xform_bidirect_winograd_code.inc
+@@ -1566,7 +1566,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset:   0, .value_kind: by_value, .value_type: i32, .name: N }
++    - { .size: 4, .offset:   0, .value_kind: by_value, .value_type: i32, .name: X }
+     - { .size: 4, .offset:   4, .value_kind: by_value, .value_type: i32, .name: C }
+     - { .size: 4, .offset:   8, .value_kind: by_value, .value_type: i32, .name: H }
+     - { .size: 4, .offset:  12, .value_kind: by_value, .value_type: i32, .name: W }
+diff --git a/src/kernels/xform_metadata.inc b/src/kernels/xform_metadata.inc
+index 960a9a2d8..83b736bee 100644
+--- a/src/kernels/xform_metadata.inc
++++ b/src/kernels/xform_metadata.inc
+@@ -74,7 +74,7 @@ amdhsa.kernels:
+     .max_flat_workgroup_size: \wg_x
+     .wavefront_size: 64
+     .args:
+-    - { .size: 4, .offset:   0, .value_kind: by_value, .value_type: i32, .name: N }
++    - { .size: 4, .offset:   0, .value_kind: by_value, .value_type: i32, .name: X }
+     - { .size: 4, .offset:   4, .value_kind: by_value, .value_type: i32, .name: C }
+     - { .size: 4, .offset:   8, .value_kind: by_value, .value_type: i32, .name: H }
+     - { .size: 4, .offset:  12, .value_kind: by_value, .value_type: i32, .name: W }
diff --git a/sci-libs/miopen/files/miopen-5.1.3-deprecate-clang-ocl.patch b/sci-libs/miopen/files/miopen-5.1.3-deprecate-clang-ocl.patch
new file mode 100644 (file)
index 0000000..93c66fd
--- /dev/null
@@ -0,0 +1,55 @@
+This is a cherry picked PR on 5.1.3, which replace clang-ocl with clang
+From 98f001dfe61208af04ecf7690023efd772ee7d43 Mon Sep 17 00:00:00 2001
+From: Jehandad Khan <jahandad@gmail.com>
+Date: Tue, 19 Jul 2022 17:24:05 -0500
+Subject: [PATCH] Remove clang-ocl  and replace with clang
+
+---
+ CMakeLists.txt              | 7 +------
+ README.md                   | 1 -
+ src/hipoc/hipoc_program.cpp | 7 ++++++-
+ 3 files changed, 7 insertions(+), 8 deletions(-)
+
+Index: MIOpen-rocm-5.1.3/CMakeLists.txt
+===================================================================
+--- MIOpen-rocm-5.1.3.orig/CMakeLists.txt
++++ MIOpen-rocm-5.1.3/CMakeLists.txt
+@@ -241,7 +241,7 @@ if( MIOPEN_BACKEND STREQUAL "HIP" OR MIO
+     # miopentensile default off
+     set(MIOPEN_USE_MIOPENTENSILE OFF CACHE BOOL "")
+-    find_program(HIP_OC_COMPILER clang-ocl
++    find_program(HIP_OC_COMPILER clang
+         PATH_SUFFIXES bin
+         PATHS
+             /opt/rocm
+Index: MIOpen-rocm-5.1.3/README.md
+===================================================================
+--- MIOpen-rocm-5.1.3.orig/README.md
++++ MIOpen-rocm-5.1.3/README.md
+@@ -14,7 +14,6 @@ MIOpen supports two programming models -
+   * OpenCL - OpenCL libraries and header files
+   * HIP - 
+     * HIP and HCC libraries and header files
+-    * [clang-ocl](https://github.com/RadeonOpenCompute/clang-ocl) -- **required**
+ * [MIOpenGEMM](https://github.com/ROCmSoftwarePlatform/MIOpenGEMM) to enable various functionalities including transposed and dilated convolutions. This is optional on the HIP backend. Users can enable this library using the cmake configuration flag `-DMIOPEN_USE_MIOPENGEMM=On`.
+ * ROCm cmake modules can be installed from [here](https://github.com/RadeonOpenCompute/rocm-cmake)
+ * [Half](http://half.sourceforge.net/) - IEEE 754-based half-precision floating point library
+Index: MIOpen-rocm-5.1.3/src/hipoc/hipoc_program.cpp
+===================================================================
+--- MIOpen-rocm-5.1.3.orig/src/hipoc/hipoc_program.cpp
++++ MIOpen-rocm-5.1.3/src/hipoc/hipoc_program.cpp
+@@ -255,7 +255,12 @@ void HIPOCProgramImpl::BuildCodeObjectIn
+         if(miopen::IsEnabled(MIOPEN_DEBUG_OPENCL_WAVE64_NOWGP{}))
+             params += " -mwavefrontsize64 -mcumode";
+         WriteFile(src, dir->path / filename);
+-        dir->Execute(HIP_OC_COMPILER, params + " " + filename + " -o " + hsaco_file.string());
++        params += " -target amdgcn-amd-amdhsa -x cl -D__AMD__=1  -O3";
++        params += " -cl-kernel-arg-info -cl-denorms-are-zero";
++        params += " -cl-std=CL1.2 -mllvm -amdgpu-early-inline-all";
++        params += " -mllvm -amdgpu-internalize-symbols ";
++        params += " " + filename + " -o " + hsaco_file.string();
++        dir->Execute(HIP_OC_COMPILER, params);
+     }
+     if(!boost::filesystem::exists(hsaco_file))
+         MIOPEN_THROW("Cant find file: " + hsaco_file.string());
diff --git a/sci-libs/miopen/files/miopen-5.1.3-gfx1031.patch b/sci-libs/miopen/files/miopen-5.1.3-gfx1031.patch
new file mode 100644 (file)
index 0000000..de22d66
--- /dev/null
@@ -0,0 +1,375 @@
+Enable gfx1031 support
+======================
+--- MIOpen-rocm-5.1.3/fin/src/include/conv_fin.hpp     2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/fin/src/include/conv_fin.hpp       2022-09-01 18:36:18.630980283 +0800
+@@ -111,6 +111,10 @@ class ConvFin : public Fin
+         {
+             assert(num_cu == 72 || num_cu == 36);
+         }
++        else if(arch == "gfx1031")
++        {
++            assert(num_cu == 40 || num_cu == 20);
++        }
+         else if(arch == "gfx90a")
+         {
+             assert(num_cu == 110);
+Only in MIOpen-rocm-5.1.3: patches
+--- MIOpen-rocm-5.1.3/src/composable_kernel/composable_kernel/include/utility/config.hpp       2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/composable_kernel/composable_kernel/include/utility/config.hpp 2022-09-01 18:36:18.634980274 +0800
+@@ -13,7 +13,7 @@
+ // GPU target
+ // should enable one and only one GPU target
+ #if !(defined(CK_AMD_GPU_GFX803) || defined(CK_AMD_GPU_GFX900) || defined(CK_AMD_GPU_GFX906) || \
+-      defined(CK_AMD_GPU_GFX908) || defined(CK_AMD_GPU_GFX90A) || defined(CK_AMD_GPU_GFX1030))
++      defined(CK_AMD_GPU_GFX908) || defined(CK_AMD_GPU_GFX90A) || defined(CK_AMD_GPU_GFX1030) || defined(CK_AMD_GPU_GFX1031))
+ #error Need to define (only) one GPU target
+ #endif
+@@ -29,7 +29,7 @@
+ #if defined(CK_AMD_GPU_GFX803) || defined(CK_AMD_GPU_GFX900) || defined(CK_AMD_GPU_GFX906) || \
+     defined(CK_AMD_GPU_GFX908) || defined(CK_AMD_GPU_GFX90A)
+ #define CK_BUFFER_RESOURCE_3RD_DWORD 0x00020000
+-#elif defined(CK_AMD_GPU_GFX1030)
++#elif (defined(CK_AMD_GPU_GFX1030) || defined(CK_AMD_GPU_GFX1031))
+ #define CK_BUFFER_RESOURCE_3RD_DWORD 0x31014000
+ #endif
+@@ -37,7 +37,7 @@
+ #if defined(CK_AMD_GPU_GFX803) || defined(CK_AMD_GPU_GFX900)
+ #define CK_USE_AMD_V_MAC_F32
+ #elif defined(CK_AMD_GPU_GFX906) || defined(CK_AMD_GPU_GFX908) || defined(CK_AMD_GPU_GFX90a) || \
+-    defined(CK_AMD_GPU_GFX1030)
++    (defined(CK_AMD_GPU_GFX1030) || defined(CK_AMD_GPU_GFX1031))
+ #define CK_USE_AMD_V_FMAC_F32
+ #define CK_USE_AMD_V_DOT2_F32_F16
+ #define CK_USE_AMD_V_DOT4_I32_I8
+--- MIOpen-rocm-5.1.3/src/include/miopen/solver/ck_utility_common.hpp  2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/include/miopen/solver/ck_utility_common.hpp    2022-09-01 18:36:18.638980266 +0800
+@@ -54,6 +54,7 @@ static inline bool is_ck_supported_hardw
+            StartsWith(handle.GetDeviceName(), "gfx908") ||
+            StartsWith(handle.GetDeviceName(), "gfx90a") ||
+            StartsWith(handle.GetDeviceName(), "gfx1030");
++           StartsWith(handle.GetDeviceName(), "gfx1031");
+ }
+ static inline bool is_support_amd_buffer_atomic_fadd(const std::string& device_name)
+@@ -83,6 +84,8 @@ static inline auto get_ck_common_compile
+         compiler_flag << " -DCK_AMD_GPU_GFX90A";
+     else if(StartsWith(device_name, "gfx1030"))
+         compiler_flag << " -DCK_AMD_GPU_GFX1030";
++    else if(StartsWith(device_name, "gfx1031"))
++        compiler_flag << " -DCK_AMD_GPU_GFX1031";
+     // buffer atomic-fadd
+     compiler_flag << " -DCK_USE_AMD_BUFFER_ATOMIC_FADD="
+--- MIOpen-rocm-5.1.3/src/include/miopen/solver/implicitgemm_util.hpp  2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/include/miopen/solver/implicitgemm_util.hpp    2022-09-01 18:36:18.638980266 +0800
+@@ -469,7 +469,7 @@ static inline bool is_use_amd_buffer_loa
+ {
+ #if WORKAROUND_MIOPEN_ISSUE_557
+     const auto device_name = ctx.GetStream().GetDeviceName();
+-    return !StartsWith(device_name, "gfx1030");
++    return !StartsWith(device_name, "gfx1030") && !StartsWith(device_name, "gfx1031");
+ #else
+     return true;
+ #endif
+@@ -478,7 +478,7 @@ static inline bool is_use_amd_buffer_loa
+ static inline bool is_use_v_fmac_f32(const ConvolutionContext& ctx)
+ {
+     const auto device_name = ctx.GetStream().GetDeviceName();
+-    return StartsWith(device_name, "gfx1030");
++    return StartsWith(device_name, "gfx1030") || StartsWith(device_name, "gfx1031");
+ }
+ static inline bool support_amd_buffer_atomic_fadd(const std::string& device_name)
+@@ -599,7 +599,8 @@ static inline bool IsComposableKernelSup
+            StartsWith(c.GetStream().GetDeviceName(), "gfx906") ||
+            StartsWith(c.GetStream().GetDeviceName(), "gfx908") ||
+            StartsWith(c.GetStream().GetDeviceName(), "gfx90a") ||
+-           StartsWith(c.GetStream().GetDeviceName(), "gfx1030");
++           StartsWith(c.GetStream().GetDeviceName(), "gfx1030")||
++           StartsWith(c.GetStream().GetDeviceName(), "gfx1031");
+ }
+ // greatest common divisor, aka highest common factor
+--- MIOpen-rocm-5.1.3/src/kernels/batchnorm_functions.h        2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/kernels/batchnorm_functions.h  2022-09-01 18:36:18.858979772 +0800
+@@ -159,6 +159,10 @@
+ #define MIO_BN_GFX1030 0
+ #endif
++#ifndef MIO_BN_GFX1031
++#define MIO_BN_GFX1031 0
++#endif
++
+ #define UNUSED __attribute__((__unused__))
+ #if(MIO_BN_VARIANT != 4)
+--- MIOpen-rocm-5.1.3/src/kernels/MIOpenBatchNormActivBwdPerAct.cl     2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/kernels/MIOpenBatchNormActivBwdPerAct.cl       2022-09-01 18:36:18.858979772 +0800
+@@ -34,7 +34,7 @@
+ #endif
+ #define MIOPEN_USE_AMDGCN 0
+-#if defined(__AMDGCN__) && MIO_BN_GFX1030 != 1
++#if defined(__AMDGCN__) && MIO_BN_GFX1030 != 1 && MIO_BN_GFX1031 != 1
+ #undef MIOPEN_USE_AMDGCN
+ #define MIOPEN_USE_AMDGCN 1
+ #endif
+--- MIOpen-rocm-5.1.3/src/kernels/MIOpenBatchNormActivBwdSpatial.cl    2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/kernels/MIOpenBatchNormActivBwdSpatial.cl      2022-09-01 18:36:18.858979772 +0800
+@@ -32,7 +32,7 @@
+ #endif
+ #define MIOPEN_USE_AMDGCN 0
+-#if defined(__AMDGCN__) && MIO_BN_GFX1030 != 1
++#if defined(__AMDGCN__) && MIO_BN_GFX1030 != 1 && MIO_BN_GFX1031 != 1
+ #undef MIOPEN_USE_AMDGCN
+ #define MIOPEN_USE_AMDGCN 1
+ #endif
+--- MIOpen-rocm-5.1.3/src/kernels/MIOpenBatchNormActivFwdTrainSpatial.cl       2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/kernels/MIOpenBatchNormActivFwdTrainSpatial.cl 2022-09-01 18:36:18.858979772 +0800
+@@ -33,7 +33,7 @@
+ #endif
+ #define MIOPEN_USE_AMDGCN 0
+-#if defined(__AMDGCN__) && MIO_BN_GFX1030 != 1
++#if defined(__AMDGCN__) && MIO_BN_GFX1030 != 1 && MIO_BN_GFX1031 != 1
+ #undef MIOPEN_USE_AMDGCN
+ #define MIOPEN_USE_AMDGCN 1
+ #endif
+--- MIOpen-rocm-5.1.3/src/kernels/MIOpenBatchNormBwdSpatial.cl 2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/kernels/MIOpenBatchNormBwdSpatial.cl   2022-09-01 18:36:18.858979772 +0800
+@@ -33,7 +33,7 @@
+ #endif
+ #define MIOPEN_USE_AMDGCN 0
+-#if defined(__AMDGCN__) && MIO_BN_GFX1030 != 1
++#if defined(__AMDGCN__) && MIO_BN_GFX1030 != 1 && MIO_BN_GFX1031 != 1
+ #undef MIOPEN_USE_AMDGCN
+ #define MIOPEN_USE_AMDGCN 1
+ #endif
+--- MIOpen-rocm-5.1.3/src/kernels/MIOpenBatchNormFwdTrainSpatial.cl    2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/kernels/MIOpenBatchNormFwdTrainSpatial.cl      2022-09-01 18:36:18.858979772 +0800
+@@ -33,7 +33,7 @@
+ #endif
+ #define MIOPEN_USE_AMDGCN 0
+-#if defined(__AMDGCN__) && MIO_BN_GFX1030 != 1
++#if defined(__AMDGCN__) && MIO_BN_GFX1030 != 1 && MIO_BN_GFX1031 != 1
+ #undef MIOPEN_USE_AMDGCN
+ #define MIOPEN_USE_AMDGCN 1
+ #endif
+--- MIOpen-rocm-5.1.3/src/md_graph.cpp 2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/md_graph.cpp   2022-09-01 18:36:18.630980283 +0800
+@@ -738,8 +738,8 @@ void FusionMDGraph::InitConv(FusionMDGra
+             add_v21_wino("gfx9", {"gfx900", "gfx906", "gfx908", "gfx90a"}, 1);
+             add_v21_wino("gfx9", {"gfx900", "gfx906", "gfx908", "gfx90a"}, 2);
+-            add_v21_wino("gfx10", {"gfx1011", "gfx1012", "gfx1030"}, 1);
+-            add_v21_wino("gfx10", {"gfx1011", "gfx1012", "gfx1030"}, 2);
++            add_v21_wino("gfx10", {"gfx1011", "gfx1012", "gfx1030", "gfx1031"}, 1);
++            add_v21_wino("gfx10", {"gfx1011", "gfx1012", "gfx1030", "gfx1031"}, 2);
+         }
+     }
+--- MIOpen-rocm-5.1.3/src/ocl/fusionopbiasbnactivocl.cpp       2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/ocl/fusionopbiasbnactivocl.cpp 2022-09-01 18:36:18.634980274 +0800
+@@ -392,7 +392,8 @@ miopenStatus_t BatchNormBwdTrainFusionOp
+            " -DMIO_BN_USESAVED=" + std::to_string(static_cast<int>(true)) +
+            " -DMIO_BN_VARIANT=" + std::to_string(variant) +
+            " -DMIO_BN_CBA_WRITE_INTERMEDIATE=" + std::to_string(0) +
+-           " -DMIO_BN_GFX1030=" + ((handle.GetDeviceName() == "gfx1030") ? "1" : "0");
++           " -DMIO_BN_GFX1030=" + ((handle.GetDeviceName() == "gfx1030") ? "1" : "0") +
++           " -DMIO_BN_GFX1031=" + ((handle.GetDeviceName() == "gfx1031") ? "1" : "0");
+     compile_config += add;
+     MIOPEN_LOG_I2(add);
+@@ -607,7 +608,8 @@ miopenStatus_t BatchNormFwdTrainFusionOp
+            " -DMIO_SAVE_MEAN_VARIANCE=" + (saveBatchStats ? "1" : "0") +
+            " -DMIO_RUNNING_RESULT=" + ((savePopStats) ? "1" : "0") +
+            " -DMIO_BN_VARIANT=" + std::to_string(variant) +
+-           " -DMIO_BN_GFX1030=" + ((handle.GetDeviceName() == "gfx1030") ? "1" : "0");
++           " -DMIO_BN_GFX1030=" + ((handle.GetDeviceName() == "gfx1030") ? "1" : "0") +
++           " -DMIO_BN_GFX1031=" + ((handle.GetDeviceName() == "gfx1031") ? "1" : "0");
+     compile_config += add;
+     MIOPEN_LOG_I2(add);
+--- MIOpen-rocm-5.1.3/src/solver/batchnorm/backward_per_activation.cpp 2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/solver/batchnorm/backward_per_activation.cpp   2022-09-01 18:36:18.638980266 +0800
+@@ -113,6 +113,7 @@ BnBwdTrainingPerActivation::GetSolution(
+             {"MIO_BN_GRP1", ylocalsize},
+             {"MIO_BN_GRP2", zlocalsize},
+             {"MIO_BN_GFX1030", ((handle.GetDeviceName() == "gfx1030") ? "1" : "0")},
++            {"MIO_BN_GFX1031", ((handle.GetDeviceName() == "gfx1031") ? "1" : "0")},
+         };
+         kernel.comp_options = build_params.GenerateFor(kbp::OpenCL{});
+--- MIOpen-rocm-5.1.3/src/solver/batchnorm/backward_spatial_multiple.cpp       2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/solver/batchnorm/backward_spatial_multiple.cpp 2022-09-01 18:36:18.638980266 +0800
+@@ -210,6 +210,7 @@ ConvSolution BnBwdTrainingSpatialMultipl
+             {"MIO_BN_GRP1", ylocalsize},
+             {"MIO_BN_GRP2", zlocalsize},
+             {"MIO_BN_GFX1030", ((handle.GetDeviceName() == "gfx1030") ? "1" : "0")},
++            {"MIO_BN_GFX1031", ((handle.GetDeviceName() == "gfx1031") ? "1" : "0")},
+             {"MIO_LAYOUT_NHWC", static_cast<int>(problem.IsLayoutNHWC())},
+         };
+--- MIOpen-rocm-5.1.3/src/solver/batchnorm/backward_spatial_single.cpp 2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/solver/batchnorm/backward_spatial_single.cpp   2022-09-01 18:36:18.638980266 +0800
+@@ -247,6 +247,7 @@ BnBwdTrainingSpatialSingle::GetSolution(
+             build_params << KernelBuildParameters{
+                 {"MIO_BN_GFX1030", (handle.GetDeviceName() == "gfx1030") ? "1" : "0"},
++                              {"MIO_BN_GFX1031", ((handle.GetDeviceName() == "gfx1031") ? "1" : "0")},
+             };
+             kernel.comp_options = build_params.GenerateFor(kbp::OpenCL{});
+--- MIOpen-rocm-5.1.3/src/solver/batchnorm/forward_inference.cpp       2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/solver/batchnorm/forward_inference.cpp 2022-09-01 18:36:18.638980266 +0800
+@@ -103,6 +103,7 @@ ConvSolution BnFwdInference::GetSolution
+             {"MIO_BN_GRP1", ylocalsize},\r
+             {"MIO_BN_GRP2", zlocalsize},\r
+             {"MIO_BN_GFX1030", ((handle.GetDeviceName() == "gfx1030") ? "1" : "0")},\r
++            {"MIO_BN_GFX1031", ((handle.GetDeviceName() == "gfx1031") ? "1" : "0")},\r
+         };\r
\r
+         kernel.comp_options = build_params.GenerateFor(kbp::OpenCL{});\r
+--- MIOpen-rocm-5.1.3/src/solver/batchnorm/forward_per_activation.cpp  2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/solver/batchnorm/forward_per_activation.cpp    2022-09-01 18:36:18.638980266 +0800
+@@ -105,6 +105,7 @@ BnFwdTrainingPerActivation::GetSolution(
+             {"MIO_BN_GRP1", ylocalsize},
+             {"MIO_BN_GRP2", zlocalsize},
+             {"MIO_BN_GFX1030", ((handle.GetDeviceName() == "gfx1030") ? "1" : "0")},
++            {"MIO_BN_GFX1031", ((handle.GetDeviceName() == "gfx1031") ? "1" : "0")},
+         };
+         auto kernel = KernelInfo{};
+--- MIOpen-rocm-5.1.3/src/solver/batchnorm/forward_spatial_multiple.cpp        2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/solver/batchnorm/forward_spatial_multiple.cpp  2022-09-01 18:36:18.638980266 +0800
+@@ -177,6 +177,7 @@ ConvSolution BnFwdTrainingSpatialMultipl
+             {"MIO_BN_GRP1", ylocalsize},
+             {"MIO_BN_GRP2", zlocalsize},
+             {"MIO_BN_GFX1030", ((handle.GetDeviceName() == "gfx1030") ? "1" : "0")},
++            {"MIO_BN_GFX1031", ((handle.GetDeviceName() == "gfx1031") ? "1" : "0")},
+             {"MIO_LAYOUT_NHWC", static_cast<int>(problem.IsLayoutNHWC())},
+         };
+--- MIOpen-rocm-5.1.3/src/solver/batchnorm/forward_spatial_single.cpp  2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/solver/batchnorm/forward_spatial_single.cpp    2022-09-01 18:36:18.638980266 +0800
+@@ -211,6 +211,7 @@ BnFwdTrainingSpatialSingle::GetSolution(
+             {"MIO_BN_GRP1", ylocalsize},
+             {"MIO_BN_GRP2", zlocalsize},
+             {"MIO_BN_GFX1030", ((handle.GetDeviceName() == "gfx1030") ? "1" : "0")},
++            {"MIO_BN_GFX1031", ((handle.GetDeviceName() == "gfx1031") ? "1" : "0")},
+             {"MIO_LAYOUT_NHWC", static_cast<int>(problem.IsLayoutNHWC())},
+         };
+--- MIOpen-rocm-5.1.3/src/target_properties.cpp        2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/src/target_properties.cpp  2022-09-01 18:36:18.630980283 +0800
+@@ -54,6 +54,7 @@ static std::string GetDeviceNameFromMap(
+         {"Vega10", "gfx900"},
+         {"gfx901", "gfx900"},
+         {"10.3.0 Sienna_Cichlid 18", "gfx1030"},
++        {"10.3.1 Navi_flounder 18", "gfx1031"},
+     };
+     const char* const p_asciz = miopen::GetStringEnv(MIOPEN_DEBUG_ENFORCE_DEVICE{});
+--- MIOpen-rocm-5.1.3/test/CMakeLists.txt      2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/test/CMakeLists.txt        2022-09-01 18:36:19.022979405 +0800
+@@ -38,6 +38,7 @@ option( MIOPEN_TEST_GFX90A "Test on gfx9
+ option( MIOPEN_TEST_GFX900 "Test on Vega10 (gfx900)" OFF )
+ option( MIOPEN_TEST_GFX906 "Test on Vega20 (gfx906)" OFF )
+ option( MIOPEN_TEST_GFX1030 "Test on Navi21 (gfx1030)" OFF )
++option( MIOPEN_TEST_GFX1031 "Test on Navi21 (gfx1031)" OFF )
+ option( MIOPEN_TEST_GPU_XNACK_ENABLED "Test as if XNACK mode is enabled" OFF )
+ option( MIOPEN_TEST_CONV Off)
+ option( MIOPEN_TEST_DEEPBENCH Off)
+@@ -74,7 +75,7 @@ endif()
+ # Also we do not detect GPU when target GPU for testing is specified explicitly.
+ set(MIOPEN_TEST_GPU_DETECTION_FAILED FALSE)
+ set(MIOPEN_NO_GPU FALSE)
+-if(NOT (MIOPEN_TEST_GFX900 OR MIOPEN_TEST_GFX906 OR MIOPEN_TEST_GFX908 OR MIOPEN_TEST_GFX90A OR MIOPEN_TEST_GFX1030 OR MIOPEN_TEST_HIP_NOGPU))
++if(NOT (MIOPEN_TEST_GFX900 OR MIOPEN_TEST_GFX906 OR MIOPEN_TEST_GFX908 OR MIOPEN_TEST_GFX90A OR MIOPEN_TEST_GFX1030 OR MIOPEN_TEST_GFX1031 OR MIOPEN_TEST_HIP_NOGPU))
+     find_program(ROCMINFO
+         NAMES rocminfo
+         PATHS
+@@ -96,6 +97,8 @@ if(NOT (MIOPEN_TEST_GFX900 OR MIOPEN_TES
+         elseif (NOT ROCMINFO_EXIT_STATUS EQUAL 0)
+             message(WARNING "ROCMINFO FAILED, GPU TYPE UNKNOWN. Manually set respective MIOPEN_TEST_GFX* CMake variable to specify target GPU for testing.")
+             set(MIOPEN_TEST_GPU_DETECTION_FAILED TRUE)
++        elseif(ROCMINFO_OUTPUT MATCHES "gfx1031")
++            set(MIOPEN_TEST_GFX1031 ON)
+         elseif(ROCMINFO_OUTPUT MATCHES "gfx1030")
+             set(MIOPEN_TEST_GFX1030 ON)
+         elseif(ROCMINFO_OUTPUT MATCHES "gfx900")
+@@ -125,6 +128,7 @@ message(STATUS "MIOPEN_TEST_GFX906 ${MIO
+ message(STATUS "MIOPEN_TEST_GFX908 ${MIOPEN_TEST_GFX908}")
+ message(STATUS "MIOPEN_TEST_GFX90A ${MIOPEN_TEST_GFX90A}")
+ message(STATUS "MIOPEN_TEST_GFX1030 ${MIOPEN_TEST_GFX1030}")
++message(STATUS "MIOPEN_TEST_GFX1031 ${MIOPEN_TEST_GFX1031}")
+ message(STATUS "MIOPEN_TEST_GPU_XNACK_ENABLED ${MIOPEN_TEST_GPU_XNACK_ENABLED}")
+ message(STATUS "MIOPEN_TEST_GPU_DETECTION_FAILED ${MIOPEN_TEST_GPU_DETECTION_FAILED}")
+@@ -167,10 +171,10 @@ endmacro()
+ set_var_to_condition(WORKAROUND_ISSUE_1187_DEFAULT MIOPEN_TEST_GFX90A AND MIOPEN_TEST_FLOAT)
+ option( WORKAROUND_ISSUE_1187 "" ${WORKAROUND_ISSUE_1187_DEFAULT})
+-set_var_to_condition(WORKAROUND_ISSUE_1148_DEFAULT MIOPEN_TEST_GFX1030 AND MIOPEN_TEST_FLOAT)
++set_var_to_condition(WORKAROUND_ISSUE_1148_DEFAULT MIOPEN_TEST_GFX1030 OR MIOPEN_TEST_GFX1031 AND MIOPEN_TEST_FLOAT)
+ option( WORKAROUND_ISSUE_1148 "" ${WORKAROUND_ISSUE_1148_DEFAULT})
+-set_var_to_condition(WORKAROUND_ISSUE_1334_DEFAULT MIOPEN_TEST_GFX1030 AND MIOPEN_TEST_FLOAT)
++set_var_to_condition(WORKAROUND_ISSUE_1334_DEFAULT MIOPEN_TEST_GFX1030 OR MIOPEN_TEST_GFX1031 AND MIOPEN_TEST_FLOAT)
+ option( WORKAROUND_ISSUE_1334 "" ${WORKAROUND_ISSUE_1334_DEFAULT})
+ if(NOT MIOPEN_TEST_MIOTENSILE)
+@@ -216,7 +220,7 @@ if (MIOPEN_NO_GPU)
+             test_pooling3d test_perfdb)
+ endif()
+-if(MIOPEN_TEST_GFX1030)
++if(MIOPEN_TEST_GFX1030 OR MIOPEN_TEST_GFX1031)
+     if(WORKAROUND_ISSUE_1053 AND MIOPEN_TEST_ALL)
+         list(APPEND SKIP_TESTS test_lrn_test)
+     endif()
+@@ -439,7 +443,7 @@ endfunction()
+ #   If nothing is specified, the default value is taken.
+ #   Default: FLOAT_ENABLED HALF_DISABLED BF16_DISABLED INT8_DISABLED
+ #
+-# GPU types: GFX900, GFX906, GFX908, GFX90A, GFX1030
++# GPU types: GFX900, GFX906, GFX908, GFX90A, GFX1030, GFX1031
+ #   The option can be enabled or disabled by using '_ENABLED' and '_DISABLED' suffix.
+ #   If nothing is specified, the default value is taken.
+ #   Default: GFX900_ENABLED, GFX906_ENABLED, GFX908_ENABLED, GFX90A_ENABLED, GFX1030_DISABLED
+@@ -571,7 +575,7 @@ function(add_custom_test NAME)
+         set_tests_properties(${NAME} PROPERTIES RUN_SERIAL On)
+     endif()
+-    if(  (is_gfx900_check OR is_gfx906_check OR is_gfx908_check OR is_gfx1030_check OR is_gfx90a_check)
++    if(  (is_gfx900_check OR is_gfx906_check OR is_gfx908_check OR is_gfx1030_check OR is_gfx1031_check OR is_gfx90a_check)
+      AND is_full_check
+      AND is_xnack_on_check
+      AND (is_miotensile_check AND is_mlir_check)
+--- MIOpen-rocm-5.1.3/test/handle_test.cpp     2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/test/handle_test.cpp       2022-09-01 18:36:19.018979413 +0800
+@@ -234,7 +234,7 @@ void test_warnings(kernel_type_t kern_ty
+ void test_arch_name()
+ {
+     auto&& h        = get_handle();
+-    auto known_arch = {"gfx908", "gfx90a", "gfx906", "gfx900", "gfx803", "gfx1030"};
++    auto known_arch = {"gfx908", "gfx90a", "gfx906", "gfx900", "gfx803", "gfx1030", "gfx1031"};
+     auto this_arch  = h.GetDeviceName();
+     EXPECT(std::any_of(
+         known_arch.begin(), known_arch.end(), [&](std::string arch) { return arch == this_arch; }));
+--- MIOpen-rocm-5.1.3/test/mdgraph.cpp 2022-05-08 14:08:05.000000000 +0800
++++ gfx1031/test/mdgraph.cpp   2022-09-01 18:36:19.022979405 +0800
+@@ -222,7 +222,7 @@ struct mdgraph_driver : test_driver
+         auto target    = h.GetTargetProperties();
+         auto wino_supported_arch = {
+-            "gfx1030", "gfx1012", "gfx1011", "gfx90a", "gfx908", "gfx906", "gfx900", "gfx803"};
++            "gfx1030", "gfx1031","gfx1012", "gfx1011", "gfx90a", "gfx908", "gfx906", "gfx900", "gfx803"};
+         auto is_wino_support = !xnack_enabled &&
+                                !miopen::IsDisabled(MIOPEN_DEBUG_GCN_ASM_KERNELS{}) &&
diff --git a/sci-libs/miopen/files/miopen-5.1.3-include-array.patch b/sci-libs/miopen/files/miopen-5.1.3-include-array.patch
new file mode 100644 (file)
index 0000000..fc6a36d
--- /dev/null
@@ -0,0 +1,12 @@
+This fixes compile error upon gcc-12 libstdc++
+index 1cfb2a72c..0f4feb406 100644
+--- a/test/sequences.cpp
++++ b/test/sequences.cpp
+@@ -25,6 +25,7 @@
+  *******************************************************************************/
+ #include "test.hpp"
+ #include <miopen/sequences.hpp>
++#include <array>
+ namespace miopen {
+ namespace seq {
diff --git a/sci-libs/miopen/files/miopen-5.1.3-no-strip.patch b/sci-libs/miopen/files/miopen-5.1.3-no-strip.patch
new file mode 100644 (file)
index 0000000..0d1d429
--- /dev/null
@@ -0,0 +1,17 @@
+Don't strip for release. Let portage handle stripping.
+Index: MIOpen-rocm-5.1.3/CMakeLists.txt
+===================================================================
+--- MIOpen-rocm-5.1.3.orig/CMakeLists.txt
++++ MIOpen-rocm-5.1.3/CMakeLists.txt
+@@ -78,11 +78,6 @@ option( BUILD_DEV "Build for development
+ option(MIOPEN_ENABLE_FIN "Enable the fin driver for MIOpen"  OFF)
+-# Strip symbols for release
+-if(NOT WIN32 AND NOT APPLE)
+-    set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
+-    set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
+-endif()
+ rocm_setup_version(VERSION 2.16.0)
diff --git a/sci-libs/miopen/miopen-5.7.1.ebuild b/sci-libs/miopen/miopen-5.7.1.ebuild
new file mode 100644 (file)
index 0000000..edf4307
--- /dev/null
@@ -0,0 +1,105 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+ROCM_VERSION=${PV}
+
+inherit cmake flag-o-matic llvm rocm
+
+LLVM_MAX_SLOT=18
+
+DESCRIPTION="AMD's Machine Intelligence Library"
+HOMEPAGE="https://github.com/ROCmSoftwarePlatform/MIOpen"
+SRC_URI="https://github.com/ROCm/MIOpen/archive/refs/tags/rocm-${PV}.tar.gz -> MIOpen-${PV}.tar.gz"
+
+LICENSE="MIT"
+KEYWORDS="~amd64"
+SLOT="0/$(ver_cut 1-2)"
+
+IUSE="debug test"
+RESTRICT="!test? ( test )"
+
+RDEPEND="
+       >=dev-util/hip-5.1.3
+       >=dev-db/sqlite-3.17
+       sci-libs/rocBLAS:${SLOT}[${ROCM_USEDEP}]
+       >=dev-libs/boost-1.72
+"
+
+DEPEND="${RDEPEND}"
+
+BDEPEND="dev-libs/half:0/1
+       dev-build/rocm-cmake
+"
+
+S="${WORKDIR}/MIOpen-rocm-${PV}"
+
+PATCHES=(
+       "${FILESDIR}/${PN}-4.2.0-gcc11-numeric_limits.patch"
+       "${FILESDIR}/${PN}-4.3.0-fix-interface-include-in-HIP_COMPILER_FLAGS.patch"
+       "${FILESDIR}/${PN}-4.3.0-enable-test.patch"
+       "${FILESDIR}/${PN}-5.1.3-no-strip.patch"
+       "${FILESDIR}/${PN}-5.1.3-include-array.patch"
+)
+
+src_prepare() {
+       cmake_src_prepare
+
+       sed -e "s:/opt/rocm/llvm:$(get_llvm_prefix ${LLVM_MAX_SLOT}) NO_DEFAULT_PATH:" \
+               -e "s:/opt/rocm/hip:$(hipconfig -p) NO_DEFAULT_PATH:" \
+               -e '/set( MIOPEN_INSTALL_DIR/s:miopen:${CMAKE_INSTALL_PREFIX}:' \
+               -e '/MIOPEN_TIDY_ERRORS ALL/d' \
+               -i CMakeLists.txt || die
+
+       sed -e "/rocm_install_symlink_subdir(\${MIOPEN_INSTALL_DIR})/d" -i src/CMakeLists.txt || die
+       sed -e "/add_test/s:--build \${CMAKE_CURRENT_BINARY_DIR}:--build ${BUILD_DIR}:" -i test/CMakeLists.txt || die
+
+       sed -e "s:\${AMD_DEVICE_LIBS_PREFIX}/lib:${EPREFIX}/usr/lib/amdgcn/bitcode:" -i cmake/hip-config.cmake || die
+
+       # This plus avoid-metadata-error-for-vanilla-clang.patch fix bug mentioned
+       # in https://github.com/ROCmSoftwarePlatform/MIOpen/issues/1731
+       find src/kernels -name "*.s" -exec \
+               sed -e "s/.name: n /.name: x /g" -e "s/.name: y /.name: z /g" \
+                       -e "s/.name: y,/.name: z,/g" -i {} \; || die
+}
+
+src_configure() {
+       if ! use debug; then
+               append-cflags "-DNDEBUG"
+               append-cxxflags "-DNDEBUG"
+               CMAKE_BUILD_TYPE="Release"
+       else
+               CMAKE_BUILD_TYPE="Debug"
+       fi
+
+       local mycmakeargs=(
+               -DCMAKE_SKIP_RPATH=ON
+               -DAMDGPU_TARGETS="$(get_amdgpu_flags)"
+               -DCMAKE_INSTALL_PREFIX="${EPREFIX}/usr"
+               -DMIOPEN_BACKEND=HIP
+               -DBoost_USE_STATIC_LIBS=OFF
+               -DMIOPEN_USE_MLIR=OFF
+               -DMIOPEN_ENABLE_AI_KERNEL_TUNING=OFF
+               -DBUILD_TESTS=$(usex test ON OFF)
+               -DMIOPEN_TEST_ALL=$(usex test ON OFF)
+       )
+
+       if use test; then
+               for gpu_target in ${AMDGPU_TARGETS}; do
+                       mycmakeargs+=( -DMIOPEN_TEST_${gpu_target^^}=ON )
+               done
+       fi
+
+       addpredict /dev/kfd
+       addpredict /dev/dri/
+       append-cxxflags "--rocm-path=$(hipconfig -R)"
+       append-cxxflags "--hip-device-lib-path=${EPREFIX}/usr/lib/amdgcn/bitcode"
+       CXX="$(get_llvm_prefix ${LLVM_MAX_SLOT})/bin/clang++" cmake_src_configure
+}
+
+src_test() {
+       check_amdgpu
+       export LD_LIBRARY_PATH="${BUILD_DIR}"/lib
+       MAKEOPTS="-j1" cmake_src_test
+}
diff --git a/sys-apps/accountsservice/Manifest b/sys-apps/accountsservice/Manifest
new file mode 100644 (file)
index 0000000..1356aa0
--- /dev/null
@@ -0,0 +1,3 @@
+AUX accountsservice-22.04.62-gentoo-system-users.patch 1318 BLAKE2B 69c74ad620cebd6864efff7ad87401a72ea5f644a773a682653b45584e34755aaf12a0e79ba816c990b0af2784d01fec5e8b657699ecfc7c38343330a36fda57 SHA512 a85a6ca785a3863d96eae39bc3eee5fe89bedd0bdae40cd6bc2e077bb88f72d73d0be63dcf0e0a788f0f5d69ed39801c9ede623afe8ed08c94372314b1fddd09
+DIST accountsservice-22.08.8.tar.xz 102672 BLAKE2B 7c9436d3845fc1883772b434c4f9e2fba934d17e6d4452a6be65e1d790a23b331eaaa64b0e6eff6fefe79587a40cf1749a0f3de09f323b10740046bd9d145c9d SHA512 2ca3ceb1b44338d9924b86788256d4eef7ec10e0c2197bfb8cc6c31ae224fab3051f03cb406a526f90057684965bef4ba0f2cc01b26198ec1fc6baec36ad3ff8
+EBUILD accountsservice-22.08.8.ebuild 2022 BLAKE2B 8e02410cf36c32b7e3356a3433e7161b7200a6205c0e32ff96f6570dcd502c2ab1fd27481f811231fa1e9120e5c4fdcad55799d0488fad282f786f57edfd9947 SHA512 9d013241850e982093cb516b61c673d4528a70069b1d9898846f58df46fee19e3b97cc12cbf9f2422ed0c13bfedf0176db6ffa5a2be8e060ab5a36f69477b6fb
diff --git a/sys-apps/accountsservice/accountsservice-22.08.8.ebuild b/sys-apps/accountsservice/accountsservice-22.08.8.ebuild
new file mode 100644 (file)
index 0000000..044591f
--- /dev/null
@@ -0,0 +1,86 @@
+# Copyright 2011-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+PYTHON_COMPAT=( python3_{8..10} )
+inherit meson python-any-r1 systemd
+
+DESCRIPTION="D-Bus interfaces for querying and manipulating user account information"
+HOMEPAGE="https://www.freedesktop.org/wiki/Software/AccountsService/"
+SRC_URI="https://www.freedesktop.org/software/${PN}/${P}.tar.xz"
+
+LICENSE="GPL-3+"
+SLOT="0"
+KEYWORDS="~alpha amd64 arm arm64 ~ia64 ~loong ppc ppc64 ~riscv ~sparc x86"
+
+IUSE="doc elogind gtk-doc +introspection selinux systemd test"
+RESTRICT="!test? ( test )"
+#REQUIRED_USE="^^ ( elogind systemd )"
+
+CDEPEND="
+       >=dev-libs/glib-2.63.5:2
+       sys-auth/polkit
+       virtual/libcrypt:=
+       elogind? ( >=sys-auth/elogind-229.4 )
+       introspection? ( >=dev-libs/gobject-introspection-0.9.12:= )
+       systemd? ( >=sys-apps/systemd-186:0= )
+"
+DEPEND="${CDEPEND}"
+BDEPEND="
+       dev-libs/libxslt
+       dev-util/gdbus-codegen
+       sys-devel/gettext
+       virtual/pkgconfig
+       doc? (
+               app-text/docbook-xml-dtd:4.1.2
+               app-text/xmlto
+       )
+       gtk-doc? (
+               dev-util/gtk-doc
+               app-text/docbook-xml-dtd:4.3
+       )
+       test? (
+               $(python_gen_any_dep '
+                       dev-python/python-dbusmock[${PYTHON_USEDEP}]
+               ')
+       )
+"
+RDEPEND="${CDEPEND}
+       selinux? ( sec-policy/selinux-accountsd )
+"
+
+PATCHES=(
+       "${FILESDIR}"/${PN}-22.04.62-gentoo-system-users.patch
+)
+
+python_check_deps() {
+       if use test; then
+               has_version "dev-python/python-dbusmock[${PYTHON_USEDEP}]"
+       fi
+}
+
+src_configure() {
+       local emesonargs=(
+               --localstatedir="${EPREFIX}/var"
+               -Dsystemdsystemunitdir="$(systemd_get_systemunitdir)"
+               -Dadmin_group="wheel"
+               $(meson_use elogind)
+               $(meson_use introspection)
+               $(meson_use doc docbook)
+               $(meson_use gtk-doc gtk_doc)
+               -Dvapi=false
+       )
+       meson_src_configure
+}
+
+src_install() {
+       meson_src_install
+
+       # https://gitlab.freedesktop.org/accountsservice/accountsservice/-/issues/90
+       if use doc; then
+               mv "${ED}/usr/share/doc/${PN}" "${ED}/usr/share/doc/${PF}" || die
+       fi
+
+       # This directories are created at runtime when needed
+       rm -r "${ED}"/var/lib || die
+}
diff --git a/sys-apps/accountsservice/files/accountsservice-22.04.62-gentoo-system-users.patch b/sys-apps/accountsservice/files/accountsservice-22.04.62-gentoo-system-users.patch
new file mode 100644 (file)
index 0000000..d65fa2f
--- /dev/null
@@ -0,0 +1,58 @@
+From 0db673b94a6031640ae5faa3b79c4a1fea078350 Mon Sep 17 00:00:00 2001
+From: Matt Turner <mattst88@gmail.com>
+Date: Sun, 30 Jan 2022 12:00:09 -0800
+Subject: [PATCH] Add more users
+
+---
+ src/user-classify.c | 35 ++++++++++++++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/src/user-classify.c b/src/user-classify.c
+index 9224905..70f1877 100644
+--- a/src/user-classify.c
++++ b/src/user-classify.c
+@@ -52,7 +52,40 @@ static const char *default_excludes[] = {
+         "at",
+         "gdm",
+         "gnome-initial-setup",
+-        "git"
++        "git",
++        /* Additional Gentoo system users with non-trivial login shell */
++        "amanda",
++        "backuppc",
++        "drqueue",
++        "firebird",
++        "flexlm",
++        "foldingathome",
++        "geneweb",
++        "gnump3d",
++        "hacluster",
++        "hg",
++        "hsqldb",
++        "infinote",
++        "jffnms",
++        "klive",
++        "mailman",
++        "mpd",
++        "mythtv",
++        "nagios",
++        "nx",
++        "oneadmin",
++        "openvpn",
++        "p2p",
++        "phxd",
++        "resin",
++        "rplayd",
++        "scponly",
++        "secoff",
++        "tinyproxy",
++        "ttrssd",
++        "vboxguest",
++        "vdr",
++        "vdradmin",
+ };
+ static gboolean
+-- 
+2.34.1
+
diff --git a/sys-fs/eudev/Manifest b/sys-fs/eudev/Manifest
new file mode 100644 (file)
index 0000000..5b72080
--- /dev/null
@@ -0,0 +1,4 @@
+AUX 40-gentoo.rules 167 BLAKE2B 07116c6e5aab7de9fa8a88c6cdd9ad76a09d797d6f7bc3d0535c93ccf83486bbdae8f68d682714576b072a174df070505cce9c6f4b729e91a6f61ed89da72e8e SHA512 92e2be610839432f46cefab4d128825199dc9f2c5ef33119f9ff84dfe635ef56a4f7aaed64ba52ea2798868b00c3a1b7955caa33219aa298c6a2b8290181f94b
+AUX udev-postmount 1208 BLAKE2B bcfbaee26ea666304091092deabcc068c533c7707252917a0d8617812f26744c0454f10f5f829031f8668a345c35034ec68396cbf07792a4a83a87e3816001bb SHA512 8ef1b911843ab13acb1c1b9b7a0a5cd76659f395c3db9e579429556f23eacebb414507dc0231e2455e7589bc70054fa1e6b6dd93dd833f7101c0da0597aabf88
+DIST eudev-3.2.11.tar.gz 2254373 BLAKE2B cfa6235d6509b751fde93ff2b0961b93c3741458e561a7ad9b07b49a57779627532cff25ad3519e5f79320854fcedfcdc23642ef542505cebcd6b2803067389a SHA512 17b328365913af3e434abe667dd0498c3702a41c6cb66f3793ca2c195b05ac06397b0a401077f81df7dd25193e4eeea13657a221ca6cb3d237c4d91e31e30b33
+EBUILD eudev-3.2.11-r4.ebuild 7146 BLAKE2B b4961871e468c9f2f708b24be8f40f59ce54c0d9de8b14df833cae7764689c2c991b1fed806aaa1c8991f3c8d145ef7dd692eae7140601d3908f7dab1ccbd8a0 SHA512 75484b41d701334673c86fb4fc1066678d0ad9140aea68ce76febda8d4edc7df61af620656be093d6971640bab515670798a4212c6cac19b1e4b7fc7dd516674
diff --git a/sys-fs/eudev/eudev-3.2.11-r4.ebuild b/sys-fs/eudev/eudev-3.2.11-r4.ebuild
new file mode 100644 (file)
index 0000000..1427c56
--- /dev/null
@@ -0,0 +1,251 @@
+# Copyright 1999-2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+KV_MIN=2.6.39
+
+inherit autotools linux-info multilib-minimal toolchain-funcs
+
+if [[ ${PV} = 9999* ]]; then
+       EGIT_REPO_URI="https://github.com/eudev-project/eudev.git"
+       inherit git-r3
+else
+       SRC_URI="https://github.com/eudev-project/eudev/archive/refs/tags/v${PV}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="~alpha amd64 arm arm64 hppa ~ia64 ~m68k ~mips ppc ppc64 ~riscv ~s390 sparc x86"
+fi
+
+DESCRIPTION="Linux dynamic and persistent device naming support (aka userspace devfs)"
+HOMEPAGE="https://github.com/gentoo/eudev"
+
+LICENSE="LGPL-2.1 MIT GPL-2"
+SLOT="0"
+IUSE="+kmod introspection rule-generator selinux static-libs test"
+RESTRICT="!test? ( test )"
+
+DEPEND=">=sys-apps/util-linux-2.20
+       >=sys-kernel/linux-headers-${KV_MIN}
+       virtual/libcrypt:=
+       introspection? ( >=dev-libs/gobject-introspection-1.38 )
+       kmod? ( >=sys-apps/kmod-16 )
+       selinux? ( >=sys-libs/libselinux-2.1.9 )
+       !sys-apps/gentoo-systemd-integration
+       !sys-apps/systemd"
+RDEPEND="${DEPEND}
+       acct-group/input
+       acct-group/kvm
+       acct-group/render
+       acct-group/audio
+       acct-group/cdrom
+       acct-group/dialout
+       acct-group/disk
+       acct-group/floppy
+       acct-group/input
+       acct-group/kmem
+       acct-group/kvm
+       acct-group/lp
+       acct-group/render
+       acct-group/sgx
+       acct-group/tape
+       acct-group/tty
+       acct-group/usb
+       acct-group/video
+       !sys-apps/systemd-utils[udev]
+       !sys-fs/udev
+       !sys-apps/systemd
+       !sys-apps/hwids[udev]"
+BDEPEND="dev-util/gperf
+       virtual/os-headers
+       virtual/pkgconfig
+       >=sys-devel/make-3.82-r4
+       test? ( app-text/tree dev-lang/perl )"
+PDEPEND=">=sys-fs/udev-init-scripts-26"
+
+MULTILIB_WRAPPED_HEADERS=(
+       /usr/include/udev.h
+)
+
+pkg_pretend() {
+       ewarn
+       ewarn "As of 2013-01-29, ${P} provides the new interface renaming functionality,"
+       ewarn "as described in the URL below:"
+       ewarn "https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames"
+       ewarn
+       ewarn "This functionality is enabled BY DEFAULT because eudev has no means of synchronizing"
+       ewarn "between the default or user-modified choice of sys-fs/udev.  If you wish to disable"
+       ewarn "this new iface naming, please be sure that /etc/udev/rules.d/80-net-name-slot.rules"
+       ewarn "exists: touch /etc/udev/rules.d/80-net-name-slot.rules"
+       ewarn
+}
+
+pkg_setup() {
+       CONFIG_CHECK="~BLK_DEV_BSG ~DEVTMPFS ~!IDE ~INOTIFY_USER ~!SYSFS_DEPRECATED ~!SYSFS_DEPRECATED_V2 ~SIGNALFD ~EPOLL ~FHANDLE ~NET ~UNIX"
+       linux-info_pkg_setup
+       get_running_version
+
+       # These are required kernel options, but we don't error out on them
+       # because you can build under one kernel and run under another.
+       if kernel_is lt ${KV_MIN//./ }; then
+               ewarn
+               ewarn "Your current running kernel version ${KV_FULL} is too old to run ${P}."
+               ewarn "Make sure to run udev under kernel version ${KV_MIN} or above."
+               ewarn
+       fi
+}
+
+src_prepare() {
+       # change rules back to group uucp instead of dialout for now
+       sed -e 's/GROUP="dialout"/GROUP="uucp"/' -i rules/*.rules \
+               || die "failed to change group dialout to uucp"
+
+       default
+       eautoreconf
+}
+
+multilib_src_configure() {
+       # bug #463846
+       tc-export CC
+       # bug #502950
+       export cc_cv_CFLAGS__flto=no
+
+       # Keep sorted by ./configure --help and only pass --disable flags
+       # when *required* to avoid external deps or unnecessary compile
+       local econf_args
+       econf_args=(
+               ac_cv_search_cap_init=
+               ac_cv_header_sys_capability_h=yes
+               DBUS_CFLAGS=' '
+               DBUS_LIBS=' '
+               --with-rootprefix=
+               --with-rootrundir=/run
+               --exec-prefix="${EPREFIX}"
+               --bindir="${EPREFIX}"/bin
+               --includedir="${EPREFIX}"/usr/include
+               --libdir="${EPREFIX}"/usr/$(get_libdir)
+               --with-rootlibexecdir="${EPREFIX}"/lib/udev
+               --enable-split-usr
+               --enable-manpages
+       )
+
+       # Only build libudev for non-native_abi, and only install it to libdir,
+       # that means all options only apply to native_abi
+       if multilib_is_native_abi; then
+               econf_args+=(
+                       --with-rootlibdir="${EPREFIX}"/$(get_libdir)
+                       $(use_enable introspection)
+                       $(use_enable kmod)
+                       $(use_enable static-libs static)
+                       $(use_enable selinux)
+                       $(use_enable rule-generator)
+               )
+       else
+               econf_args+=(
+                       --disable-static
+                       --disable-introspection
+                       --disable-kmod
+                       --disable-selinux
+                       --disable-rule-generator
+                       --disable-hwdb
+               )
+       fi
+
+       ECONF_SOURCE="${S}" econf "${econf_args[@]}"
+}
+
+multilib_src_compile() {
+       if multilib_is_native_abi; then
+               emake
+       else
+               emake -C src/shared
+               emake -C src/libudev
+       fi
+}
+
+multilib_src_test() {
+       # make sandbox get out of the way
+       # these are safe because there is a fake root filesystem put in place,
+       # but sandbox seems to evaluate the paths of the test i/o instead of the
+       # paths of the actual i/o that results.
+       # also only test for native abi
+       if multilib_is_native_abi; then
+               addread /sys
+               addwrite /dev
+               addwrite /run
+
+               default_src_test
+       fi
+}
+
+multilib_src_install() {
+       if multilib_is_native_abi; then
+               emake DESTDIR="${D}" install
+       else
+               emake -C src/libudev DESTDIR="${D}" install
+       fi
+}
+
+multilib_src_install_all() {
+       find "${ED}" -name '*.la' -delete || die
+
+       insinto /lib/udev/rules.d
+       doins "${FILESDIR}"/40-gentoo.rules
+
+       use rule-generator && doinitd "${FILESDIR}"/udev-postmount
+}
+
+pkg_postinst() {
+       mkdir -p "${EROOT}"/run
+
+       # "losetup -f" is confused if there is an empty /dev/loop/, Bug #338766
+       # So try to remove it here (will only work if empty).
+       rmdir "${EROOT}"/dev/loop 2>/dev/null
+       if [[ -d ${EROOT}/dev/loop ]]; then
+               ewarn "Please make sure your remove /dev/loop,"
+               ewarn "else losetup may be confused when looking for unused devices."
+       fi
+
+       # REPLACING_VERSIONS should only ever have zero or 1 values but in case it doesn't,
+       # process it as a list.  We only care about the zero case (new install) or the case where
+       # the same version is being re-emerged.  If there is a second version, allow it to abort.
+       local rv rvres=doitnew
+       for rv in ${REPLACING_VERSIONS} ; do
+               if [[ ${rvres} == doit* ]]; then
+                       if [[ ${rv%-r*} == ${PV} ]]; then
+                               rvres=doit
+                       else
+                               rvres=${rv}
+                       fi
+               fi
+       done
+
+       if has_version 'sys-apps/hwids[udev]'; then
+               udevadm hwdb --update --root="${ROOT}"
+
+               # https://cgit.freedesktop.org/systemd/systemd/commit/?id=1fab57c209035f7e66198343074e9cee06718bda
+               # reload database after it has be rebuilt, but only if we are not upgrading
+               # also pass if we are -9999 since who knows what hwdb related changes there might be
+               if [[ ${rvres} == doit* ]] && [[ -z ${ROOT} ]] && [[ ${PV} != "9999" ]]; then
+                       udevadm control --reload
+               fi
+       fi
+
+       if [[ ${rvres} != doitnew ]]; then
+               ewarn
+               ewarn "You need to restart eudev as soon as possible to make the"
+               ewarn "upgrade go into effect:"
+               ewarn "\t/etc/init.d/udev --nodeps restart"
+       fi
+
+       if use rule-generator && \
+       [[ -x $(type -P rc-update) ]] && rc-update show | grep udev-postmount | grep -qsv 'boot\|default\|sysinit'; then
+               ewarn
+               ewarn "Please add the udev-postmount init script to your default runlevel"
+               ewarn "to ensure the legacy rule-generator functionality works as reliably"
+               ewarn "as possible."
+               ewarn "\trc-update add udev-postmount default"
+       fi
+
+       elog
+       elog "For more information on eudev on Gentoo, writing udev rules, and"
+       elog "fixing known issues visit: https://wiki.gentoo.org/wiki/Eudev"
+}
diff --git a/sys-fs/eudev/files/40-gentoo.rules b/sys-fs/eudev/files/40-gentoo.rules
new file mode 100644 (file)
index 0000000..6b96bd0
--- /dev/null
@@ -0,0 +1,3 @@
+# Gentoo specific groups
+ACTION=="add", SUBSYSTEM=="block", KERNEL=="fd[0-9]", GROUP="floppy"
+ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", GROUP="usb"
diff --git a/sys-fs/eudev/files/udev-postmount b/sys-fs/eudev/files/udev-postmount
new file mode 100644 (file)
index 0000000..f1f94f4
--- /dev/null
@@ -0,0 +1,55 @@
+#!/sbin/openrc-run
+# Copyright 1999-2013 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+depend()
+{
+       need localmount
+       keyword -vserver -lxc
+}
+
+dir_writeable()
+{
+        touch "$1"/.test.$$ 2>/dev/null && rm "$1"/.test.$$
+}
+
+# store persistent-rules that got created while booting
+# when / was still read-only
+store_persistent_rules()
+{
+       # create /etc/udev/rules.d if it does not exist and /etc/udev is writable
+       [ -d /etc/udev/rules.d ] || \
+               dir_writeable /etc/udev && \
+               mkdir -p /etc/udev/rules.d
+
+       # only continue if rules-directory is writable
+       dir_writeable /etc/udev/rules.d || return 0
+
+       local file dest
+       for file in /run/udev/tmp-rules--*; do
+               dest=${file##*tmp-rules--}
+               [ "$dest" = '*' ] && break
+               type=${dest##70-persistent-}
+               type=${type%%.rules}
+               ebegin "Saving udev persistent ${type} rules to /etc/udev/rules.d"
+               cat "$file" >> /etc/udev/rules.d/"$dest" && rm -f "$file"
+               eend $? "Failed moving persistent rules!"
+       done
+}
+
+start()
+{
+       # check if this system uses udev
+       [ -d /run/udev ] || return 0
+
+       # store persistent-rules that got created while booting
+       # when / was still read-only
+       store_persistent_rules
+}
+
+stop()
+{
+       return 0
+}
+
+# vim:ts=4
diff --git a/sys-kernel/gentooAI-sources/Manifest b/sys-kernel/gentooAI-sources/Manifest
new file mode 100644 (file)
index 0000000..f9c5f00
--- /dev/null
@@ -0,0 +1,10 @@
+AUX patch.6.13.3 241035 BLAKE2B 4d34c2bc7139941e5e99948ece97b22614a3ead17cbc2b9e40aebbde15c796988f86e15959cc280fe2ae9bdac4edf42a67f21ea7e660d8c985702167d76f5120 SHA512 25587af6dae2a155c89a0deae2b9db9cf1b10cf7e2b6bb704edd9e55b5bce05e24aad7a7943c361861af0048fc6e82b7722424ac342572099300ee8402e847e8
+DIST genpatches-6.13-5.base.tar.xz 335748 BLAKE2B 167f3f37113e64882ac841e16344ff25a96e614d3a29ebb96b5a21ddf7496386ea4f2397d5a5df0e6ce1e98348934befad7cecae6e947ba94ce1551ff837043e SHA512 1b6d3777fc25d24d31ccf33edbca65b09a5b0f3f48d8af5058b4c8de7b32830bf6fcff330e64ef2b9220cd4a117cc571bc3f900b52e68d4a9277c2a7d1f1ef32
+DIST genpatches-6.13-5.experimental.tar.xz 6056 BLAKE2B b243d376019facce55c1df9826f89449f372f2f952c0aaf7c8fdd806d3b1659b0af338938075653ec809b3d673396f09d968f8c4ea1d9d795c6b2168b835f154 SHA512 b481e69eb1a317a2aca633160668aeb147323c4d0befa7d94cd0718f7e426713d2f4e1bf761f2e171b5970121fd0e90da56542b850ad64764571aa22ee6d0988
+DIST genpatches-6.13-5.extras.tar.xz 4056 BLAKE2B 452b32878514cf29e43de6103b298c41150b888bd78509e26211c7d39e6b8f23acff0f4a5c906e1b0a8cbbb939f0fc6a106085542d4f92bc1e6f2f85580df7f2 SHA512 688fbea8a74987de17fa4afa84a6f3904b39518db971d7ccea13d4fb4f6e7df8031c940e31c2297cf7b15c7d3ec49941232b8d9d352c69e8ca6233bf7b846779
+DIST genpatches-6.13-7.base.tar.xz 475988 BLAKE2B 0e65a5b28cbb356dce79000c5426b67c6ccea5931fb38059e797c954040a667da00ebf8523a73240e8e889fa8215c6437e670613c7346b11546975954756f5cc SHA512 48363b16244da55e0d6709aed745bb136ec493d006a903f7cf4e77646336b96191d6d3f2c165d186c1562ee6261880b7a7bf002510775690c062212cae911ec6
+DIST genpatches-6.13-7.experimental.tar.xz 6044 BLAKE2B 2afdcce58c48f2df7c2c6ca91d1baffb203b224a0c47d2caf23a529b09fcf1c6c03398d973d7ed3e2b58d7e2e099d3277135c437fa2ab366a0a13f7ffa65c8a7 SHA512 7d7ee81dd79c2a80d8790c1eeb13856fb2f6ae3323787f8c828cb60a1ab268e35e5aab578a08323937bafa9ac0f2cc33a0ffc1c2e487cd74e1b5a874377c4d57
+DIST genpatches-6.13-7.extras.tar.xz 4056 BLAKE2B 955e08c33032fbb70ab68d49a52fa38cdd4314bf397382b38164b950f3a7ef6c744835ad427e6f236f133e14ff613b241ec75e6b1019fb79378aa9f93abb2f5b SHA512 45eb08dc01d303747214185f1b4c2835f786c1a06a36fe7dd12a5a4342d46614c738a42018a12c66c34ff87e6c209667523de831e3ae8d4db012409c599f89f4
+DIST linux-6.13.tar.xz 148523052 BLAKE2B 9f617ecb3f2393b57ba03c654fea62a7213f24c835989f333a1ef29492af551bfa7d9ad786d5ef1484854adc77c7c6af38fb09a72d994d305695f512c325e77f SHA512 1137e6440132b0958f89165440e99208f82b204e7245ae69dc9c808df97d13ce8f58136db92407e0e93394fa7f6283ec7a34597c6e92a5b6d9025e0960357957
+EBUILD gentooAI-sources-6.13.3-r1.ebuild 962 BLAKE2B 2c41f65a3c87aea044ea200b49d45ebef5f5996d4723b9e54e2d30c2225c6f4a14db4468f616e0f53f68a51dc9b346af3bda03f08fbe25ecbd45df9a2c6d7f00 SHA512 20bee047c1abada5173aa89698898fdf3872f85884d34d2dab54c558a2bb78c4d7debd712fb1ae84d9564bee8ff1741ae84fb9b442a89d45104e6f46505b1738
+EBUILD gentooAI-sources-6.13.5.ebuild 961 BLAKE2B 6363d3a6ff8131d3d6361e7a048de33eefe6f04dd87da3a952346f2b3dd874c3481f3cdbcc3536fd82d74f8dfc535d9949400160ecdd622fbce7edcbaa2504e1 SHA512 472369689d54633f82f134dc5a4cf4c5ef6d74eb8be9e981717161a20a6ed47d8898bcd1ffabfffc78fe5257405a98e409ce9f3dc801c05ac188d434d6f53717
diff --git a/sys-kernel/gentooAI-sources/files/patch.6.13.3 b/sys-kernel/gentooAI-sources/files/patch.6.13.3
new file mode 100644 (file)
index 0000000..a2a640b
--- /dev/null
@@ -0,0 +1,7864 @@
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/apex_driver.c b/drivers/staging/gasket-driver/apex_driver.c
+--- a/drivers/staging/gasket-driver/apex_driver.c      1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/apex_driver.c      2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,1243 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Driver for the Apex chip.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++
++#include <linux/atomic.h>
++#include <linux/compiler.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/pci.h>
++#include <linux/printk.h>
++#include <linux/sched.h>
++#include <linux/uaccess.h>
++#include <linux/workqueue.h>
++
++#include "apex.h"
++
++#include "gasket_core.h"
++#include "gasket_interrupt.h"
++#include "gasket_page_table.h"
++#include "gasket_sysfs.h"
++
++/* Constants */
++#define APEX_DEVICE_NAME "Apex"
++#define APEX_DRIVER_VERSION "1.2"
++
++/* CSRs are in BAR 2. */
++#define APEX_BAR_INDEX 2
++
++#define APEX_PCI_VENDOR_ID 0x1ac1
++#define APEX_PCI_DEVICE_ID 0x089a
++
++/* Bar Offsets. */
++#define APEX_BAR_OFFSET 0
++#define APEX_CM_OFFSET 0x1000000
++
++/* The sizes of each Apex BAR 2. */
++#define APEX_BAR_BYTES 0x100000
++#define APEX_CH_MEM_BYTES (PAGE_SIZE * MAX_NUM_COHERENT_PAGES)
++
++/* The number of user-mappable memory ranges in BAR2 of a Apex chip. */
++#define NUM_REGIONS 3
++
++/* The number of nodes in a Apex chip. */
++#define NUM_NODES 1
++
++/*
++ * The total number of entries in the page table. Should match the value read
++ * from the register APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE_SIZE.
++ */
++#define APEX_PAGE_TABLE_TOTAL_ENTRIES 8192
++
++#define APEX_EXTENDED_SHIFT 63 /* Extended address bit position. */
++
++/* Check reset 120 times */
++#define APEX_RESET_RETRY 120
++/* Wait 100 ms between checks. Total 12 sec wait maximum. */
++#define APEX_RESET_DELAY 100
++
++/* Interval between temperature polls, 0 disables polling */
++#define DEFAULT_APEX_TEMP_POLL_INTERVAL 5000
++
++/* apex device private data */
++struct apex_dev {
++      struct gasket_dev *gasket_dev_ptr;
++      struct delayed_work check_temperature_work;
++      u32 adc_trip_points[3];
++      atomic_t temp_poll_interval;
++      u32 hw_temp_warn1_adc;
++      u32 hw_temp_warn2_adc;
++      bool hw_temp_warn1_en;
++      bool hw_temp_warn2_en;
++};
++
++/* Enumeration of the supported sysfs entries. */
++enum sysfs_attribute_type {
++      ATTR_KERNEL_HIB_PAGE_TABLE_SIZE,
++      ATTR_KERNEL_HIB_SIMPLE_PAGE_TABLE_SIZE,
++      ATTR_KERNEL_HIB_NUM_ACTIVE_PAGES,
++      ATTR_TEMP,
++      ATTR_TEMP_WARN1,
++      ATTR_TEMP_WARN1_EN,
++      ATTR_TEMP_WARN2,
++      ATTR_TEMP_WARN2_EN,
++      ATTR_TEMP_TRIP0,
++      ATTR_TEMP_TRIP1,
++      ATTR_TEMP_TRIP2,
++      ATTR_TEMP_POLL_INTERVAL,
++      ATTR_UNIQUE_ID,
++};
++
++/*
++ * Register offsets into BAR2 memory.
++ * Only values necessary for driver implementation are defined.
++ */
++enum apex_bar2_regs {
++      APEX_BAR2_REG_SCU_BASE = 0x1A300,
++      APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE_SIZE = 0x46000,
++      APEX_BAR2_REG_KERNEL_HIB_EXTENDED_TABLE = 0x46008,
++      APEX_BAR2_REG_KERNEL_HIB_TRANSLATION_ENABLE = 0x46010,
++      APEX_BAR2_REG_KERNEL_HIB_INSTR_QUEUE_INTVECCTL = 0x46018,
++      APEX_BAR2_REG_KERNEL_HIB_INPUT_ACTV_QUEUE_INTVECCTL = 0x46020,
++      APEX_BAR2_REG_KERNEL_HIB_PARAM_QUEUE_INTVECCTL = 0x46028,
++      APEX_BAR2_REG_KERNEL_HIB_OUTPUT_ACTV_QUEUE_INTVECCTL = 0x46030,
++      APEX_BAR2_REG_KERNEL_HIB_SC_HOST_INTVECCTL = 0x46038,
++      APEX_BAR2_REG_KERNEL_HIB_TOP_LEVEL_INTVECCTL = 0x46040,
++      APEX_BAR2_REG_KERNEL_HIB_FATAL_ERR_INTVECCTL = 0x46048,
++      APEX_BAR2_REG_KERNEL_HIB_DMA_PAUSE = 0x46050,
++      APEX_BAR2_REG_KERNEL_HIB_DMA_PAUSE_MASK = 0x46058,
++      APEX_BAR2_REG_KERNEL_HIB_STATUS_BLOCK_DELAY = 0x46060,
++      APEX_BAR2_REG_KERNEL_HIB_MSIX_PENDING_BIT_ARRAY0 = 0x46068,
++      APEX_BAR2_REG_KERNEL_HIB_MSIX_PENDING_BIT_ARRAY1 = 0x46070,
++      APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE_INIT = 0x46078,
++      APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE_INIT = 0x46080,
++      APEX_BAR2_REG_KERNEL_WIRE_INT_PENDING_BIT_ARRAY = 0x48778,
++      APEX_BAR2_REG_KERNEL_WIRE_INT_MASK_ARRAY = 0x48780,
++      APEX_BAR2_REG_USER_HIB_DMA_PAUSE = 0x486D8,
++      APEX_BAR2_REG_USER_HIB_DMA_PAUSED = 0x486E0,
++      APEX_BAR2_REG_IDLEGENERATOR_IDLEGEN_IDLEREGISTER = 0x4A000,
++      APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE = 0x50000,
++      APEX_BAR2_REG_OMC0_D0 = 0x01a0d0,
++      APEX_BAR2_REG_OMC0_D4 = 0x01a0d4,
++      APEX_BAR2_REG_OMC0_D8 = 0x01a0d8,
++      APEX_BAR2_REG_OMC0_DC = 0x01a0dc,
++      APEX_BAR2_REG_EFUSE_DC = 0x01a2dc,
++      APEX_BAR2_REG_EFUSE_E0 = 0x01a2e0,
++      APEX_BAR2_REG_EFUSE_E4 = 0x01a2e4,
++      APEX_BAR2_REG_EFUSE_E8 = 0x01a2e8,
++
++      /* Error registers - Used mostly for debug */
++      APEX_BAR2_REG_USER_HIB_ERROR_STATUS = 0x86f0,
++      APEX_BAR2_REG_SCALAR_CORE_ERROR_STATUS = 0x41a0,
++};
++
++/* Addresses for packed registers. */
++#define APEX_BAR2_REG_AXI_QUIESCE (APEX_BAR2_REG_SCU_BASE + 0x2C)
++#define APEX_BAR2_REG_GCB_CLOCK_GATE (APEX_BAR2_REG_SCU_BASE + 0x14)
++#define APEX_BAR2_REG_SCU_0 (APEX_BAR2_REG_SCU_BASE + 0xc)
++#define APEX_BAR2_REG_SCU_1 (APEX_BAR2_REG_SCU_BASE + 0x10)
++#define APEX_BAR2_REG_SCU_2 (APEX_BAR2_REG_SCU_BASE + 0x14)
++#define APEX_BAR2_REG_SCU_3 (APEX_BAR2_REG_SCU_BASE + 0x18)
++#define APEX_BAR2_REG_SCU_4 (APEX_BAR2_REG_SCU_BASE + 0x1c)
++#define APEX_BAR2_REG_SCU_5 (APEX_BAR2_REG_SCU_BASE + 0x20)
++
++#define SCU3_RG_PWR_STATE_OVR_BIT_OFFSET 26
++#define SCU3_RG_PWR_STATE_OVR_MASK_WIDTH 2
++#define SCU3_CUR_RST_GCB_BIT_MASK 0x10
++#define SCU2_RG_RST_GCB_BIT_MASK 0xc
++
++/* Configuration for page table. */
++static struct gasket_page_table_config apex_page_table_configs[NUM_NODES] = {
++      {
++              .id = 0,
++              .mode = GASKET_PAGE_TABLE_MODE_NORMAL,
++              .total_entries = APEX_PAGE_TABLE_TOTAL_ENTRIES,
++              .base_reg = APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE,
++              .extended_reg = APEX_BAR2_REG_KERNEL_HIB_EXTENDED_TABLE,
++              .extended_bit = APEX_EXTENDED_SHIFT,
++      },
++};
++
++/* The regions in the BAR2 space that can be mapped into user space. */
++static const struct gasket_mappable_region mappable_regions[NUM_REGIONS] = {
++      { 0x40000, 0x1000 },
++      { 0x44000, 0x1000 },
++      { 0x48000, 0x1000 },
++};
++
++/* Gasket device interrupts enums must be dense (i.e., no empty slots). */
++enum apex_interrupt {
++      APEX_INTERRUPT_INSTR_QUEUE = 0,
++      APEX_INTERRUPT_INPUT_ACTV_QUEUE = 1,
++      APEX_INTERRUPT_PARAM_QUEUE = 2,
++      APEX_INTERRUPT_OUTPUT_ACTV_QUEUE = 3,
++      APEX_INTERRUPT_SC_HOST_0 = 4,
++      APEX_INTERRUPT_SC_HOST_1 = 5,
++      APEX_INTERRUPT_SC_HOST_2 = 6,
++      APEX_INTERRUPT_SC_HOST_3 = 7,
++      APEX_INTERRUPT_TOP_LEVEL_0 = 8,
++      APEX_INTERRUPT_TOP_LEVEL_1 = 9,
++      APEX_INTERRUPT_TOP_LEVEL_2 = 10,
++      APEX_INTERRUPT_TOP_LEVEL_3 = 11,
++      APEX_INTERRUPT_FATAL_ERR = 12,
++      APEX_INTERRUPT_COUNT = 13,
++};
++
++/* Interrupt descriptors for Apex */
++static struct gasket_interrupt_desc apex_interrupts[] = {
++      {
++              APEX_INTERRUPT_INSTR_QUEUE,
++              APEX_BAR2_REG_KERNEL_HIB_INSTR_QUEUE_INTVECCTL,
++              UNPACKED,
++      },
++      {
++              APEX_INTERRUPT_INPUT_ACTV_QUEUE,
++              APEX_BAR2_REG_KERNEL_HIB_INPUT_ACTV_QUEUE_INTVECCTL,
++              UNPACKED
++      },
++      {
++              APEX_INTERRUPT_PARAM_QUEUE,
++              APEX_BAR2_REG_KERNEL_HIB_PARAM_QUEUE_INTVECCTL,
++              UNPACKED
++      },
++      {
++              APEX_INTERRUPT_OUTPUT_ACTV_QUEUE,
++              APEX_BAR2_REG_KERNEL_HIB_OUTPUT_ACTV_QUEUE_INTVECCTL,
++              UNPACKED
++      },
++      {
++              APEX_INTERRUPT_SC_HOST_0,
++              APEX_BAR2_REG_KERNEL_HIB_SC_HOST_INTVECCTL,
++              PACK_0
++      },
++      {
++              APEX_INTERRUPT_SC_HOST_1,
++              APEX_BAR2_REG_KERNEL_HIB_SC_HOST_INTVECCTL,
++              PACK_1
++      },
++      {
++              APEX_INTERRUPT_SC_HOST_2,
++              APEX_BAR2_REG_KERNEL_HIB_SC_HOST_INTVECCTL,
++              PACK_2
++      },
++      {
++              APEX_INTERRUPT_SC_HOST_3,
++              APEX_BAR2_REG_KERNEL_HIB_SC_HOST_INTVECCTL,
++              PACK_3
++      },
++      {
++              APEX_INTERRUPT_TOP_LEVEL_0,
++              APEX_BAR2_REG_KERNEL_HIB_TOP_LEVEL_INTVECCTL,
++              PACK_0
++      },
++      {
++              APEX_INTERRUPT_TOP_LEVEL_1,
++              APEX_BAR2_REG_KERNEL_HIB_TOP_LEVEL_INTVECCTL,
++              PACK_1
++      },
++      {
++              APEX_INTERRUPT_TOP_LEVEL_2,
++              APEX_BAR2_REG_KERNEL_HIB_TOP_LEVEL_INTVECCTL,
++              PACK_2
++      },
++      {
++              APEX_INTERRUPT_TOP_LEVEL_3,
++              APEX_BAR2_REG_KERNEL_HIB_TOP_LEVEL_INTVECCTL,
++              PACK_3
++      },
++      {
++              APEX_INTERRUPT_FATAL_ERR,
++              APEX_BAR2_REG_KERNEL_HIB_FATAL_ERR_INTVECCTL,
++              UNPACKED
++      },
++};
++
++/* Allows device to enter power save upon driver close(). */
++static int allow_power_save = 1;
++
++/* Allows SW based clock gating. */
++static int allow_sw_clock_gating;
++
++/* Allows HW based clock gating. */
++/* Note: this is not mutual exclusive with SW clock gating. */
++static int allow_hw_clock_gating = 1;
++
++/* Act as if only GCB is instantiated. */
++static int bypass_top_level;
++
++module_param(allow_power_save, int, 0644);
++module_param(allow_sw_clock_gating, int, 0644);
++module_param(allow_hw_clock_gating, int, 0644);
++module_param(bypass_top_level, int, 0644);
++
++/* Temperature points in milli C at which DFS is toggled */
++#define DEFAULT_TRIP_POINT0_TEMP 85000
++#define DEFAULT_TRIP_POINT1_TEMP 90000
++#define DEFAULT_TRIP_POINT2_TEMP 95000
++
++static int trip_point0_temp = DEFAULT_TRIP_POINT0_TEMP;
++static int trip_point1_temp = DEFAULT_TRIP_POINT1_TEMP;
++static int trip_point2_temp = DEFAULT_TRIP_POINT2_TEMP;
++
++module_param(trip_point0_temp, int, 0644);
++module_param(trip_point1_temp, int, 0644);
++module_param(trip_point2_temp, int, 0644);
++
++/* Hardware monitored temperature trip points in milli C
++   Apex chip drives INTR line when reaching hw_temp_warn1 temperature,
++   and SD_ALARM line when reaching hw_temp_warn2 if corresponding
++   hw_temp_warn*_en is set to true.
++ */
++static int hw_temp_warn1 = 100000;
++static int hw_temp_warn2 = 100000;
++static bool hw_temp_warn1_en = false;
++static bool hw_temp_warn2_en = true;
++
++module_param(hw_temp_warn1, int, 0644);
++module_param(hw_temp_warn2, int, 0644);
++module_param(hw_temp_warn1_en, bool, 0644);
++module_param(hw_temp_warn2_en, bool, 0644);
++
++/* Temperature poll interval in ms */
++static int temp_poll_interval = DEFAULT_APEX_TEMP_POLL_INTERVAL;
++module_param(temp_poll_interval, int, 0644);
++
++/* Check the device status registers and return device status ALIVE or DEAD. */
++static int apex_get_status(struct gasket_dev *gasket_dev)
++{
++      /* TODO: Check device status. */
++      return GASKET_STATUS_ALIVE;
++}
++
++/* Enter GCB reset state. */
++static int apex_enter_reset(struct gasket_dev *gasket_dev)
++{
++      if (bypass_top_level)
++              return 0;
++
++      /*
++       * Software reset:
++       * Enable sleep mode
++       *  - Software force GCB idle
++       *    - Enable GCB idle
++       */
++      gasket_read_modify_write_64(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_IDLEGENERATOR_IDLEGEN_IDLEREGISTER,
++                                  0x0, 1, 32);
++
++      /*    - Initiate DMA pause */
++      gasket_dev_write_64(gasket_dev, 1, APEX_BAR_INDEX,
++                          APEX_BAR2_REG_USER_HIB_DMA_PAUSE);
++
++      /*    - Wait for DMA pause complete. */
++      if (gasket_wait_with_reschedule(gasket_dev, APEX_BAR_INDEX,
++                                      APEX_BAR2_REG_USER_HIB_DMA_PAUSED, 1, 1,
++                                      APEX_RESET_DELAY, APEX_RESET_RETRY)) {
++              dev_err(gasket_dev->dev,
++                      "DMAs did not quiesce within timeout (%d ms)\n",
++                      APEX_RESET_RETRY * APEX_RESET_DELAY);
++              return -ETIMEDOUT;
++      }
++
++      /*  - Enable GCB reset (0x1 to rg_rst_gcb) */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_2, 0x1, 2, 2);
++
++      /*  - Enable GCB clock Gate (0x1 to rg_gated_gcb) */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_2, 0x1, 2, 18);
++
++      /*  - Enable GCB memory shut down (0x3 to rg_force_ram_sd) */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_3, 0x3, 2, 14);
++
++      /*    - Wait for RAM shutdown. */
++      if (gasket_wait_with_reschedule(gasket_dev, APEX_BAR_INDEX,
++                                      APEX_BAR2_REG_SCU_3, 1 << 6, 1 << 6,
++                                      APEX_RESET_DELAY, APEX_RESET_RETRY)) {
++              dev_err(gasket_dev->dev,
++                      "RAM did not shut down within timeout (%d ms)\n",
++                      APEX_RESET_RETRY * APEX_RESET_DELAY);
++              return -ETIMEDOUT;
++      }
++
++      return 0;
++}
++
++/* Quit GCB reset state. */
++static int apex_quit_reset(struct gasket_dev *gasket_dev)
++{
++      u32 val0, val1;
++
++      if (bypass_top_level)
++              return 0;
++
++      /*
++       * Disable sleep mode:
++       *  - Disable GCB memory shut down:
++       *    - b00: Not forced (HW controlled)
++       *    - b1x: Force disable
++       */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_3, 0x0, 2, 14);
++
++      /*
++       *  - Disable software clock gate:
++       *    - b00: Not forced (HW controlled)
++       *    - b1x: Force disable
++       */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_2, 0x0, 2, 18);
++
++      /*
++       *  - Disable GCB reset (rg_rst_gcb):
++       *    - b00: Not forced (HW controlled)
++       *    - b1x: Force disable = Force not Reset
++       */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_2, 0x2, 2, 2);
++
++      /*    - Wait for RAM enable. */
++      if (gasket_wait_with_reschedule(gasket_dev, APEX_BAR_INDEX,
++                                      APEX_BAR2_REG_SCU_3, 1 << 6, 0,
++                                      APEX_RESET_DELAY, APEX_RESET_RETRY)) {
++              dev_err(gasket_dev->dev,
++                      "RAM did not enable within timeout (%d ms)\n",
++                      APEX_RESET_RETRY * APEX_RESET_DELAY);
++              return -ETIMEDOUT;
++      }
++
++      /*    - Wait for Reset complete. */
++      if (gasket_wait_with_reschedule(gasket_dev, APEX_BAR_INDEX,
++                                      APEX_BAR2_REG_SCU_3,
++                                      SCU3_CUR_RST_GCB_BIT_MASK, 0,
++                                      APEX_RESET_DELAY, APEX_RESET_RETRY)) {
++              dev_err(gasket_dev->dev,
++                      "GCB did not leave reset within timeout (%d ms)\n",
++                      APEX_RESET_RETRY * APEX_RESET_DELAY);
++              return -ETIMEDOUT;
++      }
++
++      if (!allow_hw_clock_gating) {
++              val0 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                        APEX_BAR2_REG_SCU_3);
++              /* Inactive and Sleep mode are disabled. */
++              gasket_read_modify_write_32(gasket_dev,
++                                          APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_SCU_3, 0x3,
++                                          SCU3_RG_PWR_STATE_OVR_MASK_WIDTH,
++                                          SCU3_RG_PWR_STATE_OVR_BIT_OFFSET);
++              val1 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                        APEX_BAR2_REG_SCU_3);
++              dev_dbg(gasket_dev->dev,
++                      "Disallow HW clock gating 0x%x -> 0x%x\n", val0, val1);
++      } else {
++              val0 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                        APEX_BAR2_REG_SCU_3);
++              /* Inactive mode enabled - Sleep mode disabled. */
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_SCU_3, 2,
++                                          SCU3_RG_PWR_STATE_OVR_MASK_WIDTH,
++                                          SCU3_RG_PWR_STATE_OVR_BIT_OFFSET);
++              val1 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                        APEX_BAR2_REG_SCU_3);
++              dev_dbg(gasket_dev->dev, "Allow HW clock gating 0x%x -> 0x%x\n",
++                      val0, val1);
++      }
++
++      return 0;
++}
++
++/* Reset the Apex hardware. Called on final close via device_close_cb. */
++static int apex_device_cleanup(struct gasket_dev *gasket_dev)
++{
++      u64 scalar_error;
++      u64 hib_error;
++      int ret = 0;
++
++      hib_error = gasket_dev_read_64(gasket_dev, APEX_BAR_INDEX,
++                                     APEX_BAR2_REG_USER_HIB_ERROR_STATUS);
++      scalar_error = gasket_dev_read_64(gasket_dev, APEX_BAR_INDEX,
++                                        APEX_BAR2_REG_SCALAR_CORE_ERROR_STATUS);
++
++      dev_dbg(gasket_dev->dev,
++              "%s 0x%p hib_error 0x%llx scalar_error 0x%llx\n",
++              __func__, gasket_dev, hib_error, scalar_error);
++
++      if (allow_power_save)
++              ret = apex_enter_reset(gasket_dev);
++
++      return ret;
++}
++
++/* Determine if GCB is in reset state. */
++static bool is_gcb_in_reset(struct gasket_dev *gasket_dev)
++{
++      u32 val = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                   APEX_BAR2_REG_SCU_3);
++
++      /* Masks rg_rst_gcb bit of SCU_CTRL_2 */
++      return (val & SCU3_CUR_RST_GCB_BIT_MASK);
++}
++
++/* Reset the hardware, then quit reset.  Called on device open. */
++static int apex_reset(struct gasket_dev *gasket_dev)
++{
++      int ret;
++
++      if (bypass_top_level)
++              return 0;
++
++      if (!is_gcb_in_reset(gasket_dev)) {
++              /* We are not in reset - toggle the reset bit so as to force
++               * re-init of custom block
++               */
++              dev_dbg(gasket_dev->dev, "%s: toggle reset\n", __func__);
++
++              ret = apex_enter_reset(gasket_dev);
++              if (ret)
++                      return ret;
++      }
++      ret = apex_quit_reset(gasket_dev);
++
++      return ret;
++}
++
++/*
++ * Check permissions for Apex ioctls.
++ * Returns true if the current user may execute this ioctl, and false otherwise.
++ */
++static bool apex_ioctl_check_permissions(struct file *filp, uint cmd)
++{
++      return !!(filp->f_mode & FMODE_WRITE);
++}
++
++/* Gates or un-gates Apex clock. */
++static long apex_clock_gating(struct gasket_dev *gasket_dev,
++                            struct apex_gate_clock_ioctl __user *argp)
++{
++      struct apex_gate_clock_ioctl ibuf;
++
++      if (bypass_top_level || !allow_sw_clock_gating)
++              return 0;
++
++      if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
++              return -EFAULT;
++
++      dev_dbg(gasket_dev->dev, "%s %llu\n", __func__, ibuf.enable);
++
++      if (ibuf.enable) {
++              /* Quiesce AXI, gate GCB clock. */
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_AXI_QUIESCE, 0x1, 1,
++                                          16);
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_GCB_CLOCK_GATE, 0x1,
++                                          2, 18);
++      } else {
++              /* Un-gate GCB clock, un-quiesce AXI. */
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_GCB_CLOCK_GATE, 0x0,
++                                          2, 18);
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_AXI_QUIESCE, 0x0, 1,
++                                          16);
++      }
++      return 0;
++}
++
++/* apex_set_performance_expectation: Adjust clock rates for Apex. */
++static long apex_set_performance_expectation(
++      struct gasket_dev *gasket_dev,
++      struct apex_performance_expectation_ioctl __user *argp)
++{
++      struct apex_performance_expectation_ioctl ibuf;
++      uint32_t rg_gcb_clk_div = 0;
++      uint32_t rg_axi_clk_fixed = 0;
++      const int AXI_CLK_FIXED_SHIFT = 2;
++      const int MCU_CLK_FIXED_SHIFT = 3;
++
++      // 8051 clock is fixed for PCIe, as it's not used at all.
++      const uint32_t rg_8051_clk_fixed = 1;
++
++      if (bypass_top_level)
++              return 0;
++
++      if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
++              return -EFAULT;
++
++      switch (ibuf.performance) {
++              case APEX_PERFORMANCE_LOW:
++                      rg_gcb_clk_div = 3;
++                      rg_axi_clk_fixed = 0;
++                      break;
++
++              case APEX_PERFORMANCE_MED:
++                      rg_gcb_clk_div = 2;
++                      rg_axi_clk_fixed = 0;
++                      break;
++
++              case APEX_PERFORMANCE_HIGH:
++                      rg_gcb_clk_div = 1;
++                      rg_axi_clk_fixed = 0;
++                      break;
++
++              case APEX_PERFORMANCE_MAX:
++                      rg_gcb_clk_div = 0;
++                      rg_axi_clk_fixed = 0;
++                      break;
++
++              default:
++                      return -EINVAL;
++      }
++
++      /*
++       * Set clock rates for GCB, AXI, and 8051:
++       */
++      gasket_read_modify_write_32(
++              gasket_dev, APEX_BAR_INDEX, APEX_BAR2_REG_SCU_3,
++                (rg_gcb_clk_div | (rg_axi_clk_fixed << AXI_CLK_FIXED_SHIFT) | (rg_8051_clk_fixed << MCU_CLK_FIXED_SHIFT)),
++                /*mask_width=*/4, /*mask_shift=*/28);
++
++      return 0;
++}
++
++/* Apex-specific ioctl handler. */
++static long apex_ioctl(struct file *filp, uint cmd, void __user *argp)
++{
++      struct gasket_dev *gasket_dev = filp->private_data;
++
++      if (!apex_ioctl_check_permissions(filp, cmd))
++              return -EPERM;
++
++      switch (cmd) {
++      case APEX_IOCTL_GATE_CLOCK:
++              return apex_clock_gating(gasket_dev, argp);
++      case APEX_IOCTL_PERFORMANCE_EXPECTATION:
++              return apex_set_performance_expectation(gasket_dev, argp);
++      default:
++              return -ENOTTY; /* unknown command */
++      }
++}
++
++/* Linear fit optimized for 25C-100C */
++static int adc_to_millic(int adc)
++{
++      return (662 - adc) * 250 + 550;
++}
++
++static int millic_to_adc(int millic)
++{
++      return (550 - millic) / 250 + 662;
++}
++
++/* Display driver sysfs entries. */
++static ssize_t sysfs_show(struct device *device, struct device_attribute *attr,
++                        char *buf)
++{
++      int ret;
++      unsigned value, value2, value3, value4;
++      struct gasket_dev *gasket_dev;
++      struct apex_dev *apex_dev;
++      struct gasket_sysfs_attribute *gasket_attr;
++      enum sysfs_attribute_type type;
++
++      gasket_dev = gasket_sysfs_get_device_data(device);
++      if (!gasket_dev) {
++              dev_err(device, "No Apex device sysfs mapping found\n");
++              return -ENODEV;
++      }
++
++      if (!gasket_dev->pci_dev ||
++          !(apex_dev = pci_get_drvdata(gasket_dev->pci_dev))) {
++              dev_err(device, "Can't find apex_dev data\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return -ENODEV;
++      }
++
++      gasket_attr = gasket_sysfs_get_attr(device, attr);
++      if (!gasket_attr) {
++              dev_err(device, "No Apex device sysfs attr data found\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return -ENODEV;
++      }
++
++      type = (enum sysfs_attribute_type)gasket_attr->data.attr_type;
++      switch (type) {
++      case ATTR_KERNEL_HIB_PAGE_TABLE_SIZE:
++              ret = scnprintf(buf, PAGE_SIZE, "%u\n",
++                              gasket_page_table_num_entries(
++                                      gasket_dev->page_table[0]));
++              break;
++      case ATTR_KERNEL_HIB_SIMPLE_PAGE_TABLE_SIZE:
++              ret = scnprintf(buf, PAGE_SIZE, "%u\n",
++                              gasket_page_table_num_entries(
++                                      gasket_dev->page_table[0]));
++              break;
++      case ATTR_KERNEL_HIB_NUM_ACTIVE_PAGES:
++              ret = scnprintf(buf, PAGE_SIZE, "%u\n",
++                              gasket_page_table_num_active_pages(
++                                      gasket_dev->page_table[0]));
++              break;
++      case ATTR_TEMP:
++              value = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                         APEX_BAR2_REG_OMC0_DC);
++              value = (value >> 16) & ((1 << 10) - 1);
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n", adc_to_millic(value));
++              break;
++      case ATTR_TEMP_WARN1:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              adc_to_millic(apex_dev->hw_temp_warn1_adc));
++              break;
++      case ATTR_TEMP_WARN2:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              adc_to_millic(apex_dev->hw_temp_warn2_adc));
++              break;
++      case ATTR_TEMP_WARN1_EN:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              apex_dev->hw_temp_warn1_en);
++              break;
++      case ATTR_TEMP_WARN2_EN:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              apex_dev->hw_temp_warn2_en);
++              break;
++      case ATTR_TEMP_TRIP0:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              adc_to_millic(apex_dev->adc_trip_points[0]));
++              break;
++      case ATTR_TEMP_TRIP1:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              adc_to_millic(apex_dev->adc_trip_points[1]));
++              break;
++      case ATTR_TEMP_TRIP2:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              adc_to_millic(apex_dev->adc_trip_points[2]));
++              break;
++      case ATTR_TEMP_POLL_INTERVAL:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              atomic_read(&apex_dev->temp_poll_interval));
++              break;
++      case ATTR_UNIQUE_ID:
++              value = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                         APEX_BAR2_REG_EFUSE_DC);
++              value2 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_EFUSE_E0);
++              value3 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_EFUSE_E4);
++              value4 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_EFUSE_E8);
++              ret = snprintf(buf, PAGE_SIZE, "%.8x%.8x%.8x%.8x\n", value4,
++                             value3, value2, value);
++              break;
++
++      default:
++              dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
++                      attr->attr.name);
++              ret = 0;
++              break;
++      }
++
++      gasket_sysfs_put_attr(device, gasket_attr);
++      gasket_sysfs_put_device_data(device, gasket_dev);
++      return ret;
++}
++
++/* Set driver sysfs entries. */
++static ssize_t sysfs_store(struct device *device, struct device_attribute *attr,
++                         const char *buf, size_t count)
++{
++      int ret = count, value;
++      struct gasket_dev *gasket_dev;
++      struct apex_dev *apex_dev;
++      struct gasket_sysfs_attribute *gasket_attr;
++      enum sysfs_attribute_type type;
++
++      if (kstrtoint(buf, 10, &value))
++              return -EINVAL;
++
++      gasket_dev = gasket_sysfs_get_device_data(device);
++      if (!gasket_dev) {
++              dev_err(device, "No Apex device sysfs mapping found\n");
++              return -ENODEV;
++      }
++
++      if (!gasket_dev->pci_dev ||
++          !(apex_dev = pci_get_drvdata(gasket_dev->pci_dev))) {
++              dev_err(device, "Can't find apex_dev data\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return -ENODEV;
++      }
++
++      gasket_attr = gasket_sysfs_get_attr(device, attr);
++      if (!gasket_attr) {
++              dev_err(device, "No Apex device sysfs attr data found\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return -ENODEV;
++      }
++
++      type = (enum sysfs_attribute_type)gasket_attr->data.attr_type;
++      switch (type) {
++      case ATTR_TEMP_WARN1:
++              value = millic_to_adc(value);
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D4, value, 10,
++                                          16);
++              apex_dev->hw_temp_warn1_adc = value;
++              break;
++      case ATTR_TEMP_WARN2:
++              value = millic_to_adc(value);
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D8, value, 10,
++                                          16);
++              apex_dev->hw_temp_warn2_adc = value;
++              break;
++      case ATTR_TEMP_WARN1_EN:
++              value = value > 0 ? 1 : 0;
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D4, value, 1,
++                                          31);
++              apex_dev->hw_temp_warn1_en = !!value;
++              break;
++      case ATTR_TEMP_WARN2_EN:
++              value = value > 0 ? 1 : 0;
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D8, value, 1,
++                                          31);
++              apex_dev->hw_temp_warn2_en = !!value;
++              break;
++      case ATTR_TEMP_TRIP0:
++              value = millic_to_adc(value);
++              /* Note: that adc values should be in descending order */
++              if (value >= apex_dev->adc_trip_points[1]) {
++                      apex_dev->adc_trip_points[0] = value;
++              } else ret = -EINVAL;
++              break;
++      case ATTR_TEMP_TRIP1:
++              value = millic_to_adc(value);
++              if (value <= apex_dev->adc_trip_points[0] &&
++                  value >= apex_dev->adc_trip_points[2]) {
++                      apex_dev->adc_trip_points[1] = value;
++              } else ret = -EINVAL;
++              break;
++      case ATTR_TEMP_TRIP2:
++              value = millic_to_adc(value);
++              if (value <= apex_dev->adc_trip_points[1]) {
++                      apex_dev->adc_trip_points[2] = value;
++              } else ret = -EINVAL;
++              break;
++      case ATTR_TEMP_POLL_INTERVAL:
++              cancel_delayed_work_sync(&apex_dev->check_temperature_work);
++              atomic_set(&apex_dev->temp_poll_interval, value);
++              if (value > 0)
++                      schedule_delayed_work(&apex_dev->check_temperature_work,
++                                            msecs_to_jiffies(value));
++
++              break;
++      default:
++              dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
++                      attr->attr.name);
++              ret = 0;
++              break;
++      }
++
++      gasket_sysfs_put_attr(device, gasket_attr);
++      gasket_sysfs_put_device_data(device, gasket_dev);
++      return ret;
++}
++
++static struct gasket_sysfs_attribute apex_sysfs_attrs[] = {
++      GASKET_SYSFS_RO(node_0_page_table_entries, sysfs_show,
++                      ATTR_KERNEL_HIB_PAGE_TABLE_SIZE),
++      GASKET_SYSFS_RO(node_0_simple_page_table_entries, sysfs_show,
++                      ATTR_KERNEL_HIB_SIMPLE_PAGE_TABLE_SIZE),
++      GASKET_SYSFS_RO(node_0_num_mapped_pages, sysfs_show,
++                      ATTR_KERNEL_HIB_NUM_ACTIVE_PAGES),
++      GASKET_SYSFS_RO(temp, sysfs_show, ATTR_TEMP),
++      GASKET_SYSFS_RW(hw_temp_warn1, sysfs_show, sysfs_store,
++                      ATTR_TEMP_WARN1),
++      GASKET_SYSFS_RW(hw_temp_warn1_en, sysfs_show, sysfs_store,
++                      ATTR_TEMP_WARN1_EN),
++      GASKET_SYSFS_RW(hw_temp_warn2, sysfs_show, sysfs_store,
++                      ATTR_TEMP_WARN2),
++      GASKET_SYSFS_RW(hw_temp_warn2_en, sysfs_show, sysfs_store,
++                      ATTR_TEMP_WARN2_EN),
++      GASKET_SYSFS_RW(trip_point0_temp, sysfs_show, sysfs_store,
++                      ATTR_TEMP_TRIP0),
++      GASKET_SYSFS_RW(trip_point1_temp, sysfs_show, sysfs_store,
++                      ATTR_TEMP_TRIP1),
++      GASKET_SYSFS_RW(trip_point2_temp, sysfs_show, sysfs_store,
++                      ATTR_TEMP_TRIP2),
++      GASKET_SYSFS_RW(temp_poll_interval, sysfs_show, sysfs_store,
++                      ATTR_TEMP_POLL_INTERVAL),
++      GASKET_SYSFS_RO(unique_id, sysfs_show, ATTR_UNIQUE_ID),
++      GASKET_END_OF_ATTR_ARRAY
++};
++
++/* Stores kernel module parameters to device specific data buffer */
++static void apply_module_params(struct apex_dev *apex_dev) {
++      kernel_param_lock(THIS_MODULE);
++
++      /* use defaults if trip point temperatures are not in ascending order */
++      if (trip_point0_temp > trip_point1_temp ||
++          trip_point1_temp > trip_point2_temp) {
++              dev_warn(apex_dev->gasket_dev_ptr->dev,
++                       "Invalid module parameters for temperature trip points"
++                       ", using defaults\n");
++              trip_point0_temp = DEFAULT_TRIP_POINT0_TEMP;
++              trip_point1_temp = DEFAULT_TRIP_POINT1_TEMP;
++              trip_point2_temp = DEFAULT_TRIP_POINT2_TEMP;
++      }
++
++      apex_dev->adc_trip_points[0] = millic_to_adc(trip_point0_temp);
++      apex_dev->adc_trip_points[1] = millic_to_adc(trip_point1_temp);
++      apex_dev->adc_trip_points[2] = millic_to_adc(trip_point2_temp);
++      atomic_set(&apex_dev->temp_poll_interval, temp_poll_interval);
++
++      apex_dev->hw_temp_warn1_adc = millic_to_adc(hw_temp_warn1);
++      apex_dev->hw_temp_warn2_adc = millic_to_adc(hw_temp_warn2);
++      apex_dev->hw_temp_warn1_en = hw_temp_warn1_en;
++      apex_dev->hw_temp_warn2_en = hw_temp_warn2_en;
++
++      kernel_param_unlock(THIS_MODULE);
++}
++
++/* Applies hw temp warning settings to device */
++static void program_hw_temp_warnings(struct apex_dev *apex_dev) {
++      gasket_read_modify_write_32(apex_dev->gasket_dev_ptr, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_OMC0_D4,
++                                  apex_dev->hw_temp_warn1_adc, 10, 16);
++      gasket_read_modify_write_32(apex_dev->gasket_dev_ptr, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_OMC0_D8,
++                                  apex_dev->hw_temp_warn2_adc, 10, 16);
++      if (apex_dev->hw_temp_warn1_en)
++              gasket_read_modify_write_32(apex_dev->gasket_dev_ptr,
++                                          APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D4, 1, 1, 31);
++
++      if (apex_dev->hw_temp_warn2_en)
++              gasket_read_modify_write_32(apex_dev->gasket_dev_ptr,
++                                          APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D8, 1, 1, 31);
++}
++
++static void enable_thermal_sensing(struct gasket_dev *gasket_dev) {
++      // Enable thermal sensor clocks
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_OMC0_D0, 0x1, 1, 7);
++
++      // Enable thermal sensor (ENAD ENVR ENBG)
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_OMC0_D8, 0x7, 3, 0);
++
++      // Enable OMC thermal sensor controller
++      // This bit should be asserted 100 us after ENAD ENVR ENBG
++      schedule_timeout(usecs_to_jiffies(100));
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_OMC0_DC, 0x1, 1, 0);
++}
++
++static void check_temperature_work_handler(struct work_struct *work) {
++      int i, temp_poll_interval;
++      u32 adc_temp, clk_div, tmp;
++      const u32 mask = ((1 << 2) - 1) << 28;
++      struct apex_dev *apex_dev =
++              container_of(work, struct apex_dev,
++                           check_temperature_work.work);
++      struct gasket_dev *gasket_dev = apex_dev->gasket_dev_ptr;
++
++      mutex_lock(&gasket_dev->mutex);
++
++      /* Read current temperature */
++      adc_temp = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                    APEX_BAR2_REG_OMC0_DC);
++      adc_temp = (adc_temp >> 16) & ((1 << 10) - 1);
++
++      /* Find closest trip point
++         Note: that adc values are in descending order */
++      for (i = ARRAY_SIZE(apex_dev->adc_trip_points) - 1; i >= 0; --i) {
++              if (adc_temp <= apex_dev->adc_trip_points[i])
++                      break;
++      }
++      /* Compute divider value and shift into appropriate bit location */
++      clk_div = (i + 1) << 28;
++
++      /* Modify gcb clk divider if it's different from current one */
++      tmp = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                               APEX_BAR2_REG_SCU_3);
++      if (clk_div != (tmp & mask)) {
++              tmp = (tmp & ~mask) | clk_div;
++              gasket_dev_write_32(gasket_dev, tmp, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_3);
++              dev_warn(gasket_dev->dev,
++                       "Apex performance %sthrottled due to temperature\n",
++                       i == -1 ? "not " : "");
++      }
++
++      mutex_unlock(&gasket_dev->mutex);
++
++      temp_poll_interval = atomic_read(&apex_dev->temp_poll_interval);
++      if (temp_poll_interval > 0)
++              schedule_delayed_work(&apex_dev->check_temperature_work,
++                                    msecs_to_jiffies(temp_poll_interval));
++}
++
++/* On device open, perform a core reinit reset. */
++static int apex_device_open_cb(struct gasket_dev *gasket_dev)
++{
++      return gasket_reset_nolock(gasket_dev);
++}
++
++static const struct pci_device_id apex_pci_ids[] = {
++      { PCI_DEVICE(APEX_PCI_VENDOR_ID, APEX_PCI_DEVICE_ID) }, { 0 }
++};
++
++static void apex_pci_fixup_class(struct pci_dev *pdev)
++{
++      pdev->class = (PCI_CLASS_SYSTEM_OTHER << 8) | pdev->class;
++}
++DECLARE_PCI_FIXUP_CLASS_HEADER(APEX_PCI_VENDOR_ID, APEX_PCI_DEVICE_ID,
++                             PCI_ANY_ID, 8, apex_pci_fixup_class);
++
++static int apex_pci_probe(struct pci_dev *pci_dev,
++                        const struct pci_device_id *id)
++{
++      int ret, temp_poll_interval;
++      ulong page_table_ready, msix_table_ready;
++      int retries = 0;
++      struct gasket_dev *gasket_dev;
++      struct apex_dev *apex_dev;
++
++      ret = pci_enable_device(pci_dev);
++#ifdef MODULE
++      if (ret) {
++              apex_pci_fixup_class(pci_dev);
++              pci_bus_assign_resources(pci_dev->bus);
++              ret = pci_enable_device(pci_dev);
++      }
++#endif
++      if (ret) {
++              dev_err(&pci_dev->dev, "error enabling PCI device\n");
++              return ret;
++      }
++
++      pci_set_master(pci_dev);
++
++      ret = gasket_pci_add_device(pci_dev, &gasket_dev);
++      if (ret) {
++              dev_err(&pci_dev->dev, "error adding gasket device\n");
++              pci_disable_device(pci_dev);
++              return ret;
++      }
++
++      apex_dev = kzalloc(sizeof(*apex_dev), GFP_KERNEL);
++      if (!apex_dev) {
++              dev_err(&pci_dev->dev, "no memory for device\n");
++              ret = -ENOMEM;
++              goto remove_device;
++      }
++
++      INIT_DELAYED_WORK(&apex_dev->check_temperature_work,
++                        check_temperature_work_handler);
++      apex_dev->gasket_dev_ptr = gasket_dev;
++      apply_module_params(apex_dev);
++      program_hw_temp_warnings(apex_dev);
++      pci_set_drvdata(pci_dev, apex_dev);
++      apex_reset(gasket_dev);
++
++      while (retries < APEX_RESET_RETRY) {
++              page_table_ready =
++                      gasket_dev_read_64(gasket_dev, APEX_BAR_INDEX,
++                                         APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE_INIT);
++              msix_table_ready =
++                      gasket_dev_read_64(gasket_dev, APEX_BAR_INDEX,
++                                         APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE_INIT);
++              if (page_table_ready && msix_table_ready)
++                      break;
++              schedule_timeout(msecs_to_jiffies(APEX_RESET_DELAY));
++              retries++;
++      }
++
++      if (retries == APEX_RESET_RETRY) {
++              if (!page_table_ready)
++                      dev_err(gasket_dev->dev, "Page table init timed out\n");
++              if (!msix_table_ready)
++                      dev_err(gasket_dev->dev, "MSI-X table init timed out\n");
++              ret = -ETIMEDOUT;
++              goto remove_device;
++      }
++
++      enable_thermal_sensing(gasket_dev);
++
++      ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device,
++                                        apex_sysfs_attrs);
++      if (ret)
++              dev_err(&pci_dev->dev, "error creating device sysfs entries\n");
++
++      ret = gasket_enable_device(gasket_dev);
++      if (ret) {
++              dev_err(&pci_dev->dev, "error enabling gasket device\n");
++              goto remove_device;
++      }
++
++      /* Place device in low power mode until opened */
++      if (allow_power_save)
++              apex_enter_reset(gasket_dev);
++
++      /* Enable thermal polling */
++      temp_poll_interval = atomic_read(&apex_dev->temp_poll_interval);
++      if (temp_poll_interval > 0)
++              schedule_delayed_work(&apex_dev->check_temperature_work,
++                                    msecs_to_jiffies(temp_poll_interval));
++      return 0;
++
++remove_device:
++      gasket_pci_remove_device(pci_dev);
++      pci_disable_device(pci_dev);
++      kfree(apex_dev);
++      return ret;
++}
++
++static void apex_pci_remove(struct pci_dev *pci_dev)
++{
++      struct apex_dev *apex_dev = pci_get_drvdata(pci_dev);
++      struct gasket_dev *gasket_dev;
++
++      if (!apex_dev) {
++              dev_err(&pci_dev->dev, "NULL apex_dev\n");
++              goto remove_device;
++      }
++      gasket_dev = apex_dev->gasket_dev_ptr;
++
++      cancel_delayed_work_sync(&apex_dev->check_temperature_work);
++      kfree(apex_dev);
++
++      gasket_disable_device(gasket_dev);
++remove_device:
++      gasket_pci_remove_device(pci_dev);
++      pci_disable_device(pci_dev);
++}
++
++static int apex_pci_suspend(struct pci_dev *pci_dev, pm_message_t state) {
++      struct apex_dev *apex_dev = pci_get_drvdata(pci_dev);
++      struct gasket_dev *gasket_dev;
++
++      if (!apex_dev) {
++              dev_err_once(&pci_dev->dev, "NULL apex_dev\n");
++              return -ENODEV;
++      }
++
++      // Tear down MSI-x interrupts before suspending.
++      gasket_dev = apex_dev->gasket_dev_ptr;
++      gasket_interrupt_msix_cleanup(gasket_dev->interrupt_data);
++      return 0;
++}
++
++static int apex_pci_resume(struct pci_dev *pci_dev)
++{
++      struct apex_dev *apex_dev = pci_get_drvdata(pci_dev);
++      struct gasket_dev *gasket_dev;
++
++      if (!apex_dev) {
++              dev_err_once(&pci_dev->dev, "NULL apex_dev\n");
++              return -ENODEV;
++      }
++      gasket_dev = apex_dev->gasket_dev_ptr;
++
++      gasket_interrupt_reinit(gasket_dev);
++      apex_reset(gasket_dev);
++      program_hw_temp_warnings(apex_dev);
++      enable_thermal_sensing(gasket_dev);
++
++      /* Place device in low power mode until opened */
++      if (allow_power_save)
++              apex_enter_reset(gasket_dev);
++
++      return 0;
++}
++
++static struct gasket_driver_desc apex_desc = {
++      .name = "apex",
++      .driver_version = APEX_DRIVER_VERSION,
++      .major = 120,
++      .minor = 0,
++      .module = THIS_MODULE,
++      .pci_id_table = apex_pci_ids,
++
++      .num_page_tables = NUM_NODES,
++      .page_table_bar_index = APEX_BAR_INDEX,
++      .page_table_configs = apex_page_table_configs,
++      .page_table_extended_bit = APEX_EXTENDED_SHIFT,
++
++      .bar_descriptions = {
++              GASKET_UNUSED_BAR,
++              GASKET_UNUSED_BAR,
++              { APEX_BAR_BYTES, (VM_WRITE | VM_READ), APEX_BAR_OFFSET,
++                      NUM_REGIONS, mappable_regions, PCI_BAR },
++              GASKET_UNUSED_BAR,
++              GASKET_UNUSED_BAR,
++              GASKET_UNUSED_BAR,
++      },
++      .coherent_buffer_description = {
++              APEX_CH_MEM_BYTES,
++              (VM_WRITE | VM_READ),
++              APEX_CM_OFFSET,
++      },
++      .interrupt_type = PCI_MSIX,
++      .interrupt_bar_index = APEX_BAR_INDEX,
++      .num_interrupts = APEX_INTERRUPT_COUNT,
++      .interrupts = apex_interrupts,
++      .interrupt_pack_width = 7,
++
++      .device_open_cb = apex_device_open_cb,
++      .device_close_cb = apex_device_cleanup,
++
++      .ioctl_handler_cb = apex_ioctl,
++      .device_status_cb = apex_get_status,
++      .hardware_revision_cb = NULL,
++      .device_reset_cb = apex_reset,
++};
++
++static struct pci_driver apex_pci_driver = {
++      .name = "apex",
++      .probe = apex_pci_probe,
++      .remove = apex_pci_remove,
++#ifdef CONFIG_PM_SLEEP
++      .suspend = apex_pci_suspend,
++      .resume = apex_pci_resume,
++#endif
++      .id_table = apex_pci_ids,
++};
++
++static int __init apex_init(void)
++{
++      int ret;
++
++      ret = gasket_register_device(&apex_desc);
++      if (ret)
++              return ret;
++      ret = pci_register_driver(&apex_pci_driver);
++      if (ret)
++              gasket_unregister_device(&apex_desc);
++      return ret;
++}
++
++static void apex_exit(void)
++{
++      pci_unregister_driver(&apex_pci_driver);
++      gasket_unregister_device(&apex_desc);
++}
++MODULE_DESCRIPTION("Google Apex driver");
++MODULE_VERSION(APEX_DRIVER_VERSION);
++MODULE_LICENSE("GPL v2");
++MODULE_AUTHOR("John Joseph <jnjoseph@google.com>");
++MODULE_DEVICE_TABLE(pci, apex_pci_ids);
++module_init(apex_init);
++module_exit(apex_exit);
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/apex.h b/drivers/staging/gasket-driver/apex.h
+--- a/drivers/staging/gasket-driver/apex.h     1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/apex.h     2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,45 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Apex kernel-userspace interface definitions.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++#ifndef __APEX_H__
++#define __APEX_H__
++
++#include <linux/ioctl.h>
++
++/* Clock Gating ioctl. */
++struct apex_gate_clock_ioctl {
++      /* Enter or leave clock gated state. */
++      u64 enable;
++
++      /* If set, enter clock gating state, regardless of custom block's
++       * internal idle state
++       */
++      u64 force_idle;
++};
++
++/* Performance expectation ioctl. */
++enum apex_performance_expectation {
++        APEX_PERFORMANCE_LOW = 0,
++        APEX_PERFORMANCE_MED = 1,
++        APEX_PERFORMANCE_HIGH = 2,
++        APEX_PERFORMANCE_MAX = 3,
++};
++
++struct apex_performance_expectation_ioctl {
++        /* Expected performance from apex. */
++        uint32_t performance;
++};
++
++/* Base number for all Apex-common IOCTLs */
++#define APEX_IOCTL_BASE 0x7F
++
++/* Enable/Disable clock gating. */
++#define APEX_IOCTL_GATE_CLOCK                                                  \
++      _IOW(APEX_IOCTL_BASE, 0, struct apex_gate_clock_ioctl)
++
++#define APEX_IOCTL_PERFORMANCE_EXPECTATION _IOW(APEX_IOCTL_BASE, 1, struct apex_performance_expectation_ioctl)
++
++#endif /* __APEX_H__ */
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_constants.h b/drivers/staging/gasket-driver/gasket_constants.h
+--- a/drivers/staging/gasket-driver/gasket_constants.h 1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_constants.h 2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,47 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/* Copyright (C) 2018 Google, Inc. */
++#ifndef __GASKET_CONSTANTS_H__
++#define __GASKET_CONSTANTS_H__
++
++#define GASKET_FRAMEWORK_VERSION "1.1.4"
++
++/*
++ * The maximum number of simultaneous device types supported by the framework.
++ */
++#define GASKET_FRAMEWORK_DESC_MAX 2
++
++/* The maximum devices per each type. */
++#define GASKET_DEV_MAX 256
++
++/* The number of supported (and possible) PCI BARs. */
++#define GASKET_NUM_BARS 6
++
++/* The number of supported Gasket page tables per device. */
++#define GASKET_MAX_NUM_PAGE_TABLES 1
++
++/* Maximum length of device names (driver name + minor number suffix + NULL). */
++#define GASKET_NAME_MAX 32
++
++/* Device status enumeration. */
++enum gasket_status {
++      /*
++       * A device is DEAD if it has not been initialized or has had an error.
++       */
++      GASKET_STATUS_DEAD = 0,
++      /*
++       * A device is LAMED if the hardware is healthy but the kernel was
++       * unable to enable some functionality (e.g. interrupts).
++       */
++      GASKET_STATUS_LAMED,
++
++      /* A device is ALIVE if it is ready for operation. */
++      GASKET_STATUS_ALIVE,
++
++      /*
++       * This status is set when the driver is exiting and waiting for all
++       * handles to be closed.
++       */
++      GASKET_STATUS_DRIVER_EXIT,
++};
++
++#endif
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_core.c b/drivers/staging/gasket-driver/gasket_core.c
+--- a/drivers/staging/gasket-driver/gasket_core.c      1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_core.c      2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,1936 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Gasket generic driver framework. This file contains the implementation
++ * for the Gasket generic driver framework - the functionality that is common
++ * across Gasket devices.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include "gasket_core.h"
++
++#include "gasket_interrupt.h"
++#include "gasket_ioctl.h"
++#include "gasket_page_table.h"
++#include "gasket_sysfs.h"
++
++#include <linux/capability.h>
++#include <linux/compiler.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/of.h>
++#include <linux/pid_namespace.h>
++#include <linux/platform_device.h>
++#include <linux/printk.h>
++#include <linux/sched.h>
++#include <linux/version.h>
++
++#ifdef GASKET_KERNEL_TRACE_SUPPORT
++#define CREATE_TRACE_POINTS
++#include <trace/events/gasket_mmap.h>
++#else
++#define trace_gasket_mmap_exit(x)
++#define trace_gasket_mmap_entry(x, ...)
++#endif
++
++/*
++ * "Private" members of gasket_driver_desc.
++ *
++ * Contains internal per-device type tracking data, i.e., data not appropriate
++ * as part of the public interface for the generic framework.
++ */
++struct gasket_internal_desc {
++      /* Device-specific-driver-provided configuration information. */
++      const struct gasket_driver_desc *driver_desc;
++
++      /* Protects access to per-driver data (i.e. this structure). */
++      struct mutex mutex;
++
++      /* Kernel-internal device class. */
++      struct class *class;
++
++      /* Instantiated / present devices of this type. */
++      struct gasket_dev *devs[GASKET_DEV_MAX];
++};
++
++/* do_map_region() needs be able to return more than just true/false. */
++enum do_map_region_status {
++      /* The region was successfully mapped. */
++      DO_MAP_REGION_SUCCESS,
++
++      /* Attempted to map region and failed. */
++      DO_MAP_REGION_FAILURE,
++
++      /* The requested region to map was not part of a mappable region. */
++      DO_MAP_REGION_INVALID,
++};
++
++/* Global data definitions. */
++/* Mutex - only for framework-wide data. Other data should be protected by
++ * finer-grained locks.
++ */
++static DEFINE_MUTEX(g_mutex);
++
++/* List of all registered device descriptions & their supporting data. */
++static struct gasket_internal_desc g_descs[GASKET_FRAMEWORK_DESC_MAX];
++
++/* Mapping of statuses to human-readable strings. Must end with {0,NULL}. */
++static const struct gasket_num_name gasket_status_name_table[] = {
++      { GASKET_STATUS_DEAD, "DEAD" },
++      { GASKET_STATUS_ALIVE, "ALIVE" },
++      { GASKET_STATUS_LAMED, "LAMED" },
++      { GASKET_STATUS_DRIVER_EXIT, "DRIVER_EXITING" },
++      { 0, NULL },
++};
++
++/* Enumeration of the automatic Gasket framework sysfs nodes. */
++enum gasket_sysfs_attribute_type {
++      ATTR_BAR_OFFSETS,
++      ATTR_BAR_SIZES,
++      ATTR_DRIVER_VERSION,
++      ATTR_FRAMEWORK_VERSION,
++      ATTR_DEVICE_TYPE,
++      ATTR_HARDWARE_REVISION,
++      ATTR_PCI_ADDRESS,
++      ATTR_STATUS,
++      ATTR_IS_DEVICE_OWNED,
++      ATTR_DEVICE_OWNER,
++      ATTR_WRITE_OPEN_COUNT,
++      ATTR_RESET_COUNT,
++      ATTR_USER_MEM_RANGES
++};
++
++/* On some arm64 systems pcie dma controller can only access lower 4GB of
++ * addresses. Unfortunately vendor BSP isn't providing any means of determining
++ * this limitation and there're no errors reported if access to higher addresses
++ * if being done. This parameter allows to workaround this issue by pretending
++ * that our device only supports 32 bit addresses. This in turn will cause
++ * dma driver to use shadow buffers located in low 32 bit address space.
++ */
++static int dma_bit_mask = 64;
++module_param(dma_bit_mask, int, 0644);
++
++/* Perform a standard Gasket callback. */
++static inline int
++check_and_invoke_callback(struct gasket_dev *gasket_dev,
++                        int (*cb_function)(struct gasket_dev *))
++{
++      int ret = 0;
++
++      if (cb_function) {
++              mutex_lock(&gasket_dev->mutex);
++              ret = cb_function(gasket_dev);
++              mutex_unlock(&gasket_dev->mutex);
++      }
++      return ret;
++}
++
++/* Perform a standard Gasket callback without grabbing gasket_dev->mutex. */
++static inline int
++gasket_check_and_invoke_callback_nolock(struct gasket_dev *gasket_dev,
++                                      int (*cb_function)(struct gasket_dev *))
++{
++      int ret = 0;
++
++      if (cb_function)
++              ret = cb_function(gasket_dev);
++      return ret;
++}
++
++/*
++ * Return nonzero if the gasket_cdev_info is owned by the current thread group
++ * ID.
++ */
++static int gasket_owned_by_current_tgid(struct gasket_cdev_info *info)
++{
++      return (info->ownership.is_owned &&
++              (info->ownership.owner == current->tgid));
++}
++
++/*
++ * Find the next free gasket_internal_dev slot.
++ *
++ * Returns the located slot number on success or a negative number on failure.
++ */
++static int gasket_find_dev_slot(struct gasket_internal_desc *internal_desc,
++                              const char *kobj_name)
++{
++      int i;
++
++      mutex_lock(&internal_desc->mutex);
++
++      /* Search for a previous instance of this device. */
++      for (i = 0; i < GASKET_DEV_MAX; i++) {
++              if (internal_desc->devs[i] &&
++                  strcmp(internal_desc->devs[i]->kobj_name, kobj_name) == 0) {
++                      pr_err("Duplicate device %s\n", kobj_name);
++                      mutex_unlock(&internal_desc->mutex);
++                      return -EBUSY;
++              }
++      }
++
++      /* Find a free device slot. */
++      for (i = 0; i < GASKET_DEV_MAX; i++) {
++              if (!internal_desc->devs[i])
++                      break;
++      }
++
++      if (i == GASKET_DEV_MAX) {
++              pr_err("Too many registered devices; max %d\n", GASKET_DEV_MAX);
++              mutex_unlock(&internal_desc->mutex);
++              return -EBUSY;
++      }
++
++      mutex_unlock(&internal_desc->mutex);
++      return i;
++}
++
++/*
++ * Allocate and initialize a Gasket device structure, add the device to the
++ * device list.
++ *
++ * Returns 0 if successful, a negative error code otherwise.
++ */
++static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc,
++                          struct device *parent, struct gasket_dev **pdev)
++{
++      int dev_idx;
++      const struct gasket_driver_desc *driver_desc =
++              internal_desc->driver_desc;
++      struct gasket_dev *gasket_dev;
++      struct gasket_cdev_info *dev_info;
++      const char *parent_name = dev_name(parent);
++
++      pr_debug("Allocating a Gasket device, parent %s.\n", parent_name);
++
++      *pdev = NULL;
++
++      dev_idx = gasket_find_dev_slot(internal_desc, parent_name);
++      if (dev_idx < 0)
++              return dev_idx;
++
++      gasket_dev = *pdev = kzalloc(sizeof(*gasket_dev), GFP_KERNEL);
++      if (!gasket_dev) {
++              pr_err("no memory for device, parent %s\n", parent_name);
++              return -ENOMEM;
++      }
++      internal_desc->devs[dev_idx] = gasket_dev;
++
++      mutex_init(&gasket_dev->mutex);
++
++      gasket_dev->internal_desc = internal_desc;
++      gasket_dev->dev_idx = dev_idx;
++      snprintf(gasket_dev->kobj_name, GASKET_NAME_MAX, "%s", parent_name);
++      gasket_dev->dev = get_device(parent);
++      gasket_dev->dma_dev = get_device(parent);
++      /* gasket_bar_data is uninitialized. */
++      gasket_dev->num_page_tables = driver_desc->num_page_tables;
++      /* max_page_table_size and *page table are uninit'ed */
++      /* interrupt_data is not initialized. */
++      /* status is 0, or GASKET_STATUS_DEAD */
++
++      dev_info = &gasket_dev->dev_info;
++      snprintf(dev_info->name, GASKET_NAME_MAX, "%s_%u", driver_desc->name,
++               gasket_dev->dev_idx);
++      dev_info->devt =
++              MKDEV(driver_desc->major, driver_desc->minor +
++                    gasket_dev->dev_idx);
++      dev_info->device =
++              device_create(internal_desc->class, parent, dev_info->devt,
++                            gasket_dev, dev_info->name);
++
++      /* cdev has not yet been added; cdev_added is 0 */
++      dev_info->gasket_dev_ptr = gasket_dev;
++      /* ownership is all 0, indicating no owner or opens. */
++
++      return 0;
++}
++
++/* Free a Gasket device. */
++static void gasket_free_dev(struct gasket_dev *gasket_dev)
++{
++      struct gasket_internal_desc *internal_desc = gasket_dev->internal_desc;
++
++      mutex_lock(&internal_desc->mutex);
++      internal_desc->devs[gasket_dev->dev_idx] = NULL;
++      mutex_unlock(&internal_desc->mutex);
++      put_device(gasket_dev->dev);
++      put_device(gasket_dev->dma_dev);
++      kfree(gasket_dev);
++}
++
++/*
++ * Maps the specified bar into kernel space.
++ *
++ * Returns 0 on success, a negative error code otherwise.
++ * A zero-sized BAR will not be mapped, but is not an error.
++ */
++static int gasket_map_pci_bar(struct gasket_dev *gasket_dev, int bar_num)
++{
++      struct gasket_internal_desc *internal_desc = gasket_dev->internal_desc;
++      const struct gasket_driver_desc *driver_desc =
++              internal_desc->driver_desc;
++      ulong desc_bytes = driver_desc->bar_descriptions[bar_num].size;
++      int ret;
++
++      if (desc_bytes == 0)
++              return 0;
++
++      if (driver_desc->bar_descriptions[bar_num].type != PCI_BAR) {
++              /* not PCI: skip this entry */
++              return 0;
++      }
++      /*
++       * pci_resource_start and pci_resource_len return a "resource_size_t",
++       * which is safely castable to ulong (which itself is the arg to
++       * request_mem_region).
++       */
++      gasket_dev->bar_data[bar_num].phys_base =
++              (ulong)pci_resource_start(gasket_dev->pci_dev, bar_num);
++      if (!gasket_dev->bar_data[bar_num].phys_base) {
++              dev_err(gasket_dev->dev, "Cannot get BAR%u base address\n",
++                      bar_num);
++              return -EINVAL;
++      }
++
++      gasket_dev->bar_data[bar_num].length_bytes =
++              (ulong)pci_resource_len(gasket_dev->pci_dev, bar_num);
++      if (gasket_dev->bar_data[bar_num].length_bytes < desc_bytes) {
++              dev_err(gasket_dev->dev,
++                      "PCI BAR %u space is too small: %lu; expected >= %lu\n",
++                      bar_num, gasket_dev->bar_data[bar_num].length_bytes,
++                      desc_bytes);
++              return -ENOMEM;
++      }
++
++      if (!request_mem_region(gasket_dev->bar_data[bar_num].phys_base,
++                              gasket_dev->bar_data[bar_num].length_bytes,
++                              gasket_dev->dev_info.name)) {
++              dev_err(gasket_dev->dev,
++                      "Cannot get BAR %d memory region %p\n",
++                      bar_num, &gasket_dev->pci_dev->resource[bar_num]);
++              return -EINVAL;
++      }
++
++      gasket_dev->bar_data[bar_num].virt_base =
++              ioremap(gasket_dev->bar_data[bar_num].phys_base,
++                      gasket_dev->bar_data[bar_num].length_bytes);
++      if (!gasket_dev->bar_data[bar_num].virt_base) {
++              dev_err(gasket_dev->dev,
++                      "Cannot remap BAR %d memory region %p\n",
++                      bar_num, &gasket_dev->pci_dev->resource[bar_num]);
++              ret = -ENOMEM;
++              goto fail;
++      }
++
++      dma_set_mask(&gasket_dev->pci_dev->dev, DMA_BIT_MASK(dma_bit_mask));
++      dma_set_coherent_mask(&gasket_dev->pci_dev->dev,
++                            DMA_BIT_MASK(dma_bit_mask));
++
++      return 0;
++
++fail:
++      iounmap(gasket_dev->bar_data[bar_num].virt_base);
++      release_mem_region(gasket_dev->bar_data[bar_num].phys_base,
++                         gasket_dev->bar_data[bar_num].length_bytes);
++      return ret;
++}
++
++/*
++ * Releases PCI BAR mapping.
++ *
++ * A zero-sized or not-mapped BAR will not be unmapped, but is not an error.
++ */
++static void gasket_unmap_pci_bar(struct gasket_dev *dev, int bar_num)
++{
++      ulong base, bytes;
++      struct gasket_internal_desc *internal_desc = dev->internal_desc;
++      const struct gasket_driver_desc *driver_desc =
++              internal_desc->driver_desc;
++
++      if (driver_desc->bar_descriptions[bar_num].size == 0 ||
++          !dev->bar_data[bar_num].virt_base)
++              return;
++
++      if (driver_desc->bar_descriptions[bar_num].type != PCI_BAR)
++              return;
++
++      iounmap(dev->bar_data[bar_num].virt_base);
++      dev->bar_data[bar_num].virt_base = NULL;
++
++      base = pci_resource_start(dev->pci_dev, bar_num);
++      if (!base) {
++              dev_err(dev->dev, "cannot get PCI BAR%u base address\n",
++                      bar_num);
++              return;
++      }
++
++      bytes = pci_resource_len(dev->pci_dev, bar_num);
++      release_mem_region(base, bytes);
++}
++
++/*
++ * Setup PCI memory mapping for the specified device.
++ *
++ * Reads the BAR registers and sets up pointers to the device's memory mapped
++ * IO space.
++ *
++ * Returns 0 on success and a negative value otherwise.
++ */
++static int gasket_setup_pci(struct pci_dev *pci_dev,
++                          struct gasket_dev *gasket_dev)
++{
++      int i, mapped_bars, ret;
++
++      for (i = 0; i < GASKET_NUM_BARS; i++) {
++              ret = gasket_map_pci_bar(gasket_dev, i);
++              if (ret) {
++                      mapped_bars = i;
++                      goto fail;
++              }
++      }
++
++      return 0;
++
++fail:
++      for (i = 0; i < mapped_bars; i++)
++              gasket_unmap_pci_bar(gasket_dev, i);
++
++      return -ENOMEM;
++}
++
++/* Unmaps memory for the specified device. */
++static void gasket_cleanup_pci(struct gasket_dev *gasket_dev)
++{
++      int i;
++
++      for (i = 0; i < GASKET_NUM_BARS; i++)
++              gasket_unmap_pci_bar(gasket_dev, i);
++}
++
++/* Determine the health of the Gasket device. */
++static int gasket_get_hw_status(struct gasket_dev *gasket_dev)
++{
++      int status;
++      int i;
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++
++      status = gasket_check_and_invoke_callback_nolock(gasket_dev,
++                                                       driver_desc->device_status_cb);
++      if (status != GASKET_STATUS_ALIVE) {
++              dev_dbg(gasket_dev->dev, "Hardware reported status %d.\n",
++                      status);
++              return status;
++      }
++
++      status = gasket_interrupt_system_status(gasket_dev);
++      if (status != GASKET_STATUS_ALIVE) {
++              dev_dbg(gasket_dev->dev,
++                      "Interrupt system reported status %d.\n", status);
++              return status;
++      }
++
++      for (i = 0; i < driver_desc->num_page_tables; ++i) {
++              status = gasket_page_table_system_status(gasket_dev->page_table[i]);
++              if (status != GASKET_STATUS_ALIVE) {
++                      dev_dbg(gasket_dev->dev,
++                              "Page table %d reported status %d.\n",
++                              i, status);
++                      return status;
++              }
++      }
++
++      return GASKET_STATUS_ALIVE;
++}
++
++static ssize_t
++gasket_write_mappable_regions(char *buf,
++                            const struct gasket_driver_desc *driver_desc,
++                            int bar_index)
++{
++      int i;
++      ssize_t written;
++      ssize_t total_written = 0;
++      ulong min_addr, max_addr;
++      struct gasket_bar_desc bar_desc =
++              driver_desc->bar_descriptions[bar_index];
++
++      if (bar_desc.permissions == GASKET_NOMAP)
++              return 0;
++      for (i = 0;
++           i < bar_desc.num_mappable_regions && total_written < PAGE_SIZE;
++           i++) {
++              min_addr = bar_desc.mappable_regions[i].start -
++                         driver_desc->legacy_mmap_address_offset;
++              max_addr = bar_desc.mappable_regions[i].start -
++                         driver_desc->legacy_mmap_address_offset +
++                         bar_desc.mappable_regions[i].length_bytes;
++              written = scnprintf(buf, PAGE_SIZE - total_written,
++                                  "0x%08lx-0x%08lx\n", min_addr, max_addr);
++              total_written += written;
++              buf += written;
++      }
++      return total_written;
++}
++
++static ssize_t gasket_sysfs_data_show(struct device *device,
++                                    struct device_attribute *attr, char *buf)
++{
++      int i, ret = 0;
++      ssize_t current_written = 0;
++      const struct gasket_driver_desc *driver_desc;
++      struct gasket_dev *gasket_dev;
++      struct gasket_sysfs_attribute *gasket_attr;
++      const struct gasket_bar_desc *bar_desc;
++      enum gasket_sysfs_attribute_type sysfs_type;
++
++      gasket_dev = gasket_sysfs_get_device_data(device);
++      if (!gasket_dev) {
++              dev_err(device, "No sysfs mapping found for device\n");
++              return 0;
++      }
++
++      gasket_attr = gasket_sysfs_get_attr(device, attr);
++      if (!gasket_attr) {
++              dev_err(device, "No sysfs attr found for device\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return 0;
++      }
++
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++
++      sysfs_type =
++              (enum gasket_sysfs_attribute_type)gasket_attr->data.attr_type;
++      switch (sysfs_type) {
++      case ATTR_BAR_OFFSETS:
++              for (i = 0; i < GASKET_NUM_BARS; i++) {
++                      bar_desc = &driver_desc->bar_descriptions[i];
++                      if (bar_desc->size == 0)
++                              continue;
++                      current_written =
++                              snprintf(buf, PAGE_SIZE - ret, "%d: 0x%lx\n", i,
++                                       (ulong)bar_desc->base);
++                      buf += current_written;
++                      ret += current_written;
++              }
++              break;
++      case ATTR_BAR_SIZES:
++              for (i = 0; i < GASKET_NUM_BARS; i++) {
++                      bar_desc = &driver_desc->bar_descriptions[i];
++                      if (bar_desc->size == 0)
++                              continue;
++                      current_written =
++                              snprintf(buf, PAGE_SIZE - ret, "%d: 0x%lx\n", i,
++                                       (ulong)bar_desc->size);
++                      buf += current_written;
++                      ret += current_written;
++              }
++              break;
++      case ATTR_DRIVER_VERSION:
++              ret = snprintf(buf, PAGE_SIZE, "%s\n",
++                             gasket_dev->internal_desc->driver_desc->driver_version);
++              break;
++      case ATTR_FRAMEWORK_VERSION:
++              ret = snprintf(buf, PAGE_SIZE, "%s\n",
++                             GASKET_FRAMEWORK_VERSION);
++              break;
++      case ATTR_DEVICE_TYPE:
++              ret = snprintf(buf, PAGE_SIZE, "%s\n",
++                             gasket_dev->internal_desc->driver_desc->name);
++              break;
++      case ATTR_HARDWARE_REVISION:
++              ret = snprintf(buf, PAGE_SIZE, "%d\n",
++                             gasket_dev->hardware_revision);
++              break;
++      case ATTR_PCI_ADDRESS:
++              ret = snprintf(buf, PAGE_SIZE, "%s\n", gasket_dev->kobj_name);
++              break;
++      case ATTR_STATUS:
++              ret = snprintf(buf, PAGE_SIZE, "%s\n",
++                             gasket_num_name_lookup(gasket_dev->status,
++                                                    gasket_status_name_table));
++              break;
++      case ATTR_IS_DEVICE_OWNED:
++              ret = snprintf(buf, PAGE_SIZE, "%d\n",
++                             gasket_dev->dev_info.ownership.is_owned);
++              break;
++      case ATTR_DEVICE_OWNER:
++              ret = snprintf(buf, PAGE_SIZE, "%d\n",
++                             gasket_dev->dev_info.ownership.owner);
++              break;
++      case ATTR_WRITE_OPEN_COUNT:
++              ret = snprintf(buf, PAGE_SIZE, "%d\n",
++                             gasket_dev->dev_info.ownership.write_open_count);
++              break;
++      case ATTR_RESET_COUNT:
++              ret = snprintf(buf, PAGE_SIZE, "%d\n", gasket_dev->reset_count);
++              break;
++      case ATTR_USER_MEM_RANGES:
++              for (i = 0; i < GASKET_NUM_BARS; ++i) {
++                      current_written =
++                              gasket_write_mappable_regions(buf, driver_desc,
++                                                            i);
++                      buf += current_written;
++                      ret += current_written;
++              }
++              break;
++      default:
++              dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
++                      attr->attr.name);
++              ret = 0;
++              break;
++      }
++
++      gasket_sysfs_put_attr(device, gasket_attr);
++      gasket_sysfs_put_device_data(device, gasket_dev);
++      return ret;
++}
++
++/* These attributes apply to all Gasket driver instances. */
++static const struct gasket_sysfs_attribute gasket_sysfs_generic_attrs[] = {
++      GASKET_SYSFS_RO(bar_offsets, gasket_sysfs_data_show, ATTR_BAR_OFFSETS),
++      GASKET_SYSFS_RO(bar_sizes, gasket_sysfs_data_show, ATTR_BAR_SIZES),
++      GASKET_SYSFS_RO(driver_version, gasket_sysfs_data_show,
++                      ATTR_DRIVER_VERSION),
++      GASKET_SYSFS_RO(framework_version, gasket_sysfs_data_show,
++                      ATTR_FRAMEWORK_VERSION),
++      GASKET_SYSFS_RO(device_type, gasket_sysfs_data_show, ATTR_DEVICE_TYPE),
++      GASKET_SYSFS_RO(revision, gasket_sysfs_data_show,
++                      ATTR_HARDWARE_REVISION),
++      GASKET_SYSFS_RO(pci_address, gasket_sysfs_data_show, ATTR_PCI_ADDRESS),
++      GASKET_SYSFS_RO(status, gasket_sysfs_data_show, ATTR_STATUS),
++      GASKET_SYSFS_RO(is_device_owned, gasket_sysfs_data_show,
++                      ATTR_IS_DEVICE_OWNED),
++      GASKET_SYSFS_RO(device_owner, gasket_sysfs_data_show,
++                      ATTR_DEVICE_OWNER),
++      GASKET_SYSFS_RO(write_open_count, gasket_sysfs_data_show,
++                      ATTR_WRITE_OPEN_COUNT),
++      GASKET_SYSFS_RO(reset_count, gasket_sysfs_data_show, ATTR_RESET_COUNT),
++      GASKET_SYSFS_RO(user_mem_ranges, gasket_sysfs_data_show,
++                      ATTR_USER_MEM_RANGES),
++      GASKET_END_OF_ATTR_ARRAY
++};
++
++/* Add a char device and related info. */
++static int gasket_add_cdev(struct gasket_cdev_info *dev_info,
++                         const struct file_operations *file_ops,
++                         struct module *owner)
++{
++      int ret;
++
++      cdev_init(&dev_info->cdev, file_ops);
++      dev_info->cdev.owner = owner;
++      ret = cdev_add(&dev_info->cdev, dev_info->devt, 1);
++      if (ret) {
++              dev_err(dev_info->gasket_dev_ptr->dev,
++                      "cannot add char device [ret=%d]\n", ret);
++              return ret;
++      }
++      dev_info->cdev_added = 1;
++
++      return 0;
++}
++
++/* Disable device operations. */
++void gasket_disable_device(struct gasket_dev *gasket_dev)
++{
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++      int i;
++
++      dev_dbg(gasket_dev->dev, "disabling device\n");
++      /* Only delete the device if it has been successfully added. */
++      if (gasket_dev->dev_info.cdev_added)
++              cdev_del(&gasket_dev->dev_info.cdev);
++
++      gasket_dev->status = GASKET_STATUS_DEAD;
++
++      gasket_interrupt_cleanup(gasket_dev);
++
++      for (i = 0; i < driver_desc->num_page_tables; ++i) {
++              if (gasket_dev->page_table[i]) {
++                      gasket_page_table_reset(gasket_dev->page_table[i]);
++                      gasket_page_table_cleanup(gasket_dev->page_table[i]);
++              }
++      }
++}
++EXPORT_SYMBOL(gasket_disable_device);
++
++/*
++ * Registered driver descriptor lookup for PCI devices.
++ *
++ * Precondition: Called with g_mutex held (to avoid a race on return).
++ * Returns NULL if no matching device was found.
++ */
++static struct gasket_internal_desc *
++lookup_pci_internal_desc(struct pci_dev *pci_dev)
++{
++      int i;
++
++      __must_hold(&g_mutex);
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              if (g_descs[i].driver_desc &&
++                  g_descs[i].driver_desc->pci_id_table &&
++                  pci_match_id(g_descs[i].driver_desc->pci_id_table, pci_dev))
++                      return &g_descs[i];
++      }
++
++      return NULL;
++}
++
++/*
++ * Registered driver descriptor lookup for platform devices.
++ * Caller must hold g_mutex.
++ */
++static struct gasket_internal_desc *
++lookup_platform_internal_desc(struct platform_device *pdev)
++{
++      int i;
++
++      __must_hold(&g_mutex);
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              if (g_descs[i].driver_desc &&
++                  strcmp(g_descs[i].driver_desc->name, pdev->name) == 0)
++                      return &g_descs[i];
++      }
++
++      return NULL;
++}
++
++/*
++ * Verifies that the user has permissions to perform the requested mapping and
++ * that the provided descriptor/range is of adequate size to hold the range to
++ * be mapped.
++ */
++static bool gasket_mmap_has_permissions(struct gasket_dev *gasket_dev,
++                                      struct vm_area_struct *vma,
++                                      int bar_permissions)
++{
++      int requested_permissions;
++      /* Always allow sysadmin to access. */
++      if (capable(CAP_SYS_ADMIN))
++              return true;
++
++      /* Never allow non-sysadmins to access to a dead device. */
++      if (gasket_dev->status != GASKET_STATUS_ALIVE) {
++              dev_dbg(gasket_dev->dev, "Device is dead.\n");
++              return false;
++      }
++
++      /* Make sure that no wrong flags are set. */
++      requested_permissions =
++              (vma->vm_flags & (VM_WRITE | VM_READ | VM_EXEC));
++      if (requested_permissions & ~(bar_permissions)) {
++              dev_dbg(gasket_dev->dev,
++                      "Attempting to map a region with requested permissions "
++                      "0x%x, but region has permissions 0x%x.\n",
++                      requested_permissions, bar_permissions);
++              return false;
++      }
++
++      /* Do not allow a non-owner to write. */
++      if ((vma->vm_flags & VM_WRITE) &&
++          !gasket_owned_by_current_tgid(&gasket_dev->dev_info)) {
++              dev_dbg(gasket_dev->dev,
++                      "Attempting to mmap a region for write without owning "
++                      "device.\n");
++              return false;
++      }
++
++      return true;
++}
++
++/*
++ * Verifies that the input address is within the region allocated to coherent
++ * buffer.
++ */
++static bool
++gasket_is_coherent_region(const struct gasket_driver_desc *driver_desc,
++                        ulong address)
++{
++      struct gasket_coherent_buffer_desc coh_buff_desc =
++              driver_desc->coherent_buffer_description;
++
++      if (coh_buff_desc.permissions != GASKET_NOMAP) {
++              if ((address >= coh_buff_desc.base) &&
++                  (address < coh_buff_desc.base + coh_buff_desc.size)) {
++                      return true;
++              }
++      }
++      return false;
++}
++
++static int gasket_get_bar_index(const struct gasket_dev *gasket_dev,
++                              ulong phys_addr)
++{
++      int i;
++      const struct gasket_driver_desc *driver_desc;
++
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++      for (i = 0; i < GASKET_NUM_BARS; ++i) {
++              struct gasket_bar_desc bar_desc =
++                      driver_desc->bar_descriptions[i];
++
++              if (bar_desc.permissions != GASKET_NOMAP) {
++                      if (phys_addr >= bar_desc.base &&
++                          phys_addr < (bar_desc.base + bar_desc.size)) {
++                              return i;
++                      }
++              }
++      }
++      /* If we haven't found the address by now, it is invalid. */
++      return -EINVAL;
++}
++
++/*
++ * Sets the actual bounds to map, given the device's mappable region.
++ *
++ * Given the device's mappable region, along with the user-requested mapping
++ * start offset and length of the user region, determine how much of this
++ * mappable region can be mapped into the user's region (start/end offsets),
++ * and the physical offset (phys_offset) into the BAR where the mapping should
++ * begin (either the VMA's or region lower bound).
++ *
++ * In other words, this calculates the overlap between the VMA
++ * (bar_offset, requested_length) and the given gasket_mappable_region.
++ *
++ * Returns true if there's anything to map, and false otherwise.
++ */
++static bool
++gasket_mm_get_mapping_addrs(const struct gasket_mappable_region *region,
++                          ulong bar_offset, ulong requested_length,
++                          struct gasket_mappable_region *mappable_region,
++                          ulong *virt_offset)
++{
++      ulong range_start = region->start;
++      ulong range_length = region->length_bytes;
++      ulong range_end = range_start + range_length;
++
++      *virt_offset = 0;
++      if (bar_offset + requested_length < range_start) {
++              /*
++               * If the requested region is completely below the range,
++               * there is nothing to map.
++               */
++              return false;
++      } else if (bar_offset <= range_start) {
++              /* If the bar offset is below this range's start
++               * but the requested length continues into it:
++               * 1) Only map starting from the beginning of this
++               *      range's phys. offset, so we don't map unmappable
++               *      memory.
++               * 2) The length of the virtual memory to not map is the
++               *      delta between the bar offset and the
++               *      mappable start (and since the mappable start is
++               *      bigger, start - req.)
++               * 3) The map length is the minimum of the mappable
++               *      requested length (requested_length - virt_offset)
++               *      and the actual mappable length of the range.
++               */
++              mappable_region->start = range_start;
++              *virt_offset = range_start - bar_offset;
++              mappable_region->length_bytes =
++                      min(requested_length - *virt_offset, range_length);
++              return true;
++      } else if (bar_offset > range_start &&
++                 bar_offset < range_end) {
++              /*
++               * If the bar offset is within this range:
++               * 1) Map starting from the bar offset.
++               * 2) Because there is no forbidden memory between the
++               *      bar offset and the range start,
++               *      virt_offset is 0.
++               * 3) The map length is the minimum of the requested
++               *      length and the remaining length in the buffer
++               *      (range_end - bar_offset)
++               */
++              mappable_region->start = bar_offset;
++              *virt_offset = 0;
++              mappable_region->length_bytes =
++                      min(requested_length, range_end - bar_offset);
++              return true;
++      }
++
++      /*
++       * If the requested [start] offset is above range_end,
++       * there's nothing to map.
++       */
++      return false;
++}
++
++/*
++ * Calculates the offset where the VMA range begins in its containing BAR.
++ * The offset is written into bar_offset on success.
++ * Returns zero on success, anything else on error.
++ */
++static int gasket_mm_vma_bar_offset(const struct gasket_dev *gasket_dev,
++                                  const struct vm_area_struct *vma,
++                                  ulong *bar_offset)
++{
++      ulong raw_offset;
++      int bar_index;
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++
++      raw_offset = (vma->vm_pgoff << PAGE_SHIFT) +
++              driver_desc->legacy_mmap_address_offset;
++      bar_index = gasket_get_bar_index(gasket_dev, raw_offset);
++      if (bar_index < 0) {
++              dev_err(gasket_dev->dev,
++                      "Unable to find matching bar for address 0x%lx\n",
++                      raw_offset);
++              trace_gasket_mmap_exit(bar_index);
++              return bar_index;
++      }
++      *bar_offset =
++              raw_offset - driver_desc->bar_descriptions[bar_index].base;
++
++      return 0;
++}
++
++int gasket_mm_unmap_region(const struct gasket_dev *gasket_dev,
++                         struct vm_area_struct *vma,
++                         const struct gasket_mappable_region *map_region)
++{
++      ulong bar_offset;
++      ulong virt_offset;
++      struct gasket_mappable_region mappable_region;
++      int ret;
++
++      if (map_region->length_bytes == 0)
++              return 0;
++
++      ret = gasket_mm_vma_bar_offset(gasket_dev, vma, &bar_offset);
++      if (ret)
++              return ret;
++
++      if (!gasket_mm_get_mapping_addrs(map_region, bar_offset,
++                                       vma->vm_end - vma->vm_start,
++                                       &mappable_region, &virt_offset))
++              return 1;
++
++      /*
++       * The length passed to zap_vma_ptes MUST BE A MULTIPLE OF
++       * PAGE_SIZE! Trust me. I have the scars.
++       *
++       * Next multiple of y: ceil_div(x, y) * y
++       */
++      zap_vma_ptes(vma, vma->vm_start + virt_offset,
++                   DIV_ROUND_UP(mappable_region.length_bytes, PAGE_SIZE) *
++                   PAGE_SIZE);
++      return 0;
++}
++EXPORT_SYMBOL(gasket_mm_unmap_region);
++
++/* Maps a virtual address + range to a physical offset of a BAR. */
++static enum do_map_region_status
++do_map_region(const struct gasket_dev *gasket_dev, struct vm_area_struct *vma,
++            struct gasket_mappable_region *mappable_region)
++{
++      /* Maximum size of a single call to io_remap_pfn_range. */
++      /* I pulled this number out of thin air. */
++      const ulong max_chunk_size = 64 * 1024 * 1024;
++      ulong chunk_size, mapped_bytes = 0;
++
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++
++      ulong bar_offset, virt_offset;
++      struct gasket_mappable_region region_to_map;
++      ulong phys_offset, map_length;
++      ulong virt_base, phys_base;
++      int bar_index, ret;
++
++      ret = gasket_mm_vma_bar_offset(gasket_dev, vma, &bar_offset);
++      if (ret)
++              return DO_MAP_REGION_INVALID;
++
++      if (!gasket_mm_get_mapping_addrs(mappable_region, bar_offset,
++                                       vma->vm_end - vma->vm_start,
++                                       &region_to_map, &virt_offset))
++              return DO_MAP_REGION_INVALID;
++      phys_offset = region_to_map.start;
++      map_length = region_to_map.length_bytes;
++
++      virt_base = vma->vm_start + virt_offset;
++      bar_index =
++              gasket_get_bar_index(gasket_dev,
++                                   (vma->vm_pgoff << PAGE_SHIFT) +
++                                   driver_desc->legacy_mmap_address_offset);
++      phys_base = gasket_dev->bar_data[bar_index].phys_base + phys_offset;
++      while (mapped_bytes < map_length) {
++              /*
++               * io_remap_pfn_range can take a while, so we chunk its
++               * calls and call cond_resched between each.
++               */
++              chunk_size = min(max_chunk_size, map_length - mapped_bytes);
++
++              cond_resched();
++              ret = io_remap_pfn_range(vma, virt_base + mapped_bytes,
++                                       (phys_base + mapped_bytes) >>
++                                       PAGE_SHIFT, chunk_size,
++                                       vma->vm_page_prot);
++              if (ret) {
++                      dev_err(gasket_dev->dev,
++                              "Error remapping PFN range.\n");
++                      goto fail;
++              }
++              mapped_bytes += chunk_size;
++      }
++
++      return DO_MAP_REGION_SUCCESS;
++
++fail:
++      /* Unmap the partial chunk we mapped. */
++      mappable_region->length_bytes = mapped_bytes;
++      if (gasket_mm_unmap_region(gasket_dev, vma, mappable_region))
++              dev_err(gasket_dev->dev,
++                      "Error unmapping partial region 0x%lx (0x%lx bytes)\n",
++                      (ulong)virt_offset,
++                      (ulong)mapped_bytes);
++
++      return DO_MAP_REGION_FAILURE;
++}
++
++/* Map a region of coherent memory. */
++static int gasket_mmap_coherent(struct gasket_dev *gasket_dev,
++                              struct vm_area_struct *vma)
++{
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++      const ulong requested_length = vma->vm_end - vma->vm_start;
++      int ret;
++      ulong permissions;
++
++      if (requested_length == 0 || requested_length >
++          gasket_dev->coherent_buffer.length_bytes) {
++              trace_gasket_mmap_exit(-EINVAL);
++              return -EINVAL;
++      }
++
++      permissions = driver_desc->coherent_buffer_description.permissions;
++      if (!gasket_mmap_has_permissions(gasket_dev, vma, permissions)) {
++              dev_err(gasket_dev->dev, "Permission checking failed.\n");
++              trace_gasket_mmap_exit(-EPERM);
++              return -EPERM;
++      }
++
++      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++      vma->vm_pgoff = 0;
++      ret = dma_mmap_coherent(gasket_dev->dma_dev, vma,
++                              gasket_dev->coherent_buffer.virt_base,
++                              gasket_dev->coherent_buffer.phys_base,
++                              requested_length);
++      if (ret) {
++              dev_err(gasket_dev->dev,
++                      "Error mmapping coherent buffer err=%d.\n", ret);
++              trace_gasket_mmap_exit(ret);
++              return ret;
++      }
++
++      /* Record the user virtual to dma_address mapping that was
++       * created by the kernel.
++       */
++      gasket_set_user_virt(gasket_dev, requested_length,
++                           gasket_dev->coherent_buffer.phys_base,
++                           vma->vm_start);
++      return 0;
++}
++
++/* Map a device's BARs into user space. */
++static int gasket_mmap(struct file *filp, struct vm_area_struct *vma)
++{
++      int i, ret;
++      int bar_index;
++      int has_mapped_anything = 0;
++      ulong permissions;
++      ulong raw_offset, vma_size;
++      bool is_coherent_region;
++      const struct gasket_driver_desc *driver_desc;
++      struct gasket_dev *gasket_dev = (struct gasket_dev *)filp->private_data;
++      const struct gasket_bar_desc *bar_desc;
++      struct gasket_mappable_region *map_regions = NULL;
++      int num_map_regions = 0;
++      enum do_map_region_status map_status;
++
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++
++      if (vma->vm_start & ~PAGE_MASK) {
++              dev_err(gasket_dev->dev,
++                      "Base address not page-aligned: 0x%lx\n",
++                      vma->vm_start);
++              trace_gasket_mmap_exit(-EINVAL);
++              return -EINVAL;
++      }
++
++      /* Calculate the offset of this range into physical mem. */
++      raw_offset = (vma->vm_pgoff << PAGE_SHIFT) +
++              driver_desc->legacy_mmap_address_offset;
++      vma_size = vma->vm_end - vma->vm_start;
++      trace_gasket_mmap_entry(gasket_dev->dev_info.name, raw_offset,
++                              vma_size);
++
++      /*
++       * Check if the raw offset is within a bar region. If not, check if it
++       * is a coherent region.
++       */
++      bar_index = gasket_get_bar_index(gasket_dev, raw_offset);
++      is_coherent_region = gasket_is_coherent_region(driver_desc, raw_offset);
++      if (bar_index < 0 && !is_coherent_region) {
++              dev_err(gasket_dev->dev,
++                      "Unable to find matching bar for address 0x%lx\n",
++                      raw_offset);
++              trace_gasket_mmap_exit(bar_index);
++              return bar_index;
++      }
++      if (bar_index > 0 && is_coherent_region) {
++              dev_err(gasket_dev->dev,
++                      "double matching bar and coherent buffers for address "
++                      "0x%lx\n",
++                      raw_offset);
++              trace_gasket_mmap_exit(bar_index);
++              return -EINVAL;
++      }
++
++      vma->vm_private_data = gasket_dev;
++
++      if (is_coherent_region)
++              return gasket_mmap_coherent(gasket_dev, vma);
++
++      /* Everything in the rest of this function is for normal BAR mapping. */
++
++      /*
++       * Subtract the base of the bar from the raw offset to get the
++       * memory location within the bar to map.
++       */
++      bar_desc = &driver_desc->bar_descriptions[bar_index];
++      permissions = bar_desc->permissions;
++      if (!gasket_mmap_has_permissions(gasket_dev, vma, permissions)) {
++              dev_err(gasket_dev->dev, "Permission checking failed.\n");
++              trace_gasket_mmap_exit(-EPERM);
++              return -EPERM;
++      }
++
++      if (driver_desc->get_mappable_regions_cb) {
++              ret = driver_desc->get_mappable_regions_cb(gasket_dev,
++                                                         bar_index,
++                                                         &map_regions,
++                                                         &num_map_regions);
++              if (ret)
++                      return ret;
++      } else {
++              if (!gasket_mmap_has_permissions(gasket_dev, vma,
++                                               bar_desc->permissions)) {
++                      dev_err(gasket_dev->dev,
++                              "Permission checking failed.\n");
++                      trace_gasket_mmap_exit(-EPERM);
++                      return -EPERM;
++              }
++              num_map_regions = bar_desc->num_mappable_regions;
++              map_regions = kcalloc(num_map_regions,
++                                    sizeof(*bar_desc->mappable_regions),
++                                    GFP_KERNEL);
++              if (map_regions) {
++                      memcpy(map_regions, bar_desc->mappable_regions,
++                             num_map_regions *
++                                      sizeof(*bar_desc->mappable_regions));
++              }
++      }
++
++      if (!map_regions || num_map_regions == 0) {
++              dev_err(gasket_dev->dev, "No mappable regions returned!\n");
++              return -EINVAL;
++      }
++
++      /* Marks the VMA's pages as uncacheable. */
++      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++      for (i = 0; i < num_map_regions; i++) {
++              map_status = do_map_region(gasket_dev, vma, &map_regions[i]);
++              /* Try the next region if this one was not mappable. */
++              if (map_status == DO_MAP_REGION_INVALID)
++                      continue;
++              if (map_status == DO_MAP_REGION_FAILURE) {
++                      ret = -ENOMEM;
++                      goto fail;
++              }
++
++              has_mapped_anything = 1;
++      }
++
++      kfree(map_regions);
++
++      /* If we could not map any memory, the request was invalid. */
++      if (!has_mapped_anything) {
++              dev_err(gasket_dev->dev,
++                      "Map request did not contain a valid region.\n");
++              trace_gasket_mmap_exit(-EINVAL);
++              return -EINVAL;
++      }
++
++      trace_gasket_mmap_exit(0);
++      return 0;
++
++fail:
++      /* Need to unmap any mapped ranges. */
++      num_map_regions = i;
++      for (i = 0; i < num_map_regions; i++)
++              if (gasket_mm_unmap_region(gasket_dev, vma,
++                                         &bar_desc->mappable_regions[i]))
++                      dev_err(gasket_dev->dev, "Error unmapping range %d.\n",
++                              i);
++      kfree(map_regions);
++
++      return ret;
++}
++
++/*
++ * Open the char device file.
++ *
++ * If the open is for writing, and the device is not owned, this process becomes
++ * the owner.  If the open is for writing and the device is already owned by
++ * some other process, it is an error.  If this process is the owner, increment
++ * the open count.
++ *
++ * Returns 0 if successful, a negative error number otherwise.
++ */
++static int gasket_open(struct inode *inode, struct file *filp)
++{
++      int ret;
++      struct gasket_dev *gasket_dev;
++      const struct gasket_driver_desc *driver_desc;
++      struct gasket_ownership *ownership;
++      char task_name[TASK_COMM_LEN];
++      struct gasket_cdev_info *dev_info =
++          container_of(inode->i_cdev, struct gasket_cdev_info, cdev);
++      struct pid_namespace *pid_ns = task_active_pid_ns(current);
++      bool is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
++
++      gasket_dev = dev_info->gasket_dev_ptr;
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++      ownership = &dev_info->ownership;
++      get_task_comm(task_name, current);
++      filp->private_data = gasket_dev;
++      inode->i_size = 0;
++
++      dev_dbg(gasket_dev->dev,
++              "Attempting to open with tgid %u (%s) (f_mode: 0%03o, "
++              "fmode_write: %d is_root: %u)\n",
++              current->tgid, task_name, filp->f_mode,
++              (filp->f_mode & FMODE_WRITE), is_root);
++
++      /* Always allow non-writing accesses. */
++      if (!(filp->f_mode & FMODE_WRITE)) {
++              dev_dbg(gasket_dev->dev, "Allowing read-only opening.\n");
++              return 0;
++      }
++
++      mutex_lock(&gasket_dev->mutex);
++
++      dev_dbg(gasket_dev->dev,
++              "Current owner open count (owning tgid %u): %d.\n",
++              ownership->owner, ownership->write_open_count);
++
++      /* Opening a node owned by another TGID is an error (unless root) */
++      if (ownership->is_owned && ownership->owner != current->tgid &&
++          !is_root) {
++              dev_err(gasket_dev->dev,
++                      "Process %u is opening a node held by %u.\n",
++                      current->tgid, ownership->owner);
++              mutex_unlock(&gasket_dev->mutex);
++              return -EPERM;
++      }
++
++      /* If the node is not owned, assign it to the current TGID. */
++      if (!ownership->is_owned) {
++              ret = gasket_check_and_invoke_callback_nolock(gasket_dev,
++                                                            driver_desc->device_open_cb);
++              if (ret) {
++                      dev_err(gasket_dev->dev,
++                              "Error in device open cb: %d\n", ret);
++                      mutex_unlock(&gasket_dev->mutex);
++                      return ret;
++              }
++              ownership->is_owned = 1;
++              ownership->owner = current->tgid;
++              dev_dbg(gasket_dev->dev, "Device owner is now tgid %u\n",
++                      ownership->owner);
++      }
++
++      ownership->write_open_count++;
++
++      dev_dbg(gasket_dev->dev, "New open count (owning tgid %u): %d\n",
++              ownership->owner, ownership->write_open_count);
++
++      mutex_unlock(&gasket_dev->mutex);
++      return 0;
++}
++
++/*
++ * Called on a close of the device file.  If this process is the owner,
++ * decrement the open count.  On last close by the owner, free up buffers and
++ * eventfd contexts, and release ownership.
++ *
++ * Returns 0 if successful, a negative error number otherwise.
++ */
++static int gasket_release(struct inode *inode, struct file *file)
++{
++      int i;
++      struct gasket_dev *gasket_dev;
++      struct gasket_ownership *ownership;
++      const struct gasket_driver_desc *driver_desc;
++      char task_name[TASK_COMM_LEN];
++      struct gasket_cdev_info *dev_info =
++              container_of(inode->i_cdev, struct gasket_cdev_info, cdev);
++      struct pid_namespace *pid_ns = task_active_pid_ns(current);
++      bool is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
++
++      gasket_dev = dev_info->gasket_dev_ptr;
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++      ownership = &dev_info->ownership;
++      get_task_comm(task_name, current);
++      mutex_lock(&gasket_dev->mutex);
++
++      dev_dbg(gasket_dev->dev,
++              "Releasing device node. Call origin: tgid %u (%s) "
++              "(f_mode: 0%03o, fmode_write: %d, is_root: %u)\n",
++              current->tgid, task_name, file->f_mode,
++              (file->f_mode & FMODE_WRITE), is_root);
++      dev_dbg(gasket_dev->dev, "Current open count (owning tgid %u): %d\n",
++              ownership->owner, ownership->write_open_count);
++
++      if (file->f_mode & FMODE_WRITE) {
++              ownership->write_open_count--;
++              if (ownership->write_open_count == 0) {
++                      dev_dbg(gasket_dev->dev, "Device is now free\n");
++                      ownership->is_owned = 0;
++                      ownership->owner = 0;
++
++                      /* Forces chip reset before we unmap the page tables. */
++                      driver_desc->device_reset_cb(gasket_dev);
++
++                      for (i = 0; i < driver_desc->num_page_tables; ++i) {
++                              gasket_page_table_unmap_all(gasket_dev->page_table[i]);
++                              gasket_page_table_garbage_collect(gasket_dev->page_table[i]);
++                              gasket_free_coherent_memory_all(gasket_dev, i);
++                      }
++
++                      /* Closes device, enters power save. */
++                      gasket_check_and_invoke_callback_nolock(gasket_dev,
++                                                              driver_desc->device_close_cb);
++              }
++      }
++
++      dev_dbg(gasket_dev->dev, "New open count (owning tgid %u): %d\n",
++              ownership->owner, ownership->write_open_count);
++      mutex_unlock(&gasket_dev->mutex);
++      return 0;
++}
++
++/*
++ * Gasket ioctl dispatch function.
++ *
++ * Check if the ioctl is a generic ioctl. If not, pass the ioctl to the
++ * ioctl_handler_cb registered in the driver description.
++ * If the ioctl is a generic ioctl, pass it to gasket_ioctl_handler.
++ */
++static long gasket_ioctl(struct file *filp, uint cmd, ulong arg)
++{
++      struct gasket_dev *gasket_dev;
++      const struct gasket_driver_desc *driver_desc;
++      void __user *argp = (void __user *)arg;
++      char path[256];
++
++      gasket_dev = (struct gasket_dev *)filp->private_data;
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++      if (!driver_desc) {
++              dev_dbg(gasket_dev->dev,
++                      "Unable to find device descriptor for file %s\n",
++                      d_path(&filp->f_path, path, 256));
++              return -ENODEV;
++      }
++
++      if (!gasket_is_supported_ioctl(cmd)) {
++              /*
++               * The ioctl handler is not a standard Gasket callback, since
++               * it requires different arguments. This means we can't use
++               * check_and_invoke_callback.
++               */
++              if (driver_desc->ioctl_handler_cb)
++                      return driver_desc->ioctl_handler_cb(filp, cmd, argp);
++
++              dev_dbg(gasket_dev->dev, "Received unknown ioctl 0x%x\n", cmd);
++              return -EINVAL;
++      }
++
++      return gasket_handle_ioctl(filp, cmd, argp);
++}
++
++/* File operations for all Gasket devices. */
++static const struct file_operations gasket_file_ops = {
++      .owner = THIS_MODULE,
++      .llseek = no_llseek,
++      .mmap = gasket_mmap,
++      .open = gasket_open,
++      .release = gasket_release,
++      .unlocked_ioctl = gasket_ioctl,
++      .compat_ioctl = gasket_ioctl,
++};
++
++/* Perform final init and marks the device as active. */
++int gasket_enable_device(struct gasket_dev *gasket_dev)
++{
++      int tbl_idx;
++      int ret;
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++
++      dev_dbg(gasket_dev->dev, "enabling device\n");
++      ret = gasket_interrupt_init(gasket_dev);
++      if (ret) {
++              dev_err(gasket_dev->dev,
++                      "Critical failure to allocate interrupts: %d\n", ret);
++              gasket_interrupt_cleanup(gasket_dev);
++              return ret;
++      }
++
++      for (tbl_idx = 0; tbl_idx < driver_desc->num_page_tables; tbl_idx++) {
++              dev_dbg(gasket_dev->dev, "Initializing page table %d.\n",
++                      tbl_idx);
++              ret = gasket_page_table_init(&gasket_dev->page_table[tbl_idx],
++                                           &gasket_dev->bar_data[driver_desc->page_table_bar_index],
++                                           &driver_desc->page_table_configs[tbl_idx],
++                                           gasket_dev->dev,
++                                           gasket_dev->pci_dev);
++              if (ret) {
++                      dev_err(gasket_dev->dev,
++                              "Couldn't init page table %d: %d\n",
++                              tbl_idx, ret);
++                      return ret;
++              }
++              /*
++               * Make sure that the page table is clear and set to simple
++               * addresses.
++               */
++              gasket_page_table_reset(gasket_dev->page_table[tbl_idx]);
++      }
++
++      /*
++       * hardware_revision_cb returns a positive integer (the rev) if
++       * successful.)
++       */
++      ret = check_and_invoke_callback(gasket_dev,
++                                      driver_desc->hardware_revision_cb);
++      if (ret < 0) {
++              dev_err(gasket_dev->dev,
++                      "Error getting hardware revision: %d\n", ret);
++              return ret;
++      }
++      gasket_dev->hardware_revision = ret;
++
++      /* device_status_cb returns a device status, not an error code. */
++      gasket_dev->status = gasket_get_hw_status(gasket_dev);
++      if (gasket_dev->status == GASKET_STATUS_DEAD)
++              dev_err(gasket_dev->dev, "Device reported as unhealthy.\n");
++
++      ret = gasket_add_cdev(&gasket_dev->dev_info, &gasket_file_ops,
++                            driver_desc->module);
++      if (ret)
++              return ret;
++
++      return 0;
++}
++EXPORT_SYMBOL(gasket_enable_device);
++
++static int __gasket_add_device(struct device *parent_dev,
++                             struct gasket_internal_desc *internal_desc,
++                             struct gasket_dev **gasket_devp)
++{
++      int ret;
++      struct gasket_dev *gasket_dev;
++      const struct gasket_driver_desc *driver_desc =
++          internal_desc->driver_desc;
++
++      ret = gasket_alloc_dev(internal_desc, parent_dev, &gasket_dev);
++      if (ret)
++              return ret;
++      if (IS_ERR(gasket_dev->dev_info.device)) {
++              dev_err(parent_dev, "Cannot create %s device %s [ret = %ld]\n",
++                      driver_desc->name, gasket_dev->dev_info.name,
++                      PTR_ERR(gasket_dev->dev_info.device));
++              ret = -ENODEV;
++              goto free_gasket_dev;
++      }
++
++      ret = gasket_sysfs_create_mapping(gasket_dev->dev_info.device,
++                                        gasket_dev);
++      if (ret)
++              goto remove_device;
++
++      ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device,
++                                        gasket_sysfs_generic_attrs);
++      if (ret)
++              goto remove_sysfs_mapping;
++
++      *gasket_devp = gasket_dev;
++      return 0;
++
++remove_sysfs_mapping:
++      gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
++remove_device:
++      device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
++free_gasket_dev:
++      gasket_free_dev(gasket_dev);
++      return ret;
++}
++
++static void __gasket_remove_device(struct gasket_internal_desc *internal_desc,
++                                 struct gasket_dev *gasket_dev)
++{
++      gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
++      device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
++      gasket_free_dev(gasket_dev);
++}
++
++/*
++ * Add PCI gasket device.
++ *
++ * Called by Gasket device probe function.
++ * Allocates device metadata and maps device memory.  The device driver must
++ * call gasket_enable_device after driver init is complete to place the device
++ * in active use.
++ */
++int gasket_pci_add_device(struct pci_dev *pci_dev,
++                        struct gasket_dev **gasket_devp)
++{
++      int ret;
++      struct gasket_internal_desc *internal_desc;
++      struct gasket_dev *gasket_dev;
++      struct device *parent;
++
++      dev_dbg(&pci_dev->dev, "add PCI gasket device\n");
++
++      mutex_lock(&g_mutex);
++      internal_desc = lookup_pci_internal_desc(pci_dev);
++      mutex_unlock(&g_mutex);
++      if (!internal_desc) {
++              dev_err(&pci_dev->dev,
++                      "PCI add device called for unknown driver type\n");
++              return -ENODEV;
++      }
++
++      parent = &pci_dev->dev;
++      ret = __gasket_add_device(parent, internal_desc, &gasket_dev);
++      if (ret)
++              return ret;
++
++      gasket_dev->pci_dev = pci_dev;
++      ret = gasket_setup_pci(pci_dev, gasket_dev);
++      if (ret)
++              goto cleanup_pci;
++
++      /*
++       * Once we've created the mapping structures successfully, attempt to
++       * create a symlink to the pci directory of this object.
++       */
++      ret = sysfs_create_link(&gasket_dev->dev_info.device->kobj,
++                              &pci_dev->dev.kobj, dev_name(&pci_dev->dev));
++      if (ret) {
++              dev_err(gasket_dev->dev,
++                      "Cannot create sysfs pci link: %d\n", ret);
++              goto cleanup_pci;
++      }
++
++      *gasket_devp = gasket_dev;
++      return 0;
++
++cleanup_pci:
++      gasket_cleanup_pci(gasket_dev);
++      __gasket_remove_device(internal_desc, gasket_dev);
++      return ret;
++}
++EXPORT_SYMBOL(gasket_pci_add_device);
++
++/* Remove a PCI gasket device. */
++void gasket_pci_remove_device(struct pci_dev *pci_dev)
++{
++      int i;
++      struct gasket_internal_desc *internal_desc;
++      struct gasket_dev *gasket_dev = NULL;
++      /* Find the device desc. */
++      mutex_lock(&g_mutex);
++      internal_desc = lookup_pci_internal_desc(pci_dev);
++      if (!internal_desc) {
++              mutex_unlock(&g_mutex);
++              return;
++      }
++      mutex_unlock(&g_mutex);
++
++      /* Now find the specific device */
++      mutex_lock(&internal_desc->mutex);
++      for (i = 0; i < GASKET_DEV_MAX; i++) {
++              if (internal_desc->devs[i] &&
++                  internal_desc->devs[i]->pci_dev == pci_dev) {
++                      gasket_dev = internal_desc->devs[i];
++                      break;
++              }
++      }
++      mutex_unlock(&internal_desc->mutex);
++
++      if (!gasket_dev)
++              return;
++
++      dev_dbg(gasket_dev->dev, "remove %s PCI gasket device\n",
++              internal_desc->driver_desc->name);
++
++      gasket_cleanup_pci(gasket_dev);
++      __gasket_remove_device(internal_desc, gasket_dev);
++}
++EXPORT_SYMBOL(gasket_pci_remove_device);
++
++/* Add platform gasket device. Called by Gasket device probe function. */
++int gasket_platform_add_device(struct platform_device *pdev,
++                             struct gasket_dev **gasket_devp)
++{
++      int ret;
++      struct gasket_internal_desc *internal_desc;
++      struct gasket_dev *gasket_dev;
++      struct device *parent;
++
++      dev_dbg(&pdev->dev, "add platform gasket device\n");
++
++      mutex_lock(&g_mutex);
++      internal_desc = lookup_platform_internal_desc(pdev);
++      mutex_unlock(&g_mutex);
++      if (!internal_desc) {
++              dev_err(&pdev->dev,
++                      "%s called for unknown driver type\n", __func__);
++              return -ENODEV;
++      }
++
++      parent = &pdev->dev;
++      ret = __gasket_add_device(parent, internal_desc, &gasket_dev);
++      if (ret)
++              return ret;
++
++      gasket_dev->platform_dev = pdev;
++      *gasket_devp = gasket_dev;
++      return 0;
++}
++EXPORT_SYMBOL(gasket_platform_add_device);
++
++/* Remove a platform gasket device. */
++void gasket_platform_remove_device(struct platform_device *pdev)
++{
++      int i;
++      struct gasket_internal_desc *internal_desc;
++      struct gasket_dev *gasket_dev = NULL;
++
++      /* Find the device desc. */
++      mutex_lock(&g_mutex);
++      internal_desc = lookup_platform_internal_desc(pdev);
++      mutex_unlock(&g_mutex);
++      if (!internal_desc)
++              return;
++
++      /* Now find the specific device */
++      mutex_lock(&internal_desc->mutex);
++      for (i = 0; i < GASKET_DEV_MAX; i++) {
++              if (internal_desc->devs[i] &&
++                  internal_desc->devs[i]->platform_dev == pdev) {
++                      gasket_dev = internal_desc->devs[i];
++                      break;
++              }
++      }
++      mutex_unlock(&internal_desc->mutex);
++
++      if (!gasket_dev)
++              return;
++
++      dev_dbg(gasket_dev->dev, "remove %s platform gasket device\n",
++              internal_desc->driver_desc->name);
++
++      __gasket_remove_device(internal_desc, gasket_dev);
++}
++EXPORT_SYMBOL(gasket_platform_remove_device);
++
++void gasket_set_dma_device(struct gasket_dev *gasket_dev,
++                         struct device *dma_dev)
++{
++      put_device(gasket_dev->dma_dev);
++      gasket_dev->dma_dev = get_device(dma_dev);
++}
++EXPORT_SYMBOL(gasket_set_dma_device);
++
++/**
++ * Lookup a name by number in a num_name table.
++ * @num: Number to lookup.
++ * @table: Array of num_name structures, the table for the lookup.
++ *
++ * Description: Searches for num in the table.  If found, the
++ *            corresponding name is returned; otherwise NULL
++ *            is returned.
++ *
++ *            The table must have a NULL name pointer at the end.
++ */
++const char *gasket_num_name_lookup(uint num,
++                                 const struct gasket_num_name *table)
++{
++      uint i = 0;
++
++      while (table[i].snn_name) {
++              if (num == table[i].snn_num)
++                      break;
++              ++i;
++      }
++
++      return table[i].snn_name;
++}
++EXPORT_SYMBOL(gasket_num_name_lookup);
++
++int gasket_reset(struct gasket_dev *gasket_dev)
++{
++      int ret;
++
++      mutex_lock(&gasket_dev->mutex);
++      ret = gasket_reset_nolock(gasket_dev);
++      mutex_unlock(&gasket_dev->mutex);
++      return ret;
++}
++EXPORT_SYMBOL(gasket_reset);
++
++int gasket_reset_nolock(struct gasket_dev *gasket_dev)
++{
++      int ret;
++      int i;
++      const struct gasket_driver_desc *driver_desc;
++
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++      if (!driver_desc->device_reset_cb)
++              return 0;
++
++      ret = driver_desc->device_reset_cb(gasket_dev);
++      if (ret) {
++              dev_dbg(gasket_dev->dev, "Device reset cb returned %d.\n",
++                      ret);
++              return ret;
++      }
++
++      /* Reinitialize the page tables and interrupt framework. */
++      for (i = 0; i < driver_desc->num_page_tables; ++i)
++              gasket_page_table_reset(gasket_dev->page_table[i]);
++
++      ret = gasket_interrupt_reinit(gasket_dev);
++      if (ret) {
++              dev_dbg(gasket_dev->dev, "Unable to reinit interrupts: %d.\n",
++                      ret);
++              return ret;
++      }
++
++      /* Get current device health. */
++      gasket_dev->status = gasket_get_hw_status(gasket_dev);
++      if (gasket_dev->status == GASKET_STATUS_DEAD) {
++              dev_dbg(gasket_dev->dev, "Device reported as dead.\n");
++              return -EINVAL;
++      }
++
++      return 0;
++}
++EXPORT_SYMBOL(gasket_reset_nolock);
++
++gasket_ioctl_permissions_cb_t
++gasket_get_ioctl_permissions_cb(struct gasket_dev *gasket_dev)
++{
++      return gasket_dev->internal_desc->driver_desc->ioctl_permissions_cb;
++}
++EXPORT_SYMBOL(gasket_get_ioctl_permissions_cb);
++
++/* Get the driver structure for a given gasket_dev.
++ * @dev: pointer to gasket_dev, implementing the requested driver.
++ */
++const struct gasket_driver_desc *gasket_get_driver_desc(struct gasket_dev *dev)
++{
++      return dev->internal_desc->driver_desc;
++}
++
++/* Get the device structure for a given gasket_dev.
++ * @dev: pointer to gasket_dev, implementing the requested driver.
++ */
++struct device *gasket_get_device(struct gasket_dev *dev)
++{
++      return dev->dev;
++}
++
++/**
++ * Asynchronously waits on device.
++ * @gasket_dev: Device struct.
++ * @bar: Bar
++ * @offset: Register offset
++ * @mask: Register mask
++ * @val: Expected value
++ * @max_retries: number of sleep periods
++ * @delay_ms: Timeout in milliseconds
++ *
++ * Description: Busy waits for a specific combination of bits to be set on a
++ * Gasket register.
++ **/
++int gasket_wait_with_reschedule(struct gasket_dev *gasket_dev, int bar,
++                              u64 offset, u64 mask, u64 val,
++                              uint max_retries, u64 delay_ms)
++{
++      uint retries = 0;
++      u64 tmp;
++
++      while (retries < max_retries) {
++              tmp = gasket_dev_read_64(gasket_dev, bar, offset);
++              if ((tmp & mask) == val)
++                      return 0;
++              msleep(delay_ms);
++              retries++;
++      }
++      dev_dbg(gasket_dev->dev, "%s timeout: reg %llx timeout (%llu ms)\n",
++              __func__, offset, max_retries * delay_ms);
++      return -ETIMEDOUT;
++}
++EXPORT_SYMBOL(gasket_wait_with_reschedule);
++
++/* See gasket_core.h for description. */
++int gasket_register_device(const struct gasket_driver_desc *driver_desc)
++{
++      int i, ret;
++      int desc_idx = -1;
++      struct gasket_internal_desc *internal;
++
++      pr_debug("Loading %s driver version %s\n", driver_desc->name,
++               driver_desc->driver_version);
++      /* Check for duplicates and find a free slot. */
++      mutex_lock(&g_mutex);
++
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              if (g_descs[i].driver_desc == driver_desc) {
++                      pr_err("%s driver already loaded/registered\n",
++                             driver_desc->name);
++                      mutex_unlock(&g_mutex);
++                      return -EBUSY;
++              }
++      }
++
++      /* This and the above loop could be combined, but this reads easier. */
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              if (!g_descs[i].driver_desc) {
++                      g_descs[i].driver_desc = driver_desc;
++                      desc_idx = i;
++                      break;
++              }
++      }
++      mutex_unlock(&g_mutex);
++
++      if (desc_idx == -1) {
++              pr_err("too many drivers loaded, max %d\n",
++                     GASKET_FRAMEWORK_DESC_MAX);
++              return -EBUSY;
++      }
++
++      internal = &g_descs[desc_idx];
++      mutex_init(&internal->mutex);
++      memset(internal->devs, 0, sizeof(struct gasket_dev *) * GASKET_DEV_MAX);
++
++    /* Function signature for `class_create()` is changed in kernel >= 6.4.x
++     * to only accept a single argument.
++     * */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
++    internal->class = class_create(driver_desc->module, driver_desc->name);
++#else
++    internal->class = class_create(driver_desc->name);
++#endif
++
++      if (IS_ERR(internal->class)) {
++              pr_err("Cannot register %s class [ret=%ld]\n",
++                     driver_desc->name, PTR_ERR(internal->class));
++              ret = PTR_ERR(internal->class);
++              goto unregister_gasket_driver;
++      }
++
++      ret = register_chrdev_region(MKDEV(driver_desc->major,
++                                         driver_desc->minor), GASKET_DEV_MAX,
++                                   driver_desc->name);
++      if (ret) {
++              pr_err("cannot register %s char driver [ret=%d]\n",
++                     driver_desc->name, ret);
++              goto destroy_class;
++      }
++
++      return 0;
++
++destroy_class:
++      class_destroy(internal->class);
++
++unregister_gasket_driver:
++      mutex_lock(&g_mutex);
++      g_descs[desc_idx].driver_desc = NULL;
++      mutex_unlock(&g_mutex);
++      return ret;
++}
++EXPORT_SYMBOL(gasket_register_device);
++
++/* See gasket_core.h for description. */
++void gasket_unregister_device(const struct gasket_driver_desc *driver_desc)
++{
++      int i, desc_idx;
++      struct gasket_internal_desc *internal_desc = NULL;
++
++      mutex_lock(&g_mutex);
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              if (g_descs[i].driver_desc == driver_desc) {
++                      internal_desc = &g_descs[i];
++                      desc_idx = i;
++                      break;
++              }
++      }
++
++      if (!internal_desc) {
++              mutex_unlock(&g_mutex);
++              pr_err("request to unregister unknown desc: %s, %d:%d\n",
++                     driver_desc->name, driver_desc->major,
++                     driver_desc->minor);
++              return;
++      }
++
++      unregister_chrdev_region(MKDEV(driver_desc->major, driver_desc->minor),
++                               GASKET_DEV_MAX);
++
++      class_destroy(internal_desc->class);
++
++      /* Finally, effectively "remove" the driver. */
++      g_descs[desc_idx].driver_desc = NULL;
++      mutex_unlock(&g_mutex);
++
++      pr_debug("removed %s driver\n", driver_desc->name);
++}
++EXPORT_SYMBOL(gasket_unregister_device);
++
++static int __init gasket_init(void)
++{
++      int i;
++
++      mutex_lock(&g_mutex);
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              g_descs[i].driver_desc = NULL;
++              mutex_init(&g_descs[i].mutex);
++      }
++
++      gasket_sysfs_init();
++
++      mutex_unlock(&g_mutex);
++      return 0;
++}
++
++MODULE_DESCRIPTION("Google Gasket driver framework");
++MODULE_VERSION(GASKET_FRAMEWORK_VERSION);
++MODULE_LICENSE("GPL v2");
++MODULE_AUTHOR("Rob Springer <rspringer@google.com>");
++module_init(gasket_init);
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_core.h b/drivers/staging/gasket-driver/gasket_core.h
+--- a/drivers/staging/gasket-driver/gasket_core.h      1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_core.h      2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,657 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Gasket generic driver. Defines the set of data types and functions necessary
++ * to define a driver using the Gasket generic driver framework.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++#ifndef __GASKET_CORE_H__
++#define __GASKET_CORE_H__
++
++#include <linux/cdev.h>
++#include <linux/compiler.h>
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/platform_device.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++
++#include "gasket_constants.h"
++
++/**
++ * struct gasket_num_name - Map numbers to names.
++ * @ein_num: Number.
++ * @ein_name: Name associated with the number, a char pointer.
++ *
++ * This structure maps numbers to names. It is used to provide printable enum
++ * names, e.g {0, "DEAD"} or {1, "ALIVE"}.
++ */
++struct gasket_num_name {
++      uint snn_num;
++      const char *snn_name;
++};
++
++/*
++ * Register location for packed interrupts.
++ * Each value indicates the location of an interrupt field (in units of
++ * gasket_driver_desc->interrupt_pack_width) within the containing register.
++ * In other words, this indicates the shift to use when creating a mask to
++ * extract/set bits within a register for a given interrupt.
++ */
++enum gasket_interrupt_packing {
++      PACK_0 = 0,
++      PACK_1 = 1,
++      PACK_2 = 2,
++      PACK_3 = 3,
++      UNPACKED = 4,
++};
++
++/* Type of the interrupt supported by the device. */
++enum gasket_interrupt_type {
++      PCI_MSIX = 0,
++      DEVICE_MANAGED = 1, /* Managed externally in device driver */
++};
++
++/*
++ * Used to describe a Gasket interrupt. Contains an interrupt index, a register,
++ * and packing data for that interrupt. The register and packing data
++ * fields are relevant only for PCI_MSIX interrupt type and can be
++ * set to 0 for everything else.
++ */
++struct gasket_interrupt_desc {
++      /* Device-wide interrupt index/number. */
++      int index;
++      /* The register offset controlling this interrupt. */
++      u64 reg;
++      /* The location of this interrupt inside register reg, if packed. */
++      int packing;
++};
++
++/*
++ * This enum is used to identify memory regions being part of the physical
++ * memory that belongs to a device.
++ */
++enum mappable_area_type {
++      PCI_BAR = 0, /* Default */
++      BUS_REGION,  /* For SYSBUS devices, i.e. AXI etc... */
++      COHERENT_MEMORY
++};
++
++/*
++ * Metadata for each BAR mapping.
++ * This struct is used so as to track PCI memory, I/O space, AXI and coherent
++ * memory area... i.e. memory objects which can be referenced in the device's
++ * mmap function.
++ */
++struct gasket_bar_data {
++      /* Virtual base address. */
++      u8 __iomem *virt_base;
++
++      /* Physical base address. */
++      ulong phys_base;
++
++      /* Length of the mapping. */
++      ulong length_bytes;
++
++      /* Type of mappable area */
++      enum mappable_area_type type;
++};
++
++/* Maintains device open ownership data. */
++struct gasket_ownership {
++      /* 1 if the device is owned, 0 otherwise. */
++      int is_owned;
++
++      /* TGID of the owner. */
++      pid_t owner;
++
++      /* Count of current device opens in write mode. */
++      int write_open_count;
++};
++
++/* Page table modes of operation. */
++enum gasket_page_table_mode {
++      /* The page table is partitionable as normal, all simple by default. */
++      GASKET_PAGE_TABLE_MODE_NORMAL,
++
++      /* All entries are always simple. */
++      GASKET_PAGE_TABLE_MODE_SIMPLE,
++
++      /* All entries are always extended. No extended bit is used. */
++      GASKET_PAGE_TABLE_MODE_EXTENDED,
++};
++
++/* Page table configuration. One per table. */
++struct gasket_page_table_config {
++      /* The identifier/index of this page table. */
++      int id;
++
++      /* The operation mode of this page table. */
++      enum gasket_page_table_mode mode;
++
++      /* Total (first-level) entries in this page table. */
++      ulong total_entries;
++
++      /* Base register for the page table. */
++      int base_reg;
++
++      /*
++       * Register containing the extended page table. This value is unused in
++       * GASKET_PAGE_TABLE_MODE_SIMPLE and GASKET_PAGE_TABLE_MODE_EXTENDED
++       * modes.
++       */
++      int extended_reg;
++
++      /* The bit index indicating whether a PT entry is extended. */
++      int extended_bit;
++};
++
++/* Maintains information about a device node. */
++struct gasket_cdev_info {
++      /* The internal name of this device. */
++      char name[GASKET_NAME_MAX];
++
++      /* Device number. */
++      dev_t devt;
++
++      /* Kernel-internal device structure. */
++      struct device *device;
++
++      /* Character device for real. */
++      struct cdev cdev;
++
++      /* Flag indicating if cdev_add has been called for the devices. */
++      int cdev_added;
++
++      /* Pointer to the overall gasket_dev struct for this device. */
++      struct gasket_dev *gasket_dev_ptr;
++
++      /* Ownership data for the device in question. */
++      struct gasket_ownership ownership;
++};
++
++/* Describes the offset and length of mmapable device BAR regions. */
++struct gasket_mappable_region {
++      u64 start;
++      u64 length_bytes;
++};
++
++/* Describe the offset, size, and permissions for a device bar. */
++struct gasket_bar_desc {
++      /*
++       * The size of each PCI BAR range, in bytes. If a value is 0, that BAR
++       * will not be mapped into kernel space at all.
++       * For devices with 64 bit BARs, only elements 0, 2, and 4 should be
++       * populated, and 1, 3, and 5 should be set to 0.
++       * For example, for a device mapping 1M in each of the first two 64-bit
++       * BARs, this field would be set as { 0x100000, 0, 0x100000, 0, 0, 0 }
++       * (one number per bar_desc struct.)
++       */
++      u64 size;
++      /* The permissions for this bar. (Should be VM_WRITE/VM_READ/VM_EXEC,
++       * and can be or'd.) If set to GASKET_NOMAP, the bar will
++       * not be used for mmapping.
++       */
++      ulong permissions;
++      /* The memory address corresponding to the base of this bar, if used. */
++      u64 base;
++      /* The number of mappable regions in this bar. */
++      int num_mappable_regions;
++
++      /* The mappable subregions of this bar. */
++      const struct gasket_mappable_region *mappable_regions;
++
++      /* Type of mappable area */
++      enum mappable_area_type type;
++};
++
++/* Describes the offset, size, and permissions for a coherent buffer. */
++struct gasket_coherent_buffer_desc {
++      /* The size of the coherent buffer. */
++      u64 size;
++
++      /* The permissions for this bar. (Should be VM_WRITE/VM_READ/VM_EXEC,
++       * and can be or'd.) If set to GASKET_NOMAP, the bar will
++       * not be used for mmaping.
++       */
++      ulong permissions;
++
++      /* device side address. */
++      u64 base;
++};
++
++/* Coherent buffer structure. */
++struct gasket_coherent_buffer {
++      /* Virtual base address. */
++      u8 __iomem *virt_base;
++
++      /* Physical base address. */
++      dma_addr_t phys_base;
++
++      /* Length of the mapping. */
++      ulong length_bytes;
++};
++
++/* Description of Gasket-specific permissions in the mmap field. */
++enum gasket_mapping_options { GASKET_NOMAP = 0 };
++
++/* This struct represents an undefined bar that should never be mapped. */
++#define GASKET_UNUSED_BAR                                                      \
++      {                                                                      \
++              0, GASKET_NOMAP, 0, 0, NULL, 0                                 \
++      }
++
++/* Internal data for a Gasket device. See gasket_core.c for more information. */
++struct gasket_internal_desc;
++
++#define MAX_NUM_COHERENT_PAGES 16
++
++/*
++ * Device data for Gasket device instances.
++ *
++ * This structure contains the data required to manage a Gasket device.
++ */
++struct gasket_dev {
++      /* Pointer to the internal driver description for this device. */
++      struct gasket_internal_desc *internal_desc;
++
++      /* Device info */
++      struct device *dev;
++
++      /* DMA device to use, may be same as above or a parent */
++      struct device *dma_dev;
++
++      /* PCI device pointer for PCI devices */
++      struct pci_dev *pci_dev;
++
++      /* Platform device pointer for platform devices */
++      struct platform_device *platform_dev;
++
++      /* This device's index into internal_desc->devs. */
++      int dev_idx;
++
++      /* The name of this device, as reported by the kernel. */
++      char kobj_name[GASKET_NAME_MAX];
++
++      /* Virtual address of mapped BAR memory range. */
++      struct gasket_bar_data bar_data[GASKET_NUM_BARS];
++
++      /* Coherent buffer. */
++      struct gasket_coherent_buffer coherent_buffer;
++
++      /* Number of page tables for this device. */
++      int num_page_tables;
++
++      /* Address translations. Page tables have a private implementation. */
++      struct gasket_page_table *page_table[GASKET_MAX_NUM_PAGE_TABLES];
++
++      /* Interrupt data for this device. */
++      struct gasket_interrupt_data *interrupt_data;
++
++      /* Status for this device - GASKET_STATUS_ALIVE or _DEAD. */
++      uint status;
++
++      /* Number of times this device has been reset. */
++      uint reset_count;
++
++      /* Dev information for the cdev node. */
++      struct gasket_cdev_info dev_info;
++
++      /* Hardware revision value for this device. */
++      int hardware_revision;
++
++      /* Protects access to per-device data (i.e. this structure). */
++      struct mutex mutex;
++
++      /* cdev hash tracking/membership structure, Accel and legacy. */
++      /* Unused until Accel is upstreamed. */
++      struct hlist_node hlist_node;
++      struct hlist_node legacy_hlist_node;
++};
++
++/* Type of the ioctl handler callback. */
++typedef long (*gasket_ioctl_handler_cb_t)(struct file *file, uint cmd,
++                                        void __user *argp);
++/* Type of the ioctl permissions check callback. See below. */
++typedef int (*gasket_ioctl_permissions_cb_t)(struct file *filp, uint cmd,
++                                           void __user *argp);
++
++/*
++ * Device type descriptor.
++ *
++ * This structure contains device-specific data needed to identify and address a
++ * type of device to be administered via the Gasket generic driver.
++ *
++ * Device IDs are per-driver. In other words, two drivers using the Gasket
++ * framework will each have a distinct device 0 (for example).
++ */
++struct gasket_driver_desc {
++      /* The name of this device type. */
++      const char *name;
++
++      /* The name of this specific device model. */
++      const char *chip_model;
++
++      /* The version of the chip specified in chip_model. */
++      const char *chip_version;
++
++      /* The version of this driver: "1.0.0", "2.1.3", etc. */
++      const char *driver_version;
++
++      /*
++       * Non-zero if we should create "legacy" (device and device-class-
++       * specific) character devices and sysfs nodes.
++       */
++      /* Unused until Accel is upstreamed. */
++      int legacy_support;
++
++      /* Major and minor numbers identifying the device. */
++      int major, minor;
++
++      /* Module structure for this driver. */
++      struct module *module;
++
++      /* PCI ID table. */
++      const struct pci_device_id *pci_id_table;
++
++      /* The number of page tables handled by this driver. */
++      int num_page_tables;
++
++      /* The index of the bar containing the page tables. */
++      int page_table_bar_index;
++
++      /* Registers used to control each page table. */
++      const struct gasket_page_table_config *page_table_configs;
++
++      /* The bit index indicating whether a PT entry is extended. */
++      int page_table_extended_bit;
++
++      /*
++       * Legacy mmap address adjusment for legacy devices only. Should be 0
++       * for any new device.
++       */
++      ulong legacy_mmap_address_offset;
++
++      /* Set of 6 bar descriptions that describe all PCIe bars.
++       * Note that BUS/AXI devices (i.e. non PCI devices) use those.
++       */
++      struct gasket_bar_desc bar_descriptions[GASKET_NUM_BARS];
++
++      /*
++       * Coherent buffer description.
++       */
++      struct gasket_coherent_buffer_desc coherent_buffer_description;
++
++      /* Interrupt type. (One of gasket_interrupt_type). */
++      int interrupt_type;
++
++      /* Index of the bar containing the interrupt registers to program. */
++      int interrupt_bar_index;
++
++      /* Number of interrupts in the gasket_interrupt_desc array */
++      int num_interrupts;
++
++      /* Description of the interrupts for this device. */
++      const struct gasket_interrupt_desc *interrupts;
++
++      /*
++       * If this device packs multiple interrupt->MSI-X mappings into a
++       * single register (i.e., "uses packed interrupts"), only a single bit
++       * width is supported for each interrupt mapping (unpacked/"full-width"
++       * interrupts are always supported). This value specifies that width. If
++       * packed interrupts are not used, this value is ignored.
++       */
++      int interrupt_pack_width;
++
++      /* Driver callback functions - all may be NULL */
++      /*
++       * device_open_cb: Callback for when a device node is opened in write
++       * mode.
++       * @dev: The gasket_dev struct for this driver instance.
++       *
++       * This callback should perform device-specific setup that needs to
++       * occur only once when a device is first opened.
++       */
++      int (*device_open_cb)(struct gasket_dev *dev);
++
++      /*
++       * device_release_cb: Callback when a device is closed.
++       * @gasket_dev: The gasket_dev struct for this driver instance.
++       *
++       * This callback is called whenever a device node fd is closed, as
++       * opposed to device_close_cb, which is called when the _last_
++       * descriptor for an open file is closed. This call is intended to
++       * handle any per-user or per-fd cleanup.
++       */
++      int (*device_release_cb)(struct gasket_dev *gasket_dev,
++                               struct file *file);
++
++      /*
++       * device_close_cb: Callback for when a device node is closed for the
++       * last time.
++       * @dev: The gasket_dev struct for this driver instance.
++       *
++       * This callback should perform device-specific cleanup that only
++       * needs to occur when the last reference to a device node is closed.
++       *
++       * This call is intended to handle and device-wide cleanup, as opposed
++       * to per-fd cleanup (which should be handled by device_release_cb).
++       */
++      int (*device_close_cb)(struct gasket_dev *dev);
++
++      /*
++       * get_mappable_regions_cb: Get descriptors of mappable device memory.
++       * @gasket_dev: Pointer to the struct gasket_dev for this device.
++       * @bar_index: BAR for which to retrieve memory ranges.
++       * @mappable_regions: Out-pointer to the list of mappable regions on the
++       * device/BAR for this process.
++       * @num_mappable_regions: Out-pointer for the size of mappable_regions.
++       *
++       * Called when handling mmap(), this callback is used to determine which
++       * regions of device memory may be mapped by the current process. This
++       * information is then compared to mmap request to determine which
++       * regions to actually map.
++       */
++      int (*get_mappable_regions_cb)(struct gasket_dev *gasket_dev,
++                                     int bar_index,
++                                     struct gasket_mappable_region **mappable_regions,
++                                     int *num_mappable_regions);
++
++      /*
++       * ioctl_permissions_cb: Check permissions for generic ioctls.
++       * @filp: File structure pointer describing this node usage session.
++       * @cmd: ioctl number to handle.
++       * @arg: ioctl-specific data pointer.
++       *
++       * Returns 1 if the ioctl may be executed, 0 otherwise. If this callback
++       * isn't specified a default routine will be used, that only allows the
++       * original device opener (i.e, the "owner") to execute state-affecting
++       * ioctls.
++       */
++      gasket_ioctl_permissions_cb_t ioctl_permissions_cb;
++
++      /*
++       * ioctl_handler_cb: Callback to handle device-specific ioctls.
++       * @filp: File structure pointer describing this node usage session.
++       * @cmd: ioctl number to handle.
++       * @arg: ioctl-specific data pointer.
++       *
++       * Invoked whenever an ioctl is called that the generic Gasket
++       * framework doesn't support. If no cb is registered, unknown ioctls
++       * return -EINVAL. Should return an error status (either -EINVAL or
++       * the error result of the ioctl being handled).
++       */
++      gasket_ioctl_handler_cb_t ioctl_handler_cb;
++
++      /*
++       * device_status_cb: Callback to determine device health.
++       * @dev: Pointer to the gasket_dev struct for this device.
++       *
++       * Called to determine if the device is healthy or not. Should return
++       * a member of the gasket_status_type enum.
++       *
++       */
++      int (*device_status_cb)(struct gasket_dev *dev);
++
++      /*
++       * hardware_revision_cb: Get the device's hardware revision.
++       * @dev: Pointer to the gasket_dev struct for this device.
++       *
++       * Called to determine the reported rev of the physical hardware.
++       * Revision should be >0. A negative return value is an error.
++       */
++      int (*hardware_revision_cb)(struct gasket_dev *dev);
++
++      /*
++       * device_reset_cb: Reset the hardware in question.
++       * @dev: Pointer to the gasket_dev structure for this device.
++       *
++       * Called by reset ioctls. This function should not
++       * lock the gasket_dev mutex. It should return 0 on success
++       * and an error on failure.
++       */
++      int (*device_reset_cb)(struct gasket_dev *dev);
++};
++
++/*
++ * Register the specified device type with the framework.
++ * @desc: Populated/initialized device type descriptor.
++ *
++ * This function does _not_ take ownership of desc; the underlying struct must
++ * exist until the matching call to gasket_unregister_device.
++ * This function should be called from your driver's module_init function.
++ */
++int gasket_register_device(const struct gasket_driver_desc *desc);
++
++/*
++ * Remove the specified device type from the framework.
++ * @desc: Descriptor for the device type to unregister; it should have been
++ *        passed to gasket_register_device in a previous call.
++ *
++ * This function should be called from your driver's module_exit function.
++ */
++void gasket_unregister_device(const struct gasket_driver_desc *desc);
++
++/* Add a PCI gasket device. */
++int gasket_pci_add_device(struct pci_dev *pci_dev,
++                        struct gasket_dev **gasket_devp);
++/* Remove a PCI gasket device. */
++void gasket_pci_remove_device(struct pci_dev *pci_dev);
++
++/* Add a platform gasket device. */
++int gasket_platform_add_device(struct platform_device *pdev,
++                             struct gasket_dev **gasket_devp);
++
++/* Remove a platform gasket device. */
++void gasket_platform_remove_device(struct platform_device *pdev);
++
++/* Set DMA device to use (if different from PCI/platform device) */
++void gasket_set_dma_device(struct gasket_dev *gasket_dev,
++                         struct device *dma_dev);
++
++/* Enable a Gasket device. */
++int gasket_enable_device(struct gasket_dev *gasket_dev);
++
++/* Disable a Gasket device. */
++void gasket_disable_device(struct gasket_dev *gasket_dev);
++
++/*
++ * Reset the Gasket device.
++ * @gasket_dev: Gasket device struct.
++ *
++ * Calls device_reset_cb. Returns 0 on success and an error code othewrise.
++ * gasket_reset_nolock will not lock the mutex, gasket_reset will.
++ *
++ */
++int gasket_reset(struct gasket_dev *gasket_dev);
++int gasket_reset_nolock(struct gasket_dev *gasket_dev);
++
++/*
++ * Memory management functions. These will likely be spun off into their own
++ * file in the future.
++ */
++
++/* Unmaps the specified mappable region from a VMA. */
++int gasket_mm_unmap_region(const struct gasket_dev *gasket_dev,
++                         struct vm_area_struct *vma,
++                         const struct gasket_mappable_region *map_region);
++
++/*
++ * Get the ioctl permissions callback.
++ * @gasket_dev: Gasket device structure.
++ */
++gasket_ioctl_permissions_cb_t
++gasket_get_ioctl_permissions_cb(struct gasket_dev *gasket_dev);
++
++/**
++ * Lookup a name by number in a num_name table.
++ * @num: Number to lookup.
++ * @table: Array of num_name structures, the table for the lookup.
++ *
++ */
++const char *gasket_num_name_lookup(uint num,
++                                 const struct gasket_num_name *table);
++
++/* Handy inlines */
++static inline u64 gasket_dev_read_64(struct gasket_dev *gasket_dev, int bar,
++                                     ulong location)
++{
++      return readq_relaxed(&gasket_dev->bar_data[bar].virt_base[location]);
++}
++
++static inline void gasket_dev_write_64(struct gasket_dev *dev, u64 value,
++                                     int bar, ulong location)
++{
++      writeq_relaxed(value, &dev->bar_data[bar].virt_base[location]);
++}
++
++static inline void gasket_dev_write_32(struct gasket_dev *dev, u32 value,
++                                     int bar, ulong location)
++{
++      writel_relaxed(value, &dev->bar_data[bar].virt_base[location]);
++}
++
++static inline u32 gasket_dev_read_32(struct gasket_dev *dev, int bar,
++                                   ulong location)
++{
++      return readl_relaxed(&dev->bar_data[bar].virt_base[location]);
++}
++
++static inline void gasket_read_modify_write_64(struct gasket_dev *dev, int bar,
++                                             ulong location, u64 value,
++                                             u64 mask_width, u64 mask_shift)
++{
++      u64 mask, tmp;
++
++      tmp = gasket_dev_read_64(dev, bar, location);
++      mask = ((1ULL << mask_width) - 1) << mask_shift;
++      tmp = (tmp & ~mask) | (value << mask_shift);
++      gasket_dev_write_64(dev, tmp, bar, location);
++}
++
++static inline void gasket_read_modify_write_32(struct gasket_dev *dev, int bar,
++                                             ulong location, u32 value,
++                                             u32 mask_width, u32 mask_shift)
++{
++      u32 mask, tmp;
++
++      tmp = gasket_dev_read_32(dev, bar, location);
++      mask = ((1 << mask_width) - 1) << mask_shift;
++      tmp = (tmp & ~mask) | (value << mask_shift);
++      gasket_dev_write_32(dev, tmp, bar, location);
++}
++
++/* Get the Gasket driver structure for a given device. */
++const struct gasket_driver_desc *gasket_get_driver_desc(struct gasket_dev *dev);
++
++/* Get the device structure for a given device. */
++struct device *gasket_get_device(struct gasket_dev *dev);
++
++/* Helper function, Asynchronous waits on a given set of bits. */
++int gasket_wait_with_reschedule(struct gasket_dev *gasket_dev, int bar,
++                              u64 offset, u64 mask, u64 val,
++                              uint max_retries, u64 delay_ms);
++
++#endif /* __GASKET_CORE_H__ */
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket.h b/drivers/staging/gasket-driver/gasket.h
+--- a/drivers/staging/gasket-driver/gasket.h   1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket.h   2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,177 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Common Gasket device kernel and user space declarations.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++#ifndef __GASKET_H__
++#define __GASKET_H__
++
++#include <linux/ioctl.h>
++#include <linux/types.h>
++
++/* ioctl structure declarations */
++
++/* Ioctl structures are padded to a multiple of 64 bits */
++/* and padded to put 64 bit values on 64 bit boundaries. */
++/* Unsigned 64 bit integers are used to hold pointers. */
++/* This helps compatibility between 32 and 64 bits. */
++
++/*
++ * Common structure for ioctls associating an eventfd with a device interrupt,
++ * when using the Gasket interrupt module.
++ */
++struct gasket_interrupt_eventfd {
++      u64 interrupt;
++      u64 event_fd;
++};
++
++/*
++ * Common structure for ioctls mapping and unmapping buffers when using the
++ * Gasket page_table module.
++ */
++struct gasket_page_table_ioctl {
++      u64 page_table_index;
++      u64 size;
++      u64 host_address;
++      u64 device_address;
++};
++
++/*
++ * Structure for ioctl mapping buffers with flags when using the Gasket
++ * page_table module.
++ */
++struct gasket_page_table_ioctl_flags {
++      struct gasket_page_table_ioctl base;
++      /*
++       * Flags indicating status and attribute requests from the host.
++       * NOTE: STATUS bit does not need to be set in this request.
++       *       Set RESERVED bits to 0 to ensure backwards compatibility.
++       *
++       * Bitfields:
++       *   [0]     - STATUS: indicates if this entry/slot is free
++       *                0 = PTE_FREE
++       *                1 = PTE_INUSE
++       *   [2:1]   - DMA_DIRECTION: dma_data_direction requested by host
++       *               00 = DMA_BIDIRECTIONAL
++       *               01 = DMA_TO_DEVICE
++       *               10 = DMA_FROM_DEVICE
++       *               11 = DMA_NONE
++       *   [31:3]  - RESERVED
++       */
++      u32 flags;
++};
++
++/*
++ * Common structure for ioctls mapping and unmapping buffers when using the
++ * Gasket page_table module.
++ * dma_address: phys addr start of coherent memory, allocated by kernel
++ */
++struct gasket_coherent_alloc_config_ioctl {
++      u64 page_table_index;
++      u64 enable;
++      u64 size;
++      u64 dma_address;
++};
++
++/*
++ * Common structure for ioctls mapping and unmapping dma-bufs when using the
++ * Gasket page_table module.
++ * map: boolean, non-zero to map, 0 to unmap.
++ * flags: see gasket_page_table_ioctl_flags.flags.
++ */
++struct gasket_page_table_ioctl_dmabuf {
++      u64 page_table_index;
++      u64 device_address;
++      int dmabuf_fd;
++      u32 num_pages;
++      u32 map;
++      u32 flags;
++};
++
++/* Base number for all Gasket-common IOCTLs */
++#define GASKET_IOCTL_BASE 0xDC
++
++/* Reset the device. */
++#define GASKET_IOCTL_RESET _IO(GASKET_IOCTL_BASE, 0)
++
++/* Associate the specified [event]fd with the specified interrupt. */
++#define GASKET_IOCTL_SET_EVENTFD                                               \
++      _IOW(GASKET_IOCTL_BASE, 1, struct gasket_interrupt_eventfd)
++
++/*
++ * Clears any eventfd associated with the specified interrupt. The (ulong)
++ * argument is the interrupt number to clear.
++ */
++#define GASKET_IOCTL_CLEAR_EVENTFD _IOW(GASKET_IOCTL_BASE, 2, unsigned long)
++
++/*
++ * [Loopbacks only] Requests that the loopback device send the specified
++ * interrupt to the host. The (ulong) argument is the number of the interrupt to
++ * send.
++ */
++#define GASKET_IOCTL_LOOPBACK_INTERRUPT                                        \
++      _IOW(GASKET_IOCTL_BASE, 3, unsigned long)
++
++/* Queries the kernel for the number of page tables supported by the device. */
++#define GASKET_IOCTL_NUMBER_PAGE_TABLES _IOR(GASKET_IOCTL_BASE, 4, u64)
++
++/*
++ * Queries the kernel for the maximum size of the page table.  Only the size and
++ * page_table_index fields are used from the struct gasket_page_table_ioctl.
++ */
++#define GASKET_IOCTL_PAGE_TABLE_SIZE                                           \
++      _IOWR(GASKET_IOCTL_BASE, 5, struct gasket_page_table_ioctl)
++
++/*
++ * Queries the kernel for the current simple page table size.  Only the size and
++ * page_table_index fields are used from the struct gasket_page_table_ioctl.
++ */
++#define GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE                                    \
++      _IOWR(GASKET_IOCTL_BASE, 6, struct gasket_page_table_ioctl)
++
++/*
++ * Tells the kernel to change the split between the number of simple and
++ * extended entries in the given page table. Only the size and page_table_index
++ * fields are used from the struct gasket_page_table_ioctl.
++ */
++#define GASKET_IOCTL_PARTITION_PAGE_TABLE                                      \
++      _IOW(GASKET_IOCTL_BASE, 7, struct gasket_page_table_ioctl)
++
++/*
++ * Tells the kernel to map size bytes at host_address to device_address in
++ * page_table_index page table.
++ */
++#define GASKET_IOCTL_MAP_BUFFER                                                \
++      _IOW(GASKET_IOCTL_BASE, 8, struct gasket_page_table_ioctl)
++
++/*
++ * Tells the kernel to unmap size bytes at host_address from device_address in
++ * page_table_index page table.
++ */
++#define GASKET_IOCTL_UNMAP_BUFFER                                              \
++      _IOW(GASKET_IOCTL_BASE, 9, struct gasket_page_table_ioctl)
++
++/* Clear the interrupt counts stored for this device. */
++#define GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS _IO(GASKET_IOCTL_BASE, 10)
++
++/* Enable/Disable and configure the coherent allocator. */
++#define GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR                                 \
++      _IOWR(GASKET_IOCTL_BASE, 11, struct gasket_coherent_alloc_config_ioctl)
++
++/*
++ * Tells the kernel to map size bytes at host_address to device_address in
++ * page_table_index page table. Passes flags to indicate additional attribute
++ * requests for the mapped memory.
++ */
++#define GASKET_IOCTL_MAP_BUFFER_FLAGS                                          \
++      _IOW(GASKET_IOCTL_BASE, 12, struct gasket_page_table_ioctl_flags)
++
++/*
++ * Tells the kernel to map/unmap dma-buf with fd to device_address in
++ * page_table_index page table.
++ */
++#define GASKET_IOCTL_MAP_DMABUF                                                \
++      _IOW(GASKET_IOCTL_BASE, 13, struct gasket_page_table_ioctl_dmabuf)
++
++#endif /* __GASKET_H__ */
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_interrupt.c b/drivers/staging/gasket-driver/gasket_interrupt.c
+--- a/drivers/staging/gasket-driver/gasket_interrupt.c 1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_interrupt.c 2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,559 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (C) 2018 Google, Inc. */
++
++#include "gasket_interrupt.h"
++
++#include "gasket_constants.h"
++#include "gasket_core.h"
++#include "gasket_sysfs.h"
++#include <linux/device.h>
++#include <linux/interrupt.h>
++#include <linux/printk.h>
++#include <linux/spinlock.h>
++#include <linux/version.h>
++#ifdef GASKET_KERNEL_TRACE_SUPPORT
++#define CREATE_TRACE_POINTS
++#include <trace/events/gasket_interrupt.h>
++#else
++#define trace_gasket_interrupt_event(x, ...)
++#endif
++/* Retry attempts if the requested number of interrupts aren't available. */
++#define MSIX_RETRY_COUNT 3
++
++/* Instance interrupt management data. */
++struct gasket_interrupt_data {
++      /* The name associated with this interrupt data. */
++      const char *name;
++
++      /* Interrupt type. See gasket_interrupt_type in gasket_core.h */
++      int type;
++
++      /* The PCI device [if any] associated with the owning device. */
++      struct pci_dev *pci_dev;
++
++      /* Set to 1 if MSI-X has successfully been configred, 0 otherwise. */
++      int msix_configured;
++
++      /* The number of interrupts requested by the owning device. */
++      int num_interrupts;
++
++      /* A pointer to the interrupt descriptor struct for this device. */
++      const struct gasket_interrupt_desc *interrupts;
++
++      /* The index of the bar into which interrupts should be mapped. */
++      int interrupt_bar_index;
++
++      /* The width of a single interrupt in a packed interrupt register. */
++      int pack_width;
++
++      /*
++       * Design-wise, these elements should be bundled together, but
++       * pci_enable_msix's interface requires that they be managed
++       * individually (requires array of struct msix_entry).
++       */
++
++      /* The number of successfully configured interrupts. */
++      int num_configured;
++
++      /* The MSI-X data for each requested/configured interrupt. */
++      struct msix_entry *msix_entries;
++
++      /* The eventfd "callback" data for each interrupt. */
++      struct eventfd_ctx **eventfd_ctxs;
++
++      /* Spinlock to protect read/write races to eventfd_ctxs. */
++      rwlock_t eventfd_ctx_lock;
++
++      /* The number of times each interrupt has been called. */
++      ulong *interrupt_counts;
++
++      /* Linux IRQ number. */
++      int irq;
++};
++
++/* Structures to display interrupt counts in sysfs. */
++enum interrupt_sysfs_attribute_type {
++      ATTR_INTERRUPT_COUNTS,
++};
++
++/* Set up device registers for interrupt handling. */
++static void gasket_interrupt_setup(struct gasket_dev *gasket_dev)
++{
++      int i;
++      int pack_shift;
++      u64 mask;
++      u64 value;
++      struct gasket_interrupt_data *interrupt_data =
++              gasket_dev->interrupt_data;
++
++      if (!interrupt_data) {
++              dev_dbg(gasket_dev->dev, "Interrupt data is not initialized\n");
++              return;
++      }
++
++      dev_dbg(gasket_dev->dev, "Running interrupt setup\n");
++
++      if (interrupt_data->type == DEVICE_MANAGED)
++              return; /* device driver handles setup */
++
++      /* Setup the MSIX table. */
++
++      for (i = 0; i < interrupt_data->num_interrupts; i++) {
++              /*
++               * If the interrupt is not packed, we can write the index into
++               * the register directly. If not, we need to deal with a read-
++               * modify-write and shift based on the packing index.
++               */
++              dev_dbg(gasket_dev->dev,
++                      "Setting up interrupt index %d with index 0x%llx and "
++                      "packing %d\n",
++                      interrupt_data->interrupts[i].index,
++                      interrupt_data->interrupts[i].reg,
++                      interrupt_data->interrupts[i].packing);
++              if (interrupt_data->interrupts[i].packing == UNPACKED) {
++                      value = interrupt_data->interrupts[i].index;
++              } else {
++                      switch (interrupt_data->interrupts[i].packing) {
++                      case PACK_0:
++                              pack_shift = 0;
++                              break;
++                      case PACK_1:
++                              pack_shift = interrupt_data->pack_width;
++                              break;
++                      case PACK_2:
++                              pack_shift = 2 * interrupt_data->pack_width;
++                              break;
++                      case PACK_3:
++                              pack_shift = 3 * interrupt_data->pack_width;
++                              break;
++                      default:
++                              dev_dbg(gasket_dev->dev,
++                                      "Found interrupt description with "
++                                      "unknown enum %d\n",
++                                      interrupt_data->interrupts[i].packing);
++                              return;
++                      }
++
++                      mask = ~(0xFFFF << pack_shift);
++                      value = gasket_dev_read_64(gasket_dev,
++                                                 interrupt_data->interrupt_bar_index,
++                                                 interrupt_data->interrupts[i].reg);
++                      value &= mask;
++                      value |= interrupt_data->interrupts[i].index
++                               << pack_shift;
++              }
++              gasket_dev_write_64(gasket_dev, value,
++                                  interrupt_data->interrupt_bar_index,
++                                  interrupt_data->interrupts[i].reg);
++      }
++}
++
++void
++gasket_handle_interrupt(struct gasket_interrupt_data *interrupt_data,
++                      int interrupt_index)
++{
++      struct eventfd_ctx *ctx;
++
++      trace_gasket_interrupt_event(interrupt_data->name, interrupt_index);
++      read_lock(&interrupt_data->eventfd_ctx_lock);
++      ctx = interrupt_data->eventfd_ctxs[interrupt_index];
++        if (ctx)
++                #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0)
++                        eventfd_signal(ctx);
++                #else
++                        eventfd_signal(ctx, 1);
++                #endif
++        read_unlock(&interrupt_data->eventfd_ctx_lock);
++
++      ++(interrupt_data->interrupt_counts[interrupt_index]);
++}
++
++static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id)
++{
++      struct gasket_interrupt_data *interrupt_data = dev_id;
++      int interrupt = -1;
++      int i;
++
++      /* If this linear lookup is a problem, we can maintain a map/hash. */
++      for (i = 0; i < interrupt_data->num_interrupts; i++) {
++              if (interrupt_data->msix_entries[i].vector == irq) {
++                      interrupt = interrupt_data->msix_entries[i].entry;
++                      break;
++              }
++      }
++      if (interrupt == -1) {
++              pr_err("Received unknown irq %d\n", irq);
++              return IRQ_HANDLED;
++      }
++      gasket_handle_interrupt(interrupt_data, interrupt);
++      return IRQ_HANDLED;
++}
++
++static int
++gasket_interrupt_msix_init(struct gasket_interrupt_data *interrupt_data)
++{
++      int ret = 1;
++      int i;
++
++      interrupt_data->msix_entries =
++              kcalloc(interrupt_data->num_interrupts,
++                      sizeof(struct msix_entry), GFP_KERNEL);
++      if (!interrupt_data->msix_entries)
++              return -ENOMEM;
++
++      for (i = 0; i < interrupt_data->num_interrupts; i++) {
++              interrupt_data->msix_entries[i].entry = i;
++              interrupt_data->msix_entries[i].vector = 0;
++              interrupt_data->eventfd_ctxs[i] = NULL;
++      }
++
++      /* Retry MSIX_RETRY_COUNT times if not enough IRQs are available. */
++      for (i = 0; i < MSIX_RETRY_COUNT && ret > 0; i++)
++              ret = pci_enable_msix_exact(interrupt_data->pci_dev,
++                                          interrupt_data->msix_entries,
++                                          interrupt_data->num_interrupts);
++
++      if (ret)
++              return ret > 0 ? -EBUSY : ret;
++      interrupt_data->msix_configured = 1;
++
++      for (i = 0; i < interrupt_data->num_interrupts; i++) {
++              ret = request_irq(interrupt_data->msix_entries[i].vector,
++                                gasket_msix_interrupt_handler, 0,
++                                interrupt_data->name, interrupt_data);
++
++              if (ret) {
++                      dev_err(&interrupt_data->pci_dev->dev,
++                              "Cannot get IRQ for interrupt %d, vector %d; "
++                              "%d\n",
++                              i, interrupt_data->msix_entries[i].vector, ret);
++                      return ret;
++              }
++
++              interrupt_data->num_configured++;
++      }
++
++      return 0;
++}
++
++/*
++ * On QCM DragonBoard, we exit gasket_interrupt_msix_init() and kernel interrupt
++ * setup code with MSIX vectors masked. This is wrong because nothing else in
++ * the driver will normally touch the MSIX vectors.
++ *
++ * As a temporary hack, force unmasking there.
++ *
++ * TODO: Figure out why QCM kernel doesn't unmask the MSIX vectors, after
++ * gasket_interrupt_msix_init(), and remove this code.
++ */
++static void force_msix_interrupt_unmasking(struct gasket_dev *gasket_dev)
++{
++      int i;
++#define MSIX_VECTOR_SIZE 16
++#define MSIX_MASK_BIT_OFFSET 12
++#define APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE 0x46800
++      for (i = 0; i < gasket_dev->interrupt_data->num_configured; i++) {
++              /* Check if the MSIX vector is unmasked */
++              ulong location = APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE +
++                               MSIX_MASK_BIT_OFFSET + i * MSIX_VECTOR_SIZE;
++              u32 mask =
++                      gasket_dev_read_32(gasket_dev,
++                                         gasket_dev->interrupt_data->interrupt_bar_index,
++                                         location);
++              if (!(mask & 1))
++                      continue;
++              /* Unmask the msix vector (clear 32 bits) */
++              gasket_dev_write_32(gasket_dev, 0,
++                                  gasket_dev->interrupt_data->interrupt_bar_index,
++                                  location);
++      }
++#undef MSIX_VECTOR_SIZE
++#undef MSIX_MASK_BIT_OFFSET
++#undef APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE
++}
++
++static ssize_t interrupt_sysfs_show(struct device *device,
++                                  struct device_attribute *attr, char *buf)
++{
++      int i, ret;
++      ssize_t written = 0, total_written = 0;
++      struct gasket_interrupt_data *interrupt_data;
++      struct gasket_dev *gasket_dev;
++      struct gasket_sysfs_attribute *gasket_attr;
++      enum interrupt_sysfs_attribute_type sysfs_type;
++
++      gasket_dev = gasket_sysfs_get_device_data(device);
++      if (!gasket_dev) {
++              dev_dbg(device, "No sysfs mapping found for device\n");
++              return 0;
++      }
++
++      gasket_attr = gasket_sysfs_get_attr(device, attr);
++      if (!gasket_attr) {
++              dev_dbg(device, "No sysfs attr data found for device\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return 0;
++      }
++
++      sysfs_type = (enum interrupt_sysfs_attribute_type)
++              gasket_attr->data.attr_type;
++      interrupt_data = gasket_dev->interrupt_data;
++      switch (sysfs_type) {
++      case ATTR_INTERRUPT_COUNTS:
++              for (i = 0; i < interrupt_data->num_interrupts; ++i) {
++                      written =
++                              scnprintf(buf, PAGE_SIZE - total_written,
++                                        "0x%02x: %ld\n", i,
++                                        interrupt_data->interrupt_counts[i]);
++                      total_written += written;
++                      buf += written;
++              }
++              ret = total_written;
++              break;
++      default:
++              dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
++                      attr->attr.name);
++              ret = 0;
++              break;
++      }
++
++      gasket_sysfs_put_attr(device, gasket_attr);
++      gasket_sysfs_put_device_data(device, gasket_dev);
++      return ret;
++}
++
++static struct gasket_sysfs_attribute interrupt_sysfs_attrs[] = {
++      GASKET_SYSFS_RO(interrupt_counts, interrupt_sysfs_show,
++                      ATTR_INTERRUPT_COUNTS),
++      GASKET_END_OF_ATTR_ARRAY,
++};
++
++int gasket_interrupt_init(struct gasket_dev *gasket_dev)
++{
++      int ret;
++      struct gasket_interrupt_data *interrupt_data;
++      const struct gasket_driver_desc *driver_desc =
++              gasket_get_driver_desc(gasket_dev);
++
++      interrupt_data = kzalloc(sizeof(struct gasket_interrupt_data),
++                               GFP_KERNEL);
++      if (!interrupt_data)
++              return -ENOMEM;
++      gasket_dev->interrupt_data = interrupt_data;
++      interrupt_data->name = driver_desc->name;
++      interrupt_data->type = driver_desc->interrupt_type;
++      interrupt_data->pci_dev = gasket_dev->pci_dev;
++      interrupt_data->num_interrupts = driver_desc->num_interrupts;
++      interrupt_data->interrupts = driver_desc->interrupts;
++      interrupt_data->interrupt_bar_index = driver_desc->interrupt_bar_index;
++      interrupt_data->pack_width = driver_desc->interrupt_pack_width;
++
++      interrupt_data->eventfd_ctxs = kcalloc(driver_desc->num_interrupts,
++                                             sizeof(struct eventfd_ctx *),
++                                             GFP_KERNEL);
++      if (!interrupt_data->eventfd_ctxs) {
++              kfree(interrupt_data);
++              return -ENOMEM;
++      }
++
++      interrupt_data->interrupt_counts = kcalloc(driver_desc->num_interrupts,
++                                                 sizeof(ulong),
++                                                 GFP_KERNEL);
++      if (!interrupt_data->interrupt_counts) {
++              kfree(interrupt_data->eventfd_ctxs);
++              kfree(interrupt_data);
++              return -ENOMEM;
++      }
++
++      rwlock_init(&interrupt_data->eventfd_ctx_lock);
++
++      switch (interrupt_data->type) {
++      case PCI_MSIX:
++              ret = gasket_interrupt_msix_init(interrupt_data);
++              if (ret)
++                      break;
++              force_msix_interrupt_unmasking(gasket_dev);
++              break;
++
++      case DEVICE_MANAGED:  /* Device driver manages IRQ init */
++              interrupt_data->num_configured = interrupt_data->num_interrupts;
++              ret = 0;
++              break;
++
++      default:
++              ret = -EINVAL;
++      }
++
++      if (ret) {
++              /* Failing to setup interrupts will cause the device to report
++               * GASKET_STATUS_LAMED. But it is not fatal.
++               */
++              dev_warn(gasket_dev->dev,
++                       "Couldn't initialize interrupts: %d\n", ret);
++              return 0;
++      }
++
++      gasket_interrupt_setup(gasket_dev);
++      gasket_sysfs_create_entries(gasket_dev->dev_info.device,
++                                  interrupt_sysfs_attrs);
++
++      return 0;
++}
++EXPORT_SYMBOL(gasket_interrupt_init);
++
++void gasket_interrupt_msix_cleanup(struct gasket_interrupt_data *interrupt_data)
++{
++      int i;
++
++      for (i = 0; i < interrupt_data->num_configured; i++) {
++              gasket_interrupt_clear_eventfd(interrupt_data, i);
++              free_irq(interrupt_data->msix_entries[i].vector,
++                       interrupt_data);
++      }
++      interrupt_data->num_configured = 0;
++
++      if (interrupt_data->msix_configured)
++              pci_disable_msix(interrupt_data->pci_dev);
++      interrupt_data->msix_configured = 0;
++      kfree(interrupt_data->msix_entries);
++      interrupt_data->msix_entries = NULL;
++}
++EXPORT_SYMBOL(gasket_interrupt_msix_cleanup);
++
++int gasket_interrupt_reinit(struct gasket_dev *gasket_dev)
++{
++      int ret;
++
++      if (!gasket_dev->interrupt_data) {
++              dev_dbg(gasket_dev->dev,
++                      "Attempted to reinit uninitialized interrupt data\n");
++              return -EINVAL;
++      }
++
++      switch (gasket_dev->interrupt_data->type) {
++      case PCI_MSIX:
++              gasket_interrupt_msix_cleanup(gasket_dev->interrupt_data);
++              ret = gasket_interrupt_msix_init(gasket_dev->interrupt_data);
++              if (ret)
++                      break;
++              force_msix_interrupt_unmasking(gasket_dev);
++              break;
++
++      case DEVICE_MANAGED: /* Device driver manages IRQ reinit */
++              ret = 0;
++              break;
++
++      default:
++              ret = -EINVAL;
++      }
++
++      if (ret) {
++              /* Failing to setup interrupts will cause the device
++               * to report GASKET_STATUS_LAMED, but is not fatal.
++               */
++              dev_warn(gasket_dev->dev, "Couldn't reinit interrupts: %d\n",
++                       ret);
++              return 0;
++      }
++
++      gasket_interrupt_setup(gasket_dev);
++
++      return 0;
++}
++EXPORT_SYMBOL(gasket_interrupt_reinit);
++
++/* See gasket_interrupt.h for description. */
++int gasket_interrupt_reset_counts(struct gasket_dev *gasket_dev)
++{
++      dev_dbg(gasket_dev->dev, "Clearing interrupt counts\n");
++      memset(gasket_dev->interrupt_data->interrupt_counts, 0,
++             gasket_dev->interrupt_data->num_interrupts *
++                      sizeof(*gasket_dev->interrupt_data->interrupt_counts));
++      return 0;
++}
++
++/* See gasket_interrupt.h for description. */
++void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev)
++{
++      struct gasket_interrupt_data *interrupt_data =
++              gasket_dev->interrupt_data;
++      /*
++       * It is possible to get an error code from gasket_interrupt_init
++       * before interrupt_data has been allocated, so check it.
++       */
++      if (!interrupt_data)
++              return;
++
++      switch (interrupt_data->type) {
++      case PCI_MSIX:
++              gasket_interrupt_msix_cleanup(interrupt_data);
++              break;
++
++      case DEVICE_MANAGED: /* Device driver manages IRQ cleanup */
++              break;
++
++      default:
++              break;
++      }
++
++      kfree(interrupt_data->interrupt_counts);
++      kfree(interrupt_data->eventfd_ctxs);
++      kfree(interrupt_data);
++      gasket_dev->interrupt_data = NULL;
++}
++
++int gasket_interrupt_system_status(struct gasket_dev *gasket_dev)
++{
++      if (!gasket_dev->interrupt_data) {
++              dev_dbg(gasket_dev->dev, "Interrupt data is null\n");
++              return GASKET_STATUS_DEAD;
++      }
++
++      if (gasket_dev->interrupt_data->num_configured !=
++              gasket_dev->interrupt_data->num_interrupts) {
++              dev_dbg(gasket_dev->dev,
++                      "Not all interrupts were configured\n");
++              return GASKET_STATUS_LAMED;
++      }
++
++      return GASKET_STATUS_ALIVE;
++}
++
++int gasket_interrupt_set_eventfd(struct gasket_interrupt_data *interrupt_data,
++                               int interrupt, int event_fd)
++{
++      struct eventfd_ctx *ctx;
++      ulong flags;
++
++      if (interrupt < 0 || interrupt >= interrupt_data->num_interrupts)
++              return -EINVAL;
++
++      ctx = eventfd_ctx_fdget(event_fd);
++      if (IS_ERR(ctx))
++              return PTR_ERR(ctx);
++
++      /* Put the old eventfd ctx before setting, else we leak the ref. */
++      write_lock_irqsave(&interrupt_data->eventfd_ctx_lock, flags);
++      if (interrupt_data->eventfd_ctxs[interrupt] != NULL)
++              eventfd_ctx_put(interrupt_data->eventfd_ctxs[interrupt]);
++      interrupt_data->eventfd_ctxs[interrupt] = ctx;
++      write_unlock_irqrestore(&interrupt_data->eventfd_ctx_lock, flags);
++      return 0;
++}
++
++int gasket_interrupt_clear_eventfd(struct gasket_interrupt_data *interrupt_data,
++                                 int interrupt)
++{
++      ulong flags;
++
++      if (interrupt < 0 || interrupt >= interrupt_data->num_interrupts)
++              return -EINVAL;
++
++      /* Put the old eventfd ctx before clearing, else we leak the ref. */
++      write_lock_irqsave(&interrupt_data->eventfd_ctx_lock, flags);
++      if (interrupt_data->eventfd_ctxs[interrupt] != NULL)
++              eventfd_ctx_put(interrupt_data->eventfd_ctxs[interrupt]);
++      interrupt_data->eventfd_ctxs[interrupt] = NULL;
++      write_unlock_irqrestore(&interrupt_data->eventfd_ctx_lock, flags);
++      return 0;
++}
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_interrupt.h b/drivers/staging/gasket-driver/gasket_interrupt.h
+--- a/drivers/staging/gasket-driver/gasket_interrupt.h 1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_interrupt.h 2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,108 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Gasket common interrupt module. Defines functions for enabling
++ * eventfd-triggered interrupts between a Gasket device and a host process.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++#ifndef __GASKET_INTERRUPT_H__
++#define __GASKET_INTERRUPT_H__
++
++#include <linux/eventfd.h>
++#include <linux/pci.h>
++
++#include "gasket_core.h"
++
++/* Note that this currently assumes that device interrupts are a dense set,
++ * numbered from 0 - (num_interrupts - 1). Should this have to change, these
++ * APIs will have to be updated.
++ */
++
++/* Opaque type used to hold interrupt subsystem data. */
++struct gasket_interrupt_data;
++
++/*
++ * Initialize the interrupt module.
++ * @gasket_dev: The Gasket device structure for the device to be initted.
++ */
++int gasket_interrupt_init(struct gasket_dev *gasket_dev);
++
++/*
++ * Clean up a device's interrupt structure.
++ * @gasket_dev: The Gasket information structure for this device.
++ *
++ * Cleans up the device's interrupts and deallocates data.
++ */
++void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev);
++
++/*
++ * Clean up and re-initialize the MSI-x subsystem.
++ * @gasket_dev: The Gasket information structure for this device.
++ *
++ * Performs a teardown of the MSI-x subsystem and re-initializes it. Does not
++ * free the underlying data structures. Returns 0 on success and an error code
++ * on error.
++ */
++int gasket_interrupt_reinit(struct gasket_dev *gasket_dev);
++
++/*
++ * Clean up the MSI-x subsystem.
++ * @interrupt_data: The interrupt data structure for this device.
++ *
++ * Performs a teardown of the MSI-x subsystem. Does not free the underlying data structures.
++ */
++void gasket_interrupt_msix_cleanup(struct gasket_interrupt_data *interrupt_data);
++
++/* Handle gasket interrupt processing, called from an external handler. */
++void
++gasket_handle_interrupt(struct gasket_interrupt_data *interrupt_data,
++                      int interrupt_index);
++
++/*
++ * Reset the counts stored in the interrupt subsystem.
++ * @gasket_dev: The Gasket information structure for this device.
++ *
++ * Sets the counts of all interrupts in the subsystem to 0.
++ */
++int gasket_interrupt_reset_counts(struct gasket_dev *gasket_dev);
++
++/*
++ * Associates an eventfd with a device interrupt.
++ * @data: Pointer to device interrupt data.
++ * @interrupt: The device interrupt to configure.
++ * @event_fd: The eventfd to associate with the interrupt.
++ *
++ * Prepares the host to receive notification of device interrupts by associating
++ * event_fd with interrupt. Upon receipt of a device interrupt, event_fd will be
++ * signaled, after successful configuration.
++ *
++ * Returns 0 on success, a negative error code otherwise.
++ */
++int gasket_interrupt_set_eventfd(struct gasket_interrupt_data *interrupt_data,
++                               int interrupt, int event_fd);
++
++/*
++ * Removes an interrupt-eventfd association.
++ * @data: Pointer to device interrupt data.
++ * @interrupt: The device interrupt to de-associate.
++ *
++ * Removes any eventfd associated with the specified interrupt, if any.
++ */
++int gasket_interrupt_clear_eventfd(struct gasket_interrupt_data *interrupt_data,
++                                 int interrupt);
++
++/*
++ * The below functions exist for backwards compatibility.
++ * No new uses should be written.
++ */
++/*
++ * Get the health of the interrupt subsystem.
++ * @gasket_dev: The Gasket device struct.
++ *
++ * Returns DEAD if not set up, LAMED if initialization failed, and ALIVE
++ * otherwise.
++ */
++
++int gasket_interrupt_system_status(struct gasket_dev *gasket_dev);
++
++#endif
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_ioctl.c b/drivers/staging/gasket-driver/gasket_ioctl.c
+--- a/drivers/staging/gasket-driver/gasket_ioctl.c     1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_ioctl.c     2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,470 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (C) 2018 Google, Inc. */
++#include "gasket.h"
++#include "gasket_ioctl.h"
++#include "gasket_constants.h"
++#include "gasket_core.h"
++#include "gasket_interrupt.h"
++#include "gasket_page_table.h"
++#include <linux/compiler.h>
++#include <linux/device.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++
++#ifdef GASKET_KERNEL_TRACE_SUPPORT
++#define CREATE_TRACE_POINTS
++#include <trace/events/gasket_ioctl.h>
++#else
++#define trace_gasket_ioctl_entry(x, ...)
++#define trace_gasket_ioctl_exit(x)
++#define trace_gasket_ioctl_integer_data(x)
++#define trace_gasket_ioctl_eventfd_data(x, ...)
++#define trace_gasket_ioctl_page_table_data(x, ...)
++#define trace_gasket_ioctl_page_table_flags_data(x, ...)
++#define trace_gasket_ioctl_config_coherent_allocator(x, ...)
++#endif
++
++/* Associate an eventfd with an interrupt. */
++static int gasket_set_event_fd(struct gasket_dev *gasket_dev,
++                             struct gasket_interrupt_eventfd __user *argp)
++{
++      struct gasket_interrupt_eventfd die;
++
++      if (copy_from_user(&die, argp, sizeof(struct gasket_interrupt_eventfd)))
++              return -EFAULT;
++
++      trace_gasket_ioctl_eventfd_data(die.interrupt, die.event_fd);
++
++      return gasket_interrupt_set_eventfd(
++              gasket_dev->interrupt_data, die.interrupt, die.event_fd);
++}
++
++/* Read the size of the page table. */
++static int gasket_read_page_table_size(
++      struct gasket_dev *gasket_dev,
++      struct gasket_page_table_ioctl __user *argp)
++{
++      int ret = 0;
++      struct gasket_page_table_ioctl ibuf;
++
++      if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
++              return -EFAULT;
++
++      if (ibuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      ibuf.size = gasket_page_table_num_entries(
++              gasket_dev->page_table[ibuf.page_table_index]);
++
++      trace_gasket_ioctl_page_table_data(
++              ibuf.page_table_index, ibuf.size, ibuf.host_address,
++              ibuf.device_address);
++
++      if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
++              return -EFAULT;
++
++      return ret;
++}
++
++/* Read the size of the simple page table. */
++static int gasket_read_simple_page_table_size(
++      struct gasket_dev *gasket_dev,
++      struct gasket_page_table_ioctl __user *argp)
++{
++      int ret = 0;
++      struct gasket_page_table_ioctl ibuf;
++
++      if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
++              return -EFAULT;
++
++      if (ibuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      ibuf.size =
++              gasket_page_table_num_simple_entries(gasket_dev->page_table[ibuf.page_table_index]);
++
++      trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
++                                         ibuf.host_address,
++                                         ibuf.device_address);
++
++      if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
++              return -EFAULT;
++
++      return ret;
++}
++
++/* Set the boundary between the simple and extended page tables. */
++static int gasket_partition_page_table(
++      struct gasket_dev *gasket_dev,
++      struct gasket_page_table_ioctl __user *argp)
++{
++      int ret;
++      struct gasket_page_table_ioctl ibuf;
++      uint max_page_table_size;
++
++      if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
++              return -EFAULT;
++
++      trace_gasket_ioctl_page_table_data(
++              ibuf.page_table_index, ibuf.size, ibuf.host_address,
++              ibuf.device_address);
++
++      if (ibuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++      max_page_table_size = gasket_page_table_max_size(
++              gasket_dev->page_table[ibuf.page_table_index]);
++
++      if (ibuf.size > max_page_table_size) {
++              dev_dbg(gasket_dev->dev,
++                      "Partition request 0x%llx too large, max is 0x%x\n",
++                      ibuf.size, max_page_table_size);
++              return -EINVAL;
++      }
++
++      mutex_lock(&gasket_dev->mutex);
++
++      ret = gasket_page_table_partition(
++              gasket_dev->page_table[ibuf.page_table_index], ibuf.size);
++      mutex_unlock(&gasket_dev->mutex);
++
++      return ret;
++}
++
++/* Map a userspace buffer to a device virtual address. */
++static int gasket_map_buffers_common(struct gasket_dev *gasket_dev,
++                                   struct gasket_page_table_ioctl_flags
++                                   *pibuf)
++{
++      if (pibuf->base.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      if (gasket_page_table_are_addrs_bad(gasket_dev->page_table[pibuf->base.page_table_index],
++                                          pibuf->base.host_address,
++                                          pibuf->base.device_address,
++                                          pibuf->base.size))
++              return -EINVAL;
++
++      return gasket_page_table_map(gasket_dev->page_table[pibuf->base.page_table_index],
++                                   pibuf->base.host_address,
++                                   pibuf->base.device_address,
++                                   pibuf->base.size / PAGE_SIZE,
++                                   pibuf->flags);
++}
++
++static int gasket_map_buffers(struct gasket_dev *gasket_dev,
++                            struct gasket_page_table_ioctl __user *argp)
++{
++      struct gasket_page_table_ioctl_flags ibuf;
++ 
++      if (copy_from_user(&ibuf.base, argp, sizeof(struct gasket_page_table_ioctl)))
++              return -EFAULT;
++ 
++      ibuf.flags = 0;
++ 
++      trace_gasket_ioctl_page_table_data(ibuf.base.page_table_index,
++                                         ibuf.base.size,
++                                         ibuf.base.host_address,
++                                         ibuf.base.device_address);
++
++      return gasket_map_buffers_common(gasket_dev, &ibuf);
++}
++
++static int gasket_map_buffers_flags(struct gasket_dev *gasket_dev,
++                                  struct gasket_page_table_ioctl_flags __user *argp)
++{
++      struct gasket_page_table_ioctl_flags ibuf;
++
++      if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl_flags)))
++              return -EFAULT;
++ 
++      trace_gasket_ioctl_page_table_flags_data(ibuf.base.page_table_index,
++                                               ibuf.base.size,
++                                               ibuf.base.host_address,
++                                               ibuf.base.device_address,
++                                               ibuf.flags);
++ 
++      return gasket_map_buffers_common(gasket_dev, &ibuf);
++}
++
++/* Unmap a userspace buffer from a device virtual address. */
++static int gasket_unmap_buffers(struct gasket_dev *gasket_dev,
++                              struct gasket_page_table_ioctl __user *argp)
++{
++      struct gasket_page_table_ioctl ibuf;
++
++      if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
++              return -EFAULT;
++
++      trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
++                                         ibuf.host_address,
++                                         ibuf.device_address);
++
++      if (ibuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      if (gasket_page_table_is_dev_addr_bad(gasket_dev->page_table[ibuf.page_table_index],
++                                            ibuf.device_address, ibuf.size))
++              return -EINVAL;
++
++      gasket_page_table_unmap(gasket_dev->page_table[ibuf.page_table_index],
++                              ibuf.device_address, ibuf.size / PAGE_SIZE);
++
++      return 0;
++}
++
++/* Map/unmap dma-buf to/from a device virtual address. */
++static int gasket_map_dmabuf(struct gasket_dev *gasket_dev,
++                           struct gasket_page_table_ioctl_dmabuf __user *argp)
++{
++      struct gasket_page_table_ioctl_dmabuf dbuf;
++      struct gasket_page_table *pg_tbl;
++
++      if (copy_from_user(&dbuf, argp, sizeof(dbuf)))
++              return -EFAULT;
++
++      if (dbuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      pg_tbl = gasket_dev->page_table[dbuf.page_table_index];
++      if (gasket_page_table_is_dev_addr_bad(pg_tbl,
++                                            dbuf.device_address,
++                                            dbuf.num_pages * PAGE_SIZE))
++              return -EINVAL;
++
++      if (dbuf.map)
++              return gasket_page_table_map_dmabuf(pg_tbl,
++                                                  dbuf.dmabuf_fd,
++                                                  dbuf.device_address,
++                                                  dbuf.num_pages,
++                                                  dbuf.flags);
++      else
++              return gasket_page_table_unmap_dmabuf(pg_tbl,
++                                                    dbuf.dmabuf_fd,
++                                                    dbuf.device_address,
++                                                    dbuf.num_pages);
++}
++
++/*
++ * Reserve structures for coherent allocation, and allocate or free the
++ * corresponding memory.
++ */
++static int gasket_config_coherent_allocator(
++      struct gasket_dev *gasket_dev,
++      struct gasket_coherent_alloc_config_ioctl __user *argp)
++{
++      int ret;
++      struct gasket_coherent_alloc_config_ioctl ibuf;
++      dma_addr_t dma_address;
++
++      if (copy_from_user(&ibuf, argp,
++                         sizeof(struct gasket_coherent_alloc_config_ioctl)))
++              return -EFAULT;
++
++      trace_gasket_ioctl_config_coherent_allocator(ibuf.enable, ibuf.size,
++                                                   ibuf.dma_address);
++
++      if (ibuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      if (ibuf.size > PAGE_SIZE * MAX_NUM_COHERENT_PAGES)
++              return -ENOMEM;
++
++      if (ibuf.enable == 0) {
++              dma_address = ibuf.dma_address;
++              ret = gasket_free_coherent_memory(gasket_dev, ibuf.size,
++                                                dma_address,
++                                                ibuf.page_table_index);
++      } else {
++              ret = gasket_alloc_coherent_memory(gasket_dev, ibuf.size,
++                                                 &dma_address,
++                                                 ibuf.page_table_index);
++      }
++      if (ret)
++              return ret;
++
++      if (ibuf.enable != 0)
++              ibuf.dma_address = dma_address;
++
++      if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
++              return -EFAULT;
++
++      return 0;
++}
++
++/* Check permissions for Gasket ioctls. */
++static bool gasket_ioctl_check_permissions(struct file *filp, uint cmd)
++{
++      bool alive;
++      bool read, write;
++      struct gasket_dev *gasket_dev = (struct gasket_dev *)filp->private_data;
++
++      alive = (gasket_dev->status == GASKET_STATUS_ALIVE);
++      if (!alive)
++              dev_dbg(gasket_dev->dev, "%s alive %d status %d\n",
++                      __func__, alive, gasket_dev->status);
++
++      read = !!(filp->f_mode & FMODE_READ);
++      write = !!(filp->f_mode & FMODE_WRITE);
++
++      switch (cmd) {
++      case GASKET_IOCTL_RESET:
++      case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
++              return write;
++
++      case GASKET_IOCTL_PAGE_TABLE_SIZE:
++      case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
++      case GASKET_IOCTL_NUMBER_PAGE_TABLES:
++              return read;
++
++      case GASKET_IOCTL_PARTITION_PAGE_TABLE:
++      case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
++              return alive && write;
++
++      case GASKET_IOCTL_MAP_BUFFER:
++      case GASKET_IOCTL_MAP_BUFFER_FLAGS:
++      case GASKET_IOCTL_UNMAP_BUFFER:
++      case GASKET_IOCTL_MAP_DMABUF:
++              return alive && write;
++
++      case GASKET_IOCTL_CLEAR_EVENTFD:
++      case GASKET_IOCTL_SET_EVENTFD:
++              return alive && write;
++      }
++
++      return false; /* unknown permissions */
++}
++
++/*
++ * standard ioctl dispatch function.
++ * @filp: File structure pointer describing this node usage session.
++ * @cmd: ioctl number to handle.
++ * @argp: ioctl-specific data pointer.
++ *
++ * Standard ioctl dispatcher; forwards operations to individual handlers.
++ */
++long gasket_handle_ioctl(struct file *filp, uint cmd, void __user *argp)
++{
++      struct gasket_dev *gasket_dev;
++      unsigned long arg = (unsigned long)argp;
++      gasket_ioctl_permissions_cb_t ioctl_permissions_cb;
++      int retval;
++
++      gasket_dev = (struct gasket_dev *)filp->private_data;
++      trace_gasket_ioctl_entry(gasket_dev->dev_info.name, cmd);
++
++      ioctl_permissions_cb = gasket_get_ioctl_permissions_cb(gasket_dev);
++      if (ioctl_permissions_cb) {
++              retval = ioctl_permissions_cb(filp, cmd, argp);
++              if (retval < 0) {
++                      trace_gasket_ioctl_exit(retval);
++                      return retval;
++              } else if (retval == 0) {
++                      trace_gasket_ioctl_exit(-EPERM);
++                      return -EPERM;
++              }
++      } else if (!gasket_ioctl_check_permissions(filp, cmd)) {
++              trace_gasket_ioctl_exit(-EPERM);
++              dev_dbg(gasket_dev->dev, "ioctl cmd=%x noperm\n", cmd);
++              return -EPERM;
++      }
++
++      /* Tracing happens in this switch statement for all ioctls with
++       * an integer argrument, but ioctls with a struct argument
++       * that needs copying and decoding, that tracing is done within
++       * the handler call.
++       */
++      switch (cmd) {
++      case GASKET_IOCTL_RESET:
++              retval = gasket_reset(gasket_dev);
++              break;
++      case GASKET_IOCTL_SET_EVENTFD:
++              retval = gasket_set_event_fd(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_CLEAR_EVENTFD:
++              trace_gasket_ioctl_integer_data(arg);
++              retval =
++                      gasket_interrupt_clear_eventfd(gasket_dev->interrupt_data,
++                                                     (int)arg);
++              break;
++      case GASKET_IOCTL_PARTITION_PAGE_TABLE:
++              trace_gasket_ioctl_integer_data(arg);
++              retval = gasket_partition_page_table(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_NUMBER_PAGE_TABLES:
++              trace_gasket_ioctl_integer_data(gasket_dev->num_page_tables);
++              if (copy_to_user(argp, &gasket_dev->num_page_tables,
++                               sizeof(uint64_t)))
++                      retval = -EFAULT;
++              else
++                      retval = 0;
++              break;
++      case GASKET_IOCTL_PAGE_TABLE_SIZE:
++              retval = gasket_read_page_table_size(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
++              retval = gasket_read_simple_page_table_size(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_MAP_BUFFER:
++              retval = gasket_map_buffers(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_MAP_BUFFER_FLAGS:
++              retval = gasket_map_buffers_flags(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
++              retval = gasket_config_coherent_allocator(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_UNMAP_BUFFER:
++              retval = gasket_unmap_buffers(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
++              /* Clear interrupt counts doesn't take an arg, so use 0. */
++              trace_gasket_ioctl_integer_data(0);
++              retval = gasket_interrupt_reset_counts(gasket_dev);
++              break;
++      case GASKET_IOCTL_MAP_DMABUF:
++              retval = gasket_map_dmabuf(gasket_dev, argp);
++              break;
++      default:
++              /* If we don't understand the ioctl, the best we can do is trace
++               * the arg.
++               */
++              trace_gasket_ioctl_integer_data(arg);
++              dev_dbg(gasket_dev->dev,
++                      "Unknown ioctl cmd=0x%x not caught by "
++                      "gasket_is_supported_ioctl\n",
++                      cmd);
++              retval = -EINVAL;
++              break;
++      }
++
++      trace_gasket_ioctl_exit(retval);
++      return retval;
++}
++
++/*
++ * Determines if an ioctl is part of the standard Gasket framework.
++ * @cmd: The ioctl number to handle.
++ *
++ * Returns 1 if the ioctl is supported and 0 otherwise.
++ */
++long gasket_is_supported_ioctl(uint cmd)
++{
++      switch (cmd) {
++      case GASKET_IOCTL_RESET:
++      case GASKET_IOCTL_SET_EVENTFD:
++      case GASKET_IOCTL_CLEAR_EVENTFD:
++      case GASKET_IOCTL_PARTITION_PAGE_TABLE:
++      case GASKET_IOCTL_NUMBER_PAGE_TABLES:
++      case GASKET_IOCTL_PAGE_TABLE_SIZE:
++      case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
++      case GASKET_IOCTL_MAP_BUFFER:
++      case GASKET_IOCTL_MAP_BUFFER_FLAGS:
++      case GASKET_IOCTL_UNMAP_BUFFER:
++      case GASKET_IOCTL_MAP_DMABUF:
++      case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
++      case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
++              return 1;
++      default:
++              return 0;
++      }
++}
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_ioctl.h b/drivers/staging/gasket-driver/gasket_ioctl.h
+--- a/drivers/staging/gasket-driver/gasket_ioctl.h     1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_ioctl.h     2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,28 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/* Copyright (C) 2018 Google, Inc. */
++#ifndef __GASKET_IOCTL_H__
++#define __GASKET_IOCTL_H__
++
++#include "gasket_core.h"
++
++#include <linux/compiler.h>
++
++/*
++ * Handle Gasket common ioctls.
++ * @filp: Pointer to the ioctl's file.
++ * @cmd: Ioctl command.
++ * @arg: Ioctl argument pointer.
++ *
++ * Returns 0 on success and nonzero on failure.
++ */
++long gasket_handle_ioctl(struct file *filp, uint cmd, void __user *argp);
++
++/*
++ * Determines if an ioctl is part of the standard Gasket framework.
++ * @cmd: The ioctl number to handle.
++ *
++ * Returns 1 if the ioctl is supported and 0 otherwise.
++ */
++long gasket_is_supported_ioctl(uint cmd);
++
++#endif
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_page_table.c b/drivers/staging/gasket-driver/gasket_page_table.c
+--- a/drivers/staging/gasket-driver/gasket_page_table.c        1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_page_table.c        2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,1597 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Implementation of Gasket page table support.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++
++/*
++ * Implementation of Gasket page table support.
++ *
++ * This file assumes 4kB pages throughout; can be factored out when necessary.
++ *
++ * There is a configurable number of page table entries, as well as a
++ * configurable bit index for the extended address flag. Both of these are
++ * specified in gasket_page_table_init through the page_table_config parameter.
++ *
++ * The following example assumes:
++ *   page_table_config->total_entries = 8192
++ *   page_table_config->extended_bit = 63
++ *
++ * Address format:
++ * Simple addresses - those whose containing pages are directly placed in the
++ * device's address translation registers - are laid out as:
++ * [ 63 - 25: 0 | 24 - 12: page index | 11 - 0: page offset ]
++ * page index:  The index of the containing page in the device's address
++ *              translation registers.
++ * page offset: The index of the address into the containing page.
++ *
++ * Extended address - those whose containing pages are contained in a second-
++ * level page table whose address is present in the device's address translation
++ * registers - are laid out as:
++ * [ 63: flag | 62 - 34: 0 | 33 - 21: dev/level 0 index |
++ *   20 - 12: host/level 1 index | 11 - 0: page offset ]
++ * flag:        Marker indicating that this is an extended address. Always 1.
++ * dev index:   The index of the first-level page in the device's extended
++ *              address translation registers.
++ * host index:  The index of the containing page in the [host-resident] second-
++ *              level page table.
++ * page offset: The index of the address into the containing [second-level]
++ *              page.
++ */
++#include "gasket_page_table.h"
++
++#include <linux/device.h>
++#include <linux/dma-buf.h>
++#include <linux/file.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/pagemap.h>
++#include <linux/version.h>
++#include <linux/vmalloc.h>
++
++#if __has_include(<linux/dma-buf.h>)
++MODULE_IMPORT_NS(DMA_BUF);
++#endif
++
++#include "gasket_constants.h"
++#include "gasket_core.h"
++
++/* Constants & utility macros */
++/* The number of pages that can be mapped into each second-level page table. */
++#define GASKET_PAGES_PER_SUBTABLE 512
++
++/* The starting position of the page index in a simple virtual address. */
++#define GASKET_SIMPLE_PAGE_SHIFT 12
++
++/* Flag indicating that a [device] slot is valid for use. */
++#define GASKET_VALID_SLOT_FLAG 1
++
++/*
++ * The starting position of the level 0 page index (i.e., the entry in the
++ * device's extended address registers) in an extended address.
++ * Also can be thought of as (log2(PAGE_SIZE) + log2(PAGES_PER_SUBTABLE)),
++ * or (12 + 9).
++ */
++#define GASKET_EXTENDED_LVL0_SHIFT 21
++
++/*
++ * Number of first level pages that Gasket chips support. Equivalent to
++ * log2(NUM_LVL0_PAGE_TABLES)
++ *
++ * At a maximum, allowing for a 34 bits address space (or 16GB)
++ *   = GASKET_EXTENDED_LVL0_WIDTH + (log2(PAGE_SIZE) + log2(PAGES_PER_SUBTABLE)
++ * or, = 13 + 9 + 12
++ */
++#define GASKET_EXTENDED_LVL0_WIDTH 13
++
++/*
++ * The starting position of the level 1 page index (i.e., the entry in the
++ * host second-level/sub- table) in an extended address.
++ */
++#define GASKET_EXTENDED_LVL1_SHIFT 12
++
++/*
++ * Utilities for accessing flags bitfields.
++ */
++#define MASK(field)            (((1u << field##_WIDTH) - 1) << field##_SHIFT)
++#define GET(field, flags)      (((flags) & MASK(field)) >> field##_SHIFT)
++#define SET(field, flags, val) (((flags) & ~MASK(field)) | ((val) << field##_SHIFT))
++
++#define FLAGS_STATUS_SHIFT 0
++#define FLAGS_STATUS_WIDTH 1
++
++#define FLAGS_DMA_DIRECTION_SHIFT 1
++#define FLAGS_DMA_DIRECTION_WIDTH 2
++
++/* Type declarations */
++/* Valid states for a struct gasket_page_table_entry. */
++enum pte_status {
++      PTE_FREE,
++      PTE_INUSE,
++};
++
++/*
++ * Mapping metadata for a single page.
++ *
++ * In this file, host-side page table entries are referred to as that (or PTEs).
++ * Where device vs. host entries are differentiated, device-side or -visible
++ * entries are called "slots". A slot may be either an entry in the device's
++ * address translation table registers or an entry in a second-level page
++ * table ("subtable").
++ *
++ * The full data in this structure is visible on the host [of course]. Only
++ * the address contained in dma_addr is communicated to the device; that points
++ * to the actual page mapped and described by this structure.
++ */
++struct gasket_page_table_entry {
++      /*
++       * Internal structure matches gasket_page_table_ioctl_flags.flags.
++       * NOTE: All fields should have a default value of 0. This ensures that
++       * the kernel will be backwards compatible with old drivers.
++       */
++      u32 flags;
++
++      /*
++       * Index for alignment into host vaddrs.
++       * When a user specifies a host address for a mapping, that address may
++       * not be page-aligned. Offset is the index into the containing page of
++       * the host address (i.e., host_vaddr & (PAGE_SIZE - 1)).
++       * This is necessary for translating between user-specified addresses
++       * and page-aligned addresses.
++       */
++      int offset;
++
++      /* Address of the page in DMA space. */
++      dma_addr_t dma_addr;
++
++      /* Linux page descriptor for the page described by this structure. */
++      struct page *page;
++
++      /*
++       * If this is an extended and first-level entry, sublevel points
++       * to the second-level entries underneath this entry.
++       */
++      struct gasket_page_table_entry *sublevel;
++};
++
++/*
++ * Maintains virtual to physical address mapping for a coherent page that is
++ * allocated by this module for a given device.
++ * Note that coherent pages mappings virt mapping cannot be tracked by the
++ * Linux kernel, and coherent pages don't have a struct page associated,
++ * hence Linux kernel cannot perform a get_user_page_xx() on a phys address
++ * that was allocated coherent.
++ * This structure trivially implements this mechanism.
++ */
++struct gasket_coherent_page_entry {
++      /* Phys address, dma'able by the owner device */
++      dma_addr_t paddr;
++
++      /* Kernel virtual address */
++      u64 user_virt;
++
++      /* User virtual address that was mapped by the mmap kernel subsystem */
++      dma_addr_t kernel_virt;
++
++      /*
++       * Whether this page has been mapped into a user land process virtual
++       * space
++       */
++      u32 in_use;
++};
++
++/* Storage for dmabuf mapping information. */
++struct gasket_dmabuf_mapping {
++      struct dma_buf *dmabuf;
++      struct dma_buf_attachment *attachment;
++      struct sg_table *sgt;
++      enum dma_data_direction direction;
++      struct list_head list;
++};
++
++/*
++ * [Host-side] page table descriptor.
++ *
++ * This structure tracks the metadata necessary to manage both simple and
++ * extended page tables.
++ */
++struct gasket_page_table {
++      /* The config used to create this page table. */
++      struct gasket_page_table_config config;
++
++      /* The number of simple (single-level) entries in the page table. */
++      uint num_simple_entries;
++
++      /* The number of extended (two-level) entries in the page table. */
++      uint num_extended_entries;
++
++      /* Array of [host-side] page table entries. */
++      struct gasket_page_table_entry *entries;
++
++      /* Number of actively mapped kernel pages in this table. */
++      uint num_active_pages;
++
++      /* Device register: base of/first slot in the page table. */
++      u64 __iomem *base_slot;
++
++      /* Device register: holds the offset indicating the start of the
++       * extended address region of the device's address translation table.
++       */
++      u64 __iomem *extended_offset_reg;
++
++      /* Device structure for the underlying device. Only used for logging. */
++      struct device *device;
++
++      /* PCI system descriptor for the underlying device. */
++      struct pci_dev *pci_dev;
++
++      /* Location of the extended address bit for this Gasket device. */
++      u64 extended_flag;
++
++      /* Mutex to protect page table internals. */
++      struct mutex mutex;
++
++      /* Number of coherent pages accessible thru by this page table */
++      int num_coherent_pages;
++
++      /*
++       * List of coherent memory (physical) allocated for a device.
++       *
++       * This structure also remembers the user virtual mapping, this is
++       * hacky, but we need to do this because the kernel doesn't keep track
++       * of the user coherent pages (pfn pages), and virt to coherent page
++       * mapping.
++       * TODO: use find_vma() APIs to convert host address to vm_area, to
++       * dma_addr_t instead of storing user virtu address in
++       * gasket_coherent_page_entry
++       *
++       * Note that the user virtual mapping is created by the driver, in
++       * gasket_mmap function, so user_virt belongs in the driver anyhow.
++       */
++      struct gasket_coherent_page_entry *coherent_pages;
++
++      /* List of dmabufs currently attached and mapped. */
++      struct list_head dmabufs;
++};
++
++/* See gasket_page_table.h for description. */
++int gasket_page_table_init(struct gasket_page_table **ppg_tbl,
++                         const struct gasket_bar_data *bar_data,
++                         const struct gasket_page_table_config *page_table_config,
++                         struct device *device, struct pci_dev *pci_dev)
++{
++      ulong bytes;
++      struct gasket_page_table *pg_tbl;
++      ulong total_entries = page_table_config->total_entries;
++
++      /*
++       * TODO: Verify config->total_entries against value read from the
++       * hardware register that contains the page table size.
++       */
++      if (total_entries == ULONG_MAX) {
++              dev_dbg(device, "Error reading page table size. "
++                      "Initializing page table with size 0\n");
++              total_entries = 0;
++      }
++
++      dev_dbg(device,
++              "Attempting to initialize page table of size 0x%lx\n",
++              total_entries);
++
++      dev_dbg(device,
++              "Table has base reg 0x%x, extended offset reg 0x%x\n",
++              page_table_config->base_reg,
++              page_table_config->extended_reg);
++
++      *ppg_tbl = kzalloc(sizeof(**ppg_tbl), GFP_KERNEL);
++      if (!*ppg_tbl) {
++              dev_dbg(device, "No memory for page table\n");
++              return -ENOMEM;
++      }
++
++      pg_tbl = *ppg_tbl;
++      bytes = total_entries * sizeof(struct gasket_page_table_entry);
++      if (bytes != 0) {
++              pg_tbl->entries = vzalloc(bytes);
++              if (!pg_tbl->entries) {
++                      dev_dbg(device,
++                              "No memory for address translation metadata\n");
++                      kfree(pg_tbl);
++                      *ppg_tbl = NULL;
++                      return -ENOMEM;
++              }
++      }
++
++      mutex_init(&pg_tbl->mutex);
++      memcpy(&pg_tbl->config, page_table_config, sizeof(*page_table_config));
++      if (pg_tbl->config.mode == GASKET_PAGE_TABLE_MODE_NORMAL ||
++          pg_tbl->config.mode == GASKET_PAGE_TABLE_MODE_SIMPLE) {
++              pg_tbl->num_simple_entries = total_entries;
++              pg_tbl->num_extended_entries = 0;
++              pg_tbl->extended_flag = 1ull << page_table_config->extended_bit;
++      } else {
++              pg_tbl->num_simple_entries = 0;
++              pg_tbl->num_extended_entries = total_entries;
++              pg_tbl->extended_flag = 0;
++      }
++      pg_tbl->num_active_pages = 0;
++      pg_tbl->base_slot =
++              (u64 __iomem *)&bar_data->virt_base[page_table_config->base_reg];
++      pg_tbl->extended_offset_reg =
++              (u64 __iomem *)&bar_data->virt_base[page_table_config->extended_reg];
++      pg_tbl->device = get_device(device);
++      pg_tbl->pci_dev = pci_dev;
++      INIT_LIST_HEAD(&pg_tbl->dmabufs);
++
++      dev_dbg(device, "Page table initialized successfully\n");
++
++      return 0;
++}
++
++/*
++ * Check if a range of PTEs is free.
++ * The page table mutex must be held by the caller.
++ */
++static bool gasket_is_pte_range_free(struct gasket_page_table_entry *ptes,
++                                   uint num_entries)
++{
++      int i;
++
++      for (i = 0; i < num_entries; i++) {
++              if (GET(FLAGS_STATUS, ptes[i].flags) != PTE_FREE)
++                      return false;
++      }
++
++      return true;
++}
++
++/*
++ * Free a second level page [sub]table.
++ * The page table mutex must be held before this call.
++ */
++static void gasket_free_extended_subtable(struct gasket_page_table *pg_tbl,
++                                        struct gasket_page_table_entry *pte,
++                                        u64 __iomem *slot)
++{
++      /* Release the page table from the driver */
++      pte->flags = SET(FLAGS_STATUS, pte->flags, PTE_FREE);
++
++      /* Release the page table from the device */
++      writeq(0, slot);
++
++      if (pte->dma_addr)
++              dma_unmap_page(pg_tbl->device, pte->dma_addr, PAGE_SIZE,
++                             DMA_TO_DEVICE);
++
++      vfree(pte->sublevel);
++
++      if (pte->page)
++              free_page((ulong)page_address(pte->page));
++
++      memset(pte, 0, sizeof(struct gasket_page_table_entry));
++}
++
++/*
++ * Actually perform collection.
++ * The page table mutex must be held by the caller.
++ */
++static void
++gasket_page_table_garbage_collect_nolock(struct gasket_page_table *pg_tbl)
++{
++      struct gasket_page_table_entry *pte;
++      u64 __iomem *slot;
++
++      /* XXX FIX ME XXX -- more efficient to keep a usage count */
++      /* rather than scanning the second level page tables */
++
++      for (pte = pg_tbl->entries + pg_tbl->num_simple_entries,
++           slot = pg_tbl->base_slot + pg_tbl->num_simple_entries;
++           pte < pg_tbl->entries + pg_tbl->config.total_entries;
++           pte++, slot++) {
++              if (GET(FLAGS_STATUS, pte->flags) == PTE_INUSE) {
++                      if (gasket_is_pte_range_free(pte->sublevel,
++                                                   GASKET_PAGES_PER_SUBTABLE))
++                              gasket_free_extended_subtable(pg_tbl, pte,
++                                                            slot);
++              }
++      }
++}
++
++/* See gasket_page_table.h for description. */
++void gasket_page_table_garbage_collect(struct gasket_page_table *pg_tbl)
++{
++      mutex_lock(&pg_tbl->mutex);
++      gasket_page_table_garbage_collect_nolock(pg_tbl);
++      mutex_unlock(&pg_tbl->mutex);
++}
++
++/* See gasket_page_table.h for description. */
++void gasket_page_table_cleanup(struct gasket_page_table *pg_tbl)
++{
++      /* Deallocate free second-level tables. */
++      gasket_page_table_garbage_collect(pg_tbl);
++
++      /* TODO: Check that all PTEs have been freed? */
++
++      vfree(pg_tbl->entries);
++      pg_tbl->entries = NULL;
++
++      put_device(pg_tbl->device);
++      kfree(pg_tbl);
++}
++
++/* See gasket_page_table.h for description. */
++int gasket_page_table_partition(struct gasket_page_table *pg_tbl,
++                              uint num_simple_entries)
++{
++      int i, start;
++
++      mutex_lock(&pg_tbl->mutex);
++      if (num_simple_entries > pg_tbl->config.total_entries) {
++              mutex_unlock(&pg_tbl->mutex);
++              return -EINVAL;
++      }
++
++      gasket_page_table_garbage_collect_nolock(pg_tbl);
++
++      start = min(pg_tbl->num_simple_entries, num_simple_entries);
++
++      for (i = start; i < pg_tbl->config.total_entries; i++) {
++              if (GET(FLAGS_STATUS, pg_tbl->entries[i].flags) != PTE_FREE) {
++                      dev_err(pg_tbl->device, "entry %d is not free\n", i);
++                      mutex_unlock(&pg_tbl->mutex);
++                      return -EBUSY;
++              }
++      }
++
++      pg_tbl->num_simple_entries = num_simple_entries;
++      pg_tbl->num_extended_entries =
++              pg_tbl->config.total_entries - num_simple_entries;
++      writeq(num_simple_entries, pg_tbl->extended_offset_reg);
++
++      mutex_unlock(&pg_tbl->mutex);
++      return 0;
++}
++EXPORT_SYMBOL(gasket_page_table_partition);
++
++/*
++ * Return whether a host buffer was mapped as coherent memory.
++ *
++ * A Gasket page_table currently support one contiguous dma range, mapped to one
++ * contiguous virtual memory range. Check if the host_addr is within that range.
++ */
++static int is_coherent(struct gasket_page_table *pg_tbl, ulong host_addr)
++{
++      u64 min, max;
++
++      /* whether the host address is within user virt range */
++      if (!pg_tbl->coherent_pages)
++              return 0;
++
++      min = (u64)pg_tbl->coherent_pages[0].user_virt;
++      max = min + PAGE_SIZE * pg_tbl->num_coherent_pages;
++
++      return min <= host_addr && host_addr < max;
++}
++
++/* Safely return a page to the OS. */
++static bool gasket_release_page(struct page *page)
++{
++      if (!page)
++              return false;
++
++      if (!PageReserved(page))
++              SetPageDirty(page);
++      put_page(page);
++
++      return true;
++}
++
++/*
++ * Get and map last level page table buffers.
++ *
++ * slots is the location(s) to write device-mapped page address. If this is a
++ * simple mapping, these will be address translation registers. If this is
++ * an extended mapping, these will be within a second-level page table
++ * allocated by the host and so must have their __iomem attribute casted away.
++ */
++static int gasket_perform_mapping(struct gasket_page_table *pg_tbl,
++                                struct gasket_page_table_entry *ptes,
++                                u64 __iomem *slots,
++                                struct sg_page_iter *sg_iter,
++                                ulong host_addr,
++                                uint num_pages, u32 flags,
++                                int is_simple_mapping)
++{
++      int ret;
++      ulong offset;
++      struct page *page;
++      dma_addr_t dma_addr;
++      ulong page_addr;
++      int i;
++      enum dma_data_direction direction;
++
++      /* Must have a virtual host address or a sg iterator, but not both. */
++      if (!((uintptr_t)host_addr ^ (uintptr_t)sg_iter)) {
++              dev_err(pg_tbl->device, "need sg_iter or host_addr\n");
++              return -EINVAL;
++      }
++
++      direction = GET(FLAGS_DMA_DIRECTION, flags);
++      if (direction == DMA_NONE) {
++              dev_err(pg_tbl->device, "invalid DMA direction flags=0x%lx\n",
++                      (unsigned long)flags);
++              return -EINVAL;
++      }
++
++      for (i = 0; i < num_pages; i++) {
++              page_addr = host_addr + i * PAGE_SIZE;
++              offset = page_addr & (PAGE_SIZE - 1);
++              dev_dbg(pg_tbl->device, "%s i %d\n", __func__, i);
++              if (sg_iter) {
++                      if (!__sg_page_iter_next(sg_iter))
++                              return -EINVAL;
++
++                      /* Page already mapped for DMA. */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
++                      ptes[i].dma_addr = sg_page_iter_dma_address(sg_iter);
++#else
++                      ptes[i].dma_addr = sg_page_iter_dma_address(
++                              container_of(sg_iter, struct sg_dma_page_iter, base));
++#endif
++                      ptes[i].page = NULL;
++                      offset = 0;
++              } else if (is_coherent(pg_tbl, host_addr)) {
++                      u64 off =
++                              (u64)host_addr -
++                              (u64)pg_tbl->coherent_pages[0].user_virt;
++                      ptes[i].page = NULL;
++                      ptes[i].offset = offset;
++                      ptes[i].dma_addr = pg_tbl->coherent_pages[0].paddr +
++                                         off + i * PAGE_SIZE;
++              } else {
++                      ret = get_user_pages_fast(page_addr - offset, 1,
++                                                direction != DMA_TO_DEVICE,
++                                                &page);
++
++                      if (ret <= 0) {
++                              dev_err(pg_tbl->device,
++                                      "get user pages failed for addr=0x%lx, "
++                                      "offset=0x%lx [ret=%d]\n",
++                                      page_addr, offset, ret);
++                              return ret ? ret : -ENOMEM;
++                      }
++                      ++pg_tbl->num_active_pages;
++
++                      ptes[i].page = page;
++                      ptes[i].offset = offset;
++
++                      /* Map the page into DMA space. */
++                      ptes[i].dma_addr = dma_map_page(pg_tbl->device, page, 0, PAGE_SIZE,
++                                                      GET(FLAGS_DMA_DIRECTION, flags));
++                      dev_dbg(pg_tbl->device,
++                              "%s i %d pte %p pfn %p -> mapped %llx\n",
++                              __func__, i, &ptes[i],
++                              (void *)page_to_pfn(page),
++                              (unsigned long long)ptes[i].dma_addr);
++
++                      if (dma_mapping_error(pg_tbl->device,
++                                            ptes[i].dma_addr)) {
++                              dev_dbg(pg_tbl->device,
++                                      "%s i %d -> fail to map page %llx "
++                                      "[pfn %p phys %p]\n",
++                                      __func__, i,
++                                      (unsigned long long)ptes[i].dma_addr,
++                                      (void *)page_to_pfn(page),
++                                      (void *)page_to_phys(page));
++
++                              /* clean up */
++                              if (gasket_release_page(ptes[i].page))
++                                      --pg_tbl->num_active_pages;
++
++                              memset(&ptes[i], 0, sizeof(struct gasket_page_table_entry));
++                              return -EINVAL;
++                      }
++              }
++
++              /* Make the DMA-space address available to the device. */
++              dma_addr = (ptes[i].dma_addr + offset) | GASKET_VALID_SLOT_FLAG;
++
++              if (is_simple_mapping)
++                      writeq(dma_addr, &slots[i]);
++              else
++                      ((u64 __force *)slots)[i] = dma_addr;
++
++              /* Set PTE flags equal to flags param with STATUS=PTE_INUSE. */
++              ptes[i].flags = SET(FLAGS_STATUS, flags, PTE_INUSE);
++      }
++      return 0;
++}
++
++/*
++ * Return the index of the page for the address in the simple table.
++ * Does not perform validity checking.
++ */
++static int gasket_simple_page_idx(struct gasket_page_table *pg_tbl,
++                                u64 dev_addr)
++{
++      return (dev_addr >> GASKET_SIMPLE_PAGE_SHIFT) &
++              (pg_tbl->config.total_entries - 1);
++}
++
++/*
++ * Return the level 0 page index for the given address.
++ * Does not perform validity checking.
++ */
++static ulong gasket_extended_lvl0_page_idx(struct gasket_page_table *pg_tbl,
++                                         u64 dev_addr)
++{
++      return (dev_addr >> GASKET_EXTENDED_LVL0_SHIFT) &
++             (pg_tbl->config.total_entries - 1);
++}
++
++/*
++ * Return the level 1 page index for the given address.
++ * Does not perform validity checking.
++ */
++static ulong gasket_extended_lvl1_page_idx(struct gasket_page_table *pg_tbl,
++                                         u64 dev_addr)
++{
++      return (dev_addr >> GASKET_EXTENDED_LVL1_SHIFT) &
++             (GASKET_PAGES_PER_SUBTABLE - 1);
++}
++
++/*
++ * Allocate page table entries in a simple table.
++ * The page table mutex must be held by the caller.
++ */
++static int gasket_alloc_simple_entries(struct gasket_page_table *pg_tbl,
++                                     u64 dev_addr, uint num_pages)
++{
++      if (!gasket_is_pte_range_free(pg_tbl->entries +
++                                    gasket_simple_page_idx(pg_tbl, dev_addr),
++                                    num_pages))
++              return -EBUSY;
++
++      return 0;
++}
++
++/*
++ * Unmap and release mapped pages.
++ * The page table mutex must be held by the caller.
++ */
++static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl,
++                                   struct gasket_page_table_entry *ptes,
++                                   u64 __iomem *slots, uint num_pages,
++                                   int is_simple_mapping)
++{
++      int i;
++      /*
++       * For each page table entry and corresponding entry in the device's
++       * address translation table:
++       */
++      for (i = 0; i < num_pages; i++) {
++              /* release the address from the device, */
++              if (is_simple_mapping)
++                      writeq(0, &slots[i]);
++              else
++                      ((u64 __force *)slots)[i] = 0;
++
++              /* release the address from the driver, */
++              if (GET(FLAGS_STATUS, ptes[i].flags) == PTE_INUSE) {
++                      if (ptes[i].page && ptes[i].dma_addr) {
++                              dma_unmap_page(pg_tbl->device, ptes[i].dma_addr, PAGE_SIZE,
++                                             GET(FLAGS_DMA_DIRECTION, ptes[i].flags));
++                      }
++                      if (gasket_release_page(ptes[i].page))
++                              --pg_tbl->num_active_pages;
++              }
++
++              /* and clear the PTE. */
++              memset(&ptes[i], 0, sizeof(struct gasket_page_table_entry));
++      }
++}
++
++/*
++ * Unmap and release pages mapped to simple addresses.
++ * The page table mutex must be held by the caller.
++ */
++static void gasket_unmap_simple_pages(struct gasket_page_table *pg_tbl,
++                                    u64 dev_addr, uint num_pages)
++{
++      uint slot = gasket_simple_page_idx(pg_tbl, dev_addr);
++
++      gasket_perform_unmapping(pg_tbl, pg_tbl->entries + slot,
++                               pg_tbl->base_slot + slot, num_pages, 1);
++}
++
++/*
++ * Unmap and release buffers to extended addresses.
++ * The page table mutex must be held by the caller.
++ */
++static void gasket_unmap_extended_pages(struct gasket_page_table *pg_tbl,
++                                      u64 dev_addr, uint num_pages)
++{
++      uint slot_idx, remain, len;
++      struct gasket_page_table_entry *pte;
++      u64 __iomem *slot_base;
++
++      remain = num_pages;
++      slot_idx = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
++      pte = pg_tbl->entries + pg_tbl->num_simple_entries +
++            gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++
++      while (remain > 0) {
++              /* TODO: Add check to ensure pte remains valid? */
++              len = min(remain, GASKET_PAGES_PER_SUBTABLE - slot_idx);
++
++              if (GET(FLAGS_STATUS, pte->flags) == PTE_INUSE) {
++                      slot_base = (u64 __iomem *)(page_address(pte->page) +
++                                                  pte->offset);
++                      gasket_perform_unmapping(pg_tbl,
++                                               pte->sublevel + slot_idx,
++                                               slot_base + slot_idx, len, 0);
++                      /*
++                       * Extended page tables are in DRAM so they need to be
++                       * synced each time they are updated.
++                       */
++                      dma_sync_single_for_device(pg_tbl->device,
++                                                 pte->dma_addr + slot_idx * sizeof(u64),
++                                                 len * sizeof(u64), DMA_TO_DEVICE);
++              }
++
++              remain -= len;
++              slot_idx = 0;
++              pte++;
++      }
++}
++
++/* Evaluates to nonzero if the specified virtual address is simple. */
++static inline bool gasket_addr_is_simple(struct gasket_page_table *pg_tbl,
++                                       u64 addr)
++{
++      return !((addr) & (pg_tbl)->extended_flag);
++}
++
++/*
++ * Convert (simple, page, offset) into a device address.
++ * Examples:
++ * Simple page 0, offset 32:
++ *  Input (1, 0, 32), Output 0x20
++ * Simple page 1000, offset 511:
++ *  Input (1, 1000, 511), Output 0x3E81FF
++ * Extended page 0, offset 32:
++ *  Input (0, 0, 32), Output 0x8000000020
++ * Extended page 1000, offset 511:
++ *  Input (0, 1000, 511), Output 0x8003E81FF
++ */
++static u64 gasket_components_to_dev_address(struct gasket_page_table *pg_tbl,
++                                            int is_simple, uint page_index,
++                                            uint offset)
++{
++      u64 dev_addr = (page_index << GASKET_SIMPLE_PAGE_SHIFT) | offset;
++
++      return is_simple ? dev_addr : (pg_tbl->extended_flag | dev_addr);
++}
++
++/*
++ * Validity checking for simple addresses.
++ *
++ * Verify that address translation commutes (from address to/from page + offset)
++ * and that the requested page range starts and ends within the set of
++ * currently-partitioned simple pages.
++ */
++static bool gasket_is_simple_dev_addr_bad(struct gasket_page_table *pg_tbl,
++                                        u64 dev_addr, uint num_pages)
++{
++      ulong page_offset = dev_addr & (PAGE_SIZE - 1);
++      ulong page_index =
++              (dev_addr / PAGE_SIZE) & (pg_tbl->config.total_entries - 1);
++
++      if (gasket_components_to_dev_address(pg_tbl, 1, page_index,
++                                           page_offset) != dev_addr) {
++              dev_err(pg_tbl->device, "address is invalid, 0x%llX\n",
++                      dev_addr);
++              return true;
++      }
++
++      if (page_index >= pg_tbl->num_simple_entries) {
++              dev_err(pg_tbl->device,
++                      "starting slot at %lu is too large, max is < %u\n",
++                      page_index, pg_tbl->num_simple_entries);
++              return true;
++      }
++
++      if (page_index + num_pages > pg_tbl->num_simple_entries) {
++              dev_err(pg_tbl->device,
++                      "ending slot at %lu is too large, max is <= %u\n",
++                      page_index + num_pages, pg_tbl->num_simple_entries);
++              return true;
++      }
++
++      return false;
++}
++
++/*
++ * Validity checking for extended addresses.
++ *
++ * Verify that address translation commutes (from address to/from page +
++ * offset) and that the requested page range starts and ends within the set of
++ * currently-partitioned extended pages.
++ */
++static bool gasket_is_extended_dev_addr_bad(struct gasket_page_table *pg_tbl,
++                                          u64 dev_addr, uint num_pages)
++{
++      /* Starting byte index of dev_addr into the first mapped page */
++      ulong page_offset = dev_addr & (PAGE_SIZE - 1);
++      ulong page_global_idx, page_lvl0_idx;
++      ulong num_lvl0_pages;
++      u64 addr;
++
++      /* check if the device address is out of bound */
++      addr = dev_addr & ~((pg_tbl)->extended_flag);
++      if (addr >> (GASKET_EXTENDED_LVL0_WIDTH + GASKET_EXTENDED_LVL0_SHIFT)) {
++              dev_err(pg_tbl->device,
++                      "device address out of bounds: 0x%llx\n", dev_addr);
++              return true;
++      }
++
++      /* Find the starting sub-page index in the space of all sub-pages. */
++      page_global_idx = (dev_addr / PAGE_SIZE) &
++              (pg_tbl->config.total_entries * GASKET_PAGES_PER_SUBTABLE - 1);
++
++      /* Find the starting level 0 index. */
++      page_lvl0_idx = gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++
++      /* Get the count of affected level 0 pages. */
++      num_lvl0_pages = (num_pages + GASKET_PAGES_PER_SUBTABLE - 1) /
++              GASKET_PAGES_PER_SUBTABLE;
++
++      if (gasket_components_to_dev_address(pg_tbl, 0, page_global_idx,
++                                           page_offset) != dev_addr) {
++              dev_err(pg_tbl->device, "address is invalid: 0x%llx\n",
++                      dev_addr);
++              return true;
++      }
++
++      if (page_lvl0_idx >= pg_tbl->num_extended_entries) {
++              dev_err(pg_tbl->device,
++                      "starting level 0 slot at %lu is too large, max is < "
++                      "%u\n", page_lvl0_idx, pg_tbl->num_extended_entries);
++              return true;
++      }
++
++      if (page_lvl0_idx + num_lvl0_pages > pg_tbl->num_extended_entries) {
++              dev_err(pg_tbl->device,
++                      "ending level 0 slot at %lu is too large, max is <= %u\n",
++                      page_lvl0_idx + num_lvl0_pages,
++                      pg_tbl->num_extended_entries);
++              return true;
++      }
++
++      return false;
++}
++
++/*
++ * Non-locking entry to unmapping routines.
++ * The page table mutex must be held by the caller.
++ */
++static void gasket_page_table_unmap_nolock(struct gasket_page_table *pg_tbl,
++                                         u64 dev_addr, uint num_pages)
++{
++      if (!num_pages)
++              return;
++
++      if (gasket_addr_is_simple(pg_tbl, dev_addr))
++              gasket_unmap_simple_pages(pg_tbl, dev_addr, num_pages);
++      else
++              gasket_unmap_extended_pages(pg_tbl, dev_addr, num_pages);
++}
++
++/*
++ * Allocate and map pages to simple addresses.
++ * If there is an error, no pages are mapped.
++ */
++static int gasket_map_simple_pages(struct gasket_page_table *pg_tbl,
++                                 struct sg_page_iter *sg_iter,
++                                 ulong host_addr, u64 dev_addr,
++                                 uint num_pages, u32 flags)
++{
++      int ret;
++      uint slot_idx = gasket_simple_page_idx(pg_tbl, dev_addr);
++
++      ret = gasket_alloc_simple_entries(pg_tbl, dev_addr, num_pages);
++      if (ret) {
++              dev_err(pg_tbl->device,
++                      "page table slots %u (@ 0x%llx) to %u are not available\n",
++                      slot_idx, (long long unsigned int)dev_addr,
++                      slot_idx + num_pages - 1);
++              return ret;
++      }
++
++      ret = gasket_perform_mapping(pg_tbl, pg_tbl->entries + slot_idx,
++                                   pg_tbl->base_slot + slot_idx, sg_iter,
++                                   host_addr, num_pages, flags, 1);
++
++      if (ret) {
++              gasket_page_table_unmap_nolock(pg_tbl, dev_addr, num_pages);
++              dev_err(pg_tbl->device, "gasket_perform_mapping %d\n", ret);
++      }
++      return ret;
++}
++
++/*
++ * Allocate a second level page table.
++ * The page table mutex must be held by the caller.
++ */
++static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl,
++                                        struct gasket_page_table_entry *pte,
++                                        u64 __iomem *slot)
++{
++      ulong page_addr, subtable_bytes;
++      dma_addr_t dma_addr;
++
++      /* XXX FIX ME XXX this is inefficient for non-4K page sizes */
++
++      /* GFP_DMA flag must be passed to architectures for which
++       * part of the memory range is not considered DMA'able.
++       * This seems to be the case for Juno board with 4.5.0 Linaro kernel
++       */
++      page_addr = get_zeroed_page(GFP_KERNEL | GFP_DMA);
++      if (!page_addr)
++              return -ENOMEM;
++      pte->page = virt_to_page((void *)page_addr);
++      pte->offset = 0;
++
++      subtable_bytes = sizeof(struct gasket_page_table_entry) *
++              GASKET_PAGES_PER_SUBTABLE;
++      pte->sublevel = vzalloc(subtable_bytes);
++      if (!pte->sublevel) {
++              free_page(page_addr);
++              memset(pte, 0, sizeof(struct gasket_page_table_entry));
++              return -ENOMEM;
++      }
++
++      /* Map the page into DMA space. */
++      pte->dma_addr = dma_map_page(pg_tbl->device, pte->page, 0, PAGE_SIZE,
++                                   DMA_TO_DEVICE);
++      if (dma_mapping_error(pg_tbl->device, pte->dma_addr)) {
++              dev_dbg(pg_tbl->device,
++                      "%s -> fail to map page %llx "
++                      "[pfn %p phys %p]\n",
++                      __func__,
++                      (unsigned long long)pte->dma_addr,
++                      (void *)page_to_pfn(pte->page),
++                      (void *)page_to_phys(pte->page));
++
++              /* clean up */
++              free_page(page_addr);
++              vfree(pte->sublevel);
++              memset(pte, 0, sizeof(struct gasket_page_table_entry));
++
++              return -ENOMEM;
++      }
++
++      /* make the addresses available to the device */
++      dma_addr = (pte->dma_addr + pte->offset) | GASKET_VALID_SLOT_FLAG;
++      writeq(dma_addr, slot);
++
++      pte->flags = SET(FLAGS_STATUS, pte->flags, PTE_INUSE);
++
++      return 0;
++}
++
++/*
++ * Allocate slots in an extended page table.  Check to see if a range of page
++ * table slots are available. If necessary, memory is allocated for second level
++ * page tables.
++ *
++ * Note that memory for second level page tables is allocated as needed, but
++ * that memory is only freed on the final close       of the device file, when the
++ * page tables are repartitioned, or the the device is removed.  If there is an
++ * error or if the full range of slots is not available, any memory
++ * allocated for second level page tables remains allocated until final close,
++ * repartition, or device removal.
++ *
++ * The page table mutex must be held by the caller.
++ */
++static int gasket_alloc_extended_entries(struct gasket_page_table *pg_tbl,
++                                       u64 dev_addr, uint num_entries)
++{
++      int ret = 0;
++      uint remain, subtable_slot_idx, len;
++      struct gasket_page_table_entry *pte;
++      u64 __iomem *slot;
++
++      remain = num_entries;
++      subtable_slot_idx = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
++      pte = pg_tbl->entries + pg_tbl->num_simple_entries +
++            gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++      slot = pg_tbl->base_slot + pg_tbl->num_simple_entries +
++             gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++
++      while (remain > 0) {
++              len = min(remain,
++                        GASKET_PAGES_PER_SUBTABLE - subtable_slot_idx);
++
++              if (GET(FLAGS_STATUS, pte->flags) == PTE_FREE) {
++                      ret = gasket_alloc_extended_subtable(pg_tbl, pte, slot);
++                      if (ret) {
++                              dev_err(pg_tbl->device,
++                                      "no memory for extended addr subtable\n");
++                              return ret;
++                      }
++              } else {
++                      if (!gasket_is_pte_range_free(pte->sublevel +
++                                                    subtable_slot_idx, len))
++                              return -EBUSY;
++              }
++
++              remain -= len;
++              subtable_slot_idx = 0;
++              pte++;
++              slot++;
++      }
++
++      return 0;
++}
++
++/*
++ * gasket_map_extended_pages - Get and map buffers to extended addresses.
++ * If there is an error, no pages are mapped.
++ */
++static int gasket_map_extended_pages(struct gasket_page_table *pg_tbl,
++                                   struct sg_page_iter *sg_iter,
++                                   ulong host_addr, u64 dev_addr,
++                                   uint num_pages, u32 flags)
++{
++      int ret;
++      u64 dev_addr_end;
++      uint slot_idx, remain, len;
++      struct gasket_page_table_entry *pte;
++      u64 __iomem *slot_base;
++
++      ret = gasket_alloc_extended_entries(pg_tbl, dev_addr, num_pages);
++      if (ret) {
++              dev_addr_end = dev_addr + (num_pages / PAGE_SIZE) - 1;
++              dev_err(pg_tbl->device,
++                      "page table slots (%lu,%lu) (@ 0x%llx) to (%lu,%lu) "
++                      "are not available\n",
++                      gasket_extended_lvl0_page_idx(pg_tbl, dev_addr),
++                      gasket_extended_lvl1_page_idx(pg_tbl, dev_addr),
++                      (long long unsigned int)dev_addr,
++                      gasket_extended_lvl0_page_idx(pg_tbl, dev_addr_end),
++                      gasket_extended_lvl1_page_idx(pg_tbl, dev_addr_end));
++              return ret;
++      }
++
++      remain = num_pages;
++      slot_idx = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
++      pte = pg_tbl->entries + pg_tbl->num_simple_entries +
++            gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++
++      while (remain > 0) {
++              len = min(remain, GASKET_PAGES_PER_SUBTABLE - slot_idx);
++
++              slot_base =
++                      (u64 __iomem *)(page_address(pte->page) + pte->offset);
++              ret = gasket_perform_mapping(pg_tbl, pte->sublevel + slot_idx,
++                                           slot_base + slot_idx, sg_iter,
++                                           host_addr, len, flags, 0);
++              if (ret) {
++                      gasket_page_table_unmap_nolock(pg_tbl, dev_addr,
++                                                     num_pages);
++                      return ret;
++              }
++
++              /*
++               * Extended page tables are in DRAM so they need to be synced
++               * each time they are updated.
++               */
++              dma_sync_single_for_device(pg_tbl->device,
++                                         pte->dma_addr + slot_idx * sizeof(u64),
++                                         len * sizeof(u64), DMA_TO_DEVICE);
++
++              remain -= len;
++              slot_idx = 0;
++              pte++;
++              if (host_addr)
++                      host_addr += len * PAGE_SIZE;
++      }
++
++      return 0;
++}
++
++/*
++ * See gasket_page_table.h for general description.
++ *
++ * gasket_page_table_map calls either gasket_map_simple_pages() or
++ * gasket_map_extended_pages() to actually perform the mapping.
++ *
++ * The page table mutex is held for the entire operation.
++ */
++int gasket_page_table_map(struct gasket_page_table *pg_tbl, ulong host_addr,
++                        u64 dev_addr, uint num_pages, u32 flags)
++{
++      int ret;
++
++      if (!num_pages)
++              return 0;
++
++      mutex_lock(&pg_tbl->mutex);
++
++      if (gasket_addr_is_simple(pg_tbl, dev_addr)) {
++              ret = gasket_map_simple_pages(pg_tbl, NULL, host_addr, dev_addr,
++                                            num_pages, flags);
++      } else {
++              ret = gasket_map_extended_pages(pg_tbl, NULL, host_addr, dev_addr,
++                                              num_pages, flags);
++      }
++
++      mutex_unlock(&pg_tbl->mutex);
++
++      dev_dbg(pg_tbl->device,
++              "%s done: ha %llx daddr %llx num %d, flags %x ret %d\n",
++              __func__, (unsigned long long)host_addr,
++              (unsigned long long)dev_addr, num_pages, flags, ret);
++      return ret;
++}
++EXPORT_SYMBOL(gasket_page_table_map);
++
++/*
++ * See gasket_page_table.h for general description.
++ *
++ * gasket_page_table_unmap takes the page table lock and calls either
++ * gasket_unmap_simple_pages() or gasket_unmap_extended_pages() to
++ * actually unmap the pages from device space.
++ *
++ * The page table mutex is held for the entire operation.
++ */
++void gasket_page_table_unmap(struct gasket_page_table *pg_tbl, u64 dev_addr,
++                           uint num_pages)
++{
++      if (!num_pages)
++              return;
++
++      mutex_lock(&pg_tbl->mutex);
++      gasket_page_table_unmap_nolock(pg_tbl, dev_addr, num_pages);
++      mutex_unlock(&pg_tbl->mutex);
++}
++EXPORT_SYMBOL(gasket_page_table_unmap);
++
++int gasket_page_table_map_dmabuf(struct gasket_page_table *pg_tbl, int fd,
++                               u64 dev_addr, uint num_pages, u32 flags)
++{
++      int ret, locked = 0;
++      struct dma_buf *dmabuf = NULL;
++      struct dma_buf_attachment *attachment = NULL;
++      struct sg_table *sgt = NULL;
++      struct sg_page_iter sg_iter;
++      struct gasket_dmabuf_mapping *mapping = NULL;
++      enum dma_data_direction direction = GET(FLAGS_DMA_DIRECTION, flags);
++
++      if (direction == DMA_NONE) {
++              dev_err(pg_tbl->device,
++                      "invalid DMA direction flags=0x%x\n", flags);
++              return -EINVAL;
++      }
++
++      if (!num_pages)
++              return 0;
++
++      dmabuf = dma_buf_get(fd);
++      if (IS_ERR(dmabuf))
++              return PTR_ERR(dmabuf);
++
++      if (PAGE_ALIGN(dmabuf->size) / PAGE_SIZE < num_pages)
++              return -EINVAL;
++
++      mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
++      if (!mapping) {
++              ret = -ENOMEM;
++              goto out;
++      }
++
++      attachment = dma_buf_attach(dmabuf, pg_tbl->device);
++      if (IS_ERR(attachment)) {
++              ret = PTR_ERR(attachment);
++              goto out;
++      }
++
++      sgt = dma_buf_map_attachment(attachment, direction);
++      if (IS_ERR(sgt)) {
++              ret = PTR_ERR(sgt);
++              goto out;
++      }
++
++      mutex_lock(&pg_tbl->mutex);
++      locked = 1;
++
++      __sg_page_iter_start(&sg_iter, sgt->sgl, sgt->nents, 0);
++      if (gasket_addr_is_simple(pg_tbl, dev_addr)) {
++              ret = gasket_map_simple_pages(pg_tbl, &sg_iter, 0, dev_addr,
++                                            num_pages, flags);
++      } else {
++              ret = gasket_map_extended_pages(pg_tbl, &sg_iter, 0, dev_addr,
++                                              num_pages, flags);
++      }
++
++      if (!ret) {
++              INIT_LIST_HEAD(&mapping->list);
++              get_dma_buf(dmabuf);
++              mapping->dmabuf = dmabuf;
++              mapping->attachment = attachment;
++              mapping->sgt = sgt;
++              mapping->direction = direction;
++              list_add(&mapping->list, &pg_tbl->dmabufs);
++              sgt = NULL;
++              attachment = NULL;
++              mapping = NULL;
++      }
++
++out:
++      if (locked)
++              mutex_unlock(&pg_tbl->mutex);
++
++      if (!IS_ERR_OR_NULL(sgt))
++              dma_buf_unmap_attachment(attachment, sgt, direction);
++
++      if (!IS_ERR_OR_NULL(attachment))
++              dma_buf_detach(dmabuf, attachment);
++
++      kfree(mapping);
++      dma_buf_put(dmabuf);
++
++      return ret;
++}
++EXPORT_SYMBOL(gasket_page_table_map_dmabuf);
++
++/* Detach dmabuf from our device if attached, NULL to detach all. */
++static void gasket_page_table_detach_dmabuf_nolock(struct gasket_page_table *pg_tbl,
++                                                 struct dma_buf *dmabuf)
++{
++      struct gasket_dmabuf_mapping *mapping, *tmp;
++
++      list_for_each_entry_safe(mapping, tmp, &pg_tbl->dmabufs, list) {
++              if (!dmabuf || mapping->dmabuf == dmabuf) {
++                      dma_buf_unmap_attachment(mapping->attachment,
++                                               mapping->sgt,
++                                               mapping->direction);
++                      dma_buf_detach(mapping->dmabuf, mapping->attachment);
++                      dma_buf_put(mapping->dmabuf);
++                      list_del(&mapping->list);
++                      kfree(mapping);
++              }
++      }
++}
++
++int gasket_page_table_unmap_dmabuf(struct gasket_page_table *pg_tbl, int fd,
++                                 u64 dev_addr, uint num_pages)
++{
++      struct dma_buf *dmabuf;
++
++      dmabuf = dma_buf_get(fd);
++      if (IS_ERR(dmabuf))
++              return PTR_ERR(dmabuf);
++
++      if (PAGE_ALIGN(dmabuf->size) / PAGE_SIZE < num_pages) {
++              dma_buf_put(dmabuf);
++              return -EINVAL;
++      }
++
++      mutex_lock(&pg_tbl->mutex);
++
++      gasket_page_table_unmap_nolock(pg_tbl, dev_addr, num_pages);
++      gasket_page_table_detach_dmabuf_nolock(pg_tbl, dmabuf);
++
++      mutex_unlock(&pg_tbl->mutex);
++
++      dma_buf_put(dmabuf);
++
++      return 0;
++}
++EXPORT_SYMBOL(gasket_page_table_unmap_dmabuf);
++
++static void gasket_page_table_unmap_all_nolock(struct gasket_page_table *pg_tbl)
++{
++      gasket_page_table_detach_dmabuf_nolock(pg_tbl, NULL);
++
++      gasket_unmap_simple_pages(pg_tbl,
++                                gasket_components_to_dev_address(pg_tbl, 1, 0,
++                                                                 0),
++                                pg_tbl->num_simple_entries);
++      gasket_unmap_extended_pages(pg_tbl,
++                                  gasket_components_to_dev_address(pg_tbl, 0,
++                                                                   0, 0),
++                                  pg_tbl->num_extended_entries *
++                                  GASKET_PAGES_PER_SUBTABLE);
++}
++
++/* See gasket_page_table.h for description. */
++void gasket_page_table_unmap_all(struct gasket_page_table *pg_tbl)
++{
++      mutex_lock(&pg_tbl->mutex);
++      gasket_page_table_unmap_all_nolock(pg_tbl);
++      mutex_unlock(&pg_tbl->mutex);
++}
++EXPORT_SYMBOL(gasket_page_table_unmap_all);
++
++/* See gasket_page_table.h for description. */
++void gasket_page_table_reset(struct gasket_page_table *pg_tbl)
++{
++      mutex_lock(&pg_tbl->mutex);
++      gasket_page_table_unmap_all_nolock(pg_tbl);
++      writeq(pg_tbl->config.total_entries, pg_tbl->extended_offset_reg);
++      mutex_unlock(&pg_tbl->mutex);
++}
++
++/* See gasket_page_table.h for description. */
++int gasket_page_table_lookup_page(
++      struct gasket_page_table *pg_tbl, u64 dev_addr, struct page **ppage,
++      ulong *poffset)
++{
++      uint page_num;
++      struct gasket_page_table_entry *pte;
++
++      mutex_lock(&pg_tbl->mutex);
++      if (gasket_addr_is_simple(pg_tbl, dev_addr)) {
++              page_num = gasket_simple_page_idx(pg_tbl, dev_addr);
++              if (page_num >= pg_tbl->num_simple_entries)
++                      goto fail;
++
++              pte = pg_tbl->entries + page_num;
++              if (GET(FLAGS_STATUS, pte->flags) != PTE_INUSE)
++                      goto fail;
++      } else {
++              /* Find the level 0 entry, */
++              page_num = gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++              if (page_num >= pg_tbl->num_extended_entries)
++                      goto fail;
++
++              pte = pg_tbl->entries + pg_tbl->num_simple_entries + page_num;
++              if (GET(FLAGS_STATUS, pte->flags) != PTE_INUSE)
++                      goto fail;
++
++              /* and its contained level 1 entry. */
++              page_num = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
++              pte = pte->sublevel + page_num;
++              if (GET(FLAGS_STATUS, pte->flags) != PTE_INUSE)
++                      goto fail;
++      }
++
++      *ppage = pte->page;
++      *poffset = pte->offset;
++      mutex_unlock(&pg_tbl->mutex);
++      return 0;
++
++fail:
++      *ppage = NULL;
++      *poffset = 0;
++      mutex_unlock(&pg_tbl->mutex);
++      return -EINVAL;
++}
++
++/* See gasket_page_table.h for description. */
++bool gasket_page_table_are_addrs_bad(
++      struct gasket_page_table *pg_tbl, ulong host_addr, u64 dev_addr,
++      ulong bytes)
++{
++      if (host_addr & (PAGE_SIZE - 1)) {
++              dev_err(pg_tbl->device,
++                      "host mapping address 0x%lx must be page aligned\n",
++                      host_addr);
++              return true;
++      }
++
++      return gasket_page_table_is_dev_addr_bad(pg_tbl, dev_addr, bytes);
++}
++EXPORT_SYMBOL(gasket_page_table_are_addrs_bad);
++
++/* See gasket_page_table.h for description. */
++bool gasket_page_table_is_dev_addr_bad(
++      struct gasket_page_table *pg_tbl, u64 dev_addr, ulong bytes)
++{
++      uint num_pages = bytes / PAGE_SIZE;
++
++      if (bytes & (PAGE_SIZE - 1)) {
++              dev_err(pg_tbl->device,
++                      "mapping size 0x%lX must be page aligned\n", bytes);
++              return true;
++      }
++
++      if (num_pages == 0) {
++              dev_err(pg_tbl->device,
++                      "requested mapping is less than one page: %lu / %lu\n",
++                      bytes, PAGE_SIZE);
++              return true;
++      }
++
++      if (gasket_addr_is_simple(pg_tbl, dev_addr))
++              return gasket_is_simple_dev_addr_bad(pg_tbl, dev_addr,
++                                                   num_pages);
++      return gasket_is_extended_dev_addr_bad(pg_tbl, dev_addr, num_pages);
++}
++EXPORT_SYMBOL(gasket_page_table_is_dev_addr_bad);
++
++/* See gasket_page_table.h for description. */
++uint gasket_page_table_max_size(struct gasket_page_table *page_table)
++{
++      if (!page_table)
++              return 0;
++      return page_table->config.total_entries;
++}
++EXPORT_SYMBOL(gasket_page_table_max_size);
++
++/* See gasket_page_table.h for description. */
++uint gasket_page_table_num_entries(struct gasket_page_table *pg_tbl)
++{
++      if (!pg_tbl)
++              return 0;
++      return pg_tbl->num_simple_entries + pg_tbl->num_extended_entries;
++}
++EXPORT_SYMBOL(gasket_page_table_num_entries);
++
++/* See gasket_page_table.h for description. */
++uint gasket_page_table_num_simple_entries(struct gasket_page_table *pg_tbl)
++{
++      if (!pg_tbl)
++              return 0;
++      return pg_tbl->num_simple_entries;
++}
++EXPORT_SYMBOL(gasket_page_table_num_simple_entries);
++
++/* See gasket_page_table.h for description. */
++uint gasket_page_table_num_active_pages(struct gasket_page_table *pg_tbl)
++{
++      if (!pg_tbl)
++              return 0;
++      return pg_tbl->num_active_pages;
++}
++EXPORT_SYMBOL(gasket_page_table_num_active_pages);
++
++/* See gasket_page_table.h */
++int gasket_page_table_system_status(struct gasket_page_table *page_table)
++{
++      if (!page_table)
++              return GASKET_STATUS_LAMED;
++
++      if (gasket_page_table_num_entries(page_table) == 0) {
++              dev_dbg(page_table->device, "Page table size is 0\n");
++              return GASKET_STATUS_LAMED;
++      }
++
++      return GASKET_STATUS_ALIVE;
++}
++
++/* Record the host_addr to coherent dma memory mapping. */
++int gasket_set_user_virt(
++      struct gasket_dev *gasket_dev, u64 size, dma_addr_t dma_address,
++      ulong vma)
++{
++      int j;
++      struct gasket_page_table *pg_tbl;
++
++      unsigned int num_pages = size / PAGE_SIZE;
++
++      /*
++       * TODO: for future chipset, better handling of the case where multiple
++       * page tables are supported on a given device
++       */
++      pg_tbl = gasket_dev->page_table[0];
++      if (!pg_tbl) {
++              dev_dbg(gasket_dev->dev, "%s: invalid page table index\n",
++                      __func__);
++              return 0;
++      }
++      for (j = 0; j < num_pages; j++) {
++              pg_tbl->coherent_pages[j].user_virt =
++                      (u64)vma + j * PAGE_SIZE;
++      }
++      return 0;
++}
++
++/* Allocate a block of coherent memory. */
++int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size,
++                               dma_addr_t *dma_address, u64 index)
++{
++      dma_addr_t handle;
++      void *mem;
++      int j;
++      unsigned int num_pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
++      const struct gasket_driver_desc *driver_desc =
++              gasket_get_driver_desc(gasket_dev);
++
++      if (!gasket_dev->page_table[index])
++              return -EFAULT;
++
++      if (num_pages == 0)
++              return -EINVAL;
++
++      mem = dma_alloc_coherent(gasket_get_device(gasket_dev),
++                               num_pages * PAGE_SIZE, &handle, GFP_KERNEL);
++      if (!mem)
++              goto nomem;
++
++      gasket_dev->page_table[index]->num_coherent_pages = num_pages;
++
++      /* allocate the physical memory block */
++      gasket_dev->page_table[index]->coherent_pages =
++              kcalloc(num_pages, sizeof(struct gasket_coherent_page_entry),
++                      GFP_KERNEL);
++      if (!gasket_dev->page_table[index]->coherent_pages)
++              goto nomem;
++
++      gasket_dev->coherent_buffer.length_bytes =
++              PAGE_SIZE * (num_pages);
++      gasket_dev->coherent_buffer.phys_base = handle;
++      gasket_dev->coherent_buffer.virt_base = mem;
++
++      *dma_address = driver_desc->coherent_buffer_description.base;
++      for (j = 0; j < num_pages; j++) {
++              gasket_dev->page_table[index]->coherent_pages[j].paddr =
++                      handle + j * PAGE_SIZE;
++              gasket_dev->page_table[index]->coherent_pages[j].kernel_virt =
++                      (ulong)mem + j * PAGE_SIZE;
++      }
++
++      return 0;
++
++nomem:
++      if (mem) {
++              dma_free_coherent(gasket_get_device(gasket_dev),
++                                num_pages * PAGE_SIZE, mem, handle);
++              gasket_dev->coherent_buffer.length_bytes = 0;
++              gasket_dev->coherent_buffer.virt_base = NULL;
++              gasket_dev->coherent_buffer.phys_base = 0;
++      }
++
++      kfree(gasket_dev->page_table[index]->coherent_pages);
++      gasket_dev->page_table[index]->coherent_pages = NULL;
++      gasket_dev->page_table[index]->num_coherent_pages = 0;
++      return -ENOMEM;
++}
++
++/* Free a block of coherent memory. */
++int gasket_free_coherent_memory(struct gasket_dev *gasket_dev, u64 size,
++                              dma_addr_t dma_address, u64 index)
++{
++      const struct gasket_driver_desc *driver_desc;
++
++      if (!gasket_dev->page_table[index])
++              return -EFAULT;
++
++      driver_desc = gasket_get_driver_desc(gasket_dev);
++
++      if (driver_desc->coherent_buffer_description.base != dma_address)
++              return -EADDRNOTAVAIL;
++
++      gasket_free_coherent_memory_all(gasket_dev, index);
++
++      return 0;
++}
++
++/* Release all coherent memory. */
++void gasket_free_coherent_memory_all(
++      struct gasket_dev *gasket_dev, u64 index)
++{
++      if (!gasket_dev->page_table[index])
++              return;
++
++      if (gasket_dev->coherent_buffer.length_bytes) {
++              dma_free_coherent(gasket_get_device(gasket_dev),
++                                gasket_dev->coherent_buffer.length_bytes,
++                                gasket_dev->coherent_buffer.virt_base,
++                                gasket_dev->coherent_buffer.phys_base);
++              gasket_dev->coherent_buffer.length_bytes = 0;
++              gasket_dev->coherent_buffer.virt_base = NULL;
++              gasket_dev->coherent_buffer.phys_base = 0;
++      }
++
++      kfree(gasket_dev->page_table[index]->coherent_pages);
++      gasket_dev->page_table[index]->coherent_pages = NULL;
++      gasket_dev->page_table[index]->num_coherent_pages = 0;
++}
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_page_table.h b/drivers/staging/gasket-driver/gasket_page_table.h
+--- a/drivers/staging/gasket-driver/gasket_page_table.h        1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_page_table.h        2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,283 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Gasket Page Table functionality. This file describes the address
++ * translation/paging functionality supported by the Gasket driver framework.
++ * As much as possible, internal details are hidden to simplify use -
++ * all calls are thread-safe (protected by an internal mutex) except where
++ * indicated otherwise.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++
++#ifndef __GASKET_PAGE_TABLE_H__
++#define __GASKET_PAGE_TABLE_H__
++
++#include <linux/pci.h>
++#include <linux/types.h>
++
++#include "gasket_constants.h"
++#include "gasket_core.h"
++
++/*
++ * Structure used for managing address translation on a device. All details are
++ * internal to the implementation.
++ */
++struct gasket_page_table;
++
++/*
++ * Allocate and init address translation data.
++ * @ppage_table: Pointer to Gasket page table pointer. Set by this call.
++ * @att_base_reg: [Mapped] pointer to the first entry in the device's address
++ *                translation table.
++ * @extended_offset_reg: [Mapped] pointer to the device's register containing
++ *                       the starting index of the extended translation table.
++ * @extended_bit_location: The index of the bit indicating whether an address
++ *                         is extended.
++ * @total_entries: The total number of entries in the device's address
++ *                 translation table.
++ * @device: Device structure for the underlying device. Only used for logging.
++ * @pci_dev: PCI system descriptor for the underlying device.
++ * whether the driver will supply its own.
++ *
++ * Description: Allocates and initializes data to track address translation -
++ * simple and extended page table metadata. Initially, the page table is
++ * partitioned such that all addresses are "simple" (single-level lookup).
++ * gasket_partition_page_table can be called to change this paritioning.
++ *
++ * Returns 0 on success, a negative error code otherwise.
++ */
++int gasket_page_table_init(struct gasket_page_table **ppg_tbl,
++                         const struct gasket_bar_data *bar_data,
++                         const struct gasket_page_table_config *page_table_config,
++                         struct device *device, struct pci_dev *pci_dev);
++
++/*
++ * Deallocate and cleanup page table data.
++ * @page_table: Gasket page table pointer.
++ *
++ * Description: The inverse of gasket_init; frees page_table and its contained
++ *              elements.
++ *
++ *            Because this call destroys the page table, it cannot be
++ *            thread-safe (mutex-protected)!
++ */
++void gasket_page_table_cleanup(struct gasket_page_table *page_table);
++
++/*
++ * Sets the size of the simple page table.
++ * @page_table: Gasket page table pointer.
++ * @num_simple_entries: Desired size of the simple page table (in entries).
++ *
++ * Description: gasket_partition_page_table checks to see if the simple page
++ *              size can be changed (i.e., if there are no active extended
++ *              mappings in the new simple size range), and, if so,
++ *              sets the new simple and extended page table sizes.
++ *
++ *              Returns 0 if successful, or non-zero if the page table entries
++ *              are not free.
++ */
++int gasket_page_table_partition(struct gasket_page_table *page_table,
++                              uint num_simple_entries);
++
++/*
++ * Get and map [host] user space pages into device memory.
++ * @page_table: Gasket page table pointer.
++ * @host_addr: Starting host virtual memory address of the pages.
++ * @dev_addr: Starting device address of the pages.
++ * @num_pages: Number of [4kB] pages to map.
++ * @flags: Specifies attributes to apply to the pages.
++ *         Internal structure matches gasket_page_table_ioctl_flags.flags.
++ *
++ * Description: Maps the "num_pages" pages of host memory pointed to by
++ *              host_addr to the address "dev_addr" in device memory.
++ *
++ *              The caller is responsible for checking the addresses ranges.
++ *
++ *              Returns 0 if successful or a non-zero error number otherwise.
++ *              If there is an error, no pages are mapped.
++ */
++int gasket_page_table_map(struct gasket_page_table *page_table, ulong host_addr,
++                        u64 dev_addr, uint num_pages, u32 flags);
++
++/*
++ * Map dma-buf pages into device memory.
++ * @page_table: Gasket page table pointer.
++ * @fd: Dma-buf file descriptor.
++ * @dev_addr: Starting device address of the pages.
++ * @num_pages: Number of [4kB] pages to map.
++ * @flags: Specifies attributes to apply to the pages.
++ *         Internal structure matches gasket_page_table_ioctl_flags.flags.
++ *
++ * Description: Maps "num_pages" pages of dma-buf pointed to by
++ *              fd to the address "dev_addr" in device memory.
++ *
++ *              The caller is responsible for checking the dev_addr range.
++ *
++ *              Returns 0 if successful or a non-zero error number otherwise.
++ *              If there is an error, no pages are mapped.
++ */
++int gasket_page_table_map_dmabuf(struct gasket_page_table *page_table, int fd,
++                               u64 dev_addr, uint num_pages, u32 flags);
++
++/*
++ * Unmap dma-buf pages from device memory.
++ * @page_table: Gasket page table pointer.
++ * @fd: Dma-buf file descriptor.
++ * @dev_addr: Starting device address of the pages.
++ * @num_pages: Number of [4kB] pages to map.
++ *
++ * Description: The inverse of gasket_page_table_map_dmabuf.
++ */
++int gasket_page_table_unmap_dmabuf(struct gasket_page_table *page_table, int fd,
++                                 u64 dev_addr, uint num_pages);
++
++/*
++ * Un-map host pages from device memory.
++ * @page_table: Gasket page table pointer.
++ * @dev_addr: Starting device address of the pages to unmap.
++ * @num_pages: The number of [4kB] pages to unmap.
++ *
++ * Description: The inverse of gasket_map_pages. Unmaps pages from the device.
++ */
++void gasket_page_table_unmap(struct gasket_page_table *page_table,
++                           u64 dev_addr, uint num_pages);
++
++/*
++ * Unmap ALL host pages from device memory.
++ * @page_table: Gasket page table pointer.
++ */
++void gasket_page_table_unmap_all(struct gasket_page_table *page_table);
++
++/*
++ * Unmap all host pages from device memory and reset the table to fully simple
++ * addressing.
++ * @page_table: Gasket page table pointer.
++ */
++void gasket_page_table_reset(struct gasket_page_table *page_table);
++
++/*
++ * Reclaims unused page table memory.
++ * @page_table: Gasket page table pointer.
++ *
++ * Description: Examines the page table and frees any currently-unused
++ *              allocations. Called internally on gasket_cleanup().
++ */
++void gasket_page_table_garbage_collect(struct gasket_page_table *page_table);
++
++/*
++ * Retrieve the backing page for a device address.
++ * @page_table: Gasket page table pointer.
++ * @dev_addr: Gasket device address.
++ * @ppage: Pointer to a page pointer for the returned page.
++ * @poffset: Pointer to an unsigned long for the returned offset.
++ *
++ * Description: Interprets the address and looks up the corresponding page
++ *              in the page table and the offset in that page.  (We need an
++ *              offset because the host page may be larger than the Gasket chip
++ *              page it contains.)
++ *
++ *              Returns 0 if successful, -1 for an error.  The page pointer
++ *              and offset are returned through the pointers, if successful.
++ */
++int gasket_page_table_lookup_page(struct gasket_page_table *page_table,
++                                u64 dev_addr, struct page **page,
++                                ulong *poffset);
++
++/*
++ * Checks validity for input addrs and size.
++ * @page_table: Gasket page table pointer.
++ * @host_addr: Host address to check.
++ * @dev_addr: Gasket device address.
++ * @bytes: Size of the range to check (in bytes).
++ *
++ * Description: This call performs a number of checks to verify that the ranges
++ * specified by both addresses and the size are valid for mapping pages into
++ * device memory.
++ *
++ * Returns true if the mapping is bad, false otherwise.
++ */
++bool gasket_page_table_are_addrs_bad(struct gasket_page_table *page_table,
++                                   ulong host_addr, u64 dev_addr,
++                                   ulong bytes);
++
++/*
++ * Checks validity for input dev addr and size.
++ * @page_table: Gasket page table pointer.
++ * @dev_addr: Gasket device address.
++ * @bytes: Size of the range to check (in bytes).
++ *
++ * Description: This call performs a number of checks to verify that the range
++ * specified by the device address and the size is valid for mapping pages into
++ * device memory.
++ *
++ * Returns true if the address is bad, false otherwise.
++ */
++bool gasket_page_table_is_dev_addr_bad(struct gasket_page_table *page_table,
++                                     u64 dev_addr, ulong bytes);
++
++/*
++ * Gets maximum size for the given page table.
++ * @page_table: Gasket page table pointer.
++ */
++uint gasket_page_table_max_size(struct gasket_page_table *page_table);
++
++/*
++ * Gets the total number of entries in the arg.
++ * @page_table: Gasket page table pointer.
++ */
++uint gasket_page_table_num_entries(struct gasket_page_table *page_table);
++
++/*
++ * Gets the number of simple entries.
++ * @page_table: Gasket page table pointer.
++ */
++uint gasket_page_table_num_simple_entries(struct gasket_page_table *page_table);
++
++/*
++ * Gets the number of actively pinned pages.
++ * @page_table: Gasket page table pointer.
++ */
++uint gasket_page_table_num_active_pages(struct gasket_page_table *page_table);
++
++/*
++ * Get status of page table managed by @page_table.
++ * @page_table: Gasket page table pointer.
++ */
++int gasket_page_table_system_status(struct gasket_page_table *page_table);
++
++/*
++ * Allocate a block of coherent memory.
++ * @gasket_dev: Gasket Device.
++ * @size: Size of the memory block.
++ * @dma_address: Dma address allocated by the kernel.
++ * @index: Index of the gasket_page_table within this Gasket device
++ *
++ * Description: Allocate a contiguous coherent memory block, DMA'ble
++ * by this device.
++ */
++int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, uint64_t size,
++                               dma_addr_t *dma_address, uint64_t index);
++/* Release a block of contiguous coherent memory, in use by a device. */
++int gasket_free_coherent_memory(struct gasket_dev *gasket_dev, uint64_t size,
++                              dma_addr_t dma_address, uint64_t index);
++
++/* Release all coherent memory. */
++void gasket_free_coherent_memory_all(struct gasket_dev *gasket_dev,
++                                   uint64_t index);
++
++/*
++ * Records the host_addr to coherent dma memory mapping.
++ * @gasket_dev: Gasket Device.
++ * @size: Size of the virtual address range to map.
++ * @dma_address: Dma address within the coherent memory range.
++ * @vma: Virtual address we wish to map to coherent memory.
++ *
++ * Description: For each page in the virtual address range, record the
++ * coherent page mapping.
++ *
++ * Does not perform validity checking.
++ */
++int gasket_set_user_virt(struct gasket_dev *gasket_dev, uint64_t size,
++                       dma_addr_t dma_address, ulong vma);
++
++#endif  /* __GASKET_PAGE_TABLE_H__ */
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_sysfs.c b/drivers/staging/gasket-driver/gasket_sysfs.c
+--- a/drivers/staging/gasket-driver/gasket_sysfs.c     1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_sysfs.c     2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,400 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (C) 2018 Google, Inc. */
++#include "gasket_sysfs.h"
++
++#include "gasket_core.h"
++
++#include <linux/device.h>
++#include <linux/printk.h>
++
++/*
++ * Pair of kernel device and user-specified pointer. Used in lookups in sysfs
++ * "show" functions to return user data.
++ */
++
++struct gasket_sysfs_mapping {
++      /*
++       * The device bound to this mapping. If this is NULL, then this mapping
++       * is free.
++       */
++      struct device *device;
++
++      /* The Gasket descriptor for this device. */
++      struct gasket_dev *gasket_dev;
++
++      /* This device's set of sysfs attributes/nodes. */
++      struct gasket_sysfs_attribute *attributes;
++
++      /* The number of live elements in "attributes". */
++      int attribute_count;
++
++      /* Protects structure from simultaneous access. */
++      struct mutex mutex;
++
++      /* Tracks active users of this mapping. */
++      struct kref refcount;
++};
++
++/*
++ * Data needed to manage users of this sysfs utility.
++ * Currently has a fixed size; if space is a concern, this can be dynamically
++ * allocated.
++ */
++/*
++ * 'Global' (file-scoped) list of mappings between devices and gasket_data
++ * pointers. This removes the requirement to have a gasket_sysfs_data
++ * handle in all files.
++ */
++static struct gasket_sysfs_mapping dev_mappings[GASKET_SYSFS_NUM_MAPPINGS];
++
++/* Callback when a mapping's refcount goes to zero. */
++static void release_entry(struct kref *ref)
++{
++      /* All work is done after the return from kref_put. */
++}
++
++/* Look up mapping information for the given device. */
++static struct gasket_sysfs_mapping *get_mapping(struct device *device)
++{
++      int i;
++
++      for (i = 0; i < GASKET_SYSFS_NUM_MAPPINGS; i++) {
++              mutex_lock(&dev_mappings[i].mutex);
++              if (dev_mappings[i].device == device) {
++                      kref_get(&dev_mappings[i].refcount);
++                      mutex_unlock(&dev_mappings[i].mutex);
++                      return &dev_mappings[i];
++              }
++              mutex_unlock(&dev_mappings[i].mutex);
++      }
++
++      dev_dbg(device, "%s: Mapping to device %s not found\n",
++              __func__, device->kobj.name);
++      return NULL;
++}
++
++/* Put a reference to a mapping. */
++static void put_mapping(struct gasket_sysfs_mapping *mapping)
++{
++      int i;
++      int num_files_to_remove = 0;
++      struct device_attribute *files_to_remove;
++      struct device *device;
++
++      if (!mapping) {
++              pr_debug("%s: Mapping should not be NULL\n", __func__);
++              return;
++      }
++
++      mutex_lock(&mapping->mutex);
++      if (kref_put(&mapping->refcount, release_entry)) {
++              dev_dbg(mapping->device, "Removing Gasket sysfs mapping\n");
++              /*
++               * We can't remove the sysfs nodes in the kref callback, since
++               * device_remove_file() blocks until the node is free.
++               * Readers/writers of sysfs nodes, though, will be blocked on
++               * the mapping mutex, resulting in deadlock. To fix this, the
++               * sysfs nodes are removed outside the lock.
++               */
++              device = mapping->device;
++              num_files_to_remove = mapping->attribute_count;
++              files_to_remove = kcalloc(num_files_to_remove,
++                                        sizeof(*files_to_remove),
++                                        GFP_KERNEL);
++              if (files_to_remove)
++                      for (i = 0; i < num_files_to_remove; i++)
++                              files_to_remove[i] =
++                                  mapping->attributes[i].attr;
++              else
++                      num_files_to_remove = 0;
++
++              kfree(mapping->attributes);
++              mapping->attributes = NULL;
++              mapping->attribute_count = 0;
++              put_device(mapping->device);
++              mapping->device = NULL;
++              mapping->gasket_dev = NULL;
++      }
++      mutex_unlock(&mapping->mutex);
++
++      if (num_files_to_remove != 0) {
++              for (i = 0; i < num_files_to_remove; ++i)
++                      device_remove_file(device, &files_to_remove[i]);
++              kfree(files_to_remove);
++      }
++}
++
++/*
++ * Put a reference to a mapping N times.
++ *
++ * In higher-level resource acquire/release function pairs, the release function
++ * will need to release a mapping 2x - once for the refcount taken in the
++ * release function itself, and once for the count taken in the acquire call.
++ */
++static void put_mapping_n(struct gasket_sysfs_mapping *mapping, int times)
++{
++      int i;
++
++      for (i = 0; i < times; i++)
++              put_mapping(mapping);
++}
++
++void gasket_sysfs_init(void)
++{
++      int i;
++
++      for (i = 0; i < GASKET_SYSFS_NUM_MAPPINGS; i++) {
++              dev_mappings[i].device = NULL;
++              mutex_init(&dev_mappings[i].mutex);
++      }
++}
++
++int gasket_sysfs_create_mapping(struct device *device,
++                              struct gasket_dev *gasket_dev)
++{
++      struct gasket_sysfs_mapping *mapping;
++      int map_idx = -1;
++
++      /*
++       * We need a function-level mutex to protect against the same device
++       * being added [multiple times] simultaneously.
++       */
++      static DEFINE_MUTEX(function_mutex);
++
++      mutex_lock(&function_mutex);
++      dev_dbg(device, "Creating sysfs entries for device\n");
++
++      /* Check that the device we're adding hasn't already been added. */
++      mapping = get_mapping(device);
++      if (mapping) {
++              dev_err(device,
++                      "Attempting to re-initialize sysfs mapping for device\n");
++              put_mapping(mapping);
++              mutex_unlock(&function_mutex);
++              return -EBUSY;
++      }
++
++      /* Find the first empty entry in the array. */
++      for (map_idx = 0; map_idx < GASKET_SYSFS_NUM_MAPPINGS; ++map_idx) {
++              mutex_lock(&dev_mappings[map_idx].mutex);
++              if (!dev_mappings[map_idx].device)
++                      /* Break with the mutex held! */
++                      break;
++              mutex_unlock(&dev_mappings[map_idx].mutex);
++      }
++
++      if (map_idx == GASKET_SYSFS_NUM_MAPPINGS) {
++              dev_err(device, "All mappings have been exhausted\n");
++              mutex_unlock(&function_mutex);
++              return -ENOMEM;
++      }
++
++      dev_dbg(device, "Creating sysfs mapping for device %s\n",
++              device->kobj.name);
++
++      mapping = &dev_mappings[map_idx];
++      mapping->attributes = kcalloc(GASKET_SYSFS_MAX_NODES,
++                                    sizeof(*mapping->attributes),
++                                    GFP_KERNEL);
++      if (!mapping->attributes) {
++              dev_dbg(device, "Unable to allocate sysfs attribute array\n");
++              mutex_unlock(&mapping->mutex);
++              mutex_unlock(&function_mutex);
++              return -ENOMEM;
++      }
++
++      kref_init(&mapping->refcount);
++      mapping->device = get_device(device);
++      mapping->gasket_dev = gasket_dev;
++      mapping->attribute_count = 0;
++      mutex_unlock(&mapping->mutex);
++      mutex_unlock(&function_mutex);
++
++      /* Don't decrement the refcount here! One open count keeps it alive! */
++      return 0;
++}
++
++int gasket_sysfs_create_entries(struct device *device,
++                              const struct gasket_sysfs_attribute *attrs)
++{
++      int i;
++      int ret;
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++
++      if (!mapping) {
++              dev_dbg(device,
++                      "Creating entries for device without first "
++                      "initializing mapping\n");
++              return -EINVAL;
++      }
++
++      mutex_lock(&mapping->mutex);
++      for (i = 0; strcmp(attrs[i].attr.attr.name, GASKET_ARRAY_END_MARKER);
++              i++) {
++              if (mapping->attribute_count == GASKET_SYSFS_MAX_NODES) {
++                      dev_err(device,
++                              "Maximum number of sysfs nodes reached for "
++                              "device\n");
++                      mutex_unlock(&mapping->mutex);
++                      put_mapping(mapping);
++                      return -ENOMEM;
++              }
++
++              ret = device_create_file(device, &attrs[i].attr);
++              if (ret) {
++                      dev_dbg(device, "Unable to create device entries\n");
++                      mutex_unlock(&mapping->mutex);
++                      put_mapping(mapping);
++                      return ret;
++              }
++
++              mapping->attributes[mapping->attribute_count] = attrs[i];
++              ++mapping->attribute_count;
++      }
++
++      mutex_unlock(&mapping->mutex);
++      put_mapping(mapping);
++      return 0;
++}
++EXPORT_SYMBOL(gasket_sysfs_create_entries);
++
++void gasket_sysfs_remove_mapping(struct device *device)
++{
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++
++      if (!mapping) {
++              dev_err(device,
++                      "Attempted to remove non-existent sysfs mapping to "
++                      "device\n");
++              return;
++      }
++
++      put_mapping_n(mapping, 2);
++}
++
++struct gasket_dev *gasket_sysfs_get_device_data(struct device *device)
++{
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++
++      if (!mapping) {
++              dev_err(device, "device not registered\n");
++              return NULL;
++      }
++
++      return mapping->gasket_dev;
++}
++EXPORT_SYMBOL(gasket_sysfs_get_device_data);
++
++void gasket_sysfs_put_device_data(struct device *device, struct gasket_dev *dev)
++{
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++
++      if (!mapping)
++              return;
++
++      /* See comment of put_mapping_n() for why the '2' is necessary. */
++      put_mapping_n(mapping, 2);
++}
++EXPORT_SYMBOL(gasket_sysfs_put_device_data);
++
++struct gasket_sysfs_attribute *
++gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr)
++{
++      int i;
++      int num_attrs;
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++      struct gasket_sysfs_attribute *attrs = NULL;
++
++      if (!mapping)
++              return NULL;
++
++      attrs = mapping->attributes;
++      num_attrs = mapping->attribute_count;
++      for (i = 0; i < num_attrs; ++i) {
++              if (!strcmp(attrs[i].attr.attr.name, attr->attr.name))
++                      return &attrs[i];
++      }
++
++      dev_err(device, "Unable to find match for device_attribute %s\n",
++              attr->attr.name);
++      return NULL;
++}
++EXPORT_SYMBOL(gasket_sysfs_get_attr);
++
++void gasket_sysfs_put_attr(struct device *device,
++                         struct gasket_sysfs_attribute *attr)
++{
++      int i;
++      int num_attrs;
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++      struct gasket_sysfs_attribute *attrs = NULL;
++
++      if (!mapping)
++              return;
++
++      attrs = mapping->attributes;
++      num_attrs = mapping->attribute_count;
++      for (i = 0; i < num_attrs; ++i) {
++              if (&attrs[i] == attr) {
++                      put_mapping_n(mapping, 2);
++                      return;
++              }
++      }
++
++      dev_err(device, "Unable to put unknown attribute: %s\n",
++              attr->attr.attr.name);
++}
++EXPORT_SYMBOL(gasket_sysfs_put_attr);
++
++ssize_t gasket_sysfs_register_store(struct device *device,
++                                  struct device_attribute *attr,
++                                  const char *buf, size_t count)
++{
++      ulong parsed_value = 0;
++      struct gasket_sysfs_mapping *mapping;
++      struct gasket_dev *gasket_dev;
++      struct gasket_sysfs_attribute *gasket_attr;
++
++      if (count < 3 || buf[0] != '0' || buf[1] != 'x') {
++              dev_err(device,
++                      "sysfs register write format: \"0x<hex value>\"\n");
++              return -EINVAL;
++      }
++
++      if (kstrtoul(buf, 16, &parsed_value) != 0) {
++              dev_err(device,
++                      "Unable to parse input as 64-bit hex value: %s\n", buf);
++              return -EINVAL;
++      }
++
++      mapping = get_mapping(device);
++      if (!mapping) {
++              dev_err(device, "Device driver may have been removed\n");
++              return 0;
++      }
++
++      gasket_dev = mapping->gasket_dev;
++      if (!gasket_dev) {
++              dev_err(device, "Device driver may have been removed\n");
++              return 0;
++      }
++
++      gasket_attr = gasket_sysfs_get_attr(device, attr);
++      if (!gasket_attr) {
++              put_mapping(mapping);
++              return count;
++      }
++
++      gasket_dev_write_64(gasket_dev, parsed_value,
++                          gasket_attr->data.bar_address.bar,
++                          gasket_attr->data.bar_address.offset);
++
++      if (gasket_attr->write_callback)
++              gasket_attr->write_callback(gasket_dev, gasket_attr,
++                                          parsed_value);
++
++      gasket_sysfs_put_attr(device, gasket_attr);
++      put_mapping(mapping);
++      return count;
++}
++EXPORT_SYMBOL(gasket_sysfs_register_store);
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_sysfs.h b/drivers/staging/gasket-driver/gasket_sysfs.h
+--- a/drivers/staging/gasket-driver/gasket_sysfs.h     1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_sysfs.h     2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,186 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Set of common sysfs utilities.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++
++/* The functions described here are a set of utilities to allow each file in the
++ * Gasket driver framework to manage their own set of sysfs entries, instead of
++ * centralizing all that work in one file.
++ *
++ * The goal of these utilities is to allow for sysfs entries to be easily
++ * created without causing a proliferation of sysfs "show" functions. This
++ * requires O(N) string lookups during show function execution, but as reading
++ * sysfs entries is rarely performance-critical, this is likely acceptible.
++ */
++#ifndef __GASKET_SYSFS_H__
++#define __GASKET_SYSFS_H__
++
++#include "gasket_constants.h"
++#include "gasket_core.h"
++#include <linux/device.h>
++#include <linux/stringify.h>
++#include <linux/sysfs.h>
++
++/* The maximum number of mappings/devices a driver needs to support. */
++#define GASKET_SYSFS_NUM_MAPPINGS (GASKET_FRAMEWORK_DESC_MAX * GASKET_DEV_MAX)
++
++/* The maximum number of sysfs nodes in a directory.
++ */
++#define GASKET_SYSFS_MAX_NODES 196
++
++/* End markers for sysfs struct arrays. */
++#define GASKET_ARRAY_END_TOKEN GASKET_RESERVED_ARRAY_END
++#define GASKET_ARRAY_END_MARKER __stringify(GASKET_ARRAY_END_TOKEN)
++
++/*
++ * Terminator struct for a gasket_sysfs_attr array. Must be at the end of
++ * all gasket_sysfs_attribute arrays.
++ */
++#define GASKET_END_OF_ATTR_ARRAY                                               \
++      {                                                                      \
++              .attr = __ATTR(GASKET_ARRAY_END_TOKEN, S_IRUGO, NULL, NULL),   \
++              .data.attr_type = 0,                                           \
++      }
++
++/*
++ * Pairing of sysfs attribute and user data.
++ * Used in lookups in sysfs "show" functions to return attribute metadata.
++ */
++struct gasket_sysfs_attribute {
++      /* The underlying sysfs device attribute associated with this data. */
++      struct device_attribute attr;
++
++      /* User-specified data to associate with the attribute. */
++      union {
++              struct bar_address_ {
++                      ulong bar;
++                      ulong offset;
++              } bar_address;
++              uint attr_type;
++      } data;
++
++      /*
++       * Function pointer to a callback to be invoked when this attribute is
++       * written (if so configured). The arguments are to the Gasket device
++       * pointer, the enclosing gasket_attr structure, and the value written.
++       * The callback should perform any logging necessary, as errors cannot
++       * be returned from the callback.
++       */
++      void (*write_callback)(struct gasket_dev *dev,
++                             struct gasket_sysfs_attribute *attr,
++                             ulong value);
++};
++
++#define GASKET_SYSFS_RO(_name, _show_function, _attr_type)                     \
++      {                                                                      \
++              .attr = __ATTR(_name, S_IRUGO, _show_function, NULL),          \
++              .data.attr_type = _attr_type                                   \
++      }
++
++#define GASKET_SYSFS_RW(_name, _show_function, _store_function, _attr_type)    \
++      {                                                                      \
++              .attr = __ATTR(_name, S_IWUSR | S_IWGRP | S_IRUGO,             \
++                              _show_function, _store_function),              \
++              .data.attr_type = _attr_type                                   \
++      }
++
++/* Initializes the Gasket sysfs subsystem.
++ *
++ * Description: Performs one-time initialization. Must be called before usage
++ * at [Gasket] module load time.
++ */
++void gasket_sysfs_init(void);
++
++/*
++ * Create an entry in mapping_data between a device and a Gasket device.
++ * @device: Device struct to map to.
++ * @gasket_dev: The dev struct associated with the driver controlling @device.
++ *
++ * Description: This function maps a gasket_dev* to a device*. This mapping can
++ * be used in sysfs_show functions to get a handle to the gasket_dev struct
++ * controlling the device node.
++ *
++ * If this function is not called before gasket_sysfs_create_entries, a warning
++ * will be logged.
++ */
++int gasket_sysfs_create_mapping(struct device *device,
++                              struct gasket_dev *gasket_dev);
++
++/*
++ * Creates bulk entries in sysfs.
++ * @device: Kernel device structure.
++ * @attrs: List of attributes/sysfs entries to create.
++ *
++ * Description: Creates each sysfs entry described in "attrs". Can be called
++ * multiple times for a given @device. If the gasket_dev specified in
++ * gasket_sysfs_create_mapping had a legacy device, the entries will be created
++ * for it, as well.
++ */
++int gasket_sysfs_create_entries(struct device *device,
++                              const struct gasket_sysfs_attribute *attrs);
++
++/*
++ * Removes a device mapping from the global table.
++ * @device: Device to unmap.
++ *
++ * Description: Removes the device->Gasket device mapping from the internal
++ * table.
++ */
++void gasket_sysfs_remove_mapping(struct device *device);
++
++/*
++ * User data lookup based on kernel device structure.
++ * @device: Kernel device structure.
++ *
++ * Description: Returns the user data associated with "device" in a prior call
++ * to gasket_sysfs_create_entries. Returns NULL if no mapping can be found.
++ * Upon success, this call take a reference to internal sysfs data that must be
++ * released with gasket_sysfs_put_device_data. While this reference is held, the
++ * underlying device sysfs information/structure will remain valid/will not be
++ * deleted.
++ */
++struct gasket_dev *gasket_sysfs_get_device_data(struct device *device);
++
++/*
++ * Releases a references to internal data.
++ * @device: Kernel device structure.
++ * @dev: Gasket device descriptor (returned by gasket_sysfs_get_device_data).
++ */
++void gasket_sysfs_put_device_data(struct device *device,
++                                struct gasket_dev *gasket_dev);
++
++/*
++ * Gasket-specific attribute lookup.
++ * @device: Kernel device structure.
++ * @attr: Device attribute to look up.
++ *
++ * Returns the Gasket sysfs attribute associated with the kernel device
++ * attribute and device structure itself. Upon success, this call will take a
++ * reference to internal sysfs data that must be released with a call to
++ * gasket_sysfs_put_attr. While this reference is held, the underlying device
++ * sysfs information/structure will remain valid/will not be deleted.
++ */
++struct gasket_sysfs_attribute *
++gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr);
++
++/*
++ * Releases a references to internal data.
++ * @device: Kernel device structure.
++ * @attr: Gasket sysfs attribute descriptor (returned by
++ *        gasket_sysfs_get_attr).
++ */
++void gasket_sysfs_put_attr(struct device *device,
++                         struct gasket_sysfs_attribute *attr);
++
++/*
++ * Write to a register sysfs node.
++ * @buf: NULL-terminated data being written.
++ * @count: number of bytes in the "buf" argument.
++ */
++ssize_t gasket_sysfs_register_store(struct device *device,
++                                  struct device_attribute *attr,
++                                  const char *buf, size_t count);
++
++#endif /* __GASKET_SYSFS_H__ */
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/Kconfig b/drivers/staging/gasket-driver/Kconfig
+--- a/drivers/staging/gasket-driver/Kconfig    1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/Kconfig    2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,24 @@
++menu "Gasket devices"
++
++config STAGING_GASKET_FRAMEWORK
++      tristate "Gasket framework"
++      depends on PCI && (X86_64 || ARM64)
++      help
++        This framework supports Gasket-compatible devices, such as Apex.
++        It is required for any of the following module(s).
++
++        To compile this driver as a module, choose M here.  The module
++        will be called "gasket".
++
++config STAGING_APEX_DRIVER
++      tristate "Apex Driver"
++      depends on STAGING_GASKET_FRAMEWORK
++      help
++        This driver supports the Apex Edge TPU device.  See
++        https://cloud.google.com/edge-tpu/ for more information.
++        Say Y if you want to include this driver in the kernel.
++
++        To compile this driver as a module, choose M here.  The module
++        will be called "apex".
++
++endmenu
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/Makefile b/drivers/staging/gasket-driver/Makefile
+--- a/drivers/staging/gasket-driver/Makefile   1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/Makefile   2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,17 @@
++#
++#  Makefile for Gasket framework and dependent drivers.
++#
++
++obj-m += gasket.o
++obj-m += apex.o
++
++gasket-objs   := gasket_core.o gasket_ioctl.o gasket_interrupt.o gasket_page_table.o gasket_sysfs.o
++apex-objs     := apex_driver.o
++
++KVERSION := $(shell uname -r)
++
++all:
++      $(MAKE) -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
++
++clean:
++      $(MAKE) -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/TODO b/drivers/staging/gasket-driver/TODO
+--- a/drivers/staging/gasket-driver/TODO       1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/TODO       2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,9 @@
++This is a list of things that need to be done to get this driver out of the
++staging directory.
++- Document sysfs files with Documentation/ABI/ entries.
++- Use misc interface instead of major number for driver version description.
++- Add descriptions of module_param's
++- apex_get_status() should actually check status.
++- "drivers" should never be dealing with "raw" sysfs calls or mess around with
++  kobjects at all. The driver core should handle all of this for you
++  automaically. There should not be a need for raw attribute macros.
+diff '--color=auto' -urN a/drivers/staging/Kconfig b/drivers/staging/Kconfig
+--- a/drivers/staging/Kconfig  2025-02-18 23:57:39.206607973 +0000
++++ b/drivers/staging/Kconfig  2025-02-19 19:25:43.186155250 +0000
+@@ -50,4 +50,6 @@
+ source "drivers/staging/gpib/Kconfig"
++source "drivers/staging/gasket-driver/Kconfig"
++
+ endif # STAGING
diff --git a/sys-kernel/gentooAI-sources/gentooAI-sources-6.13.3-r1.ebuild b/sys-kernel/gentooAI-sources/gentooAI-sources-6.13.3-r1.ebuild
new file mode 100644 (file)
index 0000000..7470a5e
--- /dev/null
@@ -0,0 +1,38 @@
+# Copyright 1999-2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI="8"
+ETYPE="sources"
+K_WANT_GENPATCHES="base extras experimental"
+K_GENPATCHES_VER="5"
+
+inherit check-reqs kernel-2
+detect_version
+detect_arch
+
+DESCRIPTION="Full sources including the Gentoo patchset for the ${KV_MAJOR}.${KV_MINOR} kernel tree"
+HOMEPAGE="https://dev.gentoo.org/~mpagano/genpatches"
+SRC_URI="${KERNEL_URI} ${GENPATCHES_URI} ${ARCH_URI}"
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86"
+IUSE="experimental"
+
+pkg_pretend() {
+       CHECKREQS_DISK_BUILD="4G"
+       check-reqs_pkg_pretend
+}
+
+src_prepare() {
+       kernel-2_src_prepare
+       rm "${S}/tools/testing/selftests/tc-testing/action-ebpf"
+       eapply "${FILESDIR}/patch.6.13.3"
+}
+
+pkg_postinst() {
+       kernel-2_pkg_postinst
+       einfo "For more info on this patchset, and how to report problems, see:"
+       einfo "${HOMEPAGE}"
+}
+
+pkg_postrm() {
+       kernel-2_pkg_postrm
+}
diff --git a/sys-kernel/gentooAI-sources/gentooAI-sources-6.13.5.ebuild b/sys-kernel/gentooAI-sources/gentooAI-sources-6.13.5.ebuild
new file mode 100644 (file)
index 0000000..699e10a
--- /dev/null
@@ -0,0 +1,38 @@
+# Copyright 1999-2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI="8"
+ETYPE="sources"
+K_WANT_GENPATCHES="base extras experimental"
+K_GENPATCHES_VER="7"
+
+inherit check-reqs kernel-2
+detect_version
+detect_arch
+
+DESCRIPTION="Full sources including the Gentoo patchset for the ${KV_MAJOR}.${KV_MINOR} kernel tree"
+HOMEPAGE="https://dev.gentoo.org/~mpagano/genpatches"
+SRC_URI="${KERNEL_URI} ${GENPATCHES_URI} ${ARCH_URI}"
+KEYWORDS="~alpha amd64 ~arm ~arm64 ~hppa ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86"
+IUSE="experimental"
+
+pkg_pretend() {
+       CHECKREQS_DISK_BUILD="4G"
+       check-reqs_pkg_pretend
+}
+
+src_prepare() {
+       kernel-2_src_prepare
+       rm "${S}/tools/testing/selftests/tc-testing/action-ebpf"
+       eapply "${FILESDIR}/patch.6.13.3"
+}
+
+pkg_postinst() {
+       kernel-2_pkg_postinst
+       einfo "For more info on this patchset, and how to report problems, see:"
+       einfo "${HOMEPAGE}"
+}
+
+pkg_postrm() {
+       kernel-2_pkg_postrm
+}
diff --git a/sys-kernel/raspberrypi-sources/Manifest b/sys-kernel/raspberrypi-sources/Manifest
new file mode 100644 (file)
index 0000000..5d3395a
--- /dev/null
@@ -0,0 +1,7 @@
+AUX raspberrypi-sources-5.15.32-gentoo-kconfig.patch 14618 BLAKE2B d2b6bb66b8ddf7b17fff2b7e6d55cdd8360d6d4f0f033e513e34f5474c0078f21bd49ba6e8d28794ba1468e50f0e463fd79d64aa64f5d50025097e4fe733a2ac SHA512 6cd674d3dce0cd0565f28f903ff7d1b0beb492c4fa5c8f8c52c9b99c5da6f7d15e77e42d78b8671a73451033602815b3b858d59638c22a3c7c69d0e43d6ff4e1
+AUX raspberrypi-sources-6.1.21-gentoo-kconfig.patch 329 BLAKE2B f2c3f97b193968a2ad17547ffc7583af292c5bc17daa283c965ca5eb7115b94022a1d72000f1b9af03086aa7927b43c39ee10b12cfa143cb75ba423a7855bba4 SHA512 c00e9608b7bb03ee1637849e819d5a148ef4fb5a88490ac6567fe7720ef723666cc5e682cdf578ec2a7ea2a64f38828aef8847a2781d620571dfa5fa31ddf9d5
+AUX raspberrypi-sources-AI.patch 241035 BLAKE2B 4d34c2bc7139941e5e99948ece97b22614a3ead17cbc2b9e40aebbde15c796988f86e15959cc280fe2ae9bdac4edf42a67f21ea7e660d8c985702167d76f5120 SHA512 25587af6dae2a155c89a0deae2b9db9cf1b10cf7e2b6bb704edd9e55b5bce05e24aad7a7943c361861af0048fc6e82b7722424ac342572099300ee8402e847e8
+DIST genpatches-6.6-54.base.tar.xz 2922380 BLAKE2B f65404127bb6547208aeddac1996a4a2659bd99ff7429bcaff28247a867c000e962457725eab80db2c76297f1e5c27806dc6fb23e31d5694b6df783e65995227 SHA512 102f721f87478ad18599bb5ff65cd236180dd3d9d058786a5306cb36be3f30a2d2ef684e83b6f458d4de78a196323e87d346eba704bfbce733010aed6ac3d7f9
+DIST genpatches-6.6-54.extras.tar.xz 4060 BLAKE2B 22ea7d143bfe168bc5d9d30832423bcd33b49c1b3b5ddf031000d7d9fce96f6fa0fb1d06fd33b27a5de9c9f3833a139557f0ed7408ef12b23568784ff38ca7a9 SHA512 1b1a229b5923e7f3426139b17608b5feae6061313f7aea66de23f09a54696def39bf4b384c4e884a3e5c758c08e04dcfe1ab7f2aa331db74b59f5e511c6f2c5b
+DIST linux-6.6.74_p20250127-raspberrypi.tar.gz 231349139 BLAKE2B ecd1a72b6a908f4903191cacf27f036038719e132e14eb7dc25a195b39056a3b3d6fbbd8477fbceea35437ef4853e71c13175fc1ce207c43af7e8a4ba3a55ef5 SHA512 f84ec3ea33dd95ac9d4c2a601a831e62e811687da283d2ee2bc6985b115d528837569a81176f05fe4a9d9e3b40e8e071aeb3f4088da583b1d2eafbb3929d6d98
+EBUILD raspberrypi-sources-6.6.74_p20250127.ebuild 1639 BLAKE2B 4aee43ed2c22ae4d2a470a601dd593210d806435e0dc75648214c5682fb3d99529f4bdef90fa644ecaf62f803d89478fdce8c257185ceb5e0b06b1ca4fc3bc8c SHA512 de99f89f34b70e0985188bf5f321aec8a09aaaff2618c9470b56ccd534c30e9c2c8a4e9321d182502cd7dddf20be4f714f19103e0198a656343ec703cb32bb11
diff --git a/sys-kernel/raspberrypi-sources/files/raspberrypi-sources-5.15.32-gentoo-kconfig.patch b/sys-kernel/raspberrypi-sources/files/raspberrypi-sources-5.15.32-gentoo-kconfig.patch
new file mode 100644 (file)
index 0000000..8c8535a
--- /dev/null
@@ -0,0 +1,474 @@
+diff --git a/Kconfig b/Kconfig
+index 745bc773f567..16628b0c76d9 100644
+--- a/Kconfig
++++ b/Kconfig
+@@ -5,6 +5,8 @@
+ #
+ mainmenu "Linux/$(ARCH) $(KERNELVERSION) Kernel Configuration"
++source "distro/Kconfig"
++
+ source "scripts/Kconfig.include"
+ source "init/Kconfig"
+diff --git a/distro/Kconfig b/distro/Kconfig
+new file mode 100644
+index 000000000000..531a636c959d
+--- /dev/null
++++ b/distro/Kconfig
+@@ -0,0 +1,378 @@
++menu "Gentoo Linux"
++
++config GENTOO_LINUX
++      bool "Gentoo Linux support"
++
++      default y
++
++      select CPU_FREQ_DEFAULT_GOV_SCHEDUTIL
++
++      help
++              In order to boot Gentoo Linux a minimal set of config settings needs to
++              be enabled in the kernel; to avoid the users from having to enable them
++              manually as part of a Gentoo Linux installation or a new clean config,
++              we enable these config settings by default for convenience.
++
++              See the settings that become available for more details and fine-tuning.
++
++config GENTOO_LINUX_UDEV
++      bool "Linux dynamic and persistent device naming (userspace devfs) support"
++
++      depends on GENTOO_LINUX
++      default y if GENTOO_LINUX
++
++      select DEVTMPFS
++      select TMPFS
++      select UNIX
++
++      select MMU
++      select SHMEM
++
++      help
++              In order to boot Gentoo Linux a minimal set of config settings needs to
++              be enabled in the kernel; to avoid the users from having to enable them
++              manually as part of a Gentoo Linux installation or a new clean config,
++              we enable these config settings by default for convenience.
++
++              Currently this only selects TMPFS, DEVTMPFS and their dependencies.
++              TMPFS is enabled to maintain a tmpfs file system at /dev/shm, /run and
++              /sys/fs/cgroup; DEVTMPFS to maintain a devtmpfs file system at /dev.
++
++              Some of these are critical files that need to be available early in the
++              boot process; if not available, it causes sysfs and udev to malfunction.
++
++              To ensure Gentoo Linux boots, it is best to leave this setting enabled;
++              if you run a custom setup, you could consider whether to disable this.
++
++config GENTOO_LINUX_PORTAGE
++      bool "Select options required by Portage features"
++
++      depends on GENTOO_LINUX
++      default y if GENTOO_LINUX
++
++      select CGROUPS
++      select NAMESPACES
++      select IPC_NS
++      select NET_NS
++      select PID_NS
++      select SYSVIPC
++      select USER_NS
++      select UTS_NS
++
++      help
++              This enables options required by various Portage FEATURES.
++              Currently this selects:
++
++              CGROUPS     (required for FEATURES=cgroup)
++              IPC_NS      (required for FEATURES=ipc-sandbox)
++              NET_NS      (required for FEATURES=network-sandbox)
++              PID_NS          (required for FEATURES=pid-sandbox)
++              SYSVIPC     (required by IPC_NS)
++
++
++              It is highly recommended that you leave this enabled as these FEATURES
++              are, or will soon be, enabled by default.
++
++menu "Support for init systems, system and service managers"
++      visible if GENTOO_LINUX
++
++config GENTOO_LINUX_INIT_SCRIPT
++      bool "OpenRC, runit and other script based systems and managers"
++
++      default n
++
++      depends on GENTOO_LINUX
++
++      select BINFMT_SCRIPT
++      select CGROUPS
++      select EPOLL
++      select FILE_LOCKING
++      select INOTIFY_USER
++      select SIGNALFD
++      select TIMERFD
++
++      help
++              The init system is the first thing that loads after the kernel booted.
++
++              These config settings allow you to select which init systems to support;
++              instead of having to select all the individual settings all over the
++              place, these settings allows you to select all the settings at once.
++
++              This particular setting enables all the known requirements for OpenRC,
++              runit and similar script based systems and managers.
++
++              If you are unsure about this, it is best to leave this setting enabled.
++
++menuconfig GENTOO_LINUX_INIT_SYSTEMD
++      bool "systemd"
++      default y
++      depends on GENTOO_LINUX && GENTOO_LINUX_UDEV
++
++      select CGROUPS
++      select DEVTMPFS
++      select DMIID if X86_32 || X86_64 || X86
++      select EPOLL
++      select FHANDLE
++      select INOTIFY_USER
++      select PROC_FS
++      select SIGNALFD
++      select SYSFS
++      select TIMERFD
++      select UNIX
++
++      help
++              The init system is the first thing that loads after the kernel booted.
++
++              These config settings allow you to select which init systems to support;
++              instead of having to select all the individual settings all over the
++              place, these settings allows you to select all the settings at once.
++
++              This particular setting enables all the known requirements for systemd;
++              it also enables suggested optional settings, as the package suggests to.
++
++if GENTOO_LINUX_INIT_SYSTEMD
++
++comment "systemd config options"
++
++config GENTOO_LINUX_INIT_SYSTEMD_CRYPTO
++      bool "Systemd crypto/hash api"
++      default y
++      select CRYPTO_HMAC
++      select CRYPTO_SHA256
++      select CRYPTO_USER_API_HASH
++
++config GENTOO_LINUX_INIT_SYSTEMD_SCSI
++      bool "Support for some SCSI devices serial number retrieval"
++      default n
++      select BLK_DEV_BSG
++
++config GENTOO_LINUX_INIT_SYSTEMD_PRIVATE_NETWORKS
++      bool "Support PrivateNetwork directive in service units"
++      default y
++      select NET_NS
++
++      help
++              systemd-localed.service and other systemd units use
++              PrivateNetwork so this is effectively required
++
++config GENTOO_LINUX_INIT_SYSTEMD_PRIVATE_USERS
++      bool "Support PrivateUsers directive in service units"
++      default y
++      select USER_NS
++
++config GENTOO_LINUX_INIT_SYSTEMD_CPUSHARES
++      bool "Support CPUShares in resource control unit settings"
++      default y
++      select CGROUP_SCHED
++      select FAIR_GROUP_SCHED
++
++config GENTOO_LINUX_INIT_SYSTEMD_CPUQUOTA
++      bool "Support CPUQuota in resource control unit settings"
++      default y
++      select CFS_BANDWIDTH
++
++config GENTOO_LINUX_INIT_SYSTEMD_NETWORK_FILTERING
++      bool "Support network traffic filtering for IP packets and custom network traffic filters in resource control unit settings"
++      default y
++      select BPF
++      select BPF_SYSCALL
++      select BPF_JIT
++      select CGROUP_BPF
++      select HAVE_EBPF_JIT
++
++      help
++              Required for IPAddressDeny=, IPAddressAllow=, IPIngressFilterPath=,
++              IPEgressFilterPath= in resource control unit settings
++
++config GENTOO_LINUX_INIT_SYSTEMD_NETWORK
++      bool "Restrict Sockets and Network Interface access in resource control unit settings"
++      default y
++      select BPF
++      select BPF_SYSCALL
++      select BPF_JIT
++      select CGROUP_BPF
++      select EFIVAR_FS if ( X86_32 || X86_64 || X86 ) && CONFIG_EFI
++      select EFI_PARTITION if ( X86_32 || X86_64 || X86 ) && CONFIG_EFI
++      select HAVE_EBPF_JIT
++
++      help
++              Allow or deny binding a socket address to a socket by matching
++              it with the bind-rule and applying a corresponding action if
++              there is a match. Also restricts the network interfaces that
++              processes of this unit can use.
++
++config GENTOO_LINUX_INIT_SYSTEMD_FILESYSTEMS
++      bool "Support RestrictFileSystems directive in service units"
++      default n
++      depends on !GENTOO_KERNEL_SELF_PROTECTION
++      select BPF
++      select BPF_SYSCALL
++      select BPF_LSM
++      select DEBUG_INFO_BTF
++
++      help
++              Also required to select LSM="...,bpf" or kernel booted with
++              lsm="...,bpf".
++
++config GENTOO_LINUX_INIT_SYSTEMD_OOMD
++      bool "Support systemd-oomd"
++      default y
++      select PSI
++
++config GENTOO_LINUX_INIT_SYSTEMD_VERITY
++      bool "Support signed Verity images"
++      default n
++      select DM_VERITY_VERIFY_ROOTHASH_SIG
++
++config GENTOO_LINUX_INIT_SYSTEMD_OPTIONAL
++      bool "Optional but strongly recommended modules"
++      default y
++      select AUTOFS_FS
++      select IPV6
++      select KCMP
++      select SECCOMP
++      select SECCOMP_FILTER if HAVE_ARCH_SECCOMP_FILTER
++      select TMPFS_XATTR
++
++      select 9P_FS_POSIX_ACL if 9P_FS
++      select BTRFS_FS_POSIX_ACL if BTRFS_FS
++      select CEPH_FS_POSIX_ACL if CEPH_FS
++      select EROFS_FS_POSIX_ACL if EROFS_FS
++      select EXT2_FS_POSIX_ACL if EXT2_FS3
++      select EXT3_FS_POSIX_ACL if EXT3_FS
++      select EXT4_FS_POSIX_ACL if EXT4_FS
++      select F2FS_FS_POSIX_ACL if F2FS_FS
++      select NTFS3_FS_POSIX_ACL if NTFS3_FS
++      select REISERFS_FS_POSIX_ACL if REISERFS_FS
++      select TMPFS_POSIX_ACL if TMPFS
++      select XFS_POSIX_ACL if XFS_FS
++endif
++endmenu
++
++menuconfig GENTOO_KERNEL_SELF_PROTECTION
++      bool "Kernel Self Protection Project"
++      depends on GENTOO_LINUX
++      help
++              Recommended Kernel settings based on the suggestions from the Kernel Self Protection Project
++              See: https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Project/Recommended_Settings
++              Note, there may be additional settings for which the CONFIG_ setting is invisible in menuconfig due
++              to unmet dependencies. Search for GENTOO_KERNEL_SELF_PROTECTION_COMMON and search for
++              GENTOO_KERNEL_SELF_PROTECTION_{X86_64, ARM64, X86_32, ARM} for dependency information on your
++              specific architecture.
++              Note 2: Please see the URL above for numeric settings, e.g. CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
++              for X86_64
++
++if GENTOO_KERNEL_SELF_PROTECTION
++config GENTOO_KERNEL_SELF_PROTECTION_COMMON
++      bool "Enable Kernel Self Protection Project Recommendations"
++
++      depends on GENTOO_LINUX && !ACPI_CUSTOM_METHOD && !COMPAT_BRK && !DEVKMEM && !PROC_KCORE && !COMPAT_VDSO && !KEXEC && !HIBERNATION && !LEGACY_PTYS && !X86_X32 && !MODIFY_LDT_SYSCALL && GCC_PLUGINS && !GENTOO_LINUX_INIT_SYSTEMD_FILESYSTEMS
++
++      select BUG
++      select STRICT_KERNEL_RWX
++      select DEBUG_WX
++      select STACKPROTECTOR
++      select STACKPROTECTOR_STRONG
++      select STRICT_DEVMEM if DEVMEM=y
++      select IO_STRICT_DEVMEM if DEVMEM=y
++      select SYN_COOKIES
++      select DEBUG_CREDENTIALS
++      select DEBUG_NOTIFIERS
++      select DEBUG_LIST
++      select DEBUG_SG
++      select BUG_ON_DATA_CORRUPTION
++      select SCHED_STACK_END_CHECK
++      select SECCOMP if HAVE_ARCH_SECCOMP
++      select SECCOMP_FILTER if HAVE_ARCH_SECCOMP_FILTER
++      select SECURITY_YAMA
++      select SLAB_FREELIST_RANDOM
++      select SLAB_FREELIST_HARDENED
++      select SHUFFLE_PAGE_ALLOCATOR
++      select SLUB_DEBUG
++      select PAGE_POISONING
++      select PAGE_POISONING_NO_SANITY
++      select PAGE_POISONING_ZERO
++      select INIT_ON_ALLOC_DEFAULT_ON
++      select INIT_ON_FREE_DEFAULT_ON
++      select REFCOUNT_FULL
++      select FORTIFY_SOURCE
++      select SECURITY_DMESG_RESTRICT
++      select PANIC_ON_OOPS
++      select GCC_PLUGIN_LATENT_ENTROPY
++      select GCC_PLUGIN_STRUCTLEAK
++      select GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
++      select GCC_PLUGIN_RANDSTRUCT
++      select GCC_PLUGIN_RANDSTRUCT_PERFORMANCE
++
++      help
++              Search for GENTOO_KERNEL_SELF_PROTECTION_{X86_64, ARM64, X86_32, ARM} for dependency
++              information on your specific architecture.  Note 2: Please see the URL above for
++              numeric settings, e.g. CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 for X86_64
++
++config GENTOO_KERNEL_SELF_PROTECTION_X86_64
++      bool "X86_64 KSPP Settings" if GENTOO_KERNEL_SELF_PROTECTION_COMMON
++
++      depends on !X86_MSR && X86_64 && GENTOO_KERNEL_SELF_PROTECTION
++      default n
++
++      select RANDOMIZE_BASE
++      select RANDOMIZE_MEMORY
++      select RELOCATABLE
++      select LEGACY_VSYSCALL_NONE
++      select PAGE_TABLE_ISOLATION
++      select GCC_PLUGIN_STACKLEAK
++      select VMAP_STACK
++
++
++config GENTOO_KERNEL_SELF_PROTECTION_ARM64
++      bool "ARM64 KSPP Settings"
++
++      depends on ARM64
++      default n
++
++      select RANDOMIZE_BASE
++      select RELOCATABLE
++      select ARM64_SW_TTBR0_PAN
++      select CONFIG_UNMAP_KERNEL_AT_EL0
++      select GCC_PLUGIN_STACKLEAK
++      select VMAP_STACK
++
++config GENTOO_KERNEL_SELF_PROTECTION_X86_32
++      bool "X86_32 KSPP Settings"
++
++      depends on !X86_MSR && !MODIFY_LDT_SYSCALL && !M486 && X86_32
++      default n
++
++      select HIGHMEM64G
++      select X86_PAE
++      select RANDOMIZE_BASE
++      select RELOCATABLE
++      select PAGE_TABLE_ISOLATION
++
++config GENTOO_KERNEL_SELF_PROTECTION_ARM
++      bool "ARM KSPP Settings"
++
++      depends on !OABI_COMPAT && ARM
++      default n
++
++      select VMSPLIT_3G
++      select STRICT_MEMORY_RWX
++      select CPU_SW_DOMAIN_PAN
++
++endif
++
++config GENTOO_PRINT_FIRMWARE_INFO
++      bool "Print firmware information that the kernel attempts to load"
++
++      depends on GENTOO_LINUX
++      default y
++
++      help
++              Enable this option to print information about firmware that the kernel
++              is attempting to load.  This information can be accessible via the
++              dmesg command-line utility
++
++              See the settings that become available for more details and fine-tuning.
++
++endmenu
++
+diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig
+index 5b24f3959255..3e470a3dab39 100644
+--- a/drivers/base/firmware_loader/Kconfig
++++ b/drivers/base/firmware_loader/Kconfig
+@@ -70,6 +70,7 @@ config EXTRA_FIRMWARE_DIR
+ config FW_LOADER_USER_HELPER
+       bool "Enable the firmware sysfs fallback mechanism"
++      depends on !GENTOO_LINUX_INIT_SYSTEMD
+       select FW_LOADER_PAGED_BUF
+       help
+         This option enables a sysfs loading facility to enable firmware
+diff --git a/init/Kconfig b/init/Kconfig
+index 11f8a845f259..c826ddeb9ab3 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1008,6 +1008,7 @@ config CFS_BANDWIDTH
+ config RT_GROUP_SCHED
+       bool "Group scheduling for SCHED_RR/FIFO"
+       depends on CGROUP_SCHED
++      depends on !GENTOO_LINUX_INIT_SYSTEMD
+       default n
+       help
+         This feature lets you explicitly allocate real CPU bandwidth
+@@ -1272,6 +1273,7 @@ config SCHED_AUTOGROUP
+ config SYSFS_DEPRECATED
+       bool "Enable deprecated sysfs features to support old userspace tools"
+       depends on SYSFS
++      depends on !GENTOO_LINUX_INIT_SYSTEMD
+       default n
+       help
+         This option adds code that switches the layout of the "block" class
+diff --git a/mm/Kconfig b/mm/Kconfig
+index c048dea7e342..81a1dfd69adc 100644
+--- a/mm/Kconfig
++++ b/mm/Kconfig
+@@ -305,6 +305,8 @@ config KSM
+ config DEFAULT_MMAP_MIN_ADDR
+       int "Low address space to protect from user allocation"
+       depends on MMU
++      default 65536 if ( X86_64 || X86_32 || PPC64 || IA64 ) && GENTOO_KERNEL_SELF_PROTECTION
++      default 32768 if ( ARM64 || ARM ) && GENTOO_KERNEL_SELF_PROTECTION
+       default 4096
+       help
+         This is the portion of low virtual memory which should be protected
+diff --git a/security/Kconfig b/security/Kconfig
+index fe6c0395fa02..6b1b81cd120e 100644
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -166,6 +166,7 @@ config HARDENED_USERCOPY
+ config HARDENED_USERCOPY_FALLBACK
+       bool "Allow usercopy whitelist violations to fallback to object size"
+       depends on HARDENED_USERCOPY
++      depends on !GENTOO_KERNEL_SELF_PROTECTION
+       default y
+       help
+         This is a temporary option that allows missing usercopy whitelists
+@@ -181,6 +182,7 @@ config HARDENED_USERCOPY_PAGESPAN
+       bool "Refuse to copy allocations that span multiple pages"
+       depends on HARDENED_USERCOPY
+       depends on EXPERT
++      depends on !GENTOO_KERNEL_SELF_PROTECTION
+       help
+         When a multi-page allocation is done without __GFP_COMP,
+         hardened usercopy will reject attempts to copy it. There are,
+diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
+index 9e921fc72538..9e1f7ce887b6 100644
+--- a/security/selinux/Kconfig
++++ b/security/selinux/Kconfig
+@@ -12,6 +12,7 @@ config SECURITY_SELINUX
+ config SECURITY_SELINUX_BOOTPARAM
+       bool "NSA SELinux boot parameter"
+       depends on SECURITY_SELINUX
++      depends on !GENTOO_KERNEL_SELF_PROTECTION
+       default n
+       help
+         This option adds a kernel parameter 'selinux', which allows SELinux
diff --git a/sys-kernel/raspberrypi-sources/files/raspberrypi-sources-6.1.21-gentoo-kconfig.patch b/sys-kernel/raspberrypi-sources/files/raspberrypi-sources-6.1.21-gentoo-kconfig.patch
new file mode 100644 (file)
index 0000000..941501e
--- /dev/null
@@ -0,0 +1,13 @@
+--- a/drivers/base/firmware_loader/Kconfig
++++ b/drivers/base/firmware_loader/Kconfig
+@@ -75,6 +75,7 @@ config EXTRA_FIRMWARE_DIR
+ config FW_LOADER_USER_HELPER
+       bool "Enable the firmware sysfs fallback mechanism"
++      depends on !GENTOO_LINUX_INIT_SYSTEMD
+       select FW_LOADER_SYSFS
+       select FW_LOADER_PAGED_BUF
+       help
+-- 
+2.41.0
+
diff --git a/sys-kernel/raspberrypi-sources/files/raspberrypi-sources-AI.patch b/sys-kernel/raspberrypi-sources/files/raspberrypi-sources-AI.patch
new file mode 100644 (file)
index 0000000..a2a640b
--- /dev/null
@@ -0,0 +1,7864 @@
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/apex_driver.c b/drivers/staging/gasket-driver/apex_driver.c
+--- a/drivers/staging/gasket-driver/apex_driver.c      1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/apex_driver.c      2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,1243 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Driver for the Apex chip.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++
++#include <linux/atomic.h>
++#include <linux/compiler.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/pci.h>
++#include <linux/printk.h>
++#include <linux/sched.h>
++#include <linux/uaccess.h>
++#include <linux/workqueue.h>
++
++#include "apex.h"
++
++#include "gasket_core.h"
++#include "gasket_interrupt.h"
++#include "gasket_page_table.h"
++#include "gasket_sysfs.h"
++
++/* Constants */
++#define APEX_DEVICE_NAME "Apex"
++#define APEX_DRIVER_VERSION "1.2"
++
++/* CSRs are in BAR 2. */
++#define APEX_BAR_INDEX 2
++
++#define APEX_PCI_VENDOR_ID 0x1ac1
++#define APEX_PCI_DEVICE_ID 0x089a
++
++/* Bar Offsets. */
++#define APEX_BAR_OFFSET 0
++#define APEX_CM_OFFSET 0x1000000
++
++/* The sizes of each Apex BAR 2. */
++#define APEX_BAR_BYTES 0x100000
++#define APEX_CH_MEM_BYTES (PAGE_SIZE * MAX_NUM_COHERENT_PAGES)
++
++/* The number of user-mappable memory ranges in BAR2 of a Apex chip. */
++#define NUM_REGIONS 3
++
++/* The number of nodes in a Apex chip. */
++#define NUM_NODES 1
++
++/*
++ * The total number of entries in the page table. Should match the value read
++ * from the register APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE_SIZE.
++ */
++#define APEX_PAGE_TABLE_TOTAL_ENTRIES 8192
++
++#define APEX_EXTENDED_SHIFT 63 /* Extended address bit position. */
++
++/* Check reset 120 times */
++#define APEX_RESET_RETRY 120
++/* Wait 100 ms between checks. Total 12 sec wait maximum. */
++#define APEX_RESET_DELAY 100
++
++/* Interval between temperature polls, 0 disables polling */
++#define DEFAULT_APEX_TEMP_POLL_INTERVAL 5000
++
++/* apex device private data */
++struct apex_dev {
++      struct gasket_dev *gasket_dev_ptr;
++      struct delayed_work check_temperature_work;
++      u32 adc_trip_points[3];
++      atomic_t temp_poll_interval;
++      u32 hw_temp_warn1_adc;
++      u32 hw_temp_warn2_adc;
++      bool hw_temp_warn1_en;
++      bool hw_temp_warn2_en;
++};
++
++/* Enumeration of the supported sysfs entries. */
++enum sysfs_attribute_type {
++      ATTR_KERNEL_HIB_PAGE_TABLE_SIZE,
++      ATTR_KERNEL_HIB_SIMPLE_PAGE_TABLE_SIZE,
++      ATTR_KERNEL_HIB_NUM_ACTIVE_PAGES,
++      ATTR_TEMP,
++      ATTR_TEMP_WARN1,
++      ATTR_TEMP_WARN1_EN,
++      ATTR_TEMP_WARN2,
++      ATTR_TEMP_WARN2_EN,
++      ATTR_TEMP_TRIP0,
++      ATTR_TEMP_TRIP1,
++      ATTR_TEMP_TRIP2,
++      ATTR_TEMP_POLL_INTERVAL,
++      ATTR_UNIQUE_ID,
++};
++
++/*
++ * Register offsets into BAR2 memory.
++ * Only values necessary for driver implementation are defined.
++ */
++enum apex_bar2_regs {
++      APEX_BAR2_REG_SCU_BASE = 0x1A300,
++      APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE_SIZE = 0x46000,
++      APEX_BAR2_REG_KERNEL_HIB_EXTENDED_TABLE = 0x46008,
++      APEX_BAR2_REG_KERNEL_HIB_TRANSLATION_ENABLE = 0x46010,
++      APEX_BAR2_REG_KERNEL_HIB_INSTR_QUEUE_INTVECCTL = 0x46018,
++      APEX_BAR2_REG_KERNEL_HIB_INPUT_ACTV_QUEUE_INTVECCTL = 0x46020,
++      APEX_BAR2_REG_KERNEL_HIB_PARAM_QUEUE_INTVECCTL = 0x46028,
++      APEX_BAR2_REG_KERNEL_HIB_OUTPUT_ACTV_QUEUE_INTVECCTL = 0x46030,
++      APEX_BAR2_REG_KERNEL_HIB_SC_HOST_INTVECCTL = 0x46038,
++      APEX_BAR2_REG_KERNEL_HIB_TOP_LEVEL_INTVECCTL = 0x46040,
++      APEX_BAR2_REG_KERNEL_HIB_FATAL_ERR_INTVECCTL = 0x46048,
++      APEX_BAR2_REG_KERNEL_HIB_DMA_PAUSE = 0x46050,
++      APEX_BAR2_REG_KERNEL_HIB_DMA_PAUSE_MASK = 0x46058,
++      APEX_BAR2_REG_KERNEL_HIB_STATUS_BLOCK_DELAY = 0x46060,
++      APEX_BAR2_REG_KERNEL_HIB_MSIX_PENDING_BIT_ARRAY0 = 0x46068,
++      APEX_BAR2_REG_KERNEL_HIB_MSIX_PENDING_BIT_ARRAY1 = 0x46070,
++      APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE_INIT = 0x46078,
++      APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE_INIT = 0x46080,
++      APEX_BAR2_REG_KERNEL_WIRE_INT_PENDING_BIT_ARRAY = 0x48778,
++      APEX_BAR2_REG_KERNEL_WIRE_INT_MASK_ARRAY = 0x48780,
++      APEX_BAR2_REG_USER_HIB_DMA_PAUSE = 0x486D8,
++      APEX_BAR2_REG_USER_HIB_DMA_PAUSED = 0x486E0,
++      APEX_BAR2_REG_IDLEGENERATOR_IDLEGEN_IDLEREGISTER = 0x4A000,
++      APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE = 0x50000,
++      APEX_BAR2_REG_OMC0_D0 = 0x01a0d0,
++      APEX_BAR2_REG_OMC0_D4 = 0x01a0d4,
++      APEX_BAR2_REG_OMC0_D8 = 0x01a0d8,
++      APEX_BAR2_REG_OMC0_DC = 0x01a0dc,
++      APEX_BAR2_REG_EFUSE_DC = 0x01a2dc,
++      APEX_BAR2_REG_EFUSE_E0 = 0x01a2e0,
++      APEX_BAR2_REG_EFUSE_E4 = 0x01a2e4,
++      APEX_BAR2_REG_EFUSE_E8 = 0x01a2e8,
++
++      /* Error registers - Used mostly for debug */
++      APEX_BAR2_REG_USER_HIB_ERROR_STATUS = 0x86f0,
++      APEX_BAR2_REG_SCALAR_CORE_ERROR_STATUS = 0x41a0,
++};
++
++/* Addresses for packed registers. */
++#define APEX_BAR2_REG_AXI_QUIESCE (APEX_BAR2_REG_SCU_BASE + 0x2C)
++#define APEX_BAR2_REG_GCB_CLOCK_GATE (APEX_BAR2_REG_SCU_BASE + 0x14)
++#define APEX_BAR2_REG_SCU_0 (APEX_BAR2_REG_SCU_BASE + 0xc)
++#define APEX_BAR2_REG_SCU_1 (APEX_BAR2_REG_SCU_BASE + 0x10)
++#define APEX_BAR2_REG_SCU_2 (APEX_BAR2_REG_SCU_BASE + 0x14)
++#define APEX_BAR2_REG_SCU_3 (APEX_BAR2_REG_SCU_BASE + 0x18)
++#define APEX_BAR2_REG_SCU_4 (APEX_BAR2_REG_SCU_BASE + 0x1c)
++#define APEX_BAR2_REG_SCU_5 (APEX_BAR2_REG_SCU_BASE + 0x20)
++
++#define SCU3_RG_PWR_STATE_OVR_BIT_OFFSET 26
++#define SCU3_RG_PWR_STATE_OVR_MASK_WIDTH 2
++#define SCU3_CUR_RST_GCB_BIT_MASK 0x10
++#define SCU2_RG_RST_GCB_BIT_MASK 0xc
++
++/* Configuration for page table. */
++static struct gasket_page_table_config apex_page_table_configs[NUM_NODES] = {
++      {
++              .id = 0,
++              .mode = GASKET_PAGE_TABLE_MODE_NORMAL,
++              .total_entries = APEX_PAGE_TABLE_TOTAL_ENTRIES,
++              .base_reg = APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE,
++              .extended_reg = APEX_BAR2_REG_KERNEL_HIB_EXTENDED_TABLE,
++              .extended_bit = APEX_EXTENDED_SHIFT,
++      },
++};
++
++/* The regions in the BAR2 space that can be mapped into user space. */
++static const struct gasket_mappable_region mappable_regions[NUM_REGIONS] = {
++      { 0x40000, 0x1000 },
++      { 0x44000, 0x1000 },
++      { 0x48000, 0x1000 },
++};
++
++/* Gasket device interrupts enums must be dense (i.e., no empty slots). */
++enum apex_interrupt {
++      APEX_INTERRUPT_INSTR_QUEUE = 0,
++      APEX_INTERRUPT_INPUT_ACTV_QUEUE = 1,
++      APEX_INTERRUPT_PARAM_QUEUE = 2,
++      APEX_INTERRUPT_OUTPUT_ACTV_QUEUE = 3,
++      APEX_INTERRUPT_SC_HOST_0 = 4,
++      APEX_INTERRUPT_SC_HOST_1 = 5,
++      APEX_INTERRUPT_SC_HOST_2 = 6,
++      APEX_INTERRUPT_SC_HOST_3 = 7,
++      APEX_INTERRUPT_TOP_LEVEL_0 = 8,
++      APEX_INTERRUPT_TOP_LEVEL_1 = 9,
++      APEX_INTERRUPT_TOP_LEVEL_2 = 10,
++      APEX_INTERRUPT_TOP_LEVEL_3 = 11,
++      APEX_INTERRUPT_FATAL_ERR = 12,
++      APEX_INTERRUPT_COUNT = 13,
++};
++
++/* Interrupt descriptors for Apex */
++static struct gasket_interrupt_desc apex_interrupts[] = {
++      {
++              APEX_INTERRUPT_INSTR_QUEUE,
++              APEX_BAR2_REG_KERNEL_HIB_INSTR_QUEUE_INTVECCTL,
++              UNPACKED,
++      },
++      {
++              APEX_INTERRUPT_INPUT_ACTV_QUEUE,
++              APEX_BAR2_REG_KERNEL_HIB_INPUT_ACTV_QUEUE_INTVECCTL,
++              UNPACKED
++      },
++      {
++              APEX_INTERRUPT_PARAM_QUEUE,
++              APEX_BAR2_REG_KERNEL_HIB_PARAM_QUEUE_INTVECCTL,
++              UNPACKED
++      },
++      {
++              APEX_INTERRUPT_OUTPUT_ACTV_QUEUE,
++              APEX_BAR2_REG_KERNEL_HIB_OUTPUT_ACTV_QUEUE_INTVECCTL,
++              UNPACKED
++      },
++      {
++              APEX_INTERRUPT_SC_HOST_0,
++              APEX_BAR2_REG_KERNEL_HIB_SC_HOST_INTVECCTL,
++              PACK_0
++      },
++      {
++              APEX_INTERRUPT_SC_HOST_1,
++              APEX_BAR2_REG_KERNEL_HIB_SC_HOST_INTVECCTL,
++              PACK_1
++      },
++      {
++              APEX_INTERRUPT_SC_HOST_2,
++              APEX_BAR2_REG_KERNEL_HIB_SC_HOST_INTVECCTL,
++              PACK_2
++      },
++      {
++              APEX_INTERRUPT_SC_HOST_3,
++              APEX_BAR2_REG_KERNEL_HIB_SC_HOST_INTVECCTL,
++              PACK_3
++      },
++      {
++              APEX_INTERRUPT_TOP_LEVEL_0,
++              APEX_BAR2_REG_KERNEL_HIB_TOP_LEVEL_INTVECCTL,
++              PACK_0
++      },
++      {
++              APEX_INTERRUPT_TOP_LEVEL_1,
++              APEX_BAR2_REG_KERNEL_HIB_TOP_LEVEL_INTVECCTL,
++              PACK_1
++      },
++      {
++              APEX_INTERRUPT_TOP_LEVEL_2,
++              APEX_BAR2_REG_KERNEL_HIB_TOP_LEVEL_INTVECCTL,
++              PACK_2
++      },
++      {
++              APEX_INTERRUPT_TOP_LEVEL_3,
++              APEX_BAR2_REG_KERNEL_HIB_TOP_LEVEL_INTVECCTL,
++              PACK_3
++      },
++      {
++              APEX_INTERRUPT_FATAL_ERR,
++              APEX_BAR2_REG_KERNEL_HIB_FATAL_ERR_INTVECCTL,
++              UNPACKED
++      },
++};
++
++/* Allows device to enter power save upon driver close(). */
++static int allow_power_save = 1;
++
++/* Allows SW based clock gating. */
++static int allow_sw_clock_gating;
++
++/* Allows HW based clock gating. */
++/* Note: this is not mutual exclusive with SW clock gating. */
++static int allow_hw_clock_gating = 1;
++
++/* Act as if only GCB is instantiated. */
++static int bypass_top_level;
++
++module_param(allow_power_save, int, 0644);
++module_param(allow_sw_clock_gating, int, 0644);
++module_param(allow_hw_clock_gating, int, 0644);
++module_param(bypass_top_level, int, 0644);
++
++/* Temperature points in milli C at which DFS is toggled */
++#define DEFAULT_TRIP_POINT0_TEMP 85000
++#define DEFAULT_TRIP_POINT1_TEMP 90000
++#define DEFAULT_TRIP_POINT2_TEMP 95000
++
++static int trip_point0_temp = DEFAULT_TRIP_POINT0_TEMP;
++static int trip_point1_temp = DEFAULT_TRIP_POINT1_TEMP;
++static int trip_point2_temp = DEFAULT_TRIP_POINT2_TEMP;
++
++module_param(trip_point0_temp, int, 0644);
++module_param(trip_point1_temp, int, 0644);
++module_param(trip_point2_temp, int, 0644);
++
++/* Hardware monitored temperature trip points in milli C
++   Apex chip drives INTR line when reaching hw_temp_warn1 temperature,
++   and SD_ALARM line when reaching hw_temp_warn2 if corresponding
++   hw_temp_warn*_en is set to true.
++ */
++static int hw_temp_warn1 = 100000;
++static int hw_temp_warn2 = 100000;
++static bool hw_temp_warn1_en = false;
++static bool hw_temp_warn2_en = true;
++
++module_param(hw_temp_warn1, int, 0644);
++module_param(hw_temp_warn2, int, 0644);
++module_param(hw_temp_warn1_en, bool, 0644);
++module_param(hw_temp_warn2_en, bool, 0644);
++
++/* Temperature poll interval in ms */
++static int temp_poll_interval = DEFAULT_APEX_TEMP_POLL_INTERVAL;
++module_param(temp_poll_interval, int, 0644);
++
++/* Check the device status registers and return device status ALIVE or DEAD. */
++static int apex_get_status(struct gasket_dev *gasket_dev)
++{
++      /* TODO: Check device status. */
++      return GASKET_STATUS_ALIVE;
++}
++
++/* Enter GCB reset state. */
++static int apex_enter_reset(struct gasket_dev *gasket_dev)
++{
++      if (bypass_top_level)
++              return 0;
++
++      /*
++       * Software reset:
++       * Enable sleep mode
++       *  - Software force GCB idle
++       *    - Enable GCB idle
++       */
++      gasket_read_modify_write_64(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_IDLEGENERATOR_IDLEGEN_IDLEREGISTER,
++                                  0x0, 1, 32);
++
++      /*    - Initiate DMA pause */
++      gasket_dev_write_64(gasket_dev, 1, APEX_BAR_INDEX,
++                          APEX_BAR2_REG_USER_HIB_DMA_PAUSE);
++
++      /*    - Wait for DMA pause complete. */
++      if (gasket_wait_with_reschedule(gasket_dev, APEX_BAR_INDEX,
++                                      APEX_BAR2_REG_USER_HIB_DMA_PAUSED, 1, 1,
++                                      APEX_RESET_DELAY, APEX_RESET_RETRY)) {
++              dev_err(gasket_dev->dev,
++                      "DMAs did not quiesce within timeout (%d ms)\n",
++                      APEX_RESET_RETRY * APEX_RESET_DELAY);
++              return -ETIMEDOUT;
++      }
++
++      /*  - Enable GCB reset (0x1 to rg_rst_gcb) */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_2, 0x1, 2, 2);
++
++      /*  - Enable GCB clock Gate (0x1 to rg_gated_gcb) */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_2, 0x1, 2, 18);
++
++      /*  - Enable GCB memory shut down (0x3 to rg_force_ram_sd) */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_3, 0x3, 2, 14);
++
++      /*    - Wait for RAM shutdown. */
++      if (gasket_wait_with_reschedule(gasket_dev, APEX_BAR_INDEX,
++                                      APEX_BAR2_REG_SCU_3, 1 << 6, 1 << 6,
++                                      APEX_RESET_DELAY, APEX_RESET_RETRY)) {
++              dev_err(gasket_dev->dev,
++                      "RAM did not shut down within timeout (%d ms)\n",
++                      APEX_RESET_RETRY * APEX_RESET_DELAY);
++              return -ETIMEDOUT;
++      }
++
++      return 0;
++}
++
++/* Quit GCB reset state. */
++static int apex_quit_reset(struct gasket_dev *gasket_dev)
++{
++      u32 val0, val1;
++
++      if (bypass_top_level)
++              return 0;
++
++      /*
++       * Disable sleep mode:
++       *  - Disable GCB memory shut down:
++       *    - b00: Not forced (HW controlled)
++       *    - b1x: Force disable
++       */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_3, 0x0, 2, 14);
++
++      /*
++       *  - Disable software clock gate:
++       *    - b00: Not forced (HW controlled)
++       *    - b1x: Force disable
++       */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_2, 0x0, 2, 18);
++
++      /*
++       *  - Disable GCB reset (rg_rst_gcb):
++       *    - b00: Not forced (HW controlled)
++       *    - b1x: Force disable = Force not Reset
++       */
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_2, 0x2, 2, 2);
++
++      /*    - Wait for RAM enable. */
++      if (gasket_wait_with_reschedule(gasket_dev, APEX_BAR_INDEX,
++                                      APEX_BAR2_REG_SCU_3, 1 << 6, 0,
++                                      APEX_RESET_DELAY, APEX_RESET_RETRY)) {
++              dev_err(gasket_dev->dev,
++                      "RAM did not enable within timeout (%d ms)\n",
++                      APEX_RESET_RETRY * APEX_RESET_DELAY);
++              return -ETIMEDOUT;
++      }
++
++      /*    - Wait for Reset complete. */
++      if (gasket_wait_with_reschedule(gasket_dev, APEX_BAR_INDEX,
++                                      APEX_BAR2_REG_SCU_3,
++                                      SCU3_CUR_RST_GCB_BIT_MASK, 0,
++                                      APEX_RESET_DELAY, APEX_RESET_RETRY)) {
++              dev_err(gasket_dev->dev,
++                      "GCB did not leave reset within timeout (%d ms)\n",
++                      APEX_RESET_RETRY * APEX_RESET_DELAY);
++              return -ETIMEDOUT;
++      }
++
++      if (!allow_hw_clock_gating) {
++              val0 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                        APEX_BAR2_REG_SCU_3);
++              /* Inactive and Sleep mode are disabled. */
++              gasket_read_modify_write_32(gasket_dev,
++                                          APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_SCU_3, 0x3,
++                                          SCU3_RG_PWR_STATE_OVR_MASK_WIDTH,
++                                          SCU3_RG_PWR_STATE_OVR_BIT_OFFSET);
++              val1 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                        APEX_BAR2_REG_SCU_3);
++              dev_dbg(gasket_dev->dev,
++                      "Disallow HW clock gating 0x%x -> 0x%x\n", val0, val1);
++      } else {
++              val0 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                        APEX_BAR2_REG_SCU_3);
++              /* Inactive mode enabled - Sleep mode disabled. */
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_SCU_3, 2,
++                                          SCU3_RG_PWR_STATE_OVR_MASK_WIDTH,
++                                          SCU3_RG_PWR_STATE_OVR_BIT_OFFSET);
++              val1 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                        APEX_BAR2_REG_SCU_3);
++              dev_dbg(gasket_dev->dev, "Allow HW clock gating 0x%x -> 0x%x\n",
++                      val0, val1);
++      }
++
++      return 0;
++}
++
++/* Reset the Apex hardware. Called on final close via device_close_cb. */
++static int apex_device_cleanup(struct gasket_dev *gasket_dev)
++{
++      u64 scalar_error;
++      u64 hib_error;
++      int ret = 0;
++
++      hib_error = gasket_dev_read_64(gasket_dev, APEX_BAR_INDEX,
++                                     APEX_BAR2_REG_USER_HIB_ERROR_STATUS);
++      scalar_error = gasket_dev_read_64(gasket_dev, APEX_BAR_INDEX,
++                                        APEX_BAR2_REG_SCALAR_CORE_ERROR_STATUS);
++
++      dev_dbg(gasket_dev->dev,
++              "%s 0x%p hib_error 0x%llx scalar_error 0x%llx\n",
++              __func__, gasket_dev, hib_error, scalar_error);
++
++      if (allow_power_save)
++              ret = apex_enter_reset(gasket_dev);
++
++      return ret;
++}
++
++/* Determine if GCB is in reset state. */
++static bool is_gcb_in_reset(struct gasket_dev *gasket_dev)
++{
++      u32 val = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                   APEX_BAR2_REG_SCU_3);
++
++      /* Masks rg_rst_gcb bit of SCU_CTRL_2 */
++      return (val & SCU3_CUR_RST_GCB_BIT_MASK);
++}
++
++/* Reset the hardware, then quit reset.  Called on device open. */
++static int apex_reset(struct gasket_dev *gasket_dev)
++{
++      int ret;
++
++      if (bypass_top_level)
++              return 0;
++
++      if (!is_gcb_in_reset(gasket_dev)) {
++              /* We are not in reset - toggle the reset bit so as to force
++               * re-init of custom block
++               */
++              dev_dbg(gasket_dev->dev, "%s: toggle reset\n", __func__);
++
++              ret = apex_enter_reset(gasket_dev);
++              if (ret)
++                      return ret;
++      }
++      ret = apex_quit_reset(gasket_dev);
++
++      return ret;
++}
++
++/*
++ * Check permissions for Apex ioctls.
++ * Returns true if the current user may execute this ioctl, and false otherwise.
++ */
++static bool apex_ioctl_check_permissions(struct file *filp, uint cmd)
++{
++      return !!(filp->f_mode & FMODE_WRITE);
++}
++
++/* Gates or un-gates Apex clock. */
++static long apex_clock_gating(struct gasket_dev *gasket_dev,
++                            struct apex_gate_clock_ioctl __user *argp)
++{
++      struct apex_gate_clock_ioctl ibuf;
++
++      if (bypass_top_level || !allow_sw_clock_gating)
++              return 0;
++
++      if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
++              return -EFAULT;
++
++      dev_dbg(gasket_dev->dev, "%s %llu\n", __func__, ibuf.enable);
++
++      if (ibuf.enable) {
++              /* Quiesce AXI, gate GCB clock. */
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_AXI_QUIESCE, 0x1, 1,
++                                          16);
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_GCB_CLOCK_GATE, 0x1,
++                                          2, 18);
++      } else {
++              /* Un-gate GCB clock, un-quiesce AXI. */
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_GCB_CLOCK_GATE, 0x0,
++                                          2, 18);
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_AXI_QUIESCE, 0x0, 1,
++                                          16);
++      }
++      return 0;
++}
++
++/* apex_set_performance_expectation: Adjust clock rates for Apex. */
++static long apex_set_performance_expectation(
++      struct gasket_dev *gasket_dev,
++      struct apex_performance_expectation_ioctl __user *argp)
++{
++      struct apex_performance_expectation_ioctl ibuf;
++      uint32_t rg_gcb_clk_div = 0;
++      uint32_t rg_axi_clk_fixed = 0;
++      const int AXI_CLK_FIXED_SHIFT = 2;
++      const int MCU_CLK_FIXED_SHIFT = 3;
++
++      // 8051 clock is fixed for PCIe, as it's not used at all.
++      const uint32_t rg_8051_clk_fixed = 1;
++
++      if (bypass_top_level)
++              return 0;
++
++      if (copy_from_user(&ibuf, argp, sizeof(ibuf)))
++              return -EFAULT;
++
++      switch (ibuf.performance) {
++              case APEX_PERFORMANCE_LOW:
++                      rg_gcb_clk_div = 3;
++                      rg_axi_clk_fixed = 0;
++                      break;
++
++              case APEX_PERFORMANCE_MED:
++                      rg_gcb_clk_div = 2;
++                      rg_axi_clk_fixed = 0;
++                      break;
++
++              case APEX_PERFORMANCE_HIGH:
++                      rg_gcb_clk_div = 1;
++                      rg_axi_clk_fixed = 0;
++                      break;
++
++              case APEX_PERFORMANCE_MAX:
++                      rg_gcb_clk_div = 0;
++                      rg_axi_clk_fixed = 0;
++                      break;
++
++              default:
++                      return -EINVAL;
++      }
++
++      /*
++       * Set clock rates for GCB, AXI, and 8051:
++       */
++      gasket_read_modify_write_32(
++              gasket_dev, APEX_BAR_INDEX, APEX_BAR2_REG_SCU_3,
++                (rg_gcb_clk_div | (rg_axi_clk_fixed << AXI_CLK_FIXED_SHIFT) | (rg_8051_clk_fixed << MCU_CLK_FIXED_SHIFT)),
++                /*mask_width=*/4, /*mask_shift=*/28);
++
++      return 0;
++}
++
++/* Apex-specific ioctl handler. */
++static long apex_ioctl(struct file *filp, uint cmd, void __user *argp)
++{
++      struct gasket_dev *gasket_dev = filp->private_data;
++
++      if (!apex_ioctl_check_permissions(filp, cmd))
++              return -EPERM;
++
++      switch (cmd) {
++      case APEX_IOCTL_GATE_CLOCK:
++              return apex_clock_gating(gasket_dev, argp);
++      case APEX_IOCTL_PERFORMANCE_EXPECTATION:
++              return apex_set_performance_expectation(gasket_dev, argp);
++      default:
++              return -ENOTTY; /* unknown command */
++      }
++}
++
++/* Linear fit optimized for 25C-100C */
++static int adc_to_millic(int adc)
++{
++      return (662 - adc) * 250 + 550;
++}
++
++static int millic_to_adc(int millic)
++{
++      return (550 - millic) / 250 + 662;
++}
++
++/* Display driver sysfs entries. */
++static ssize_t sysfs_show(struct device *device, struct device_attribute *attr,
++                        char *buf)
++{
++      int ret;
++      unsigned value, value2, value3, value4;
++      struct gasket_dev *gasket_dev;
++      struct apex_dev *apex_dev;
++      struct gasket_sysfs_attribute *gasket_attr;
++      enum sysfs_attribute_type type;
++
++      gasket_dev = gasket_sysfs_get_device_data(device);
++      if (!gasket_dev) {
++              dev_err(device, "No Apex device sysfs mapping found\n");
++              return -ENODEV;
++      }
++
++      if (!gasket_dev->pci_dev ||
++          !(apex_dev = pci_get_drvdata(gasket_dev->pci_dev))) {
++              dev_err(device, "Can't find apex_dev data\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return -ENODEV;
++      }
++
++      gasket_attr = gasket_sysfs_get_attr(device, attr);
++      if (!gasket_attr) {
++              dev_err(device, "No Apex device sysfs attr data found\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return -ENODEV;
++      }
++
++      type = (enum sysfs_attribute_type)gasket_attr->data.attr_type;
++      switch (type) {
++      case ATTR_KERNEL_HIB_PAGE_TABLE_SIZE:
++              ret = scnprintf(buf, PAGE_SIZE, "%u\n",
++                              gasket_page_table_num_entries(
++                                      gasket_dev->page_table[0]));
++              break;
++      case ATTR_KERNEL_HIB_SIMPLE_PAGE_TABLE_SIZE:
++              ret = scnprintf(buf, PAGE_SIZE, "%u\n",
++                              gasket_page_table_num_entries(
++                                      gasket_dev->page_table[0]));
++              break;
++      case ATTR_KERNEL_HIB_NUM_ACTIVE_PAGES:
++              ret = scnprintf(buf, PAGE_SIZE, "%u\n",
++                              gasket_page_table_num_active_pages(
++                                      gasket_dev->page_table[0]));
++              break;
++      case ATTR_TEMP:
++              value = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                         APEX_BAR2_REG_OMC0_DC);
++              value = (value >> 16) & ((1 << 10) - 1);
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n", adc_to_millic(value));
++              break;
++      case ATTR_TEMP_WARN1:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              adc_to_millic(apex_dev->hw_temp_warn1_adc));
++              break;
++      case ATTR_TEMP_WARN2:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              adc_to_millic(apex_dev->hw_temp_warn2_adc));
++              break;
++      case ATTR_TEMP_WARN1_EN:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              apex_dev->hw_temp_warn1_en);
++              break;
++      case ATTR_TEMP_WARN2_EN:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              apex_dev->hw_temp_warn2_en);
++              break;
++      case ATTR_TEMP_TRIP0:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              adc_to_millic(apex_dev->adc_trip_points[0]));
++              break;
++      case ATTR_TEMP_TRIP1:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              adc_to_millic(apex_dev->adc_trip_points[1]));
++              break;
++      case ATTR_TEMP_TRIP2:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              adc_to_millic(apex_dev->adc_trip_points[2]));
++              break;
++      case ATTR_TEMP_POLL_INTERVAL:
++              ret = scnprintf(buf, PAGE_SIZE, "%i\n",
++                              atomic_read(&apex_dev->temp_poll_interval));
++              break;
++      case ATTR_UNIQUE_ID:
++              value = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                         APEX_BAR2_REG_EFUSE_DC);
++              value2 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_EFUSE_E0);
++              value3 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_EFUSE_E4);
++              value4 = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_EFUSE_E8);
++              ret = snprintf(buf, PAGE_SIZE, "%.8x%.8x%.8x%.8x\n", value4,
++                             value3, value2, value);
++              break;
++
++      default:
++              dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
++                      attr->attr.name);
++              ret = 0;
++              break;
++      }
++
++      gasket_sysfs_put_attr(device, gasket_attr);
++      gasket_sysfs_put_device_data(device, gasket_dev);
++      return ret;
++}
++
++/* Set driver sysfs entries. */
++static ssize_t sysfs_store(struct device *device, struct device_attribute *attr,
++                         const char *buf, size_t count)
++{
++      int ret = count, value;
++      struct gasket_dev *gasket_dev;
++      struct apex_dev *apex_dev;
++      struct gasket_sysfs_attribute *gasket_attr;
++      enum sysfs_attribute_type type;
++
++      if (kstrtoint(buf, 10, &value))
++              return -EINVAL;
++
++      gasket_dev = gasket_sysfs_get_device_data(device);
++      if (!gasket_dev) {
++              dev_err(device, "No Apex device sysfs mapping found\n");
++              return -ENODEV;
++      }
++
++      if (!gasket_dev->pci_dev ||
++          !(apex_dev = pci_get_drvdata(gasket_dev->pci_dev))) {
++              dev_err(device, "Can't find apex_dev data\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return -ENODEV;
++      }
++
++      gasket_attr = gasket_sysfs_get_attr(device, attr);
++      if (!gasket_attr) {
++              dev_err(device, "No Apex device sysfs attr data found\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return -ENODEV;
++      }
++
++      type = (enum sysfs_attribute_type)gasket_attr->data.attr_type;
++      switch (type) {
++      case ATTR_TEMP_WARN1:
++              value = millic_to_adc(value);
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D4, value, 10,
++                                          16);
++              apex_dev->hw_temp_warn1_adc = value;
++              break;
++      case ATTR_TEMP_WARN2:
++              value = millic_to_adc(value);
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D8, value, 10,
++                                          16);
++              apex_dev->hw_temp_warn2_adc = value;
++              break;
++      case ATTR_TEMP_WARN1_EN:
++              value = value > 0 ? 1 : 0;
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D4, value, 1,
++                                          31);
++              apex_dev->hw_temp_warn1_en = !!value;
++              break;
++      case ATTR_TEMP_WARN2_EN:
++              value = value > 0 ? 1 : 0;
++              gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D8, value, 1,
++                                          31);
++              apex_dev->hw_temp_warn2_en = !!value;
++              break;
++      case ATTR_TEMP_TRIP0:
++              value = millic_to_adc(value);
++              /* Note: that adc values should be in descending order */
++              if (value >= apex_dev->adc_trip_points[1]) {
++                      apex_dev->adc_trip_points[0] = value;
++              } else ret = -EINVAL;
++              break;
++      case ATTR_TEMP_TRIP1:
++              value = millic_to_adc(value);
++              if (value <= apex_dev->adc_trip_points[0] &&
++                  value >= apex_dev->adc_trip_points[2]) {
++                      apex_dev->adc_trip_points[1] = value;
++              } else ret = -EINVAL;
++              break;
++      case ATTR_TEMP_TRIP2:
++              value = millic_to_adc(value);
++              if (value <= apex_dev->adc_trip_points[1]) {
++                      apex_dev->adc_trip_points[2] = value;
++              } else ret = -EINVAL;
++              break;
++      case ATTR_TEMP_POLL_INTERVAL:
++              cancel_delayed_work_sync(&apex_dev->check_temperature_work);
++              atomic_set(&apex_dev->temp_poll_interval, value);
++              if (value > 0)
++                      schedule_delayed_work(&apex_dev->check_temperature_work,
++                                            msecs_to_jiffies(value));
++
++              break;
++      default:
++              dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
++                      attr->attr.name);
++              ret = 0;
++              break;
++      }
++
++      gasket_sysfs_put_attr(device, gasket_attr);
++      gasket_sysfs_put_device_data(device, gasket_dev);
++      return ret;
++}
++
++static struct gasket_sysfs_attribute apex_sysfs_attrs[] = {
++      GASKET_SYSFS_RO(node_0_page_table_entries, sysfs_show,
++                      ATTR_KERNEL_HIB_PAGE_TABLE_SIZE),
++      GASKET_SYSFS_RO(node_0_simple_page_table_entries, sysfs_show,
++                      ATTR_KERNEL_HIB_SIMPLE_PAGE_TABLE_SIZE),
++      GASKET_SYSFS_RO(node_0_num_mapped_pages, sysfs_show,
++                      ATTR_KERNEL_HIB_NUM_ACTIVE_PAGES),
++      GASKET_SYSFS_RO(temp, sysfs_show, ATTR_TEMP),
++      GASKET_SYSFS_RW(hw_temp_warn1, sysfs_show, sysfs_store,
++                      ATTR_TEMP_WARN1),
++      GASKET_SYSFS_RW(hw_temp_warn1_en, sysfs_show, sysfs_store,
++                      ATTR_TEMP_WARN1_EN),
++      GASKET_SYSFS_RW(hw_temp_warn2, sysfs_show, sysfs_store,
++                      ATTR_TEMP_WARN2),
++      GASKET_SYSFS_RW(hw_temp_warn2_en, sysfs_show, sysfs_store,
++                      ATTR_TEMP_WARN2_EN),
++      GASKET_SYSFS_RW(trip_point0_temp, sysfs_show, sysfs_store,
++                      ATTR_TEMP_TRIP0),
++      GASKET_SYSFS_RW(trip_point1_temp, sysfs_show, sysfs_store,
++                      ATTR_TEMP_TRIP1),
++      GASKET_SYSFS_RW(trip_point2_temp, sysfs_show, sysfs_store,
++                      ATTR_TEMP_TRIP2),
++      GASKET_SYSFS_RW(temp_poll_interval, sysfs_show, sysfs_store,
++                      ATTR_TEMP_POLL_INTERVAL),
++      GASKET_SYSFS_RO(unique_id, sysfs_show, ATTR_UNIQUE_ID),
++      GASKET_END_OF_ATTR_ARRAY
++};
++
++/* Stores kernel module parameters to device specific data buffer */
++static void apply_module_params(struct apex_dev *apex_dev) {
++      kernel_param_lock(THIS_MODULE);
++
++      /* use defaults if trip point temperatures are not in ascending order */
++      if (trip_point0_temp > trip_point1_temp ||
++          trip_point1_temp > trip_point2_temp) {
++              dev_warn(apex_dev->gasket_dev_ptr->dev,
++                       "Invalid module parameters for temperature trip points"
++                       ", using defaults\n");
++              trip_point0_temp = DEFAULT_TRIP_POINT0_TEMP;
++              trip_point1_temp = DEFAULT_TRIP_POINT1_TEMP;
++              trip_point2_temp = DEFAULT_TRIP_POINT2_TEMP;
++      }
++
++      apex_dev->adc_trip_points[0] = millic_to_adc(trip_point0_temp);
++      apex_dev->adc_trip_points[1] = millic_to_adc(trip_point1_temp);
++      apex_dev->adc_trip_points[2] = millic_to_adc(trip_point2_temp);
++      atomic_set(&apex_dev->temp_poll_interval, temp_poll_interval);
++
++      apex_dev->hw_temp_warn1_adc = millic_to_adc(hw_temp_warn1);
++      apex_dev->hw_temp_warn2_adc = millic_to_adc(hw_temp_warn2);
++      apex_dev->hw_temp_warn1_en = hw_temp_warn1_en;
++      apex_dev->hw_temp_warn2_en = hw_temp_warn2_en;
++
++      kernel_param_unlock(THIS_MODULE);
++}
++
++/* Applies hw temp warning settings to device */
++static void program_hw_temp_warnings(struct apex_dev *apex_dev) {
++      gasket_read_modify_write_32(apex_dev->gasket_dev_ptr, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_OMC0_D4,
++                                  apex_dev->hw_temp_warn1_adc, 10, 16);
++      gasket_read_modify_write_32(apex_dev->gasket_dev_ptr, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_OMC0_D8,
++                                  apex_dev->hw_temp_warn2_adc, 10, 16);
++      if (apex_dev->hw_temp_warn1_en)
++              gasket_read_modify_write_32(apex_dev->gasket_dev_ptr,
++                                          APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D4, 1, 1, 31);
++
++      if (apex_dev->hw_temp_warn2_en)
++              gasket_read_modify_write_32(apex_dev->gasket_dev_ptr,
++                                          APEX_BAR_INDEX,
++                                          APEX_BAR2_REG_OMC0_D8, 1, 1, 31);
++}
++
++static void enable_thermal_sensing(struct gasket_dev *gasket_dev) {
++      // Enable thermal sensor clocks
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_OMC0_D0, 0x1, 1, 7);
++
++      // Enable thermal sensor (ENAD ENVR ENBG)
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_OMC0_D8, 0x7, 3, 0);
++
++      // Enable OMC thermal sensor controller
++      // This bit should be asserted 100 us after ENAD ENVR ENBG
++      schedule_timeout(usecs_to_jiffies(100));
++      gasket_read_modify_write_32(gasket_dev, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_OMC0_DC, 0x1, 1, 0);
++}
++
++static void check_temperature_work_handler(struct work_struct *work) {
++      int i, temp_poll_interval;
++      u32 adc_temp, clk_div, tmp;
++      const u32 mask = ((1 << 2) - 1) << 28;
++      struct apex_dev *apex_dev =
++              container_of(work, struct apex_dev,
++                           check_temperature_work.work);
++      struct gasket_dev *gasket_dev = apex_dev->gasket_dev_ptr;
++
++      mutex_lock(&gasket_dev->mutex);
++
++      /* Read current temperature */
++      adc_temp = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                                    APEX_BAR2_REG_OMC0_DC);
++      adc_temp = (adc_temp >> 16) & ((1 << 10) - 1);
++
++      /* Find closest trip point
++         Note: that adc values are in descending order */
++      for (i = ARRAY_SIZE(apex_dev->adc_trip_points) - 1; i >= 0; --i) {
++              if (adc_temp <= apex_dev->adc_trip_points[i])
++                      break;
++      }
++      /* Compute divider value and shift into appropriate bit location */
++      clk_div = (i + 1) << 28;
++
++      /* Modify gcb clk divider if it's different from current one */
++      tmp = gasket_dev_read_32(gasket_dev, APEX_BAR_INDEX,
++                               APEX_BAR2_REG_SCU_3);
++      if (clk_div != (tmp & mask)) {
++              tmp = (tmp & ~mask) | clk_div;
++              gasket_dev_write_32(gasket_dev, tmp, APEX_BAR_INDEX,
++                                  APEX_BAR2_REG_SCU_3);
++              dev_warn(gasket_dev->dev,
++                       "Apex performance %sthrottled due to temperature\n",
++                       i == -1 ? "not " : "");
++      }
++
++      mutex_unlock(&gasket_dev->mutex);
++
++      temp_poll_interval = atomic_read(&apex_dev->temp_poll_interval);
++      if (temp_poll_interval > 0)
++              schedule_delayed_work(&apex_dev->check_temperature_work,
++                                    msecs_to_jiffies(temp_poll_interval));
++}
++
++/* On device open, perform a core reinit reset. */
++static int apex_device_open_cb(struct gasket_dev *gasket_dev)
++{
++      return gasket_reset_nolock(gasket_dev);
++}
++
++static const struct pci_device_id apex_pci_ids[] = {
++      { PCI_DEVICE(APEX_PCI_VENDOR_ID, APEX_PCI_DEVICE_ID) }, { 0 }
++};
++
++static void apex_pci_fixup_class(struct pci_dev *pdev)
++{
++      pdev->class = (PCI_CLASS_SYSTEM_OTHER << 8) | pdev->class;
++}
++DECLARE_PCI_FIXUP_CLASS_HEADER(APEX_PCI_VENDOR_ID, APEX_PCI_DEVICE_ID,
++                             PCI_ANY_ID, 8, apex_pci_fixup_class);
++
++static int apex_pci_probe(struct pci_dev *pci_dev,
++                        const struct pci_device_id *id)
++{
++      int ret, temp_poll_interval;
++      ulong page_table_ready, msix_table_ready;
++      int retries = 0;
++      struct gasket_dev *gasket_dev;
++      struct apex_dev *apex_dev;
++
++      ret = pci_enable_device(pci_dev);
++#ifdef MODULE
++      if (ret) {
++              apex_pci_fixup_class(pci_dev);
++              pci_bus_assign_resources(pci_dev->bus);
++              ret = pci_enable_device(pci_dev);
++      }
++#endif
++      if (ret) {
++              dev_err(&pci_dev->dev, "error enabling PCI device\n");
++              return ret;
++      }
++
++      pci_set_master(pci_dev);
++
++      ret = gasket_pci_add_device(pci_dev, &gasket_dev);
++      if (ret) {
++              dev_err(&pci_dev->dev, "error adding gasket device\n");
++              pci_disable_device(pci_dev);
++              return ret;
++      }
++
++      apex_dev = kzalloc(sizeof(*apex_dev), GFP_KERNEL);
++      if (!apex_dev) {
++              dev_err(&pci_dev->dev, "no memory for device\n");
++              ret = -ENOMEM;
++              goto remove_device;
++      }
++
++      INIT_DELAYED_WORK(&apex_dev->check_temperature_work,
++                        check_temperature_work_handler);
++      apex_dev->gasket_dev_ptr = gasket_dev;
++      apply_module_params(apex_dev);
++      program_hw_temp_warnings(apex_dev);
++      pci_set_drvdata(pci_dev, apex_dev);
++      apex_reset(gasket_dev);
++
++      while (retries < APEX_RESET_RETRY) {
++              page_table_ready =
++                      gasket_dev_read_64(gasket_dev, APEX_BAR_INDEX,
++                                         APEX_BAR2_REG_KERNEL_HIB_PAGE_TABLE_INIT);
++              msix_table_ready =
++                      gasket_dev_read_64(gasket_dev, APEX_BAR_INDEX,
++                                         APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE_INIT);
++              if (page_table_ready && msix_table_ready)
++                      break;
++              schedule_timeout(msecs_to_jiffies(APEX_RESET_DELAY));
++              retries++;
++      }
++
++      if (retries == APEX_RESET_RETRY) {
++              if (!page_table_ready)
++                      dev_err(gasket_dev->dev, "Page table init timed out\n");
++              if (!msix_table_ready)
++                      dev_err(gasket_dev->dev, "MSI-X table init timed out\n");
++              ret = -ETIMEDOUT;
++              goto remove_device;
++      }
++
++      enable_thermal_sensing(gasket_dev);
++
++      ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device,
++                                        apex_sysfs_attrs);
++      if (ret)
++              dev_err(&pci_dev->dev, "error creating device sysfs entries\n");
++
++      ret = gasket_enable_device(gasket_dev);
++      if (ret) {
++              dev_err(&pci_dev->dev, "error enabling gasket device\n");
++              goto remove_device;
++      }
++
++      /* Place device in low power mode until opened */
++      if (allow_power_save)
++              apex_enter_reset(gasket_dev);
++
++      /* Enable thermal polling */
++      temp_poll_interval = atomic_read(&apex_dev->temp_poll_interval);
++      if (temp_poll_interval > 0)
++              schedule_delayed_work(&apex_dev->check_temperature_work,
++                                    msecs_to_jiffies(temp_poll_interval));
++      return 0;
++
++remove_device:
++      gasket_pci_remove_device(pci_dev);
++      pci_disable_device(pci_dev);
++      kfree(apex_dev);
++      return ret;
++}
++
++static void apex_pci_remove(struct pci_dev *pci_dev)
++{
++      struct apex_dev *apex_dev = pci_get_drvdata(pci_dev);
++      struct gasket_dev *gasket_dev;
++
++      if (!apex_dev) {
++              dev_err(&pci_dev->dev, "NULL apex_dev\n");
++              goto remove_device;
++      }
++      gasket_dev = apex_dev->gasket_dev_ptr;
++
++      cancel_delayed_work_sync(&apex_dev->check_temperature_work);
++      kfree(apex_dev);
++
++      gasket_disable_device(gasket_dev);
++remove_device:
++      gasket_pci_remove_device(pci_dev);
++      pci_disable_device(pci_dev);
++}
++
++static int apex_pci_suspend(struct pci_dev *pci_dev, pm_message_t state) {
++      struct apex_dev *apex_dev = pci_get_drvdata(pci_dev);
++      struct gasket_dev *gasket_dev;
++
++      if (!apex_dev) {
++              dev_err_once(&pci_dev->dev, "NULL apex_dev\n");
++              return -ENODEV;
++      }
++
++      // Tear down MSI-x interrupts before suspending.
++      gasket_dev = apex_dev->gasket_dev_ptr;
++      gasket_interrupt_msix_cleanup(gasket_dev->interrupt_data);
++      return 0;
++}
++
++static int apex_pci_resume(struct pci_dev *pci_dev)
++{
++      struct apex_dev *apex_dev = pci_get_drvdata(pci_dev);
++      struct gasket_dev *gasket_dev;
++
++      if (!apex_dev) {
++              dev_err_once(&pci_dev->dev, "NULL apex_dev\n");
++              return -ENODEV;
++      }
++      gasket_dev = apex_dev->gasket_dev_ptr;
++
++      gasket_interrupt_reinit(gasket_dev);
++      apex_reset(gasket_dev);
++      program_hw_temp_warnings(apex_dev);
++      enable_thermal_sensing(gasket_dev);
++
++      /* Place device in low power mode until opened */
++      if (allow_power_save)
++              apex_enter_reset(gasket_dev);
++
++      return 0;
++}
++
++static struct gasket_driver_desc apex_desc = {
++      .name = "apex",
++      .driver_version = APEX_DRIVER_VERSION,
++      .major = 120,
++      .minor = 0,
++      .module = THIS_MODULE,
++      .pci_id_table = apex_pci_ids,
++
++      .num_page_tables = NUM_NODES,
++      .page_table_bar_index = APEX_BAR_INDEX,
++      .page_table_configs = apex_page_table_configs,
++      .page_table_extended_bit = APEX_EXTENDED_SHIFT,
++
++      .bar_descriptions = {
++              GASKET_UNUSED_BAR,
++              GASKET_UNUSED_BAR,
++              { APEX_BAR_BYTES, (VM_WRITE | VM_READ), APEX_BAR_OFFSET,
++                      NUM_REGIONS, mappable_regions, PCI_BAR },
++              GASKET_UNUSED_BAR,
++              GASKET_UNUSED_BAR,
++              GASKET_UNUSED_BAR,
++      },
++      .coherent_buffer_description = {
++              APEX_CH_MEM_BYTES,
++              (VM_WRITE | VM_READ),
++              APEX_CM_OFFSET,
++      },
++      .interrupt_type = PCI_MSIX,
++      .interrupt_bar_index = APEX_BAR_INDEX,
++      .num_interrupts = APEX_INTERRUPT_COUNT,
++      .interrupts = apex_interrupts,
++      .interrupt_pack_width = 7,
++
++      .device_open_cb = apex_device_open_cb,
++      .device_close_cb = apex_device_cleanup,
++
++      .ioctl_handler_cb = apex_ioctl,
++      .device_status_cb = apex_get_status,
++      .hardware_revision_cb = NULL,
++      .device_reset_cb = apex_reset,
++};
++
++static struct pci_driver apex_pci_driver = {
++      .name = "apex",
++      .probe = apex_pci_probe,
++      .remove = apex_pci_remove,
++#ifdef CONFIG_PM_SLEEP
++      .suspend = apex_pci_suspend,
++      .resume = apex_pci_resume,
++#endif
++      .id_table = apex_pci_ids,
++};
++
++static int __init apex_init(void)
++{
++      int ret;
++
++      ret = gasket_register_device(&apex_desc);
++      if (ret)
++              return ret;
++      ret = pci_register_driver(&apex_pci_driver);
++      if (ret)
++              gasket_unregister_device(&apex_desc);
++      return ret;
++}
++
++static void apex_exit(void)
++{
++      pci_unregister_driver(&apex_pci_driver);
++      gasket_unregister_device(&apex_desc);
++}
++MODULE_DESCRIPTION("Google Apex driver");
++MODULE_VERSION(APEX_DRIVER_VERSION);
++MODULE_LICENSE("GPL v2");
++MODULE_AUTHOR("John Joseph <jnjoseph@google.com>");
++MODULE_DEVICE_TABLE(pci, apex_pci_ids);
++module_init(apex_init);
++module_exit(apex_exit);
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/apex.h b/drivers/staging/gasket-driver/apex.h
+--- a/drivers/staging/gasket-driver/apex.h     1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/apex.h     2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,45 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Apex kernel-userspace interface definitions.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++#ifndef __APEX_H__
++#define __APEX_H__
++
++#include <linux/ioctl.h>
++
++/* Clock Gating ioctl. */
++struct apex_gate_clock_ioctl {
++      /* Enter or leave clock gated state. */
++      u64 enable;
++
++      /* If set, enter clock gating state, regardless of custom block's
++       * internal idle state
++       */
++      u64 force_idle;
++};
++
++/* Performance expectation ioctl. */
++enum apex_performance_expectation {
++        APEX_PERFORMANCE_LOW = 0,
++        APEX_PERFORMANCE_MED = 1,
++        APEX_PERFORMANCE_HIGH = 2,
++        APEX_PERFORMANCE_MAX = 3,
++};
++
++struct apex_performance_expectation_ioctl {
++        /* Expected performance from apex. */
++        uint32_t performance;
++};
++
++/* Base number for all Apex-common IOCTLs */
++#define APEX_IOCTL_BASE 0x7F
++
++/* Enable/Disable clock gating. */
++#define APEX_IOCTL_GATE_CLOCK                                                  \
++      _IOW(APEX_IOCTL_BASE, 0, struct apex_gate_clock_ioctl)
++
++#define APEX_IOCTL_PERFORMANCE_EXPECTATION _IOW(APEX_IOCTL_BASE, 1, struct apex_performance_expectation_ioctl)
++
++#endif /* __APEX_H__ */
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_constants.h b/drivers/staging/gasket-driver/gasket_constants.h
+--- a/drivers/staging/gasket-driver/gasket_constants.h 1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_constants.h 2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,47 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/* Copyright (C) 2018 Google, Inc. */
++#ifndef __GASKET_CONSTANTS_H__
++#define __GASKET_CONSTANTS_H__
++
++#define GASKET_FRAMEWORK_VERSION "1.1.4"
++
++/*
++ * The maximum number of simultaneous device types supported by the framework.
++ */
++#define GASKET_FRAMEWORK_DESC_MAX 2
++
++/* The maximum devices per each type. */
++#define GASKET_DEV_MAX 256
++
++/* The number of supported (and possible) PCI BARs. */
++#define GASKET_NUM_BARS 6
++
++/* The number of supported Gasket page tables per device. */
++#define GASKET_MAX_NUM_PAGE_TABLES 1
++
++/* Maximum length of device names (driver name + minor number suffix + NULL). */
++#define GASKET_NAME_MAX 32
++
++/* Device status enumeration. */
++enum gasket_status {
++      /*
++       * A device is DEAD if it has not been initialized or has had an error.
++       */
++      GASKET_STATUS_DEAD = 0,
++      /*
++       * A device is LAMED if the hardware is healthy but the kernel was
++       * unable to enable some functionality (e.g. interrupts).
++       */
++      GASKET_STATUS_LAMED,
++
++      /* A device is ALIVE if it is ready for operation. */
++      GASKET_STATUS_ALIVE,
++
++      /*
++       * This status is set when the driver is exiting and waiting for all
++       * handles to be closed.
++       */
++      GASKET_STATUS_DRIVER_EXIT,
++};
++
++#endif
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_core.c b/drivers/staging/gasket-driver/gasket_core.c
+--- a/drivers/staging/gasket-driver/gasket_core.c      1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_core.c      2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,1936 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Gasket generic driver framework. This file contains the implementation
++ * for the Gasket generic driver framework - the functionality that is common
++ * across Gasket devices.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include "gasket_core.h"
++
++#include "gasket_interrupt.h"
++#include "gasket_ioctl.h"
++#include "gasket_page_table.h"
++#include "gasket_sysfs.h"
++
++#include <linux/capability.h>
++#include <linux/compiler.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/of.h>
++#include <linux/pid_namespace.h>
++#include <linux/platform_device.h>
++#include <linux/printk.h>
++#include <linux/sched.h>
++#include <linux/version.h>
++
++#ifdef GASKET_KERNEL_TRACE_SUPPORT
++#define CREATE_TRACE_POINTS
++#include <trace/events/gasket_mmap.h>
++#else
++#define trace_gasket_mmap_exit(x)
++#define trace_gasket_mmap_entry(x, ...)
++#endif
++
++/*
++ * "Private" members of gasket_driver_desc.
++ *
++ * Contains internal per-device type tracking data, i.e., data not appropriate
++ * as part of the public interface for the generic framework.
++ */
++struct gasket_internal_desc {
++      /* Device-specific-driver-provided configuration information. */
++      const struct gasket_driver_desc *driver_desc;
++
++      /* Protects access to per-driver data (i.e. this structure). */
++      struct mutex mutex;
++
++      /* Kernel-internal device class. */
++      struct class *class;
++
++      /* Instantiated / present devices of this type. */
++      struct gasket_dev *devs[GASKET_DEV_MAX];
++};
++
++/* do_map_region() needs be able to return more than just true/false. */
++enum do_map_region_status {
++      /* The region was successfully mapped. */
++      DO_MAP_REGION_SUCCESS,
++
++      /* Attempted to map region and failed. */
++      DO_MAP_REGION_FAILURE,
++
++      /* The requested region to map was not part of a mappable region. */
++      DO_MAP_REGION_INVALID,
++};
++
++/* Global data definitions. */
++/* Mutex - only for framework-wide data. Other data should be protected by
++ * finer-grained locks.
++ */
++static DEFINE_MUTEX(g_mutex);
++
++/* List of all registered device descriptions & their supporting data. */
++static struct gasket_internal_desc g_descs[GASKET_FRAMEWORK_DESC_MAX];
++
++/* Mapping of statuses to human-readable strings. Must end with {0,NULL}. */
++static const struct gasket_num_name gasket_status_name_table[] = {
++      { GASKET_STATUS_DEAD, "DEAD" },
++      { GASKET_STATUS_ALIVE, "ALIVE" },
++      { GASKET_STATUS_LAMED, "LAMED" },
++      { GASKET_STATUS_DRIVER_EXIT, "DRIVER_EXITING" },
++      { 0, NULL },
++};
++
++/* Enumeration of the automatic Gasket framework sysfs nodes. */
++enum gasket_sysfs_attribute_type {
++      ATTR_BAR_OFFSETS,
++      ATTR_BAR_SIZES,
++      ATTR_DRIVER_VERSION,
++      ATTR_FRAMEWORK_VERSION,
++      ATTR_DEVICE_TYPE,
++      ATTR_HARDWARE_REVISION,
++      ATTR_PCI_ADDRESS,
++      ATTR_STATUS,
++      ATTR_IS_DEVICE_OWNED,
++      ATTR_DEVICE_OWNER,
++      ATTR_WRITE_OPEN_COUNT,
++      ATTR_RESET_COUNT,
++      ATTR_USER_MEM_RANGES
++};
++
++/* On some arm64 systems pcie dma controller can only access lower 4GB of
++ * addresses. Unfortunately vendor BSP isn't providing any means of determining
++ * this limitation and there're no errors reported if access to higher addresses
++ * if being done. This parameter allows to workaround this issue by pretending
++ * that our device only supports 32 bit addresses. This in turn will cause
++ * dma driver to use shadow buffers located in low 32 bit address space.
++ */
++static int dma_bit_mask = 64;
++module_param(dma_bit_mask, int, 0644);
++
++/* Perform a standard Gasket callback. */
++static inline int
++check_and_invoke_callback(struct gasket_dev *gasket_dev,
++                        int (*cb_function)(struct gasket_dev *))
++{
++      int ret = 0;
++
++      if (cb_function) {
++              mutex_lock(&gasket_dev->mutex);
++              ret = cb_function(gasket_dev);
++              mutex_unlock(&gasket_dev->mutex);
++      }
++      return ret;
++}
++
++/* Perform a standard Gasket callback without grabbing gasket_dev->mutex. */
++static inline int
++gasket_check_and_invoke_callback_nolock(struct gasket_dev *gasket_dev,
++                                      int (*cb_function)(struct gasket_dev *))
++{
++      int ret = 0;
++
++      if (cb_function)
++              ret = cb_function(gasket_dev);
++      return ret;
++}
++
++/*
++ * Return nonzero if the gasket_cdev_info is owned by the current thread group
++ * ID.
++ */
++static int gasket_owned_by_current_tgid(struct gasket_cdev_info *info)
++{
++      return (info->ownership.is_owned &&
++              (info->ownership.owner == current->tgid));
++}
++
++/*
++ * Find the next free gasket_internal_dev slot.
++ *
++ * Returns the located slot number on success or a negative number on failure.
++ */
++static int gasket_find_dev_slot(struct gasket_internal_desc *internal_desc,
++                              const char *kobj_name)
++{
++      int i;
++
++      mutex_lock(&internal_desc->mutex);
++
++      /* Search for a previous instance of this device. */
++      for (i = 0; i < GASKET_DEV_MAX; i++) {
++              if (internal_desc->devs[i] &&
++                  strcmp(internal_desc->devs[i]->kobj_name, kobj_name) == 0) {
++                      pr_err("Duplicate device %s\n", kobj_name);
++                      mutex_unlock(&internal_desc->mutex);
++                      return -EBUSY;
++              }
++      }
++
++      /* Find a free device slot. */
++      for (i = 0; i < GASKET_DEV_MAX; i++) {
++              if (!internal_desc->devs[i])
++                      break;
++      }
++
++      if (i == GASKET_DEV_MAX) {
++              pr_err("Too many registered devices; max %d\n", GASKET_DEV_MAX);
++              mutex_unlock(&internal_desc->mutex);
++              return -EBUSY;
++      }
++
++      mutex_unlock(&internal_desc->mutex);
++      return i;
++}
++
++/*
++ * Allocate and initialize a Gasket device structure, add the device to the
++ * device list.
++ *
++ * Returns 0 if successful, a negative error code otherwise.
++ */
++static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc,
++                          struct device *parent, struct gasket_dev **pdev)
++{
++      int dev_idx;
++      const struct gasket_driver_desc *driver_desc =
++              internal_desc->driver_desc;
++      struct gasket_dev *gasket_dev;
++      struct gasket_cdev_info *dev_info;
++      const char *parent_name = dev_name(parent);
++
++      pr_debug("Allocating a Gasket device, parent %s.\n", parent_name);
++
++      *pdev = NULL;
++
++      dev_idx = gasket_find_dev_slot(internal_desc, parent_name);
++      if (dev_idx < 0)
++              return dev_idx;
++
++      gasket_dev = *pdev = kzalloc(sizeof(*gasket_dev), GFP_KERNEL);
++      if (!gasket_dev) {
++              pr_err("no memory for device, parent %s\n", parent_name);
++              return -ENOMEM;
++      }
++      internal_desc->devs[dev_idx] = gasket_dev;
++
++      mutex_init(&gasket_dev->mutex);
++
++      gasket_dev->internal_desc = internal_desc;
++      gasket_dev->dev_idx = dev_idx;
++      snprintf(gasket_dev->kobj_name, GASKET_NAME_MAX, "%s", parent_name);
++      gasket_dev->dev = get_device(parent);
++      gasket_dev->dma_dev = get_device(parent);
++      /* gasket_bar_data is uninitialized. */
++      gasket_dev->num_page_tables = driver_desc->num_page_tables;
++      /* max_page_table_size and *page table are uninit'ed */
++      /* interrupt_data is not initialized. */
++      /* status is 0, or GASKET_STATUS_DEAD */
++
++      dev_info = &gasket_dev->dev_info;
++      snprintf(dev_info->name, GASKET_NAME_MAX, "%s_%u", driver_desc->name,
++               gasket_dev->dev_idx);
++      dev_info->devt =
++              MKDEV(driver_desc->major, driver_desc->minor +
++                    gasket_dev->dev_idx);
++      dev_info->device =
++              device_create(internal_desc->class, parent, dev_info->devt,
++                            gasket_dev, dev_info->name);
++
++      /* cdev has not yet been added; cdev_added is 0 */
++      dev_info->gasket_dev_ptr = gasket_dev;
++      /* ownership is all 0, indicating no owner or opens. */
++
++      return 0;
++}
++
++/* Free a Gasket device. */
++static void gasket_free_dev(struct gasket_dev *gasket_dev)
++{
++      struct gasket_internal_desc *internal_desc = gasket_dev->internal_desc;
++
++      mutex_lock(&internal_desc->mutex);
++      internal_desc->devs[gasket_dev->dev_idx] = NULL;
++      mutex_unlock(&internal_desc->mutex);
++      put_device(gasket_dev->dev);
++      put_device(gasket_dev->dma_dev);
++      kfree(gasket_dev);
++}
++
++/*
++ * Maps the specified bar into kernel space.
++ *
++ * Returns 0 on success, a negative error code otherwise.
++ * A zero-sized BAR will not be mapped, but is not an error.
++ */
++static int gasket_map_pci_bar(struct gasket_dev *gasket_dev, int bar_num)
++{
++      struct gasket_internal_desc *internal_desc = gasket_dev->internal_desc;
++      const struct gasket_driver_desc *driver_desc =
++              internal_desc->driver_desc;
++      ulong desc_bytes = driver_desc->bar_descriptions[bar_num].size;
++      int ret;
++
++      if (desc_bytes == 0)
++              return 0;
++
++      if (driver_desc->bar_descriptions[bar_num].type != PCI_BAR) {
++              /* not PCI: skip this entry */
++              return 0;
++      }
++      /*
++       * pci_resource_start and pci_resource_len return a "resource_size_t",
++       * which is safely castable to ulong (which itself is the arg to
++       * request_mem_region).
++       */
++      gasket_dev->bar_data[bar_num].phys_base =
++              (ulong)pci_resource_start(gasket_dev->pci_dev, bar_num);
++      if (!gasket_dev->bar_data[bar_num].phys_base) {
++              dev_err(gasket_dev->dev, "Cannot get BAR%u base address\n",
++                      bar_num);
++              return -EINVAL;
++      }
++
++      gasket_dev->bar_data[bar_num].length_bytes =
++              (ulong)pci_resource_len(gasket_dev->pci_dev, bar_num);
++      if (gasket_dev->bar_data[bar_num].length_bytes < desc_bytes) {
++              dev_err(gasket_dev->dev,
++                      "PCI BAR %u space is too small: %lu; expected >= %lu\n",
++                      bar_num, gasket_dev->bar_data[bar_num].length_bytes,
++                      desc_bytes);
++              return -ENOMEM;
++      }
++
++      if (!request_mem_region(gasket_dev->bar_data[bar_num].phys_base,
++                              gasket_dev->bar_data[bar_num].length_bytes,
++                              gasket_dev->dev_info.name)) {
++              dev_err(gasket_dev->dev,
++                      "Cannot get BAR %d memory region %p\n",
++                      bar_num, &gasket_dev->pci_dev->resource[bar_num]);
++              return -EINVAL;
++      }
++
++      gasket_dev->bar_data[bar_num].virt_base =
++              ioremap(gasket_dev->bar_data[bar_num].phys_base,
++                      gasket_dev->bar_data[bar_num].length_bytes);
++      if (!gasket_dev->bar_data[bar_num].virt_base) {
++              dev_err(gasket_dev->dev,
++                      "Cannot remap BAR %d memory region %p\n",
++                      bar_num, &gasket_dev->pci_dev->resource[bar_num]);
++              ret = -ENOMEM;
++              goto fail;
++      }
++
++      dma_set_mask(&gasket_dev->pci_dev->dev, DMA_BIT_MASK(dma_bit_mask));
++      dma_set_coherent_mask(&gasket_dev->pci_dev->dev,
++                            DMA_BIT_MASK(dma_bit_mask));
++
++      return 0;
++
++fail:
++      iounmap(gasket_dev->bar_data[bar_num].virt_base);
++      release_mem_region(gasket_dev->bar_data[bar_num].phys_base,
++                         gasket_dev->bar_data[bar_num].length_bytes);
++      return ret;
++}
++
++/*
++ * Releases PCI BAR mapping.
++ *
++ * A zero-sized or not-mapped BAR will not be unmapped, but is not an error.
++ */
++static void gasket_unmap_pci_bar(struct gasket_dev *dev, int bar_num)
++{
++      ulong base, bytes;
++      struct gasket_internal_desc *internal_desc = dev->internal_desc;
++      const struct gasket_driver_desc *driver_desc =
++              internal_desc->driver_desc;
++
++      if (driver_desc->bar_descriptions[bar_num].size == 0 ||
++          !dev->bar_data[bar_num].virt_base)
++              return;
++
++      if (driver_desc->bar_descriptions[bar_num].type != PCI_BAR)
++              return;
++
++      iounmap(dev->bar_data[bar_num].virt_base);
++      dev->bar_data[bar_num].virt_base = NULL;
++
++      base = pci_resource_start(dev->pci_dev, bar_num);
++      if (!base) {
++              dev_err(dev->dev, "cannot get PCI BAR%u base address\n",
++                      bar_num);
++              return;
++      }
++
++      bytes = pci_resource_len(dev->pci_dev, bar_num);
++      release_mem_region(base, bytes);
++}
++
++/*
++ * Setup PCI memory mapping for the specified device.
++ *
++ * Reads the BAR registers and sets up pointers to the device's memory mapped
++ * IO space.
++ *
++ * Returns 0 on success and a negative value otherwise.
++ */
++static int gasket_setup_pci(struct pci_dev *pci_dev,
++                          struct gasket_dev *gasket_dev)
++{
++      int i, mapped_bars, ret;
++
++      for (i = 0; i < GASKET_NUM_BARS; i++) {
++              ret = gasket_map_pci_bar(gasket_dev, i);
++              if (ret) {
++                      mapped_bars = i;
++                      goto fail;
++              }
++      }
++
++      return 0;
++
++fail:
++      for (i = 0; i < mapped_bars; i++)
++              gasket_unmap_pci_bar(gasket_dev, i);
++
++      return -ENOMEM;
++}
++
++/* Unmaps memory for the specified device. */
++static void gasket_cleanup_pci(struct gasket_dev *gasket_dev)
++{
++      int i;
++
++      for (i = 0; i < GASKET_NUM_BARS; i++)
++              gasket_unmap_pci_bar(gasket_dev, i);
++}
++
++/* Determine the health of the Gasket device. */
++static int gasket_get_hw_status(struct gasket_dev *gasket_dev)
++{
++      int status;
++      int i;
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++
++      status = gasket_check_and_invoke_callback_nolock(gasket_dev,
++                                                       driver_desc->device_status_cb);
++      if (status != GASKET_STATUS_ALIVE) {
++              dev_dbg(gasket_dev->dev, "Hardware reported status %d.\n",
++                      status);
++              return status;
++      }
++
++      status = gasket_interrupt_system_status(gasket_dev);
++      if (status != GASKET_STATUS_ALIVE) {
++              dev_dbg(gasket_dev->dev,
++                      "Interrupt system reported status %d.\n", status);
++              return status;
++      }
++
++      for (i = 0; i < driver_desc->num_page_tables; ++i) {
++              status = gasket_page_table_system_status(gasket_dev->page_table[i]);
++              if (status != GASKET_STATUS_ALIVE) {
++                      dev_dbg(gasket_dev->dev,
++                              "Page table %d reported status %d.\n",
++                              i, status);
++                      return status;
++              }
++      }
++
++      return GASKET_STATUS_ALIVE;
++}
++
++static ssize_t
++gasket_write_mappable_regions(char *buf,
++                            const struct gasket_driver_desc *driver_desc,
++                            int bar_index)
++{
++      int i;
++      ssize_t written;
++      ssize_t total_written = 0;
++      ulong min_addr, max_addr;
++      struct gasket_bar_desc bar_desc =
++              driver_desc->bar_descriptions[bar_index];
++
++      if (bar_desc.permissions == GASKET_NOMAP)
++              return 0;
++      for (i = 0;
++           i < bar_desc.num_mappable_regions && total_written < PAGE_SIZE;
++           i++) {
++              min_addr = bar_desc.mappable_regions[i].start -
++                         driver_desc->legacy_mmap_address_offset;
++              max_addr = bar_desc.mappable_regions[i].start -
++                         driver_desc->legacy_mmap_address_offset +
++                         bar_desc.mappable_regions[i].length_bytes;
++              written = scnprintf(buf, PAGE_SIZE - total_written,
++                                  "0x%08lx-0x%08lx\n", min_addr, max_addr);
++              total_written += written;
++              buf += written;
++      }
++      return total_written;
++}
++
++static ssize_t gasket_sysfs_data_show(struct device *device,
++                                    struct device_attribute *attr, char *buf)
++{
++      int i, ret = 0;
++      ssize_t current_written = 0;
++      const struct gasket_driver_desc *driver_desc;
++      struct gasket_dev *gasket_dev;
++      struct gasket_sysfs_attribute *gasket_attr;
++      const struct gasket_bar_desc *bar_desc;
++      enum gasket_sysfs_attribute_type sysfs_type;
++
++      gasket_dev = gasket_sysfs_get_device_data(device);
++      if (!gasket_dev) {
++              dev_err(device, "No sysfs mapping found for device\n");
++              return 0;
++      }
++
++      gasket_attr = gasket_sysfs_get_attr(device, attr);
++      if (!gasket_attr) {
++              dev_err(device, "No sysfs attr found for device\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return 0;
++      }
++
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++
++      sysfs_type =
++              (enum gasket_sysfs_attribute_type)gasket_attr->data.attr_type;
++      switch (sysfs_type) {
++      case ATTR_BAR_OFFSETS:
++              for (i = 0; i < GASKET_NUM_BARS; i++) {
++                      bar_desc = &driver_desc->bar_descriptions[i];
++                      if (bar_desc->size == 0)
++                              continue;
++                      current_written =
++                              snprintf(buf, PAGE_SIZE - ret, "%d: 0x%lx\n", i,
++                                       (ulong)bar_desc->base);
++                      buf += current_written;
++                      ret += current_written;
++              }
++              break;
++      case ATTR_BAR_SIZES:
++              for (i = 0; i < GASKET_NUM_BARS; i++) {
++                      bar_desc = &driver_desc->bar_descriptions[i];
++                      if (bar_desc->size == 0)
++                              continue;
++                      current_written =
++                              snprintf(buf, PAGE_SIZE - ret, "%d: 0x%lx\n", i,
++                                       (ulong)bar_desc->size);
++                      buf += current_written;
++                      ret += current_written;
++              }
++              break;
++      case ATTR_DRIVER_VERSION:
++              ret = snprintf(buf, PAGE_SIZE, "%s\n",
++                             gasket_dev->internal_desc->driver_desc->driver_version);
++              break;
++      case ATTR_FRAMEWORK_VERSION:
++              ret = snprintf(buf, PAGE_SIZE, "%s\n",
++                             GASKET_FRAMEWORK_VERSION);
++              break;
++      case ATTR_DEVICE_TYPE:
++              ret = snprintf(buf, PAGE_SIZE, "%s\n",
++                             gasket_dev->internal_desc->driver_desc->name);
++              break;
++      case ATTR_HARDWARE_REVISION:
++              ret = snprintf(buf, PAGE_SIZE, "%d\n",
++                             gasket_dev->hardware_revision);
++              break;
++      case ATTR_PCI_ADDRESS:
++              ret = snprintf(buf, PAGE_SIZE, "%s\n", gasket_dev->kobj_name);
++              break;
++      case ATTR_STATUS:
++              ret = snprintf(buf, PAGE_SIZE, "%s\n",
++                             gasket_num_name_lookup(gasket_dev->status,
++                                                    gasket_status_name_table));
++              break;
++      case ATTR_IS_DEVICE_OWNED:
++              ret = snprintf(buf, PAGE_SIZE, "%d\n",
++                             gasket_dev->dev_info.ownership.is_owned);
++              break;
++      case ATTR_DEVICE_OWNER:
++              ret = snprintf(buf, PAGE_SIZE, "%d\n",
++                             gasket_dev->dev_info.ownership.owner);
++              break;
++      case ATTR_WRITE_OPEN_COUNT:
++              ret = snprintf(buf, PAGE_SIZE, "%d\n",
++                             gasket_dev->dev_info.ownership.write_open_count);
++              break;
++      case ATTR_RESET_COUNT:
++              ret = snprintf(buf, PAGE_SIZE, "%d\n", gasket_dev->reset_count);
++              break;
++      case ATTR_USER_MEM_RANGES:
++              for (i = 0; i < GASKET_NUM_BARS; ++i) {
++                      current_written =
++                              gasket_write_mappable_regions(buf, driver_desc,
++                                                            i);
++                      buf += current_written;
++                      ret += current_written;
++              }
++              break;
++      default:
++              dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
++                      attr->attr.name);
++              ret = 0;
++              break;
++      }
++
++      gasket_sysfs_put_attr(device, gasket_attr);
++      gasket_sysfs_put_device_data(device, gasket_dev);
++      return ret;
++}
++
++/* These attributes apply to all Gasket driver instances. */
++static const struct gasket_sysfs_attribute gasket_sysfs_generic_attrs[] = {
++      GASKET_SYSFS_RO(bar_offsets, gasket_sysfs_data_show, ATTR_BAR_OFFSETS),
++      GASKET_SYSFS_RO(bar_sizes, gasket_sysfs_data_show, ATTR_BAR_SIZES),
++      GASKET_SYSFS_RO(driver_version, gasket_sysfs_data_show,
++                      ATTR_DRIVER_VERSION),
++      GASKET_SYSFS_RO(framework_version, gasket_sysfs_data_show,
++                      ATTR_FRAMEWORK_VERSION),
++      GASKET_SYSFS_RO(device_type, gasket_sysfs_data_show, ATTR_DEVICE_TYPE),
++      GASKET_SYSFS_RO(revision, gasket_sysfs_data_show,
++                      ATTR_HARDWARE_REVISION),
++      GASKET_SYSFS_RO(pci_address, gasket_sysfs_data_show, ATTR_PCI_ADDRESS),
++      GASKET_SYSFS_RO(status, gasket_sysfs_data_show, ATTR_STATUS),
++      GASKET_SYSFS_RO(is_device_owned, gasket_sysfs_data_show,
++                      ATTR_IS_DEVICE_OWNED),
++      GASKET_SYSFS_RO(device_owner, gasket_sysfs_data_show,
++                      ATTR_DEVICE_OWNER),
++      GASKET_SYSFS_RO(write_open_count, gasket_sysfs_data_show,
++                      ATTR_WRITE_OPEN_COUNT),
++      GASKET_SYSFS_RO(reset_count, gasket_sysfs_data_show, ATTR_RESET_COUNT),
++      GASKET_SYSFS_RO(user_mem_ranges, gasket_sysfs_data_show,
++                      ATTR_USER_MEM_RANGES),
++      GASKET_END_OF_ATTR_ARRAY
++};
++
++/* Add a char device and related info. */
++static int gasket_add_cdev(struct gasket_cdev_info *dev_info,
++                         const struct file_operations *file_ops,
++                         struct module *owner)
++{
++      int ret;
++
++      cdev_init(&dev_info->cdev, file_ops);
++      dev_info->cdev.owner = owner;
++      ret = cdev_add(&dev_info->cdev, dev_info->devt, 1);
++      if (ret) {
++              dev_err(dev_info->gasket_dev_ptr->dev,
++                      "cannot add char device [ret=%d]\n", ret);
++              return ret;
++      }
++      dev_info->cdev_added = 1;
++
++      return 0;
++}
++
++/* Disable device operations. */
++void gasket_disable_device(struct gasket_dev *gasket_dev)
++{
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++      int i;
++
++      dev_dbg(gasket_dev->dev, "disabling device\n");
++      /* Only delete the device if it has been successfully added. */
++      if (gasket_dev->dev_info.cdev_added)
++              cdev_del(&gasket_dev->dev_info.cdev);
++
++      gasket_dev->status = GASKET_STATUS_DEAD;
++
++      gasket_interrupt_cleanup(gasket_dev);
++
++      for (i = 0; i < driver_desc->num_page_tables; ++i) {
++              if (gasket_dev->page_table[i]) {
++                      gasket_page_table_reset(gasket_dev->page_table[i]);
++                      gasket_page_table_cleanup(gasket_dev->page_table[i]);
++              }
++      }
++}
++EXPORT_SYMBOL(gasket_disable_device);
++
++/*
++ * Registered driver descriptor lookup for PCI devices.
++ *
++ * Precondition: Called with g_mutex held (to avoid a race on return).
++ * Returns NULL if no matching device was found.
++ */
++static struct gasket_internal_desc *
++lookup_pci_internal_desc(struct pci_dev *pci_dev)
++{
++      int i;
++
++      __must_hold(&g_mutex);
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              if (g_descs[i].driver_desc &&
++                  g_descs[i].driver_desc->pci_id_table &&
++                  pci_match_id(g_descs[i].driver_desc->pci_id_table, pci_dev))
++                      return &g_descs[i];
++      }
++
++      return NULL;
++}
++
++/*
++ * Registered driver descriptor lookup for platform devices.
++ * Caller must hold g_mutex.
++ */
++static struct gasket_internal_desc *
++lookup_platform_internal_desc(struct platform_device *pdev)
++{
++      int i;
++
++      __must_hold(&g_mutex);
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              if (g_descs[i].driver_desc &&
++                  strcmp(g_descs[i].driver_desc->name, pdev->name) == 0)
++                      return &g_descs[i];
++      }
++
++      return NULL;
++}
++
++/*
++ * Verifies that the user has permissions to perform the requested mapping and
++ * that the provided descriptor/range is of adequate size to hold the range to
++ * be mapped.
++ */
++static bool gasket_mmap_has_permissions(struct gasket_dev *gasket_dev,
++                                      struct vm_area_struct *vma,
++                                      int bar_permissions)
++{
++      int requested_permissions;
++      /* Always allow sysadmin to access. */
++      if (capable(CAP_SYS_ADMIN))
++              return true;
++
++      /* Never allow non-sysadmins to access to a dead device. */
++      if (gasket_dev->status != GASKET_STATUS_ALIVE) {
++              dev_dbg(gasket_dev->dev, "Device is dead.\n");
++              return false;
++      }
++
++      /* Make sure that no wrong flags are set. */
++      requested_permissions =
++              (vma->vm_flags & (VM_WRITE | VM_READ | VM_EXEC));
++      if (requested_permissions & ~(bar_permissions)) {
++              dev_dbg(gasket_dev->dev,
++                      "Attempting to map a region with requested permissions "
++                      "0x%x, but region has permissions 0x%x.\n",
++                      requested_permissions, bar_permissions);
++              return false;
++      }
++
++      /* Do not allow a non-owner to write. */
++      if ((vma->vm_flags & VM_WRITE) &&
++          !gasket_owned_by_current_tgid(&gasket_dev->dev_info)) {
++              dev_dbg(gasket_dev->dev,
++                      "Attempting to mmap a region for write without owning "
++                      "device.\n");
++              return false;
++      }
++
++      return true;
++}
++
++/*
++ * Verifies that the input address is within the region allocated to coherent
++ * buffer.
++ */
++static bool
++gasket_is_coherent_region(const struct gasket_driver_desc *driver_desc,
++                        ulong address)
++{
++      struct gasket_coherent_buffer_desc coh_buff_desc =
++              driver_desc->coherent_buffer_description;
++
++      if (coh_buff_desc.permissions != GASKET_NOMAP) {
++              if ((address >= coh_buff_desc.base) &&
++                  (address < coh_buff_desc.base + coh_buff_desc.size)) {
++                      return true;
++              }
++      }
++      return false;
++}
++
++static int gasket_get_bar_index(const struct gasket_dev *gasket_dev,
++                              ulong phys_addr)
++{
++      int i;
++      const struct gasket_driver_desc *driver_desc;
++
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++      for (i = 0; i < GASKET_NUM_BARS; ++i) {
++              struct gasket_bar_desc bar_desc =
++                      driver_desc->bar_descriptions[i];
++
++              if (bar_desc.permissions != GASKET_NOMAP) {
++                      if (phys_addr >= bar_desc.base &&
++                          phys_addr < (bar_desc.base + bar_desc.size)) {
++                              return i;
++                      }
++              }
++      }
++      /* If we haven't found the address by now, it is invalid. */
++      return -EINVAL;
++}
++
++/*
++ * Sets the actual bounds to map, given the device's mappable region.
++ *
++ * Given the device's mappable region, along with the user-requested mapping
++ * start offset and length of the user region, determine how much of this
++ * mappable region can be mapped into the user's region (start/end offsets),
++ * and the physical offset (phys_offset) into the BAR where the mapping should
++ * begin (either the VMA's or region lower bound).
++ *
++ * In other words, this calculates the overlap between the VMA
++ * (bar_offset, requested_length) and the given gasket_mappable_region.
++ *
++ * Returns true if there's anything to map, and false otherwise.
++ */
++static bool
++gasket_mm_get_mapping_addrs(const struct gasket_mappable_region *region,
++                          ulong bar_offset, ulong requested_length,
++                          struct gasket_mappable_region *mappable_region,
++                          ulong *virt_offset)
++{
++      ulong range_start = region->start;
++      ulong range_length = region->length_bytes;
++      ulong range_end = range_start + range_length;
++
++      *virt_offset = 0;
++      if (bar_offset + requested_length < range_start) {
++              /*
++               * If the requested region is completely below the range,
++               * there is nothing to map.
++               */
++              return false;
++      } else if (bar_offset <= range_start) {
++              /* If the bar offset is below this range's start
++               * but the requested length continues into it:
++               * 1) Only map starting from the beginning of this
++               *      range's phys. offset, so we don't map unmappable
++               *      memory.
++               * 2) The length of the virtual memory to not map is the
++               *      delta between the bar offset and the
++               *      mappable start (and since the mappable start is
++               *      bigger, start - req.)
++               * 3) The map length is the minimum of the mappable
++               *      requested length (requested_length - virt_offset)
++               *      and the actual mappable length of the range.
++               */
++              mappable_region->start = range_start;
++              *virt_offset = range_start - bar_offset;
++              mappable_region->length_bytes =
++                      min(requested_length - *virt_offset, range_length);
++              return true;
++      } else if (bar_offset > range_start &&
++                 bar_offset < range_end) {
++              /*
++               * If the bar offset is within this range:
++               * 1) Map starting from the bar offset.
++               * 2) Because there is no forbidden memory between the
++               *      bar offset and the range start,
++               *      virt_offset is 0.
++               * 3) The map length is the minimum of the requested
++               *      length and the remaining length in the buffer
++               *      (range_end - bar_offset)
++               */
++              mappable_region->start = bar_offset;
++              *virt_offset = 0;
++              mappable_region->length_bytes =
++                      min(requested_length, range_end - bar_offset);
++              return true;
++      }
++
++      /*
++       * If the requested [start] offset is above range_end,
++       * there's nothing to map.
++       */
++      return false;
++}
++
++/*
++ * Calculates the offset where the VMA range begins in its containing BAR.
++ * The offset is written into bar_offset on success.
++ * Returns zero on success, anything else on error.
++ */
++static int gasket_mm_vma_bar_offset(const struct gasket_dev *gasket_dev,
++                                  const struct vm_area_struct *vma,
++                                  ulong *bar_offset)
++{
++      ulong raw_offset;
++      int bar_index;
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++
++      raw_offset = (vma->vm_pgoff << PAGE_SHIFT) +
++              driver_desc->legacy_mmap_address_offset;
++      bar_index = gasket_get_bar_index(gasket_dev, raw_offset);
++      if (bar_index < 0) {
++              dev_err(gasket_dev->dev,
++                      "Unable to find matching bar for address 0x%lx\n",
++                      raw_offset);
++              trace_gasket_mmap_exit(bar_index);
++              return bar_index;
++      }
++      *bar_offset =
++              raw_offset - driver_desc->bar_descriptions[bar_index].base;
++
++      return 0;
++}
++
++int gasket_mm_unmap_region(const struct gasket_dev *gasket_dev,
++                         struct vm_area_struct *vma,
++                         const struct gasket_mappable_region *map_region)
++{
++      ulong bar_offset;
++      ulong virt_offset;
++      struct gasket_mappable_region mappable_region;
++      int ret;
++
++      if (map_region->length_bytes == 0)
++              return 0;
++
++      ret = gasket_mm_vma_bar_offset(gasket_dev, vma, &bar_offset);
++      if (ret)
++              return ret;
++
++      if (!gasket_mm_get_mapping_addrs(map_region, bar_offset,
++                                       vma->vm_end - vma->vm_start,
++                                       &mappable_region, &virt_offset))
++              return 1;
++
++      /*
++       * The length passed to zap_vma_ptes MUST BE A MULTIPLE OF
++       * PAGE_SIZE! Trust me. I have the scars.
++       *
++       * Next multiple of y: ceil_div(x, y) * y
++       */
++      zap_vma_ptes(vma, vma->vm_start + virt_offset,
++                   DIV_ROUND_UP(mappable_region.length_bytes, PAGE_SIZE) *
++                   PAGE_SIZE);
++      return 0;
++}
++EXPORT_SYMBOL(gasket_mm_unmap_region);
++
++/* Maps a virtual address + range to a physical offset of a BAR. */
++static enum do_map_region_status
++do_map_region(const struct gasket_dev *gasket_dev, struct vm_area_struct *vma,
++            struct gasket_mappable_region *mappable_region)
++{
++      /* Maximum size of a single call to io_remap_pfn_range. */
++      /* I pulled this number out of thin air. */
++      const ulong max_chunk_size = 64 * 1024 * 1024;
++      ulong chunk_size, mapped_bytes = 0;
++
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++
++      ulong bar_offset, virt_offset;
++      struct gasket_mappable_region region_to_map;
++      ulong phys_offset, map_length;
++      ulong virt_base, phys_base;
++      int bar_index, ret;
++
++      ret = gasket_mm_vma_bar_offset(gasket_dev, vma, &bar_offset);
++      if (ret)
++              return DO_MAP_REGION_INVALID;
++
++      if (!gasket_mm_get_mapping_addrs(mappable_region, bar_offset,
++                                       vma->vm_end - vma->vm_start,
++                                       &region_to_map, &virt_offset))
++              return DO_MAP_REGION_INVALID;
++      phys_offset = region_to_map.start;
++      map_length = region_to_map.length_bytes;
++
++      virt_base = vma->vm_start + virt_offset;
++      bar_index =
++              gasket_get_bar_index(gasket_dev,
++                                   (vma->vm_pgoff << PAGE_SHIFT) +
++                                   driver_desc->legacy_mmap_address_offset);
++      phys_base = gasket_dev->bar_data[bar_index].phys_base + phys_offset;
++      while (mapped_bytes < map_length) {
++              /*
++               * io_remap_pfn_range can take a while, so we chunk its
++               * calls and call cond_resched between each.
++               */
++              chunk_size = min(max_chunk_size, map_length - mapped_bytes);
++
++              cond_resched();
++              ret = io_remap_pfn_range(vma, virt_base + mapped_bytes,
++                                       (phys_base + mapped_bytes) >>
++                                       PAGE_SHIFT, chunk_size,
++                                       vma->vm_page_prot);
++              if (ret) {
++                      dev_err(gasket_dev->dev,
++                              "Error remapping PFN range.\n");
++                      goto fail;
++              }
++              mapped_bytes += chunk_size;
++      }
++
++      return DO_MAP_REGION_SUCCESS;
++
++fail:
++      /* Unmap the partial chunk we mapped. */
++      mappable_region->length_bytes = mapped_bytes;
++      if (gasket_mm_unmap_region(gasket_dev, vma, mappable_region))
++              dev_err(gasket_dev->dev,
++                      "Error unmapping partial region 0x%lx (0x%lx bytes)\n",
++                      (ulong)virt_offset,
++                      (ulong)mapped_bytes);
++
++      return DO_MAP_REGION_FAILURE;
++}
++
++/* Map a region of coherent memory. */
++static int gasket_mmap_coherent(struct gasket_dev *gasket_dev,
++                              struct vm_area_struct *vma)
++{
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++      const ulong requested_length = vma->vm_end - vma->vm_start;
++      int ret;
++      ulong permissions;
++
++      if (requested_length == 0 || requested_length >
++          gasket_dev->coherent_buffer.length_bytes) {
++              trace_gasket_mmap_exit(-EINVAL);
++              return -EINVAL;
++      }
++
++      permissions = driver_desc->coherent_buffer_description.permissions;
++      if (!gasket_mmap_has_permissions(gasket_dev, vma, permissions)) {
++              dev_err(gasket_dev->dev, "Permission checking failed.\n");
++              trace_gasket_mmap_exit(-EPERM);
++              return -EPERM;
++      }
++
++      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++      vma->vm_pgoff = 0;
++      ret = dma_mmap_coherent(gasket_dev->dma_dev, vma,
++                              gasket_dev->coherent_buffer.virt_base,
++                              gasket_dev->coherent_buffer.phys_base,
++                              requested_length);
++      if (ret) {
++              dev_err(gasket_dev->dev,
++                      "Error mmapping coherent buffer err=%d.\n", ret);
++              trace_gasket_mmap_exit(ret);
++              return ret;
++      }
++
++      /* Record the user virtual to dma_address mapping that was
++       * created by the kernel.
++       */
++      gasket_set_user_virt(gasket_dev, requested_length,
++                           gasket_dev->coherent_buffer.phys_base,
++                           vma->vm_start);
++      return 0;
++}
++
++/* Map a device's BARs into user space. */
++static int gasket_mmap(struct file *filp, struct vm_area_struct *vma)
++{
++      int i, ret;
++      int bar_index;
++      int has_mapped_anything = 0;
++      ulong permissions;
++      ulong raw_offset, vma_size;
++      bool is_coherent_region;
++      const struct gasket_driver_desc *driver_desc;
++      struct gasket_dev *gasket_dev = (struct gasket_dev *)filp->private_data;
++      const struct gasket_bar_desc *bar_desc;
++      struct gasket_mappable_region *map_regions = NULL;
++      int num_map_regions = 0;
++      enum do_map_region_status map_status;
++
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++
++      if (vma->vm_start & ~PAGE_MASK) {
++              dev_err(gasket_dev->dev,
++                      "Base address not page-aligned: 0x%lx\n",
++                      vma->vm_start);
++              trace_gasket_mmap_exit(-EINVAL);
++              return -EINVAL;
++      }
++
++      /* Calculate the offset of this range into physical mem. */
++      raw_offset = (vma->vm_pgoff << PAGE_SHIFT) +
++              driver_desc->legacy_mmap_address_offset;
++      vma_size = vma->vm_end - vma->vm_start;
++      trace_gasket_mmap_entry(gasket_dev->dev_info.name, raw_offset,
++                              vma_size);
++
++      /*
++       * Check if the raw offset is within a bar region. If not, check if it
++       * is a coherent region.
++       */
++      bar_index = gasket_get_bar_index(gasket_dev, raw_offset);
++      is_coherent_region = gasket_is_coherent_region(driver_desc, raw_offset);
++      if (bar_index < 0 && !is_coherent_region) {
++              dev_err(gasket_dev->dev,
++                      "Unable to find matching bar for address 0x%lx\n",
++                      raw_offset);
++              trace_gasket_mmap_exit(bar_index);
++              return bar_index;
++      }
++      if (bar_index > 0 && is_coherent_region) {
++              dev_err(gasket_dev->dev,
++                      "double matching bar and coherent buffers for address "
++                      "0x%lx\n",
++                      raw_offset);
++              trace_gasket_mmap_exit(bar_index);
++              return -EINVAL;
++      }
++
++      vma->vm_private_data = gasket_dev;
++
++      if (is_coherent_region)
++              return gasket_mmap_coherent(gasket_dev, vma);
++
++      /* Everything in the rest of this function is for normal BAR mapping. */
++
++      /*
++       * Subtract the base of the bar from the raw offset to get the
++       * memory location within the bar to map.
++       */
++      bar_desc = &driver_desc->bar_descriptions[bar_index];
++      permissions = bar_desc->permissions;
++      if (!gasket_mmap_has_permissions(gasket_dev, vma, permissions)) {
++              dev_err(gasket_dev->dev, "Permission checking failed.\n");
++              trace_gasket_mmap_exit(-EPERM);
++              return -EPERM;
++      }
++
++      if (driver_desc->get_mappable_regions_cb) {
++              ret = driver_desc->get_mappable_regions_cb(gasket_dev,
++                                                         bar_index,
++                                                         &map_regions,
++                                                         &num_map_regions);
++              if (ret)
++                      return ret;
++      } else {
++              if (!gasket_mmap_has_permissions(gasket_dev, vma,
++                                               bar_desc->permissions)) {
++                      dev_err(gasket_dev->dev,
++                              "Permission checking failed.\n");
++                      trace_gasket_mmap_exit(-EPERM);
++                      return -EPERM;
++              }
++              num_map_regions = bar_desc->num_mappable_regions;
++              map_regions = kcalloc(num_map_regions,
++                                    sizeof(*bar_desc->mappable_regions),
++                                    GFP_KERNEL);
++              if (map_regions) {
++                      memcpy(map_regions, bar_desc->mappable_regions,
++                             num_map_regions *
++                                      sizeof(*bar_desc->mappable_regions));
++              }
++      }
++
++      if (!map_regions || num_map_regions == 0) {
++              dev_err(gasket_dev->dev, "No mappable regions returned!\n");
++              return -EINVAL;
++      }
++
++      /* Marks the VMA's pages as uncacheable. */
++      vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++      for (i = 0; i < num_map_regions; i++) {
++              map_status = do_map_region(gasket_dev, vma, &map_regions[i]);
++              /* Try the next region if this one was not mappable. */
++              if (map_status == DO_MAP_REGION_INVALID)
++                      continue;
++              if (map_status == DO_MAP_REGION_FAILURE) {
++                      ret = -ENOMEM;
++                      goto fail;
++              }
++
++              has_mapped_anything = 1;
++      }
++
++      kfree(map_regions);
++
++      /* If we could not map any memory, the request was invalid. */
++      if (!has_mapped_anything) {
++              dev_err(gasket_dev->dev,
++                      "Map request did not contain a valid region.\n");
++              trace_gasket_mmap_exit(-EINVAL);
++              return -EINVAL;
++      }
++
++      trace_gasket_mmap_exit(0);
++      return 0;
++
++fail:
++      /* Need to unmap any mapped ranges. */
++      num_map_regions = i;
++      for (i = 0; i < num_map_regions; i++)
++              if (gasket_mm_unmap_region(gasket_dev, vma,
++                                         &bar_desc->mappable_regions[i]))
++                      dev_err(gasket_dev->dev, "Error unmapping range %d.\n",
++                              i);
++      kfree(map_regions);
++
++      return ret;
++}
++
++/*
++ * Open the char device file.
++ *
++ * If the open is for writing, and the device is not owned, this process becomes
++ * the owner.  If the open is for writing and the device is already owned by
++ * some other process, it is an error.  If this process is the owner, increment
++ * the open count.
++ *
++ * Returns 0 if successful, a negative error number otherwise.
++ */
++static int gasket_open(struct inode *inode, struct file *filp)
++{
++      int ret;
++      struct gasket_dev *gasket_dev;
++      const struct gasket_driver_desc *driver_desc;
++      struct gasket_ownership *ownership;
++      char task_name[TASK_COMM_LEN];
++      struct gasket_cdev_info *dev_info =
++          container_of(inode->i_cdev, struct gasket_cdev_info, cdev);
++      struct pid_namespace *pid_ns = task_active_pid_ns(current);
++      bool is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
++
++      gasket_dev = dev_info->gasket_dev_ptr;
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++      ownership = &dev_info->ownership;
++      get_task_comm(task_name, current);
++      filp->private_data = gasket_dev;
++      inode->i_size = 0;
++
++      dev_dbg(gasket_dev->dev,
++              "Attempting to open with tgid %u (%s) (f_mode: 0%03o, "
++              "fmode_write: %d is_root: %u)\n",
++              current->tgid, task_name, filp->f_mode,
++              (filp->f_mode & FMODE_WRITE), is_root);
++
++      /* Always allow non-writing accesses. */
++      if (!(filp->f_mode & FMODE_WRITE)) {
++              dev_dbg(gasket_dev->dev, "Allowing read-only opening.\n");
++              return 0;
++      }
++
++      mutex_lock(&gasket_dev->mutex);
++
++      dev_dbg(gasket_dev->dev,
++              "Current owner open count (owning tgid %u): %d.\n",
++              ownership->owner, ownership->write_open_count);
++
++      /* Opening a node owned by another TGID is an error (unless root) */
++      if (ownership->is_owned && ownership->owner != current->tgid &&
++          !is_root) {
++              dev_err(gasket_dev->dev,
++                      "Process %u is opening a node held by %u.\n",
++                      current->tgid, ownership->owner);
++              mutex_unlock(&gasket_dev->mutex);
++              return -EPERM;
++      }
++
++      /* If the node is not owned, assign it to the current TGID. */
++      if (!ownership->is_owned) {
++              ret = gasket_check_and_invoke_callback_nolock(gasket_dev,
++                                                            driver_desc->device_open_cb);
++              if (ret) {
++                      dev_err(gasket_dev->dev,
++                              "Error in device open cb: %d\n", ret);
++                      mutex_unlock(&gasket_dev->mutex);
++                      return ret;
++              }
++              ownership->is_owned = 1;
++              ownership->owner = current->tgid;
++              dev_dbg(gasket_dev->dev, "Device owner is now tgid %u\n",
++                      ownership->owner);
++      }
++
++      ownership->write_open_count++;
++
++      dev_dbg(gasket_dev->dev, "New open count (owning tgid %u): %d\n",
++              ownership->owner, ownership->write_open_count);
++
++      mutex_unlock(&gasket_dev->mutex);
++      return 0;
++}
++
++/*
++ * Called on a close of the device file.  If this process is the owner,
++ * decrement the open count.  On last close by the owner, free up buffers and
++ * eventfd contexts, and release ownership.
++ *
++ * Returns 0 if successful, a negative error number otherwise.
++ */
++static int gasket_release(struct inode *inode, struct file *file)
++{
++      int i;
++      struct gasket_dev *gasket_dev;
++      struct gasket_ownership *ownership;
++      const struct gasket_driver_desc *driver_desc;
++      char task_name[TASK_COMM_LEN];
++      struct gasket_cdev_info *dev_info =
++              container_of(inode->i_cdev, struct gasket_cdev_info, cdev);
++      struct pid_namespace *pid_ns = task_active_pid_ns(current);
++      bool is_root = ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN);
++
++      gasket_dev = dev_info->gasket_dev_ptr;
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++      ownership = &dev_info->ownership;
++      get_task_comm(task_name, current);
++      mutex_lock(&gasket_dev->mutex);
++
++      dev_dbg(gasket_dev->dev,
++              "Releasing device node. Call origin: tgid %u (%s) "
++              "(f_mode: 0%03o, fmode_write: %d, is_root: %u)\n",
++              current->tgid, task_name, file->f_mode,
++              (file->f_mode & FMODE_WRITE), is_root);
++      dev_dbg(gasket_dev->dev, "Current open count (owning tgid %u): %d\n",
++              ownership->owner, ownership->write_open_count);
++
++      if (file->f_mode & FMODE_WRITE) {
++              ownership->write_open_count--;
++              if (ownership->write_open_count == 0) {
++                      dev_dbg(gasket_dev->dev, "Device is now free\n");
++                      ownership->is_owned = 0;
++                      ownership->owner = 0;
++
++                      /* Forces chip reset before we unmap the page tables. */
++                      driver_desc->device_reset_cb(gasket_dev);
++
++                      for (i = 0; i < driver_desc->num_page_tables; ++i) {
++                              gasket_page_table_unmap_all(gasket_dev->page_table[i]);
++                              gasket_page_table_garbage_collect(gasket_dev->page_table[i]);
++                              gasket_free_coherent_memory_all(gasket_dev, i);
++                      }
++
++                      /* Closes device, enters power save. */
++                      gasket_check_and_invoke_callback_nolock(gasket_dev,
++                                                              driver_desc->device_close_cb);
++              }
++      }
++
++      dev_dbg(gasket_dev->dev, "New open count (owning tgid %u): %d\n",
++              ownership->owner, ownership->write_open_count);
++      mutex_unlock(&gasket_dev->mutex);
++      return 0;
++}
++
++/*
++ * Gasket ioctl dispatch function.
++ *
++ * Check if the ioctl is a generic ioctl. If not, pass the ioctl to the
++ * ioctl_handler_cb registered in the driver description.
++ * If the ioctl is a generic ioctl, pass it to gasket_ioctl_handler.
++ */
++static long gasket_ioctl(struct file *filp, uint cmd, ulong arg)
++{
++      struct gasket_dev *gasket_dev;
++      const struct gasket_driver_desc *driver_desc;
++      void __user *argp = (void __user *)arg;
++      char path[256];
++
++      gasket_dev = (struct gasket_dev *)filp->private_data;
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++      if (!driver_desc) {
++              dev_dbg(gasket_dev->dev,
++                      "Unable to find device descriptor for file %s\n",
++                      d_path(&filp->f_path, path, 256));
++              return -ENODEV;
++      }
++
++      if (!gasket_is_supported_ioctl(cmd)) {
++              /*
++               * The ioctl handler is not a standard Gasket callback, since
++               * it requires different arguments. This means we can't use
++               * check_and_invoke_callback.
++               */
++              if (driver_desc->ioctl_handler_cb)
++                      return driver_desc->ioctl_handler_cb(filp, cmd, argp);
++
++              dev_dbg(gasket_dev->dev, "Received unknown ioctl 0x%x\n", cmd);
++              return -EINVAL;
++      }
++
++      return gasket_handle_ioctl(filp, cmd, argp);
++}
++
++/* File operations for all Gasket devices. */
++static const struct file_operations gasket_file_ops = {
++      .owner = THIS_MODULE,
++      .llseek = no_llseek,
++      .mmap = gasket_mmap,
++      .open = gasket_open,
++      .release = gasket_release,
++      .unlocked_ioctl = gasket_ioctl,
++      .compat_ioctl = gasket_ioctl,
++};
++
++/* Perform final init and marks the device as active. */
++int gasket_enable_device(struct gasket_dev *gasket_dev)
++{
++      int tbl_idx;
++      int ret;
++      const struct gasket_driver_desc *driver_desc =
++              gasket_dev->internal_desc->driver_desc;
++
++      dev_dbg(gasket_dev->dev, "enabling device\n");
++      ret = gasket_interrupt_init(gasket_dev);
++      if (ret) {
++              dev_err(gasket_dev->dev,
++                      "Critical failure to allocate interrupts: %d\n", ret);
++              gasket_interrupt_cleanup(gasket_dev);
++              return ret;
++      }
++
++      for (tbl_idx = 0; tbl_idx < driver_desc->num_page_tables; tbl_idx++) {
++              dev_dbg(gasket_dev->dev, "Initializing page table %d.\n",
++                      tbl_idx);
++              ret = gasket_page_table_init(&gasket_dev->page_table[tbl_idx],
++                                           &gasket_dev->bar_data[driver_desc->page_table_bar_index],
++                                           &driver_desc->page_table_configs[tbl_idx],
++                                           gasket_dev->dev,
++                                           gasket_dev->pci_dev);
++              if (ret) {
++                      dev_err(gasket_dev->dev,
++                              "Couldn't init page table %d: %d\n",
++                              tbl_idx, ret);
++                      return ret;
++              }
++              /*
++               * Make sure that the page table is clear and set to simple
++               * addresses.
++               */
++              gasket_page_table_reset(gasket_dev->page_table[tbl_idx]);
++      }
++
++      /*
++       * hardware_revision_cb returns a positive integer (the rev) if
++       * successful.)
++       */
++      ret = check_and_invoke_callback(gasket_dev,
++                                      driver_desc->hardware_revision_cb);
++      if (ret < 0) {
++              dev_err(gasket_dev->dev,
++                      "Error getting hardware revision: %d\n", ret);
++              return ret;
++      }
++      gasket_dev->hardware_revision = ret;
++
++      /* device_status_cb returns a device status, not an error code. */
++      gasket_dev->status = gasket_get_hw_status(gasket_dev);
++      if (gasket_dev->status == GASKET_STATUS_DEAD)
++              dev_err(gasket_dev->dev, "Device reported as unhealthy.\n");
++
++      ret = gasket_add_cdev(&gasket_dev->dev_info, &gasket_file_ops,
++                            driver_desc->module);
++      if (ret)
++              return ret;
++
++      return 0;
++}
++EXPORT_SYMBOL(gasket_enable_device);
++
++static int __gasket_add_device(struct device *parent_dev,
++                             struct gasket_internal_desc *internal_desc,
++                             struct gasket_dev **gasket_devp)
++{
++      int ret;
++      struct gasket_dev *gasket_dev;
++      const struct gasket_driver_desc *driver_desc =
++          internal_desc->driver_desc;
++
++      ret = gasket_alloc_dev(internal_desc, parent_dev, &gasket_dev);
++      if (ret)
++              return ret;
++      if (IS_ERR(gasket_dev->dev_info.device)) {
++              dev_err(parent_dev, "Cannot create %s device %s [ret = %ld]\n",
++                      driver_desc->name, gasket_dev->dev_info.name,
++                      PTR_ERR(gasket_dev->dev_info.device));
++              ret = -ENODEV;
++              goto free_gasket_dev;
++      }
++
++      ret = gasket_sysfs_create_mapping(gasket_dev->dev_info.device,
++                                        gasket_dev);
++      if (ret)
++              goto remove_device;
++
++      ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device,
++                                        gasket_sysfs_generic_attrs);
++      if (ret)
++              goto remove_sysfs_mapping;
++
++      *gasket_devp = gasket_dev;
++      return 0;
++
++remove_sysfs_mapping:
++      gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
++remove_device:
++      device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
++free_gasket_dev:
++      gasket_free_dev(gasket_dev);
++      return ret;
++}
++
++static void __gasket_remove_device(struct gasket_internal_desc *internal_desc,
++                                 struct gasket_dev *gasket_dev)
++{
++      gasket_sysfs_remove_mapping(gasket_dev->dev_info.device);
++      device_destroy(internal_desc->class, gasket_dev->dev_info.devt);
++      gasket_free_dev(gasket_dev);
++}
++
++/*
++ * Add PCI gasket device.
++ *
++ * Called by Gasket device probe function.
++ * Allocates device metadata and maps device memory.  The device driver must
++ * call gasket_enable_device after driver init is complete to place the device
++ * in active use.
++ */
++int gasket_pci_add_device(struct pci_dev *pci_dev,
++                        struct gasket_dev **gasket_devp)
++{
++      int ret;
++      struct gasket_internal_desc *internal_desc;
++      struct gasket_dev *gasket_dev;
++      struct device *parent;
++
++      dev_dbg(&pci_dev->dev, "add PCI gasket device\n");
++
++      mutex_lock(&g_mutex);
++      internal_desc = lookup_pci_internal_desc(pci_dev);
++      mutex_unlock(&g_mutex);
++      if (!internal_desc) {
++              dev_err(&pci_dev->dev,
++                      "PCI add device called for unknown driver type\n");
++              return -ENODEV;
++      }
++
++      parent = &pci_dev->dev;
++      ret = __gasket_add_device(parent, internal_desc, &gasket_dev);
++      if (ret)
++              return ret;
++
++      gasket_dev->pci_dev = pci_dev;
++      ret = gasket_setup_pci(pci_dev, gasket_dev);
++      if (ret)
++              goto cleanup_pci;
++
++      /*
++       * Once we've created the mapping structures successfully, attempt to
++       * create a symlink to the pci directory of this object.
++       */
++      ret = sysfs_create_link(&gasket_dev->dev_info.device->kobj,
++                              &pci_dev->dev.kobj, dev_name(&pci_dev->dev));
++      if (ret) {
++              dev_err(gasket_dev->dev,
++                      "Cannot create sysfs pci link: %d\n", ret);
++              goto cleanup_pci;
++      }
++
++      *gasket_devp = gasket_dev;
++      return 0;
++
++cleanup_pci:
++      gasket_cleanup_pci(gasket_dev);
++      __gasket_remove_device(internal_desc, gasket_dev);
++      return ret;
++}
++EXPORT_SYMBOL(gasket_pci_add_device);
++
++/* Remove a PCI gasket device. */
++void gasket_pci_remove_device(struct pci_dev *pci_dev)
++{
++      int i;
++      struct gasket_internal_desc *internal_desc;
++      struct gasket_dev *gasket_dev = NULL;
++      /* Find the device desc. */
++      mutex_lock(&g_mutex);
++      internal_desc = lookup_pci_internal_desc(pci_dev);
++      if (!internal_desc) {
++              mutex_unlock(&g_mutex);
++              return;
++      }
++      mutex_unlock(&g_mutex);
++
++      /* Now find the specific device */
++      mutex_lock(&internal_desc->mutex);
++      for (i = 0; i < GASKET_DEV_MAX; i++) {
++              if (internal_desc->devs[i] &&
++                  internal_desc->devs[i]->pci_dev == pci_dev) {
++                      gasket_dev = internal_desc->devs[i];
++                      break;
++              }
++      }
++      mutex_unlock(&internal_desc->mutex);
++
++      if (!gasket_dev)
++              return;
++
++      dev_dbg(gasket_dev->dev, "remove %s PCI gasket device\n",
++              internal_desc->driver_desc->name);
++
++      gasket_cleanup_pci(gasket_dev);
++      __gasket_remove_device(internal_desc, gasket_dev);
++}
++EXPORT_SYMBOL(gasket_pci_remove_device);
++
++/* Add platform gasket device. Called by Gasket device probe function. */
++int gasket_platform_add_device(struct platform_device *pdev,
++                             struct gasket_dev **gasket_devp)
++{
++      int ret;
++      struct gasket_internal_desc *internal_desc;
++      struct gasket_dev *gasket_dev;
++      struct device *parent;
++
++      dev_dbg(&pdev->dev, "add platform gasket device\n");
++
++      mutex_lock(&g_mutex);
++      internal_desc = lookup_platform_internal_desc(pdev);
++      mutex_unlock(&g_mutex);
++      if (!internal_desc) {
++              dev_err(&pdev->dev,
++                      "%s called for unknown driver type\n", __func__);
++              return -ENODEV;
++      }
++
++      parent = &pdev->dev;
++      ret = __gasket_add_device(parent, internal_desc, &gasket_dev);
++      if (ret)
++              return ret;
++
++      gasket_dev->platform_dev = pdev;
++      *gasket_devp = gasket_dev;
++      return 0;
++}
++EXPORT_SYMBOL(gasket_platform_add_device);
++
++/* Remove a platform gasket device. */
++void gasket_platform_remove_device(struct platform_device *pdev)
++{
++      int i;
++      struct gasket_internal_desc *internal_desc;
++      struct gasket_dev *gasket_dev = NULL;
++
++      /* Find the device desc. */
++      mutex_lock(&g_mutex);
++      internal_desc = lookup_platform_internal_desc(pdev);
++      mutex_unlock(&g_mutex);
++      if (!internal_desc)
++              return;
++
++      /* Now find the specific device */
++      mutex_lock(&internal_desc->mutex);
++      for (i = 0; i < GASKET_DEV_MAX; i++) {
++              if (internal_desc->devs[i] &&
++                  internal_desc->devs[i]->platform_dev == pdev) {
++                      gasket_dev = internal_desc->devs[i];
++                      break;
++              }
++      }
++      mutex_unlock(&internal_desc->mutex);
++
++      if (!gasket_dev)
++              return;
++
++      dev_dbg(gasket_dev->dev, "remove %s platform gasket device\n",
++              internal_desc->driver_desc->name);
++
++      __gasket_remove_device(internal_desc, gasket_dev);
++}
++EXPORT_SYMBOL(gasket_platform_remove_device);
++
++void gasket_set_dma_device(struct gasket_dev *gasket_dev,
++                         struct device *dma_dev)
++{
++      put_device(gasket_dev->dma_dev);
++      gasket_dev->dma_dev = get_device(dma_dev);
++}
++EXPORT_SYMBOL(gasket_set_dma_device);
++
++/**
++ * Lookup a name by number in a num_name table.
++ * @num: Number to lookup.
++ * @table: Array of num_name structures, the table for the lookup.
++ *
++ * Description: Searches for num in the table.  If found, the
++ *            corresponding name is returned; otherwise NULL
++ *            is returned.
++ *
++ *            The table must have a NULL name pointer at the end.
++ */
++const char *gasket_num_name_lookup(uint num,
++                                 const struct gasket_num_name *table)
++{
++      uint i = 0;
++
++      while (table[i].snn_name) {
++              if (num == table[i].snn_num)
++                      break;
++              ++i;
++      }
++
++      return table[i].snn_name;
++}
++EXPORT_SYMBOL(gasket_num_name_lookup);
++
++int gasket_reset(struct gasket_dev *gasket_dev)
++{
++      int ret;
++
++      mutex_lock(&gasket_dev->mutex);
++      ret = gasket_reset_nolock(gasket_dev);
++      mutex_unlock(&gasket_dev->mutex);
++      return ret;
++}
++EXPORT_SYMBOL(gasket_reset);
++
++int gasket_reset_nolock(struct gasket_dev *gasket_dev)
++{
++      int ret;
++      int i;
++      const struct gasket_driver_desc *driver_desc;
++
++      driver_desc = gasket_dev->internal_desc->driver_desc;
++      if (!driver_desc->device_reset_cb)
++              return 0;
++
++      ret = driver_desc->device_reset_cb(gasket_dev);
++      if (ret) {
++              dev_dbg(gasket_dev->dev, "Device reset cb returned %d.\n",
++                      ret);
++              return ret;
++      }
++
++      /* Reinitialize the page tables and interrupt framework. */
++      for (i = 0; i < driver_desc->num_page_tables; ++i)
++              gasket_page_table_reset(gasket_dev->page_table[i]);
++
++      ret = gasket_interrupt_reinit(gasket_dev);
++      if (ret) {
++              dev_dbg(gasket_dev->dev, "Unable to reinit interrupts: %d.\n",
++                      ret);
++              return ret;
++      }
++
++      /* Get current device health. */
++      gasket_dev->status = gasket_get_hw_status(gasket_dev);
++      if (gasket_dev->status == GASKET_STATUS_DEAD) {
++              dev_dbg(gasket_dev->dev, "Device reported as dead.\n");
++              return -EINVAL;
++      }
++
++      return 0;
++}
++EXPORT_SYMBOL(gasket_reset_nolock);
++
++gasket_ioctl_permissions_cb_t
++gasket_get_ioctl_permissions_cb(struct gasket_dev *gasket_dev)
++{
++      return gasket_dev->internal_desc->driver_desc->ioctl_permissions_cb;
++}
++EXPORT_SYMBOL(gasket_get_ioctl_permissions_cb);
++
++/* Get the driver structure for a given gasket_dev.
++ * @dev: pointer to gasket_dev, implementing the requested driver.
++ */
++const struct gasket_driver_desc *gasket_get_driver_desc(struct gasket_dev *dev)
++{
++      return dev->internal_desc->driver_desc;
++}
++
++/* Get the device structure for a given gasket_dev.
++ * @dev: pointer to gasket_dev, implementing the requested driver.
++ */
++struct device *gasket_get_device(struct gasket_dev *dev)
++{
++      return dev->dev;
++}
++
++/**
++ * Asynchronously waits on device.
++ * @gasket_dev: Device struct.
++ * @bar: Bar
++ * @offset: Register offset
++ * @mask: Register mask
++ * @val: Expected value
++ * @max_retries: number of sleep periods
++ * @delay_ms: Timeout in milliseconds
++ *
++ * Description: Busy waits for a specific combination of bits to be set on a
++ * Gasket register.
++ **/
++int gasket_wait_with_reschedule(struct gasket_dev *gasket_dev, int bar,
++                              u64 offset, u64 mask, u64 val,
++                              uint max_retries, u64 delay_ms)
++{
++      uint retries = 0;
++      u64 tmp;
++
++      while (retries < max_retries) {
++              tmp = gasket_dev_read_64(gasket_dev, bar, offset);
++              if ((tmp & mask) == val)
++                      return 0;
++              msleep(delay_ms);
++              retries++;
++      }
++      dev_dbg(gasket_dev->dev, "%s timeout: reg %llx timeout (%llu ms)\n",
++              __func__, offset, max_retries * delay_ms);
++      return -ETIMEDOUT;
++}
++EXPORT_SYMBOL(gasket_wait_with_reschedule);
++
++/* See gasket_core.h for description. */
++int gasket_register_device(const struct gasket_driver_desc *driver_desc)
++{
++      int i, ret;
++      int desc_idx = -1;
++      struct gasket_internal_desc *internal;
++
++      pr_debug("Loading %s driver version %s\n", driver_desc->name,
++               driver_desc->driver_version);
++      /* Check for duplicates and find a free slot. */
++      mutex_lock(&g_mutex);
++
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              if (g_descs[i].driver_desc == driver_desc) {
++                      pr_err("%s driver already loaded/registered\n",
++                             driver_desc->name);
++                      mutex_unlock(&g_mutex);
++                      return -EBUSY;
++              }
++      }
++
++      /* This and the above loop could be combined, but this reads easier. */
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              if (!g_descs[i].driver_desc) {
++                      g_descs[i].driver_desc = driver_desc;
++                      desc_idx = i;
++                      break;
++              }
++      }
++      mutex_unlock(&g_mutex);
++
++      if (desc_idx == -1) {
++              pr_err("too many drivers loaded, max %d\n",
++                     GASKET_FRAMEWORK_DESC_MAX);
++              return -EBUSY;
++      }
++
++      internal = &g_descs[desc_idx];
++      mutex_init(&internal->mutex);
++      memset(internal->devs, 0, sizeof(struct gasket_dev *) * GASKET_DEV_MAX);
++
++    /* Function signature for `class_create()` is changed in kernel >= 6.4.x
++     * to only accept a single argument.
++     * */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
++    internal->class = class_create(driver_desc->module, driver_desc->name);
++#else
++    internal->class = class_create(driver_desc->name);
++#endif
++
++      if (IS_ERR(internal->class)) {
++              pr_err("Cannot register %s class [ret=%ld]\n",
++                     driver_desc->name, PTR_ERR(internal->class));
++              ret = PTR_ERR(internal->class);
++              goto unregister_gasket_driver;
++      }
++
++      ret = register_chrdev_region(MKDEV(driver_desc->major,
++                                         driver_desc->minor), GASKET_DEV_MAX,
++                                   driver_desc->name);
++      if (ret) {
++              pr_err("cannot register %s char driver [ret=%d]\n",
++                     driver_desc->name, ret);
++              goto destroy_class;
++      }
++
++      return 0;
++
++destroy_class:
++      class_destroy(internal->class);
++
++unregister_gasket_driver:
++      mutex_lock(&g_mutex);
++      g_descs[desc_idx].driver_desc = NULL;
++      mutex_unlock(&g_mutex);
++      return ret;
++}
++EXPORT_SYMBOL(gasket_register_device);
++
++/* See gasket_core.h for description. */
++void gasket_unregister_device(const struct gasket_driver_desc *driver_desc)
++{
++      int i, desc_idx;
++      struct gasket_internal_desc *internal_desc = NULL;
++
++      mutex_lock(&g_mutex);
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              if (g_descs[i].driver_desc == driver_desc) {
++                      internal_desc = &g_descs[i];
++                      desc_idx = i;
++                      break;
++              }
++      }
++
++      if (!internal_desc) {
++              mutex_unlock(&g_mutex);
++              pr_err("request to unregister unknown desc: %s, %d:%d\n",
++                     driver_desc->name, driver_desc->major,
++                     driver_desc->minor);
++              return;
++      }
++
++      unregister_chrdev_region(MKDEV(driver_desc->major, driver_desc->minor),
++                               GASKET_DEV_MAX);
++
++      class_destroy(internal_desc->class);
++
++      /* Finally, effectively "remove" the driver. */
++      g_descs[desc_idx].driver_desc = NULL;
++      mutex_unlock(&g_mutex);
++
++      pr_debug("removed %s driver\n", driver_desc->name);
++}
++EXPORT_SYMBOL(gasket_unregister_device);
++
++static int __init gasket_init(void)
++{
++      int i;
++
++      mutex_lock(&g_mutex);
++      for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) {
++              g_descs[i].driver_desc = NULL;
++              mutex_init(&g_descs[i].mutex);
++      }
++
++      gasket_sysfs_init();
++
++      mutex_unlock(&g_mutex);
++      return 0;
++}
++
++MODULE_DESCRIPTION("Google Gasket driver framework");
++MODULE_VERSION(GASKET_FRAMEWORK_VERSION);
++MODULE_LICENSE("GPL v2");
++MODULE_AUTHOR("Rob Springer <rspringer@google.com>");
++module_init(gasket_init);
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_core.h b/drivers/staging/gasket-driver/gasket_core.h
+--- a/drivers/staging/gasket-driver/gasket_core.h      1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_core.h      2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,657 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Gasket generic driver. Defines the set of data types and functions necessary
++ * to define a driver using the Gasket generic driver framework.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++#ifndef __GASKET_CORE_H__
++#define __GASKET_CORE_H__
++
++#include <linux/cdev.h>
++#include <linux/compiler.h>
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/platform_device.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++
++#include "gasket_constants.h"
++
++/**
++ * struct gasket_num_name - Map numbers to names.
++ * @ein_num: Number.
++ * @ein_name: Name associated with the number, a char pointer.
++ *
++ * This structure maps numbers to names. It is used to provide printable enum
++ * names, e.g {0, "DEAD"} or {1, "ALIVE"}.
++ */
++struct gasket_num_name {
++      uint snn_num;
++      const char *snn_name;
++};
++
++/*
++ * Register location for packed interrupts.
++ * Each value indicates the location of an interrupt field (in units of
++ * gasket_driver_desc->interrupt_pack_width) within the containing register.
++ * In other words, this indicates the shift to use when creating a mask to
++ * extract/set bits within a register for a given interrupt.
++ */
++enum gasket_interrupt_packing {
++      PACK_0 = 0,
++      PACK_1 = 1,
++      PACK_2 = 2,
++      PACK_3 = 3,
++      UNPACKED = 4,
++};
++
++/* Type of the interrupt supported by the device. */
++enum gasket_interrupt_type {
++      PCI_MSIX = 0,
++      DEVICE_MANAGED = 1, /* Managed externally in device driver */
++};
++
++/*
++ * Used to describe a Gasket interrupt. Contains an interrupt index, a register,
++ * and packing data for that interrupt. The register and packing data
++ * fields are relevant only for PCI_MSIX interrupt type and can be
++ * set to 0 for everything else.
++ */
++struct gasket_interrupt_desc {
++      /* Device-wide interrupt index/number. */
++      int index;
++      /* The register offset controlling this interrupt. */
++      u64 reg;
++      /* The location of this interrupt inside register reg, if packed. */
++      int packing;
++};
++
++/*
++ * This enum is used to identify memory regions being part of the physical
++ * memory that belongs to a device.
++ */
++enum mappable_area_type {
++      PCI_BAR = 0, /* Default */
++      BUS_REGION,  /* For SYSBUS devices, i.e. AXI etc... */
++      COHERENT_MEMORY
++};
++
++/*
++ * Metadata for each BAR mapping.
++ * This struct is used so as to track PCI memory, I/O space, AXI and coherent
++ * memory area... i.e. memory objects which can be referenced in the device's
++ * mmap function.
++ */
++struct gasket_bar_data {
++      /* Virtual base address. */
++      u8 __iomem *virt_base;
++
++      /* Physical base address. */
++      ulong phys_base;
++
++      /* Length of the mapping. */
++      ulong length_bytes;
++
++      /* Type of mappable area */
++      enum mappable_area_type type;
++};
++
++/* Maintains device open ownership data. */
++struct gasket_ownership {
++      /* 1 if the device is owned, 0 otherwise. */
++      int is_owned;
++
++      /* TGID of the owner. */
++      pid_t owner;
++
++      /* Count of current device opens in write mode. */
++      int write_open_count;
++};
++
++/* Page table modes of operation. */
++enum gasket_page_table_mode {
++      /* The page table is partitionable as normal, all simple by default. */
++      GASKET_PAGE_TABLE_MODE_NORMAL,
++
++      /* All entries are always simple. */
++      GASKET_PAGE_TABLE_MODE_SIMPLE,
++
++      /* All entries are always extended. No extended bit is used. */
++      GASKET_PAGE_TABLE_MODE_EXTENDED,
++};
++
++/* Page table configuration. One per table. */
++struct gasket_page_table_config {
++      /* The identifier/index of this page table. */
++      int id;
++
++      /* The operation mode of this page table. */
++      enum gasket_page_table_mode mode;
++
++      /* Total (first-level) entries in this page table. */
++      ulong total_entries;
++
++      /* Base register for the page table. */
++      int base_reg;
++
++      /*
++       * Register containing the extended page table. This value is unused in
++       * GASKET_PAGE_TABLE_MODE_SIMPLE and GASKET_PAGE_TABLE_MODE_EXTENDED
++       * modes.
++       */
++      int extended_reg;
++
++      /* The bit index indicating whether a PT entry is extended. */
++      int extended_bit;
++};
++
++/* Maintains information about a device node. */
++struct gasket_cdev_info {
++      /* The internal name of this device. */
++      char name[GASKET_NAME_MAX];
++
++      /* Device number. */
++      dev_t devt;
++
++      /* Kernel-internal device structure. */
++      struct device *device;
++
++      /* Character device for real. */
++      struct cdev cdev;
++
++      /* Flag indicating if cdev_add has been called for the devices. */
++      int cdev_added;
++
++      /* Pointer to the overall gasket_dev struct for this device. */
++      struct gasket_dev *gasket_dev_ptr;
++
++      /* Ownership data for the device in question. */
++      struct gasket_ownership ownership;
++};
++
++/* Describes the offset and length of mmapable device BAR regions. */
++struct gasket_mappable_region {
++      u64 start;
++      u64 length_bytes;
++};
++
++/* Describe the offset, size, and permissions for a device bar. */
++struct gasket_bar_desc {
++      /*
++       * The size of each PCI BAR range, in bytes. If a value is 0, that BAR
++       * will not be mapped into kernel space at all.
++       * For devices with 64 bit BARs, only elements 0, 2, and 4 should be
++       * populated, and 1, 3, and 5 should be set to 0.
++       * For example, for a device mapping 1M in each of the first two 64-bit
++       * BARs, this field would be set as { 0x100000, 0, 0x100000, 0, 0, 0 }
++       * (one number per bar_desc struct.)
++       */
++      u64 size;
++      /* The permissions for this bar. (Should be VM_WRITE/VM_READ/VM_EXEC,
++       * and can be or'd.) If set to GASKET_NOMAP, the bar will
++       * not be used for mmapping.
++       */
++      ulong permissions;
++      /* The memory address corresponding to the base of this bar, if used. */
++      u64 base;
++      /* The number of mappable regions in this bar. */
++      int num_mappable_regions;
++
++      /* The mappable subregions of this bar. */
++      const struct gasket_mappable_region *mappable_regions;
++
++      /* Type of mappable area */
++      enum mappable_area_type type;
++};
++
++/* Describes the offset, size, and permissions for a coherent buffer. */
++struct gasket_coherent_buffer_desc {
++      /* The size of the coherent buffer. */
++      u64 size;
++
++      /* The permissions for this bar. (Should be VM_WRITE/VM_READ/VM_EXEC,
++       * and can be or'd.) If set to GASKET_NOMAP, the bar will
++       * not be used for mmaping.
++       */
++      ulong permissions;
++
++      /* device side address. */
++      u64 base;
++};
++
++/* Coherent buffer structure. */
++struct gasket_coherent_buffer {
++      /* Virtual base address. */
++      u8 __iomem *virt_base;
++
++      /* Physical base address. */
++      dma_addr_t phys_base;
++
++      /* Length of the mapping. */
++      ulong length_bytes;
++};
++
++/* Description of Gasket-specific permissions in the mmap field. */
++enum gasket_mapping_options { GASKET_NOMAP = 0 };
++
++/* This struct represents an undefined bar that should never be mapped. */
++#define GASKET_UNUSED_BAR                                                      \
++      {                                                                      \
++              0, GASKET_NOMAP, 0, 0, NULL, 0                                 \
++      }
++
++/* Internal data for a Gasket device. See gasket_core.c for more information. */
++struct gasket_internal_desc;
++
++#define MAX_NUM_COHERENT_PAGES 16
++
++/*
++ * Device data for Gasket device instances.
++ *
++ * This structure contains the data required to manage a Gasket device.
++ */
++struct gasket_dev {
++      /* Pointer to the internal driver description for this device. */
++      struct gasket_internal_desc *internal_desc;
++
++      /* Device info */
++      struct device *dev;
++
++      /* DMA device to use, may be same as above or a parent */
++      struct device *dma_dev;
++
++      /* PCI device pointer for PCI devices */
++      struct pci_dev *pci_dev;
++
++      /* Platform device pointer for platform devices */
++      struct platform_device *platform_dev;
++
++      /* This device's index into internal_desc->devs. */
++      int dev_idx;
++
++      /* The name of this device, as reported by the kernel. */
++      char kobj_name[GASKET_NAME_MAX];
++
++      /* Virtual address of mapped BAR memory range. */
++      struct gasket_bar_data bar_data[GASKET_NUM_BARS];
++
++      /* Coherent buffer. */
++      struct gasket_coherent_buffer coherent_buffer;
++
++      /* Number of page tables for this device. */
++      int num_page_tables;
++
++      /* Address translations. Page tables have a private implementation. */
++      struct gasket_page_table *page_table[GASKET_MAX_NUM_PAGE_TABLES];
++
++      /* Interrupt data for this device. */
++      struct gasket_interrupt_data *interrupt_data;
++
++      /* Status for this device - GASKET_STATUS_ALIVE or _DEAD. */
++      uint status;
++
++      /* Number of times this device has been reset. */
++      uint reset_count;
++
++      /* Dev information for the cdev node. */
++      struct gasket_cdev_info dev_info;
++
++      /* Hardware revision value for this device. */
++      int hardware_revision;
++
++      /* Protects access to per-device data (i.e. this structure). */
++      struct mutex mutex;
++
++      /* cdev hash tracking/membership structure, Accel and legacy. */
++      /* Unused until Accel is upstreamed. */
++      struct hlist_node hlist_node;
++      struct hlist_node legacy_hlist_node;
++};
++
++/* Type of the ioctl handler callback. */
++typedef long (*gasket_ioctl_handler_cb_t)(struct file *file, uint cmd,
++                                        void __user *argp);
++/* Type of the ioctl permissions check callback. See below. */
++typedef int (*gasket_ioctl_permissions_cb_t)(struct file *filp, uint cmd,
++                                           void __user *argp);
++
++/*
++ * Device type descriptor.
++ *
++ * This structure contains device-specific data needed to identify and address a
++ * type of device to be administered via the Gasket generic driver.
++ *
++ * Device IDs are per-driver. In other words, two drivers using the Gasket
++ * framework will each have a distinct device 0 (for example).
++ */
++struct gasket_driver_desc {
++      /* The name of this device type. */
++      const char *name;
++
++      /* The name of this specific device model. */
++      const char *chip_model;
++
++      /* The version of the chip specified in chip_model. */
++      const char *chip_version;
++
++      /* The version of this driver: "1.0.0", "2.1.3", etc. */
++      const char *driver_version;
++
++      /*
++       * Non-zero if we should create "legacy" (device and device-class-
++       * specific) character devices and sysfs nodes.
++       */
++      /* Unused until Accel is upstreamed. */
++      int legacy_support;
++
++      /* Major and minor numbers identifying the device. */
++      int major, minor;
++
++      /* Module structure for this driver. */
++      struct module *module;
++
++      /* PCI ID table. */
++      const struct pci_device_id *pci_id_table;
++
++      /* The number of page tables handled by this driver. */
++      int num_page_tables;
++
++      /* The index of the bar containing the page tables. */
++      int page_table_bar_index;
++
++      /* Registers used to control each page table. */
++      const struct gasket_page_table_config *page_table_configs;
++
++      /* The bit index indicating whether a PT entry is extended. */
++      int page_table_extended_bit;
++
++      /*
++       * Legacy mmap address adjusment for legacy devices only. Should be 0
++       * for any new device.
++       */
++      ulong legacy_mmap_address_offset;
++
++      /* Set of 6 bar descriptions that describe all PCIe bars.
++       * Note that BUS/AXI devices (i.e. non PCI devices) use those.
++       */
++      struct gasket_bar_desc bar_descriptions[GASKET_NUM_BARS];
++
++      /*
++       * Coherent buffer description.
++       */
++      struct gasket_coherent_buffer_desc coherent_buffer_description;
++
++      /* Interrupt type. (One of gasket_interrupt_type). */
++      int interrupt_type;
++
++      /* Index of the bar containing the interrupt registers to program. */
++      int interrupt_bar_index;
++
++      /* Number of interrupts in the gasket_interrupt_desc array */
++      int num_interrupts;
++
++      /* Description of the interrupts for this device. */
++      const struct gasket_interrupt_desc *interrupts;
++
++      /*
++       * If this device packs multiple interrupt->MSI-X mappings into a
++       * single register (i.e., "uses packed interrupts"), only a single bit
++       * width is supported for each interrupt mapping (unpacked/"full-width"
++       * interrupts are always supported). This value specifies that width. If
++       * packed interrupts are not used, this value is ignored.
++       */
++      int interrupt_pack_width;
++
++      /* Driver callback functions - all may be NULL */
++      /*
++       * device_open_cb: Callback for when a device node is opened in write
++       * mode.
++       * @dev: The gasket_dev struct for this driver instance.
++       *
++       * This callback should perform device-specific setup that needs to
++       * occur only once when a device is first opened.
++       */
++      int (*device_open_cb)(struct gasket_dev *dev);
++
++      /*
++       * device_release_cb: Callback when a device is closed.
++       * @gasket_dev: The gasket_dev struct for this driver instance.
++       *
++       * This callback is called whenever a device node fd is closed, as
++       * opposed to device_close_cb, which is called when the _last_
++       * descriptor for an open file is closed. This call is intended to
++       * handle any per-user or per-fd cleanup.
++       */
++      int (*device_release_cb)(struct gasket_dev *gasket_dev,
++                               struct file *file);
++
++      /*
++       * device_close_cb: Callback for when a device node is closed for the
++       * last time.
++       * @dev: The gasket_dev struct for this driver instance.
++       *
++       * This callback should perform device-specific cleanup that only
++       * needs to occur when the last reference to a device node is closed.
++       *
++       * This call is intended to handle and device-wide cleanup, as opposed
++       * to per-fd cleanup (which should be handled by device_release_cb).
++       */
++      int (*device_close_cb)(struct gasket_dev *dev);
++
++      /*
++       * get_mappable_regions_cb: Get descriptors of mappable device memory.
++       * @gasket_dev: Pointer to the struct gasket_dev for this device.
++       * @bar_index: BAR for which to retrieve memory ranges.
++       * @mappable_regions: Out-pointer to the list of mappable regions on the
++       * device/BAR for this process.
++       * @num_mappable_regions: Out-pointer for the size of mappable_regions.
++       *
++       * Called when handling mmap(), this callback is used to determine which
++       * regions of device memory may be mapped by the current process. This
++       * information is then compared to mmap request to determine which
++       * regions to actually map.
++       */
++      int (*get_mappable_regions_cb)(struct gasket_dev *gasket_dev,
++                                     int bar_index,
++                                     struct gasket_mappable_region **mappable_regions,
++                                     int *num_mappable_regions);
++
++      /*
++       * ioctl_permissions_cb: Check permissions for generic ioctls.
++       * @filp: File structure pointer describing this node usage session.
++       * @cmd: ioctl number to handle.
++       * @arg: ioctl-specific data pointer.
++       *
++       * Returns 1 if the ioctl may be executed, 0 otherwise. If this callback
++       * isn't specified a default routine will be used, that only allows the
++       * original device opener (i.e, the "owner") to execute state-affecting
++       * ioctls.
++       */
++      gasket_ioctl_permissions_cb_t ioctl_permissions_cb;
++
++      /*
++       * ioctl_handler_cb: Callback to handle device-specific ioctls.
++       * @filp: File structure pointer describing this node usage session.
++       * @cmd: ioctl number to handle.
++       * @arg: ioctl-specific data pointer.
++       *
++       * Invoked whenever an ioctl is called that the generic Gasket
++       * framework doesn't support. If no cb is registered, unknown ioctls
++       * return -EINVAL. Should return an error status (either -EINVAL or
++       * the error result of the ioctl being handled).
++       */
++      gasket_ioctl_handler_cb_t ioctl_handler_cb;
++
++      /*
++       * device_status_cb: Callback to determine device health.
++       * @dev: Pointer to the gasket_dev struct for this device.
++       *
++       * Called to determine if the device is healthy or not. Should return
++       * a member of the gasket_status_type enum.
++       *
++       */
++      int (*device_status_cb)(struct gasket_dev *dev);
++
++      /*
++       * hardware_revision_cb: Get the device's hardware revision.
++       * @dev: Pointer to the gasket_dev struct for this device.
++       *
++       * Called to determine the reported rev of the physical hardware.
++       * Revision should be >0. A negative return value is an error.
++       */
++      int (*hardware_revision_cb)(struct gasket_dev *dev);
++
++      /*
++       * device_reset_cb: Reset the hardware in question.
++       * @dev: Pointer to the gasket_dev structure for this device.
++       *
++       * Called by reset ioctls. This function should not
++       * lock the gasket_dev mutex. It should return 0 on success
++       * and an error on failure.
++       */
++      int (*device_reset_cb)(struct gasket_dev *dev);
++};
++
++/*
++ * Register the specified device type with the framework.
++ * @desc: Populated/initialized device type descriptor.
++ *
++ * This function does _not_ take ownership of desc; the underlying struct must
++ * exist until the matching call to gasket_unregister_device.
++ * This function should be called from your driver's module_init function.
++ */
++int gasket_register_device(const struct gasket_driver_desc *desc);
++
++/*
++ * Remove the specified device type from the framework.
++ * @desc: Descriptor for the device type to unregister; it should have been
++ *        passed to gasket_register_device in a previous call.
++ *
++ * This function should be called from your driver's module_exit function.
++ */
++void gasket_unregister_device(const struct gasket_driver_desc *desc);
++
++/* Add a PCI gasket device. */
++int gasket_pci_add_device(struct pci_dev *pci_dev,
++                        struct gasket_dev **gasket_devp);
++/* Remove a PCI gasket device. */
++void gasket_pci_remove_device(struct pci_dev *pci_dev);
++
++/* Add a platform gasket device. */
++int gasket_platform_add_device(struct platform_device *pdev,
++                             struct gasket_dev **gasket_devp);
++
++/* Remove a platform gasket device. */
++void gasket_platform_remove_device(struct platform_device *pdev);
++
++/* Set DMA device to use (if different from PCI/platform device) */
++void gasket_set_dma_device(struct gasket_dev *gasket_dev,
++                         struct device *dma_dev);
++
++/* Enable a Gasket device. */
++int gasket_enable_device(struct gasket_dev *gasket_dev);
++
++/* Disable a Gasket device. */
++void gasket_disable_device(struct gasket_dev *gasket_dev);
++
++/*
++ * Reset the Gasket device.
++ * @gasket_dev: Gasket device struct.
++ *
++ * Calls device_reset_cb. Returns 0 on success and an error code othewrise.
++ * gasket_reset_nolock will not lock the mutex, gasket_reset will.
++ *
++ */
++int gasket_reset(struct gasket_dev *gasket_dev);
++int gasket_reset_nolock(struct gasket_dev *gasket_dev);
++
++/*
++ * Memory management functions. These will likely be spun off into their own
++ * file in the future.
++ */
++
++/* Unmaps the specified mappable region from a VMA. */
++int gasket_mm_unmap_region(const struct gasket_dev *gasket_dev,
++                         struct vm_area_struct *vma,
++                         const struct gasket_mappable_region *map_region);
++
++/*
++ * Get the ioctl permissions callback.
++ * @gasket_dev: Gasket device structure.
++ */
++gasket_ioctl_permissions_cb_t
++gasket_get_ioctl_permissions_cb(struct gasket_dev *gasket_dev);
++
++/**
++ * Lookup a name by number in a num_name table.
++ * @num: Number to lookup.
++ * @table: Array of num_name structures, the table for the lookup.
++ *
++ */
++const char *gasket_num_name_lookup(uint num,
++                                 const struct gasket_num_name *table);
++
++/* Handy inlines */
++static inline u64 gasket_dev_read_64(struct gasket_dev *gasket_dev, int bar,
++                                     ulong location)
++{
++      return readq_relaxed(&gasket_dev->bar_data[bar].virt_base[location]);
++}
++
++static inline void gasket_dev_write_64(struct gasket_dev *dev, u64 value,
++                                     int bar, ulong location)
++{
++      writeq_relaxed(value, &dev->bar_data[bar].virt_base[location]);
++}
++
++static inline void gasket_dev_write_32(struct gasket_dev *dev, u32 value,
++                                     int bar, ulong location)
++{
++      writel_relaxed(value, &dev->bar_data[bar].virt_base[location]);
++}
++
++static inline u32 gasket_dev_read_32(struct gasket_dev *dev, int bar,
++                                   ulong location)
++{
++      return readl_relaxed(&dev->bar_data[bar].virt_base[location]);
++}
++
++static inline void gasket_read_modify_write_64(struct gasket_dev *dev, int bar,
++                                             ulong location, u64 value,
++                                             u64 mask_width, u64 mask_shift)
++{
++      u64 mask, tmp;
++
++      tmp = gasket_dev_read_64(dev, bar, location);
++      mask = ((1ULL << mask_width) - 1) << mask_shift;
++      tmp = (tmp & ~mask) | (value << mask_shift);
++      gasket_dev_write_64(dev, tmp, bar, location);
++}
++
++static inline void gasket_read_modify_write_32(struct gasket_dev *dev, int bar,
++                                             ulong location, u32 value,
++                                             u32 mask_width, u32 mask_shift)
++{
++      u32 mask, tmp;
++
++      tmp = gasket_dev_read_32(dev, bar, location);
++      mask = ((1 << mask_width) - 1) << mask_shift;
++      tmp = (tmp & ~mask) | (value << mask_shift);
++      gasket_dev_write_32(dev, tmp, bar, location);
++}
++
++/* Get the Gasket driver structure for a given device. */
++const struct gasket_driver_desc *gasket_get_driver_desc(struct gasket_dev *dev);
++
++/* Get the device structure for a given device. */
++struct device *gasket_get_device(struct gasket_dev *dev);
++
++/* Helper function, Asynchronous waits on a given set of bits. */
++int gasket_wait_with_reschedule(struct gasket_dev *gasket_dev, int bar,
++                              u64 offset, u64 mask, u64 val,
++                              uint max_retries, u64 delay_ms);
++
++#endif /* __GASKET_CORE_H__ */
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket.h b/drivers/staging/gasket-driver/gasket.h
+--- a/drivers/staging/gasket-driver/gasket.h   1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket.h   2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,177 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Common Gasket device kernel and user space declarations.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++#ifndef __GASKET_H__
++#define __GASKET_H__
++
++#include <linux/ioctl.h>
++#include <linux/types.h>
++
++/* ioctl structure declarations */
++
++/* Ioctl structures are padded to a multiple of 64 bits */
++/* and padded to put 64 bit values on 64 bit boundaries. */
++/* Unsigned 64 bit integers are used to hold pointers. */
++/* This helps compatibility between 32 and 64 bits. */
++
++/*
++ * Common structure for ioctls associating an eventfd with a device interrupt,
++ * when using the Gasket interrupt module.
++ */
++struct gasket_interrupt_eventfd {
++      u64 interrupt;
++      u64 event_fd;
++};
++
++/*
++ * Common structure for ioctls mapping and unmapping buffers when using the
++ * Gasket page_table module.
++ */
++struct gasket_page_table_ioctl {
++      u64 page_table_index;
++      u64 size;
++      u64 host_address;
++      u64 device_address;
++};
++
++/*
++ * Structure for ioctl mapping buffers with flags when using the Gasket
++ * page_table module.
++ */
++struct gasket_page_table_ioctl_flags {
++      struct gasket_page_table_ioctl base;
++      /*
++       * Flags indicating status and attribute requests from the host.
++       * NOTE: STATUS bit does not need to be set in this request.
++       *       Set RESERVED bits to 0 to ensure backwards compatibility.
++       *
++       * Bitfields:
++       *   [0]     - STATUS: indicates if this entry/slot is free
++       *                0 = PTE_FREE
++       *                1 = PTE_INUSE
++       *   [2:1]   - DMA_DIRECTION: dma_data_direction requested by host
++       *               00 = DMA_BIDIRECTIONAL
++       *               01 = DMA_TO_DEVICE
++       *               10 = DMA_FROM_DEVICE
++       *               11 = DMA_NONE
++       *   [31:3]  - RESERVED
++       */
++      u32 flags;
++};
++
++/*
++ * Common structure for ioctls mapping and unmapping buffers when using the
++ * Gasket page_table module.
++ * dma_address: phys addr start of coherent memory, allocated by kernel
++ */
++struct gasket_coherent_alloc_config_ioctl {
++      u64 page_table_index;
++      u64 enable;
++      u64 size;
++      u64 dma_address;
++};
++
++/*
++ * Common structure for ioctls mapping and unmapping dma-bufs when using the
++ * Gasket page_table module.
++ * map: boolean, non-zero to map, 0 to unmap.
++ * flags: see gasket_page_table_ioctl_flags.flags.
++ */
++struct gasket_page_table_ioctl_dmabuf {
++      u64 page_table_index;
++      u64 device_address;
++      int dmabuf_fd;
++      u32 num_pages;
++      u32 map;
++      u32 flags;
++};
++
++/* Base number for all Gasket-common IOCTLs */
++#define GASKET_IOCTL_BASE 0xDC
++
++/* Reset the device. */
++#define GASKET_IOCTL_RESET _IO(GASKET_IOCTL_BASE, 0)
++
++/* Associate the specified [event]fd with the specified interrupt. */
++#define GASKET_IOCTL_SET_EVENTFD                                               \
++      _IOW(GASKET_IOCTL_BASE, 1, struct gasket_interrupt_eventfd)
++
++/*
++ * Clears any eventfd associated with the specified interrupt. The (ulong)
++ * argument is the interrupt number to clear.
++ */
++#define GASKET_IOCTL_CLEAR_EVENTFD _IOW(GASKET_IOCTL_BASE, 2, unsigned long)
++
++/*
++ * [Loopbacks only] Requests that the loopback device send the specified
++ * interrupt to the host. The (ulong) argument is the number of the interrupt to
++ * send.
++ */
++#define GASKET_IOCTL_LOOPBACK_INTERRUPT                                        \
++      _IOW(GASKET_IOCTL_BASE, 3, unsigned long)
++
++/* Queries the kernel for the number of page tables supported by the device. */
++#define GASKET_IOCTL_NUMBER_PAGE_TABLES _IOR(GASKET_IOCTL_BASE, 4, u64)
++
++/*
++ * Queries the kernel for the maximum size of the page table.  Only the size and
++ * page_table_index fields are used from the struct gasket_page_table_ioctl.
++ */
++#define GASKET_IOCTL_PAGE_TABLE_SIZE                                           \
++      _IOWR(GASKET_IOCTL_BASE, 5, struct gasket_page_table_ioctl)
++
++/*
++ * Queries the kernel for the current simple page table size.  Only the size and
++ * page_table_index fields are used from the struct gasket_page_table_ioctl.
++ */
++#define GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE                                    \
++      _IOWR(GASKET_IOCTL_BASE, 6, struct gasket_page_table_ioctl)
++
++/*
++ * Tells the kernel to change the split between the number of simple and
++ * extended entries in the given page table. Only the size and page_table_index
++ * fields are used from the struct gasket_page_table_ioctl.
++ */
++#define GASKET_IOCTL_PARTITION_PAGE_TABLE                                      \
++      _IOW(GASKET_IOCTL_BASE, 7, struct gasket_page_table_ioctl)
++
++/*
++ * Tells the kernel to map size bytes at host_address to device_address in
++ * page_table_index page table.
++ */
++#define GASKET_IOCTL_MAP_BUFFER                                                \
++      _IOW(GASKET_IOCTL_BASE, 8, struct gasket_page_table_ioctl)
++
++/*
++ * Tells the kernel to unmap size bytes at host_address from device_address in
++ * page_table_index page table.
++ */
++#define GASKET_IOCTL_UNMAP_BUFFER                                              \
++      _IOW(GASKET_IOCTL_BASE, 9, struct gasket_page_table_ioctl)
++
++/* Clear the interrupt counts stored for this device. */
++#define GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS _IO(GASKET_IOCTL_BASE, 10)
++
++/* Enable/Disable and configure the coherent allocator. */
++#define GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR                                 \
++      _IOWR(GASKET_IOCTL_BASE, 11, struct gasket_coherent_alloc_config_ioctl)
++
++/*
++ * Tells the kernel to map size bytes at host_address to device_address in
++ * page_table_index page table. Passes flags to indicate additional attribute
++ * requests for the mapped memory.
++ */
++#define GASKET_IOCTL_MAP_BUFFER_FLAGS                                          \
++      _IOW(GASKET_IOCTL_BASE, 12, struct gasket_page_table_ioctl_flags)
++
++/*
++ * Tells the kernel to map/unmap dma-buf with fd to device_address in
++ * page_table_index page table.
++ */
++#define GASKET_IOCTL_MAP_DMABUF                                                \
++      _IOW(GASKET_IOCTL_BASE, 13, struct gasket_page_table_ioctl_dmabuf)
++
++#endif /* __GASKET_H__ */
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_interrupt.c b/drivers/staging/gasket-driver/gasket_interrupt.c
+--- a/drivers/staging/gasket-driver/gasket_interrupt.c 1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_interrupt.c 2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,559 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (C) 2018 Google, Inc. */
++
++#include "gasket_interrupt.h"
++
++#include "gasket_constants.h"
++#include "gasket_core.h"
++#include "gasket_sysfs.h"
++#include <linux/device.h>
++#include <linux/interrupt.h>
++#include <linux/printk.h>
++#include <linux/spinlock.h>
++#include <linux/version.h>
++#ifdef GASKET_KERNEL_TRACE_SUPPORT
++#define CREATE_TRACE_POINTS
++#include <trace/events/gasket_interrupt.h>
++#else
++#define trace_gasket_interrupt_event(x, ...)
++#endif
++/* Retry attempts if the requested number of interrupts aren't available. */
++#define MSIX_RETRY_COUNT 3
++
++/* Instance interrupt management data. */
++struct gasket_interrupt_data {
++      /* The name associated with this interrupt data. */
++      const char *name;
++
++      /* Interrupt type. See gasket_interrupt_type in gasket_core.h */
++      int type;
++
++      /* The PCI device [if any] associated with the owning device. */
++      struct pci_dev *pci_dev;
++
++      /* Set to 1 if MSI-X has successfully been configred, 0 otherwise. */
++      int msix_configured;
++
++      /* The number of interrupts requested by the owning device. */
++      int num_interrupts;
++
++      /* A pointer to the interrupt descriptor struct for this device. */
++      const struct gasket_interrupt_desc *interrupts;
++
++      /* The index of the bar into which interrupts should be mapped. */
++      int interrupt_bar_index;
++
++      /* The width of a single interrupt in a packed interrupt register. */
++      int pack_width;
++
++      /*
++       * Design-wise, these elements should be bundled together, but
++       * pci_enable_msix's interface requires that they be managed
++       * individually (requires array of struct msix_entry).
++       */
++
++      /* The number of successfully configured interrupts. */
++      int num_configured;
++
++      /* The MSI-X data for each requested/configured interrupt. */
++      struct msix_entry *msix_entries;
++
++      /* The eventfd "callback" data for each interrupt. */
++      struct eventfd_ctx **eventfd_ctxs;
++
++      /* Spinlock to protect read/write races to eventfd_ctxs. */
++      rwlock_t eventfd_ctx_lock;
++
++      /* The number of times each interrupt has been called. */
++      ulong *interrupt_counts;
++
++      /* Linux IRQ number. */
++      int irq;
++};
++
++/* Structures to display interrupt counts in sysfs. */
++enum interrupt_sysfs_attribute_type {
++      ATTR_INTERRUPT_COUNTS,
++};
++
++/* Set up device registers for interrupt handling. */
++static void gasket_interrupt_setup(struct gasket_dev *gasket_dev)
++{
++      int i;
++      int pack_shift;
++      u64 mask;
++      u64 value;
++      struct gasket_interrupt_data *interrupt_data =
++              gasket_dev->interrupt_data;
++
++      if (!interrupt_data) {
++              dev_dbg(gasket_dev->dev, "Interrupt data is not initialized\n");
++              return;
++      }
++
++      dev_dbg(gasket_dev->dev, "Running interrupt setup\n");
++
++      if (interrupt_data->type == DEVICE_MANAGED)
++              return; /* device driver handles setup */
++
++      /* Setup the MSIX table. */
++
++      for (i = 0; i < interrupt_data->num_interrupts; i++) {
++              /*
++               * If the interrupt is not packed, we can write the index into
++               * the register directly. If not, we need to deal with a read-
++               * modify-write and shift based on the packing index.
++               */
++              dev_dbg(gasket_dev->dev,
++                      "Setting up interrupt index %d with index 0x%llx and "
++                      "packing %d\n",
++                      interrupt_data->interrupts[i].index,
++                      interrupt_data->interrupts[i].reg,
++                      interrupt_data->interrupts[i].packing);
++              if (interrupt_data->interrupts[i].packing == UNPACKED) {
++                      value = interrupt_data->interrupts[i].index;
++              } else {
++                      switch (interrupt_data->interrupts[i].packing) {
++                      case PACK_0:
++                              pack_shift = 0;
++                              break;
++                      case PACK_1:
++                              pack_shift = interrupt_data->pack_width;
++                              break;
++                      case PACK_2:
++                              pack_shift = 2 * interrupt_data->pack_width;
++                              break;
++                      case PACK_3:
++                              pack_shift = 3 * interrupt_data->pack_width;
++                              break;
++                      default:
++                              dev_dbg(gasket_dev->dev,
++                                      "Found interrupt description with "
++                                      "unknown enum %d\n",
++                                      interrupt_data->interrupts[i].packing);
++                              return;
++                      }
++
++                      mask = ~(0xFFFF << pack_shift);
++                      value = gasket_dev_read_64(gasket_dev,
++                                                 interrupt_data->interrupt_bar_index,
++                                                 interrupt_data->interrupts[i].reg);
++                      value &= mask;
++                      value |= interrupt_data->interrupts[i].index
++                               << pack_shift;
++              }
++              gasket_dev_write_64(gasket_dev, value,
++                                  interrupt_data->interrupt_bar_index,
++                                  interrupt_data->interrupts[i].reg);
++      }
++}
++
++void
++gasket_handle_interrupt(struct gasket_interrupt_data *interrupt_data,
++                      int interrupt_index)
++{
++      struct eventfd_ctx *ctx;
++
++      trace_gasket_interrupt_event(interrupt_data->name, interrupt_index);
++      read_lock(&interrupt_data->eventfd_ctx_lock);
++      ctx = interrupt_data->eventfd_ctxs[interrupt_index];
++        if (ctx)
++                #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0)
++                        eventfd_signal(ctx);
++                #else
++                        eventfd_signal(ctx, 1);
++                #endif
++        read_unlock(&interrupt_data->eventfd_ctx_lock);
++
++      ++(interrupt_data->interrupt_counts[interrupt_index]);
++}
++
++static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id)
++{
++      struct gasket_interrupt_data *interrupt_data = dev_id;
++      int interrupt = -1;
++      int i;
++
++      /* If this linear lookup is a problem, we can maintain a map/hash. */
++      for (i = 0; i < interrupt_data->num_interrupts; i++) {
++              if (interrupt_data->msix_entries[i].vector == irq) {
++                      interrupt = interrupt_data->msix_entries[i].entry;
++                      break;
++              }
++      }
++      if (interrupt == -1) {
++              pr_err("Received unknown irq %d\n", irq);
++              return IRQ_HANDLED;
++      }
++      gasket_handle_interrupt(interrupt_data, interrupt);
++      return IRQ_HANDLED;
++}
++
++static int
++gasket_interrupt_msix_init(struct gasket_interrupt_data *interrupt_data)
++{
++      int ret = 1;
++      int i;
++
++      interrupt_data->msix_entries =
++              kcalloc(interrupt_data->num_interrupts,
++                      sizeof(struct msix_entry), GFP_KERNEL);
++      if (!interrupt_data->msix_entries)
++              return -ENOMEM;
++
++      for (i = 0; i < interrupt_data->num_interrupts; i++) {
++              interrupt_data->msix_entries[i].entry = i;
++              interrupt_data->msix_entries[i].vector = 0;
++              interrupt_data->eventfd_ctxs[i] = NULL;
++      }
++
++      /* Retry MSIX_RETRY_COUNT times if not enough IRQs are available. */
++      for (i = 0; i < MSIX_RETRY_COUNT && ret > 0; i++)
++              ret = pci_enable_msix_exact(interrupt_data->pci_dev,
++                                          interrupt_data->msix_entries,
++                                          interrupt_data->num_interrupts);
++
++      if (ret)
++              return ret > 0 ? -EBUSY : ret;
++      interrupt_data->msix_configured = 1;
++
++      for (i = 0; i < interrupt_data->num_interrupts; i++) {
++              ret = request_irq(interrupt_data->msix_entries[i].vector,
++                                gasket_msix_interrupt_handler, 0,
++                                interrupt_data->name, interrupt_data);
++
++              if (ret) {
++                      dev_err(&interrupt_data->pci_dev->dev,
++                              "Cannot get IRQ for interrupt %d, vector %d; "
++                              "%d\n",
++                              i, interrupt_data->msix_entries[i].vector, ret);
++                      return ret;
++              }
++
++              interrupt_data->num_configured++;
++      }
++
++      return 0;
++}
++
++/*
++ * On QCM DragonBoard, we exit gasket_interrupt_msix_init() and kernel interrupt
++ * setup code with MSIX vectors masked. This is wrong because nothing else in
++ * the driver will normally touch the MSIX vectors.
++ *
++ * As a temporary hack, force unmasking there.
++ *
++ * TODO: Figure out why QCM kernel doesn't unmask the MSIX vectors, after
++ * gasket_interrupt_msix_init(), and remove this code.
++ */
++static void force_msix_interrupt_unmasking(struct gasket_dev *gasket_dev)
++{
++      int i;
++#define MSIX_VECTOR_SIZE 16
++#define MSIX_MASK_BIT_OFFSET 12
++#define APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE 0x46800
++      for (i = 0; i < gasket_dev->interrupt_data->num_configured; i++) {
++              /* Check if the MSIX vector is unmasked */
++              ulong location = APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE +
++                               MSIX_MASK_BIT_OFFSET + i * MSIX_VECTOR_SIZE;
++              u32 mask =
++                      gasket_dev_read_32(gasket_dev,
++                                         gasket_dev->interrupt_data->interrupt_bar_index,
++                                         location);
++              if (!(mask & 1))
++                      continue;
++              /* Unmask the msix vector (clear 32 bits) */
++              gasket_dev_write_32(gasket_dev, 0,
++                                  gasket_dev->interrupt_data->interrupt_bar_index,
++                                  location);
++      }
++#undef MSIX_VECTOR_SIZE
++#undef MSIX_MASK_BIT_OFFSET
++#undef APEX_BAR2_REG_KERNEL_HIB_MSIX_TABLE
++}
++
++static ssize_t interrupt_sysfs_show(struct device *device,
++                                  struct device_attribute *attr, char *buf)
++{
++      int i, ret;
++      ssize_t written = 0, total_written = 0;
++      struct gasket_interrupt_data *interrupt_data;
++      struct gasket_dev *gasket_dev;
++      struct gasket_sysfs_attribute *gasket_attr;
++      enum interrupt_sysfs_attribute_type sysfs_type;
++
++      gasket_dev = gasket_sysfs_get_device_data(device);
++      if (!gasket_dev) {
++              dev_dbg(device, "No sysfs mapping found for device\n");
++              return 0;
++      }
++
++      gasket_attr = gasket_sysfs_get_attr(device, attr);
++      if (!gasket_attr) {
++              dev_dbg(device, "No sysfs attr data found for device\n");
++              gasket_sysfs_put_device_data(device, gasket_dev);
++              return 0;
++      }
++
++      sysfs_type = (enum interrupt_sysfs_attribute_type)
++              gasket_attr->data.attr_type;
++      interrupt_data = gasket_dev->interrupt_data;
++      switch (sysfs_type) {
++      case ATTR_INTERRUPT_COUNTS:
++              for (i = 0; i < interrupt_data->num_interrupts; ++i) {
++                      written =
++                              scnprintf(buf, PAGE_SIZE - total_written,
++                                        "0x%02x: %ld\n", i,
++                                        interrupt_data->interrupt_counts[i]);
++                      total_written += written;
++                      buf += written;
++              }
++              ret = total_written;
++              break;
++      default:
++              dev_dbg(gasket_dev->dev, "Unknown attribute: %s\n",
++                      attr->attr.name);
++              ret = 0;
++              break;
++      }
++
++      gasket_sysfs_put_attr(device, gasket_attr);
++      gasket_sysfs_put_device_data(device, gasket_dev);
++      return ret;
++}
++
++static struct gasket_sysfs_attribute interrupt_sysfs_attrs[] = {
++      GASKET_SYSFS_RO(interrupt_counts, interrupt_sysfs_show,
++                      ATTR_INTERRUPT_COUNTS),
++      GASKET_END_OF_ATTR_ARRAY,
++};
++
++int gasket_interrupt_init(struct gasket_dev *gasket_dev)
++{
++      int ret;
++      struct gasket_interrupt_data *interrupt_data;
++      const struct gasket_driver_desc *driver_desc =
++              gasket_get_driver_desc(gasket_dev);
++
++      interrupt_data = kzalloc(sizeof(struct gasket_interrupt_data),
++                               GFP_KERNEL);
++      if (!interrupt_data)
++              return -ENOMEM;
++      gasket_dev->interrupt_data = interrupt_data;
++      interrupt_data->name = driver_desc->name;
++      interrupt_data->type = driver_desc->interrupt_type;
++      interrupt_data->pci_dev = gasket_dev->pci_dev;
++      interrupt_data->num_interrupts = driver_desc->num_interrupts;
++      interrupt_data->interrupts = driver_desc->interrupts;
++      interrupt_data->interrupt_bar_index = driver_desc->interrupt_bar_index;
++      interrupt_data->pack_width = driver_desc->interrupt_pack_width;
++
++      interrupt_data->eventfd_ctxs = kcalloc(driver_desc->num_interrupts,
++                                             sizeof(struct eventfd_ctx *),
++                                             GFP_KERNEL);
++      if (!interrupt_data->eventfd_ctxs) {
++              kfree(interrupt_data);
++              return -ENOMEM;
++      }
++
++      interrupt_data->interrupt_counts = kcalloc(driver_desc->num_interrupts,
++                                                 sizeof(ulong),
++                                                 GFP_KERNEL);
++      if (!interrupt_data->interrupt_counts) {
++              kfree(interrupt_data->eventfd_ctxs);
++              kfree(interrupt_data);
++              return -ENOMEM;
++      }
++
++      rwlock_init(&interrupt_data->eventfd_ctx_lock);
++
++      switch (interrupt_data->type) {
++      case PCI_MSIX:
++              ret = gasket_interrupt_msix_init(interrupt_data);
++              if (ret)
++                      break;
++              force_msix_interrupt_unmasking(gasket_dev);
++              break;
++
++      case DEVICE_MANAGED:  /* Device driver manages IRQ init */
++              interrupt_data->num_configured = interrupt_data->num_interrupts;
++              ret = 0;
++              break;
++
++      default:
++              ret = -EINVAL;
++      }
++
++      if (ret) {
++              /* Failing to setup interrupts will cause the device to report
++               * GASKET_STATUS_LAMED. But it is not fatal.
++               */
++              dev_warn(gasket_dev->dev,
++                       "Couldn't initialize interrupts: %d\n", ret);
++              return 0;
++      }
++
++      gasket_interrupt_setup(gasket_dev);
++      gasket_sysfs_create_entries(gasket_dev->dev_info.device,
++                                  interrupt_sysfs_attrs);
++
++      return 0;
++}
++EXPORT_SYMBOL(gasket_interrupt_init);
++
++void gasket_interrupt_msix_cleanup(struct gasket_interrupt_data *interrupt_data)
++{
++      int i;
++
++      for (i = 0; i < interrupt_data->num_configured; i++) {
++              gasket_interrupt_clear_eventfd(interrupt_data, i);
++              free_irq(interrupt_data->msix_entries[i].vector,
++                       interrupt_data);
++      }
++      interrupt_data->num_configured = 0;
++
++      if (interrupt_data->msix_configured)
++              pci_disable_msix(interrupt_data->pci_dev);
++      interrupt_data->msix_configured = 0;
++      kfree(interrupt_data->msix_entries);
++      interrupt_data->msix_entries = NULL;
++}
++EXPORT_SYMBOL(gasket_interrupt_msix_cleanup);
++
++int gasket_interrupt_reinit(struct gasket_dev *gasket_dev)
++{
++      int ret;
++
++      if (!gasket_dev->interrupt_data) {
++              dev_dbg(gasket_dev->dev,
++                      "Attempted to reinit uninitialized interrupt data\n");
++              return -EINVAL;
++      }
++
++      switch (gasket_dev->interrupt_data->type) {
++      case PCI_MSIX:
++              gasket_interrupt_msix_cleanup(gasket_dev->interrupt_data);
++              ret = gasket_interrupt_msix_init(gasket_dev->interrupt_data);
++              if (ret)
++                      break;
++              force_msix_interrupt_unmasking(gasket_dev);
++              break;
++
++      case DEVICE_MANAGED: /* Device driver manages IRQ reinit */
++              ret = 0;
++              break;
++
++      default:
++              ret = -EINVAL;
++      }
++
++      if (ret) {
++              /* Failing to setup interrupts will cause the device
++               * to report GASKET_STATUS_LAMED, but is not fatal.
++               */
++              dev_warn(gasket_dev->dev, "Couldn't reinit interrupts: %d\n",
++                       ret);
++              return 0;
++      }
++
++      gasket_interrupt_setup(gasket_dev);
++
++      return 0;
++}
++EXPORT_SYMBOL(gasket_interrupt_reinit);
++
++/* See gasket_interrupt.h for description. */
++int gasket_interrupt_reset_counts(struct gasket_dev *gasket_dev)
++{
++      dev_dbg(gasket_dev->dev, "Clearing interrupt counts\n");
++      memset(gasket_dev->interrupt_data->interrupt_counts, 0,
++             gasket_dev->interrupt_data->num_interrupts *
++                      sizeof(*gasket_dev->interrupt_data->interrupt_counts));
++      return 0;
++}
++
++/* See gasket_interrupt.h for description. */
++void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev)
++{
++      struct gasket_interrupt_data *interrupt_data =
++              gasket_dev->interrupt_data;
++      /*
++       * It is possible to get an error code from gasket_interrupt_init
++       * before interrupt_data has been allocated, so check it.
++       */
++      if (!interrupt_data)
++              return;
++
++      switch (interrupt_data->type) {
++      case PCI_MSIX:
++              gasket_interrupt_msix_cleanup(interrupt_data);
++              break;
++
++      case DEVICE_MANAGED: /* Device driver manages IRQ cleanup */
++              break;
++
++      default:
++              break;
++      }
++
++      kfree(interrupt_data->interrupt_counts);
++      kfree(interrupt_data->eventfd_ctxs);
++      kfree(interrupt_data);
++      gasket_dev->interrupt_data = NULL;
++}
++
++int gasket_interrupt_system_status(struct gasket_dev *gasket_dev)
++{
++      if (!gasket_dev->interrupt_data) {
++              dev_dbg(gasket_dev->dev, "Interrupt data is null\n");
++              return GASKET_STATUS_DEAD;
++      }
++
++      if (gasket_dev->interrupt_data->num_configured !=
++              gasket_dev->interrupt_data->num_interrupts) {
++              dev_dbg(gasket_dev->dev,
++                      "Not all interrupts were configured\n");
++              return GASKET_STATUS_LAMED;
++      }
++
++      return GASKET_STATUS_ALIVE;
++}
++
++int gasket_interrupt_set_eventfd(struct gasket_interrupt_data *interrupt_data,
++                               int interrupt, int event_fd)
++{
++      struct eventfd_ctx *ctx;
++      ulong flags;
++
++      if (interrupt < 0 || interrupt >= interrupt_data->num_interrupts)
++              return -EINVAL;
++
++      ctx = eventfd_ctx_fdget(event_fd);
++      if (IS_ERR(ctx))
++              return PTR_ERR(ctx);
++
++      /* Put the old eventfd ctx before setting, else we leak the ref. */
++      write_lock_irqsave(&interrupt_data->eventfd_ctx_lock, flags);
++      if (interrupt_data->eventfd_ctxs[interrupt] != NULL)
++              eventfd_ctx_put(interrupt_data->eventfd_ctxs[interrupt]);
++      interrupt_data->eventfd_ctxs[interrupt] = ctx;
++      write_unlock_irqrestore(&interrupt_data->eventfd_ctx_lock, flags);
++      return 0;
++}
++
++int gasket_interrupt_clear_eventfd(struct gasket_interrupt_data *interrupt_data,
++                                 int interrupt)
++{
++      ulong flags;
++
++      if (interrupt < 0 || interrupt >= interrupt_data->num_interrupts)
++              return -EINVAL;
++
++      /* Put the old eventfd ctx before clearing, else we leak the ref. */
++      write_lock_irqsave(&interrupt_data->eventfd_ctx_lock, flags);
++      if (interrupt_data->eventfd_ctxs[interrupt] != NULL)
++              eventfd_ctx_put(interrupt_data->eventfd_ctxs[interrupt]);
++      interrupt_data->eventfd_ctxs[interrupt] = NULL;
++      write_unlock_irqrestore(&interrupt_data->eventfd_ctx_lock, flags);
++      return 0;
++}
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_interrupt.h b/drivers/staging/gasket-driver/gasket_interrupt.h
+--- a/drivers/staging/gasket-driver/gasket_interrupt.h 1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_interrupt.h 2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,108 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Gasket common interrupt module. Defines functions for enabling
++ * eventfd-triggered interrupts between a Gasket device and a host process.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++#ifndef __GASKET_INTERRUPT_H__
++#define __GASKET_INTERRUPT_H__
++
++#include <linux/eventfd.h>
++#include <linux/pci.h>
++
++#include "gasket_core.h"
++
++/* Note that this currently assumes that device interrupts are a dense set,
++ * numbered from 0 - (num_interrupts - 1). Should this have to change, these
++ * APIs will have to be updated.
++ */
++
++/* Opaque type used to hold interrupt subsystem data. */
++struct gasket_interrupt_data;
++
++/*
++ * Initialize the interrupt module.
++ * @gasket_dev: The Gasket device structure for the device to be initted.
++ */
++int gasket_interrupt_init(struct gasket_dev *gasket_dev);
++
++/*
++ * Clean up a device's interrupt structure.
++ * @gasket_dev: The Gasket information structure for this device.
++ *
++ * Cleans up the device's interrupts and deallocates data.
++ */
++void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev);
++
++/*
++ * Clean up and re-initialize the MSI-x subsystem.
++ * @gasket_dev: The Gasket information structure for this device.
++ *
++ * Performs a teardown of the MSI-x subsystem and re-initializes it. Does not
++ * free the underlying data structures. Returns 0 on success and an error code
++ * on error.
++ */
++int gasket_interrupt_reinit(struct gasket_dev *gasket_dev);
++
++/*
++ * Clean up the MSI-x subsystem.
++ * @interrupt_data: The interrupt data structure for this device.
++ *
++ * Performs a teardown of the MSI-x subsystem. Does not free the underlying data structures.
++ */
++void gasket_interrupt_msix_cleanup(struct gasket_interrupt_data *interrupt_data);
++
++/* Handle gasket interrupt processing, called from an external handler. */
++void
++gasket_handle_interrupt(struct gasket_interrupt_data *interrupt_data,
++                      int interrupt_index);
++
++/*
++ * Reset the counts stored in the interrupt subsystem.
++ * @gasket_dev: The Gasket information structure for this device.
++ *
++ * Sets the counts of all interrupts in the subsystem to 0.
++ */
++int gasket_interrupt_reset_counts(struct gasket_dev *gasket_dev);
++
++/*
++ * Associates an eventfd with a device interrupt.
++ * @data: Pointer to device interrupt data.
++ * @interrupt: The device interrupt to configure.
++ * @event_fd: The eventfd to associate with the interrupt.
++ *
++ * Prepares the host to receive notification of device interrupts by associating
++ * event_fd with interrupt. Upon receipt of a device interrupt, event_fd will be
++ * signaled, after successful configuration.
++ *
++ * Returns 0 on success, a negative error code otherwise.
++ */
++int gasket_interrupt_set_eventfd(struct gasket_interrupt_data *interrupt_data,
++                               int interrupt, int event_fd);
++
++/*
++ * Removes an interrupt-eventfd association.
++ * @data: Pointer to device interrupt data.
++ * @interrupt: The device interrupt to de-associate.
++ *
++ * Removes any eventfd associated with the specified interrupt, if any.
++ */
++int gasket_interrupt_clear_eventfd(struct gasket_interrupt_data *interrupt_data,
++                                 int interrupt);
++
++/*
++ * The below functions exist for backwards compatibility.
++ * No new uses should be written.
++ */
++/*
++ * Get the health of the interrupt subsystem.
++ * @gasket_dev: The Gasket device struct.
++ *
++ * Returns DEAD if not set up, LAMED if initialization failed, and ALIVE
++ * otherwise.
++ */
++
++int gasket_interrupt_system_status(struct gasket_dev *gasket_dev);
++
++#endif
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_ioctl.c b/drivers/staging/gasket-driver/gasket_ioctl.c
+--- a/drivers/staging/gasket-driver/gasket_ioctl.c     1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_ioctl.c     2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,470 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (C) 2018 Google, Inc. */
++#include "gasket.h"
++#include "gasket_ioctl.h"
++#include "gasket_constants.h"
++#include "gasket_core.h"
++#include "gasket_interrupt.h"
++#include "gasket_page_table.h"
++#include <linux/compiler.h>
++#include <linux/device.h>
++#include <linux/fs.h>
++#include <linux/uaccess.h>
++
++#ifdef GASKET_KERNEL_TRACE_SUPPORT
++#define CREATE_TRACE_POINTS
++#include <trace/events/gasket_ioctl.h>
++#else
++#define trace_gasket_ioctl_entry(x, ...)
++#define trace_gasket_ioctl_exit(x)
++#define trace_gasket_ioctl_integer_data(x)
++#define trace_gasket_ioctl_eventfd_data(x, ...)
++#define trace_gasket_ioctl_page_table_data(x, ...)
++#define trace_gasket_ioctl_page_table_flags_data(x, ...)
++#define trace_gasket_ioctl_config_coherent_allocator(x, ...)
++#endif
++
++/* Associate an eventfd with an interrupt. */
++static int gasket_set_event_fd(struct gasket_dev *gasket_dev,
++                             struct gasket_interrupt_eventfd __user *argp)
++{
++      struct gasket_interrupt_eventfd die;
++
++      if (copy_from_user(&die, argp, sizeof(struct gasket_interrupt_eventfd)))
++              return -EFAULT;
++
++      trace_gasket_ioctl_eventfd_data(die.interrupt, die.event_fd);
++
++      return gasket_interrupt_set_eventfd(
++              gasket_dev->interrupt_data, die.interrupt, die.event_fd);
++}
++
++/* Read the size of the page table. */
++static int gasket_read_page_table_size(
++      struct gasket_dev *gasket_dev,
++      struct gasket_page_table_ioctl __user *argp)
++{
++      int ret = 0;
++      struct gasket_page_table_ioctl ibuf;
++
++      if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
++              return -EFAULT;
++
++      if (ibuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      ibuf.size = gasket_page_table_num_entries(
++              gasket_dev->page_table[ibuf.page_table_index]);
++
++      trace_gasket_ioctl_page_table_data(
++              ibuf.page_table_index, ibuf.size, ibuf.host_address,
++              ibuf.device_address);
++
++      if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
++              return -EFAULT;
++
++      return ret;
++}
++
++/* Read the size of the simple page table. */
++static int gasket_read_simple_page_table_size(
++      struct gasket_dev *gasket_dev,
++      struct gasket_page_table_ioctl __user *argp)
++{
++      int ret = 0;
++      struct gasket_page_table_ioctl ibuf;
++
++      if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
++              return -EFAULT;
++
++      if (ibuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      ibuf.size =
++              gasket_page_table_num_simple_entries(gasket_dev->page_table[ibuf.page_table_index]);
++
++      trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
++                                         ibuf.host_address,
++                                         ibuf.device_address);
++
++      if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
++              return -EFAULT;
++
++      return ret;
++}
++
++/* Set the boundary between the simple and extended page tables. */
++static int gasket_partition_page_table(
++      struct gasket_dev *gasket_dev,
++      struct gasket_page_table_ioctl __user *argp)
++{
++      int ret;
++      struct gasket_page_table_ioctl ibuf;
++      uint max_page_table_size;
++
++      if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
++              return -EFAULT;
++
++      trace_gasket_ioctl_page_table_data(
++              ibuf.page_table_index, ibuf.size, ibuf.host_address,
++              ibuf.device_address);
++
++      if (ibuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++      max_page_table_size = gasket_page_table_max_size(
++              gasket_dev->page_table[ibuf.page_table_index]);
++
++      if (ibuf.size > max_page_table_size) {
++              dev_dbg(gasket_dev->dev,
++                      "Partition request 0x%llx too large, max is 0x%x\n",
++                      ibuf.size, max_page_table_size);
++              return -EINVAL;
++      }
++
++      mutex_lock(&gasket_dev->mutex);
++
++      ret = gasket_page_table_partition(
++              gasket_dev->page_table[ibuf.page_table_index], ibuf.size);
++      mutex_unlock(&gasket_dev->mutex);
++
++      return ret;
++}
++
++/* Map a userspace buffer to a device virtual address. */
++static int gasket_map_buffers_common(struct gasket_dev *gasket_dev,
++                                   struct gasket_page_table_ioctl_flags
++                                   *pibuf)
++{
++      if (pibuf->base.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      if (gasket_page_table_are_addrs_bad(gasket_dev->page_table[pibuf->base.page_table_index],
++                                          pibuf->base.host_address,
++                                          pibuf->base.device_address,
++                                          pibuf->base.size))
++              return -EINVAL;
++
++      return gasket_page_table_map(gasket_dev->page_table[pibuf->base.page_table_index],
++                                   pibuf->base.host_address,
++                                   pibuf->base.device_address,
++                                   pibuf->base.size / PAGE_SIZE,
++                                   pibuf->flags);
++}
++
++static int gasket_map_buffers(struct gasket_dev *gasket_dev,
++                            struct gasket_page_table_ioctl __user *argp)
++{
++      struct gasket_page_table_ioctl_flags ibuf;
++ 
++      if (copy_from_user(&ibuf.base, argp, sizeof(struct gasket_page_table_ioctl)))
++              return -EFAULT;
++ 
++      ibuf.flags = 0;
++ 
++      trace_gasket_ioctl_page_table_data(ibuf.base.page_table_index,
++                                         ibuf.base.size,
++                                         ibuf.base.host_address,
++                                         ibuf.base.device_address);
++
++      return gasket_map_buffers_common(gasket_dev, &ibuf);
++}
++
++static int gasket_map_buffers_flags(struct gasket_dev *gasket_dev,
++                                  struct gasket_page_table_ioctl_flags __user *argp)
++{
++      struct gasket_page_table_ioctl_flags ibuf;
++
++      if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl_flags)))
++              return -EFAULT;
++ 
++      trace_gasket_ioctl_page_table_flags_data(ibuf.base.page_table_index,
++                                               ibuf.base.size,
++                                               ibuf.base.host_address,
++                                               ibuf.base.device_address,
++                                               ibuf.flags);
++ 
++      return gasket_map_buffers_common(gasket_dev, &ibuf);
++}
++
++/* Unmap a userspace buffer from a device virtual address. */
++static int gasket_unmap_buffers(struct gasket_dev *gasket_dev,
++                              struct gasket_page_table_ioctl __user *argp)
++{
++      struct gasket_page_table_ioctl ibuf;
++
++      if (copy_from_user(&ibuf, argp, sizeof(struct gasket_page_table_ioctl)))
++              return -EFAULT;
++
++      trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size,
++                                         ibuf.host_address,
++                                         ibuf.device_address);
++
++      if (ibuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      if (gasket_page_table_is_dev_addr_bad(gasket_dev->page_table[ibuf.page_table_index],
++                                            ibuf.device_address, ibuf.size))
++              return -EINVAL;
++
++      gasket_page_table_unmap(gasket_dev->page_table[ibuf.page_table_index],
++                              ibuf.device_address, ibuf.size / PAGE_SIZE);
++
++      return 0;
++}
++
++/* Map/unmap dma-buf to/from a device virtual address. */
++static int gasket_map_dmabuf(struct gasket_dev *gasket_dev,
++                           struct gasket_page_table_ioctl_dmabuf __user *argp)
++{
++      struct gasket_page_table_ioctl_dmabuf dbuf;
++      struct gasket_page_table *pg_tbl;
++
++      if (copy_from_user(&dbuf, argp, sizeof(dbuf)))
++              return -EFAULT;
++
++      if (dbuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      pg_tbl = gasket_dev->page_table[dbuf.page_table_index];
++      if (gasket_page_table_is_dev_addr_bad(pg_tbl,
++                                            dbuf.device_address,
++                                            dbuf.num_pages * PAGE_SIZE))
++              return -EINVAL;
++
++      if (dbuf.map)
++              return gasket_page_table_map_dmabuf(pg_tbl,
++                                                  dbuf.dmabuf_fd,
++                                                  dbuf.device_address,
++                                                  dbuf.num_pages,
++                                                  dbuf.flags);
++      else
++              return gasket_page_table_unmap_dmabuf(pg_tbl,
++                                                    dbuf.dmabuf_fd,
++                                                    dbuf.device_address,
++                                                    dbuf.num_pages);
++}
++
++/*
++ * Reserve structures for coherent allocation, and allocate or free the
++ * corresponding memory.
++ */
++static int gasket_config_coherent_allocator(
++      struct gasket_dev *gasket_dev,
++      struct gasket_coherent_alloc_config_ioctl __user *argp)
++{
++      int ret;
++      struct gasket_coherent_alloc_config_ioctl ibuf;
++      dma_addr_t dma_address;
++
++      if (copy_from_user(&ibuf, argp,
++                         sizeof(struct gasket_coherent_alloc_config_ioctl)))
++              return -EFAULT;
++
++      trace_gasket_ioctl_config_coherent_allocator(ibuf.enable, ibuf.size,
++                                                   ibuf.dma_address);
++
++      if (ibuf.page_table_index >= gasket_dev->num_page_tables)
++              return -EFAULT;
++
++      if (ibuf.size > PAGE_SIZE * MAX_NUM_COHERENT_PAGES)
++              return -ENOMEM;
++
++      if (ibuf.enable == 0) {
++              dma_address = ibuf.dma_address;
++              ret = gasket_free_coherent_memory(gasket_dev, ibuf.size,
++                                                dma_address,
++                                                ibuf.page_table_index);
++      } else {
++              ret = gasket_alloc_coherent_memory(gasket_dev, ibuf.size,
++                                                 &dma_address,
++                                                 ibuf.page_table_index);
++      }
++      if (ret)
++              return ret;
++
++      if (ibuf.enable != 0)
++              ibuf.dma_address = dma_address;
++
++      if (copy_to_user(argp, &ibuf, sizeof(ibuf)))
++              return -EFAULT;
++
++      return 0;
++}
++
++/* Check permissions for Gasket ioctls. */
++static bool gasket_ioctl_check_permissions(struct file *filp, uint cmd)
++{
++      bool alive;
++      bool read, write;
++      struct gasket_dev *gasket_dev = (struct gasket_dev *)filp->private_data;
++
++      alive = (gasket_dev->status == GASKET_STATUS_ALIVE);
++      if (!alive)
++              dev_dbg(gasket_dev->dev, "%s alive %d status %d\n",
++                      __func__, alive, gasket_dev->status);
++
++      read = !!(filp->f_mode & FMODE_READ);
++      write = !!(filp->f_mode & FMODE_WRITE);
++
++      switch (cmd) {
++      case GASKET_IOCTL_RESET:
++      case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
++              return write;
++
++      case GASKET_IOCTL_PAGE_TABLE_SIZE:
++      case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
++      case GASKET_IOCTL_NUMBER_PAGE_TABLES:
++              return read;
++
++      case GASKET_IOCTL_PARTITION_PAGE_TABLE:
++      case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
++              return alive && write;
++
++      case GASKET_IOCTL_MAP_BUFFER:
++      case GASKET_IOCTL_MAP_BUFFER_FLAGS:
++      case GASKET_IOCTL_UNMAP_BUFFER:
++      case GASKET_IOCTL_MAP_DMABUF:
++              return alive && write;
++
++      case GASKET_IOCTL_CLEAR_EVENTFD:
++      case GASKET_IOCTL_SET_EVENTFD:
++              return alive && write;
++      }
++
++      return false; /* unknown permissions */
++}
++
++/*
++ * standard ioctl dispatch function.
++ * @filp: File structure pointer describing this node usage session.
++ * @cmd: ioctl number to handle.
++ * @argp: ioctl-specific data pointer.
++ *
++ * Standard ioctl dispatcher; forwards operations to individual handlers.
++ */
++long gasket_handle_ioctl(struct file *filp, uint cmd, void __user *argp)
++{
++      struct gasket_dev *gasket_dev;
++      unsigned long arg = (unsigned long)argp;
++      gasket_ioctl_permissions_cb_t ioctl_permissions_cb;
++      int retval;
++
++      gasket_dev = (struct gasket_dev *)filp->private_data;
++      trace_gasket_ioctl_entry(gasket_dev->dev_info.name, cmd);
++
++      ioctl_permissions_cb = gasket_get_ioctl_permissions_cb(gasket_dev);
++      if (ioctl_permissions_cb) {
++              retval = ioctl_permissions_cb(filp, cmd, argp);
++              if (retval < 0) {
++                      trace_gasket_ioctl_exit(retval);
++                      return retval;
++              } else if (retval == 0) {
++                      trace_gasket_ioctl_exit(-EPERM);
++                      return -EPERM;
++              }
++      } else if (!gasket_ioctl_check_permissions(filp, cmd)) {
++              trace_gasket_ioctl_exit(-EPERM);
++              dev_dbg(gasket_dev->dev, "ioctl cmd=%x noperm\n", cmd);
++              return -EPERM;
++      }
++
++      /* Tracing happens in this switch statement for all ioctls with
++       * an integer argrument, but ioctls with a struct argument
++       * that needs copying and decoding, that tracing is done within
++       * the handler call.
++       */
++      switch (cmd) {
++      case GASKET_IOCTL_RESET:
++              retval = gasket_reset(gasket_dev);
++              break;
++      case GASKET_IOCTL_SET_EVENTFD:
++              retval = gasket_set_event_fd(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_CLEAR_EVENTFD:
++              trace_gasket_ioctl_integer_data(arg);
++              retval =
++                      gasket_interrupt_clear_eventfd(gasket_dev->interrupt_data,
++                                                     (int)arg);
++              break;
++      case GASKET_IOCTL_PARTITION_PAGE_TABLE:
++              trace_gasket_ioctl_integer_data(arg);
++              retval = gasket_partition_page_table(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_NUMBER_PAGE_TABLES:
++              trace_gasket_ioctl_integer_data(gasket_dev->num_page_tables);
++              if (copy_to_user(argp, &gasket_dev->num_page_tables,
++                               sizeof(uint64_t)))
++                      retval = -EFAULT;
++              else
++                      retval = 0;
++              break;
++      case GASKET_IOCTL_PAGE_TABLE_SIZE:
++              retval = gasket_read_page_table_size(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
++              retval = gasket_read_simple_page_table_size(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_MAP_BUFFER:
++              retval = gasket_map_buffers(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_MAP_BUFFER_FLAGS:
++              retval = gasket_map_buffers_flags(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
++              retval = gasket_config_coherent_allocator(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_UNMAP_BUFFER:
++              retval = gasket_unmap_buffers(gasket_dev, argp);
++              break;
++      case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
++              /* Clear interrupt counts doesn't take an arg, so use 0. */
++              trace_gasket_ioctl_integer_data(0);
++              retval = gasket_interrupt_reset_counts(gasket_dev);
++              break;
++      case GASKET_IOCTL_MAP_DMABUF:
++              retval = gasket_map_dmabuf(gasket_dev, argp);
++              break;
++      default:
++              /* If we don't understand the ioctl, the best we can do is trace
++               * the arg.
++               */
++              trace_gasket_ioctl_integer_data(arg);
++              dev_dbg(gasket_dev->dev,
++                      "Unknown ioctl cmd=0x%x not caught by "
++                      "gasket_is_supported_ioctl\n",
++                      cmd);
++              retval = -EINVAL;
++              break;
++      }
++
++      trace_gasket_ioctl_exit(retval);
++      return retval;
++}
++
++/*
++ * Determines if an ioctl is part of the standard Gasket framework.
++ * @cmd: The ioctl number to handle.
++ *
++ * Returns 1 if the ioctl is supported and 0 otherwise.
++ */
++long gasket_is_supported_ioctl(uint cmd)
++{
++      switch (cmd) {
++      case GASKET_IOCTL_RESET:
++      case GASKET_IOCTL_SET_EVENTFD:
++      case GASKET_IOCTL_CLEAR_EVENTFD:
++      case GASKET_IOCTL_PARTITION_PAGE_TABLE:
++      case GASKET_IOCTL_NUMBER_PAGE_TABLES:
++      case GASKET_IOCTL_PAGE_TABLE_SIZE:
++      case GASKET_IOCTL_SIMPLE_PAGE_TABLE_SIZE:
++      case GASKET_IOCTL_MAP_BUFFER:
++      case GASKET_IOCTL_MAP_BUFFER_FLAGS:
++      case GASKET_IOCTL_UNMAP_BUFFER:
++      case GASKET_IOCTL_MAP_DMABUF:
++      case GASKET_IOCTL_CLEAR_INTERRUPT_COUNTS:
++      case GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR:
++              return 1;
++      default:
++              return 0;
++      }
++}
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_ioctl.h b/drivers/staging/gasket-driver/gasket_ioctl.h
+--- a/drivers/staging/gasket-driver/gasket_ioctl.h     1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_ioctl.h     2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,28 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/* Copyright (C) 2018 Google, Inc. */
++#ifndef __GASKET_IOCTL_H__
++#define __GASKET_IOCTL_H__
++
++#include "gasket_core.h"
++
++#include <linux/compiler.h>
++
++/*
++ * Handle Gasket common ioctls.
++ * @filp: Pointer to the ioctl's file.
++ * @cmd: Ioctl command.
++ * @arg: Ioctl argument pointer.
++ *
++ * Returns 0 on success and nonzero on failure.
++ */
++long gasket_handle_ioctl(struct file *filp, uint cmd, void __user *argp);
++
++/*
++ * Determines if an ioctl is part of the standard Gasket framework.
++ * @cmd: The ioctl number to handle.
++ *
++ * Returns 1 if the ioctl is supported and 0 otherwise.
++ */
++long gasket_is_supported_ioctl(uint cmd);
++
++#endif
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_page_table.c b/drivers/staging/gasket-driver/gasket_page_table.c
+--- a/drivers/staging/gasket-driver/gasket_page_table.c        1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_page_table.c        2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,1597 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Implementation of Gasket page table support.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++
++/*
++ * Implementation of Gasket page table support.
++ *
++ * This file assumes 4kB pages throughout; can be factored out when necessary.
++ *
++ * There is a configurable number of page table entries, as well as a
++ * configurable bit index for the extended address flag. Both of these are
++ * specified in gasket_page_table_init through the page_table_config parameter.
++ *
++ * The following example assumes:
++ *   page_table_config->total_entries = 8192
++ *   page_table_config->extended_bit = 63
++ *
++ * Address format:
++ * Simple addresses - those whose containing pages are directly placed in the
++ * device's address translation registers - are laid out as:
++ * [ 63 - 25: 0 | 24 - 12: page index | 11 - 0: page offset ]
++ * page index:  The index of the containing page in the device's address
++ *              translation registers.
++ * page offset: The index of the address into the containing page.
++ *
++ * Extended address - those whose containing pages are contained in a second-
++ * level page table whose address is present in the device's address translation
++ * registers - are laid out as:
++ * [ 63: flag | 62 - 34: 0 | 33 - 21: dev/level 0 index |
++ *   20 - 12: host/level 1 index | 11 - 0: page offset ]
++ * flag:        Marker indicating that this is an extended address. Always 1.
++ * dev index:   The index of the first-level page in the device's extended
++ *              address translation registers.
++ * host index:  The index of the containing page in the [host-resident] second-
++ *              level page table.
++ * page offset: The index of the address into the containing [second-level]
++ *              page.
++ */
++#include "gasket_page_table.h"
++
++#include <linux/device.h>
++#include <linux/dma-buf.h>
++#include <linux/file.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/pagemap.h>
++#include <linux/version.h>
++#include <linux/vmalloc.h>
++
++#if __has_include(<linux/dma-buf.h>)
++MODULE_IMPORT_NS(DMA_BUF);
++#endif
++
++#include "gasket_constants.h"
++#include "gasket_core.h"
++
++/* Constants & utility macros */
++/* The number of pages that can be mapped into each second-level page table. */
++#define GASKET_PAGES_PER_SUBTABLE 512
++
++/* The starting position of the page index in a simple virtual address. */
++#define GASKET_SIMPLE_PAGE_SHIFT 12
++
++/* Flag indicating that a [device] slot is valid for use. */
++#define GASKET_VALID_SLOT_FLAG 1
++
++/*
++ * The starting position of the level 0 page index (i.e., the entry in the
++ * device's extended address registers) in an extended address.
++ * Also can be thought of as (log2(PAGE_SIZE) + log2(PAGES_PER_SUBTABLE)),
++ * or (12 + 9).
++ */
++#define GASKET_EXTENDED_LVL0_SHIFT 21
++
++/*
++ * Number of first level pages that Gasket chips support. Equivalent to
++ * log2(NUM_LVL0_PAGE_TABLES)
++ *
++ * At a maximum, allowing for a 34 bits address space (or 16GB)
++ *   = GASKET_EXTENDED_LVL0_WIDTH + (log2(PAGE_SIZE) + log2(PAGES_PER_SUBTABLE)
++ * or, = 13 + 9 + 12
++ */
++#define GASKET_EXTENDED_LVL0_WIDTH 13
++
++/*
++ * The starting position of the level 1 page index (i.e., the entry in the
++ * host second-level/sub- table) in an extended address.
++ */
++#define GASKET_EXTENDED_LVL1_SHIFT 12
++
++/*
++ * Utilities for accessing flags bitfields.
++ */
++#define MASK(field)            (((1u << field##_WIDTH) - 1) << field##_SHIFT)
++#define GET(field, flags)      (((flags) & MASK(field)) >> field##_SHIFT)
++#define SET(field, flags, val) (((flags) & ~MASK(field)) | ((val) << field##_SHIFT))
++
++#define FLAGS_STATUS_SHIFT 0
++#define FLAGS_STATUS_WIDTH 1
++
++#define FLAGS_DMA_DIRECTION_SHIFT 1
++#define FLAGS_DMA_DIRECTION_WIDTH 2
++
++/* Type declarations */
++/* Valid states for a struct gasket_page_table_entry. */
++enum pte_status {
++      PTE_FREE,
++      PTE_INUSE,
++};
++
++/*
++ * Mapping metadata for a single page.
++ *
++ * In this file, host-side page table entries are referred to as that (or PTEs).
++ * Where device vs. host entries are differentiated, device-side or -visible
++ * entries are called "slots". A slot may be either an entry in the device's
++ * address translation table registers or an entry in a second-level page
++ * table ("subtable").
++ *
++ * The full data in this structure is visible on the host [of course]. Only
++ * the address contained in dma_addr is communicated to the device; that points
++ * to the actual page mapped and described by this structure.
++ */
++struct gasket_page_table_entry {
++      /*
++       * Internal structure matches gasket_page_table_ioctl_flags.flags.
++       * NOTE: All fields should have a default value of 0. This ensures that
++       * the kernel will be backwards compatible with old drivers.
++       */
++      u32 flags;
++
++      /*
++       * Index for alignment into host vaddrs.
++       * When a user specifies a host address for a mapping, that address may
++       * not be page-aligned. Offset is the index into the containing page of
++       * the host address (i.e., host_vaddr & (PAGE_SIZE - 1)).
++       * This is necessary for translating between user-specified addresses
++       * and page-aligned addresses.
++       */
++      int offset;
++
++      /* Address of the page in DMA space. */
++      dma_addr_t dma_addr;
++
++      /* Linux page descriptor for the page described by this structure. */
++      struct page *page;
++
++      /*
++       * If this is an extended and first-level entry, sublevel points
++       * to the second-level entries underneath this entry.
++       */
++      struct gasket_page_table_entry *sublevel;
++};
++
++/*
++ * Maintains virtual to physical address mapping for a coherent page that is
++ * allocated by this module for a given device.
++ * Note that coherent pages mappings virt mapping cannot be tracked by the
++ * Linux kernel, and coherent pages don't have a struct page associated,
++ * hence Linux kernel cannot perform a get_user_page_xx() on a phys address
++ * that was allocated coherent.
++ * This structure trivially implements this mechanism.
++ */
++struct gasket_coherent_page_entry {
++      /* Phys address, dma'able by the owner device */
++      dma_addr_t paddr;
++
++      /* Kernel virtual address */
++      u64 user_virt;
++
++      /* User virtual address that was mapped by the mmap kernel subsystem */
++      dma_addr_t kernel_virt;
++
++      /*
++       * Whether this page has been mapped into a user land process virtual
++       * space
++       */
++      u32 in_use;
++};
++
++/* Storage for dmabuf mapping information. */
++struct gasket_dmabuf_mapping {
++      struct dma_buf *dmabuf;
++      struct dma_buf_attachment *attachment;
++      struct sg_table *sgt;
++      enum dma_data_direction direction;
++      struct list_head list;
++};
++
++/*
++ * [Host-side] page table descriptor.
++ *
++ * This structure tracks the metadata necessary to manage both simple and
++ * extended page tables.
++ */
++struct gasket_page_table {
++      /* The config used to create this page table. */
++      struct gasket_page_table_config config;
++
++      /* The number of simple (single-level) entries in the page table. */
++      uint num_simple_entries;
++
++      /* The number of extended (two-level) entries in the page table. */
++      uint num_extended_entries;
++
++      /* Array of [host-side] page table entries. */
++      struct gasket_page_table_entry *entries;
++
++      /* Number of actively mapped kernel pages in this table. */
++      uint num_active_pages;
++
++      /* Device register: base of/first slot in the page table. */
++      u64 __iomem *base_slot;
++
++      /* Device register: holds the offset indicating the start of the
++       * extended address region of the device's address translation table.
++       */
++      u64 __iomem *extended_offset_reg;
++
++      /* Device structure for the underlying device. Only used for logging. */
++      struct device *device;
++
++      /* PCI system descriptor for the underlying device. */
++      struct pci_dev *pci_dev;
++
++      /* Location of the extended address bit for this Gasket device. */
++      u64 extended_flag;
++
++      /* Mutex to protect page table internals. */
++      struct mutex mutex;
++
++      /* Number of coherent pages accessible thru by this page table */
++      int num_coherent_pages;
++
++      /*
++       * List of coherent memory (physical) allocated for a device.
++       *
++       * This structure also remembers the user virtual mapping, this is
++       * hacky, but we need to do this because the kernel doesn't keep track
++       * of the user coherent pages (pfn pages), and virt to coherent page
++       * mapping.
++       * TODO: use find_vma() APIs to convert host address to vm_area, to
++       * dma_addr_t instead of storing user virtu address in
++       * gasket_coherent_page_entry
++       *
++       * Note that the user virtual mapping is created by the driver, in
++       * gasket_mmap function, so user_virt belongs in the driver anyhow.
++       */
++      struct gasket_coherent_page_entry *coherent_pages;
++
++      /* List of dmabufs currently attached and mapped. */
++      struct list_head dmabufs;
++};
++
++/* See gasket_page_table.h for description. */
++int gasket_page_table_init(struct gasket_page_table **ppg_tbl,
++                         const struct gasket_bar_data *bar_data,
++                         const struct gasket_page_table_config *page_table_config,
++                         struct device *device, struct pci_dev *pci_dev)
++{
++      ulong bytes;
++      struct gasket_page_table *pg_tbl;
++      ulong total_entries = page_table_config->total_entries;
++
++      /*
++       * TODO: Verify config->total_entries against value read from the
++       * hardware register that contains the page table size.
++       */
++      if (total_entries == ULONG_MAX) {
++              dev_dbg(device, "Error reading page table size. "
++                      "Initializing page table with size 0\n");
++              total_entries = 0;
++      }
++
++      dev_dbg(device,
++              "Attempting to initialize page table of size 0x%lx\n",
++              total_entries);
++
++      dev_dbg(device,
++              "Table has base reg 0x%x, extended offset reg 0x%x\n",
++              page_table_config->base_reg,
++              page_table_config->extended_reg);
++
++      *ppg_tbl = kzalloc(sizeof(**ppg_tbl), GFP_KERNEL);
++      if (!*ppg_tbl) {
++              dev_dbg(device, "No memory for page table\n");
++              return -ENOMEM;
++      }
++
++      pg_tbl = *ppg_tbl;
++      bytes = total_entries * sizeof(struct gasket_page_table_entry);
++      if (bytes != 0) {
++              pg_tbl->entries = vzalloc(bytes);
++              if (!pg_tbl->entries) {
++                      dev_dbg(device,
++                              "No memory for address translation metadata\n");
++                      kfree(pg_tbl);
++                      *ppg_tbl = NULL;
++                      return -ENOMEM;
++              }
++      }
++
++      mutex_init(&pg_tbl->mutex);
++      memcpy(&pg_tbl->config, page_table_config, sizeof(*page_table_config));
++      if (pg_tbl->config.mode == GASKET_PAGE_TABLE_MODE_NORMAL ||
++          pg_tbl->config.mode == GASKET_PAGE_TABLE_MODE_SIMPLE) {
++              pg_tbl->num_simple_entries = total_entries;
++              pg_tbl->num_extended_entries = 0;
++              pg_tbl->extended_flag = 1ull << page_table_config->extended_bit;
++      } else {
++              pg_tbl->num_simple_entries = 0;
++              pg_tbl->num_extended_entries = total_entries;
++              pg_tbl->extended_flag = 0;
++      }
++      pg_tbl->num_active_pages = 0;
++      pg_tbl->base_slot =
++              (u64 __iomem *)&bar_data->virt_base[page_table_config->base_reg];
++      pg_tbl->extended_offset_reg =
++              (u64 __iomem *)&bar_data->virt_base[page_table_config->extended_reg];
++      pg_tbl->device = get_device(device);
++      pg_tbl->pci_dev = pci_dev;
++      INIT_LIST_HEAD(&pg_tbl->dmabufs);
++
++      dev_dbg(device, "Page table initialized successfully\n");
++
++      return 0;
++}
++
++/*
++ * Check if a range of PTEs is free.
++ * The page table mutex must be held by the caller.
++ */
++static bool gasket_is_pte_range_free(struct gasket_page_table_entry *ptes,
++                                   uint num_entries)
++{
++      int i;
++
++      for (i = 0; i < num_entries; i++) {
++              if (GET(FLAGS_STATUS, ptes[i].flags) != PTE_FREE)
++                      return false;
++      }
++
++      return true;
++}
++
++/*
++ * Free a second level page [sub]table.
++ * The page table mutex must be held before this call.
++ */
++static void gasket_free_extended_subtable(struct gasket_page_table *pg_tbl,
++                                        struct gasket_page_table_entry *pte,
++                                        u64 __iomem *slot)
++{
++      /* Release the page table from the driver */
++      pte->flags = SET(FLAGS_STATUS, pte->flags, PTE_FREE);
++
++      /* Release the page table from the device */
++      writeq(0, slot);
++
++      if (pte->dma_addr)
++              dma_unmap_page(pg_tbl->device, pte->dma_addr, PAGE_SIZE,
++                             DMA_TO_DEVICE);
++
++      vfree(pte->sublevel);
++
++      if (pte->page)
++              free_page((ulong)page_address(pte->page));
++
++      memset(pte, 0, sizeof(struct gasket_page_table_entry));
++}
++
++/*
++ * Actually perform collection.
++ * The page table mutex must be held by the caller.
++ */
++static void
++gasket_page_table_garbage_collect_nolock(struct gasket_page_table *pg_tbl)
++{
++      struct gasket_page_table_entry *pte;
++      u64 __iomem *slot;
++
++      /* XXX FIX ME XXX -- more efficient to keep a usage count */
++      /* rather than scanning the second level page tables */
++
++      for (pte = pg_tbl->entries + pg_tbl->num_simple_entries,
++           slot = pg_tbl->base_slot + pg_tbl->num_simple_entries;
++           pte < pg_tbl->entries + pg_tbl->config.total_entries;
++           pte++, slot++) {
++              if (GET(FLAGS_STATUS, pte->flags) == PTE_INUSE) {
++                      if (gasket_is_pte_range_free(pte->sublevel,
++                                                   GASKET_PAGES_PER_SUBTABLE))
++                              gasket_free_extended_subtable(pg_tbl, pte,
++                                                            slot);
++              }
++      }
++}
++
++/* See gasket_page_table.h for description. */
++void gasket_page_table_garbage_collect(struct gasket_page_table *pg_tbl)
++{
++      mutex_lock(&pg_tbl->mutex);
++      gasket_page_table_garbage_collect_nolock(pg_tbl);
++      mutex_unlock(&pg_tbl->mutex);
++}
++
++/* See gasket_page_table.h for description. */
++void gasket_page_table_cleanup(struct gasket_page_table *pg_tbl)
++{
++      /* Deallocate free second-level tables. */
++      gasket_page_table_garbage_collect(pg_tbl);
++
++      /* TODO: Check that all PTEs have been freed? */
++
++      vfree(pg_tbl->entries);
++      pg_tbl->entries = NULL;
++
++      put_device(pg_tbl->device);
++      kfree(pg_tbl);
++}
++
++/* See gasket_page_table.h for description. */
++int gasket_page_table_partition(struct gasket_page_table *pg_tbl,
++                              uint num_simple_entries)
++{
++      int i, start;
++
++      mutex_lock(&pg_tbl->mutex);
++      if (num_simple_entries > pg_tbl->config.total_entries) {
++              mutex_unlock(&pg_tbl->mutex);
++              return -EINVAL;
++      }
++
++      gasket_page_table_garbage_collect_nolock(pg_tbl);
++
++      start = min(pg_tbl->num_simple_entries, num_simple_entries);
++
++      for (i = start; i < pg_tbl->config.total_entries; i++) {
++              if (GET(FLAGS_STATUS, pg_tbl->entries[i].flags) != PTE_FREE) {
++                      dev_err(pg_tbl->device, "entry %d is not free\n", i);
++                      mutex_unlock(&pg_tbl->mutex);
++                      return -EBUSY;
++              }
++      }
++
++      pg_tbl->num_simple_entries = num_simple_entries;
++      pg_tbl->num_extended_entries =
++              pg_tbl->config.total_entries - num_simple_entries;
++      writeq(num_simple_entries, pg_tbl->extended_offset_reg);
++
++      mutex_unlock(&pg_tbl->mutex);
++      return 0;
++}
++EXPORT_SYMBOL(gasket_page_table_partition);
++
++/*
++ * Return whether a host buffer was mapped as coherent memory.
++ *
++ * A Gasket page_table currently support one contiguous dma range, mapped to one
++ * contiguous virtual memory range. Check if the host_addr is within that range.
++ */
++static int is_coherent(struct gasket_page_table *pg_tbl, ulong host_addr)
++{
++      u64 min, max;
++
++      /* whether the host address is within user virt range */
++      if (!pg_tbl->coherent_pages)
++              return 0;
++
++      min = (u64)pg_tbl->coherent_pages[0].user_virt;
++      max = min + PAGE_SIZE * pg_tbl->num_coherent_pages;
++
++      return min <= host_addr && host_addr < max;
++}
++
++/* Safely return a page to the OS. */
++static bool gasket_release_page(struct page *page)
++{
++      if (!page)
++              return false;
++
++      if (!PageReserved(page))
++              SetPageDirty(page);
++      put_page(page);
++
++      return true;
++}
++
++/*
++ * Get and map last level page table buffers.
++ *
++ * slots is the location(s) to write device-mapped page address. If this is a
++ * simple mapping, these will be address translation registers. If this is
++ * an extended mapping, these will be within a second-level page table
++ * allocated by the host and so must have their __iomem attribute casted away.
++ */
++static int gasket_perform_mapping(struct gasket_page_table *pg_tbl,
++                                struct gasket_page_table_entry *ptes,
++                                u64 __iomem *slots,
++                                struct sg_page_iter *sg_iter,
++                                ulong host_addr,
++                                uint num_pages, u32 flags,
++                                int is_simple_mapping)
++{
++      int ret;
++      ulong offset;
++      struct page *page;
++      dma_addr_t dma_addr;
++      ulong page_addr;
++      int i;
++      enum dma_data_direction direction;
++
++      /* Must have a virtual host address or a sg iterator, but not both. */
++      if (!((uintptr_t)host_addr ^ (uintptr_t)sg_iter)) {
++              dev_err(pg_tbl->device, "need sg_iter or host_addr\n");
++              return -EINVAL;
++      }
++
++      direction = GET(FLAGS_DMA_DIRECTION, flags);
++      if (direction == DMA_NONE) {
++              dev_err(pg_tbl->device, "invalid DMA direction flags=0x%lx\n",
++                      (unsigned long)flags);
++              return -EINVAL;
++      }
++
++      for (i = 0; i < num_pages; i++) {
++              page_addr = host_addr + i * PAGE_SIZE;
++              offset = page_addr & (PAGE_SIZE - 1);
++              dev_dbg(pg_tbl->device, "%s i %d\n", __func__, i);
++              if (sg_iter) {
++                      if (!__sg_page_iter_next(sg_iter))
++                              return -EINVAL;
++
++                      /* Page already mapped for DMA. */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
++                      ptes[i].dma_addr = sg_page_iter_dma_address(sg_iter);
++#else
++                      ptes[i].dma_addr = sg_page_iter_dma_address(
++                              container_of(sg_iter, struct sg_dma_page_iter, base));
++#endif
++                      ptes[i].page = NULL;
++                      offset = 0;
++              } else if (is_coherent(pg_tbl, host_addr)) {
++                      u64 off =
++                              (u64)host_addr -
++                              (u64)pg_tbl->coherent_pages[0].user_virt;
++                      ptes[i].page = NULL;
++                      ptes[i].offset = offset;
++                      ptes[i].dma_addr = pg_tbl->coherent_pages[0].paddr +
++                                         off + i * PAGE_SIZE;
++              } else {
++                      ret = get_user_pages_fast(page_addr - offset, 1,
++                                                direction != DMA_TO_DEVICE,
++                                                &page);
++
++                      if (ret <= 0) {
++                              dev_err(pg_tbl->device,
++                                      "get user pages failed for addr=0x%lx, "
++                                      "offset=0x%lx [ret=%d]\n",
++                                      page_addr, offset, ret);
++                              return ret ? ret : -ENOMEM;
++                      }
++                      ++pg_tbl->num_active_pages;
++
++                      ptes[i].page = page;
++                      ptes[i].offset = offset;
++
++                      /* Map the page into DMA space. */
++                      ptes[i].dma_addr = dma_map_page(pg_tbl->device, page, 0, PAGE_SIZE,
++                                                      GET(FLAGS_DMA_DIRECTION, flags));
++                      dev_dbg(pg_tbl->device,
++                              "%s i %d pte %p pfn %p -> mapped %llx\n",
++                              __func__, i, &ptes[i],
++                              (void *)page_to_pfn(page),
++                              (unsigned long long)ptes[i].dma_addr);
++
++                      if (dma_mapping_error(pg_tbl->device,
++                                            ptes[i].dma_addr)) {
++                              dev_dbg(pg_tbl->device,
++                                      "%s i %d -> fail to map page %llx "
++                                      "[pfn %p phys %p]\n",
++                                      __func__, i,
++                                      (unsigned long long)ptes[i].dma_addr,
++                                      (void *)page_to_pfn(page),
++                                      (void *)page_to_phys(page));
++
++                              /* clean up */
++                              if (gasket_release_page(ptes[i].page))
++                                      --pg_tbl->num_active_pages;
++
++                              memset(&ptes[i], 0, sizeof(struct gasket_page_table_entry));
++                              return -EINVAL;
++                      }
++              }
++
++              /* Make the DMA-space address available to the device. */
++              dma_addr = (ptes[i].dma_addr + offset) | GASKET_VALID_SLOT_FLAG;
++
++              if (is_simple_mapping)
++                      writeq(dma_addr, &slots[i]);
++              else
++                      ((u64 __force *)slots)[i] = dma_addr;
++
++              /* Set PTE flags equal to flags param with STATUS=PTE_INUSE. */
++              ptes[i].flags = SET(FLAGS_STATUS, flags, PTE_INUSE);
++      }
++      return 0;
++}
++
++/*
++ * Return the index of the page for the address in the simple table.
++ * Does not perform validity checking.
++ */
++static int gasket_simple_page_idx(struct gasket_page_table *pg_tbl,
++                                u64 dev_addr)
++{
++      return (dev_addr >> GASKET_SIMPLE_PAGE_SHIFT) &
++              (pg_tbl->config.total_entries - 1);
++}
++
++/*
++ * Return the level 0 page index for the given address.
++ * Does not perform validity checking.
++ */
++static ulong gasket_extended_lvl0_page_idx(struct gasket_page_table *pg_tbl,
++                                         u64 dev_addr)
++{
++      return (dev_addr >> GASKET_EXTENDED_LVL0_SHIFT) &
++             (pg_tbl->config.total_entries - 1);
++}
++
++/*
++ * Return the level 1 page index for the given address.
++ * Does not perform validity checking.
++ */
++static ulong gasket_extended_lvl1_page_idx(struct gasket_page_table *pg_tbl,
++                                         u64 dev_addr)
++{
++      return (dev_addr >> GASKET_EXTENDED_LVL1_SHIFT) &
++             (GASKET_PAGES_PER_SUBTABLE - 1);
++}
++
++/*
++ * Allocate page table entries in a simple table.
++ * The page table mutex must be held by the caller.
++ */
++static int gasket_alloc_simple_entries(struct gasket_page_table *pg_tbl,
++                                     u64 dev_addr, uint num_pages)
++{
++      if (!gasket_is_pte_range_free(pg_tbl->entries +
++                                    gasket_simple_page_idx(pg_tbl, dev_addr),
++                                    num_pages))
++              return -EBUSY;
++
++      return 0;
++}
++
++/*
++ * Unmap and release mapped pages.
++ * The page table mutex must be held by the caller.
++ */
++static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl,
++                                   struct gasket_page_table_entry *ptes,
++                                   u64 __iomem *slots, uint num_pages,
++                                   int is_simple_mapping)
++{
++      int i;
++      /*
++       * For each page table entry and corresponding entry in the device's
++       * address translation table:
++       */
++      for (i = 0; i < num_pages; i++) {
++              /* release the address from the device, */
++              if (is_simple_mapping)
++                      writeq(0, &slots[i]);
++              else
++                      ((u64 __force *)slots)[i] = 0;
++
++              /* release the address from the driver, */
++              if (GET(FLAGS_STATUS, ptes[i].flags) == PTE_INUSE) {
++                      if (ptes[i].page && ptes[i].dma_addr) {
++                              dma_unmap_page(pg_tbl->device, ptes[i].dma_addr, PAGE_SIZE,
++                                             GET(FLAGS_DMA_DIRECTION, ptes[i].flags));
++                      }
++                      if (gasket_release_page(ptes[i].page))
++                              --pg_tbl->num_active_pages;
++              }
++
++              /* and clear the PTE. */
++              memset(&ptes[i], 0, sizeof(struct gasket_page_table_entry));
++      }
++}
++
++/*
++ * Unmap and release pages mapped to simple addresses.
++ * The page table mutex must be held by the caller.
++ */
++static void gasket_unmap_simple_pages(struct gasket_page_table *pg_tbl,
++                                    u64 dev_addr, uint num_pages)
++{
++      uint slot = gasket_simple_page_idx(pg_tbl, dev_addr);
++
++      gasket_perform_unmapping(pg_tbl, pg_tbl->entries + slot,
++                               pg_tbl->base_slot + slot, num_pages, 1);
++}
++
++/*
++ * Unmap and release buffers to extended addresses.
++ * The page table mutex must be held by the caller.
++ */
++static void gasket_unmap_extended_pages(struct gasket_page_table *pg_tbl,
++                                      u64 dev_addr, uint num_pages)
++{
++      uint slot_idx, remain, len;
++      struct gasket_page_table_entry *pte;
++      u64 __iomem *slot_base;
++
++      remain = num_pages;
++      slot_idx = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
++      pte = pg_tbl->entries + pg_tbl->num_simple_entries +
++            gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++
++      while (remain > 0) {
++              /* TODO: Add check to ensure pte remains valid? */
++              len = min(remain, GASKET_PAGES_PER_SUBTABLE - slot_idx);
++
++              if (GET(FLAGS_STATUS, pte->flags) == PTE_INUSE) {
++                      slot_base = (u64 __iomem *)(page_address(pte->page) +
++                                                  pte->offset);
++                      gasket_perform_unmapping(pg_tbl,
++                                               pte->sublevel + slot_idx,
++                                               slot_base + slot_idx, len, 0);
++                      /*
++                       * Extended page tables are in DRAM so they need to be
++                       * synced each time they are updated.
++                       */
++                      dma_sync_single_for_device(pg_tbl->device,
++                                                 pte->dma_addr + slot_idx * sizeof(u64),
++                                                 len * sizeof(u64), DMA_TO_DEVICE);
++              }
++
++              remain -= len;
++              slot_idx = 0;
++              pte++;
++      }
++}
++
++/* Evaluates to nonzero if the specified virtual address is simple. */
++static inline bool gasket_addr_is_simple(struct gasket_page_table *pg_tbl,
++                                       u64 addr)
++{
++      return !((addr) & (pg_tbl)->extended_flag);
++}
++
++/*
++ * Convert (simple, page, offset) into a device address.
++ * Examples:
++ * Simple page 0, offset 32:
++ *  Input (1, 0, 32), Output 0x20
++ * Simple page 1000, offset 511:
++ *  Input (1, 1000, 511), Output 0x3E81FF
++ * Extended page 0, offset 32:
++ *  Input (0, 0, 32), Output 0x8000000020
++ * Extended page 1000, offset 511:
++ *  Input (0, 1000, 511), Output 0x8003E81FF
++ */
++static u64 gasket_components_to_dev_address(struct gasket_page_table *pg_tbl,
++                                            int is_simple, uint page_index,
++                                            uint offset)
++{
++      u64 dev_addr = (page_index << GASKET_SIMPLE_PAGE_SHIFT) | offset;
++
++      return is_simple ? dev_addr : (pg_tbl->extended_flag | dev_addr);
++}
++
++/*
++ * Validity checking for simple addresses.
++ *
++ * Verify that address translation commutes (from address to/from page + offset)
++ * and that the requested page range starts and ends within the set of
++ * currently-partitioned simple pages.
++ */
++static bool gasket_is_simple_dev_addr_bad(struct gasket_page_table *pg_tbl,
++                                        u64 dev_addr, uint num_pages)
++{
++      ulong page_offset = dev_addr & (PAGE_SIZE - 1);
++      ulong page_index =
++              (dev_addr / PAGE_SIZE) & (pg_tbl->config.total_entries - 1);
++
++      if (gasket_components_to_dev_address(pg_tbl, 1, page_index,
++                                           page_offset) != dev_addr) {
++              dev_err(pg_tbl->device, "address is invalid, 0x%llX\n",
++                      dev_addr);
++              return true;
++      }
++
++      if (page_index >= pg_tbl->num_simple_entries) {
++              dev_err(pg_tbl->device,
++                      "starting slot at %lu is too large, max is < %u\n",
++                      page_index, pg_tbl->num_simple_entries);
++              return true;
++      }
++
++      if (page_index + num_pages > pg_tbl->num_simple_entries) {
++              dev_err(pg_tbl->device,
++                      "ending slot at %lu is too large, max is <= %u\n",
++                      page_index + num_pages, pg_tbl->num_simple_entries);
++              return true;
++      }
++
++      return false;
++}
++
++/*
++ * Validity checking for extended addresses.
++ *
++ * Verify that address translation commutes (from address to/from page +
++ * offset) and that the requested page range starts and ends within the set of
++ * currently-partitioned extended pages.
++ */
++static bool gasket_is_extended_dev_addr_bad(struct gasket_page_table *pg_tbl,
++                                          u64 dev_addr, uint num_pages)
++{
++      /* Starting byte index of dev_addr into the first mapped page */
++      ulong page_offset = dev_addr & (PAGE_SIZE - 1);
++      ulong page_global_idx, page_lvl0_idx;
++      ulong num_lvl0_pages;
++      u64 addr;
++
++      /* check if the device address is out of bound */
++      addr = dev_addr & ~((pg_tbl)->extended_flag);
++      if (addr >> (GASKET_EXTENDED_LVL0_WIDTH + GASKET_EXTENDED_LVL0_SHIFT)) {
++              dev_err(pg_tbl->device,
++                      "device address out of bounds: 0x%llx\n", dev_addr);
++              return true;
++      }
++
++      /* Find the starting sub-page index in the space of all sub-pages. */
++      page_global_idx = (dev_addr / PAGE_SIZE) &
++              (pg_tbl->config.total_entries * GASKET_PAGES_PER_SUBTABLE - 1);
++
++      /* Find the starting level 0 index. */
++      page_lvl0_idx = gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++
++      /* Get the count of affected level 0 pages. */
++      num_lvl0_pages = (num_pages + GASKET_PAGES_PER_SUBTABLE - 1) /
++              GASKET_PAGES_PER_SUBTABLE;
++
++      if (gasket_components_to_dev_address(pg_tbl, 0, page_global_idx,
++                                           page_offset) != dev_addr) {
++              dev_err(pg_tbl->device, "address is invalid: 0x%llx\n",
++                      dev_addr);
++              return true;
++      }
++
++      if (page_lvl0_idx >= pg_tbl->num_extended_entries) {
++              dev_err(pg_tbl->device,
++                      "starting level 0 slot at %lu is too large, max is < "
++                      "%u\n", page_lvl0_idx, pg_tbl->num_extended_entries);
++              return true;
++      }
++
++      if (page_lvl0_idx + num_lvl0_pages > pg_tbl->num_extended_entries) {
++              dev_err(pg_tbl->device,
++                      "ending level 0 slot at %lu is too large, max is <= %u\n",
++                      page_lvl0_idx + num_lvl0_pages,
++                      pg_tbl->num_extended_entries);
++              return true;
++      }
++
++      return false;
++}
++
++/*
++ * Non-locking entry to unmapping routines.
++ * The page table mutex must be held by the caller.
++ */
++static void gasket_page_table_unmap_nolock(struct gasket_page_table *pg_tbl,
++                                         u64 dev_addr, uint num_pages)
++{
++      if (!num_pages)
++              return;
++
++      if (gasket_addr_is_simple(pg_tbl, dev_addr))
++              gasket_unmap_simple_pages(pg_tbl, dev_addr, num_pages);
++      else
++              gasket_unmap_extended_pages(pg_tbl, dev_addr, num_pages);
++}
++
++/*
++ * Allocate and map pages to simple addresses.
++ * If there is an error, no pages are mapped.
++ */
++static int gasket_map_simple_pages(struct gasket_page_table *pg_tbl,
++                                 struct sg_page_iter *sg_iter,
++                                 ulong host_addr, u64 dev_addr,
++                                 uint num_pages, u32 flags)
++{
++      int ret;
++      uint slot_idx = gasket_simple_page_idx(pg_tbl, dev_addr);
++
++      ret = gasket_alloc_simple_entries(pg_tbl, dev_addr, num_pages);
++      if (ret) {
++              dev_err(pg_tbl->device,
++                      "page table slots %u (@ 0x%llx) to %u are not available\n",
++                      slot_idx, (long long unsigned int)dev_addr,
++                      slot_idx + num_pages - 1);
++              return ret;
++      }
++
++      ret = gasket_perform_mapping(pg_tbl, pg_tbl->entries + slot_idx,
++                                   pg_tbl->base_slot + slot_idx, sg_iter,
++                                   host_addr, num_pages, flags, 1);
++
++      if (ret) {
++              gasket_page_table_unmap_nolock(pg_tbl, dev_addr, num_pages);
++              dev_err(pg_tbl->device, "gasket_perform_mapping %d\n", ret);
++      }
++      return ret;
++}
++
++/*
++ * Allocate a second level page table.
++ * The page table mutex must be held by the caller.
++ */
++static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl,
++                                        struct gasket_page_table_entry *pte,
++                                        u64 __iomem *slot)
++{
++      ulong page_addr, subtable_bytes;
++      dma_addr_t dma_addr;
++
++      /* XXX FIX ME XXX this is inefficient for non-4K page sizes */
++
++      /* GFP_DMA flag must be passed to architectures for which
++       * part of the memory range is not considered DMA'able.
++       * This seems to be the case for Juno board with 4.5.0 Linaro kernel
++       */
++      page_addr = get_zeroed_page(GFP_KERNEL | GFP_DMA);
++      if (!page_addr)
++              return -ENOMEM;
++      pte->page = virt_to_page((void *)page_addr);
++      pte->offset = 0;
++
++      subtable_bytes = sizeof(struct gasket_page_table_entry) *
++              GASKET_PAGES_PER_SUBTABLE;
++      pte->sublevel = vzalloc(subtable_bytes);
++      if (!pte->sublevel) {
++              free_page(page_addr);
++              memset(pte, 0, sizeof(struct gasket_page_table_entry));
++              return -ENOMEM;
++      }
++
++      /* Map the page into DMA space. */
++      pte->dma_addr = dma_map_page(pg_tbl->device, pte->page, 0, PAGE_SIZE,
++                                   DMA_TO_DEVICE);
++      if (dma_mapping_error(pg_tbl->device, pte->dma_addr)) {
++              dev_dbg(pg_tbl->device,
++                      "%s -> fail to map page %llx "
++                      "[pfn %p phys %p]\n",
++                      __func__,
++                      (unsigned long long)pte->dma_addr,
++                      (void *)page_to_pfn(pte->page),
++                      (void *)page_to_phys(pte->page));
++
++              /* clean up */
++              free_page(page_addr);
++              vfree(pte->sublevel);
++              memset(pte, 0, sizeof(struct gasket_page_table_entry));
++
++              return -ENOMEM;
++      }
++
++      /* make the addresses available to the device */
++      dma_addr = (pte->dma_addr + pte->offset) | GASKET_VALID_SLOT_FLAG;
++      writeq(dma_addr, slot);
++
++      pte->flags = SET(FLAGS_STATUS, pte->flags, PTE_INUSE);
++
++      return 0;
++}
++
++/*
++ * Allocate slots in an extended page table.  Check to see if a range of page
++ * table slots are available. If necessary, memory is allocated for second level
++ * page tables.
++ *
++ * Note that memory for second level page tables is allocated as needed, but
++ * that memory is only freed on the final close       of the device file, when the
++ * page tables are repartitioned, or the the device is removed.  If there is an
++ * error or if the full range of slots is not available, any memory
++ * allocated for second level page tables remains allocated until final close,
++ * repartition, or device removal.
++ *
++ * The page table mutex must be held by the caller.
++ */
++static int gasket_alloc_extended_entries(struct gasket_page_table *pg_tbl,
++                                       u64 dev_addr, uint num_entries)
++{
++      int ret = 0;
++      uint remain, subtable_slot_idx, len;
++      struct gasket_page_table_entry *pte;
++      u64 __iomem *slot;
++
++      remain = num_entries;
++      subtable_slot_idx = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
++      pte = pg_tbl->entries + pg_tbl->num_simple_entries +
++            gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++      slot = pg_tbl->base_slot + pg_tbl->num_simple_entries +
++             gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++
++      while (remain > 0) {
++              len = min(remain,
++                        GASKET_PAGES_PER_SUBTABLE - subtable_slot_idx);
++
++              if (GET(FLAGS_STATUS, pte->flags) == PTE_FREE) {
++                      ret = gasket_alloc_extended_subtable(pg_tbl, pte, slot);
++                      if (ret) {
++                              dev_err(pg_tbl->device,
++                                      "no memory for extended addr subtable\n");
++                              return ret;
++                      }
++              } else {
++                      if (!gasket_is_pte_range_free(pte->sublevel +
++                                                    subtable_slot_idx, len))
++                              return -EBUSY;
++              }
++
++              remain -= len;
++              subtable_slot_idx = 0;
++              pte++;
++              slot++;
++      }
++
++      return 0;
++}
++
++/*
++ * gasket_map_extended_pages - Get and map buffers to extended addresses.
++ * If there is an error, no pages are mapped.
++ */
++static int gasket_map_extended_pages(struct gasket_page_table *pg_tbl,
++                                   struct sg_page_iter *sg_iter,
++                                   ulong host_addr, u64 dev_addr,
++                                   uint num_pages, u32 flags)
++{
++      int ret;
++      u64 dev_addr_end;
++      uint slot_idx, remain, len;
++      struct gasket_page_table_entry *pte;
++      u64 __iomem *slot_base;
++
++      ret = gasket_alloc_extended_entries(pg_tbl, dev_addr, num_pages);
++      if (ret) {
++              dev_addr_end = dev_addr + (num_pages / PAGE_SIZE) - 1;
++              dev_err(pg_tbl->device,
++                      "page table slots (%lu,%lu) (@ 0x%llx) to (%lu,%lu) "
++                      "are not available\n",
++                      gasket_extended_lvl0_page_idx(pg_tbl, dev_addr),
++                      gasket_extended_lvl1_page_idx(pg_tbl, dev_addr),
++                      (long long unsigned int)dev_addr,
++                      gasket_extended_lvl0_page_idx(pg_tbl, dev_addr_end),
++                      gasket_extended_lvl1_page_idx(pg_tbl, dev_addr_end));
++              return ret;
++      }
++
++      remain = num_pages;
++      slot_idx = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
++      pte = pg_tbl->entries + pg_tbl->num_simple_entries +
++            gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++
++      while (remain > 0) {
++              len = min(remain, GASKET_PAGES_PER_SUBTABLE - slot_idx);
++
++              slot_base =
++                      (u64 __iomem *)(page_address(pte->page) + pte->offset);
++              ret = gasket_perform_mapping(pg_tbl, pte->sublevel + slot_idx,
++                                           slot_base + slot_idx, sg_iter,
++                                           host_addr, len, flags, 0);
++              if (ret) {
++                      gasket_page_table_unmap_nolock(pg_tbl, dev_addr,
++                                                     num_pages);
++                      return ret;
++              }
++
++              /*
++               * Extended page tables are in DRAM so they need to be synced
++               * each time they are updated.
++               */
++              dma_sync_single_for_device(pg_tbl->device,
++                                         pte->dma_addr + slot_idx * sizeof(u64),
++                                         len * sizeof(u64), DMA_TO_DEVICE);
++
++              remain -= len;
++              slot_idx = 0;
++              pte++;
++              if (host_addr)
++                      host_addr += len * PAGE_SIZE;
++      }
++
++      return 0;
++}
++
++/*
++ * See gasket_page_table.h for general description.
++ *
++ * gasket_page_table_map calls either gasket_map_simple_pages() or
++ * gasket_map_extended_pages() to actually perform the mapping.
++ *
++ * The page table mutex is held for the entire operation.
++ */
++int gasket_page_table_map(struct gasket_page_table *pg_tbl, ulong host_addr,
++                        u64 dev_addr, uint num_pages, u32 flags)
++{
++      int ret;
++
++      if (!num_pages)
++              return 0;
++
++      mutex_lock(&pg_tbl->mutex);
++
++      if (gasket_addr_is_simple(pg_tbl, dev_addr)) {
++              ret = gasket_map_simple_pages(pg_tbl, NULL, host_addr, dev_addr,
++                                            num_pages, flags);
++      } else {
++              ret = gasket_map_extended_pages(pg_tbl, NULL, host_addr, dev_addr,
++                                              num_pages, flags);
++      }
++
++      mutex_unlock(&pg_tbl->mutex);
++
++      dev_dbg(pg_tbl->device,
++              "%s done: ha %llx daddr %llx num %d, flags %x ret %d\n",
++              __func__, (unsigned long long)host_addr,
++              (unsigned long long)dev_addr, num_pages, flags, ret);
++      return ret;
++}
++EXPORT_SYMBOL(gasket_page_table_map);
++
++/*
++ * See gasket_page_table.h for general description.
++ *
++ * gasket_page_table_unmap takes the page table lock and calls either
++ * gasket_unmap_simple_pages() or gasket_unmap_extended_pages() to
++ * actually unmap the pages from device space.
++ *
++ * The page table mutex is held for the entire operation.
++ */
++void gasket_page_table_unmap(struct gasket_page_table *pg_tbl, u64 dev_addr,
++                           uint num_pages)
++{
++      if (!num_pages)
++              return;
++
++      mutex_lock(&pg_tbl->mutex);
++      gasket_page_table_unmap_nolock(pg_tbl, dev_addr, num_pages);
++      mutex_unlock(&pg_tbl->mutex);
++}
++EXPORT_SYMBOL(gasket_page_table_unmap);
++
++int gasket_page_table_map_dmabuf(struct gasket_page_table *pg_tbl, int fd,
++                               u64 dev_addr, uint num_pages, u32 flags)
++{
++      int ret, locked = 0;
++      struct dma_buf *dmabuf = NULL;
++      struct dma_buf_attachment *attachment = NULL;
++      struct sg_table *sgt = NULL;
++      struct sg_page_iter sg_iter;
++      struct gasket_dmabuf_mapping *mapping = NULL;
++      enum dma_data_direction direction = GET(FLAGS_DMA_DIRECTION, flags);
++
++      if (direction == DMA_NONE) {
++              dev_err(pg_tbl->device,
++                      "invalid DMA direction flags=0x%x\n", flags);
++              return -EINVAL;
++      }
++
++      if (!num_pages)
++              return 0;
++
++      dmabuf = dma_buf_get(fd);
++      if (IS_ERR(dmabuf))
++              return PTR_ERR(dmabuf);
++
++      if (PAGE_ALIGN(dmabuf->size) / PAGE_SIZE < num_pages)
++              return -EINVAL;
++
++      mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
++      if (!mapping) {
++              ret = -ENOMEM;
++              goto out;
++      }
++
++      attachment = dma_buf_attach(dmabuf, pg_tbl->device);
++      if (IS_ERR(attachment)) {
++              ret = PTR_ERR(attachment);
++              goto out;
++      }
++
++      sgt = dma_buf_map_attachment(attachment, direction);
++      if (IS_ERR(sgt)) {
++              ret = PTR_ERR(sgt);
++              goto out;
++      }
++
++      mutex_lock(&pg_tbl->mutex);
++      locked = 1;
++
++      __sg_page_iter_start(&sg_iter, sgt->sgl, sgt->nents, 0);
++      if (gasket_addr_is_simple(pg_tbl, dev_addr)) {
++              ret = gasket_map_simple_pages(pg_tbl, &sg_iter, 0, dev_addr,
++                                            num_pages, flags);
++      } else {
++              ret = gasket_map_extended_pages(pg_tbl, &sg_iter, 0, dev_addr,
++                                              num_pages, flags);
++      }
++
++      if (!ret) {
++              INIT_LIST_HEAD(&mapping->list);
++              get_dma_buf(dmabuf);
++              mapping->dmabuf = dmabuf;
++              mapping->attachment = attachment;
++              mapping->sgt = sgt;
++              mapping->direction = direction;
++              list_add(&mapping->list, &pg_tbl->dmabufs);
++              sgt = NULL;
++              attachment = NULL;
++              mapping = NULL;
++      }
++
++out:
++      if (locked)
++              mutex_unlock(&pg_tbl->mutex);
++
++      if (!IS_ERR_OR_NULL(sgt))
++              dma_buf_unmap_attachment(attachment, sgt, direction);
++
++      if (!IS_ERR_OR_NULL(attachment))
++              dma_buf_detach(dmabuf, attachment);
++
++      kfree(mapping);
++      dma_buf_put(dmabuf);
++
++      return ret;
++}
++EXPORT_SYMBOL(gasket_page_table_map_dmabuf);
++
++/* Detach dmabuf from our device if attached, NULL to detach all. */
++static void gasket_page_table_detach_dmabuf_nolock(struct gasket_page_table *pg_tbl,
++                                                 struct dma_buf *dmabuf)
++{
++      struct gasket_dmabuf_mapping *mapping, *tmp;
++
++      list_for_each_entry_safe(mapping, tmp, &pg_tbl->dmabufs, list) {
++              if (!dmabuf || mapping->dmabuf == dmabuf) {
++                      dma_buf_unmap_attachment(mapping->attachment,
++                                               mapping->sgt,
++                                               mapping->direction);
++                      dma_buf_detach(mapping->dmabuf, mapping->attachment);
++                      dma_buf_put(mapping->dmabuf);
++                      list_del(&mapping->list);
++                      kfree(mapping);
++              }
++      }
++}
++
++int gasket_page_table_unmap_dmabuf(struct gasket_page_table *pg_tbl, int fd,
++                                 u64 dev_addr, uint num_pages)
++{
++      struct dma_buf *dmabuf;
++
++      dmabuf = dma_buf_get(fd);
++      if (IS_ERR(dmabuf))
++              return PTR_ERR(dmabuf);
++
++      if (PAGE_ALIGN(dmabuf->size) / PAGE_SIZE < num_pages) {
++              dma_buf_put(dmabuf);
++              return -EINVAL;
++      }
++
++      mutex_lock(&pg_tbl->mutex);
++
++      gasket_page_table_unmap_nolock(pg_tbl, dev_addr, num_pages);
++      gasket_page_table_detach_dmabuf_nolock(pg_tbl, dmabuf);
++
++      mutex_unlock(&pg_tbl->mutex);
++
++      dma_buf_put(dmabuf);
++
++      return 0;
++}
++EXPORT_SYMBOL(gasket_page_table_unmap_dmabuf);
++
++static void gasket_page_table_unmap_all_nolock(struct gasket_page_table *pg_tbl)
++{
++      gasket_page_table_detach_dmabuf_nolock(pg_tbl, NULL);
++
++      gasket_unmap_simple_pages(pg_tbl,
++                                gasket_components_to_dev_address(pg_tbl, 1, 0,
++                                                                 0),
++                                pg_tbl->num_simple_entries);
++      gasket_unmap_extended_pages(pg_tbl,
++                                  gasket_components_to_dev_address(pg_tbl, 0,
++                                                                   0, 0),
++                                  pg_tbl->num_extended_entries *
++                                  GASKET_PAGES_PER_SUBTABLE);
++}
++
++/* See gasket_page_table.h for description. */
++void gasket_page_table_unmap_all(struct gasket_page_table *pg_tbl)
++{
++      mutex_lock(&pg_tbl->mutex);
++      gasket_page_table_unmap_all_nolock(pg_tbl);
++      mutex_unlock(&pg_tbl->mutex);
++}
++EXPORT_SYMBOL(gasket_page_table_unmap_all);
++
++/* See gasket_page_table.h for description. */
++void gasket_page_table_reset(struct gasket_page_table *pg_tbl)
++{
++      mutex_lock(&pg_tbl->mutex);
++      gasket_page_table_unmap_all_nolock(pg_tbl);
++      writeq(pg_tbl->config.total_entries, pg_tbl->extended_offset_reg);
++      mutex_unlock(&pg_tbl->mutex);
++}
++
++/* See gasket_page_table.h for description. */
++int gasket_page_table_lookup_page(
++      struct gasket_page_table *pg_tbl, u64 dev_addr, struct page **ppage,
++      ulong *poffset)
++{
++      uint page_num;
++      struct gasket_page_table_entry *pte;
++
++      mutex_lock(&pg_tbl->mutex);
++      if (gasket_addr_is_simple(pg_tbl, dev_addr)) {
++              page_num = gasket_simple_page_idx(pg_tbl, dev_addr);
++              if (page_num >= pg_tbl->num_simple_entries)
++                      goto fail;
++
++              pte = pg_tbl->entries + page_num;
++              if (GET(FLAGS_STATUS, pte->flags) != PTE_INUSE)
++                      goto fail;
++      } else {
++              /* Find the level 0 entry, */
++              page_num = gasket_extended_lvl0_page_idx(pg_tbl, dev_addr);
++              if (page_num >= pg_tbl->num_extended_entries)
++                      goto fail;
++
++              pte = pg_tbl->entries + pg_tbl->num_simple_entries + page_num;
++              if (GET(FLAGS_STATUS, pte->flags) != PTE_INUSE)
++                      goto fail;
++
++              /* and its contained level 1 entry. */
++              page_num = gasket_extended_lvl1_page_idx(pg_tbl, dev_addr);
++              pte = pte->sublevel + page_num;
++              if (GET(FLAGS_STATUS, pte->flags) != PTE_INUSE)
++                      goto fail;
++      }
++
++      *ppage = pte->page;
++      *poffset = pte->offset;
++      mutex_unlock(&pg_tbl->mutex);
++      return 0;
++
++fail:
++      *ppage = NULL;
++      *poffset = 0;
++      mutex_unlock(&pg_tbl->mutex);
++      return -EINVAL;
++}
++
++/* See gasket_page_table.h for description. */
++bool gasket_page_table_are_addrs_bad(
++      struct gasket_page_table *pg_tbl, ulong host_addr, u64 dev_addr,
++      ulong bytes)
++{
++      if (host_addr & (PAGE_SIZE - 1)) {
++              dev_err(pg_tbl->device,
++                      "host mapping address 0x%lx must be page aligned\n",
++                      host_addr);
++              return true;
++      }
++
++      return gasket_page_table_is_dev_addr_bad(pg_tbl, dev_addr, bytes);
++}
++EXPORT_SYMBOL(gasket_page_table_are_addrs_bad);
++
++/* See gasket_page_table.h for description. */
++bool gasket_page_table_is_dev_addr_bad(
++      struct gasket_page_table *pg_tbl, u64 dev_addr, ulong bytes)
++{
++      uint num_pages = bytes / PAGE_SIZE;
++
++      if (bytes & (PAGE_SIZE - 1)) {
++              dev_err(pg_tbl->device,
++                      "mapping size 0x%lX must be page aligned\n", bytes);
++              return true;
++      }
++
++      if (num_pages == 0) {
++              dev_err(pg_tbl->device,
++                      "requested mapping is less than one page: %lu / %lu\n",
++                      bytes, PAGE_SIZE);
++              return true;
++      }
++
++      if (gasket_addr_is_simple(pg_tbl, dev_addr))
++              return gasket_is_simple_dev_addr_bad(pg_tbl, dev_addr,
++                                                   num_pages);
++      return gasket_is_extended_dev_addr_bad(pg_tbl, dev_addr, num_pages);
++}
++EXPORT_SYMBOL(gasket_page_table_is_dev_addr_bad);
++
++/* See gasket_page_table.h for description. */
++uint gasket_page_table_max_size(struct gasket_page_table *page_table)
++{
++      if (!page_table)
++              return 0;
++      return page_table->config.total_entries;
++}
++EXPORT_SYMBOL(gasket_page_table_max_size);
++
++/* See gasket_page_table.h for description. */
++uint gasket_page_table_num_entries(struct gasket_page_table *pg_tbl)
++{
++      if (!pg_tbl)
++              return 0;
++      return pg_tbl->num_simple_entries + pg_tbl->num_extended_entries;
++}
++EXPORT_SYMBOL(gasket_page_table_num_entries);
++
++/* See gasket_page_table.h for description. */
++uint gasket_page_table_num_simple_entries(struct gasket_page_table *pg_tbl)
++{
++      if (!pg_tbl)
++              return 0;
++      return pg_tbl->num_simple_entries;
++}
++EXPORT_SYMBOL(gasket_page_table_num_simple_entries);
++
++/* See gasket_page_table.h for description. */
++uint gasket_page_table_num_active_pages(struct gasket_page_table *pg_tbl)
++{
++      if (!pg_tbl)
++              return 0;
++      return pg_tbl->num_active_pages;
++}
++EXPORT_SYMBOL(gasket_page_table_num_active_pages);
++
++/* See gasket_page_table.h */
++int gasket_page_table_system_status(struct gasket_page_table *page_table)
++{
++      if (!page_table)
++              return GASKET_STATUS_LAMED;
++
++      if (gasket_page_table_num_entries(page_table) == 0) {
++              dev_dbg(page_table->device, "Page table size is 0\n");
++              return GASKET_STATUS_LAMED;
++      }
++
++      return GASKET_STATUS_ALIVE;
++}
++
++/* Record the host_addr to coherent dma memory mapping. */
++int gasket_set_user_virt(
++      struct gasket_dev *gasket_dev, u64 size, dma_addr_t dma_address,
++      ulong vma)
++{
++      int j;
++      struct gasket_page_table *pg_tbl;
++
++      unsigned int num_pages = size / PAGE_SIZE;
++
++      /*
++       * TODO: for future chipset, better handling of the case where multiple
++       * page tables are supported on a given device
++       */
++      pg_tbl = gasket_dev->page_table[0];
++      if (!pg_tbl) {
++              dev_dbg(gasket_dev->dev, "%s: invalid page table index\n",
++                      __func__);
++              return 0;
++      }
++      for (j = 0; j < num_pages; j++) {
++              pg_tbl->coherent_pages[j].user_virt =
++                      (u64)vma + j * PAGE_SIZE;
++      }
++      return 0;
++}
++
++/* Allocate a block of coherent memory. */
++int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size,
++                               dma_addr_t *dma_address, u64 index)
++{
++      dma_addr_t handle;
++      void *mem;
++      int j;
++      unsigned int num_pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
++      const struct gasket_driver_desc *driver_desc =
++              gasket_get_driver_desc(gasket_dev);
++
++      if (!gasket_dev->page_table[index])
++              return -EFAULT;
++
++      if (num_pages == 0)
++              return -EINVAL;
++
++      mem = dma_alloc_coherent(gasket_get_device(gasket_dev),
++                               num_pages * PAGE_SIZE, &handle, GFP_KERNEL);
++      if (!mem)
++              goto nomem;
++
++      gasket_dev->page_table[index]->num_coherent_pages = num_pages;
++
++      /* allocate the physical memory block */
++      gasket_dev->page_table[index]->coherent_pages =
++              kcalloc(num_pages, sizeof(struct gasket_coherent_page_entry),
++                      GFP_KERNEL);
++      if (!gasket_dev->page_table[index]->coherent_pages)
++              goto nomem;
++
++      gasket_dev->coherent_buffer.length_bytes =
++              PAGE_SIZE * (num_pages);
++      gasket_dev->coherent_buffer.phys_base = handle;
++      gasket_dev->coherent_buffer.virt_base = mem;
++
++      *dma_address = driver_desc->coherent_buffer_description.base;
++      for (j = 0; j < num_pages; j++) {
++              gasket_dev->page_table[index]->coherent_pages[j].paddr =
++                      handle + j * PAGE_SIZE;
++              gasket_dev->page_table[index]->coherent_pages[j].kernel_virt =
++                      (ulong)mem + j * PAGE_SIZE;
++      }
++
++      return 0;
++
++nomem:
++      if (mem) {
++              dma_free_coherent(gasket_get_device(gasket_dev),
++                                num_pages * PAGE_SIZE, mem, handle);
++              gasket_dev->coherent_buffer.length_bytes = 0;
++              gasket_dev->coherent_buffer.virt_base = NULL;
++              gasket_dev->coherent_buffer.phys_base = 0;
++      }
++
++      kfree(gasket_dev->page_table[index]->coherent_pages);
++      gasket_dev->page_table[index]->coherent_pages = NULL;
++      gasket_dev->page_table[index]->num_coherent_pages = 0;
++      return -ENOMEM;
++}
++
++/* Free a block of coherent memory. */
++int gasket_free_coherent_memory(struct gasket_dev *gasket_dev, u64 size,
++                              dma_addr_t dma_address, u64 index)
++{
++      const struct gasket_driver_desc *driver_desc;
++
++      if (!gasket_dev->page_table[index])
++              return -EFAULT;
++
++      driver_desc = gasket_get_driver_desc(gasket_dev);
++
++      if (driver_desc->coherent_buffer_description.base != dma_address)
++              return -EADDRNOTAVAIL;
++
++      gasket_free_coherent_memory_all(gasket_dev, index);
++
++      return 0;
++}
++
++/* Release all coherent memory. */
++void gasket_free_coherent_memory_all(
++      struct gasket_dev *gasket_dev, u64 index)
++{
++      if (!gasket_dev->page_table[index])
++              return;
++
++      if (gasket_dev->coherent_buffer.length_bytes) {
++              dma_free_coherent(gasket_get_device(gasket_dev),
++                                gasket_dev->coherent_buffer.length_bytes,
++                                gasket_dev->coherent_buffer.virt_base,
++                                gasket_dev->coherent_buffer.phys_base);
++              gasket_dev->coherent_buffer.length_bytes = 0;
++              gasket_dev->coherent_buffer.virt_base = NULL;
++              gasket_dev->coherent_buffer.phys_base = 0;
++      }
++
++      kfree(gasket_dev->page_table[index]->coherent_pages);
++      gasket_dev->page_table[index]->coherent_pages = NULL;
++      gasket_dev->page_table[index]->num_coherent_pages = 0;
++}
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_page_table.h b/drivers/staging/gasket-driver/gasket_page_table.h
+--- a/drivers/staging/gasket-driver/gasket_page_table.h        1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_page_table.h        2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,283 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Gasket Page Table functionality. This file describes the address
++ * translation/paging functionality supported by the Gasket driver framework.
++ * As much as possible, internal details are hidden to simplify use -
++ * all calls are thread-safe (protected by an internal mutex) except where
++ * indicated otherwise.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++
++#ifndef __GASKET_PAGE_TABLE_H__
++#define __GASKET_PAGE_TABLE_H__
++
++#include <linux/pci.h>
++#include <linux/types.h>
++
++#include "gasket_constants.h"
++#include "gasket_core.h"
++
++/*
++ * Structure used for managing address translation on a device. All details are
++ * internal to the implementation.
++ */
++struct gasket_page_table;
++
++/*
++ * Allocate and init address translation data.
++ * @ppage_table: Pointer to Gasket page table pointer. Set by this call.
++ * @att_base_reg: [Mapped] pointer to the first entry in the device's address
++ *                translation table.
++ * @extended_offset_reg: [Mapped] pointer to the device's register containing
++ *                       the starting index of the extended translation table.
++ * @extended_bit_location: The index of the bit indicating whether an address
++ *                         is extended.
++ * @total_entries: The total number of entries in the device's address
++ *                 translation table.
++ * @device: Device structure for the underlying device. Only used for logging.
++ * @pci_dev: PCI system descriptor for the underlying device.
++ * whether the driver will supply its own.
++ *
++ * Description: Allocates and initializes data to track address translation -
++ * simple and extended page table metadata. Initially, the page table is
++ * partitioned such that all addresses are "simple" (single-level lookup).
++ * gasket_partition_page_table can be called to change this paritioning.
++ *
++ * Returns 0 on success, a negative error code otherwise.
++ */
++int gasket_page_table_init(struct gasket_page_table **ppg_tbl,
++                         const struct gasket_bar_data *bar_data,
++                         const struct gasket_page_table_config *page_table_config,
++                         struct device *device, struct pci_dev *pci_dev);
++
++/*
++ * Deallocate and cleanup page table data.
++ * @page_table: Gasket page table pointer.
++ *
++ * Description: The inverse of gasket_init; frees page_table and its contained
++ *              elements.
++ *
++ *            Because this call destroys the page table, it cannot be
++ *            thread-safe (mutex-protected)!
++ */
++void gasket_page_table_cleanup(struct gasket_page_table *page_table);
++
++/*
++ * Sets the size of the simple page table.
++ * @page_table: Gasket page table pointer.
++ * @num_simple_entries: Desired size of the simple page table (in entries).
++ *
++ * Description: gasket_partition_page_table checks to see if the simple page
++ *              size can be changed (i.e., if there are no active extended
++ *              mappings in the new simple size range), and, if so,
++ *              sets the new simple and extended page table sizes.
++ *
++ *              Returns 0 if successful, or non-zero if the page table entries
++ *              are not free.
++ */
++int gasket_page_table_partition(struct gasket_page_table *page_table,
++                              uint num_simple_entries);
++
++/*
++ * Get and map [host] user space pages into device memory.
++ * @page_table: Gasket page table pointer.
++ * @host_addr: Starting host virtual memory address of the pages.
++ * @dev_addr: Starting device address of the pages.
++ * @num_pages: Number of [4kB] pages to map.
++ * @flags: Specifies attributes to apply to the pages.
++ *         Internal structure matches gasket_page_table_ioctl_flags.flags.
++ *
++ * Description: Maps the "num_pages" pages of host memory pointed to by
++ *              host_addr to the address "dev_addr" in device memory.
++ *
++ *              The caller is responsible for checking the addresses ranges.
++ *
++ *              Returns 0 if successful or a non-zero error number otherwise.
++ *              If there is an error, no pages are mapped.
++ */
++int gasket_page_table_map(struct gasket_page_table *page_table, ulong host_addr,
++                        u64 dev_addr, uint num_pages, u32 flags);
++
++/*
++ * Map dma-buf pages into device memory.
++ * @page_table: Gasket page table pointer.
++ * @fd: Dma-buf file descriptor.
++ * @dev_addr: Starting device address of the pages.
++ * @num_pages: Number of [4kB] pages to map.
++ * @flags: Specifies attributes to apply to the pages.
++ *         Internal structure matches gasket_page_table_ioctl_flags.flags.
++ *
++ * Description: Maps "num_pages" pages of dma-buf pointed to by
++ *              fd to the address "dev_addr" in device memory.
++ *
++ *              The caller is responsible for checking the dev_addr range.
++ *
++ *              Returns 0 if successful or a non-zero error number otherwise.
++ *              If there is an error, no pages are mapped.
++ */
++int gasket_page_table_map_dmabuf(struct gasket_page_table *page_table, int fd,
++                               u64 dev_addr, uint num_pages, u32 flags);
++
++/*
++ * Unmap dma-buf pages from device memory.
++ * @page_table: Gasket page table pointer.
++ * @fd: Dma-buf file descriptor.
++ * @dev_addr: Starting device address of the pages.
++ * @num_pages: Number of [4kB] pages to map.
++ *
++ * Description: The inverse of gasket_page_table_map_dmabuf.
++ */
++int gasket_page_table_unmap_dmabuf(struct gasket_page_table *page_table, int fd,
++                                 u64 dev_addr, uint num_pages);
++
++/*
++ * Un-map host pages from device memory.
++ * @page_table: Gasket page table pointer.
++ * @dev_addr: Starting device address of the pages to unmap.
++ * @num_pages: The number of [4kB] pages to unmap.
++ *
++ * Description: The inverse of gasket_map_pages. Unmaps pages from the device.
++ */
++void gasket_page_table_unmap(struct gasket_page_table *page_table,
++                           u64 dev_addr, uint num_pages);
++
++/*
++ * Unmap ALL host pages from device memory.
++ * @page_table: Gasket page table pointer.
++ */
++void gasket_page_table_unmap_all(struct gasket_page_table *page_table);
++
++/*
++ * Unmap all host pages from device memory and reset the table to fully simple
++ * addressing.
++ * @page_table: Gasket page table pointer.
++ */
++void gasket_page_table_reset(struct gasket_page_table *page_table);
++
++/*
++ * Reclaims unused page table memory.
++ * @page_table: Gasket page table pointer.
++ *
++ * Description: Examines the page table and frees any currently-unused
++ *              allocations. Called internally on gasket_cleanup().
++ */
++void gasket_page_table_garbage_collect(struct gasket_page_table *page_table);
++
++/*
++ * Retrieve the backing page for a device address.
++ * @page_table: Gasket page table pointer.
++ * @dev_addr: Gasket device address.
++ * @ppage: Pointer to a page pointer for the returned page.
++ * @poffset: Pointer to an unsigned long for the returned offset.
++ *
++ * Description: Interprets the address and looks up the corresponding page
++ *              in the page table and the offset in that page.  (We need an
++ *              offset because the host page may be larger than the Gasket chip
++ *              page it contains.)
++ *
++ *              Returns 0 if successful, -1 for an error.  The page pointer
++ *              and offset are returned through the pointers, if successful.
++ */
++int gasket_page_table_lookup_page(struct gasket_page_table *page_table,
++                                u64 dev_addr, struct page **page,
++                                ulong *poffset);
++
++/*
++ * Checks validity for input addrs and size.
++ * @page_table: Gasket page table pointer.
++ * @host_addr: Host address to check.
++ * @dev_addr: Gasket device address.
++ * @bytes: Size of the range to check (in bytes).
++ *
++ * Description: This call performs a number of checks to verify that the ranges
++ * specified by both addresses and the size are valid for mapping pages into
++ * device memory.
++ *
++ * Returns true if the mapping is bad, false otherwise.
++ */
++bool gasket_page_table_are_addrs_bad(struct gasket_page_table *page_table,
++                                   ulong host_addr, u64 dev_addr,
++                                   ulong bytes);
++
++/*
++ * Checks validity for input dev addr and size.
++ * @page_table: Gasket page table pointer.
++ * @dev_addr: Gasket device address.
++ * @bytes: Size of the range to check (in bytes).
++ *
++ * Description: This call performs a number of checks to verify that the range
++ * specified by the device address and the size is valid for mapping pages into
++ * device memory.
++ *
++ * Returns true if the address is bad, false otherwise.
++ */
++bool gasket_page_table_is_dev_addr_bad(struct gasket_page_table *page_table,
++                                     u64 dev_addr, ulong bytes);
++
++/*
++ * Gets maximum size for the given page table.
++ * @page_table: Gasket page table pointer.
++ */
++uint gasket_page_table_max_size(struct gasket_page_table *page_table);
++
++/*
++ * Gets the total number of entries in the arg.
++ * @page_table: Gasket page table pointer.
++ */
++uint gasket_page_table_num_entries(struct gasket_page_table *page_table);
++
++/*
++ * Gets the number of simple entries.
++ * @page_table: Gasket page table pointer.
++ */
++uint gasket_page_table_num_simple_entries(struct gasket_page_table *page_table);
++
++/*
++ * Gets the number of actively pinned pages.
++ * @page_table: Gasket page table pointer.
++ */
++uint gasket_page_table_num_active_pages(struct gasket_page_table *page_table);
++
++/*
++ * Get status of page table managed by @page_table.
++ * @page_table: Gasket page table pointer.
++ */
++int gasket_page_table_system_status(struct gasket_page_table *page_table);
++
++/*
++ * Allocate a block of coherent memory.
++ * @gasket_dev: Gasket Device.
++ * @size: Size of the memory block.
++ * @dma_address: Dma address allocated by the kernel.
++ * @index: Index of the gasket_page_table within this Gasket device
++ *
++ * Description: Allocate a contiguous coherent memory block, DMA'ble
++ * by this device.
++ */
++int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, uint64_t size,
++                               dma_addr_t *dma_address, uint64_t index);
++/* Release a block of contiguous coherent memory, in use by a device. */
++int gasket_free_coherent_memory(struct gasket_dev *gasket_dev, uint64_t size,
++                              dma_addr_t dma_address, uint64_t index);
++
++/* Release all coherent memory. */
++void gasket_free_coherent_memory_all(struct gasket_dev *gasket_dev,
++                                   uint64_t index);
++
++/*
++ * Records the host_addr to coherent dma memory mapping.
++ * @gasket_dev: Gasket Device.
++ * @size: Size of the virtual address range to map.
++ * @dma_address: Dma address within the coherent memory range.
++ * @vma: Virtual address we wish to map to coherent memory.
++ *
++ * Description: For each page in the virtual address range, record the
++ * coherent page mapping.
++ *
++ * Does not perform validity checking.
++ */
++int gasket_set_user_virt(struct gasket_dev *gasket_dev, uint64_t size,
++                       dma_addr_t dma_address, ulong vma);
++
++#endif  /* __GASKET_PAGE_TABLE_H__ */
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_sysfs.c b/drivers/staging/gasket-driver/gasket_sysfs.c
+--- a/drivers/staging/gasket-driver/gasket_sysfs.c     1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_sysfs.c     2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,400 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Copyright (C) 2018 Google, Inc. */
++#include "gasket_sysfs.h"
++
++#include "gasket_core.h"
++
++#include <linux/device.h>
++#include <linux/printk.h>
++
++/*
++ * Pair of kernel device and user-specified pointer. Used in lookups in sysfs
++ * "show" functions to return user data.
++ */
++
++struct gasket_sysfs_mapping {
++      /*
++       * The device bound to this mapping. If this is NULL, then this mapping
++       * is free.
++       */
++      struct device *device;
++
++      /* The Gasket descriptor for this device. */
++      struct gasket_dev *gasket_dev;
++
++      /* This device's set of sysfs attributes/nodes. */
++      struct gasket_sysfs_attribute *attributes;
++
++      /* The number of live elements in "attributes". */
++      int attribute_count;
++
++      /* Protects structure from simultaneous access. */
++      struct mutex mutex;
++
++      /* Tracks active users of this mapping. */
++      struct kref refcount;
++};
++
++/*
++ * Data needed to manage users of this sysfs utility.
++ * Currently has a fixed size; if space is a concern, this can be dynamically
++ * allocated.
++ */
++/*
++ * 'Global' (file-scoped) list of mappings between devices and gasket_data
++ * pointers. This removes the requirement to have a gasket_sysfs_data
++ * handle in all files.
++ */
++static struct gasket_sysfs_mapping dev_mappings[GASKET_SYSFS_NUM_MAPPINGS];
++
++/* Callback when a mapping's refcount goes to zero. */
++static void release_entry(struct kref *ref)
++{
++      /* All work is done after the return from kref_put. */
++}
++
++/* Look up mapping information for the given device. */
++static struct gasket_sysfs_mapping *get_mapping(struct device *device)
++{
++      int i;
++
++      for (i = 0; i < GASKET_SYSFS_NUM_MAPPINGS; i++) {
++              mutex_lock(&dev_mappings[i].mutex);
++              if (dev_mappings[i].device == device) {
++                      kref_get(&dev_mappings[i].refcount);
++                      mutex_unlock(&dev_mappings[i].mutex);
++                      return &dev_mappings[i];
++              }
++              mutex_unlock(&dev_mappings[i].mutex);
++      }
++
++      dev_dbg(device, "%s: Mapping to device %s not found\n",
++              __func__, device->kobj.name);
++      return NULL;
++}
++
++/* Put a reference to a mapping. */
++static void put_mapping(struct gasket_sysfs_mapping *mapping)
++{
++      int i;
++      int num_files_to_remove = 0;
++      struct device_attribute *files_to_remove;
++      struct device *device;
++
++      if (!mapping) {
++              pr_debug("%s: Mapping should not be NULL\n", __func__);
++              return;
++      }
++
++      mutex_lock(&mapping->mutex);
++      if (kref_put(&mapping->refcount, release_entry)) {
++              dev_dbg(mapping->device, "Removing Gasket sysfs mapping\n");
++              /*
++               * We can't remove the sysfs nodes in the kref callback, since
++               * device_remove_file() blocks until the node is free.
++               * Readers/writers of sysfs nodes, though, will be blocked on
++               * the mapping mutex, resulting in deadlock. To fix this, the
++               * sysfs nodes are removed outside the lock.
++               */
++              device = mapping->device;
++              num_files_to_remove = mapping->attribute_count;
++              files_to_remove = kcalloc(num_files_to_remove,
++                                        sizeof(*files_to_remove),
++                                        GFP_KERNEL);
++              if (files_to_remove)
++                      for (i = 0; i < num_files_to_remove; i++)
++                              files_to_remove[i] =
++                                  mapping->attributes[i].attr;
++              else
++                      num_files_to_remove = 0;
++
++              kfree(mapping->attributes);
++              mapping->attributes = NULL;
++              mapping->attribute_count = 0;
++              put_device(mapping->device);
++              mapping->device = NULL;
++              mapping->gasket_dev = NULL;
++      }
++      mutex_unlock(&mapping->mutex);
++
++      if (num_files_to_remove != 0) {
++              for (i = 0; i < num_files_to_remove; ++i)
++                      device_remove_file(device, &files_to_remove[i]);
++              kfree(files_to_remove);
++      }
++}
++
++/*
++ * Put a reference to a mapping N times.
++ *
++ * In higher-level resource acquire/release function pairs, the release function
++ * will need to release a mapping 2x - once for the refcount taken in the
++ * release function itself, and once for the count taken in the acquire call.
++ */
++static void put_mapping_n(struct gasket_sysfs_mapping *mapping, int times)
++{
++      int i;
++
++      for (i = 0; i < times; i++)
++              put_mapping(mapping);
++}
++
++void gasket_sysfs_init(void)
++{
++      int i;
++
++      for (i = 0; i < GASKET_SYSFS_NUM_MAPPINGS; i++) {
++              dev_mappings[i].device = NULL;
++              mutex_init(&dev_mappings[i].mutex);
++      }
++}
++
++int gasket_sysfs_create_mapping(struct device *device,
++                              struct gasket_dev *gasket_dev)
++{
++      struct gasket_sysfs_mapping *mapping;
++      int map_idx = -1;
++
++      /*
++       * We need a function-level mutex to protect against the same device
++       * being added [multiple times] simultaneously.
++       */
++      static DEFINE_MUTEX(function_mutex);
++
++      mutex_lock(&function_mutex);
++      dev_dbg(device, "Creating sysfs entries for device\n");
++
++      /* Check that the device we're adding hasn't already been added. */
++      mapping = get_mapping(device);
++      if (mapping) {
++              dev_err(device,
++                      "Attempting to re-initialize sysfs mapping for device\n");
++              put_mapping(mapping);
++              mutex_unlock(&function_mutex);
++              return -EBUSY;
++      }
++
++      /* Find the first empty entry in the array. */
++      for (map_idx = 0; map_idx < GASKET_SYSFS_NUM_MAPPINGS; ++map_idx) {
++              mutex_lock(&dev_mappings[map_idx].mutex);
++              if (!dev_mappings[map_idx].device)
++                      /* Break with the mutex held! */
++                      break;
++              mutex_unlock(&dev_mappings[map_idx].mutex);
++      }
++
++      if (map_idx == GASKET_SYSFS_NUM_MAPPINGS) {
++              dev_err(device, "All mappings have been exhausted\n");
++              mutex_unlock(&function_mutex);
++              return -ENOMEM;
++      }
++
++      dev_dbg(device, "Creating sysfs mapping for device %s\n",
++              device->kobj.name);
++
++      mapping = &dev_mappings[map_idx];
++      mapping->attributes = kcalloc(GASKET_SYSFS_MAX_NODES,
++                                    sizeof(*mapping->attributes),
++                                    GFP_KERNEL);
++      if (!mapping->attributes) {
++              dev_dbg(device, "Unable to allocate sysfs attribute array\n");
++              mutex_unlock(&mapping->mutex);
++              mutex_unlock(&function_mutex);
++              return -ENOMEM;
++      }
++
++      kref_init(&mapping->refcount);
++      mapping->device = get_device(device);
++      mapping->gasket_dev = gasket_dev;
++      mapping->attribute_count = 0;
++      mutex_unlock(&mapping->mutex);
++      mutex_unlock(&function_mutex);
++
++      /* Don't decrement the refcount here! One open count keeps it alive! */
++      return 0;
++}
++
++int gasket_sysfs_create_entries(struct device *device,
++                              const struct gasket_sysfs_attribute *attrs)
++{
++      int i;
++      int ret;
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++
++      if (!mapping) {
++              dev_dbg(device,
++                      "Creating entries for device without first "
++                      "initializing mapping\n");
++              return -EINVAL;
++      }
++
++      mutex_lock(&mapping->mutex);
++      for (i = 0; strcmp(attrs[i].attr.attr.name, GASKET_ARRAY_END_MARKER);
++              i++) {
++              if (mapping->attribute_count == GASKET_SYSFS_MAX_NODES) {
++                      dev_err(device,
++                              "Maximum number of sysfs nodes reached for "
++                              "device\n");
++                      mutex_unlock(&mapping->mutex);
++                      put_mapping(mapping);
++                      return -ENOMEM;
++              }
++
++              ret = device_create_file(device, &attrs[i].attr);
++              if (ret) {
++                      dev_dbg(device, "Unable to create device entries\n");
++                      mutex_unlock(&mapping->mutex);
++                      put_mapping(mapping);
++                      return ret;
++              }
++
++              mapping->attributes[mapping->attribute_count] = attrs[i];
++              ++mapping->attribute_count;
++      }
++
++      mutex_unlock(&mapping->mutex);
++      put_mapping(mapping);
++      return 0;
++}
++EXPORT_SYMBOL(gasket_sysfs_create_entries);
++
++void gasket_sysfs_remove_mapping(struct device *device)
++{
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++
++      if (!mapping) {
++              dev_err(device,
++                      "Attempted to remove non-existent sysfs mapping to "
++                      "device\n");
++              return;
++      }
++
++      put_mapping_n(mapping, 2);
++}
++
++struct gasket_dev *gasket_sysfs_get_device_data(struct device *device)
++{
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++
++      if (!mapping) {
++              dev_err(device, "device not registered\n");
++              return NULL;
++      }
++
++      return mapping->gasket_dev;
++}
++EXPORT_SYMBOL(gasket_sysfs_get_device_data);
++
++void gasket_sysfs_put_device_data(struct device *device, struct gasket_dev *dev)
++{
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++
++      if (!mapping)
++              return;
++
++      /* See comment of put_mapping_n() for why the '2' is necessary. */
++      put_mapping_n(mapping, 2);
++}
++EXPORT_SYMBOL(gasket_sysfs_put_device_data);
++
++struct gasket_sysfs_attribute *
++gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr)
++{
++      int i;
++      int num_attrs;
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++      struct gasket_sysfs_attribute *attrs = NULL;
++
++      if (!mapping)
++              return NULL;
++
++      attrs = mapping->attributes;
++      num_attrs = mapping->attribute_count;
++      for (i = 0; i < num_attrs; ++i) {
++              if (!strcmp(attrs[i].attr.attr.name, attr->attr.name))
++                      return &attrs[i];
++      }
++
++      dev_err(device, "Unable to find match for device_attribute %s\n",
++              attr->attr.name);
++      return NULL;
++}
++EXPORT_SYMBOL(gasket_sysfs_get_attr);
++
++void gasket_sysfs_put_attr(struct device *device,
++                         struct gasket_sysfs_attribute *attr)
++{
++      int i;
++      int num_attrs;
++      struct gasket_sysfs_mapping *mapping = get_mapping(device);
++      struct gasket_sysfs_attribute *attrs = NULL;
++
++      if (!mapping)
++              return;
++
++      attrs = mapping->attributes;
++      num_attrs = mapping->attribute_count;
++      for (i = 0; i < num_attrs; ++i) {
++              if (&attrs[i] == attr) {
++                      put_mapping_n(mapping, 2);
++                      return;
++              }
++      }
++
++      dev_err(device, "Unable to put unknown attribute: %s\n",
++              attr->attr.attr.name);
++}
++EXPORT_SYMBOL(gasket_sysfs_put_attr);
++
++ssize_t gasket_sysfs_register_store(struct device *device,
++                                  struct device_attribute *attr,
++                                  const char *buf, size_t count)
++{
++      ulong parsed_value = 0;
++      struct gasket_sysfs_mapping *mapping;
++      struct gasket_dev *gasket_dev;
++      struct gasket_sysfs_attribute *gasket_attr;
++
++      if (count < 3 || buf[0] != '0' || buf[1] != 'x') {
++              dev_err(device,
++                      "sysfs register write format: \"0x<hex value>\"\n");
++              return -EINVAL;
++      }
++
++      if (kstrtoul(buf, 16, &parsed_value) != 0) {
++              dev_err(device,
++                      "Unable to parse input as 64-bit hex value: %s\n", buf);
++              return -EINVAL;
++      }
++
++      mapping = get_mapping(device);
++      if (!mapping) {
++              dev_err(device, "Device driver may have been removed\n");
++              return 0;
++      }
++
++      gasket_dev = mapping->gasket_dev;
++      if (!gasket_dev) {
++              dev_err(device, "Device driver may have been removed\n");
++              return 0;
++      }
++
++      gasket_attr = gasket_sysfs_get_attr(device, attr);
++      if (!gasket_attr) {
++              put_mapping(mapping);
++              return count;
++      }
++
++      gasket_dev_write_64(gasket_dev, parsed_value,
++                          gasket_attr->data.bar_address.bar,
++                          gasket_attr->data.bar_address.offset);
++
++      if (gasket_attr->write_callback)
++              gasket_attr->write_callback(gasket_dev, gasket_attr,
++                                          parsed_value);
++
++      gasket_sysfs_put_attr(device, gasket_attr);
++      put_mapping(mapping);
++      return count;
++}
++EXPORT_SYMBOL(gasket_sysfs_register_store);
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/gasket_sysfs.h b/drivers/staging/gasket-driver/gasket_sysfs.h
+--- a/drivers/staging/gasket-driver/gasket_sysfs.h     1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/gasket_sysfs.h     2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,186 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * Set of common sysfs utilities.
++ *
++ * Copyright (C) 2018 Google, Inc.
++ */
++
++/* The functions described here are a set of utilities to allow each file in the
++ * Gasket driver framework to manage their own set of sysfs entries, instead of
++ * centralizing all that work in one file.
++ *
++ * The goal of these utilities is to allow for sysfs entries to be easily
++ * created without causing a proliferation of sysfs "show" functions. This
++ * requires O(N) string lookups during show function execution, but as reading
++ * sysfs entries is rarely performance-critical, this is likely acceptible.
++ */
++#ifndef __GASKET_SYSFS_H__
++#define __GASKET_SYSFS_H__
++
++#include "gasket_constants.h"
++#include "gasket_core.h"
++#include <linux/device.h>
++#include <linux/stringify.h>
++#include <linux/sysfs.h>
++
++/* The maximum number of mappings/devices a driver needs to support. */
++#define GASKET_SYSFS_NUM_MAPPINGS (GASKET_FRAMEWORK_DESC_MAX * GASKET_DEV_MAX)
++
++/* The maximum number of sysfs nodes in a directory.
++ */
++#define GASKET_SYSFS_MAX_NODES 196
++
++/* End markers for sysfs struct arrays. */
++#define GASKET_ARRAY_END_TOKEN GASKET_RESERVED_ARRAY_END
++#define GASKET_ARRAY_END_MARKER __stringify(GASKET_ARRAY_END_TOKEN)
++
++/*
++ * Terminator struct for a gasket_sysfs_attr array. Must be at the end of
++ * all gasket_sysfs_attribute arrays.
++ */
++#define GASKET_END_OF_ATTR_ARRAY                                               \
++      {                                                                      \
++              .attr = __ATTR(GASKET_ARRAY_END_TOKEN, S_IRUGO, NULL, NULL),   \
++              .data.attr_type = 0,                                           \
++      }
++
++/*
++ * Pairing of sysfs attribute and user data.
++ * Used in lookups in sysfs "show" functions to return attribute metadata.
++ */
++struct gasket_sysfs_attribute {
++      /* The underlying sysfs device attribute associated with this data. */
++      struct device_attribute attr;
++
++      /* User-specified data to associate with the attribute. */
++      union {
++              struct bar_address_ {
++                      ulong bar;
++                      ulong offset;
++              } bar_address;
++              uint attr_type;
++      } data;
++
++      /*
++       * Function pointer to a callback to be invoked when this attribute is
++       * written (if so configured). The arguments are to the Gasket device
++       * pointer, the enclosing gasket_attr structure, and the value written.
++       * The callback should perform any logging necessary, as errors cannot
++       * be returned from the callback.
++       */
++      void (*write_callback)(struct gasket_dev *dev,
++                             struct gasket_sysfs_attribute *attr,
++                             ulong value);
++};
++
++#define GASKET_SYSFS_RO(_name, _show_function, _attr_type)                     \
++      {                                                                      \
++              .attr = __ATTR(_name, S_IRUGO, _show_function, NULL),          \
++              .data.attr_type = _attr_type                                   \
++      }
++
++#define GASKET_SYSFS_RW(_name, _show_function, _store_function, _attr_type)    \
++      {                                                                      \
++              .attr = __ATTR(_name, S_IWUSR | S_IWGRP | S_IRUGO,             \
++                              _show_function, _store_function),              \
++              .data.attr_type = _attr_type                                   \
++      }
++
++/* Initializes the Gasket sysfs subsystem.
++ *
++ * Description: Performs one-time initialization. Must be called before usage
++ * at [Gasket] module load time.
++ */
++void gasket_sysfs_init(void);
++
++/*
++ * Create an entry in mapping_data between a device and a Gasket device.
++ * @device: Device struct to map to.
++ * @gasket_dev: The dev struct associated with the driver controlling @device.
++ *
++ * Description: This function maps a gasket_dev* to a device*. This mapping can
++ * be used in sysfs_show functions to get a handle to the gasket_dev struct
++ * controlling the device node.
++ *
++ * If this function is not called before gasket_sysfs_create_entries, a warning
++ * will be logged.
++ */
++int gasket_sysfs_create_mapping(struct device *device,
++                              struct gasket_dev *gasket_dev);
++
++/*
++ * Creates bulk entries in sysfs.
++ * @device: Kernel device structure.
++ * @attrs: List of attributes/sysfs entries to create.
++ *
++ * Description: Creates each sysfs entry described in "attrs". Can be called
++ * multiple times for a given @device. If the gasket_dev specified in
++ * gasket_sysfs_create_mapping had a legacy device, the entries will be created
++ * for it, as well.
++ */
++int gasket_sysfs_create_entries(struct device *device,
++                              const struct gasket_sysfs_attribute *attrs);
++
++/*
++ * Removes a device mapping from the global table.
++ * @device: Device to unmap.
++ *
++ * Description: Removes the device->Gasket device mapping from the internal
++ * table.
++ */
++void gasket_sysfs_remove_mapping(struct device *device);
++
++/*
++ * User data lookup based on kernel device structure.
++ * @device: Kernel device structure.
++ *
++ * Description: Returns the user data associated with "device" in a prior call
++ * to gasket_sysfs_create_entries. Returns NULL if no mapping can be found.
++ * Upon success, this call take a reference to internal sysfs data that must be
++ * released with gasket_sysfs_put_device_data. While this reference is held, the
++ * underlying device sysfs information/structure will remain valid/will not be
++ * deleted.
++ */
++struct gasket_dev *gasket_sysfs_get_device_data(struct device *device);
++
++/*
++ * Releases a references to internal data.
++ * @device: Kernel device structure.
++ * @dev: Gasket device descriptor (returned by gasket_sysfs_get_device_data).
++ */
++void gasket_sysfs_put_device_data(struct device *device,
++                                struct gasket_dev *gasket_dev);
++
++/*
++ * Gasket-specific attribute lookup.
++ * @device: Kernel device structure.
++ * @attr: Device attribute to look up.
++ *
++ * Returns the Gasket sysfs attribute associated with the kernel device
++ * attribute and device structure itself. Upon success, this call will take a
++ * reference to internal sysfs data that must be released with a call to
++ * gasket_sysfs_put_attr. While this reference is held, the underlying device
++ * sysfs information/structure will remain valid/will not be deleted.
++ */
++struct gasket_sysfs_attribute *
++gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr);
++
++/*
++ * Releases a references to internal data.
++ * @device: Kernel device structure.
++ * @attr: Gasket sysfs attribute descriptor (returned by
++ *        gasket_sysfs_get_attr).
++ */
++void gasket_sysfs_put_attr(struct device *device,
++                         struct gasket_sysfs_attribute *attr);
++
++/*
++ * Write to a register sysfs node.
++ * @buf: NULL-terminated data being written.
++ * @count: number of bytes in the "buf" argument.
++ */
++ssize_t gasket_sysfs_register_store(struct device *device,
++                                  struct device_attribute *attr,
++                                  const char *buf, size_t count);
++
++#endif /* __GASKET_SYSFS_H__ */
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/Kconfig b/drivers/staging/gasket-driver/Kconfig
+--- a/drivers/staging/gasket-driver/Kconfig    1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/Kconfig    2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,24 @@
++menu "Gasket devices"
++
++config STAGING_GASKET_FRAMEWORK
++      tristate "Gasket framework"
++      depends on PCI && (X86_64 || ARM64)
++      help
++        This framework supports Gasket-compatible devices, such as Apex.
++        It is required for any of the following module(s).
++
++        To compile this driver as a module, choose M here.  The module
++        will be called "gasket".
++
++config STAGING_APEX_DRIVER
++      tristate "Apex Driver"
++      depends on STAGING_GASKET_FRAMEWORK
++      help
++        This driver supports the Apex Edge TPU device.  See
++        https://cloud.google.com/edge-tpu/ for more information.
++        Say Y if you want to include this driver in the kernel.
++
++        To compile this driver as a module, choose M here.  The module
++        will be called "apex".
++
++endmenu
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/Makefile b/drivers/staging/gasket-driver/Makefile
+--- a/drivers/staging/gasket-driver/Makefile   1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/Makefile   2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,17 @@
++#
++#  Makefile for Gasket framework and dependent drivers.
++#
++
++obj-m += gasket.o
++obj-m += apex.o
++
++gasket-objs   := gasket_core.o gasket_ioctl.o gasket_interrupt.o gasket_page_table.o gasket_sysfs.o
++apex-objs     := apex_driver.o
++
++KVERSION := $(shell uname -r)
++
++all:
++      $(MAKE) -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
++
++clean:
++      $(MAKE) -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
+diff '--color=auto' -urN a/drivers/staging/gasket-driver/TODO b/drivers/staging/gasket-driver/TODO
+--- a/drivers/staging/gasket-driver/TODO       1970-01-01 01:00:00.000000000 +0100
++++ b/drivers/staging/gasket-driver/TODO       2025-02-19 19:25:02.480079055 +0000
+@@ -0,0 +1,9 @@
++This is a list of things that need to be done to get this driver out of the
++staging directory.
++- Document sysfs files with Documentation/ABI/ entries.
++- Use misc interface instead of major number for driver version description.
++- Add descriptions of module_param's
++- apex_get_status() should actually check status.
++- "drivers" should never be dealing with "raw" sysfs calls or mess around with
++  kobjects at all. The driver core should handle all of this for you
++  automaically. There should not be a need for raw attribute macros.
+diff '--color=auto' -urN a/drivers/staging/Kconfig b/drivers/staging/Kconfig
+--- a/drivers/staging/Kconfig  2025-02-18 23:57:39.206607973 +0000
++++ b/drivers/staging/Kconfig  2025-02-19 19:25:43.186155250 +0000
+@@ -50,4 +50,6 @@
+ source "drivers/staging/gpib/Kconfig"
++source "drivers/staging/gasket-driver/Kconfig"
++
+ endif # STAGING
diff --git a/sys-kernel/raspberrypi-sources/raspberrypi-sources-6.6.74_p20250127.ebuild b/sys-kernel/raspberrypi-sources/raspberrypi-sources-6.6.74_p20250127.ebuild
new file mode 100644 (file)
index 0000000..dd619af
--- /dev/null
@@ -0,0 +1,83 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+ETYPE=sources
+K_DEFCONFIG="bcmrpi_defconfig"
+K_SECURITY_UNSUPPORTED=1
+EXTRAVERSION="-${PN}/-*"
+
+K_EXP_GENPATCHES_NOUSE=1
+K_GENPATCHES_VER=54
+K_DEBLOB_AVAILABLE=0
+K_WANT_GENPATCHES="base extras"
+
+inherit kernel-2 linux-info
+detect_version
+detect_arch
+
+MY_P=$(ver_cut 4-)
+MY_P="stable_${MY_P/p/}"
+#COMMIT=789af262fb268b2006099a096faf4a383592ce1b
+#MY_P=${COMMIT}
+
+DESCRIPTION="Raspberry Pi kernel sources"
+HOMEPAGE="https://github.com/raspberrypi/linux"
+SRC_URI="
+       https://github.com/raspberrypi/linux/archive/${MY_P}.tar.gz -> linux-${KV_FULL}.tar.gz
+       ${GENPATCHES_URI}
+"
+
+KEYWORDS="arm arm64"
+
+PATCHES=(      "${FILESDIR}"/${PN}-6.1.21-gentoo-kconfig.patch
+                       "${FILESDIR}"/raspberrypi-sources-AI.patch)
+
+UNIPATCH_EXCLUDE="
+       10*
+       15*
+       1700
+       1730
+       2000
+       201*
+       2700
+       2800
+       29*
+       3000
+       4567"
+
+pkg_setup() {
+       ewarn ""
+       ewarn "${PN} is *not* supported by the Gentoo Kernel Project in any way."
+       ewarn "If you need support, please contact the raspberrypi developers directly."
+       ewarn "Do *not* open bugs in Gentoo's bugzilla unless you have issues with"
+       ewarn "the ebuilds. Thank you."
+       ewarn ""
+
+       kernel-2_pkg_setup
+}
+
+universal_unpack() {
+       unpack linux-${KV_FULL}.tar.gz
+
+       # We want to rename the unpacked directory to a nice normalised string
+       # bug #762766
+       mv "${WORKDIR}"/linux-${MY_P} "${WORKDIR}"/linux-${KV_FULL} || die
+
+       # remove all backup files
+       find . -iname "*~" -exec rm {} \; 2>/dev/null
+}
+
+src_prepare() {
+       default
+       kernel-2_src_prepare
+}
+
+pkg_postinst() {
+       kernel-2_pkg_postinst
+}
+
+pkg_postrm() {
+       kernel-2_pkg_postrm
+}
diff --git a/www-client/vivaldi/Manifest b/www-client/vivaldi/Manifest
new file mode 100644 (file)
index 0000000..5bf65f3
--- /dev/null
@@ -0,0 +1,8 @@
+DIST vivaldi-stable_5.2.2623.48-1_amd64.deb 87799980 BLAKE2B bd6a128a4e2ed558436b516e8f9fb4ed31ff64ded5704084a21817d674cc8bf575f9f69c7be47cba72ed3e34cfb5b59de7321a1893e15865c190c2cc6c205fb1 SHA512 c69a6b4c46099969d6804a8cf6e692410cb4b04a28e1b28d23b300ce66bc603eac7e03b98eade1b7b227f9f4ae5f6111c37bd6576ccd35e32a738906dc38529e
+DIST vivaldi-stable_5.2.2623.48-1_arm64.deb 83044644 BLAKE2B b1b3162e328a458219b38daf8defbd63f099c1ee1c878a36374fc9a8f7402692995faa782a5a128d08bedc86b07705ca76f4fb67ea95a346e041ac80ef449eb1 SHA512 aa73afddb6b1562a7337d95ee00df3a031b75c14ead977034fa267b6c54b26b7a36449faa4cfb78ed7911d87fc019eb42c1d074c01dc67f148b1d4229323de33
+DIST vivaldi-stable_5.2.2623.48-1_armhf.deb 78932488 BLAKE2B ddd4350733714fec96c232b7cb99f9ae9a8ea295d4ad90810ee46a4f0e881478bdb8ccae09ef9701e757e20919151c48fea68bf194d39b0563fce99c0db92355 SHA512 b42f0dc66d78feacc22be5b4ed15fefd407a991001210d61deeb3dca51c622a4a54fbfb2ca036268a8b212f132f62c79e5179baf6fa1427ee75b1eadccf5c04c
+DIST vivaldi-stable_5.3.2679.68-1_amd64.deb 89858344 BLAKE2B 0eee5fcaf28750e1f81021c6fe38de3fea5a5c2d6096ae99ba5b78e4ba9b7f688f9a8b34d350d051033f72a3c1aecbd0dbf60ede6b8cfdd3e2819d1d790db909 SHA512 ea3f49215a213e9b35145f2514aae0913dc5f3f5392c0cf833a208b22c763152c7bbc106e55c0f52ad48088866d05dd7f973ed059f4a64149b2f42999b10e459
+DIST vivaldi-stable_5.3.2679.68-1_arm64.deb 81622244 BLAKE2B aa2c0c8af294d4083b8dec4894fe671480d88dabc20e2df5d0fb70395a4406596e75a46e32171836f3d9f44b5b5e59aa9c2a489982c1c6ccf41835e7496d199b SHA512 8a41530bff46f5e5b0d6335af39726a2f4e08f7fc00407a296c9c52a9c659c77527405baea2188dac1e31a40acb61bd28ad6325312a26bd298ce8cb5a747669c
+DIST vivaldi-stable_5.3.2679.68-1_armhf.deb 81301176 BLAKE2B d8df8482de3f3e4a2ebad71540b4feabbe9e5c28042a95892c86ec838980406c6635ac215a2c3614a16436db3c3238f84c500ab792a37370c762614335c2f3e8 SHA512 092655f1bc00e2d167cfb8dd3b5e54e262cd56124db57c5d0d0e5a57e775cf50097c9ac8923bf76e26d2c8d5513e0b48f8996a928a6a854540f81265c4964851
+EBUILD vivaldi-5.2.2623.48.ebuild 3660 BLAKE2B b1ad18fea4f5e8121caa04d2a31d519d1a3f517d11940ba040926eaa69113b89b686c38d2bdac91f423ee857e4586cc816a1ca728db2471f16178ea11a81d978 SHA512 5af4f410d790a00bb58a1fed497fed2eb273d30a3121a7eff08f68de15eafb8fe4548fb22db718bd6b05523acae808b55fa0e4ef3fd1fdc1272e58e824b2867b
+EBUILD vivaldi-5.3.2679.68.ebuild 3660 BLAKE2B b1ad18fea4f5e8121caa04d2a31d519d1a3f517d11940ba040926eaa69113b89b686c38d2bdac91f423ee857e4586cc816a1ca728db2471f16178ea11a81d978 SHA512 5af4f410d790a00bb58a1fed497fed2eb273d30a3121a7eff08f68de15eafb8fe4548fb22db718bd6b05523acae808b55fa0e4ef3fd1fdc1272e58e824b2867b
diff --git a/www-client/vivaldi/vivaldi-5.2.2623.48.ebuild b/www-client/vivaldi/vivaldi-5.2.2623.48.ebuild
new file mode 100644 (file)
index 0000000..cc81556
--- /dev/null
@@ -0,0 +1,206 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+CHROMIUM_VERSION="102"
+CHROMIUM_LANGS="
+       af
+       am
+       ar
+       az
+       be
+       bg
+       bn
+       ca
+       cs
+       da
+       de
+       de-CH
+       el
+       en-GB
+       en-US
+       eo
+       es
+       es-419
+       es-PE
+       et
+       eu
+       fa
+       fi
+       fil
+       fr
+       fy
+       gd
+       gl
+       gu
+       he
+       hi
+       hr
+       hu
+       hy
+       id
+       io
+       is
+       it
+       ja
+       jbo
+       ka
+       kab
+       kn
+       ko
+       ku
+       lt
+       lv
+       mk
+       ml
+       mr
+       ms
+       nb
+       nl
+       nn
+       pa
+       pl
+       pt-BR
+       pt-PT
+       ro
+       ru
+       sc
+       sk
+       sl
+       sq
+       sr
+       sr-Latn
+       sv
+       sw
+       ta
+       te
+       th
+       tr
+       uk
+       ur
+       vi
+       zh-CN
+       zh-TW
+"
+
+inherit chromium-2 desktop unpacker xdg
+
+VIVALDI_PN="${PN/%vivaldi/vivaldi-stable}"
+VIVALDI_HOME="opt/${PN}"
+DESCRIPTION="A browser for our friends"
+HOMEPAGE="https://vivaldi.com/"
+
+if [[ ${PV} = *_p* ]]; then
+       DEB_REV="${PV#*_p}"
+else
+       DEB_REV=1
+fi
+
+KEYWORDS="-* ~amd64 ~arm ~arm64"
+VIVALDI_BASE_URI="https://downloads.vivaldi.com/${VIVALDI_PN#vivaldi-}/${VIVALDI_PN}_${PV%_p*}-${DEB_REV}_"
+
+RE="\bamd64\b"; [[ ${KEYWORDS} =~ ${RE} ]] && SRC_URI+=" amd64? ( ${VIVALDI_BASE_URI}amd64.deb )"
+RE="\barm\b"; [[ ${KEYWORDS} =~ ${RE} ]] && SRC_URI+=" arm? ( ${VIVALDI_BASE_URI}armhf.deb )"
+RE="\barm64\b"; [[ ${KEYWORDS} =~ ${RE} ]] && SRC_URI+=" arm64? ( ${VIVALDI_BASE_URI}arm64.deb )"
+RE="\bx86\b"; [[ ${KEYWORDS} =~ ${RE} ]] && SRC_URI+=" x86? ( ${VIVALDI_BASE_URI}i386.deb )"
+
+LICENSE="Vivaldi"
+SLOT="0"
+IUSE="proprietary-codecs widevine"
+RESTRICT="bindist mirror"
+
+RDEPEND="
+       app-accessibility/at-spi2-atk:2
+       app-accessibility/at-spi2-core:2
+       dev-libs/atk
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/libX11
+       x11-libs/libxcb
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libxkbcommon
+       x11-libs/libXrandr
+       x11-libs/pango[X]
+       || ( gui-libs/gtk:4 x11-libs/gtk+:3 )
+       proprietary-codecs? ( media-video/ffmpeg-chromium:${CHROMIUM_VERSION} )
+       widevine? ( www-plugins/chrome-binary-plugins )
+"
+
+QA_PREBUILT="*"
+S="${WORKDIR}"
+
+src_unpack() {
+       unpack_deb ${A}
+}
+
+src_prepare() {
+       # Rename docs directory to our needs.
+       mv usr/share/doc/{${VIVALDI_PN},${PF}}/ || die
+
+       # Decompress the docs.
+       gunzip usr/share/doc/${PF}/changelog.gz || die
+
+       # The appdata directory is deprecated.
+       mv usr/share/{appdata,metainfo}/ || die
+
+       # Remove cron job for updating from Debian repos.
+       rm etc/cron.daily/${PN} ${VIVALDI_HOME}/cron/${PN} || die
+       rmdir etc/{cron.daily/,} ${VIVALDI_HOME}/cron/ || die
+
+       # Remove scripts that will most likely break things.
+       rm -vf ${VIVALDI_HOME}/update-{ffmpeg,widevine} || die
+
+       pushd ${VIVALDI_HOME}/locales > /dev/null || die
+       rm ja-KS.pak || die # No flag for Kansai as not in IETF list.
+       chromium_remove_language_paks
+       popd > /dev/null || die
+
+       if use proprietary-codecs; then
+               rm ${VIVALDI_HOME}/lib/libffmpeg.so || die
+               rmdir ${VIVALDI_HOME}/lib || die
+       fi
+
+       eapply_user
+}
+
+src_install() {
+       mv */ "${D}" || die
+       dosym ../../${VIVALDI_HOME}/${PN} /usr/bin/${VIVALDI_PN}
+       fperms 4711 /${VIVALDI_HOME}/vivaldi-sandbox
+
+       local logo size
+       for logo in "${ED}"/${VIVALDI_HOME}/product_logo_*.png; do
+               size=${logo##*_}
+               size=${size%.*}
+               newicon -s "${size}" "${logo}" ${PN}.png
+       done
+
+       if use proprietary-codecs; then
+               dosym ../../usr/$(get_libdir)/chromium/libffmpeg.so.${CHROMIUM_VERSION} \
+                         /${VIVALDI_HOME}/libffmpeg.so.$(ver_cut 1-2)
+       fi
+
+       if use widevine; then
+               dosym ../../usr/$(get_libdir)/chromium-browser/WidevineCdm \
+                         /${VIVALDI_HOME}/WidevineCdm
+       else
+               rm "${ED}"/${VIVALDI_HOME}/WidevineCdm || die
+       fi
+
+       case ${PN} in
+               vivaldi) dosym ${VIVALDI_PN} /usr/bin/${PN} ;;
+               vivaldi-snapshot) dosym ${PN} /${VIVALDI_HOME}/vivaldi ;;
+       esac
+}
diff --git a/www-client/vivaldi/vivaldi-5.3.2679.68.ebuild b/www-client/vivaldi/vivaldi-5.3.2679.68.ebuild
new file mode 100644 (file)
index 0000000..cc81556
--- /dev/null
@@ -0,0 +1,206 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+CHROMIUM_VERSION="102"
+CHROMIUM_LANGS="
+       af
+       am
+       ar
+       az
+       be
+       bg
+       bn
+       ca
+       cs
+       da
+       de
+       de-CH
+       el
+       en-GB
+       en-US
+       eo
+       es
+       es-419
+       es-PE
+       et
+       eu
+       fa
+       fi
+       fil
+       fr
+       fy
+       gd
+       gl
+       gu
+       he
+       hi
+       hr
+       hu
+       hy
+       id
+       io
+       is
+       it
+       ja
+       jbo
+       ka
+       kab
+       kn
+       ko
+       ku
+       lt
+       lv
+       mk
+       ml
+       mr
+       ms
+       nb
+       nl
+       nn
+       pa
+       pl
+       pt-BR
+       pt-PT
+       ro
+       ru
+       sc
+       sk
+       sl
+       sq
+       sr
+       sr-Latn
+       sv
+       sw
+       ta
+       te
+       th
+       tr
+       uk
+       ur
+       vi
+       zh-CN
+       zh-TW
+"
+
+inherit chromium-2 desktop unpacker xdg
+
+VIVALDI_PN="${PN/%vivaldi/vivaldi-stable}"
+VIVALDI_HOME="opt/${PN}"
+DESCRIPTION="A browser for our friends"
+HOMEPAGE="https://vivaldi.com/"
+
+if [[ ${PV} = *_p* ]]; then
+       DEB_REV="${PV#*_p}"
+else
+       DEB_REV=1
+fi
+
+KEYWORDS="-* ~amd64 ~arm ~arm64"
+VIVALDI_BASE_URI="https://downloads.vivaldi.com/${VIVALDI_PN#vivaldi-}/${VIVALDI_PN}_${PV%_p*}-${DEB_REV}_"
+
+RE="\bamd64\b"; [[ ${KEYWORDS} =~ ${RE} ]] && SRC_URI+=" amd64? ( ${VIVALDI_BASE_URI}amd64.deb )"
+RE="\barm\b"; [[ ${KEYWORDS} =~ ${RE} ]] && SRC_URI+=" arm? ( ${VIVALDI_BASE_URI}armhf.deb )"
+RE="\barm64\b"; [[ ${KEYWORDS} =~ ${RE} ]] && SRC_URI+=" arm64? ( ${VIVALDI_BASE_URI}arm64.deb )"
+RE="\bx86\b"; [[ ${KEYWORDS} =~ ${RE} ]] && SRC_URI+=" x86? ( ${VIVALDI_BASE_URI}i386.deb )"
+
+LICENSE="Vivaldi"
+SLOT="0"
+IUSE="proprietary-codecs widevine"
+RESTRICT="bindist mirror"
+
+RDEPEND="
+       app-accessibility/at-spi2-atk:2
+       app-accessibility/at-spi2-core:2
+       dev-libs/atk
+       dev-libs/expat
+       dev-libs/glib:2
+       dev-libs/nspr
+       dev-libs/nss
+       media-libs/alsa-lib
+       media-libs/mesa[gbm(+)]
+       net-print/cups
+       sys-apps/dbus
+       x11-libs/cairo
+       x11-libs/libdrm
+       x11-libs/libX11
+       x11-libs/libxcb
+       x11-libs/libXcomposite
+       x11-libs/libXdamage
+       x11-libs/libXext
+       x11-libs/libXfixes
+       x11-libs/libxkbcommon
+       x11-libs/libXrandr
+       x11-libs/pango[X]
+       || ( gui-libs/gtk:4 x11-libs/gtk+:3 )
+       proprietary-codecs? ( media-video/ffmpeg-chromium:${CHROMIUM_VERSION} )
+       widevine? ( www-plugins/chrome-binary-plugins )
+"
+
+QA_PREBUILT="*"
+S="${WORKDIR}"
+
+src_unpack() {
+       unpack_deb ${A}
+}
+
+src_prepare() {
+       # Rename docs directory to our needs.
+       mv usr/share/doc/{${VIVALDI_PN},${PF}}/ || die
+
+       # Decompress the docs.
+       gunzip usr/share/doc/${PF}/changelog.gz || die
+
+       # The appdata directory is deprecated.
+       mv usr/share/{appdata,metainfo}/ || die
+
+       # Remove cron job for updating from Debian repos.
+       rm etc/cron.daily/${PN} ${VIVALDI_HOME}/cron/${PN} || die
+       rmdir etc/{cron.daily/,} ${VIVALDI_HOME}/cron/ || die
+
+       # Remove scripts that will most likely break things.
+       rm -vf ${VIVALDI_HOME}/update-{ffmpeg,widevine} || die
+
+       pushd ${VIVALDI_HOME}/locales > /dev/null || die
+       rm ja-KS.pak || die # No flag for Kansai as not in IETF list.
+       chromium_remove_language_paks
+       popd > /dev/null || die
+
+       if use proprietary-codecs; then
+               rm ${VIVALDI_HOME}/lib/libffmpeg.so || die
+               rmdir ${VIVALDI_HOME}/lib || die
+       fi
+
+       eapply_user
+}
+
+src_install() {
+       mv */ "${D}" || die
+       dosym ../../${VIVALDI_HOME}/${PN} /usr/bin/${VIVALDI_PN}
+       fperms 4711 /${VIVALDI_HOME}/vivaldi-sandbox
+
+       local logo size
+       for logo in "${ED}"/${VIVALDI_HOME}/product_logo_*.png; do
+               size=${logo##*_}
+               size=${size%.*}
+               newicon -s "${size}" "${logo}" ${PN}.png
+       done
+
+       if use proprietary-codecs; then
+               dosym ../../usr/$(get_libdir)/chromium/libffmpeg.so.${CHROMIUM_VERSION} \
+                         /${VIVALDI_HOME}/libffmpeg.so.$(ver_cut 1-2)
+       fi
+
+       if use widevine; then
+               dosym ../../usr/$(get_libdir)/chromium-browser/WidevineCdm \
+                         /${VIVALDI_HOME}/WidevineCdm
+       else
+               rm "${ED}"/${VIVALDI_HOME}/WidevineCdm || die
+       fi
+
+       case ${PN} in
+               vivaldi) dosym ${VIVALDI_PN} /usr/bin/${PN} ;;
+               vivaldi-snapshot) dosym ${PN} /${VIVALDI_HOME}/vivaldi ;;
+       esac
+}
diff --git a/www-misc/zoneminder/Manifest b/www-misc/zoneminder/Manifest
new file mode 100644 (file)
index 0000000..01a503d
--- /dev/null
@@ -0,0 +1,13 @@
+AUX 10_zoneminder.conf 864 BLAKE2B 1e99239e99d8fb6df8e177e4994e436d8878a556a208e9f83d03be10ba4beed4140fbd51c2cf39bc8442198f6fee59eea25884874bf621b77e6aad58d4ab2e23 SHA512 c95c4d72c1ee085d88dbda5d7f4eb3851b0692f5ebff8a65978e672b5bf2ae7ce1a1b9ce15d8857c0529bc2bf955ed52aec5ccd3f86084538610c7276a084c4e
+AUX README.gentoo 1103 BLAKE2B 264bf5cfff7c61a7ccac32260bad7aabf5e33e165560297e344f264df09d2f56a2cf9c317b6ae2d708c8a8dbc1202127cb8e587055bb0f43e1ac9af2a7202d1c SHA512 e6e4f8d1dad5f6d0f00f8f9d77086aa39f08f673d8d17babc59eb98eadff0f94a83fcea25321d64c941061ae80f7e563eb82ef28cf05bcb8d0a2d1fe4705ac7e
+AUX conf.d 138 BLAKE2B 41ccdedf00277d98a011ac56015c0e46b641df13bf1ad9828a0d62fc2459c43237918a7b4b59d2594de2f3ef01ee8cc89cf63aa79f56bdb368d837d0a9203819 SHA512 66a3447869a5c7ed613a90a81ae3b0464836a8d1804b195770dd4832e61e89f826998f58dba1ce42d7d411c543d485290e670b0bf929646ad99f48a996bc609a
+AUX init.d 415 BLAKE2B 1d72ddbabe6e39b771e18ca5605fdfebc975dd8998561c4a7fd59a40491448489d42ff58fa507143a4feb8b16c7ca1a926ee8ee62bac2a7687a3e624cef54772 SHA512 97ab5d9ddf450241513be6a778bcb346e449b3dab4d6b3d55be41dfe7bb48233a08a598f4306e2f9b35336ab14021b2a2b0e68ddef83bb121f720e11cfcd0bb5
+AUX zoneminder.service 212 BLAKE2B 4a7497025b8d315c5a77a6e1f0d80000c3eb363ced1f2285c6b594b871283eba941e267a4590fba5ea89fb3e1529dcec93a63d67025b569ba0411f9e42103680 SHA512 3824076594e18ee89ca28e622f87bf9bd51156d0ef9d71fe8d20d69b682ecf8c96fb779cbaf33f1709aec0ec9fd1b5448b8524c781510718549282e68c095a90
+DIST Crud-3.1.0.tar.gz 72993 BLAKE2B d11938a0a667f6747bbe3609e51ccc5665b8d243e1787a5779319c679f1f20301afd6b0a14c5489976b9f66f57b5f18ef3ae0ee5a24e1368702cb43a5d564dd5 SHA512 7ec84afaa336b1bd582b7f39724f77081bdb3008947c4124ad96e4bc7755a03fbe31e01666d4d1939ebe17b342db37bf3766a42d88fbed0e99706807ff5b9d01
+DIST ZM_RtspServer-1.36.20.tar.bz2 3810921 BLAKE2B 2d7301ddfe12fa3e9f3c69b0e9c947e019458041468e2dc7a15237e3a8ff1aa03fd8e4f9044491b941d9980cbe8ea4913f849385f70165e4b7bafc356538ee86 SHA512 f9828c8689b12dbb6ad881e4c5f2199a8f71b9ce40fba6239a3335d004285a3bce14a49460bf1ad5ed74cdd12682a6b471f249ae2297908587fcb5057be81f53
+DIST ZM_SubModules-1.36.21.tar.bz2 1484310 BLAKE2B 6ce984ef3b797f1567f82c56904c76755ecaff61d87f67d47c4b5e2610d8d87f96cfa9ec4319eea7d4fdda0240dc9d44cf658fcb383cd3d86e255f2def64981d SHA512 15a561348c55f9643889ebdd8258733ed40fdba09347bbe2da20fb2703e4d661765c72ea197b1d29896758f48cfa8b997b5afc2134715fcb6a5b27b824f4a54a
+DIST zoneminder-1.36.20.tar.gz 11351218 BLAKE2B b89f7908cd3f31db39a37b8cfc585368d5b5243250847635e888351e5ec48eab0bf1219078edb88ff040d3d478d5553d9c7dfa3705226af8d569d31df2a6007a SHA512 b869d6cdba362cd372898167143a8617a22639bd2c13dae21b605bbd528496269e4d67e10366ebadf5c010d858fe2fbbe7663d113134a4a826f894d720ce02a0
+DIST zoneminder-1.36.21.tar.gz 11352458 BLAKE2B 864f616abc6ce89a751b62eece927da423499e3a0c38693f5c12f2b4ed64c805c17b461254f8539f96a1177c159121b1d33e3fc7b374fb971bd0b86c09dd94a5 SHA512 294a3bea783cbdbe368751f2fa680b6edcc6d1cadf47450f4e0b64b568b565c615e28fec269f553a4942c5c8758cdccc8f95a092912ad3bbd36de2e056773d3a
+EBUILD zoneminder-1.36.20.ebuild 4398 BLAKE2B 3c9ed290740d5dce5686ad2a7eb26d8b6efe2583feabba1ada2929bc25de6a0af09737ec6f1b10d8d878accd00835acbdf18bcda083af4218a0af81fddb85aff SHA512 3f825dd6d8d5a6b712e36c2da4f4ebbf6bc5bff70bfb969c8006f97d8e2df9e63df71799152f6506299131509018ee9ccb9985c6a9cb860b5a9620baab750eca
+EBUILD zoneminder-1.36.21.ebuild 4126 BLAKE2B ad90fcf72b1a1d88d3a76fb5fb959239dfa7202b51b2279d4008e1fccf8380e5bcaa6061e1c54df3ed4a86efca136f4ef32c3dae56e1ee5efae967feb7718731 SHA512 07b1f2ead0531225d3668db8fe4ef40f7aadbdc88292d3122ddb85399c461cb732165e3db6d97097a2d2e4938fd76561e4ad2fb907a15ca66a721b3b90eb7f9b
+MISC metadata.xml 435 BLAKE2B fbf306b96ac38b8f234f360500284d7036f5866c7f95d684488b9b94019998f02ed4f86bfe08f477bfd2f4cde75309b729570522fd52fa57fcf6da3c7e3e32bf SHA512 7aef30cab92e0b1607f5643fa91d96e0e14b38e4d234c2cfed6f44e9ea77473b0ecce492b5104bf98f81ad98cce63eb28c16234a307b885409ce8c82b303e7c7
diff --git a/www-misc/zoneminder/files/10_zoneminder.conf b/www-misc/zoneminder/files/10_zoneminder.conf
new file mode 100644 (file)
index 0000000..bc09eda
--- /dev/null
@@ -0,0 +1,37 @@
+ScriptAlias /zm/cgi-bin "/usr/libexec/zoneminder/cgi-bin/"
+
+<Directory "/usr/libexec/zoneminder/cgi-bin">
+  AllowOverride All
+  Options +ExecCGI
+  Require all granted
+</Directory>
+
+Alias /zm "%ZM_WEBDIR%"
+
+<Directory "%ZM_WEBDIR%">
+  Options -Indexes +MultiViews +FollowSymLinks
+  AllowOverride All
+  Require all granted
+</Directory>
+
+<Directory "%ZM_WEBDIR%/api">
+  RewriteEngine on
+   RewriteRule ^$ app/webroot/ [L]
+   RewriteRule (.*) app/webroot/$1 [L]
+   RewriteBase /zm/api
+</Directory>
+
+<Directory "%ZM_WEBDIR%/api/app">
+   RewriteEngine on
+   RewriteRule ^$ webroot/ [L]
+   RewriteRule (.*) webroot/$1 [L]
+   RewriteBase /zm/api
+</Directory>
+
+<Directory "%ZM_WEBDIR%/api/app/webroot">
+    RewriteEngine On
+    RewriteCond %{REQUEST_FILENAME} !-d
+    RewriteCond %{REQUEST_FILENAME} !-f
+    RewriteRule ^ index.php [L]
+    RewriteBase /zm/api
+</Directory>
diff --git a/www-misc/zoneminder/files/README.gentoo b/www-misc/zoneminder/files/README.gentoo
new file mode 100644 (file)
index 0000000..8713fda
--- /dev/null
@@ -0,0 +1,27 @@
+1. If this is a new installation, you will need to create a MySQL
+   database for zoneminder to use
+   (see https://wiki.gentoo.org/wiki/MySQL/Startup_Guide).
+   E.g., when logged into mysql as root,
+     mysql> CREATE DATABASE \`zm\`;
+     mysql> grant select,insert,alter,update,lock tables,delete on zm.* to 'zmuser'@localhost identified by 'zmpass';
+     mysql> flush privileges;
+   Once you completed that you should execute the following:
+     mysql -p < /usr/share/zoneminder/db/zm_create.sql
+
+2. Set your database settings in /etc/zm.conf, including above zmpass
+
+3. Configure apache to use zoneminder, see /usr/share/doc/zoneminder*/10_zoneminder.conf
+   for an example configuration snippet.
+
+4. Enable PHP in your webserver configuration,
+   enable short_open_tags in php.ini (likely on by default now)
+   set the time zone in php.ini,
+   and restart/reload the webserver.
+
+5. Start the zoneminder daemon:
+     /etc/init.d/zoneminder start
+
+6. Finally point your browser to http://your.webserver/zm
+
+If you are upgrading, you will need to run the zmupdate.pl script: 
+   /usr/bin/zmupdate.pl
diff --git a/www-misc/zoneminder/files/conf.d b/www-misc/zoneminder/files/conf.d
new file mode 100644 (file)
index 0000000..d2e0336
--- /dev/null
@@ -0,0 +1,6 @@
+ZM_SCRIPT=/usr/bin/zmpkg.pl
+
+# Commands for starting and stopping the server
+
+CMD_START="${ZM_SCRIPT} start"
+CMD_STOP="${ZM_SCRIPT} stop"
diff --git a/www-misc/zoneminder/files/init.d b/www-misc/zoneminder/files/init.d
new file mode 100644 (file)
index 0000000..6ee8a16
--- /dev/null
@@ -0,0 +1,25 @@
+#!/sbin/openrc-run
+# Copyright 1999-2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+depend() {
+       need mysql
+       need apache2
+}
+
+start_pre() {
+       checkpath -d -m 0775 -o apache:apache /var/run/zm
+       checkpath -d -m 0775 -o apache:apache /var/tmp/zm
+}
+
+start() {
+       ebegin "Starting zoneminder"
+       ${CMD_START}
+       eend $?
+}
+
+stop() {
+       ebegin "Stopping zoneminder"
+       ${CMD_STOP}
+       eend $?
+}
diff --git a/www-misc/zoneminder/files/zoneminder.service b/www-misc/zoneminder/files/zoneminder.service
new file mode 100644 (file)
index 0000000..9ef5bc6
--- /dev/null
@@ -0,0 +1,11 @@
+[Unit]
+Description=Video Security and Survellance System
+
+[Service]
+Type=forking
+ExecStart=/usr/bin/zmpkg.pl start
+ExecReload=/usr/bin/zmpkg.pl reload
+PIDFile=/run/zm/zm.pid
+
+[Install]
+WantedBy=multi-user.target
diff --git a/www-misc/zoneminder/metadata.xml b/www-misc/zoneminder/metadata.xml
new file mode 100644 (file)
index 0000000..5d75d2f
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+       <use>
+               <flag name="curl">Enable using net-misc/curl for streaming from cameras</flag>
+               <flag name="gcrypt">...</flag>
+               <flag name="vlc">Enable using media-libs/vlc for streaming from cameras</flag>
+       </use>
+       <upstream>
+               <remote-id type="github">ZoneMinder/ZoneMinder</remote-id>
+       </upstream>
+</pkgmetadata>
diff --git a/www-misc/zoneminder/zoneminder-1.36.20.ebuild b/www-misc/zoneminder/zoneminder-1.36.20.ebuild
new file mode 100644 (file)
index 0000000..d00861c
--- /dev/null
@@ -0,0 +1,176 @@
+# Copyright 2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit cmake perl-functions readme.gentoo-r1 depend.apache flag-o-matic systemd
+
+MY_PN="ZoneMinder"
+
+MY_CRUD_VERSION="3.1.0"
+
+DESCRIPTION="Capture, analyse, record and monitor any cameras attached to your system"
+HOMEPAGE="http://www.zoneminder.com/"
+SRC_URI="
+       https://liquid.me.uk/ZM_RtspServer-${PV}.tar.bz2
+       https://github.com/${MY_PN}/${MY_PN}/archive/${PV}.tar.gz -> ${P}.tar.gz
+       https://github.com/FriendsOfCake/crud/archive/v${MY_CRUD_VERSION}.tar.gz -> Crud-${MY_CRUD_VERSION}.tar.gz
+"
+
+LICENSE="GPL-2"
+KEYWORDS="~amd64"
+IUSE="curl encode ffmpeg gcrypt gnutls +mmap +ssl libressl vlc"
+SLOT="0"
+
+REQUIRED_USE="
+       || ( ssl gnutls )
+"
+
+DEPEND="
+app-eselect/eselect-php[apache2]
+dev-lang/perl:=
+dev-lang/php:*[apache2,cgi,curl,gd,inifile,pdo,mysql,mysqli,sockets]
+dev-libs/libpcre
+dev-perl/Archive-Zip
+dev-perl/Class-Std-Fast
+dev-perl/Crypt-Eksblowfish
+dev-perl/Data-Entropy
+dev-perl/Data-Float
+dev-perl/Data-Dump
+dev-perl/Date-Manip
+dev-perl/Data-UUID
+dev-perl/DBD-mysql
+dev-perl/DBI
+dev-perl/IO-Socket-Multicast
+dev-perl/SOAP-WSDL
+dev-perl/Sys-CPU
+dev-perl/Sys-MemInfo
+dev-perl/URI-Encode
+dev-perl/libwww-perl
+dev-perl/Number-Bytes-Human
+dev-perl/JSON-MaybeXS
+dev-php/pecl-apcu:*
+media-libs/libv4l
+sys-auth/polkit
+sys-libs/zlib
+ffmpeg? ( media-video/ffmpeg )
+encode? ( media-libs/libmp4v2 )
+virtual/httpd-php:*
+virtual/jpeg:0
+virtual/mysql
+virtual/perl-ExtUtils-MakeMaker
+virtual/perl-Getopt-Long
+virtual/perl-Sys-Syslog
+virtual/perl-Time-HiRes
+www-servers/apache
+curl? ( net-misc/curl )
+gcrypt? ( dev-libs/libgcrypt:0= )
+gnutls? ( net-libs/gnutls )
+mmap? ( dev-perl/Sys-Mmap )
+ssl? (
+       !libressl? ( dev-libs/openssl:0= )
+       libressl? ( dev-libs/libressl:0= )
+)
+vlc? ( media-video/vlc[live] )
+"
+RDEPEND="${DEPEND}"
+
+need_apache
+
+PATCHES=(
+)
+
+MY_ZM_WEBDIR=/usr/share/zoneminder/www
+
+src_prepare() {
+       cmake_src_prepare
+       rmdir "${S}/web/api/app/Plugin/Crud" || die
+       mv "${WORKDIR}/crud-${MY_CRUD_VERSION}" "${S}/web/api/app/Plugin/Crud" || die
+       rm "${WORKDIR}/${P}/conf.d/README" || die
+       eapply_user
+}
+
+src_configure() {
+       append-cxxflags -D__STDC_CONSTANT_MACROS
+       perl_set_version
+       export TZ=UTC # bug 630470
+       MYCMAKEARGS=(
+               -DZM_PERL_SUBPREFIX=${VENDOR_LIB#/usr}
+               -DZM_TMPDIR=/var/tmp/zm
+               -DZM_SOCKDIR=/var/run/zm
+               -DZM_WEB_USER=apache
+               -DZM_WEB_GROUP=apache
+               -DZM_WEBDIR=${MY_ZM_WEBDIR}
+               -DZM_NO_MMAP="$(usex mmap OFF ON)"
+               -DZM_NO_X10=OFF
+               -DZM_NO_FFMPEG="$(usex ffmpeg OFF ON)"
+               -DZM_NO_CURL="$(usex curl OFF ON)"
+               -DZM_NO_LIBVLC="$(usex vlc OFF ON)"
+               -DCMAKE_DISABLE_FIND_PACKAGE_OpenSSL="$(usex ssl OFF ON)"
+               -DHAVE_GNUTLS="$(usex gnutls ON OFF)"
+               -DHAVE_GCRYPT="$(usex gcrypt ON OFF)"
+       )
+
+       cmake_src_configure
+
+}
+
+src_install() {
+       cmake_src_install
+
+       # the log directory
+       keepdir /var/log/zm
+       fowners apache:apache /var/log/zm
+
+       # the logrotate script
+       insinto /etc/logrotate.d
+       newins distros/ubuntu1604/zoneminder.logrotate zoneminder
+
+       # now we duplicate the work of zmlinkcontent.sh
+       keepdir /var/lib/zoneminder /var/lib/zoneminder/images /var/lib/zoneminder/events /var/lib/zoneminder/api_tmp
+       fperms -R 0775 /var/lib/zoneminder
+       fowners -R apache:apache /var/lib/zoneminder
+       dosym /var/lib/zoneminder/images ${MY_ZM_WEBDIR}/images
+       dosym /var/lib/zoneminder/events ${MY_ZM_WEBDIR}/events
+       dosym /var/cache/zoneminder ${MY_ZM_WEBDIR}/cache
+       dosym /var/lib/zoneminder/api_tmp ${MY_ZM_WEBDIR}/api/app/tmp
+
+       # the cache directory
+       keepdir /var/cache/zoneminder
+       fowners apache:apache /var/cache/zoneminder
+
+       # bug 523058
+       keepdir ${MY_ZM_WEBDIR}/temp
+       fowners -R apache:apache ${MY_ZM_WEBDIR}/temp
+
+       # the configuration file
+       fperms 0640 /etc/zm.conf
+       fowners root:apache /etc/zm.conf
+
+       # init scripts etc
+       newinitd "${FILESDIR}"/init.d zoneminder
+       newconfd "${FILESDIR}"/conf.d zoneminder
+
+       # systemd unit file
+       systemd_dounit "${FILESDIR}"/zoneminder.service
+
+       cp "${FILESDIR}"/10_zoneminder.conf "${T}"/10_zoneminder.conf || die
+       sed -i "${T}"/10_zoneminder.conf -e "s:%ZM_WEBDIR%:${MY_ZM_WEBDIR}:g" || die
+
+       dodoc README.md "${T}"/10_zoneminder.conf
+
+       perl_delete_packlist
+
+       readme.gentoo_create_doc
+}
+
+pkg_postinst() {
+       readme.gentoo_print_elog
+
+       local v
+       for v in ${REPLACING_VERSIONS}; do
+               if ! version_is_at_least ${PV} ${v}; then
+                       elog "You have upgraded zoneminder and may have to upgrade your database now using the 'zmupdate.pl' script."
+               fi
+       done
+}
diff --git a/www-misc/zoneminder/zoneminder-1.36.21.ebuild b/www-misc/zoneminder/zoneminder-1.36.21.ebuild
new file mode 100644 (file)
index 0000000..91bd4b3
--- /dev/null
@@ -0,0 +1,171 @@
+# Copyright 2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit cmake perl-functions readme.gentoo-r1 depend.apache flag-o-matic systemd
+
+MY_PN="ZoneMinder"
+
+
+DESCRIPTION="Capture, analyse, record and monitor any cameras attached to your system"
+HOMEPAGE="http://www.zoneminder.com/"
+SRC_URI="
+       https://liquid.me.uk/ZM_SubModules-${PV}.tar.bz2
+       https://github.com/${MY_PN}/${MY_PN}/archive/${PV}.tar.gz -> ${P}.tar.gz
+"
+
+LICENSE="GPL-2"
+KEYWORDS="~amd64"
+IUSE="curl encode ffmpeg gcrypt gnutls +mmap +ssl libressl vlc"
+SLOT="0"
+
+REQUIRED_USE="
+       || ( ssl gnutls )
+"
+
+DEPEND="
+app-eselect/eselect-php[apache2]
+dev-lang/perl:=
+dev-lang/php:*[apache2,cgi,curl,gd,inifile,pdo,mysql,mysqli,sockets]
+dev-libs/libpcre
+dev-perl/Archive-Zip
+dev-perl/Class-Std-Fast
+dev-perl/Crypt-Eksblowfish
+dev-perl/Data-Entropy
+dev-perl/Data-Float
+dev-perl/Data-Dump
+dev-perl/Date-Manip
+dev-perl/Data-UUID
+dev-perl/DBD-mysql
+dev-perl/DBI
+dev-perl/IO-Socket-Multicast
+dev-perl/SOAP-WSDL
+dev-perl/Sys-CPU
+dev-perl/Sys-MemInfo
+dev-perl/URI-Encode
+dev-perl/libwww-perl
+dev-perl/Number-Bytes-Human
+dev-perl/JSON-MaybeXS
+dev-php/pecl-apcu:*
+media-libs/libv4l
+sys-libs/zlib
+ffmpeg? ( media-video/ffmpeg )
+encode? ( media-libs/libmp4v2 )
+virtual/httpd-php:*
+virtual/jpeg:0
+virtual/mysql
+virtual/perl-ExtUtils-MakeMaker
+virtual/perl-Getopt-Long
+virtual/perl-Sys-Syslog
+virtual/perl-Time-HiRes
+www-servers/apache
+curl? ( net-misc/curl )
+gcrypt? ( dev-libs/libgcrypt:0= )
+gnutls? ( net-libs/gnutls )
+mmap? ( dev-perl/Sys-Mmap )
+ssl? (
+       !libressl? ( dev-libs/openssl:0= )
+       libressl? ( dev-libs/libressl:0= )
+)
+vlc? ( media-video/vlc[live] )
+"
+RDEPEND="${DEPEND}"
+
+need_apache
+
+PATCHES=(
+)
+
+MY_ZM_WEBDIR=/usr/share/zoneminder/www
+
+src_prepare() {
+       cmake_src_prepare
+       rm "${WORKDIR}/${P}/conf.d/README" || die
+       eapply_user
+}
+
+src_configure() {
+       append-cxxflags -D__STDC_CONSTANT_MACROS
+       perl_set_version
+       export TZ=UTC # bug 630470
+       MYCMAKEARGS=(
+               -DZM_PERL_SUBPREFIX=${VENDOR_LIB#/usr}
+               -DZM_TMPDIR=/var/tmp/zm
+               -DZM_SOCKDIR=/var/run/zm
+               -DZM_WEB_USER=apache
+               -DZM_WEB_GROUP=apache
+               -DZM_WEBDIR=${MY_ZM_WEBDIR}
+               -DZM_NO_MMAP="$(usex mmap OFF ON)"
+               -DZM_NO_X10=OFF
+               -DZM_NO_FFMPEG="$(usex ffmpeg OFF ON)"
+               -DZM_NO_CURL="$(usex curl OFF ON)"
+               -DZM_NO_LIBVLC="$(usex vlc OFF ON)"
+               -DCMAKE_DISABLE_FIND_PACKAGE_OpenSSL="$(usex ssl OFF ON)"
+               -DHAVE_GNUTLS="$(usex gnutls ON OFF)"
+               -DHAVE_GCRYPT="$(usex gcrypt ON OFF)"
+       )
+
+       cmake_src_configure
+
+}
+
+src_install() {
+       cmake_src_install
+
+       # the log directory
+       keepdir /var/log/zm
+       fowners apache:apache /var/log/zm
+
+       # the logrotate script
+       insinto /etc/logrotate.d
+       newins distros/ubuntu1604/zoneminder.logrotate zoneminder
+
+       # now we duplicate the work of zmlinkcontent.sh
+       keepdir /var/lib/zoneminder /var/lib/zoneminder/images /var/lib/zoneminder/events /var/lib/zoneminder/api_tmp
+       fperms -R 0775 /var/lib/zoneminder
+       fowners -R apache:apache /var/lib/zoneminder
+       dosym /var/lib/zoneminder/images ${MY_ZM_WEBDIR}/images
+       dosym /var/lib/zoneminder/events ${MY_ZM_WEBDIR}/events
+       dosym /var/cache/zoneminder ${MY_ZM_WEBDIR}/cache
+       dosym /var/lib/zoneminder/api_tmp ${MY_ZM_WEBDIR}/api/app/tmp
+
+       # the cache directory
+       keepdir /var/cache/zoneminder
+       fowners apache:apache /var/cache/zoneminder
+
+       # bug 523058
+       keepdir ${MY_ZM_WEBDIR}/temp
+       fowners -R apache:apache ${MY_ZM_WEBDIR}/temp
+
+       # the configuration file
+       fperms 0640 /etc/zm.conf
+       fowners root:apache /etc/zm.conf
+
+       # init scripts etc
+       newinitd "${FILESDIR}"/init.d zoneminder
+       newconfd "${FILESDIR}"/conf.d zoneminder
+
+       # systemd unit file
+       systemd_dounit "${FILESDIR}"/zoneminder.service
+
+       cp "${FILESDIR}"/10_zoneminder.conf "${T}"/10_zoneminder.conf || die
+       sed -i "${T}"/10_zoneminder.conf -e "s:%ZM_WEBDIR%:${MY_ZM_WEBDIR}:g" || die
+
+       dodoc README.md "${T}"/10_zoneminder.conf
+
+       perl_delete_packlist
+
+       readme.gentoo_create_doc
+}
+
+pkg_postinst() {
+       readme.gentoo_print_elog
+
+       local v
+       for v in ${REPLACING_VERSIONS}; do
+               if ! version_is_at_least ${PV} ${v}; then
+                       elog "You have upgraded zoneminder and may have to upgrade your database now using the 'zmupdate.pl' script."
+               fi
+       done
+}
diff --git a/x11-misc/appmenu-gtk-module/Manifest b/x11-misc/appmenu-gtk-module/Manifest
new file mode 100644 (file)
index 0000000..f404bc9
--- /dev/null
@@ -0,0 +1,6 @@
+AUX appmenu-gtk-module 239 BLAKE2B c5f055154136c6ba862ce9f74edf898fd9baa5b699fe149fd29b125bd42cee94174e7f8f8bf7a40ee63e880f38a161a652e45c171dae399e8cd2b76e4a94e2f5 SHA512 daf70376ebcd1b67eec093c8b905b6d085d4206958573ce7aa8709c053928a78a7b8d06b6fdba9a221731d89e3fe6720394d1e8cee208adfaaf298825a9cc04e
+AUX appmenu-gtk-module-0.7.6-fix-pkgconfig.patch 309 BLAKE2B 960371a9722ebd715fa16a72cab960225f99d5a68d6b1e4ae6cf8113530769497b218708c990221aa558544778315c43968819ea968ba1f29d07a97257eef07e SHA512 8a08bccf369b87f261a4edfbeb1f942c3ea9c6efda19ca0a6490f91405b920516f0d8d8fd28172b2abf4d1d9ee2e16fab4c490653545239c82f8ee1e1cb7fee9
+AUX appmenu-gtk-module-0.7.6-no-automagic-gtk.patch 951 BLAKE2B 5dd2dbfe6464bf323b4b66d9a1f87ffc8b417991991529631d03ebb9253b999718e90a28c85b6e3573c4a7e0597f05cfdfbda6c6900197266253dad86452adb5 SHA512 5d2a8bf395d8151f06f9b42d0197d3c7b606161343ae166430fefa73f5170b7a61b15d34ff7bf7d8aa6602609cb612c98eba11067aac29ce06830f9e05970e94
+AUX appmenu-gtk-module-0.7.6-no-automagic-unitdir.patch 2164 BLAKE2B f89af2da72c5f41eec2eeba1d2ea7a59e4f0b7e2aaf17c3dca07b8cd24e9a56ef8ba156abdd888a8051fc72e7369f9104389db4243132b510de0e6aaf412ef90 SHA512 63beeef3e2677a013aa46486baae8692bdc34c31ccd24f8eb2c5a18610025da5e77b50bdbbee6d8a6a34f3ee8e8595fbcc0df9ced417cd2a281b08f3947eb038
+DIST appmenu-gtk-module-0.7.3.tar.xz 48460 BLAKE2B b7008aa618e643a95445aad25bc19eed5b887810891318a891f088284f8f128e6392671226742a8b0c70699a9455739ee61ed56aec32129532ba53dc69809913 SHA512 d7df7e3cea3ccb66d013b23ae8796b8cbb0e0787f37f54078715c4863797c28d44ff38d7ac965b6eb0fd5cb327c1a4b891c74c66ba95b9b9a06e2c06ba5b2ad8
+EBUILD appmenu-gtk-module-0.7.3-r2.ebuild 1100 BLAKE2B 889cfdecca88bf8149d965c8cf4bdb854a70c8dfad70509782bae2e39ad719388b146d516fcf7450a320a8d8a35acd96e002c6d072e23765d3301c8f1450eb0e SHA512 3e8b3b4dedf822194ebf93e736e88c1340003ffd2c85f700233876d2149e9cf975b45f0890d901a9ca0428cfcfeffdacb237f8680c68dcae063f370c186b78f4
diff --git a/x11-misc/appmenu-gtk-module/appmenu-gtk-module-0.7.3-r2.ebuild b/x11-misc/appmenu-gtk-module/appmenu-gtk-module-0.7.3-r2.ebuild
new file mode 100644 (file)
index 0000000..ba6f7be
--- /dev/null
@@ -0,0 +1,50 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit cmake gnome2-utils systemd
+
+DESCRIPTION="Application menu module for GTK"
+HOMEPAGE="https://gitlab.com/vala-panel-project/vala-panel-appmenu"
+SRC_URI="https://gitlab.com/vala-panel-project/vala-panel-appmenu/uploads/570a2d1a65e77d42cb19e5972d0d1b84/${P}.tar.xz"
+
+LICENSE="GPL-2 LGPL-2"
+SLOT="0"
+KEYWORDS="amd64 ~arm arm64 ~loong ~ppc64 ~riscv x86"
+IUSE="wayland"
+
+RDEPEND="
+       dev-libs/glib[dbus]
+       >=x11-libs/gtk+-2.24.0:2
+       wayland? ( >=x11-libs/gtk+-3.22.0:3[wayland=] )
+"
+DEPEND="${RDEPEND}
+       wayland? ( dev-libs/wayland )
+"
+
+src_prepare() {
+       cmake_src_prepare
+       sed -i -e "/^pkg_check_modules(SYSTEMD/d" data/CMakeLists.txt || die
+}
+
+src_configure() {
+       local mycmakeargs=(
+               -DGSETTINGS_COMPILE=OFF
+               -DCMAKE_DISABLE_FIND_PACKAGE_VCM=ON
+       )
+       cmake_src_configure
+}
+
+src_install() {
+       cmake_src_install
+
+       exeinto /etc/X11/xinit/xinitrc.d
+       newexe "${FILESDIR}"/${PN} 85-${PN}
+
+       systemd_dounit "${BUILD_DIR}"/data/appmenu-gtk-module.service
+}
+
+pkg_postinst() {
+       gnome2_schemas_update
+}
diff --git a/x11-misc/appmenu-gtk-module/files/appmenu-gtk-module b/x11-misc/appmenu-gtk-module/files/appmenu-gtk-module
new file mode 100644 (file)
index 0000000..e6520aa
--- /dev/null
@@ -0,0 +1,12 @@
+if [[ -n "$GTK_MODULES" ]]; then
+    GTK_MODULES="${GTK_MODULES}:appmenu-gtk-module"
+else
+    GTK_MODULES="appmenu-gtk-module"
+fi
+
+if [[ -z "$UBUNTU_MENUPROXY" ]]; then
+    UBUNTU_MENUPROXY=1
+fi
+
+export GTK_MODULES
+export UBUNTU_MENUPROXY
diff --git a/x11-misc/appmenu-gtk-module/files/appmenu-gtk-module-0.7.6-fix-pkgconfig.patch b/x11-misc/appmenu-gtk-module/files/appmenu-gtk-module-0.7.6-fix-pkgconfig.patch
new file mode 100644 (file)
index 0000000..f8b5439
--- /dev/null
@@ -0,0 +1,10 @@
+--- a/meson.build      2020-10-28 22:05:23.000000000 +0100
++++ b/meson.build      2022-07-17 09:53:55.047880112 +0200
+@@ -1,6 +1,6 @@
+ project('appmenu-gtk-module', 'c',
+       meson_version: '>=0.49.0',
+-      version: '0.7',
++      version: '0.7.6',
+       license: ['LGPL-3.0-or-later'],
+     default_options: [
+         'c_std=gnu11',
diff --git a/x11-misc/appmenu-gtk-module/files/appmenu-gtk-module-0.7.6-no-automagic-gtk.patch b/x11-misc/appmenu-gtk-module/files/appmenu-gtk-module-0.7.6-no-automagic-gtk.patch
new file mode 100644 (file)
index 0000000..716aefa
--- /dev/null
@@ -0,0 +1,28 @@
+From 59994f8b0a431f61786de5715c45c24b0dd76cd1 Mon Sep 17 00:00:00 2001
+From: Georgy Yakovlev <gyakovlev@gentoo.org>
+Date: Tue, 4 Jan 2022 18:33:12 -0800
+Subject: [PATCH] appmenu-gtk-module/meson.build: only build gtk if requested
+
+Signed-off-by: Georgy Yakovlev <gyakovlev@gentoo.org>
+---
+ subprojects/appmenu-gtk-module/meson.build | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/subprojects/appmenu-gtk-module/meson.build b/subprojects/appmenu-gtk-module/meson.build
+index 06ab76d..7279f97 100644
+--- a/meson.build
++++ b/meson.build
+@@ -41,8 +41,8 @@ gtk3_ver = '>=3.22.0'
+ gtk2 = dependency('gtk+-2.0', version: gtk2_ver, required: gtk2_requested)
+ gtk3 = dependency('gtk+-3.0', version: gtk3_ver, required: gtk3_requested)
+-build_gtk2 = gtk2.found()
+-build_gtk3 = gtk3.found()
++build_gtk2 = gtk2_requested and gtk2.found()
++build_gtk3 = gtk3_requested and gtk3.found()
+ #################
+ # Configuration #
+-- 
+2.34.1
+
diff --git a/x11-misc/appmenu-gtk-module/files/appmenu-gtk-module-0.7.6-no-automagic-unitdir.patch b/x11-misc/appmenu-gtk-module/files/appmenu-gtk-module-0.7.6-no-automagic-unitdir.patch
new file mode 100644 (file)
index 0000000..e46fe74
--- /dev/null
@@ -0,0 +1,56 @@
+From c60d530583a8bd07aea22c4f3f3aa8b0aaf271c1 Mon Sep 17 00:00:00 2001
+From: Georgy Yakovlev <gyakovlev@gentoo.org>
+Date: Tue, 4 Jan 2022 19:06:37 -0800
+Subject: [PATCH] appmenu-gtk-module: add userunitdir option
+
+allows setting systemd unit on systemd-less systems
+
+Signed-off-by: Georgy Yakovlev <gyakovlev@gentoo.org>
+---
+ .../appmenu-gtk-module/data/meson.build       | 19 ++++++++++++-------
+ .../appmenu-gtk-module/meson_options.txt      |  1 +
+ 2 files changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/subprojects/appmenu-gtk-module/data/meson.build b/subprojects/appmenu-gtk-module/data/meson.build
+index 8378965..d0d1717 100644
+--- a/data/meson.build
++++ b/data/meson.build
+@@ -2,14 +2,19 @@ install_data([
+     'org.appmenu.gtk-module.gschema.xml'
+ ], install_dir: schema_dir)
++userunitdir = get_option('userunitdir')
+ systemd = dependency('systemd', required: false)
+-if systemd.found()
++if userunitdir == ''
++  if systemd.found()
+     userunitdir = systemd.get_pkgconfig_variable('systemduserunitdir')
+-    configure_file(
+-        input: 'appmenu-gtk-module.service.in',
+-        output: 'appmenu-gtk-module.service',
+-        install_dir: userunitdir,
+-        configuration: {'CMAKE_INSTALL_FULL_BINDIR': join_paths(prefix,get_option('bindir'))}
+-    )
++  else
++    userunitdir = '/usr/lib/systemd/user'
++  endif
+ endif
++configure_file(
++  input: 'appmenu-gtk-module.service.in',
++  output: 'appmenu-gtk-module.service',
++  install_dir: userunitdir,
++  configuration: {'CMAKE_INSTALL_FULL_BINDIR': join_paths(prefix,get_option('bindir'))}
++)
+diff --git a/subprojects/appmenu-gtk-module/meson_options.txt b/subprojects/appmenu-gtk-module/meson_options.txt
+index f93877a..ec0b3a6 100644
+--- a/meson_options.txt
++++ b/meson_options.txt
+@@ -1,3 +1,4 @@
+ option('gtk', type: 'array', choices : ['2','3'],  value: ['2','3'], description: 'Supported GTK versions')
+ option('tests', type : 'boolean', value : false, description: 'Parser tests')
+ option('gtk_doc', type: 'boolean', value: false, description: 'Build API reference')
++option('userunitdir', type: 'string', description: 'Installation path for user unit file (optional)')
+-- 
+2.34.1
+