Architecture specific change in rpms/pdfgrep.git
by githook-noreply@fedoraproject.org
The package rpms/pdfgrep.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/pdfgrep.git/commit/?id=536e6fdce6....
Change:
+%ifnarch s390x
Thanks.
Full change:
============
commit 536e6fdce6396475e9e201f7b2d63cb78c3e0401
Author: Robert Scheck <robert(a)fedoraproject.org>
Date: Tue Mar 26 01:05:44 2024 +0100
Upgrade to 2.2.0 (#2128346, #2271384)
diff --git a/pdfgrep.spec b/pdfgrep.spec
index bda2e99..6b88a24 100644
--- a/pdfgrep.spec
+++ b/pdfgrep.spec
@@ -1,7 +1,7 @@
Summary: Tool to search text in PDF files
Name: pdfgrep
-Version: 2.1.2
-Release: 14%{?dist}
+Version: 2.2.0
+Release: 1%{?dist}
License: GPL-2.0-or-later
URL: https://pdfgrep.org/
@@ -12,10 +12,21 @@ Source2: https://keys.openpgp.org/vks/v1/by-fingerprint/432FC753112F26D9E
BuildRequires: make
BuildRequires: gnupg2
BuildRequires: gcc-c++
-BuildRequires: poppler-cpp-devel
-BuildRequires: libgcrypt-devel
-BuildRequires: pcre-devel
+BuildRequires: poppler-cpp-devel >= 0.36.0
+BuildRequires: libgcrypt-devel >= 1.0.0
+BuildRequires: pcre2-devel
BuildRequires: asciidoc
+%if 0%{?fedora}
+# Tests: runtest(1), pdflatex(1) with parskip.sty
+BuildRequires: dejagnu
+BuildRequires: texlive-latex
+BuildRequires: tex(parskip.sty)
+# RHEL requires expl3.sty and pdftex.map explicitly
+%if 0%{?rhel} && 0%{?rhel} < 10
+BuildRequires: tex(expl3.sty)
+BuildRequires: tex(pdftex.map)
+%endif
+%endif
%description
Pdfgrep is a tool, that works similar to grep, to search text in PDF files.
@@ -35,6 +46,16 @@ colored output and finally also support for password protected PDF files.
%install
%make_install
+# /usr/share/texlive/texmf-dist/scripts/texlive/mktexlsr is run too early in dnf
+# transaction on RHEL 8 and 9, thus pdflatex(1) is unusable - thanks Red Hat ;-(
+%if 0%{?fedora}
+# Tests are broken on s390x, see https://gitlab.com/pdfgrep/pdfgrep/-/issues/70
+%ifnarch s390x
+%check
+make check
+%endif
+%endif
+
%files
%license COPYING
%doc AUTHORS NEWS.md README.md
@@ -48,6 +69,9 @@ colored output and finally also support for password protected PDF files.
%{_datadir}/zsh/site-functions/_%{name}
%changelog
+* Tue Mar 26 2024 Robert Scheck <robert(a)fedoraproject.org> - 2.2.0-1
+- Upgrade to 2.2.0 (#2128346, #2271384)
+
* Thu Jan 25 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 2.1.2-14
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
diff --git a/sources b/sources
index b9dc500..6de4090 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-SHA512 (pdfgrep-2.1.2.tar.gz) = 27bc4741e5203b2fd265815a22ad8d702b3455b2ae932641b040fc9ce615bc9ff0abef221eb2ec8aa59c79cb139d31184261d076f9731177129a473d62aa4e5c
-SHA512 (pdfgrep-2.1.2.tar.gz.asc) = 136a187fc2f2a04b9ac83b04d1f7aa7f440674fa4c94fe28729eaa595c291e45e62d902013dd2f89a62c7730c146af642859cfd8085719c3516644bca1f314f1
+SHA512 (pdfgrep-2.2.0.tar.gz) = de39ccb266f30b32ec71083759553979a31f7220b4923a4c3c74e1001c2f2c0dbef17c00f8139ffe88eec2031c48a13f18a057c7523ad363689b0f5b004c420f
+SHA512 (pdfgrep-2.2.0.tar.gz.asc) = bbca59f23e033c91c0ac871d99eb20dd684b53cf6be4a8f75cb8d89d470f00b9075491c1f5dc3975775d6f207199590effd0a59df9eba0c7dc0ae019c87ab7d9
commit eee0a8e5d69a48f01232b0b4754bd10d945bffee
Author: Fedora Release Engineering <releng(a)fedoraproject.org>
Date: Thu Jan 25 12:26:00 2024 +0000
Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
diff --git a/pdfgrep.spec b/pdfgrep.spec
index 8e6bd0f..bda2e99 100644
--- a/pdfgrep.spec
+++ b/pdfgrep.spec
@@ -1,7 +1,7 @@
Summary: Tool to search text in PDF files
Name: pdfgrep
Version: 2.1.2
-Release: 13%{?dist}
+Release: 14%{?dist}
License: GPL-2.0-or-later
URL: https://pdfgrep.org/
@@ -48,6 +48,9 @@ colored output and finally also support for password protected PDF files.
%{_datadir}/zsh/site-functions/_%{name}
%changelog
+* Thu Jan 25 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 2.1.2-14
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
* Sun Jan 21 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 2.1.2-13
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
commit 811ff2cd9b6d7a319d4bceabb77dd0f844f4786b
Author: Fedora Release Engineering <releng(a)fedoraproject.org>
Date: Sun Jan 21 12:04:40 2024 +0000
Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
diff --git a/pdfgrep.spec b/pdfgrep.spec
index ca8476b..8e6bd0f 100644
--- a/pdfgrep.spec
+++ b/pdfgrep.spec
@@ -1,7 +1,7 @@
Summary: Tool to search text in PDF files
Name: pdfgrep
Version: 2.1.2
-Release: 12%{?dist}
+Release: 13%{?dist}
License: GPL-2.0-or-later
URL: https://pdfgrep.org/
@@ -48,6 +48,9 @@ colored output and finally also support for password protected PDF files.
%{_datadir}/zsh/site-functions/_%{name}
%changelog
+* Sun Jan 21 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 2.1.2-13
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
* Thu Jul 20 2023 Fedora Release Engineering <releng(a)fedoraproject.org> - 2.1.2-12
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
1 month, 3 weeks
Architecture specific change in rpms/pdfgrep.git
by githook-noreply@fedoraproject.org
The package rpms/pdfgrep.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/pdfgrep.git/commit/?id=536e6fdce6....
Change:
+%ifnarch s390x
Thanks.
Full change:
============
commit 536e6fdce6396475e9e201f7b2d63cb78c3e0401
Author: Robert Scheck <robert(a)fedoraproject.org>
Date: Tue Mar 26 01:05:44 2024 +0100
Upgrade to 2.2.0 (#2128346, #2271384)
diff --git a/pdfgrep.spec b/pdfgrep.spec
index bda2e99..6b88a24 100644
--- a/pdfgrep.spec
+++ b/pdfgrep.spec
@@ -1,7 +1,7 @@
Summary: Tool to search text in PDF files
Name: pdfgrep
-Version: 2.1.2
-Release: 14%{?dist}
+Version: 2.2.0
+Release: 1%{?dist}
License: GPL-2.0-or-later
URL: https://pdfgrep.org/
@@ -12,10 +12,21 @@ Source2: https://keys.openpgp.org/vks/v1/by-fingerprint/432FC753112F26D9E
BuildRequires: make
BuildRequires: gnupg2
BuildRequires: gcc-c++
-BuildRequires: poppler-cpp-devel
-BuildRequires: libgcrypt-devel
-BuildRequires: pcre-devel
+BuildRequires: poppler-cpp-devel >= 0.36.0
+BuildRequires: libgcrypt-devel >= 1.0.0
+BuildRequires: pcre2-devel
BuildRequires: asciidoc
+%if 0%{?fedora}
+# Tests: runtest(1), pdflatex(1) with parskip.sty
+BuildRequires: dejagnu
+BuildRequires: texlive-latex
+BuildRequires: tex(parskip.sty)
+# RHEL requires expl3.sty and pdftex.map explicitly
+%if 0%{?rhel} && 0%{?rhel} < 10
+BuildRequires: tex(expl3.sty)
+BuildRequires: tex(pdftex.map)
+%endif
+%endif
%description
Pdfgrep is a tool, that works similar to grep, to search text in PDF files.
@@ -35,6 +46,16 @@ colored output and finally also support for password protected PDF files.
%install
%make_install
+# /usr/share/texlive/texmf-dist/scripts/texlive/mktexlsr is run too early in dnf
+# transaction on RHEL 8 and 9, thus pdflatex(1) is unusable - thanks Red Hat ;-(
+%if 0%{?fedora}
+# Tests are broken on s390x, see https://gitlab.com/pdfgrep/pdfgrep/-/issues/70
+%ifnarch s390x
+%check
+make check
+%endif
+%endif
+
%files
%license COPYING
%doc AUTHORS NEWS.md README.md
@@ -48,6 +69,9 @@ colored output and finally also support for password protected PDF files.
%{_datadir}/zsh/site-functions/_%{name}
%changelog
+* Tue Mar 26 2024 Robert Scheck <robert(a)fedoraproject.org> - 2.2.0-1
+- Upgrade to 2.2.0 (#2128346, #2271384)
+
* Thu Jan 25 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 2.1.2-14
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
diff --git a/sources b/sources
index b9dc500..6de4090 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-SHA512 (pdfgrep-2.1.2.tar.gz) = 27bc4741e5203b2fd265815a22ad8d702b3455b2ae932641b040fc9ce615bc9ff0abef221eb2ec8aa59c79cb139d31184261d076f9731177129a473d62aa4e5c
-SHA512 (pdfgrep-2.1.2.tar.gz.asc) = 136a187fc2f2a04b9ac83b04d1f7aa7f440674fa4c94fe28729eaa595c291e45e62d902013dd2f89a62c7730c146af642859cfd8085719c3516644bca1f314f1
+SHA512 (pdfgrep-2.2.0.tar.gz) = de39ccb266f30b32ec71083759553979a31f7220b4923a4c3c74e1001c2f2c0dbef17c00f8139ffe88eec2031c48a13f18a057c7523ad363689b0f5b004c420f
+SHA512 (pdfgrep-2.2.0.tar.gz.asc) = bbca59f23e033c91c0ac871d99eb20dd684b53cf6be4a8f75cb8d89d470f00b9075491c1f5dc3975775d6f207199590effd0a59df9eba0c7dc0ae019c87ab7d9
1 month, 3 weeks
[Report] Packages Restricting Arches
by root
Package no longer excluding arches (1)
==================================
- blend2d
List of packages currently excluding arches (2153)
===========================================
- 0ad
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64 ppc64le
- 389-ds-base
ExcludeArch: i686
- 4ti2
ExcludeArch: %{ix86}
- 90-Second-Portraits
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc64le riscv64
- AcetoneISO
ExcludeArch: ppc %{power64} s390x
- Agda
ExcludeArch: %{ix86} armv7hl
- Agda-stdlib
ExcludeArch: armv7hl %{ix86}
- BareBonesBrowserLaunch
ExclusiveArch: %{java_arches} noarch
- CFR
ExclusiveArch: %{java_arches} noarch
- COPASI
ExcludeArch: %{ix86}
- CardManager
ExclusiveArch: %{java_arches} noarch
- CuraEngine
ExcludeArch: %{ix86}
- E
ExcludeArch: %{ix86}
- GAPDoc
ExcludeArch: %{ix86}
- GoldenCheetah
ExclusiveArch: %{qt5_qtwebengine_arches}
- GtkAda
ExclusiveArch: %{GPRbuild_arches}
- GtkAda3
ExclusiveArch: %{GPRbuild_arches}
- HPCombi
ExclusiveArch: x86_64 %{arm64}
- IPAddress
ExclusiveArch: %{java_arches} noarch
- IQmol
ExcludeArch: %{ix86}
- JUnitParams
ExclusiveArch: %{java_arches} noarch
- L-function
ExcludeArch: %{ix86}
- LabPlot
ExcludeArch: sparc64 s390 s390x
- MUSIC
ExcludeArch: %{ix86}
- Macaulay2
ExcludeArch: %{ix86} ppc64le
- Maelstrom
ExcludeArch: %{ix86}
- Mars
ExclusiveArch: %{java_arches} noarch
- NiaAML-GUI
ExcludeArch: %{ix86}
- OpenColorIO
ExcludeArch: i686
ExclusiveArch: x86_64 ppc64le
- OpenImageIO
ExcludeArch: i686
ExclusiveArch: x86_64 ppc64le
- OpenMolcas
ExclusiveArch: x86_64 aarch64 ppc64le s390x
- OpenStego
ExclusiveArch: %{java_arches} noarch
- Pencil2D
ExcludeArch: %{ix86}
- PragmARC
ExclusiveArch: %{GPRbuild_arches}
- ProDy
ExcludeArch: ppc64 s390x
- R-IRkernel
ExcludeArch: %{ix86}
- R-V8
ExclusiveArch: %{nodejs_arches}
- R-ape
ExcludeArch: %{ix86}
- R-igraph
ExcludeArch: %{ix86}
- R-kernlab
ExcludeArch: %{ix86} s390x
- R-rJava
ExclusiveArch: %{java_arches}
- Random123
ExcludeArch: mips64r2 mips32r2 s390
- RdRand
ExclusiveArch: %{ix86} x86_64
- RediSearch
ExclusiveArch: x86_64
- SLOF
ExclusiveArch: ppc64le
- Singular
ExcludeArch: %{ix86}
- TOPCOM
ExcludeArch: %{ix86}
- VulkanMemoryAllocator
ExcludeArch: %{ix86}
- WoeUSB
ExcludeArch: s390x
- YafaRay
ExclusiveArch: %{ix86} x86_64
- Zim
ExcludeArch: %{ix86}
- aardvark-dns
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- abiword
ExcludeArch: %{ix86}
- abrt-java-connector
ExcludeArch: %{ix86}
- accel-config
ExclusiveArch: %{ix86} x86_64
- acpica-tools
ExcludeArch: i686 armv7hl
- acpid
ExclusiveArch: ia64 x86_64 %{ix86} %{arm} aarch64 riscv64
- act
ExcludeArch: %{ix86}
- admeshgui
ExcludeArch: %{ix86}
- aemu
ExcludeArch: %{ix86} %{power64} s390x
- agenda
ExcludeArch: %{ix86}
- ahven
ExclusiveArch: %{GPRbuild_arches}
- algobox
ExclusiveArch: %{qt5_qtwebengine_arches}
- alienarena
ExcludeArch: s390x
- alizams
ExcludeArch: %{power64} %{ix86} s390x
- alt-ergo
ExcludeArch: %{ix86}
- american-fuzzy-lop
ExclusiveArch: x86_64 s390x
- amg4psblas
ExcludeArch: %{ix86}
- android-tools
ExcludeArch: ppc ppc64 s390x ppc64le
- anet
ExclusiveArch: %{GPRbuild_arches}
- ansible-collection-microsoft-sql
ExcludeArch: i686
- ant
ExclusiveArch: %{java_arches} noarch
- ant-antunit
ExclusiveArch: %{java_arches} noarch
- ant-contrib
ExclusiveArch: %{java_arches} noarch
- antlr
ExclusiveArch: %{java_arches}
- antlr3
ExclusiveArch: %{java_arches}
- antlr4-project
ExclusiveArch: %{java_arches}
- antlrworks
ExclusiveArch: %{java_arches} noarch
- aopalliance
ExclusiveArch: %{java_arches} noarch
- apache-commons-beanutils
ExclusiveArch: %{java_arches} noarch
- apache-commons-cli
ExclusiveArch: %{java_arches} noarch
- apache-commons-codec
ExclusiveArch: %{java_arches} noarch
- apache-commons-collections
ExclusiveArch: %{java_arches} noarch
- apache-commons-collections4
ExclusiveArch: %{java_arches} noarch
- apache-commons-compress
ExclusiveArch: %{java_arches} noarch
- apache-commons-configuration
ExclusiveArch: %{java_arches} noarch
- apache-commons-digester
ExclusiveArch: %{java_arches} noarch
- apache-commons-exec
ExclusiveArch: %{java_arches} noarch
- apache-commons-io
ExclusiveArch: %{java_arches} noarch
- apache-commons-jexl
ExclusiveArch: %{java_arches} noarch
- apache-commons-jxpath
ExclusiveArch: %{java_arches} noarch
- apache-commons-lang3
ExclusiveArch: %{java_arches} noarch
- apache-commons-logging
ExclusiveArch: %{java_arches} noarch
- apache-commons-math
ExclusiveArch: %{java_arches} noarch
- apache-commons-modeler
ExclusiveArch: %{java_arches} noarch
- apache-commons-net
ExclusiveArch: %{java_arches} noarch
- apache-commons-parent
ExclusiveArch: %{java_arches} noarch
- apache-commons-pool
ExclusiveArch: %{java_arches} noarch
- apache-commons-vfs
ExclusiveArch: %{java_arches} noarch
- apache-ivy
ExclusiveArch: %{java_arches} noarch
- apache-logging-parent
ExclusiveArch: %{java_arches} noarch
- apache-parent
ExclusiveArch: %{java_arches} noarch
- apache-resource-bundles
ExclusiveArch: %{java_arches} noarch
- apache-sshd
ExclusiveArch: %{java_arches} noarch
- apiguardian
ExclusiveArch: %{java_arches} noarch
- apmd
ExclusiveArch: %{ix86}
- appeditor
ExcludeArch: %{ix86}
- appstream-generator
ExclusiveArch: %{ldc_arches}
- apricots
ExcludeArch: ppc64le aarch64
- apron
ExcludeArch: %{ix86}
- aqute-bnd
ExclusiveArch: %{java_arches} noarch
- arbor
ExcludeArch: mips64r2 mips32r2 s390x %{ix86}
- arc-theme
ExcludeArch: %{ix86}
- args4j
ExclusiveArch: %{java_arches} noarch
- arianna
ExclusiveArch: %{qt6_qtwebengine_arches}
- arm-none-eabi-binutils-cs
ExcludeArch: %{ix86}
- arm-none-eabi-gcc-cs
ExcludeArch: %{ix86}
- arm-trusted-firmware
ExclusiveArch: aarch64
- arpwatch
ExcludeArch: %{ix86}
- asahi-installer
ExcludeArch: s390x
- asdcplib
ExcludeArch: %{ix86} %{arm}
- asmjit
ExclusiveArch: aarch64 x86_64
- assertj-core
ExclusiveArch: %{java_arches} noarch
- astromenace
ExcludeArch: ppc64 s390x
- astrometry-tycho2
ExcludeArch: s390x
- asv
ExcludeArch: %{ix86}
- atinject
ExclusiveArch: %{java_arches} noarch
- atlantik
ExcludeArch: %{ix86}
- atomic-queue
ExcludeArch: %{ix86}
- aubit4gl
ExcludeArch: i686 s390x ppc64le
- audacity
ExcludeArch: %{ix86} s390x
- audiocd-kio
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- aunit
ExclusiveArch: %GPRbuild_arches
- auryn
ExcludeArch: %{ix86}
- auto
ExclusiveArch: %{java_arches} noarch
- autolink-java
ExclusiveArch: noarch %{java_arches}
- avgtime
ExclusiveArch: %{ldc_arches}
- aws
ExclusiveArch: %GPRbuild_arches
- awscli2
ExcludeArch: s390x
- azove
ExcludeArch: %{ix86}
- azure-cli
ExclusiveArch: %{java_arches} noarch
- batik
ExclusiveArch: %{java_arches} noarch
- bcal
ExclusiveArch: x86_64 aarch64 ia64 ppc64 ppc64le s390x riscv64
- bcc
ExclusiveArch: x86_64 %{power64} aarch64 s390x armv7hl riscv64
- bcel
ExclusiveArch: %{java_arches} noarch
- bcftools
ExcludeArch: s390x
- bcm283x-firmware
ExclusiveArch: aarch64
- beansbinding
ExclusiveArch: %{java_arches} noarch
- bear
ExcludeArch: %{ix86}
- bear-factory
ExcludeArch: ppc64le
- berusky2
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64 %{mips} riscv64
- beust-jcommander
ExclusiveArch: %{java_arches} noarch
- bibletime
ExclusiveArch: %{java_arches}
- bigloo
ExcludeArch: %{ix86}
- binaryen
ExcludeArch: ppc64 s390x
- binutils
ExcludeArch: aarch64-linux-gnu aarch64-redhat-linux
ExcludeArch: ppc64le-linux-gnu ppc64le-redhat-linux
ExcludeArch: s390x-linux-gnu s390x-redhat-linux
ExcludeArch: x86_64-linux-gnu x86_64-redhat-linux i686-linux-gnu i686-redhat-linux
- biosdevname
ExclusiveArch: %{ix86} x86_64
- blake3
ExcludeArch: %{ix86}
- blender
ExcludeArch: %{ix86} %{arm}
- bless
ExclusiveArch: %mono_arches
- bliss
ExcludeArch: %{ix86}
- blueprint-compiler
ExcludeArch: s390x
- bluez-hcidump
ExcludeArch: s390 s390x
- bochs
ExcludeArch: s390x i686
- bodhi-server
ExclusiveArch: %{golang_arches_future}
- boinc-client
ExcludeArch: s390x
- bolzplatz2006
ExclusiveArch: %{java_arches}
- bootc
ExcludeArch: %{ix86}
- bottles
ExcludeArch: s390x
- bouncycastle
ExclusiveArch: %{java_arches} noarch
- bout++
ExcludeArch: %{ix86}
- bowtie
ExcludeArch: i686 armv7hl
- bowtie2
ExcludeArch: %{ix86} %{arm} s390x
- box64
ExclusiveArch: aarch64 riscv64 ppc64le x86_64
- boxes
ExcludeArch: %{ix86}
- bpftrace
ExclusiveArch: x86_64 %{power64} aarch64 s390x
- brazil
ExclusiveArch: %{java_arches} noarch
- breakid
ExcludeArch: %{ix86}
- brewtarget
ExcludeArch: %{ix86}
- brial
ExcludeArch: %{ix86}
- bsf
ExclusiveArch: %{java_arches} noarch
- bsh
ExclusiveArch: %{java_arches} noarch
- build-helper-maven-plugin
ExclusiveArch: %{java_arches} noarch
- buildah
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- busybox
ExcludeArch: i686 s390x
- bwping
ExcludeArch: %{ix86}
- byebyebios
ExclusiveArch: x86_64
- byte-buddy
ExclusiveArch: %{java_arches} noarch
- byteman
ExclusiveArch: %{java_arches} noarch
- cachelib
ExclusiveArch: x86_64 aarch64 ppc64le
- caddy
ExclusiveArch: %{golang_arches}
ExclusiveArch: %{golang_arches_future}
- cadical
ExcludeArch: %{ix86}
- caffe
ExclusiveArch: x86_64 aarch64 ppc64le
- calamares
ExclusiveArch: %{ix86} x86_64 aarch64 riscv64
- calc
ExcludeArch: s390x
- calibre
ExclusiveArch: aarch64 x86_64
- calligra
ExcludeArch: %{ix86}
- cambozola
ExclusiveArch: %{java_arches} noarch
- canl-java
ExclusiveArch: %{java_arches} noarch
- cantera
ExcludeArch: %{ix86}
- carat
ExcludeArch: %{ix86}
- casc
ExcludeArch: %{ix86}
- cataclysm-dda
ExcludeArch: i686
- catatonit
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- ccdciel
ExclusiveArch: %{fpc_arches}
ExcludeArch: %{ix86}
- ccluster
ExcludeArch: %{ix86}
- cdcollect
ExclusiveArch: %{mono_arches}
- cdi-api
ExclusiveArch: %{java_arches} noarch
- cdrdao
ExcludeArch: s390 s390x
- ceph
ExcludeArch: i686 armv7hl
ExclusiveArch: x86_64 aarch64 ppc64le s390x
- ceres-solver
ExcludeArch: ppc64
- cfn-lint
ExcludeArch: %{ix86}
- cglib
ExclusiveArch: %{java_arches} noarch
- cgreen
ExcludeArch: s390x
- chatterino2
ExcludeArch: %{ix86}
- chatty
ExcludeArch: i686
- checkpointctl
ExclusiveArch: %{golang_arches_future}
- chromium
ExclusiveArch: x86_64
ExclusiveArch: x86_64 aarch64 ppc64le
ExclusiveArch: x86_64 aarch64
- cinnamon
ExcludeArch: %{ix86}
- cinnamon-control-center
ExcludeArch: %{ix86}
- cinnamon-desktop
ExcludeArch: %{ix86}
- cinnamon-menus
ExcludeArch: %{ix86}
- cinnamon-screensaver
ExcludeArch: %{ix86}
- cinnamon-session
ExcludeArch: %{ix86}
- cinnamon-settings-daemon
ExcludeArch: %{ix86}
- cjdns
ExclusiveArch: %{nodejs_arches}
- cjs
ExcludeArch: %{ix86}
- classloader-leak-test-framework
ExclusiveArch: %{java_arches} noarch
- classpathless-compiler
ExclusiveArch: %{java_arches} noarch
- cld2
ExcludeArch: ppc64 s390x
- clevis-pin-tpm2
ExclusiveArch: %{rust_arches}
- clibs-list
ExcludeArch: %{ix86}
- clojure
ExclusiveArch: %{java_arches} noarch
- clojure-core-specs-alpha
ExclusiveArch: %{java_arches} noarch
- clojure-maven-plugin
ExclusiveArch: %{java_arches} noarch
- clojure-spec-alpha
ExclusiveArch: %{java_arches} noarch
- cloudcompare
ExcludeArch: %{ix86}
- clover2
ExcludeArch: armv7hl
- cmospwd
ExclusiveArch: %{ix86} x86_64
- cmrt
ExclusiveArch: %{ix86} x86_64 ia64
- coan
ExcludeArch: ppc64 s390x
- coccinelle
ExcludeArch: %{ix86}
- cocoalib
ExcludeArch: %{ix86}
- codeblocks
ExcludeArch: %{ix86}
- codehaus-parent
ExclusiveArch: %{java_arches} noarch
- cohomCalg
ExcludeArch: %{ix86}
- coin-or-Alps
ExcludeArch: %{ix86}
- coin-or-Bcp
ExcludeArch: %{ix86}
- coin-or-Bcps
ExcludeArch: %{ix86}
- coin-or-Blis
ExcludeArch: %{ix86}
- coin-or-Bonmin
ExcludeArch: %{ix86}
- coin-or-CoinMP
ExcludeArch: %{ix86}
- coin-or-Couenne
ExcludeArch: %{ix86}
- coin-or-Dip
ExcludeArch: %{ix86}
- coin-or-FlopC++
ExcludeArch: %{ix86}
- coin-or-HiGHS
ExcludeArch: %{ix86}
- coin-or-Ipopt
ExcludeArch: %{ix86}
- coin-or-OS
ExcludeArch: %{ix86}
- coin-or-SYMPHONY
ExcludeArch: %{ix86}
- coin-or-lemon
ExcludeArch: %{ix86}
- colorful
ExclusiveArch: %{fpc_arches}
- colossus
ExclusiveArch: %{java_arches} noarch
- compiz-plugins-experimental
ExcludeArch: s390 s390x
- conmon
ExclusiveArch: %{golang_arches_future}
- console-image-viewer
ExclusiveArch: %{java_arches} noarch
- containernetworking-plugins
ExclusiveArch: %{golang_arches}
- containers-common
ExclusiveArch: %{golang_arches} noarch
- contour-terminal
ExclusiveArch: x86_64 aarch64
- contractor
ExcludeArch: %{ix86}
- conu
ExcludeArch: ppc64
- coolreader
ExcludeArch: %{ix86}
- coq
ExclusiveArch: %{ocaml_native_compiler}
- corectrl
ExcludeArch: %{ix86}
- cortado
ExclusiveArch: %{java_arches} noarch
- coxeter
ExcludeArch: %{ix86}
- cpp-hocon
ExcludeArch: %{ix86}
- cpu-x
ExclusiveArch: i686 x86_64
- cpufetch
ExclusiveArch: %{arm} aarch64 x86_64 ppc ppc64 ppc64le
- cpuid
ExclusiveArch: %{ix86} x86_64
- cpuinfo
ExclusiveArch: x86_64 aarch64
- cqrlog
ExclusiveArch: %{fpc_arches}
- cramjam-cli
ExcludeArch: %{ix86}
- crash
ExclusiveArch: %{ix86} ia64 x86_64 ppc ppc64 s390 s390x %{arm} aarch64 ppc64le
- crash-gcore-command
ExclusiveArch: aarch64 ppc64le x86_64
- crash-trace-command
ExclusiveArch: aarch64 ppc64le s390x x86_64
- credentials-fetcher
ExclusiveArch: x86_64 aarch64 s390x
- crest
ExcludeArch: s390x
- cri-o
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
- cri-tools
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
- criu
ExclusiveArch: x86_64 %{arm} ppc64le aarch64 s390x
- crun
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le riscv64 s390x x86_64
- cryfs
ExcludeArch: i686
- cryptlib
ExclusiveArch: x86_64 aarch64 ppc64le
- crypto-policies
ExclusiveArch: %{java_arches} noarch
- cryptobone
ExclusiveArch: x86_64 ppc64le aarch64
- cryptominisat
ExcludeArch: %{ix86}
- csdp
ExcludeArch: %{ix86}
- csslint
ExclusiveArch: %{nodejs_arches} noarch
- cura
ExcludeArch: %{ix86}
- cura-fdm-materials
ExcludeArch: %{ix86}
- cvc5
ExcludeArch: %{ix86}
- cxsc
ExcludeArch: %{ix86}
- daggy
ExcludeArch: s390x
- dapl
ExcludeArch: s390, armv7hl
- daq
ExclusiveArch: x86_64 aarch64
- darktable
ExcludeArch: armv7hl i686 s390x
ExcludeArch: aarch64
- dbus-parsec
ExcludeArch: ppc64le s390x
- dbus-sharp
ExclusiveArch: %mono_arches
- dbus-sharp-glib
ExclusiveArch: %mono_arches
- ddccontrol
ExcludeArch: s390 s390x
- ddcutil
ExcludeArch: s390 s390x
- ddd
ExcludeArch: %{ix86}
- ddnet
ExcludeArch: s390x
- decentxml
ExclusiveArch: %{java_arches} noarch
- deepin-daemon
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
- deepin-desktop-schemas
ExclusiveArch: %{go_arches}
- dhall
ExcludeArch: %{ix86}
- dhall-json
ExcludeArch: %{ix86}
- dialect
ExcludeArch: s390x
- diffoscope
ExcludeArch: %{ix86}
- dippi
ExcludeArch: %{ix86}
- directory-maven-plugin
ExclusiveArch: %{java_arches} noarch
- dirgra
ExclusiveArch: %{java_arches} noarch
- disruptor
ExclusiveArch: %{java_arches} noarch
- ditaa
ExclusiveArch: %{java_arches} noarch
- dl_poly
ExcludeArch: i686
- dlib
ExcludeArch: ppc64le
- dlm
ExclusiveArch: i686 x86_64
- dmidecode
ExclusiveArch: %{ix86} x86_64 ia64 aarch64
- dmtcp
ExclusiveArch: x86_64
- dnsdist
ExcludeArch: %{ix86} #1994125
ExcludeArch: armv7hl #1994125
- docker-distribution
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
- dogtag-pki
ExclusiveArch: %{java_arches}
ExcludeArch: i686
- dolfin
ExcludeArch: %{ix86}
- dolphin-emu
ExclusiveArch: x86_64 aarch64
- dom4j
ExclusiveArch: %{java_arches} noarch
- dosbox-staging
ExcludeArch: %{ix86}
- dotnet6.0
ExclusiveArch: aarch64 x86_64 s390x
ExclusiveArch: x86_64
- dotnet8.0
ExclusiveArch: aarch64 ppc64le s390x x86_64
- doublecmd
ExclusiveArch: %{ix86} x86_64
- dpdk
ExclusiveArch: x86_64 i686 aarch64 ppc64le
- dragonbox
ExcludeArch: %{ix86}
- drat-trim
ExcludeArch: %{ix86}
- drat2er
ExcludeArch: %{ix86}
- dub
ExclusiveArch: %{ldc_arches}
- duperemove
ExcludeArch: %{ix86}
- dvdauthor
ExcludeArch: %{ix86}
- dvgrab
ExcludeArch: s390 s390x
- dxvk-native
ExclusiveArch: %{ix86} x86_64
- dyninst
ExclusiveArch: %{ix86} x86_64 ppc64le aarch64
- e-antic
ExcludeArch: %{ix86}
- e00compr
ExcludeArch: %{ix86}
- e3
ExclusiveArch: %{ix86} x86_64
- easymock
ExclusiveArch: %{java_arches} noarch
- eccodes
ExcludeArch: i686
- ecj
ExclusiveArch: %{java_arches} noarch
- eclib
ExcludeArch: %{ix86}
- eclipse-swt
ExclusiveArch: %{java_arches}
- ed25519-java
ExclusiveArch: %{java_arches} noarch
- edac-utils
ExcludeArch: %{ix86}
- edflib
ExcludeArch: s390x %{ix86}
- edk2
ExclusiveArch: x86_64 aarch64 riscv64
- edwin-fonts
ExcludeArch: %{ix86}
- eegdev
ExcludeArch: %{ix86}
- eegview
ExcludeArch: %{ix86}
- efax
ExcludeArch: s390 s390x
- efibootmgr
ExclusiveArch: %{efi}
- efifs
ExclusiveArch: %{efi}
- efitools
ExclusiveArch: %{efi}
- efivar
ExclusiveArch: %{efi}
- electron-cash
ExcludeArch: %{ix86}
- electrum
ExcludeArch: %{ix86}
- elk
ExclusiveArch: x86_64 %{ix86}
ExclusiveArch: x86_64 aarch64 %{arm} %{power64}
ExclusiveArch: x86_64 %{ix86} aarch64 %{arm} %{power64}
- emacs-common-proofgeneral
ExcludeArch: %{ix86}
- emacs-company-mode
ExcludeArch: %{ix86}
- emacs-iedit
ExcludeArch: %{ix86}
- emacs-slime
ExclusiveArch: %{arm} %{ix86} x86_64 ppc sparcv9 aarch64
- embree
ExclusiveArch: aarch64 x86_64
- embree3
ExclusiveArch: aarch64 x86_64
- enjarify
ExclusiveArch: %{java_arches} noarch
- enki
ExclusiveArch: %{qt5_qtwebengine_arches} noarch
- envytools
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64 riscv64
- eot-utils
ExcludeArch: %{ix86}
- ergo
ExcludeArch: %{ix86}
- eric
ExclusiveArch: %{qt6_qtwebengine_arches} noarch
- erlang-corba
ExclusiveArch: %{java_arches}
- esmi_ib_library
ExclusiveArch: x86_64
- espresso
ExcludeArch: s390x i686 armv7hl
- eth-tools
ExclusiveArch: x86_64
- exec-maven-plugin
ExclusiveArch: %{java_arches} noarch
- external-editor-revived
ExclusiveArch: %{rust_arches}
- extra-enforcer-rules
ExclusiveArch: %{java_arches} noarch
- fasterxml-oss-parent
ExclusiveArch: %{java_arches} noarch
- fb303
ExclusiveArch: x86_64 aarch64 ppc64le
- fbreader
ExcludeArch: %{ix86}
ExcludeArch: armv7hl
- fbthrift
ExclusiveArch: x86_64 aarch64 ppc64le
- fcitx-libpinyin
ExclusiveArch: %{qt5_qtwebengine_arches}
- fcitx5-mozc
ExcludeArch: ppc ppc64 sparcv9 sparc64 s390x
- fcoe-utils
ExcludeArch: ppc s390
ExcludeArch: %{ix86}
- fedora-dockerfiles
ExclusiveArch: %{go_arches}
ExcludeArch: ppc64
- felix-parent
ExclusiveArch: %{java_arches} noarch
- felix-utils
ExclusiveArch: %{java_arches} noarch
- fernflower
ExclusiveArch: %{java_arches} noarch
- fes
ExclusiveArch: %{ix86} x86_64
- fido-device-onboard
ExcludeArch: %{ix86}
- filedrop
ExclusiveArch: %{java_arches} noarch
- filezilla
ExcludeArch: s390x
- firecracker
ExclusiveArch: aarch64 x86_64
- firefox
ExcludeArch: i686
- fishbowl
ExclusiveArch: %{java_arches} noarch
- fizz
ExclusiveArch: x86_64 aarch64 ppc64le
- flang
ExcludeArch: i686 s390x
- flashrom
ExcludeArch: s390 s390x
- flatbuffers
ExcludeArch: %{ix86}
- flatpak
ExcludeArch: %{ix86}
- flatpak-builder
ExcludeArch: %{ix86}
- flatpak-module-tools
ExcludeArch: i386 i686
- flexmark-java
ExclusiveArch: noarch %{java_arches}
- flickcurl
ExcludeArch: %{ix86}
- flint
ExcludeArch: %{ix86}
- flocq
ExclusiveArch: %{ocaml_native_compiler}
- floppy-support
ExcludeArch: %{arm} aarch64 s390x
- florist
ExclusiveArch: %{GPRbuild_arches}
- flterm
ExcludeArch: s390 s390x sparcv9
- fluent-bit
ExclusiveArch: x86_64 aarch64
- flute
ExclusiveArch: %{java_arches} noarch
- fmidi
ExcludeArch: %{ix86}
- folly
ExclusiveArch: x86_64 aarch64 ppc64le
- fop
ExclusiveArch: %{java_arches} noarch
- forge-parent
ExclusiveArch: %{java_arches} noarch
- fotocx
ExcludeArch: %{ix86}
- foxi
ExclusiveArch: x86_64 aarch64
- fpc
ExclusiveArch: %{arm} aarch64 %{ix86} x86_64 ppc64le
- fprintd
ExcludeArch: s390 s390x
- fractal
ExcludeArch: %{ix86}
- fragments
ExcludeArch: %{ix86}
- frama-c
ExclusiveArch: %{ocaml_native_compiler}
- free42
ExcludeArch: %{ix86}
- freecol
ExclusiveArch: %{java_arches} noarch
- freedink
ExcludeArch: s390x
- freedink-dfarc
ExcludeArch: s390x
- freefem++
ExcludeArch: %{ix86}
- freemarker
ExclusiveArch: %{java_arches} noarch
- freerouting
ExclusiveArch: %{java_arches} noarch
- freetennis
ExcludeArch: sparc64 s390 s390x %{ix86}
- frescobaldi
ExclusiveArch: %{qt5_qtwebengine_arches}
- frysk
ExclusiveArch: x86_64 ppc64
- fuse-overlayfs
ExclusiveArch: %{arm64} ppc64le s390x x86_64 riscv64
- fusesource-pom
ExclusiveArch: %{java_arches} noarch
- fwts
ExclusiveArch: x86_64 %{arm} aarch64 s390x riscv64 %{power64}
- fwupd-efi
ExclusiveArch: x86_64 aarch64
- ga
ExcludeArch: %{ix86}
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64 ppc64le
- gambas3
ExcludeArch: i686
- gap
ExcludeArch: %{ix86}
- gap-pkg-ace
ExcludeArch: %{ix86}
- gap-pkg-aclib
ExcludeArch: %{ix86}
- gap-pkg-alnuth
ExcludeArch: %{ix86}
- gap-pkg-atlasrep
ExcludeArch: %{ix86}
- gap-pkg-autodoc
ExcludeArch: %{ix86}
- gap-pkg-automata
ExcludeArch: %{ix86}
- gap-pkg-autpgrp
ExcludeArch: %{ix86}
- gap-pkg-browse
ExcludeArch: %{ix86}
- gap-pkg-caratinterface
ExcludeArch: %{ix86}
- gap-pkg-circle
ExcludeArch: %{ix86}
- gap-pkg-cohomolo
ExcludeArch: %{ix86}
- gap-pkg-congruence
ExcludeArch: %{ix86}
- gap-pkg-corelg
ExcludeArch: %{ix86}
- gap-pkg-crime
ExcludeArch: %{ix86}
- gap-pkg-crisp
ExcludeArch: %{ix86}
- gap-pkg-crypting
ExcludeArch: %{ix86}
- gap-pkg-cryst
ExcludeArch: %{ix86}
- gap-pkg-crystcat
ExcludeArch: %{ix86}
- gap-pkg-ctbllib
ExcludeArch: %{ix86}
- gap-pkg-curlinterface
ExcludeArch: %{ix86}
- gap-pkg-cvec
ExcludeArch: %{ix86}
- gap-pkg-datastructures
ExcludeArch: %{ix86}
- gap-pkg-design
ExcludeArch: %{ix86}
- gap-pkg-digraphs
ExcludeArch: %{ix86}
- gap-pkg-edim
ExcludeArch: %{ix86}
- gap-pkg-factint
ExcludeArch: %{ix86}
- gap-pkg-ferret
ExcludeArch: %{ix86}
- gap-pkg-fga
ExcludeArch: %{ix86}
- gap-pkg-fining
ExcludeArch: %{ix86}
- gap-pkg-float
ExcludeArch: %{ix86}
- gap-pkg-format
ExcludeArch: %{ix86}
- gap-pkg-forms
ExcludeArch: %{ix86}
- gap-pkg-fr
ExcludeArch: %{ix86}
- gap-pkg-francy
ExcludeArch: %{ix86}
- gap-pkg-gbnp
ExcludeArch: %{ix86}
- gap-pkg-genss
ExcludeArch: %{ix86}
- gap-pkg-grape
ExcludeArch: %{ix86}
- gap-pkg-groupoids
ExcludeArch: %{ix86}
- gap-pkg-grpconst
ExcludeArch: %{ix86}
- gap-pkg-guava
ExcludeArch: %{ix86}
- gap-pkg-hap
ExcludeArch: %{ix86}
- gap-pkg-hapcryst
ExcludeArch: %{ix86}
- gap-pkg-hecke
ExcludeArch: %{ix86}
- gap-pkg-images
ExcludeArch: %{ix86}
- gap-pkg-io
ExcludeArch: %{ix86}
- gap-pkg-irredsol
ExcludeArch: %{ix86}
- gap-pkg-json
ExcludeArch: %{ix86}
- gap-pkg-jupyterkernel
ExcludeArch: %{ix86}
- gap-pkg-jupyterviz
ExcludeArch: %{ix86}
- gap-pkg-laguna
ExcludeArch: %{ix86}
- gap-pkg-liealgdb
ExcludeArch: %{ix86}
- gap-pkg-liepring
ExcludeArch: %{ix86}
- gap-pkg-liering
ExcludeArch: %{ix86}
- gap-pkg-loops
ExcludeArch: %{ix86}
- gap-pkg-lpres
ExcludeArch: %{ix86}
- gap-pkg-mapclass
ExcludeArch: %{ix86}
- gap-pkg-nautytracesinterface
ExcludeArch: %{ix86}
- gap-pkg-nq
ExcludeArch: %{ix86}
- gap-pkg-openmath
ExcludeArch: %{ix86}
- gap-pkg-orb
ExcludeArch: %{ix86}
- gap-pkg-polenta
ExcludeArch: %{ix86}
- gap-pkg-polycyclic
ExcludeArch: %{ix86}
- gap-pkg-polymaking
ExcludeArch: %{ix86}
- gap-pkg-primgrp
ExcludeArch: %{ix86}
- gap-pkg-profiling
ExcludeArch: %{ix86}
- gap-pkg-qpa
ExcludeArch: %{ix86}
- gap-pkg-quagroup
ExcludeArch: %{ix86}
- gap-pkg-radiroot
ExcludeArch: %{ix86}
- gap-pkg-recog
ExcludeArch: %{ix86}
- gap-pkg-repsn
ExcludeArch: %{ix86}
- gap-pkg-resclasses
ExcludeArch: %{ix86}
- gap-pkg-scscp
ExcludeArch: %{ix86}
- gap-pkg-semigroups
ExcludeArch: %{ix86}
- gap-pkg-singular
ExcludeArch: %{ix86}
- gap-pkg-sla
ExcludeArch: %{ix86}
- gap-pkg-smallgrp
ExcludeArch: %{ix86}
- gap-pkg-smallsemi
ExcludeArch: %{ix86}
- gap-pkg-sonata
ExcludeArch: %{ix86}
- gap-pkg-sophus
ExcludeArch: %{ix86}
- gap-pkg-spinsym
ExcludeArch: %{ix86}
- gap-pkg-standardff
ExcludeArch: %{ix86}
- gap-pkg-tomlib
ExcludeArch: %{ix86}
- gap-pkg-toric
ExcludeArch: %{ix86}
- gap-pkg-transgrp
ExcludeArch: %{ix86}
- gap-pkg-utils
ExcludeArch: %{ix86}
- gap-pkg-uuid
ExcludeArch: %{ix86}
- gap-pkg-xmod
ExcludeArch: %{ix86}
- gap-pkg-zeromqinterface
ExcludeArch: %{ix86}
- gappa
ExcludeArch: %{ix86}
- gappalib-coq
ExclusiveArch: %{ocaml_native_compiler}
- gauche
ExcludeArch: armv7hl
- gbrainy
ExclusiveArch: %mono_arches
- gcl
ExcludeArch: s390x
- gdb
ExclusiveArch: %{ix86} x86_64
ExcludeArch: aarch64
- gdb-exploitable
ExclusiveArch: x86_64 i386
ExclusiveArch: x86_64 noarch
- gdl
ExcludeArch: %{ix86}
- gearhead1
ExclusiveArch: %{fpc_arches}
- gearhead2
ExclusiveArch: %{fpc_arches}
- gearmand
ExcludeArch: ppc
- geeqie
ExcludeArch: %{ix86}
- gfan
ExcludeArch: %{ix86}
- gfs2-utils
ExcludeArch: %{ix86}
- gfxstream
ExcludeArch: %{ix86} %{power64} s390x
- ghc
ExcludeArch: armv7hl
- ghc-cborg
ExcludeArch: %{ix86}
- ghc-cborg-json
ExcludeArch: %{ix86}
- ghc-gi-gtk
ExcludeArch: armv7hl
- ghc-serialise
ExcludeArch: %{ix86}
- ghc9.10
ExcludeArch: armv7hl
- ghc9.2
ExcludeArch: armv7hl
- ghc9.4
ExcludeArch: armv7hl
- ghc9.6
ExcludeArch: armv7hl
- ghc9.8
ExcludeArch: armv7hl
- ghdl
ExclusiveArch: %{GNAT_arches}
ExcludeArch: armv7hl %{ix86}
- ghostwriter
ExclusiveArch: %{qt6_qtwebengine_arches}
- gimp-fourier-plugin
ExcludeArch: %{ix86}
- gio-sharp
ExclusiveArch: %mono_arches
- gir-to-d
ExclusiveArch: %{ldc_arches}
- git-lfs
ExcludeArch: %{ix86}
- git-octopus
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
- gitqlient
ExclusiveArch: %{qt5_qtwebengine_arches}
- giver
ExclusiveArch: %{mono_arches}
- gkeyfile-sharp
ExclusiveArch: %mono_arches
- gkrellm-wifi
ExcludeArch: s390 s390x
- glava
ExcludeArch: %{ix86}
- glibc32
ExclusiveArch: x86_64
- glibd
ExclusiveArch: %{ldc_arches}
- gloo
ExcludeArch: i686
- glycin-loaders
ExcludeArch: %{ix86}
- gmult
ExcludeArch: %{ix86}
- gn
ExcludeArch: %{ix86}
- gnatcoll
ExclusiveArch: %{GPRbuild_arches}
- gnatcoll-bindings
ExclusiveArch: %{GPRbuild_arches}
- gnatcoll-db
ExclusiveArch: %{GPRbuild_arches}
ExcludeArch: s390x
- gnofract4d
ExcludeArch: %{ix86}
- gnome-applets
ExcludeArch: %{ix86}
- gnome-bluetooth
ExcludeArch: s390 s390x
- gnome-bluetooth3.34
ExcludeArch: s390 s390x
- gnome-boxes
ExclusiveArch: x86_64
- gnome-chemistry-utils
ExcludeArch: %{ix86}
- gnome-desktop-sharp
ExclusiveArch: %mono_arches
- gnome-do
ExclusiveArch: %mono_arches
ExcludeArch: armv7hl
- gnome-flashback
ExcludeArch: %{ix86}
- gnome-hexgl
ExcludeArch: i686
- gnome-initial-setup
ExcludeArch: %{ix86}
- gnome-keyring-sharp
ExclusiveArch: %mono_arches
- gnome-monitor-config
ExcludeArch: %{ix86}
- gnome-panel
ExcludeArch: %{ix86}
- gnome-rdp
ExclusiveArch: %{mono_arches}
ExcludeArch: %{ix86}
- gnome-session
ExcludeArch: %{ix86}
- gnome-sharp
ExclusiveArch: %mono_arches
- gnome-shell
ExcludeArch: %{ix86}
- gnome-software
ExcludeArch: %{ix86}
- gnome-subtitles
ExclusiveArch: %mono_arches
- gnome-terminal
ExcludeArch: %{ix86}
- gnu-efi
ExclusiveArch: %{efi}
- gnucash
ExcludeArch: ppc64 s390x
- gnumeric
ExcludeArch: %{ix86}
- go-bindata
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
- godep
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
- godot
ExcludeArch: s390x
- godot3
ExcludeArch: ppc64 ppc64le s390x
- goffice
ExcludeArch: %{ix86}
- golang
ExclusiveArch: %{golang_arches}
- golang-entgo-ent
ExcludeArch: %{arm32} %{ix86}
- golang-github-ebitengine-purego
ExcludeArch: ppc64le s390x
- golang-github-elliotchance-orderedmap
ExcludeArch: aarch64
ExcludeArch: ppc64le
ExcludeArch: s390x
- golang-github-facebookincubator-nvdtools
ExcludeArch: i686 armv7hl
- golang-github-google-goterm
ExcludeArch: ppc64le s390x
- golang-helm-3
ExcludeArch: armv7hl aarch64
- golang-tinygo-x-llvm
ExcludeArch: %{ix86}
- goldendict-ng
ExclusiveArch: aarch64 x86_64
- google-compute-engine-guest-configs
ExcludeArch: %{ix86}
- google-cpu_features
ExcludeArch: s390x
- google-gson
ExclusiveArch: %{java_arches} noarch
- google-guest-agent
ExcludeArch: ppc64le
ExcludeArch: s390x
- google-guice
ExclusiveArch: %{java_arches} noarch
- google-osconfig-agent
ExcludeArch: ppc64le s390x
- gotcha
ExcludeArch: %{ix86}
- gotun
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
ExclusiveArch: x86_64
- gource
ExcludeArch: ppc64le
- goverlay
ExclusiveArch: %{fpc_arches}
- gpaste
ExcludeArch: %{ix86}
- gpaw
ExcludeArch: ppc64
ExcludeArch: %{ix86}
- gperftools
ExcludeArch: s390
- gprbuild
ExclusiveArch: %{GPRbuild_arches}
- gprolog
ExclusiveArch: x86_64 %{ix86} ppc alpha aarch64
- gr-air-modes
ExcludeArch: %{ix86}
- grafana
ExclusiveArch: %{grafana_arches}
- grafana-pcp
ExclusiveArch: %{grafanapcp_arches}
- greenboot
ExcludeArch: s390x
- gretl
ExcludeArch: %{ix86}
- gromacs
ExcludeArch: i686 armv7hl s390x
- grub-customizer
ExcludeArch: s390 s390x %{arm}
- grub2
ExcludeArch: s390 s390x %{ix86}
- grub2-breeze-theme
ExcludeArch: s390 s390x %{arm}
- grubby
ExcludeArch: %{ix86}
- gsequencer
ExcludeArch: i686
- gthree
ExcludeArch: i686
- gthumb
ExcludeArch: s390x
- gtk-sharp-beans
ExclusiveArch: %mono_arches
- gtk-sharp2
ExclusiveArch: %mono_arches
- gtk-sharp3
ExclusiveArch: %{mono_arches}
- gtkd
ExclusiveArch: %{ldc_arches}
- gtkhash
ExcludeArch: %{ix86}
- gtkwave
ExcludeArch: s390x
- guava
ExclusiveArch: %{java_arches} noarch
- gudev-sharp
ExclusiveArch: %mono_arches
- guestfs-tools
ExclusiveArch: %{kernel_arches}
ExcludeArch: %{power64}
- gvisor-tap-vsock
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- hamcrest
ExclusiveArch: %{java_arches} noarch
- harec
ExclusiveArch: x86_64 aarch64 riscv64
- harmonyseq
ExcludeArch: %{ix86}
- harvey
ExcludeArch: %{ix86}
- hashcat
ExcludeArch: ppc64 s390x
- hawtjni
ExclusiveArch: %{java_arches} noarch
- haxe
ExcludeArch: %{ix86}
- hcloud
ExcludeArch: %{ix86}
- heaptrack
ExcludeArch: s390 s390x
- hedgewars
ExclusiveArch: %{fpc_arches}
ExcludeArch: ppc64le
- hevea
ExcludeArch: %{ix86}
- hibernate-jpa-2.0-api
ExclusiveArch: %{java_arches} noarch
- hid4java
ExclusiveArch: %{java_arches} noarch
- highfive
ExcludeArch: %{ix86}
- hipblas
ExclusiveArch: x86_64
- hipcub
ExclusiveArch: x86_64
- hipfft
ExclusiveArch: x86_64
- hipify
ExclusiveArch: x86_64
- hiprand
ExclusiveArch: x86_64
- hipsolver
ExclusiveArch: x86_64
- hipsparse
ExclusiveArch: x86_64
- hmmer
ExcludeArch: aarch64 ppc64le s390x
- honggfuzz
ExcludeArch: %{arm} %{power64} s390 s390x
- howl
ExcludeArch: ppc64le s390x
ExcludeArch: %{ix86}
- hsakmt
ExclusiveArch: x86_64 aarch64 ppc64le
- httpcomponents-client
ExclusiveArch: %{java_arches} noarch
- httpcomponents-core
ExclusiveArch: %{java_arches} noarch
- httpcomponents-project
ExclusiveArch: %{java_arches} noarch
- hydrapaper
ExcludeArch: s390x
- hyena
ExclusiveArch: %{mono_arches}
- hyperhdr
ExcludeArch: %{ix86}
- hyperrogue
ExcludeArch: armv7hl
- hyperscan
ExclusiveArch: x86_64
- hyperv-daemons
ExclusiveArch: i686 x86_64 aarch64
- hyprcursor
ExcludeArch: %{ix86}
- hyprland
ExcludeArch: %{ix86}
- hyprlang
ExcludeArch: %{ix86}
- i2c-tools
ExcludeArch: s390 s390x
- ibsim
ExcludeArch: s390 %{arm}
- ibus-typing-booster
ExcludeArch: ppc64 s390x
- icecat
ExcludeArch: %{arm}
ExcludeArch: s390x
- icedtea-web
ExclusiveArch: %{java_arches}
- icu4j
ExclusiveArch: %{java_arches} noarch
- ignition
ExcludeArch: %{ix86}
- iir1
ExcludeArch: %{ix86}
- ilua
ExcludeArch: %{ix86}
- imagej
ExclusiveArch: %{java_arches} noarch
- imhex
ExclusiveArch: x86_64 %{arm64}
- iml
ExcludeArch: %{ix86}
- imvirt
ExclusiveArch: %{ix86} x86_64 ia64
- indistarter
ExclusiveArch: %{fpc_arches}
- infinipath-psm
ExclusiveArch: x86_64
- intel-cm-compiler
ExclusiveArch: i686 x86_64
- intel-cmt-cat
ExclusiveArch: x86_64
- intel-compute-runtime
ExclusiveArch: x86_64
- intel-gmmlib
ExcludeArch: s390x ppc64le
- intel-igc
ExclusiveArch: x86_64
- intel-ipp-crypto-mb
ExclusiveArch: x86_64
- intel-ipsec-mb
ExclusiveArch: x86_64
- intel-lpmd
ExclusiveArch: x86_64
- intel-media-driver-free
ExclusiveArch: i686 x86_64
- intel-mediasdk
ExclusiveArch: x86_64
- intel-metee
ExclusiveArch: x86_64
- intel-undervolt
ExclusiveArch: i386 x86_64
- ioport
ExclusiveArch: %{ix86} x86_64
- ipe
ExcludeArch: %{ix86}
- ipmctl
ExclusiveArch: x86_64
- irda-utils
ExcludeArch: s390 s390x
- irqbalance
ExcludeArch: s390 s390x
- isa-l
ExcludeArch: %{ix86}
- ispc
ExclusiveArch: x86_64 aarch64
- iucode-tool
ExclusiveArch: %{ix86} x86_64
- iyfct
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc64le
- jFormatString
ExclusiveArch: %{java_arches} noarch
- jack-mixer
ExcludeArch: armv7hl
ExcludeArch: i686
- jackson-annotations
ExclusiveArch: %{java_arches} noarch
- jackson-bom
ExclusiveArch: %{java_arches} noarch
- jackson-core
ExclusiveArch: %{java_arches} noarch
- jackson-databind
ExclusiveArch: %{java_arches} noarch
- jackson-jaxrs-providers
ExclusiveArch: %{java_arches} noarch
- jackson-modules-base
ExclusiveArch: %{java_arches} noarch
- jackson-parent
ExclusiveArch: %{java_arches} noarch
- jacoco
ExclusiveArch: %{java_arches} noarch
- jacop
ExclusiveArch: %{java_arches} noarch
- jakarta-activation
ExclusiveArch: %{java_arches} noarch
- jakarta-activation1
ExclusiveArch: %{java_arches} noarch
- jakarta-annotations
ExclusiveArch: %{java_arches} noarch
- jakarta-el
ExclusiveArch: %{java_arches} noarch
- jakarta-interceptors
ExclusiveArch: %{java_arches} noarch
- jakarta-json
ExclusiveArch: %{java_arches} noarch
- jakarta-mail
ExclusiveArch: %{java_arches} noarch
- jakarta-mail1
ExclusiveArch: %{java_arches} noarch
- jakarta-oro
ExclusiveArch: %{java_arches} noarch
- jakarta-saaj
ExclusiveArch: %{java_arches} noarch
- jakarta-server-pages
ExclusiveArch: %{java_arches} noarch
- jakarta-servlet
ExclusiveArch: %{java_arches} noarch
- jakarta-xml-ws
ExclusiveArch: %{java_arches} noarch
- janino
ExclusiveArch: %{java_arches} noarch
- jansi
ExclusiveArch: %{java_arches}
- jansi-native
ExclusiveArch: %{java_arches}
- jansi1
ExclusiveArch: %{java_arches} noarch
- java-1.8.0-openjdk
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-1.8.0-openjdk-portable
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-11-openjdk
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-11-openjdk-portable
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-17-openjdk
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-17-openjdk-portable
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-21-openjdk
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-21-openjdk-portable
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-diff-utils
ExclusiveArch: %{java_arches} noarch
- java-dirq
ExclusiveArch: %{java_arches} noarch
- java-jd-decompiler
ExclusiveArch: %{java_arches} noarch
- java-latest-openjdk
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-latest-openjdk-portable
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-runtime-decompiler
ExclusiveArch: %{java_arches} noarch
- java-scrypt
ExclusiveArch: %{java_arches} noarch
- java_cup
ExclusiveArch: %{java_arches} noarch
- javacc
ExclusiveArch: %{java_arches} noarch
- javacc-maven-plugin
ExclusiveArch: %{java_arches} noarch
- javaewah
ExclusiveArch: %{java_arches} noarch
- javapackages-bootstrap
ExclusiveArch: %{java_arches}
- javaparser
ExclusiveArch: %{java_arches} noarch
- javapoet
ExclusiveArch: %{java_arches} noarch
- javassist
ExclusiveArch: %{java_arches} noarch
- jaxb
ExclusiveArch: %{java_arches} noarch
- jaxb-api
ExclusiveArch: %{java_arches} noarch
- jaxb-api2
ExclusiveArch: %{java_arches} noarch
- jaxb-dtd-parser
ExclusiveArch: %{java_arches} noarch
- jaxb-fi
ExclusiveArch: %{java_arches} noarch
- jaxb-istack-commons
ExclusiveArch: %{java_arches} noarch
- jaxb-stax-ex
ExclusiveArch: %{java_arches} noarch
- jaxen
ExclusiveArch: %{java_arches} noarch
- jblas
ExcludeArch: %{ix86}
- jboss-jaxrs-2.0-api
ExclusiveArch: %{java_arches} noarch
- jboss-logging
ExclusiveArch: %{java_arches} noarch
- jboss-logging-tools
ExclusiveArch: %{java_arches} noarch
- jboss-parent
ExclusiveArch: %{java_arches} noarch
- jchardet
ExclusiveArch: %{java_arches} noarch
- jcip-annotations
ExclusiveArch: %{java_arches} noarch
- jctools
ExclusiveArch: %{java_arches} noarch
- jcuber
ExclusiveArch: %{java_arches} noarch
- jdeparser
ExclusiveArch: %{java_arches} noarch
- jdepend
ExclusiveArch: %{java_arches} noarch
- jdependency
ExclusiveArch: %{java_arches} noarch
- jdom
ExclusiveArch: %{java_arches} noarch
- jdom2
ExclusiveArch: %{java_arches} noarch
- jedit
ExclusiveArch: %{java_arches} noarch
- jericho-html
ExclusiveArch: %{java_arches} noarch
- jetbrains-annotations
ExclusiveArch: noarch %{java_arches}
- jetty
ExclusiveArch: %{java_arches} noarch
- jflex
ExclusiveArch: %{java_arches} noarch
- jfreechart
ExclusiveArch: %{java_arches} noarch
- jgit
ExclusiveArch: %{java_arches} noarch
- jglobus
ExclusiveArch: %{java_arches} noarch
- jgoodies-common
ExclusiveArch: %{java_arches} noarch
- jgoodies-forms
ExclusiveArch: %{java_arches} noarch
- jgoodies-looks
ExclusiveArch: %{java_arches} noarch
- jigawatts
ExclusiveArch: x86_64 %{arm} ppc64le aarch64 s390x
- jline
ExclusiveArch: %{java_arches}
- jline2
ExclusiveArch: %{java_arches} noarch
- jmock
ExclusiveArch: %{java_arches} noarch
- jmol
ExclusiveArch: %{java_arches} noarch
- jna
ExclusiveArch: %{java_arches}
- jneuroml-core
ExclusiveArch: %{java_arches} noarch
- jni-inchi
ExclusiveArch: %{java_arches}
- jo
ExcludeArch: %{ix86}
- jol
ExclusiveArch: %{java_arches} noarch
- jolokia-jvm-agent
ExclusiveArch: %{java_arches} noarch
- jopt-simple
ExclusiveArch: %{java_arches} noarch
- jorbis
ExclusiveArch: %{java_arches} noarch
- jowl
ExclusiveArch: %{nodejs_arches} noarch
- jpanoramamaker
ExclusiveArch: %{java_arches} noarch
- jpilot
ExcludeArch: s390, s390x
- jpilot-backup
ExcludeArch: s390 s390x
- jsch
ExclusiveArch: %{java_arches} noarch
- jsch-agent-proxy
ExclusiveArch: %{java_arches} noarch
- json_simple
ExclusiveArch: %{java_arches} noarch
- jsoup
ExclusiveArch: %{java_arches} noarch
- jsr-305
ExclusiveArch: %{java_arches} noarch
- jss
ExclusiveArch: %{java_arches}
ExcludeArch: i686
- jssc
ExclusiveArch: %{java_arches}
- jtidy
ExclusiveArch: %{java_arches} noarch
- julia
ExclusiveArch: x86_64
- junit
ExclusiveArch: %{java_arches} noarch
- junit5
ExclusiveArch: %{java_arches} noarch
- juniversalchardet
ExclusiveArch: %{java_arches} noarch
- jzlib
ExclusiveArch: %{java_arches} noarch
- kaffeine
ExcludeArch: %{ix86}
- kaidan
ExclusiveArch: %{qt5_qtwebengine_arches}
ExcludeArch: %{ix86}
- kata-containers
ExcludeArch: %{arm} %{ix86} s390 s390x
- kawa
ExcludeArch: i686
- kchmviewer
ExclusiveArch: %{qt5_qtwebengine_arches}
- kcm_wacomtablet
ExcludeArch: s390 s390x
- kcov
ExcludeArch: s390 s390x
- kdenlive
ExcludeArch: %{ix86}
- keepass
ExclusiveArch: %{mono_arches}
ExcludeArch: armv7hl
- keepassxc
ExcludeArch: s390x
- kernel
ExclusiveArch: noarch x86_64 s390x aarch64 ppc64le
ExclusiveArch: noarch i386 i686 x86_64 s390x aarch64 ppc64le
- kernelshark
ExcludeArch: %{ix86} %{arm}
- keydb
ExcludeArch: %{ix86}
- keylime-agent-rust
ExclusiveArch: %{rust_arches}
- keyring-ima-signer
ExclusiveArch: %{rust_arches}
- kf5-akonadi-search
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-kblog
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-kcalendarcore
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-kcalendarutils
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-kitinerary
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-ktnef
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-libkdcraw
ExclusiveArch: x86_64 ppc64le %{arm}
- khelpcenter
ExclusiveArch: %{qt6_qtwebengine_arches}
- kicad
ExclusiveArch: x86_64 aarch64 ppc64le
- kissat
ExcludeArch: %{ix86}
- kitty
ExcludeArch: %{ix86}
- kiwix-desktop
ExclusiveArch: %{qt5_qtwebengine_arches}
- knot-resolver
ExclusiveArch: %{ix86} x86_64
ExclusiveArch: %{arm} aarch64 %{ix86} x86_64
- kokkos
ExcludeArch: i686 armv7hl
- komikku
ExcludeArch: s390x
- kpilot
ExcludeArch: s390 s390x
- krita
ExcludeArch: %{ix86}
- ksensors
ExcludeArch: s390 s390x
- kubernetes
ExclusiveArch: x86_64 aarch64 ppc64le s390x %{arm}
- ladspa-autotalent-plugins
ExcludeArch: %{ix86}
- laf-plugin
ExclusiveArch: %{java_arches} noarch
- latte-integrale
ExcludeArch: %{ix86}
- lazarus
ExclusiveArch: %{fpc_arches}
- lazpaint
ExclusiveArch: %{fpc_arches}
- lcd4linux
ExcludeArch: s390 s390x
- ldapjdk
ExclusiveArch: %{java_arches} noarch
- ldc
ExclusiveArch: %{ldc_arches} ppc64le
- ledmon
ExcludeArch: %{ix86}
- leland-fonts
ExcludeArch: %{ix86}
- lfortran
ExclusiveArch: x86_64
- lfsc
ExcludeArch: %{ix86}
- lib3mf
ExcludeArch: %{ix86}
- libCombine
ExcludeArch: %{ix86}
- libaiff
ExcludeArch: %{ix86}
- libarcus
ExcludeArch: %{ix86}
- libarrow
ExcludeArch: %{ix86} %{arm}
- libavc1394
ExcludeArch: s390 s390x
- libbase
ExclusiveArch: %{java_arches} noarch
- libcamera
ExcludeArch: s390x ppc64le
- libcamera-apps
ExcludeArch: %{power64} s390x
- libcint
ExcludeArch: %{power64}
- libcircle
ExcludeArch: %{ix86}
- libcpuid
ExcludeArch: aarch64 %arm ppc64le ppc64 s390x
- libcrystalhd
ExcludeArch: s390 s390x
- libcxl
ExclusiveArch: %{power64}
- libcxx
ExcludeArch: ppc64 ppc64le
- libdc1394
ExcludeArch: s390 s390x
- libdfp
ExclusiveArch: ppc ppc64 ppc64le s390 s390x x86_64
- libdigidocpp
ExcludeArch: %{ix86}
- libdispatch
ExclusiveArch: x86_64 aarch64 ppc64le
- libffado
ExcludeArch: s390 s390x
- libfilezilla
ExcludeArch: s390x
- libfonts
ExclusiveArch: %{java_arches} noarch
- libformula
ExclusiveArch: %{java_arches} noarch
- libfprint
ExcludeArch: s390 s390x
- libguestfs
ExcludeArch: %{ix86}
ExclusiveArch: %{kernel_arches}
ExcludeArch: %{power64}
- libhomfly
ExcludeArch: %{ix86}
- libibcommon
ExcludeArch: s390 s390x
- libica
ExclusiveArch: s390 s390x
- libiec61883
ExcludeArch: s390 s390x
- libinsane
ExcludeArch: %{ix86}
- libipt
ExclusiveArch: %{ix86} x86_64
ExclusiveArch: %{ix86} x86_64
- libkrun
ExclusiveArch: x86_64 aarch64
- libkrunfw
ExclusiveArch: x86_64 aarch64
- liblayout
ExclusiveArch: %{java_arches} noarch
- libldac
ExcludeArch: s390x
- libloader
ExclusiveArch: %{java_arches} noarch
- libnuml
ExcludeArch: %{ix86}
- libnxz
ExclusiveArch: ppc64le
- libobjc2
ExcludeArch: armv7hl i686 ppc64le s390x
- libocxl
ExclusiveArch: ppc64le
- libopenshot
ExcludeArch: ppc64le
- libopenshot-audio
ExcludeArch: ppc64le
- liborc
ExcludeArch: i686 armv7hl
- libpoly
ExcludeArch: %{ix86}
- libpsm2
ExclusiveArch: x86_64
- libquentier
ExclusiveArch: %{qt5_qtwebengine_arches}
- libraw1394
ExcludeArch: s390 s390x
- libreoffice
ExcludeArch: %{ix86}
- libreoffice-TexMaths
ExclusiveArch: %{java_arches}
ExcludeArch: aarch64 s390x
- librepository
ExclusiveArch: %{java_arches} noarch
- libretro-desmume2015
ExclusiveArch: i686 x86_64
- libretro-pcsx-rearmed
ExcludeArch: armv7hl
- librtas
ExclusiveArch: %{power64}
- libsavitar
ExcludeArch: %{ix86}
- libsedml
ExcludeArch: %{ix86}
- libsemigroups
ExcludeArch: %{ix86}
- libserializer
ExclusiveArch: %{java_arches} noarch
- libservicelog
ExclusiveArch: ppc %{power64}
- libsmbios
ExclusiveArch: x86_64 %{ix86}
- libsonata
ExcludeArch: %{ix86}
- libtracecmd
ExcludeArch: %{ix86} %{arm}
- libunibreak
ExcludeArch: %{ix86}
- libunicode
ExclusiveArch: x86_64 aarch64
- libunifex
ExcludeArch: i686
- libunwind
ExclusiveArch: %{arm} aarch64 hppa ia64 mips ppc %{power64} s390x %{ix86} x86_64 riscv64
- libva-intel-hybrid-driver
ExclusiveArch: %{ix86} x86_64 ia64
- libva-nvidia-driver
ExclusiveArch: %{x86_64} %{ix86} %{arm64} ppc64le
- libvirt-java
ExclusiveArch: %{java_arches} noarch
- libvma
ExclusiveArch: x86_64 ppc64le ppc64 aarch64
- libvmi
ExclusiveArch: x86_64
- libvpd
ExclusiveArch: %{power64}
- libvpl
ExclusiveArch: x86_64
- libx86
ExcludeArch: ppc %{power64} s390 s390x %{sparc} aarch64 armv7hl
- libxsmm
ExclusiveArch: x86_64
- libzdnn
ExclusiveArch: s390x
- libzfcphbaapi
ExclusiveArch: s390 s390x
- libzpc
ExclusiveArch: s390x
- liferea
ExcludeArch: %{ix86}
- linbox
ExcludeArch: %{ix86}
- linux-system-roles
ExcludeArch: i686
- liquidctl
ExcludeArch: s390 s390x
- lite-xl
ExcludeArch: %{ix86}
- llama-cpp
ExclusiveArch: x86_64 aarch64
- lld13
ExcludeArch: s390x
- lld15
ExcludeArch: s390x
- lld16
ExcludeArch: s390x
- lld17
ExcludeArch: s390x
- llhttp
ExclusiveArch: %{nodejs_arches}
- llvm-bolt
ExcludeArch: s390x ppc64le i686
- log4j
ExclusiveArch: %{java_arches} noarch
- log4net
ExclusiveArch: %mono_arches
- loupe
ExcludeArch: %{ix86}
- love
ExcludeArch: ppc ppc64 s390x
- lrmi
ExclusiveArch: %{ix86}
- lsvpd
ExclusiveArch: %{power64}
- luajit
ExcludeArch: riscv64 ppc64 ppc64le
- lucene
ExclusiveArch: %{java_arches} noarch
- luckybackup
ExcludeArch: %{ix86}
- lujavrite
ExclusiveArch: %{java_arches}
- luminance-hdr
ExcludeArch: %{ix86}
- lusol
ExcludeArch: %{ix86}
- luxcorerender
ExclusiveArch: x86_64
- lzfse
ExcludeArch: s390x
- m4rie
ExcludeArch: %{ix86}
- mactel-boot
ExclusiveArch: x86_64
- magicmirror
ExclusiveArch: %{nodejs_arches} noarch
- magicmirror-module-airnow
ExclusiveArch: %{nodejs_arches} noarch
- magicmirror-module-onthisday
ExclusiveArch: %{nodejs_arches} noarch
- magicmirror-module-singlestock
ExclusiveArch: %{nodejs_arches} noarch
- makemusic-finale-fonts
ExcludeArch: %{ix86}
- mame
ExcludeArch: %{arm} %{ix86}
- manifest-tool
ExclusiveArch: x86_64 aarch64 ppc64le s390x
- mapnik
ExcludeArch: ppc ppc64 s390 s390x
- marcsabatella-campania-fonts
ExcludeArch: %{ix86}
- mariadb-java-client
ExclusiveArch: %{java_arches} noarch
- marked
ExclusiveArch: %{nodejs_arches} noarch
ExclusiveArch: %{ix86} x86_64 %{arm} noarch
- mate-applets
ExcludeArch: i386 i686
- matrix-synapse
ExclusiveArch: %{rust_arches}
- maui-mauikit
ExclusiveArch: %{ix86} s390x aarch64 x86_64
- maven
ExclusiveArch: %{java_arches} noarch
- maven-antrun-plugin
ExclusiveArch: %{java_arches} noarch
- maven-archetype
ExclusiveArch: %{java_arches} noarch
- maven-archiver
ExclusiveArch: %{java_arches} noarch
- maven-artifact-transfer
ExclusiveArch: %{java_arches} noarch
- maven-assembly-plugin
ExclusiveArch: %{java_arches} noarch
- maven-bundle-plugin
ExclusiveArch: %{java_arches} noarch
- maven-clean-plugin
ExclusiveArch: %{java_arches} noarch
- maven-common-artifact-filters
ExclusiveArch: %{java_arches} noarch
- maven-compiler-plugin
ExclusiveArch: %{java_arches} noarch
- maven-dependency-analyzer
ExclusiveArch: %{java_arches} noarch
- maven-dependency-plugin
ExclusiveArch: %{java_arches} noarch
- maven-dependency-tree
ExclusiveArch: %{java_arches} noarch
- maven-doxia
ExclusiveArch: %{java_arches} noarch
- maven-doxia-sitetools
ExclusiveArch: %{java_arches} noarch
- maven-enforcer
ExclusiveArch: %{java_arches} noarch
- maven-file-management
ExclusiveArch: %{java_arches} noarch
- maven-filtering
ExclusiveArch: %{java_arches} noarch
- maven-invoker
ExclusiveArch: %{java_arches} noarch
- maven-invoker-plugin
ExclusiveArch: %{java_arches} noarch
- maven-jar-plugin
ExclusiveArch: %{java_arches} noarch
- maven-mapping
ExclusiveArch: %{java_arches} noarch
- maven-native
ExclusiveArch: %{java_arches} noarch
- maven-parent
ExclusiveArch: %{java_arches} noarch
- maven-patch-plugin
ExclusiveArch: %{java_arches} noarch
- maven-plugin-testing
ExclusiveArch: %{java_arches} noarch
- maven-plugin-tools
ExclusiveArch: %{java_arches} noarch
- maven-remote-resources-plugin
ExclusiveArch: %{java_arches} noarch
- maven-reporting-api
ExclusiveArch: %{java_arches} noarch
- maven-reporting-impl
ExclusiveArch: %{java_arches} noarch
- maven-resolver
ExclusiveArch: %{java_arches} noarch
- maven-resources-plugin
ExclusiveArch: %{java_arches} noarch
- maven-script-interpreter
ExclusiveArch: %{java_arches} noarch
- maven-shade-plugin
ExclusiveArch: %{java_arches} noarch
- maven-shared-incremental
ExclusiveArch: %{java_arches} noarch
- maven-shared-io
ExclusiveArch: %{java_arches} noarch
- maven-shared-utils
ExclusiveArch: %{java_arches} noarch
- maven-source-plugin
ExclusiveArch: %{java_arches} noarch
- maven-surefire
ExclusiveArch: %{java_arches} noarch
- maven-verifier
ExclusiveArch: %{java_arches} noarch
- maven-verifier-plugin
ExclusiveArch: %{java_arches} noarch
- maven-wagon
ExclusiveArch: %{java_arches} noarch
- maxima
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc sparcv9
ExclusiveArch: %{ix86} x86_64 ppc sparcv9
- mbpfan
ExclusiveArch: x86_64
- mcelog
ExclusiveArch: i686 x86_64
- mcqd
ExcludeArch: %{ix86}
- mcrouter
ExclusiveArch: x86_64 aarch64 ppc64le
- mecab-java
ExclusiveArch: %java_arches
- mediaconch
ExclusiveArch: %{qt5_qtwebengine_arches}
- mellowplayer
ExclusiveArch: %{qt5_qtwebengine_arches}
- memkind
ExclusiveArch: x86_64 ppc64 ppc64le s390x aarch64
- memtest86+
ExclusiveArch: x86_64 %{ix86}
- merkuro
ExclusiveArch: %{qt6_qtwebengine_arches}
- meshlab
ExclusiveArch: aarch64 x86_64
ExcludeArch: %{ix86}
- metamath
ExcludeArch: %{ix86}
- mfem
ExcludeArch: %{ix86}
- microcode_ctl
ExclusiveArch: %{ix86} x86_64
- micropython
ExclusiveArch: %{arm} x86_64 riscv64
- miglayout
ExclusiveArch: %{java_arches} noarch
- mine_detector
ExclusiveArch: %{GPRbuild_arches}
- minetest
ExclusiveArch: %{ix86} x86_64
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips} aarch64
- mingw-libidn2
ExclusiveArch: %{ix86} x86_64 %{arm}
- mingw-qt6-qtlocation
ExcludeArch: s390x
- mingw-wine-gecko
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64
- miopen
ExclusiveArch: x86_64
- mirrormanager2
ExcludeArch: %{ix86}
- mkbootdisk
ExclusiveArch: %{ix86} sparc sparc64 x86_64
- mlir
ExcludeArch: i686
- mlpack
ExcludeArch: s390
- mmapper
ExcludeArch: %{ix86}
- mmlib
ExcludeArch: %{ix86}
- moby-engine
ExclusiveArch: %{golang_arches}
- mockito
ExclusiveArch: %{java_arches} noarch
- mod_gnutls
ExcludeArch: %{ix86} %{arm}
- mod_mono
ExclusiveArch: %mono_arches
- mod_proxy_cluster
ExcludeArch: i686 i386
- modello
ExclusiveArch: %{java_arches} noarch
- moditect
ExclusiveArch: %{java_arches} noarch
- module-build-service
ExclusiveArch: %{ix86} x86_64 noarch
- modulemaker-maven-plugin
ExclusiveArch: %{java_arches} noarch
- mojo-executor
ExclusiveArch: %{java_arches} noarch
- mojo-parent
ExclusiveArch: %{java_arches} noarch
- mokutil
ExclusiveArch: %{ix86} x86_64 aarch64 %{arm}
- mold
ExcludeArch: %{ix86}
- mono
ExclusiveArch: %mono_arches
- mono-addins
ExclusiveArch: %mono_arches
- mono-basic
ExclusiveArch: %{mono_arches}
- mono-bouncycastle
ExclusiveArch: %mono_arches
ExcludeArch: armv7hl
- mono-cecil
ExclusiveArch: %mono_arches
- mono-cecil-flowanalysis
ExclusiveArch: %mono_arches
- mono-reflection
ExclusiveArch: %mono_arches
- mono-tools
ExclusiveArch: %mono_arches
- mono-zeroconf
ExclusiveArch: %mono_arches
- monodevelop
ExclusiveArch: %mono_arches
ExcludeArch: armv7hl
- monodevelop-debugger-gdb
ExclusiveArch: %{mono_arches}
ExcludeArch: armv7hl
- moose
ExcludeArch: s390x
- morphio
ExcludeArch: %{ix86}
- mozc
ExcludeArch: ppc ppc64 sparcv9 sparc64 s390x
- mozilla-ublock-origin
ExcludeArch: ppc64 s390x
- mp
ExcludeArch: %{ix86}
- mpark-patterns
ExcludeArch: %{ix86}
- mpi4py
ExcludeArch: %{ix86}
- mpibash
ExcludeArch: %{ix86}
- mpris-scrobbler
ExcludeArch: s390x
- mpsolve
ExcludeArch: %{ix86}
- mrchem
ExcludeArch: s390x
- mrcpp
ExcludeArch: s390x
- mrrescue
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc64le
- msolve
ExcludeArch: %{ix86}
- msr-tools
ExclusiveArch: %{ix86} x86_64
- mstflint
ExcludeArch: s390 s390x %{arm}
- msv
ExclusiveArch: %{java_arches} noarch
- mt32emu
ExcludeArch: %{ix86}
- muffin
ExcludeArch: %{ix86}
- mumble
ExcludeArch: %{ix86}
- mupen64plus
ExcludeArch: s390x
- musescore
ExcludeArch: %{ix86}
- musl
ExcludeArch: s390
- mvfst
ExclusiveArch: x86_64 aarch64 ppc64le
- mxparser
ExclusiveArch: %{java_arches} noarch
- mysql-connector-java
ExclusiveArch: %{java_arches} noarch
- mysql-connector-net
ExclusiveArch: %{mono_arches}
- naev
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips} aarch64
ExcludeArch: %{ix86}
- naga
ExclusiveArch: %{java_arches} noarch
- nagios-plugins-check-updates
ExcludeArch: %{ix86}
- nant
ExclusiveArch: %mono_arches
ExcludeArch: armv7hl
- nativejit
ExclusiveArch: x86_64
- nbc
ExclusiveArch: %{fpc_arches}
- nbdkit
ExcludeArch: i686
- ncl
ExcludeArch: %{ix86}
- ndesk-dbus
ExclusiveArch: %{mono_arches}
- ndesk-dbus-glib
ExclusiveArch: %{mono_arches}
- nekohtml
ExclusiveArch: %{java_arches} noarch
- nemo
ExcludeArch: %{ix86}
- nemo-extensions
ExcludeArch: %{ix86}
- nest
ExcludeArch: %{ix86}
- netatalk
ExcludeArch: aarch64 s390x
- netavark
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- netcdf-fortran
ExcludeArch: %{ix86}
- netdata
ExcludeArch: s390x
- neuron
ExcludeArch: mips64r2 mips32r2
ExcludeArch: %{ix86}
- newtonsoft-json
ExclusiveArch: %{mono_arches}
ExcludeArch: armv7hl
- nextcloud-client
ExcludeArch: %{ix86}
ExcludeArch: ppc64 ppc64le s390x
- nodejs-acorn-object-spread
ExclusiveArch: %{nodejs_arches} noarch
ExclusiveArch: %{ix86} x86_64 %{arm} noarch
- nodejs-backbone
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-bash-language-server
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-buble
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-cjs-module-lexer
ExclusiveArch: %{nodejs_arches} noarch
ExclusiveArch: %{ix86} x86_64 aarch64 ppc64le riscv64 noarch
- nodejs-colors
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-less
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-linefix
ExclusiveArch: %{nodejs_arches} noarch
ExclusiveArch: %{ix86} x86_64 %{arm} noarch
- nodejs-nodemon
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-packaging
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-replace-require-self
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-underscore
ExclusiveArch: %{nodejs_arches} noarch
ExclusiveArch: %{ix86} x86_64 %{arm} noarch
- nodejs-undici
ExclusiveArch: %{ix86} x86_64 aarch64 ppc64le riscv64 noarch
- nodejs18
ExclusiveArch: %{nodejs_arches}
- nodejs20
ExclusiveArch: %{nodejs_arches}
- nom-tam-fits
ExclusiveArch: %{java_arches} noarch
- normaliz
ExcludeArch: %{ix86}
- not-ocamlfind
ExcludeArch: %{ix86}
- notejot
ExcludeArch: %{ix86}
- notify-sharp
ExclusiveArch: %{mono_arches}
- notify-sharp3
ExclusiveArch: %{mono_arches}
- ntfs2btrfs
ExcludeArch: ppc64 s390x
- nuget
ExclusiveArch: %{mono_arches}
- numactl
ExcludeArch: s390 %{arm}
- numatop
ExclusiveArch: x86_64 ppc64le
- numptyphysics
ExcludeArch: ppc64le
- nunit
ExclusiveArch: %{mono_arches}
- nunit2
ExclusiveArch: %{mono_arches}
ExcludeArch: armv7hl
- nut
ExcludeArch: s390 s390x
- nvml
ExclusiveArch: x86_64 ppc64le
- nwchem
ExcludeArch: %{ix86} s390x
ExcludeArch: s390x
- objectweb-asm
ExclusiveArch: %{java_arches} noarch
- objenesis
ExclusiveArch: %{java_arches} noarch
- obs-cef
ExclusiveArch: x86_64 aarch64
- obs-service-rust2rpm
ExclusiveArch: %{rust_arches} noarch
- obs-studio-plugin-vkcapture
ExcludeArch: s390x
- ocaml
ExcludeArch: %{ix86}
- ocaml-SDL
ExcludeArch: %{ix86}
- ocaml-alcotest
ExcludeArch: %{ix86}
- ocaml-astring
ExcludeArch: %{ix86}
- ocaml-atd
ExcludeArch: %{ix86}
- ocaml-augeas
ExcludeArch: %{ix86}
- ocaml-autoconf
ExcludeArch: %{ix86}
- ocaml-base
ExcludeArch: %{ix86}
- ocaml-base64
ExcludeArch: %{ix86}
- ocaml-benchmark
ExcludeArch: %{ix86}
- ocaml-bigarray-compat
ExcludeArch: %{ix86}
- ocaml-bin-prot
ExcludeArch: %{ix86}
- ocaml-biniou
ExcludeArch: %{ix86}
- ocaml-bisect-ppx
ExcludeArch: %{ix86}
- ocaml-bos
ExcludeArch: %{ix86}
- ocaml-cairo
ExcludeArch: %{ix86}
- ocaml-calendar
ExcludeArch: %{ix86}
- ocaml-camlbz2
ExcludeArch: %{ix86}
- ocaml-camlidl
ExcludeArch: %{ix86}
- ocaml-camlimages
ExcludeArch: %{ix86}
- ocaml-camlp-streams
ExcludeArch: %{ix86}
- ocaml-camlp5
ExcludeArch: %{ix86}
- ocaml-camlp5-buildscripts
ExcludeArch: %{ix86}
- ocaml-camomile
ExcludeArch: %{ix86}
- ocaml-cinaps
ExcludeArch: %{ix86}
- ocaml-cmdliner
ExcludeArch: %{ix86}
- ocaml-compiler-libs-janestreet
ExcludeArch: %{ix86}
- ocaml-cppo
ExcludeArch: %{ix86}
- ocaml-crunch
ExcludeArch: %{ix86}
- ocaml-cryptokit
ExcludeArch: %{ix86}
- ocaml-csexp
ExcludeArch: %{ix86}
- ocaml-csv
ExcludeArch: %{ix86}
- ocaml-ctypes
ExcludeArch: %{ix86}
- ocaml-cudf
ExcludeArch: %{ix86}
- ocaml-curl
ExcludeArch: %{ix86}
- ocaml-curses
ExcludeArch: %{ix86}
- ocaml-dbus
ExcludeArch: %{ix86}
- ocaml-dose3
ExcludeArch: %{ix86}
- ocaml-dune
ExcludeArch: %{ix86}
- ocaml-easy-format
ExcludeArch: %{ix86}
- ocaml-expat
ExcludeArch: %{ix86}
- ocaml-extlib
ExcludeArch: %{ix86}
- ocaml-facile
ExcludeArch: %{ix86}
- ocaml-fieldslib
ExcludeArch: %{ix86}
- ocaml-fileutils
ExcludeArch: %{ix86}
- ocaml-findlib
ExcludeArch: %{ix86}
- ocaml-fmt
ExcludeArch: %{ix86}
- ocaml-fpath
ExcludeArch: %{ix86}
- ocaml-gen
ExcludeArch: %{ix86}
- ocaml-gettext
ExcludeArch: %{ix86}
- ocaml-graphics
ExcludeArch: %{ix86}
- ocaml-gsl
ExcludeArch: %{ix86}
ExcludeArch: armv7hl
- ocaml-integers
ExcludeArch: %{ix86}
- ocaml-jane-street-headers
ExcludeArch: %{ix86}
- ocaml-jst-config
ExcludeArch: %{ix86}
- ocaml-lablgl
ExcludeArch: %{ix86}
- ocaml-lablgtk
ExcludeArch: %{ix86}
- ocaml-lablgtk3
ExcludeArch: %{ix86}
- ocaml-labltk
ExcludeArch: %{ix86}
- ocaml-lacaml
ExcludeArch: %{ix86}
- ocaml-lambda-term
ExcludeArch: %{ix86}
- ocaml-libvirt
ExcludeArch: %{ix86}
- ocaml-logs
ExcludeArch: %{ix86}
- ocaml-luv
ExcludeArch: %{ix86}
- ocaml-lwt
ExcludeArch: %{ix86}
- ocaml-markup
ExcludeArch: %{ix86}
- ocaml-mccs
ExcludeArch: %{ix86}
- ocaml-mdx
ExcludeArch: %{ix86}
- ocaml-menhir
ExcludeArch: %{ix86}
- ocaml-merlin
ExcludeArch: %{ix86}
- ocaml-mew
ExcludeArch: %{ix86}
- ocaml-mew-vi
ExcludeArch: %{ix86}
- ocaml-mlgmpidl
ExcludeArch: %{ix86}
- ocaml-mlmpfr
ExcludeArch: %{ix86}
- ocaml-mtime
ExcludeArch: %{ix86}
- ocaml-mysql
ExcludeArch: %{ix86}
- ocaml-num
ExcludeArch: %{ix86}
- ocaml-obuild
ExcludeArch: %{ix86}
- ocaml-ocamlbuild
ExcludeArch: %{ix86}
- ocaml-ocamlgraph
ExcludeArch: %{ix86}
- ocaml-ocamlnet
ExcludeArch: %{ix86}
- ocaml-ocp-indent
ExcludeArch: %{ix86}
- ocaml-ocplib-endian
ExcludeArch: %{ix86}
- ocaml-ocplib-simplex
ExcludeArch: %{ix86}
- ocaml-octavius
ExcludeArch: %{ix86}
- ocaml-odoc
ExcludeArch: %{ix86}
- ocaml-omake
ExcludeArch: %{ix86}
- ocaml-opam-file-format
ExcludeArch: %{ix86}
- ocaml-ounit
ExcludeArch: %{ix86}
- ocaml-parmap
ExcludeArch: %{ix86}
- ocaml-parsexp
ExcludeArch: %{ix86}
- ocaml-pcre
ExcludeArch: %{ix86}
- ocaml-pcre2
ExcludeArch: %{ix86}
- ocaml-perl4caml
ExcludeArch: %{ix86}
- ocaml-postgresql
ExcludeArch: %{ix86}
- ocaml-pp
ExcludeArch: %{ix86}
- ocaml-ppx-assert
ExcludeArch: %{ix86}
- ocaml-ppx-base
ExcludeArch: %{ix86}
- ocaml-ppx-cold
ExcludeArch: %{ix86}
- ocaml-ppx-compare
ExcludeArch: %{ix86}
- ocaml-ppx-custom-printf
ExcludeArch: %{ix86}
- ocaml-ppx-derivers
ExcludeArch: %{ix86}
- ocaml-ppx-deriving
ExcludeArch: %{ix86}
- ocaml-ppx-deriving-yaml
ExcludeArch: %{ix86}
- ocaml-ppx-deriving-yojson
ExcludeArch: %{ix86}
- ocaml-ppx-enumerate
ExcludeArch: %{ix86}
- ocaml-ppx-expect
ExcludeArch: %{ix86}
- ocaml-ppx-fields-conv
ExcludeArch: %{ix86}
- ocaml-ppx-globalize
ExcludeArch: %{ix86}
- ocaml-ppx-hash
ExcludeArch: %{ix86}
- ocaml-ppx-here
ExcludeArch: %{ix86}
- ocaml-ppx-import
ExcludeArch: %{ix86}
- ocaml-ppx-inline-test
ExcludeArch: %{ix86}
- ocaml-ppx-js-style
ExcludeArch: %{ix86}
- ocaml-ppx-let
ExcludeArch: %{ix86}
- ocaml-ppx-optcomp
ExcludeArch: %{ix86}
- ocaml-ppx-sexp-conv
ExcludeArch: %{ix86}
- ocaml-ppx-stable-witness
ExcludeArch: %{ix86}
- ocaml-ppx-variants-conv
ExcludeArch: %{ix86}
- ocaml-ppxlib
ExcludeArch: %{ix86}
- ocaml-psmt2-frontend
ExcludeArch: %{ix86}
- ocaml-ptime
ExcludeArch: %{ix86}
- ocaml-ptmap
ExcludeArch: %{ix86}
- ocaml-pyml
ExcludeArch: %{ix86}
- ocaml-qcheck
ExcludeArch: %{ix86}
- ocaml-qtest
ExcludeArch: %{ix86}
- ocaml-re
ExcludeArch: %{ix86}
- ocaml-react
ExcludeArch: %{ix86}
- ocaml-res
ExcludeArch: %{ix86}
- ocaml-result
ExcludeArch: %{ix86}
- ocaml-rresult
ExcludeArch: %{ix86}
- ocaml-sedlex
ExcludeArch: %{ix86}
- ocaml-sexplib
ExcludeArch: %{ix86}
- ocaml-sexplib0
ExcludeArch: %{ix86}
- ocaml-sha
ExcludeArch: %{ix86}
- ocaml-sqlite
ExcludeArch: %{ix86}
- ocaml-ssl
ExcludeArch: %{ix86}
- ocaml-stdcompat
ExcludeArch: %{ix86}
- ocaml-stdio
ExcludeArch: %{ix86}
- ocaml-stdlib-random
ExcludeArch: %{ix86}
- ocaml-time-now
ExcludeArch: %{ix86}
- ocaml-topkg
ExcludeArch: %{ix86}
- ocaml-trie
ExcludeArch: %{ix86}
- ocaml-tyxml
ExcludeArch: %{ix86}
- ocaml-unionfind
ExcludeArch: %{ix86}
- ocaml-uucd
ExcludeArch: %{ix86}
- ocaml-uucp
ExcludeArch: %{ix86}
- ocaml-uunf
ExcludeArch: %{ix86}
- ocaml-uuseg
ExcludeArch: %{ix86}
- ocaml-uutf
ExcludeArch: %{ix86}
- ocaml-variantslib
ExcludeArch: %{ix86}
- ocaml-version
ExcludeArch: %{ix86}
- ocaml-xml-light
ExcludeArch: %{ix86}
- ocaml-xmlm
ExcludeArch: %{ix86}
- ocaml-xmlrpc-light
ExcludeArch: %{ix86}
- ocaml-yaml
ExcludeArch: %{ix86}
- ocaml-yojson
ExcludeArch: %{ix86}
- ocaml-zarith
ExcludeArch: %{ix86}
- ocaml-zed
ExcludeArch: %{ix86}
- ocaml-zip
ExcludeArch: %{ix86}
- ocaml-zmq
ExcludeArch: %{ix86}
- ocamlify
ExcludeArch: %{ix86}
- ocamlmod
ExcludeArch: %{ix86}
- oci-seccomp-bpf-hook
ExclusiveArch: x86_64 %{power64} aarch64 s390x armv7hl
ExclusiveArch: %{golang_arches_future}
- ocrmypdf
ExcludeArch: %{ix86}
- octave-communications
ExcludeArch: s390x
- octave-iso2mesh
ExcludeArch: armv7hl
- octave-signal
ExcludeArch: s390x
- odio-sacd
ExcludeArch: ppc64le
- oidc-agent
ExcludeArch: %{ix86}
- oidn
ExclusiveArch: x86_64
- oneVPL
ExclusiveArch: x86_64
- oneVPL-intel-gpu
ExclusiveArch: x86_64
- oneapi-level-zero
ExclusiveArch: x86_64
- onednn
ExclusiveArch: x86_64 aarch64 ppc64le s390x
- onedrive
ExclusiveArch: %{ldc_arches}
- ongres-scram
ExclusiveArch: %{java_arches} noarch
- ongres-stringprep
ExclusiveArch: %{java_arches} noarch
- onnx
ExcludeArch: s390x
- onnxruntime
ExcludeArch: s390x %{arm} %{ix86}
- oomd
ExcludeArch: i686 armv7hl
- opae
ExclusiveArch: x86_64
- opal-prd
ExclusiveArch: ppc64le
- opam
ExcludeArch: %{ix86}
- open-vm-tools
ExclusiveArch: x86_64 aarch64
ExclusiveArch: %{ix86} x86_64 aarch64
ExclusiveArch: x86_64
- openblas
ExclusiveArch: %{openblas_arches}
- opencsg
ExcludeArch: %{ix86}
- opengrm-ngram
ExcludeArch: %{ix86}
- openjdk-asmtools
ExclusiveArch: %{java_arches} noarch
- openjdk-asmtools7
ExclusiveArch: %{java_arches} noarch
- openjfx
ExclusiveArch: %{java_arches}
- openjfx8
ExclusiveArch: x86_64
- openlibm
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 %{power64}
- openmeeg
ExcludeArch: s390x
- openmpi
ExcludeArch: %{ix86}
- openms
ExclusiveArch: %{qt5_qtwebengine_arches}
ExcludeArch: %{ix86}
- openni
ExclusiveArch: x86_64 %{arm}
- openni-primesense
ExclusiveArch: x86_64 %{arm}
- openobex
ExcludeArch: s390 s390x
- openoffice.org-diafilter
ExclusiveArch: %{java_arches}
- openpgl
ExclusiveArch: aarch64 x86_64
- openrgb
ExcludeArch: %{ix86}
- openscad
ExcludeArch: %{ix86}
- openshadinglanguage
ExcludeArch: %{ix86} %{arm}
- openshot
ExcludeArch: ppc64le
- opensm
ExcludeArch: s390 %{arm}
- openssl-ibmca
ExclusiveArch: s390 s390x
- openstack-java-sdk
ExclusiveArch: %{java_arches} noarch
- opentest4j
ExclusiveArch: %{java_arches} noarch
- opentype-sanitizer
ExcludeArch: %{ix86}
- openvdb
ExcludeArch: i686
- openvkl
ExclusiveArch: aarch64 x86_64
- optee_client
ExclusiveArch: aarch64
- optee_os
ExclusiveArch: aarch64
- options
ExclusiveArch: %{java_arches} noarch
- orthorobot
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc64le
- os-autoinst
ExcludeArch: %{arm}
- osbuild-composer
ExcludeArch: i686 armv7hl
- osgi-annotation
ExclusiveArch: %{java_arches} noarch
- osgi-compendium
ExclusiveArch: %{java_arches} noarch
- osgi-core
ExclusiveArch: %{java_arches} noarch
- osm2pgsql
ExcludeArch: %{ix86}
- osslsigncode
ExcludeArch: i686
- ostree
ExcludeArch: %{ix86}
- otf2
ExcludeArch: i686 s390x
- oz
ExcludeArch: %{ix86}
- pacemaker
ExclusiveArch: aarch64 i686 ppc64le s390x x86_64 %{arm}
ExclusiveArch: aarch64 i686 ppc64le s390x x86_64
- pageedit
ExclusiveArch: %{qt5_qtwebengine_arches}
- paperwork
ExcludeArch: %{ix86}
- papi
ExcludeArch: s390 s390x
- papilo
ExcludeArch: %{ix86}
- paraview
ExcludeArch: %{ix86}
- pari-nftables
ExcludeArch: %{ix86}
- parlaylib
ExcludeArch: aarch64 s390x arm-hfp ppc64le i686
- parserng
ExclusiveArch: %{java_arches} noarch
- pasdoc
ExclusiveArch: %{fpc_arches}
- pcc
ExclusiveArch: %{ix86} x86_64
- pcem
ExcludeArch: armv7hl i686 ppc64le s390x
- pcfi
ExclusiveArch: %{java_arches} noarch
- pcg-cpp
ExcludeArch: %{ix86}
- pcm
ExclusiveArch: %{ix86} x86_64
- pcp
ExcludeArch: %{ix86}
- pcp2pdf
ExcludeArch: %{ix86}
- pdbg
ExclusiveArch: ppc64le
- pdfarranger
ExcludeArch: %{ix86}
- pdfbox
ExclusiveArch: %{java_arches} noarch
- pdfmod
ExclusiveArch: %mono_arches
- pdftk-java
ExclusiveArch: %{java_arches} noarch
- pdns
ExcludeArch: %{arm} %{ix86}
- pdns-recursor
ExcludeArch: %{arm} %{ix86}
- pdqsort
ExcludeArch: %{ix86}
- pengupop
ExcludeArch: s390x
- pentaho-libxml
ExclusiveArch: %{java_arches} noarch
- pentaho-reporting-flow-engine
ExclusiveArch: %{java_arches} noarch
- perftest
ExcludeArch: s390 %{arm}
- perl-Dumbbench
ExclusiveArch: %{ix86} x86_64 noarch
- perl-LMDB_File
ExcludeArch: armv7hl i686
- perl-Math-Int128
ExcludeArch: %{arm32} %{ix86}
- perl-MaxMind-DB-Reader-XS
ExcludeArch: %{arm} %{ix86}
- perl-MongoDB
ExcludeArch: ppc %{sparc} s390
- perl-Net-Works
ExcludeArch: %{arm32} %{ix86}
- perl-Parse-DMIDecode
ExclusiveArch: %{ix86} x86_64 ia64 aarch64
- perl-threads-lite
ExcludeArch: aarch64 ppc ppc64 ppc64le
- permlib
ExcludeArch: %{ix86}
- pesign
ExclusiveArch: %{ix86} x86_64 ia64 aarch64 %{arm}
- pesign-test-app
ExclusiveArch: x86_64
- pf-bb-config
ExcludeArch: s390x
- pgadmin4
ExcludeArch: i686 armv7hl s390x ppc64le
- phd2
ExcludeArch: %{ix86}
- phosh
ExcludeArch: i686
- phosh-mobile-settings
ExcludeArch: i686
- php-pecl-mongodb
ExcludeArch: %{ix86}
- picard
ExcludeArch: ppc64
- picocli
ExclusiveArch: %{java_arches} noarch
- pigeonascent
ExcludeArch: ppc64le
ExcludeArch: s390x
- pilot-link
ExcludeArch: s390 s390x
- pinta
ExclusiveArch: %mono_arches
ExcludeArch: armv7hl
- pioneer
ExclusiveArch: %{ix86} x86_64
- pl
ExcludeArch: %{ix86}
- planets
ExcludeArch: %{ix86}
- plantri
ExcludeArch: %{ix86}
- plantuml
ExclusiveArch: %{java_arches} noarch
- plasma-dialer
ExclusiveArch: %{java_arches}
- playonlinux
ExclusiveArch: %{arm} aarch64 %{ix86} x86_64
- plee-the-bear
ExcludeArch: %{power64}
- plexus-archiver
ExclusiveArch: %{java_arches} noarch
- plexus-build-api
ExclusiveArch: %{java_arches} noarch
- plexus-build-api0
ExclusiveArch: %{java_arches} noarch
- plexus-cipher
ExclusiveArch: %{java_arches} noarch
- plexus-classworlds
ExclusiveArch: %{java_arches} noarch
- plexus-compiler
ExclusiveArch: %{java_arches} noarch
- plexus-component-api
ExclusiveArch: %{java_arches} noarch
- plexus-components-pom
ExclusiveArch: %{java_arches} noarch
- plexus-containers
ExclusiveArch: %{java_arches} noarch
- plexus-i18n
ExclusiveArch: %{java_arches} noarch
- plexus-interpolation
ExclusiveArch: %{java_arches} noarch
- plexus-io
ExclusiveArch: %{java_arches} noarch
- plexus-languages
ExclusiveArch: %{java_arches} noarch
- plexus-pom
ExclusiveArch: %{java_arches} noarch
- plexus-resources
ExclusiveArch: %{java_arches} noarch
- plexus-sec-dispatcher
ExclusiveArch: %{java_arches} noarch
- plexus-testing
ExclusiveArch: %{java_arches} noarch
- plexus-utils
ExclusiveArch: %{java_arches} noarch
- plexus-velocity
ExclusiveArch: %{java_arches} noarch
- plexus-xml
ExclusiveArch: %{java_arches} noarch
- pmix
ExcludeArch: %{ix86}
- pngcheck
ExcludeArch: %{ix86}
- podman
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- polymake
ExcludeArch: %{ix86}
- polyml
ExcludeArch: %{ix86}
- poppler-sharp
ExclusiveArch: %mono_arches
- popub
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
- postgresql-jdbc
ExclusiveArch: %{java_arches} noarch
- postgresql-pgpool-II
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
- powerpc-utils
ExclusiveArch: ppc %{power64}
- powerstat
ExclusiveArch: %{ix86} x86_64
- ppc64-diag
ExclusiveArch: ppc %{power64}
- ppl
ExcludeArch: %{ix86}
- pplite
ExcludeArch: %{ix86}
- prestopalette
ExcludeArch: i686
- printer-driver-brlaser
ExcludeArch: %{ix86}
- procdump
ExcludeArch: ppc64le
- procyon
ExclusiveArch: %{java_arches} noarch
ExclusiveArch: %{java_arches} noarch
ExclusiveArch: %{java_arches} noarch
ExclusiveArch: %{java_arches} noarch
ExclusiveArch: %{java_arches} noarch
ExclusiveArch: %{java_arches} noarch
- proguard
ExclusiveArch: %{java_arches} noarch
- prometheus-jmx-exporter
ExclusiveArch: %{java_arches} noarch
- prometheus-simpleclient-java
ExclusiveArch: %{java_arches} noarch
- prooftree
ExcludeArch: %{ix86}
- proxmark3
ExcludeArch: ppc64le s390x
- proxygen
ExclusiveArch: x86_64 aarch64 ppc64le
- proxysql
ExcludeArch: %{power64} s390x
- prrte
ExcludeArch: %{ix86}
- prusa-slicer
ExcludeArch: %{ix86}
- psblas3
ExcludeArch: %{ix86}
- purple-telegram
ExcludeArch: s390x
ExcludeArch: ppc64
- pveclib
ExclusiveArch: ppc %{power64}
- pygrib
ExcludeArch: i686
ExcludeArch: armv7hl
- pygsl
ExcludeArch: %{ix86}
- pyosmium
ExcludeArch: %{ix86}
- pypy
ExcludeArch: %{ix86}
- pypy3.10
ExcludeArch: %{ix86}
- pypy3.9
ExcludeArch: %{ix86}
- pyqtwebengine
ExclusiveArch: %{qt5_qtwebengine_arches}
- python-ZEO
ExcludeArch: %{ix86}
- python-ZODB3
ExcludeArch: %{ix86}
- python-aioresponses
ExcludeArch: s390x
- python-ast-monitor
ExclusiveArch: %{qt6_qtwebengine_arches} noarch
- python-astroplan
ExcludeArch: %{ix86}
- python-astroscrappy
ExcludeArch: %{ix86}
- python-asyncmy
ExcludeArch: %{ix86}
- python-aws-sam-translator
ExcludeArch: %{ix86}
- python-awscrt
ExcludeArch: s390x
- python-bitstruct
ExcludeArch: s390x
- python-blosc2
ExcludeArch: %{ix86}
- python-bluepyopt
ExcludeArch: s390x %{ix86} %{power64}
- python-chaospy
ExcludeArch: %{ix86} %{arm32}
- python-colorcet
ExcludeArch: %{ix86}
- python-colorthief
ExcludeArch: %{ix86}
- python-compreffor
ExcludeArch: %{ix86}
- python-contextualbandits
ExcludeArch: %{ix86}
- python-cradox
ExcludeArch: i686 armv7hl
- python-cryptography
ExclusiveArch: %{rust_arches}
- python-cvxopt
ExcludeArch: %{ix86}
- python-cyipopt
ExcludeArch: %{ix86}
- python-dask
ExcludeArch: %{ix86}
- python-databases
ExcludeArch: %{ix86}
- python-devicely
ExcludeArch: s390x
- python-dijitso
ExcludeArch: i686
- python-dipy
ExcludeArch: %{ix86} s390x
- python-ducc0
ExcludeArch: %{ix86}
- python-earthpy
ExcludeArch: %{ix86}
- python-eccodes
ExcludeArch: i686
ExcludeArch: armv7hl
- python-efel
ExcludeArch: s390x
- python-elephant
ExcludeArch: s390x
ExcludeArch: %{ix86}
- python-ephyviewer
ExcludeArch: s390x %{ix86}
- python-etcd
ExclusiveArch: noarch %{ix86} x86_64 %{arm} aarch64 ppc64le s390x riscv64
- python-fastavro
ExcludeArch: %{arm32} %{ix86}
- python-folium
ExcludeArch: %{ix86}
- python-formulaic
ExcludeArch: %{ix86}
- python-fsleyes
ExcludeArch: %{ix86}
- python-fsleyes-props
ExcludeArch: %{ix86}
- python-fslpy
ExcludeArch: %{ix86}
- python-gbinder
ExcludeArch: %{ix86}
- python-giacpy
ExcludeArch: aarch64 %{power64} s390x
- python-graph-tool
ExcludeArch: %{ix86}
- python-hdfs
ExcludeArch: %{ix86}
- python-healpy
ExcludeArch: %{ix86} %{arm}
- python-heapdict
ExcludeArch: %{ix86}
- python-img2pdf
ExcludeArch: s390x
- python-intbitset
ExcludeArch: s390x
- python-javaobj
ExclusiveArch: %{java_arches} noarch
- python-jnius
ExclusiveArch: %{java_arches}
ExclusiveArch: %{java_arches}
- python-json-minify
ExcludeArch: %{ix86}
- python-jupymake
ExcludeArch: %{ix86}
- python-jupyter-c-kernel
ExcludeArch: %{ix86}
- python-jupyter-kernel-singular
ExcludeArch: %{ix86}
- python-jupyter-polymake
ExcludeArch: %{ix86}
- python-jupyter-sphinx
ExcludeArch: %{ix86}
- python-lazy-ops
ExcludeArch: %{ix86}
- python-lfpy
ExcludeArch: mips64r2 mips32r2
ExcludeArch: %{power64} %{ix86} armv7hl
- python-mapnik
ExcludeArch: ppc ppc64 s390 s390x
- python-missingno
ExcludeArch: %{ix86}
- python-mne
ExcludeArch: %{ix86}
- python-mne-bids
ExcludeArch: %{ix86}
- python-mplcairo
ExcludeArch: %{ix86}
- python-mplcursors
ExcludeArch: %{ix86}
- python-music21
ExcludeArch: %{ix86}
- python-ndindex
ExcludeArch: %{ix86}
- python-neatdend
ExcludeArch: %{ix86}
- python-neo
ExcludeArch: s390x
- python-netpyne
ExcludeArch: %{ix86}
- python-neurom
ExcludeArch: %{ix86}
- python-neurotune
ExcludeArch: %{ix86}
- python-numpoly
ExcludeArch: %{ix86}
- python-octave-kernel
ExcludeArch: %{ix86}
- python-openoffice
ExclusiveArch: noarch x86_64
- python-openpaperwork-core
ExcludeArch: %{ix86}
- python-openpaperwork-gtk
ExcludeArch: %{ix86}
- python-opentype-sanitizer
ExcludeArch: %{ix86}
- python-pandas-flavor
ExcludeArch: %{ix86}
- python-papermill
ExcludeArch: %{ix86}
- python-paperwork-backend
ExcludeArch: %{ix86}
- python-param
ExcludeArch: %{ix86}
- python-pari-jupyter
ExcludeArch: %{ix86}
- python-pep8-naming
ExcludeArch: %{ix86}
- python-phyghtmap
ExcludeArch: %{ix86}
- python-pingouin
ExcludeArch: %{ix86}
- python-plotnine
ExcludeArch: %{ix86}
- python-pplpy
ExcludeArch: %{ix86}
- python-primecountpy
ExcludeArch: %{ix86}
- python-psycopg3
ExcludeArch: %{ix86}
- python-pyahocorasick
ExclusiveArch: x86_64 %{arm64} ppc64le riscv64
- python-pybids
ExcludeArch: %{ix86}
- python-pybv
ExcludeArch: %{ix86}
- python-pyct
ExcludeArch: %{ix86}
- python-pyedflib
ExcludeArch: s390x
- python-pyfastnoisesimd
ExcludeArch: %{ix86}
- python-pyfiglet
ExcludeArch: %{ix86}
- python-pykdtree
ExcludeArch: %{ix86}
- python-pyliblzfse
ExcludeArch: s390x
- python-pymapvbvd
ExcludeArch: s390x
- python-pymatreader
ExcludeArch: %{ix86}
ExcludeArch: s390x
- python-pynn
ExcludeArch: mips64r2 mips32r2 s390x %{ix86}
- python-pyocr
ExcludeArch: %{ix86}
- python-pypet
ExcludeArch: %{ix86}
ExcludeArch: s390x
- python-pyphi
ExcludeArch: s390x
- python-pypillowfight
ExcludeArch: %{ix86}
- python-pyqt6-webengine
ExclusiveArch: %{qt6_qtwebengine_arches}
- python-pyroaring
ExcludeArch: %{ix86}
- python-pyscf
ExcludeArch: %{power64}
- python-pyshtools
ExcludeArch: %{ix86}
- python-pysingular
ExcludeArch: %{ix86}
- python-pyswarms
ExcludeArch: %{ix86}
- python-pyswip
ExcludeArch: %{ix86}
- python-pytest-arraydiff
ExcludeArch: %{ix86}
- python-pytest-tornado
ExcludeArch: %{ix86}
- python-pyvat
ExcludeArch: %{ix86}
- python-ratinabox
ExcludeArch: %{ix86}
- python-recordclass
ExcludeArch: %{ix86}
- python-reproject
ExcludeArch: %{ix86}
- python-ruffus
ExcludeArch: %{ix86}
- python-scikit-learn
ExcludeArch: %{ix86}
- python-sgp4
ExcludeArch: %{ix86}
- python-simplebayes
ExcludeArch: %{ix86}
- python-sklearn-genetic-opt
ExcludeArch: %{ix86}
- python-statsmodels
ExcludeArch: %{ix86}
- python-steps
ExcludeArch: %{ix86}
- python-tables
ExcludeArch: %{ix86}
- python-tdlib
ExcludeArch: %{ix86}
- python-tensile
ExclusiveArch: x86_64
- python-tkrzw
ExcludeArch: i686
- python-torch
ExclusiveArch: x86_64 aarch64
- python-torchdata
ExclusiveArch: x86_64 aarch64
- python-torchvision
ExclusiveArch: x86_64 aarch64
- python-traitsui
ExcludeArch: ppc64le
- python-trimesh
ExcludeArch: %{ix86}
- python-uranium
ExcludeArch: %{ix86}
- python-willow
ExcludeArch: %{ix86}
- python-xattr
ExcludeArch: %{ix86}
- python-xbout
ExcludeArch: %{ix86}
- python-xmp-toolkit
ExcludeArch: %{ix86}
- python-zeep
ExcludeArch: s390x
- python-zict
ExcludeArch: %{ix86}
- q4wine
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64
- qalculate-qt
ExcludeArch: %{ix86}
- qatengine
ExclusiveArch: x86_64
- qatlib
ExcludeArch: %{arm} aarch64 %{power64} s390x i686
- qatzip
ExclusiveArch: x86_64
- qbe
ExclusiveArch: x86_64 aarch64 riscv64
- qbittorrent
ExcludeArch: %{ix86}
- qbs
ExcludeArch: i686
- qcas
ExcludeArch: aarch64 %{power64} s390x
- qcint
ExclusiveArch: x86_64
- qclib
ExclusiveArch: s390 s390x
- qdigidoc
ExcludeArch: %{ix86}
- qdox
ExclusiveArch: %{java_arches} noarch
- qemu-sanity-check
ExclusiveArch: %{kernel_arches}
ExcludeArch: %{power64}
- qevercloud
ExclusiveArch: %{qt5_qtwebengine_arches}
- qflipper
ExcludeArch: %{ix86}
- qmapshack
ExclusiveArch: %{qt5_qtwebengine_arches}
- qoauth
ExcludeArch: ppc64
- qownnotes
ExcludeArch: %{ix86}
- qpdfview
ExcludeArch: s390x
- qperf
ExcludeArch: %{arm}
- qsopt-ex
ExcludeArch: %{ix86}
- qt4pas
ExclusiveArch: %{fpc_arches}
- qt5-qtwebengine
ExclusiveArch: %{qt5_qtwebengine_arches}
- qt6-qtwebengine
ExclusiveArch: aarch64 x86_64
- qt6-qtwebview
ExclusiveArch: aarch64 x86_64
- qt6ct
ExcludeArch: s390x
- qtile
ExcludeArch: %{ix86}
- quantum-espresso
ExclusiveArch: x86_64 aarch64 %{power64}
- quentier
ExclusiveArch: %{qt5_qtwebengine_arches}
- rEFInd
ExclusiveArch: %{efi}
ExcludeArch: %{arm32}
- racket
ExcludeArch: %{arm} s390x
ExcludeArch: ppc64le
- rasdaemon
ExcludeArch: s390 s390x
- rdma-core
ExcludeArch: %{arm}
- realtime-tests
ExcludeArch: %{arm}
- rear
ExclusiveArch: %ix86 x86_64 ppc ppc64 ppc64le ia64 s390x
- redeclipse
ExcludeArch: %{ix86}
- reflections
ExclusiveArch: %{java_arches} noarch
- reg
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
- regexp
ExclusiveArch: %{java_arches} noarch
- relaxng-datatype-java
ExclusiveArch: %{java_arches} noarch
- remake
ExcludeArch: %{ix86}
- renderdoc
ExclusiveArch: x86_64 aarch64
- replacer
ExclusiveArch: %{java_arches} noarch
- reptyr
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64
- rescene
ExclusiveArch: %{mono_arches}
- resteasy
ExclusiveArch: %{java_arches} noarch
- restool
ExclusiveArch: aarch64
- restsharp
ExclusiveArch: %{mono_arches}
ExcludeArch: armv7hl
- retroarch
ExcludeArch: %{ix86}
ExcludeArch: s390x
- retsnoop
ExclusiveArch: %{rust_arches}
ExcludeArch: armv7hl
- rhino
ExclusiveArch: %{java_arches} noarch
ExcludeArch: %{ix86}
- rhythmbox
ExcludeArch: s390 s390x
- rhythmbox-alternative-toolbar
ExcludeArch: s390 s390x
- rhythmbox-ampache
ExcludeArch: s390 s390x
- river
ExclusiveArch: %{zig_arches}
- rkcommon
ExclusiveArch: x86_64 aarch64
- rocalution
ExclusiveArch: x86_64
- rocblas
ExclusiveArch: x86_64
- rocclr
ExclusiveArch: x86_64
- rocfft
ExclusiveArch: x86_64
- rocm-compilersupport
ExclusiveArch: x86_64 aarch64 ppc64le
- rocm-core
ExclusiveArch: x86_64
- rocm-device-libs
ExclusiveArch: x86_64 aarch64 ppc64le
- rocm-rpm-macros
ExclusiveArch: x86_64
- rocm-runtime
ExclusiveArch: x86_64 aarch64 ppc64le
- rocm-smi
ExclusiveArch: x86_64 aarch64 ppc64le riscv64
- rocminfo
ExclusiveArch: x86_64 aarch64 ppc64le
- rocprim
ExclusiveArch: x86_64
- rocrand
ExclusiveArch: x86_64
- rocsolver
ExclusiveArch: x86_64
- rocsparse
ExclusiveArch: x86_64
- rocthrust
ExclusiveArch: x86_64
- roctracer
ExclusiveArch: x86_64
- rpi-imager
ExcludeArch: s390x
- rpm-ostree
ExclusiveArch: %{rust_arches}
ExcludeArch: %{ix86}
- rr
ExclusiveArch: %{ix86} x86_64 aarch64
- rssguard
ExclusiveArch: %{qt6_qtwebengine_arches}
- rstudio
ExclusiveArch: %{java_arches}
- rsyntaxtextarea
ExclusiveArch: %{java_arches} noarch
- rubiks
ExcludeArch: %{ix86}
- rubygem-childprocess
ExclusiveArch: %{ix86} x86_64 noarch
- ruff
ExcludeArch: %{ix86}
- ruff-lsp
ExcludeArch: %{ix86}
- runc
ExclusiveArch: %{golang_arches_future}
- rundoc
ExclusiveArch: %{java_arches} noarch
- rust
ExclusiveArch: %{rust_arches}
- rust-bankstown-lv2
ExcludeArch: ppc64le s390x
- rust-below
ExcludeArch: %{arm32} %{ix86}
- rust-below-btrfs
ExcludeArch: %{arm32} %{ix86}
- rust-below-config
ExcludeArch: %{arm32} %{ix86}
- rust-below-dump
ExcludeArch: %{arm32} %{ix86}
- rust-below-model
ExcludeArch: %{arm32} %{ix86}
- rust-compress-tools
ExclusiveArch: %{rust_arches}
- rust-crypto-auditing-agent
ExcludeArch: i386 i686
- rust-ct-logs
ExcludeArch: ppc64le s390x
- rust-ctr
ExclusiveArch: %{rust_arches}
- rust-dashmap4
ExclusiveArch: %{rust_arches}
- rust-deflate
ExclusiveArch: %{rust_arches}
- rust-deflate0.8
ExclusiveArch: %{rust_arches}
- rust-getch
ExclusiveArch: %{rust_arches}
- rust-gzip-header
ExclusiveArch: %{rust_arches}
- rust-hamming
ExclusiveArch: %{rust_arches}
- rust-hidapi
ExclusiveArch: %{rust_arches}
- rust-httparse
ExclusiveArch: %{rust_arches}
- rust-humantime-serde
ExclusiveArch: %{rust_arches}
- rust-hyperlocal
ExclusiveArch: %{rust_arches}
- rust-inflate
ExclusiveArch: %{rust_arches}
- rust-k9
ExclusiveArch: %{rust_arches}
- rust-krunvm
ExclusiveArch: x86_64 aarch64
- rust-kstring
ExclusiveArch: %{rust_arches}
- rust-kvm-bindings
ExcludeArch: %{ix86}
- rust-kvm-ioctls
ExclusiveArch: x86_64 aarch64
- rust-lebe
ExclusiveArch: %{rust_arches}
- rust-lv2
ExcludeArch: ppc64le s390x
- rust-lv2-atom
ExcludeArch: ppc64le s390x
- rust-lv2-core
ExcludeArch: ppc64le s390x
- rust-lv2-midi
ExcludeArch: ppc64le s390x
- rust-lv2-state
ExcludeArch: ppc64le s390x
- rust-lv2-sys
ExcludeArch: ppc64le s390x
- rust-lv2-time
ExcludeArch: ppc64le s390x
- rust-lv2-units
ExcludeArch: ppc64le s390x
- rust-lv2-urid
ExcludeArch: ppc64le s390x
- rust-lv2-worker
ExcludeArch: ppc64le s390x
- rust-msru
ExclusiveArch: x86_64
- rust-nanorand
ExclusiveArch: %{rust_arches}
- rust-netstat2
ExclusiveArch: %{rust_arches}
- rust-nu
ExcludeArch: %{ix86}
- rust-oci-spec
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
- rust-onig
ExclusiveArch: %{rust_arches}
- rust-openat-ext
ExclusiveArch: %{rust_arches}
- rust-os_type
ExclusiveArch: %{rust_arches}
- rust-pager
ExclusiveArch: %{rust_arches}
- rust-pathsearch
ExclusiveArch: %{rust_arches}
- rust-prefixdevname
ExcludeArch: %{ix86}
- rust-pretty-bytes
ExclusiveArch: %{rust_arches}
- rust-primal-bit
ExclusiveArch: %{rust_arches}
- rust-primal-check
ExclusiveArch: %{rust_arches}
- rust-primal-estimate
ExclusiveArch: %{rust_arches}
- rust-probe
ExcludeArch: ppc64le s390x
- rust-procfs0.9
ExclusiveArch: %{rust_arches}
- rust-psl-types
ExclusiveArch: %{rust_arches}
- rust-psm
ExclusiveArch: %{rust_arches}
- rust-pwd
ExclusiveArch: %{rust_arches}
- rust-rand_core
ExclusiveArch: %{rust_arches}
- rust-schemafy_core
ExclusiveArch: %{rust_arches}
- rust-schemafy_lib
ExclusiveArch: %{rust_arches}
- rust-scx_layered
ExcludeArch: %{ix86}
- rust-scx_rustland
ExcludeArch: %{ix86}
- rust-scx_rusty
ExcludeArch: %{ix86}
- rust-scx_utils
ExcludeArch: %{ix86}
- rust-seahash
ExclusiveArch: %{rust_arches}
- rust-sequoia-octopus-librnp
ExcludeArch: %{ix86} %{arm} s390x
- rust-serde_yaml0.8
ExclusiveArch: %{rust_arches}
- rust-sev
ExclusiveArch: x86_64
- rust-sevctl
ExclusiveArch: x86_64
- rust-sinit
ExclusiveArch: %{rust_arches}
- rust-snphost
ExclusiveArch: x86_64
- rust-ssh-key-dir
ExclusiveArch: %{rust_arches}
- rust-stacker
ExclusiveArch: %{rust_arches}
- rust-structopt
ExclusiveArch: %{rust_arches}
- rust-tiny-dfr
ExcludeArch: %{ix86}
- rust-totp-lite
ExclusiveArch: %{rust_arches}
- rust-tower-layer
ExclusiveArch: %{rust_arches}
- rust-tpm2-policy
ExclusiveArch: %{rust_arches}
- rust-unicode-normalization
ExclusiveArch: %{rust_arches}
- rust-unicode-xid
ExclusiveArch: %{rust_arches}
- rust-uriparse
ExclusiveArch: %{rust_arches}
- rust-varlink_generator
ExclusiveArch: %{rust_arches}
- rust-varlink_parser
ExclusiveArch: %{rust_arches}
- rust-vhost-device-scmi
ExcludeArch: s390x
- rust-virtio-bindings
ExclusiveArch: x86_64 aarch64 ppc64le riscv64
- rust-virtio-queue
ExcludeArch: i686
- rust-vm-memory
ExcludeArch: %{ix86}
- rust-vmm-sys-util
ExclusiveArch: x86_64 aarch64 ppc64le riscv64
- rust-vtparse
ExclusiveArch: %{rust_arches}
- rust-web-ext-native-messaging
ExclusiveArch: %{rust_arches}
- rust-wezterm-color-types
ExclusiveArch: %{rust_arches}
- rust-wezterm-dynamic
ExclusiveArch: %{rust_arches}
- rust-wezterm-dynamic-derive
ExclusiveArch: %{rust_arches}
- rust-zbus1
ExclusiveArch: %{rust_arches}
- rust-zbus_macros1
ExclusiveArch: %{rust_arches}
- rust-zincati
ExcludeArch: armv7hl i686
- rust-zvariant2
ExclusiveArch: %{rust_arches}
- rust-zvariant_derive2
ExclusiveArch: %{rust_arches}
- rustup
ExclusiveArch: x86_64 aarch64
- rutabaga-gfx-ffi
ExclusiveArch: x86_64 aarch64
- s390utils
ExcludeArch: %{ix86}
- sac
ExclusiveArch: %{java_arches} noarch
- safeint
ExcludeArch: %{ix86}
- safetyblanket
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc64le
- sandia-omega-h
ExcludeArch: %{ix86} s390x
- sat4j
ExclusiveArch: %{java_arches} noarch
- sayonara
ExcludeArch: %{ix86}
- sbcl
ExclusiveArch: %{ix86} x86_64 aarch64 %{power64}
- sbd
ExclusiveArch: i686 x86_64 s390x aarch64 ppc64le
- sblim-cim-client
ExclusiveArch: %{java_arches} noarch
- sblim-cim-client2
ExclusiveArch: %{java_arches} noarch
- sbsigntools
ExclusiveArch: x86_64 aarch64 %{arm} %{ix86}
- scala
ExclusiveArch: %{java_arches} noarch
- scalasca
ExcludeArch: s390 s390x armv7hl i686
- scannotation
ExclusiveArch: %{java_arches} noarch
- scip
ExcludeArch: %{ix86}
- scorep
ExcludeArch: s390 s390x armv7hl i686
- sdljava
ExclusiveArch: %{java_arches}
- sdrangel
ExclusiveArch: %{qt5_qtwebengine_arches}
- sdsl-lite
ExclusiveArch: %{power64} x86_64 aarch64
- sdubby
ExclusiveArch: %{efi}
- seabios
ExclusiveArch: x86_64
- seadrive-gui
ExclusiveArch: %{qt5_qtwebengine_arches}
- seafile-client
ExclusiveArch: %{qt6_qtwebengine_arches}
- seamonkey
ExclusiveArch: x86_64
- sedutil
ExcludeArch: ppc ppc64 s390 s390x
- sentencepiece
ExcludeArch: s390x
- seqan3
ExclusiveArch: %{power64} x86_64 aarch64
- sequeler
ExcludeArch: %{ix86}
- sequence-library
ExclusiveArch: %{java_arches} noarch
- servicelog
ExclusiveArch: ppc %{power64}
- setserial
ExcludeArch: s390 s390x
- sfnt2woff-zopfli
ExcludeArch: %{ix86}
- sharedmeataxe
ExcludeArch: %{ix86}
- sharpfont
ExclusiveArch: %mono_arches
- sharpziplib
ExclusiveArch: %{mono_arches}
- shim
ExclusiveArch: %{efi}
ExcludeArch: %{ix86}
ExcludeArch: %{arm}
- shim-unsigned-aarch64
ExclusiveArch: aarch64
- shim-unsigned-x64
ExclusiveArch: x86_64
- sigil
ExclusiveArch: %{qt5_qtwebengine_arches}
ExcludeArch: %{ix86}
- sigul
ExclusiveArch: x86_64
ExcludeArch: %{ix86}
- simdutf
ExcludeArch: s390 s390x
- singularity-ce
ExclusiveArch: %{go_arches}
ExcludeArch: %{ix86}
- sirocco
ExcludeArch: %{ix86}
- sisu
ExclusiveArch: %{java_arches} noarch
- sisu-mojos
ExclusiveArch: %{java_arches} noarch
- ski
ExcludeArch: %{ix86}
ExcludeArch: aarch64
- skopeo
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- skychart
ExclusiveArch: %{fpc_arches}
ExcludeArch: %{ix86}
- slapi-nis
ExcludeArch: %{ix86}
- sleef
ExcludeArch: %{ix86}
- slf4j
ExclusiveArch: %{java_arches} noarch
- slic3r
ExcludeArch: %{ix86}
ExcludeArch: ppc ppc64 s390 s390x %{ix86}
ExcludeArch: ppc ppc64 s390 s390x
- slick-greeter
ExcludeArch: %{ix86}
- slimdata
ExcludeArch: ppc64 ppc sparcv9 sparc64
- slirp4netns
ExclusiveArch: %{golang_arches_future}
- slurm
ExcludeArch: armv7hl
ExcludeArch: i686
- snakeyaml
ExclusiveArch: %{java_arches} noarch
- snapd
ExclusiveArch: %{?golang_arches}%{!?golang_arches:%{ix86} x86_64 %{arm} aarch64 ppc64le s390x}
- snapshot
ExcludeArch: %{ix86}
- snip
ExclusiveArch: %{java_arches} noarch
- softnet-stat
ExclusiveArch: %{rust_arches}
- soplex
ExcludeArch: %{ix86}
- sound-juicer
ExcludeArch: s390 s390x
- soup-sharp
ExclusiveArch: %{mono_arches}
- sourcextractor++
ExcludeArch: %{ix86}
- spacebar
ExclusiveArch: %{java_arches}
- sparkleshare
ExclusiveArch: %{mono_arches}
ExcludeArch: %{ix86}
- spasm
ExcludeArch: %{ix86}
- spec-version-maven-plugin
ExclusiveArch: %{java_arches} noarch
- speed-dreams
ExcludeArch: s390x
- spicctrl
ExclusiveArch: %{ix86} x86_64
- spice
ExclusiveArch: x86_64
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64 riscv64
- spice-parent
ExclusiveArch: %{java_arches} noarch
- springlobby
ExclusiveArch: %{ix86} x86_64
- spyder
ExcludeArch: %{ix86}
ExclusiveArch: %{qt5_qtwebengine_arches} noarch
- squeekboard
ExclusiveArch: %{rust_arches}
ExcludeArch: ppc64le
ExcludeArch: s390x
- squirrel
ExcludeArch: %{ix86}
- startdde
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
- stats-collect
ExclusiveArch: %{ix86} x86_64 noarch
- statsd
ExclusiveArch: %{nodejs_arches} noarch
- statserial
ExcludeArch: s390 s390x
- steinberg-bravura-fonts
ExcludeArch: %{ix86}
- steinberg-petaluma-fonts
ExcludeArch: %{ix86}
- stellarium
ExcludeArch: armv7hl
- stlsplit
ExcludeArch: %{ix86}
- stp
ExcludeArch: %{ix86}
- stratis-cli
ExclusiveArch: %{rust_arches} noarch
ExcludeArch: i686
- stratisd
ExclusiveArch: %{rust_arches}
ExcludeArch: i686
ExclusiveArch: %{rust_arches}
ExcludeArch: i686
ExclusiveArch: %{rust_arches}
ExcludeArch: i686
- string-template-maven-plugin
ExclusiveArch: %{java_arches} noarch
- stringtemplate
ExclusiveArch: %{java_arches} noarch
- stringtemplate4
ExclusiveArch: %{java_arches} noarch
- stripesnoop
ExclusiveArch: %{ix86} x86_64
- subscription-manager-cockpit
ExclusiveArch: %{nodejs_arches} noarch
- supercollider
ExclusiveArch: %{qt5_qtwebengine_arches}
- supermin
ExcludeArch: %{ix86}
ExclusiveArch: %{kernel_arches}
ExcludeArch: %{power64}
- supertux
ExcludeArch: s390x
- suricata
ExcludeArch: ppc64le i686
- svt-vp9
ExclusiveArch: x86_64
- swift-lang
ExclusiveArch: x86_64 aarch64
- swiftlint
ExclusiveArch: x86_64 aarch64
- swing-layout
ExclusiveArch: %{java_arches} noarch
- symfpu
ExcludeArch: %{ix86}
- symmetrica
ExcludeArch: %{ix86}
- sympol
ExcludeArch: %{ix86}
- sympow
ExcludeArch: %{ix86}
- synfig
ExcludeArch: ppc64le
- synfigstudio
ExcludeArch: ppc64le
- sysbench
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips}
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips} aarch64
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips} aarch64 ppc64le s390x
- syslinux
ExclusiveArch: %{ix86} x86_64
ExclusiveArch: %{ix86} x86_64
- system-rules
ExclusiveArch: %{java_arches} noarch
- systemd-boot
ExclusiveArch: %efi
- t-digest
ExclusiveArch: %{java_arches} noarch
- taglib-sharp
ExclusiveArch: %{mono_arches}
- tagsoup
ExclusiveArch: %{java_arches} noarch
- tarantool
ExclusiveArch: %{ix86} x86_64
- tboot
ExclusiveArch: %{ix86} x86_64
- tcmu-runner
ExcludeArch: i686 armv7hl
- tdlib
ExclusiveArch: x86_64 aarch64
- teem
ExcludeArch: %{ix86}
- templates_parser
ExclusiveArch: %GPRbuild_arches
- terminology
ExcludeArch: s390x
- terminus-fonts
ExcludeArch: %{grub2_exclude_arches}
- ternimal
ExclusiveArch: %{rust_arches}
- testcloud
ExclusiveArch: %{kernel_arches} noarch
- testng
ExclusiveArch: %{java_arches} noarch
- texlive
ExclusiveArch: %{java_arches} noarch
- texmaker
ExclusiveArch: %{qt6_qtwebengine_arches}
ExcludeArch: ppc64 ppc64le s390x
- thermald
ExclusiveArch: %{ix86} x86_64
- thunderbird
ExcludeArch: armv7hl
ExcludeArch: s390x
- tiled
ExcludeArch: %{ix86}
- tilix
ExclusiveArch: %{ldc_arches}
- tinygo
ExcludeArch: ppc64le s390x
ExcludeArch: %{ix86}
- tokodon
ExclusiveArch: %{qt6_qtwebengine_arches}
- tomboy
ExclusiveArch: %{mono_arches}
- tomcat
ExclusiveArch: %{java_arches} noarch
- tomcat-jakartaee-migration
ExclusiveArch: %{java_arches} noarch
- tomcat-native
ExclusiveArch: %{java_arches}
- tomcat-taglibs-parent
ExclusiveArch: %{java_arches} noarch
- torbrowser-launcher
ExclusiveArch: %{ix86} x86_64
- trace-cmd
ExcludeArch: %{ix86} %{arm}
- trafficserver
ExcludeArch: %{arm} %{ix86} s390x
- treelayout
ExclusiveArch: %{java_arches} noarch
- trilead-ssh2
ExclusiveArch: %{java_arches} noarch
- trojita
ExcludeArch: ppc64 ppc64le s390x
- trunk
ExcludeArch: %{ix86}
- truth
ExclusiveArch: %{java_arches} noarch
- tth
ExcludeArch: %{ix86}
- tuned-profiles-nfv-host-bin
ExclusiveArch: %{ix86} x86_64
- tuxguitar
ExcludeArch: s390 %{arm} %{ix86}
- tvtime
ExcludeArch: s390 s390x
- typescript
ExclusiveArch: %{nodejs_arches} noarch
- tzdata
ExcludeArch: i686
- uClibc
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips}
- uboot-tools
ExcludeArch: s390x
- ucx
ExclusiveArch: aarch64 ppc64le x86_64
- uglify-js
ExclusiveArch: %{nodejs_arches} noarch
- ugrep
ExcludeArch: %{ix86}
- umr
ExclusiveArch: x86_64 aarch64 ppc64le
- unetbootin
ExclusiveArch: %{ix86} x86_64
- unicorn
ExcludeArch: s390x
- univocity-parsers
ExclusiveArch: %{java_arches} noarch
- ursa-major
ExclusiveArch: noarch aarch64 ppc64le s390x x86_64
- usbip
ExcludeArch: s390x
- usd
ExclusiveArch: aarch64 x86_64
- usnic-tools
ExcludeArch: %{arm}
- utop
ExcludeArch: %{ix86}
- v-hacd
ExcludeArch: %{ix86}
- v8-314
ExclusiveArch: %{ix86} x86_64 %{arm} mips mipsel ppc ppc64
- vakzination
ExclusiveArch: %{java_arches}
- valgrind
ExclusiveArch: %{ix86} x86_64 ppc ppc64 ppc64le s390x armv7hl aarch64
- vboot-utils
ExclusiveArch: %{arm} aarch64 %{ix86} x86_64
- vdr-tvscraper
ExcludeArch: armv7hl
- vecmath1.2
ExclusiveArch: %{java_arches} noarch
- velocity
ExclusiveArch: %{java_arches} noarch
- viking
ExcludeArch: s390 s390x
- vim-go
ExclusiveArch: %{?golang_arches}%{!?golang_arches:%{ix86} x86_64 %{arm}}
- vim-syntastic
ExclusiveArch: %{java_arches} noarch
- vinci
ExcludeArch: %{ix86}
- virt-p2v
ExclusiveArch: x86_64
- virt-top
ExcludeArch: %{ix86}
ExcludeArch: %{power64}
- virt-v2v
ExcludeArch: %{ix86}
ExclusiveArch: x86_64
- virtiofsd
ExclusiveArch: %{rust_arches}
ExcludeArch: i686
- virtualbox-guest-additions
ExclusiveArch: i686 x86_64
- visidata
ExcludeArch: %{ix86}
- visualboyadvance-m
ExcludeArch: %{ix86}
- vkd3d
ExclusiveArch: %{ix86} x86_64 %{arm}
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64
- vkmark
ExcludeArch: s390x
- vmaf
ExclusiveArch: x86_64
- voms-api-java
ExclusiveArch: %{java_arches} noarch
- voms-clients-java
ExclusiveArch: %{java_arches} noarch
- votca
ExcludeArch: %{ix86}
- vrq
ExclusiveArch: %{ix86} x86_64
- wangle
ExclusiveArch: x86_64 aarch64 ppc64le
- warsow
ExclusiveArch: %{ix86} x86_64 %{arm}
- warsow-data
ExclusiveArch: %{ix86} x86_64 %{arm} noarch
ExclusiveArch: %{ix86} x86_64 %{arm}
- warzone2100
ExcludeArch: %{ix86}
- wasmedge
ExclusiveArch: x86_64 aarch64
- watchman
ExclusiveArch: x86_64 aarch64 ppc64le
- wdt
ExclusiveArch: x86_64 aarch64 ppc64le
- webkit2-sharp
ExclusiveArch: %mono_arches
- weld-parent
ExclusiveArch: %{java_arches} noarch
- whatip
ExcludeArch: s390x
- whipper
ExcludeArch: s390x
- whisper-cpp
ExclusiveArch: x86_64 aarch64 ppc64le
- why3
ExclusiveArch: %{ocaml_native_compiler}
- widevine-installer
ExclusiveArch: aarch64
- wildcard
ExcludeArch: %{ix86} s390x
- wine
ExclusiveArch: %{ix86} x86_64 aarch64
ExclusiveArch: %{ix86} x86_64
ExclusiveArch: %{ix86}
- wine-dxvk
ExclusiveArch: %{ix86} x86_64
- wine-mono
ExcludeArch: %{power64} s390x s390
- winetricks
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64
ExcludeArch: ppc64 ppc64le
- woff
ExcludeArch: %{ix86}
- workrave
ExcludeArch: %{ix86}
- ws-commons-util
ExclusiveArch: %{java_arches} noarch
- wsdl4j
ExclusiveArch: %{java_arches} noarch
- wult
ExclusiveArch: x86_64
- wxMaxima
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc sparcv9
- x2goclient
ExclusiveArch: x86_64
- x2gokdrive
ExcludeArch: %{ix86}
- x86-simd-sort
ExclusiveArch: x86_64
- xalan-j2
ExclusiveArch: %{java_arches} noarch
- xapps
ExcludeArch: %{ix86}
- xbean
ExclusiveArch: %{java_arches} noarch
- xbyak
ExclusiveArch: x86_64
- xbyak_aarch64
ExclusiveArch: aarch64
- xdg-desktop-portal
ExcludeArch: %{ix86}
- xdg-desktop-portal-gnome
ExcludeArch: %{ix86}
- xdg-desktop-portal-gtk
ExcludeArch: %{ix86}
- xdg-desktop-portal-hyprland
ExcludeArch: %{ix86}
- xe-guest-utilities-latest
ExclusiveArch: %{ix86} x86_64
- xed
ExcludeArch: %{ix86}
- xen
ExclusiveArch: x86_64 aarch64
- xephem
ExcludeArch: %{ix86}
- xerces-j2
ExclusiveArch: %{java_arches} noarch
- xeus
ExcludeArch: %{ix86}
- xeus-zmq
ExcludeArch: %{ix86}
- xfce4-sensors-plugin
ExcludeArch: s390 s390x
- xgap
ExcludeArch: %{ix86}
- xiphos
ExcludeArch: ppc64
- xml-commons-apis
ExclusiveArch: %{java_arches} noarch
- xml-commons-resolver
ExclusiveArch: %{java_arches} noarch
- xml-maven-plugin
ExclusiveArch: %{java_arches} noarch
- xmlada
ExclusiveArch: %{GPRbuild_arches}
- xmlgraphics-commons
ExclusiveArch: %{java_arches} noarch
- xmlpull
ExclusiveArch: %{java_arches} noarch
- xmlstreambuffer
ExclusiveArch: %{java_arches} noarch
- xmlunit
ExclusiveArch: %{java_arches} noarch
- xmvn
ExclusiveArch: %{java_arches} noarch
- xmvn-connector-ivy
ExclusiveArch: %{java_arches} noarch
- xmvn-generator
ExclusiveArch: %{java_arches}
- xnnpack
ExclusiveArch: x86_64 aarch64
- xnvme
ExcludeArch: %{ix86}
- xorg-x11-drv-amdgpu
ExcludeArch: s390 s390x
- xorg-x11-drv-armsoc
ExclusiveArch: %{arm} aarch64
- xorg-x11-drv-ati
ExcludeArch: s390 s390x
- xorg-x11-drv-fbdev
ExcludeArch: s390 s390x
- xorg-x11-drv-intel
ExclusiveArch: %{ix86} x86_64
- xorg-x11-drv-nouveau
ExcludeArch: s390 s390x
- xorg-x11-drv-openchrome
ExclusiveArch: %{ix86} x86_64
- xorg-x11-drv-qxl
ExcludeArch: s390 s390x
- xorg-x11-drv-synaptics
ExcludeArch: s390 s390x
- xorg-x11-drv-vesa
ExclusiveArch: %{ix86} x86_64
- xorg-x11-drv-vmware
ExclusiveArch: %{ix86} x86_64 ia64
- xreader
ExcludeArch: %{ix86}
- xsensors
ExcludeArch: %{ix86}
- xsp
ExclusiveArch: %mono_arches
- xstream
ExclusiveArch: %{java_arches} noarch
- xtb
ExcludeArch: s390x
- xtensor-python
ExcludeArch: armv7hl ppc64le s390x
- xz-java
ExclusiveArch: %{java_arches} noarch
- yarnpkg
ExclusiveArch: %{nodejs_arches}
- yices
ExcludeArch: %{ix86}
- yle-dl
ExcludeArch: %{ix86}
- yosys
ExcludeArch: %{ix86}
ExcludeArch: s390x
- zcfan
ExclusiveArch: x86_64
- zeal
ExclusiveArch: aarch64 x86_64
- zenon
ExclusiveArch: %{ocaml_native_compiler}
- zeromq-ada
ExclusiveArch: %{GPRbuild_arches}
- zfs-fuse
ExcludeArch: s390 s390x aarch64
- zig
ExclusiveArch: %{zig_arches}
- zile
ExcludeArch: ppc64le
- zimpl
ExcludeArch: %{ix86}
- zlib-ada
ExclusiveArch: %{GPRbuild_arches}
- zola
ExclusiveArch: %{rust_arches}
- zstr
ExcludeArch: %{ix86}
- zxcvbn-c
ExcludeArch: %{ix86}
- zycore-c
ExcludeArch: s390x
- zydis
ExcludeArch: s390x
1 month, 3 weeks
Architecture specific change in rpms/chatty.git
by githook-noreply@fedoraproject.org
The package rpms/chatty.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/chatty.git/commit/?id=29de29ef81d...
https://src.fedoraproject.org/cgit/rpms/chatty.git/commit/?id=3820f2a064a....
Change:
-ExcludeArch: ppc64le
+ExcludeArch: i686
Thanks.
Full change:
============
commit 240a9d5bdad87568566f363c950d2dfe227f5f1d
Author: Tomi Lähteenmäki <lihis(a)lihis.net>
Date: Fri Mar 22 12:22:49 2024 +0200
Upstream release 0.8.2
diff --git a/.gitignore b/.gitignore
index 249bfae..8db90a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,3 +43,4 @@
/libcmatrix-702b894675f12ecd43439b3b3eee66cc74899b82.tar.gz
/Chatty-v0.8.0.tar.gz
/Chatty-v0.8.1.tar.gz
+/Chatty-v0.8.2.tar.gz
diff --git a/chatty.spec b/chatty.spec
index b58775b..f3cd7a6 100644
--- a/chatty.spec
+++ b/chatty.spec
@@ -3,7 +3,7 @@
%global libcmatrix_commit 702b894675f12ecd43439b3b3eee66cc74899b82
Name: chatty
-Version: 0.8.1
+Version: 0.8.2
Release: %{autorelease}
Summary: A libpurple messaging client
@@ -31,8 +31,8 @@ BuildRequires: itstool
BuildRequires: pkgconfig(libebook-contacts-1.2)
BuildRequires: pkgconfig(libebook-1.2) >= 3.42.0
BuildRequires: pkgconfig(libfeedback-0.0)
-BuildRequires: pkgconfig(libadwaita-1) >= 1.2
-BuildRequires: pkgconfig(gtk4) >= 4.10
+BuildRequires: pkgconfig(libadwaita-1) >= 1.4
+BuildRequires: pkgconfig(gtk4) >= 4.12
BuildRequires: pkgconfig(gio-2.0) >= 2.66
BuildRequires: pkgconfig(gio-unix-2.0) >= 2.62
BuildRequires: pkgconfig(purple)
@@ -45,6 +45,7 @@ BuildRequires: pkgconfig(libgcrypt)
BuildRequires: pkgconfig(libsoup-3.0)
BuildRequires: pkgconfig(json-glib-1.0)
BuildRequires: pkgconfig(mm-glib) >= 1.12.0
+BuildRequires: pkgconfig(gstreamer-1.0)
BuildRequires: gspell-devel
BuildRequires: libolm-devel
BuildRequires: openssl1.1-devel
diff --git a/sources b/sources
index 4b80523..3469b26 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-SHA512 (Chatty-v0.8.1.tar.gz) = 962fe7ab333d9bc383ccc4dfeed1eca47365ee0016ef2b06c2268a72a4b34dc987bb3991e88ffe404401ce30171ce879c698a6b0d46526700a47bff3b0dbd749
+SHA512 (Chatty-v0.8.2.tar.gz) = 5422fb413d7ccaa0012daa61d227f26a6f1addc48934750b82b7a269439f1219a1794c52df95a2e9f564327b62cb64fc09afa994140913920dd32e6dccf27e1d
SHA512 (libcmatrix-702b894675f12ecd43439b3b3eee66cc74899b82.tar.gz) = 9fc66c3f5115c54af76cf90f191c4b7dd78d22ba160feadefefa32590deea01a51aa670fa34b1f849de35dbf95ab4a4c0dc2160db827636e89bd7a2e22b0a188
commit ef24e8037a6fa5796fa2db6d31be48e0514c933f
Author: Tomi Lähteenmäki <lihis(a)lihis.net>
Date: Fri Mar 22 12:08:31 2024 +0200
Switch to %{autorelease}
[skip changelog]
diff --git a/chatty.spec b/chatty.spec
index 4a82c67..b58775b 100644
--- a/chatty.spec
+++ b/chatty.spec
@@ -4,7 +4,7 @@
Name: chatty
Version: 0.8.1
-Release: 1%{?dist}
+Release: %{autorelease}
Summary: A libpurple messaging client
License: GPL-3.0-or-later AND LGPL-2.1-or-later
commit b82f4bc8f019f0432dce398a7fa097a0d141d48c
Author: Tomi Lähteenmäki <lihis(a)lihis.net>
Date: Fri Mar 22 12:07:25 2024 +0200
Remove superfluous changelog entries
These were added by an old version of rpmdev-bumpspec which couldn’t
deal with %autochangelog without %autorelease.
[skip changelog]
diff --git a/chatty.spec b/chatty.spec
index 3131025..4a82c67 100644
--- a/chatty.spec
+++ b/chatty.spec
@@ -130,11 +130,3 @@ echo "%{_libdir}/chatty" > %{buildroot}/%{_sysconfdir}/ld.so.conf.d/chatty.conf
%changelog
%autochangelog
-* Tue Jan 23 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 0.8.0-3
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
-
-* Fri Jan 19 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 0.8.0-2
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
-
-* Wed Jul 19 2023 Fedora Release Engineering <releng(a)fedoraproject.org> - 0.7.3-3
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
commit 5ed99ea4dfd518eb515491991bd8323229d6e25e
Author: Tomi Lähteenmäki <lihis(a)lihis.net>
Date: Sun Jan 28 17:04:30 2024 +0200
Upstream release v0.8.1 (fedora#2259895)
diff --git a/.gitignore b/.gitignore
index cd45f18..249bfae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,4 @@
/chatty-v0.8.0_rc0.tar.gz
/libcmatrix-702b894675f12ecd43439b3b3eee66cc74899b82.tar.gz
/Chatty-v0.8.0.tar.gz
+/Chatty-v0.8.1.tar.gz
diff --git a/chatty.spec b/chatty.spec
index 9910bc1..3131025 100644
--- a/chatty.spec
+++ b/chatty.spec
@@ -3,8 +3,8 @@
%global libcmatrix_commit 702b894675f12ecd43439b3b3eee66cc74899b82
Name: chatty
-Version: 0.8.0
-Release: 3%{?dist}
+Version: 0.8.1
+Release: 1%{?dist}
Summary: A libpurple messaging client
License: GPL-3.0-or-later AND LGPL-2.1-or-later
@@ -32,7 +32,7 @@ BuildRequires: pkgconfig(libebook-contacts-1.2)
BuildRequires: pkgconfig(libebook-1.2) >= 3.42.0
BuildRequires: pkgconfig(libfeedback-0.0)
BuildRequires: pkgconfig(libadwaita-1) >= 1.2
-BuildRequires: pkgconfig(gtk4) >= 4.8
+BuildRequires: pkgconfig(gtk4) >= 4.10
BuildRequires: pkgconfig(gio-2.0) >= 2.66
BuildRequires: pkgconfig(gio-unix-2.0) >= 2.62
BuildRequires: pkgconfig(purple)
@@ -129,12 +129,12 @@ echo "%{_libdir}/chatty" > %{buildroot}/%{_sysconfdir}/ld.so.conf.d/chatty.conf
%license COPYING
%changelog
+%autochangelog
* Tue Jan 23 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 0.8.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Fri Jan 19 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 0.8.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
-%autochangelog
* Wed Jul 19 2023 Fedora Release Engineering <releng(a)fedoraproject.org> - 0.7.3-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
diff --git a/sources b/sources
index 1fc51ac..4b80523 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-SHA512 (Chatty-v0.8.0.tar.gz) = 4fdba6f4f3787ddae37e52000cd9d882431a333520e8df07bc3f4e6f192894998600f5c6ff6a482eb0d7b4bd9c33cf541240e4aad87fe4dc79c82e3b630c7e48
+SHA512 (Chatty-v0.8.1.tar.gz) = 962fe7ab333d9bc383ccc4dfeed1eca47365ee0016ef2b06c2268a72a4b34dc987bb3991e88ffe404401ce30171ce879c698a6b0d46526700a47bff3b0dbd749
SHA512 (libcmatrix-702b894675f12ecd43439b3b3eee66cc74899b82.tar.gz) = 9fc66c3f5115c54af76cf90f191c4b7dd78d22ba160feadefefa32590deea01a51aa670fa34b1f849de35dbf95ab4a4c0dc2160db827636e89bd7a2e22b0a188
commit f830b5aa78afa54c67686919345142c168a19b90
Author: Fedora Release Engineering <releng(a)fedoraproject.org>
Date: Tue Jan 23 01:30:10 2024 +0000
Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
diff --git a/chatty.spec b/chatty.spec
index 80a34a5..9910bc1 100644
--- a/chatty.spec
+++ b/chatty.spec
@@ -4,7 +4,7 @@
Name: chatty
Version: 0.8.0
-Release: 2%{?dist}
+Release: 3%{?dist}
Summary: A libpurple messaging client
License: GPL-3.0-or-later AND LGPL-2.1-or-later
@@ -129,6 +129,9 @@ echo "%{_libdir}/chatty" > %{buildroot}/%{_sysconfdir}/ld.so.conf.d/chatty.conf
%license COPYING
%changelog
+* Tue Jan 23 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 0.8.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
* Fri Jan 19 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 0.8.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
commit 4b723b67d51b66afc8ca20e6b128117670c23e0c
Author: Fedora Release Engineering <releng(a)fedoraproject.org>
Date: Fri Jan 19 15:19:28 2024 +0000
Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
diff --git a/chatty.spec b/chatty.spec
index bace40a..80a34a5 100644
--- a/chatty.spec
+++ b/chatty.spec
@@ -4,7 +4,7 @@
Name: chatty
Version: 0.8.0
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: A libpurple messaging client
License: GPL-3.0-or-later AND LGPL-2.1-or-later
@@ -129,6 +129,9 @@ echo "%{_libdir}/chatty" > %{buildroot}/%{_sysconfdir}/ld.so.conf.d/chatty.conf
%license COPYING
%changelog
+* Fri Jan 19 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 0.8.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
%autochangelog
* Wed Jul 19 2023 Fedora Release Engineering <releng(a)fedoraproject.org> - 0.7.3-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
commit afed8117a85cbced37b19332f6815fac21418a0e
Author: Tomi Lähteenmäki <lihis(a)lihis.net>
Date: Wed Dec 27 20:19:29 2023 +0200
Don't run tests in parallel
On x86_64 rawhide (f40) history -test fails if tests
are run in parallel
diff --git a/chatty.spec b/chatty.spec
index deec47d..bace40a 100644
--- a/chatty.spec
+++ b/chatty.spec
@@ -93,7 +93,7 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/sm.puri.Chatty.deskt
# and the appstream file
LC_ALL=C.UTF-8 xvfb-run sh <<'SH'
-%meson_test -t 2
+%meson_test -t 2 --num-processes 1
SH
%install
commit 29de29ef81d70dec02ea45f8e9f97283fe684a01
Author: Tomi Lähteenmäki <lihis(a)lihis.net>
Date: Fri Dec 22 12:54:14 2023 +0200
Drop exclusion of arch ppc64le
diff --git a/chatty.spec b/chatty.spec
index 32d01d8..deec47d 100644
--- a/chatty.spec
+++ b/chatty.spec
@@ -19,8 +19,6 @@ Source1: https://source.puri.sm/Librem5/libcmatrix/-/archive/%{libcmatrix_commit
# project, to be used in other packages.
Patch0: 0001-hacky-hack.patch
-# Temporary. Test failure on ppc64le
-ExcludeArch: ppc64le
ExcludeArch: i686
BuildRequires: gcc
commit 3820f2a064aef167df9e72312f5ee957d552e34f
Author: Tomi Lähteenmäki <lihis(a)lihis.net>
Date: Fri Dec 22 11:32:06 2023 +0200
Upstream release v0.8.0
diff --git a/.gitignore b/.gitignore
index 982b096..cd45f18 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,3 +41,4 @@
/chatty-v0.7.3.tar.gz
/chatty-v0.8.0_rc0.tar.gz
/libcmatrix-702b894675f12ecd43439b3b3eee66cc74899b82.tar.gz
+/Chatty-v0.8.0.tar.gz
diff --git a/0001-Preliminary-port-to-libsoup-3.0-patch-v2.patch b/0001-Preliminary-port-to-libsoup-3.0-patch-v2.patch
deleted file mode 100644
index c4e2cb0..0000000
--- a/0001-Preliminary-port-to-libsoup-3.0-patch-v2.patch
+++ /dev/null
@@ -1,342 +0,0 @@
-From 920380afbb8776bc763737d0cc6cc8f894298b1e Mon Sep 17 00:00:00 2001
-From: marcin <marcin(a)ipv8.pl>
-Date: Sun, 7 Aug 2022 03:57:25 +0200
-Subject: [PATCH] Preliminary port to libsoup-3.0 (patch v2)
-
----
- meson.build | 2 +-
- src/cm-client.c | 7 ++--
- src/cm-net.c | 80 +++++++++++-------------------------------
- src/cm-utils-private.h | 3 --
- src/cm-utils.c | 58 +++++++++---------------------
- 5 files changed, 41 insertions(+), 109 deletions(-)
-
-diff --git a/meson.build b/meson.build
-index 295633a..f0ea89b 100644
---- a/meson.build
-+++ b/meson.build
-@@ -112,7 +112,7 @@ src_inc = include_directories('src')
- gio_dep = dependency('gio-2.0', version: '>= 2.66')
- cmatrix_deps = [
- dependency('libgcrypt'),
-- dependency('libsoup-2.4'),
-+ dependency('libsoup-3.0'),
- dependency('json-glib-1.0'),
- dependency('sqlite3', version: '>=3.26.0'),
- libolm_dep,
-diff --git a/src/cm-client.c b/src/cm-client.c
-index 0cb0fc8..4b54b3a 100644
---- a/src/cm-client.c
-+++ b/src/cm-client.c
-@@ -241,9 +241,8 @@ handle_matrix_glitches (CmClient *self,
- * The G_RESOLVER_ERROR may be suggesting that the hostname is wrong, but we don't
- * know if it's network/DNS/Proxy error. So keep retrying.
- */
-- if ((error->domain == SOUP_HTTP_ERROR &&
-- error->code <= SOUP_STATUS_TLS_FAILED &&
-- error->code > SOUP_STATUS_CANCELLED) ||
-+ if (error->domain == SOUP_TLD_ERROR ||
-+ error->domain == G_TLS_ERROR ||
- g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE) ||
- g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) ||
- /* Should we handle connection_refused, or just keep it for localhost? */
-@@ -947,7 +946,7 @@ gboolean
- cm_client_set_homeserver (CmClient *self,
- const char *homeserver)
- {
-- g_autoptr(SoupURI) uri = NULL;
-+ g_autoptr(GUri) uri = NULL;
- GString *server;
-
- g_return_val_if_fail (CM_IS_CLIENT (self), FALSE);
-diff --git a/src/cm-net.c b/src/cm-net.c
-index 8cca289..4eaa52a 100644
---- a/src/cm-net.c
-+++ b/src/cm-net.c
-@@ -182,7 +182,8 @@ queue_data (CmNet *self,
- GTask *task)
- {
- g_autoptr(SoupMessage) message = NULL;
-- g_autoptr(SoupURI) uri = NULL;
-+ g_autoptr(GUri) uri = NULL;
-+ g_autoptr(GBytes) content_data = NULL;
- GCancellable *cancellable;
- SoupMessagePriority msg_priority;
- int priority = 0;
-@@ -196,20 +197,20 @@ queue_data (CmNet *self,
- method == SOUP_METHOD_POST ||
- method == SOUP_METHOD_PUT);
-
-- uri = soup_uri_new (self->homeserver);
-- soup_uri_set_path (uri, uri_path);
-+ uri = g_uri_parse (self->homeserver, SOUP_HTTP_URI_FLAGS, NULL);
-+ uri = soup_uri_copy (uri, SOUP_URI_PATH, uri_path, SOUP_URI_NONE);
-
- if (self->access_token) {
- if (!query)
- query = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
- g_hash_table_replace (query, g_strdup ("access_token"), g_strdup (self->access_token));
-- soup_uri_set_query_from_form (uri, query);
-+ uri = soup_uri_copy(uri, SOUP_URI_QUERY, soup_form_encode_hash(query), SOUP_URI_NONE);
- g_hash_table_unref (query);
- }
-
- message = soup_message_new_from_uri (method, uri);
-- soup_message_headers_append (message->request_headers, "Accept-Encoding", "gzip");
-+ soup_message_headers_append (soup_message_get_request_headers(message), "Accept-Encoding", "gzip");
-
- priority = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "priority"));
-
-@@ -226,12 +227,14 @@ queue_data (CmNet *self,
-
- soup_message_set_priority (message, msg_priority);
-
-- if (data)
-- soup_message_set_request (message, "application/json", SOUP_MEMORY_TAKE, data, size);
-+ if (data) {
-+ content_data = g_bytes_new_static (data, size);
-+ soup_message_set_request_body_from_bytes (message, "application/json", content_data);
-+ }
-
- cancellable = g_task_get_cancellable (task);
- g_task_set_task_data (task, g_object_ref (message), g_object_unref);
-- soup_session_send_async (self->soup_session, message, cancellable,
-+ soup_session_send_async (self->soup_session, message, msg_priority, cancellable,
- session_send_cb, task);
- }
-
-@@ -324,7 +327,7 @@ cm_net_get_access_token (CmNet *self)
- * @size: The @data size in bytes
- * @uri_path: A string of the matrix uri path
- * @method: An interned string for GET, PUT, POST, etc.
-- * @query: (nullable): A query to pass to internal #SoupURI
-+ * @query: (nullable): A query to pass to internal #GUri
- * @cancellable: (nullable): A #GCancellable
- * @callback: The callback to run when completed
- * @user_data: user data for @callback
-@@ -375,7 +378,7 @@ cm_net_send_data_async (CmNet *self,
- * @object: (nullable) (transfer full): The data to send
- * @uri_path: A string of the matrix uri path
- * @method: An interned string for GET, PUT, POST, etc.
-- * @query: (nullable): A query to pass to internal #SoupURI
-+ * @query: (nullable): A query to pass to internal #GUri
- * @cancellable: (nullable): A #GCancellable
- * @callback: The callback to run when completed
- * @user_data: user data for @callback
-@@ -477,7 +480,7 @@ cm_net_get_file_async (CmNet *self,
- g_object_set_data (G_OBJECT (task), "file", enc_file);
- g_object_set_data_full (G_OBJECT (task), "msg", msg, g_object_unref);
-
-- soup_session_send_async (self->file_session, msg, cancellable,
-+ soup_session_send_async (self->file_session, msg, 0, cancellable,
- net_get_file_stream_cb, task);
- }
-
-@@ -531,42 +534,10 @@ put_file_async_cb (GObject *obj,
- }
- }
-
--static void
--put_file_chunk (GTask *task,
-- SoupMessage *msg)
--{
-- CmNet *self;
-- GInputStream *stream;
-- char buffer[8 * 1024];
-- gssize n_read;
--
-- g_assert (G_IS_TASK (task));
-- g_assert (SOUP_IS_MESSAGE (msg));
--
-- self = g_task_get_source_object (task);
-- g_assert (CM_IS_NET (self));
--
-- stream = g_object_get_data (G_OBJECT (task), "stream");
-- n_read = g_input_stream_read (stream, buffer, 8 * 1024, NULL, NULL);
--
-- if (n_read == 0)
-- {
-- soup_message_body_complete (msg->request_body);
-- }
-- else if (n_read == -1)
-- {
-- soup_session_cancel_message (self->file_session, msg, SOUP_STATUS_CANCELLED);
-- }
-- else
-- {
-- soup_message_body_append (msg->request_body, SOUP_MEMORY_COPY, buffer, n_read);
-- }
--}
--
- static void
- wrote_body_data_cb (GTask *task,
- SoupMessage *msg,
-- SoupBuffer *chunk)
-+ guint chunk_size)
- {
- GFileProgressCallback progress_cb;
- gpointer progress_user_data;
-@@ -614,18 +585,13 @@ cm_net_put_file_async (CmNet *self,
-
- url = g_strconcat (self->homeserver, "/_matrix/media/r0/upload", NULL);
- msg = soup_message_new (SOUP_METHOD_POST, url);
-- soup_uri_set_query_from_form (soup_message_get_uri (msg), query);
-+ soup_message_set_uri(msg, soup_uri_copy(soup_message_get_uri(msg), SOUP_URI_QUERY, soup_form_encode_hash(query), SOUP_URI_NONE));
-
- /* We're uploading files in chunk */
-- soup_message_headers_set_encoding (msg->request_headers, SOUP_ENCODING_CHUNKED);
-- soup_message_body_set_accumulate (msg->request_body, FALSE);
-- soup_message_headers_set_content_length (msg->request_headers,
-- cm_input_stream_get_size (cm_stream));
-- soup_message_headers_set_content_type (msg->request_headers,
-- cm_input_stream_get_content_type (cm_stream), NULL);
--
-- /* Use this once we port to libsoup-3 */
-- /* soup_message_set_request_body (msg, "fixme", G_INPUT_STREAM (cm_stream), -1); */
-+ soup_message_set_request_body (msg,
-+ cm_input_stream_get_content_type (cm_stream),
-+ G_INPUT_STREAM (cm_stream),
-+ cm_input_stream_get_size (cm_stream));
-
- g_task_set_task_data (task, g_object_ref (file), g_object_unref);
- g_object_set_data_full (G_OBJECT (task), "msg", msg, g_object_unref);
-@@ -634,15 +600,11 @@ cm_net_put_file_async (CmNet *self,
- local_task = g_task_new (self, cancellable, put_file_async_cb, self);
- g_task_set_task_data (local_task, task, g_object_unref);
-
-- g_signal_connect_object (msg, "wrote-headers",
-- G_CALLBACK (put_file_chunk), task, G_CONNECT_SWAPPED);
-- g_signal_connect_object (msg, "wrote-chunk",
-- G_CALLBACK (put_file_chunk), task, G_CONNECT_SWAPPED);
- if (progress_callback)
- g_signal_connect_object (msg, "wrote-body-data",
- G_CALLBACK (wrote_body_data_cb), task, G_CONNECT_SWAPPED);
-
-- soup_session_send_async (self->file_session, msg, cancellable,
-+ soup_session_send_async (self->file_session, msg, 0, cancellable,
- session_send_cb, local_task);
- }
-
-diff --git a/src/cm-utils-private.h b/src/cm-utils-private.h
-index 50694b9..669d250 100644
---- a/src/cm-utils-private.h
-+++ b/src/cm-utils-private.h
-@@ -31,9 +31,6 @@ JsonObject *cm_utils_json_object_get_object (JsonObject *object,
- const char *member);
- JsonArray *cm_utils_json_object_get_array (JsonObject *object,
- const char *member);
--
--JsonObject *cm_utils_get_message_json_object (SoupMessage *message,
-- const char *member);
- void cm_utils_clear (char *buffer,
- size_t length);
- void cm_utils_free_buffer (char *buffer);
-diff --git a/src/cm-utils.c b/src/cm-utils.c
-index 7cebce3..42894ec 100644
---- a/src/cm-utils.c
-+++ b/src/cm-utils.c
-@@ -241,16 +241,16 @@ cm_utils_home_server_valid (const char *homeserver)
- if (homeserver)
- {
- g_autofree char *server = NULL;
-- g_autoptr(SoupURI) uri = NULL;
-+ g_autoptr(GUri) uri = NULL;
-
- if (!strstr (homeserver, "//"))
- server = g_strconcat ("https://", homeserver, NULL);
-
-- uri = soup_uri_new (server ?: homeserver);
-+ uri = g_uri_parse (server ?: homeserver, SOUP_HTTP_URI_FLAGS, NULL);
-
-- valid = SOUP_URI_VALID_FOR_HTTP (uri);
-+ valid = !!uri;
- /* We need an absolute path URI */
-- valid = valid && *uri->host && g_str_equal (soup_uri_get_path (uri), "/");
-+ valid = valid && *g_uri_get_host(uri) && g_str_equal (g_uri_get_path (uri), "/");
- }
-
- return valid;
-@@ -465,38 +465,6 @@ cm_utils_json_object_get_array (JsonObject *object,
- return NULL;
- }
-
--JsonObject *
--cm_utils_get_message_json_object (SoupMessage *message,
-- const char *member)
--{
-- g_autoptr(JsonParser) parser = NULL;
-- g_autoptr(SoupBuffer) buffer = NULL;
-- JsonObject *object = NULL;
-- gboolean is_json;
--
-- if (!message || !message->response_body)
-- return NULL;
--
-- buffer = soup_message_body_flatten (message->response_body);
-- parser = json_parser_new ();
-- is_json = json_parser_load_from_data (parser, buffer->data, buffer->length, NULL);
--
-- if (is_json)
--{
-- JsonNode *root;
--
-- root = json_parser_get_root (parser);
--
-- if (root && JSON_NODE_HOLDS_OBJECT (root))
-- object = json_node_get_object (root);
--
-- if (member && object)
-- object = json_object_get_object_member (object, member);
-- }
--
-- return object ? json_object_ref (object) : NULL;
--}
--
- static void
- load_from_stream_cb (JsonParser *parser,
- GAsyncResult *result,
-@@ -575,11 +543,8 @@ uri_file_read_cb (GObject *object,
- return;
- }
-
-- soup_message_get_https_status (message, NULL, &err_flags);
--
- if (message &&
-- soup_message_get_https_status (message, NULL, &err_flags) &&
-- err_flags)
-+ (err_flags = soup_message_get_tls_peer_certificate_errors (message)))
- {
- guint timeout_id, timeout;
-
-@@ -624,6 +589,14 @@ message_network_event_cb (SoupMessage *msg,
- g_object_set_data_full (user_data, "address", address, g_object_unref);
- }
-
-+static gboolean
-+accept_certificate_callback (SoupMessage *msg, GTlsCertificate *certificate,
-+ GTlsCertificateFlags tls_errors, gpointer user_data)
-+{
-+ // Returning TRUE trusts it anyway.
-+ return TRUE;
-+}
-+
- void
- cm_utils_read_uri_async (const char *uri,
- guint timeout,
-@@ -670,9 +643,10 @@ cm_utils_read_uri_async (const char *uri,
- G_CALLBACK (message_network_event_cb), task,
- G_CONNECT_AFTER);
- session = soup_session_new ();
-- g_object_set (G_OBJECT (session), SOUP_SESSION_SSL_STRICT, FALSE, NULL);
-+ /* Accept invalid certificates */
-+ g_signal_connect (message, "accept-certificate", G_CALLBACK (accept_certificate_callback), NULL);
-
-- soup_session_send_async (session, message, cancel,
-+ soup_session_send_async (session, message, 0, cancel,
- uri_file_read_cb,
- g_steal_pointer (&task));
- }
---
-2.35.1
-
diff --git a/chatty-0.6.7-fix-gnome43.patch b/chatty-0.6.7-fix-gnome43.patch
deleted file mode 100644
index 4b9acec..0000000
--- a/chatty-0.6.7-fix-gnome43.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 142d5061ab183db885f307fd77c7a2f50f8f79d0 Mon Sep 17 00:00:00 2001
-From: Jeremy Bicha <jeremy.bicha(a)canonical.com>
-Date: Mon, 1 Aug 2022 10:05:56 -0400
-Subject: [PATCH] utils: update for GNOME Desktop 43 thumbnail API changes
-
-Fixes: #726
----
- src/chatty-utils.c | 21 +++++++++++++++++++++
- 1 file changed, 21 insertions(+)
-
-diff --git a/src/chatty-utils.c b/src/chatty-utils.c
-index c95d938c..6d38ad10 100644
---- a/src/chatty-utils.c
-+++ b/src/chatty-utils.c
-@@ -550,6 +550,26 @@ utils_create_thumbnail (GTask *task,
- return;
- }
-
-+#if defined(GNOME_DESKTOP_PLATFORM_VERSION) && GNOME_DESKTOP_PLATFORM_VERSION >= 43
-+ thumbnail = gnome_desktop_thumbnail_factory_generate_thumbnail (factory, uri, content_type, NULL, &error);
-+ if (!thumbnail) {
-+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to create thumbnail for file: %s (%s)", uri, error->message);
-+
-+ g_warning ("Failed to create thumbnail for file: %s", uri);
-+
-+ g_error_free (error);
-+ return;
-+ }
-+
-+ gnome_desktop_thumbnail_factory_save_thumbnail (factory, thumbnail, uri, mtime, NULL, &error);
-+ if (error) {
-+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to create thumbnail for file: %s (%s)", uri, error->message);
-+ g_error_free (error);
-+ return;
-+ }
-+
-+ g_task_return_boolean (task, TRUE);
-+#else
- thumbnail = gnome_desktop_thumbnail_factory_generate_thumbnail (factory, uri, content_type);
-
- if (thumbnail) {
-@@ -562,6 +582,7 @@ utils_create_thumbnail (GTask *task,
- }
-
- g_task_return_boolean (task, TRUE);
-+#endif
- }
-
- void
---
-GitLab
-
diff --git a/chatty-0.6.7-migrate-to-libcmatrix.patch b/chatty-0.6.7-migrate-to-libcmatrix.patch
deleted file mode 100644
index 241f1b1..0000000
--- a/chatty-0.6.7-migrate-to-libcmatrix.patch
+++ /dev/null
@@ -1,11284 +0,0 @@
-From 7799898cb96e7a8610f8aa0b8af8effa6aa98e64 Mon Sep 17 00:00:00 2001
-From: Mohammed Sadiq <sadiq(a)sadiqpk.org>
-Date: Wed, 9 Feb 2022 15:09:34 +0530
-Subject: [PATCH] matrix: Port to use libcmatrix
-
-the matrix client is now better implemented separately. Use it for
-matrix support and remove local matrix implementation
----
- .gitlab-ci.yml | 7 +-
- .gitmodules | 3 +
- meson.build | 22 +-
- src/chatty-application.c | 3 +
- src/chatty-chat-view.c | 11 +-
- src/chatty-history.c | 4 +-
- src/chatty-manager.c | 13 +
- src/chatty-manager.h | 1 +
- src/chatty-secret-store.c | 15 +-
- src/dialogs/chatty-settings-dialog.c | 194 +-
- src/matrix/chatty-ma-account.c | 711 +++----
- src/matrix/chatty-ma-account.h | 12 +-
- src/matrix/chatty-ma-buddy.c | 222 +--
- src/matrix/chatty-ma-buddy.h | 15 +-
- src/matrix/chatty-ma-chat.c | 1228 ++++--------
- src/matrix/chatty-ma-chat.h | 13 +-
- src/matrix/chatty-matrix.c | 172 +-
- src/matrix/chatty-matrix.h | 8 +-
- src/matrix/matrix-api.c | 2561 --------------------------
- src/matrix/matrix-api.h | 235 ---
- src/matrix/matrix-db.c | 1320 -------------
- src/matrix/matrix-db.h | 165 --
- src/matrix/matrix-enc.c | 1330 -------------
- src/matrix/matrix-enc.h | 88 -
- src/matrix/matrix-enums.h | 83 -
- src/matrix/matrix-net.c | 610 ------
- src/matrix/matrix-net.h | 59 -
- src/matrix/matrix-utils.c | 1 -
- src/matrix/matrix-utils.h | 2 +
- src/matrix/meson.build | 7 -
- src/meson.build | 1 +
- subprojects/libcmatrix | 1 +
- subprojects/libcmatrix.wrap | 4 +
- tests/matrix-api.c | 71 -
- tests/matrix-db.c | 230 ---
- tests/matrix-enc.c | 186 --
- tests/meson.build | 3 -
- 37 files changed, 993 insertions(+), 8618 deletions(-)
- delete mode 100644 src/matrix/matrix-api.c
- delete mode 100644 src/matrix/matrix-api.h
- delete mode 100644 src/matrix/matrix-db.c
- delete mode 100644 src/matrix/matrix-db.h
- delete mode 100644 src/matrix/matrix-enc.c
- delete mode 100644 src/matrix/matrix-enc.h
- delete mode 100644 src/matrix/matrix-enums.h
- delete mode 100644 src/matrix/matrix-net.c
- delete mode 100644 src/matrix/matrix-net.h
- create mode 160000 subprojects/libcmatrix
- create mode 100644 subprojects/libcmatrix.wrap
- delete mode 100644 tests/matrix-api.c
- delete mode 100644 tests/matrix-db.c
- delete mode 100644 tests/matrix-enc.c
-
-diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
-index 2af1724a..4c0193b9 100644
---- a/.gitlab-ci.yml
-+++ b/.gitlab-ci.yml
-@@ -25,6 +25,7 @@ build-pureos-gcc-byzantium-no-purple:
- stage: build
- script:
- - apt-get -y build-dep .
-+ - apt-get -y install git
- - export LC_ALL=C.UTF-8
- - meson . _build -Dpurple=disabled
- - ninja -C _build
-@@ -35,7 +36,7 @@ build-pureos-gcc-byzantium:
- stage: build
- script:
- - apt-get -y build-dep .
-- - apt-get -y install libgtk-3-bin xvfb
-+ - apt-get -y install libgtk-3-bin xvfb git
- - export LC_ALL=C.UTF-8
- - meson . _build -Db_coverage=true --werror
- - ninja -C _build
-@@ -51,7 +52,7 @@ test:debian-gcc:
- - build-pureos-gcc-byzantium
- script:
- - apt-get -y build-dep .
-- - apt-get -y install libgtk-3-bin xvfb lcov
-+ - apt-get -y install libgtk-3-bin xvfb lcov git
- - export G_DEBUG=fatal-warnings
- - export LC_ALL=C.UTF-8
- - xvfb-run -a -s "-screen 0 1024x768x24" ninja -C _build test
-@@ -66,7 +67,7 @@ check-po:
- - build-pureos-gcc-byzantium
- before_script:
- - apt-get -y update
-- - apt-get -y install intltool
-+ - apt-get -y install intltool git
- script:
- # barf on untranslated C files. Seems intltool
- # can't be told to exit with non-zero exit status
-diff --git a/.gitmodules b/.gitmodules
-index fa136361..f92a064f 100644
---- a/.gitmodules
-+++ b/.gitmodules
-@@ -1,3 +1,6 @@
- [submodule "subprojects/libgd"]
- path = subprojects/libgd
- url = https://gitlab.gnome.org/GNOME/libgd.git
-+[submodule "subprojects/libcmatrix"]
-+ path = subprojects/libcmatrix
-+ url = https://source.puri.sm/mohammed.sadiq/libcmatrix.git
-diff --git a/meson.build b/meson.build
-index 66df1e80..d85f5e53 100644
---- a/meson.build
-+++ b/meson.build
-@@ -21,21 +21,6 @@ config_h.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), get_option('lo
- config_h.set_quoted('PACKAGE_NAME', meson.project_name())
- config_h.set_quoted('PACKAGE_VERSION', meson.project_version())
-
--# TODO: Use has_headers: 'olm/olm.h' when we bump meson requirement
--libolm_dep = cc.find_library('olm', required: true)
--
--if (cc.has_function('olm_account_unpublished_fallback_key', dependencies: libolm_dep))
-- config_h.set('OLM_ACCOUNT_PICKLE_V4', true)
--else
-- config_h.set('OLM_ACCOUNT_PICKLE_V4', false)
--endif
--
--if (cc.has_function('olm_pk_key_from_private', dependencies: libolm_dep))
-- config_h.set('HAVE_OLM3', true)
--else
-- config_h.set('HAVE_OLM2', true)
--endif
--
- configure_file(
- output: 'config.h',
- configuration: config_h,
-@@ -118,6 +103,13 @@ libgd = subproject('libgd',
-
- libgd_dep = libgd.get_variable('libgd_dep')
-
-+libcmatrix = subproject('libcmatrix',
-+ default_options: [
-+ 'build-examples=false',
-+ ])
-+libcmatrix_dep = libcmatrix.get_variable('libcmatrix_dep')
-+
-+
- subdir('completion')
- subdir('data')
- subdir('help')
-diff --git a/src/chatty-application.c b/src/chatty-application.c
-index b8273ddd..78f5fe2d 100644
---- a/src/chatty-application.c
-+++ b/src/chatty-application.c
-@@ -28,6 +28,8 @@
- # include "version.h"
- #endif
-
-+#define CMATRIX_USE_EXPERIMENTAL_API
-+#include <cmatrix.h>
- #include <glib/gi18n.h>
- #include <handy.h>
-
-@@ -329,6 +331,7 @@ chatty_application_startup (GApplication *application)
- g_info ("%s %s, git version: %s", PACKAGE_NAME, PACKAGE_VERSION, GIT_VERSION);
-
- hdy_init ();
-+ cm_init (TRUE);
-
- g_set_application_name (_("Chats"));
-
-diff --git a/src/chatty-chat-view.c b/src/chatty-chat-view.c
-index ccb69c77..d1daeecb 100644
---- a/src/chatty-chat-view.c
-+++ b/src/chatty-chat-view.c
-@@ -285,6 +285,12 @@ chat_view_attachment_revealer_notify_cb (ChattyChatView *self)
- has_text = gtk_text_buffer_get_char_count (self->message_input_buffer) > 0;
-
- gtk_widget_set_visible (self->send_message_button, has_files || has_text);
-+
-+ if (!has_files)
-+ {
-+ gtk_widget_set_sensitive (self->send_file_button, TRUE);
-+ gtk_widget_set_sensitive (self->message_input, TRUE);
-+ }
- }
-
- static void
-@@ -429,6 +435,8 @@ chat_view_show_file_chooser (ChattyChatView *self)
-
- /* Currently multiple files are allowed only for MMS chats */
- gtk_widget_set_sensitive (self->send_file_button, CHATTY_IS_MM_CHAT (self->chat));
-+ /* Files with message content is supported only by MMS chats */
-+ gtk_widget_set_sensitive (self->message_input, CHATTY_IS_MM_CHAT (self->chat));
- }
-
- gtk_widget_destroy (dialog);
-@@ -445,8 +453,7 @@ chat_view_send_file_button_clicked_cb (ChattyChatView *self,
- if (CHATTY_IS_MM_CHAT (self->chat)) {
- chat_view_show_file_chooser (self);
- } else if (CHATTY_IS_MA_CHAT (self->chat)) {
-- /* TODO */
--
-+ chat_view_show_file_chooser (self);
- } else {
- #ifdef PURPLE_ENABLED
- chatty_pp_chat_show_file_upload (CHATTY_PP_CHAT (self->chat));
-diff --git a/src/chatty-history.c b/src/chatty-history.c
-index 9a75ae9c..42b4f08b 100644
---- a/src/chatty-history.c
-+++ b/src/chatty-history.c
-@@ -3017,8 +3017,8 @@ history_load_account (ChattyHistory *self,
-
- if (!user_name || !*user_name) {
- g_task_return_new_error (task,
-- G_IO_ERROR, G_IO_ERROR_FAILED,
-- "Error: username name is empty");
-+ G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
-+ "Username name is empty");
- return;
- }
-
-diff --git a/src/chatty-manager.c b/src/chatty-manager.c
-index 3868ecb0..0cb73bf5 100644
---- a/src/chatty-manager.c
-+++ b/src/chatty-manager.c
-@@ -18,6 +18,8 @@
- #define LIBFEEDBACK_USE_UNSTABLE_API
- #include <libfeedback.h>
- #include <glib/gi18n.h>
-+#define CMATRIX_USE_EXPERIMENTAL_API
-+#include "cmatrix.h"
- #include "contrib/gtk.h"
-
- #include "chatty-settings.h"
-@@ -749,3 +751,14 @@ chatty_manager_get_history (ChattyManager *self)
-
- return self->history;
- }
-+
-+gpointer
-+chatty_manager_matrix_client_new (ChattyManager *self)
-+{
-+ g_return_val_if_fail (CHATTY_IS_MANAGER (self), NULL);
-+
-+ if (!self->matrix || !chatty_settings_get_experimental_features (chatty_settings_get_default ()))
-+ return NULL;
-+
-+ return chatty_matrix_client_new (self->matrix);
-+}
-diff --git a/src/chatty-manager.h b/src/chatty-manager.h
-index 47e690ae..28ea71b2 100644
---- a/src/chatty-manager.h
-+++ b/src/chatty-manager.h
-@@ -64,5 +64,6 @@ gboolean chatty_manager_set_uri (ChattyManager *self,
- const char *uri,
- const char *name);
- ChattyHistory *chatty_manager_get_history (ChattyManager *self);
-+gpointer chatty_manager_matrix_client_new (ChattyManager *self);
-
- G_END_DECLS
-diff --git a/src/chatty-secret-store.c b/src/chatty-secret-store.c
-index 4e9c8d9b..94f4b24a 100644
---- a/src/chatty-secret-store.c
-+++ b/src/chatty-secret-store.c
-@@ -89,10 +89,11 @@ chatty_secret_store_save_async (ChattyAccount *account,
- /* XXX: We use a dumb string search, so don't change the order or spacing of the format string */
- credentials = g_strdup_printf ("{\"username\": \"%s\", \"password\": \"%s\","
- "\"access-token\": \"%s\", "
-- "\"pickle-key\": \"%s\", \"device-id\": \"%s\"}",
-+ "\"pickle-key\": \"%s\", \"device-id\": \"%s\", \"enabled\": \"%s\"}",
- chatty_item_get_username (CHATTY_ITEM (account)),
- password ? password : "", token ? token : "",
-- key ? key : "", device_id);
-+ key ? key : "", device_id,
-+ chatty_account_get_enabled (account) ? "true" : "false");
- schema = secret_store_get_schema ();
- server = chatty_ma_account_get_homeserver (CHATTY_MA_ACCOUNT (account));
- label = g_strdup_printf (_("Chatty password for \"%s\""), username);
-@@ -142,19 +143,15 @@ secret_load_cb (GObject *object,
- }
-
- for (GList *item = secrets; item; item = item->next) {
-- ChattyMaAccount *account;
--
- if (!accounts)
- accounts = g_ptr_array_new_full (5, g_object_unref);
-
-- account = chatty_ma_account_new_secret (item->data);
--
-- if (account)
-- g_ptr_array_insert (accounts, -1, account);
-+ if (item->data)
-+ g_ptr_array_insert (accounts, -1, item->data);
- }
-
- if (secrets)
-- g_list_free_full (secrets, g_object_unref);
-+ g_list_free (secrets);
-
- g_task_return_pointer (task, accounts, (GDestroyNotify)g_ptr_array_unref);
- }
-diff --git a/src/dialogs/chatty-settings-dialog.c b/src/dialogs/chatty-settings-dialog.c
-index bcd505e6..a2dbd1cc 100644
---- a/src/dialogs/chatty-settings-dialog.c
-+++ b/src/dialogs/chatty-settings-dialog.c
-@@ -30,6 +30,8 @@
- #endif
-
- #include <glib/gi18n.h>
-+#define CMATRIX_USE_EXPERIMENTAL_API
-+#include "cmatrix.h"
-
- #include "chatty-utils.h"
- #include "matrix-utils.h"
-@@ -241,83 +243,153 @@ matrix_home_server_verify_cb (GObject *object,
- ChattySettingsDialog *self = user_data;
- g_autoptr(ChattyMaAccount) account = NULL;
- g_autoptr(GError) error = NULL;
-- const char *username, *password, *server;
-+ const char *homeserver, *server;
-
- g_assert (CHATTY_IS_SETTINGS_DIALOG (self));
-
- settings_dialog_set_save_state (self, FALSE);
-+ /* verified homeserver URL */
-+ homeserver = cm_client_get_homeserver_finish (CM_CLIENT (object), result, &error);
-+ /* homeserver URL entered by the user */
- server = gtk_entry_get_text (GTK_ENTRY (self->matrix_homeserver_entry));
-
-- if (!matrix_utils_verify_homeserver_finish (result, &error)) {
-+ if (!homeserver) {
- gtk_widget_set_sensitive (self->add_button, FALSE);
- g_clear_handle_id (&self->revealer_timeout_id, g_source_remove);
-- gtk_label_set_text (GTK_LABEL (self->notification_label),
-- _("Failed to verify server"));
-- gtk_revealer_set_reveal_child (GTK_REVEALER (self->notification_revealer), TRUE);
-- self->revealer_timeout_id = g_timeout_add_seconds (5, dialog_notification_timeout_cb, self);
-- return;
-- }
--
-- username = gtk_entry_get_text (GTK_ENTRY (self->new_account_id_entry));
-- password = gtk_entry_get_text (GTK_ENTRY (self->new_password_entry));
--
-- account = chatty_ma_account_new (username, password);
-- chatty_ma_account_set_homeserver (account, server);
-- chatty_manager_save_account_async (chatty_manager_get_default (), CHATTY_ACCOUNT (account),
-- NULL, settings_save_account_cb, self);
--}
-
--static void
--chatty_settings_save_matrix (ChattySettingsDialog *self,
-- const char *user_id,
-- const char *password);
--static void
--matrix_home_server_got_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- ChattySettingsDialog *self = user_data;
-- g_autoptr(ChattyMaAccount) account = NULL;
-- g_autofree char *home_server = NULL;
-+ if (error)
-+ g_dbus_error_strip_remote_error (error);
-
-- g_assert (CHATTY_IS_SETTINGS_DIALOG (self));
-+ if (server && *server) {
-+ g_autofree char *label = NULL;
-
-- home_server = matrix_utils_get_homeserver_finish (result, NULL);
-+ if (error)
-+ label = g_strdup_printf (_("Failed to verify server: %s"), error->message);
-+ else
-+ label = g_strdup (_("Failed to verify server"));
-
-- if (g_cancellable_is_cancelled (self->cancellable)) {
-- settings_dialog_set_save_state (self, FALSE);
-- return;
-- }
--
-- if (home_server && *home_server) {
-- const char *username, *password;
--
-- username = gtk_entry_get_text (GTK_ENTRY (self->new_account_id_entry));
-- password = gtk_entry_get_text (GTK_ENTRY (self->new_password_entry));
--
-- gtk_entry_set_text (GTK_ENTRY (self->matrix_homeserver_entry), home_server);
-- chatty_settings_save_matrix (self, username, password);
-- } else {
-- settings_dialog_set_save_state (self, FALSE);
-- gtk_widget_set_sensitive (self->add_button, FALSE);
-+ gtk_label_set_text (GTK_LABEL (self->notification_label), label);
-+ } else {
-+ settings_dialog_set_save_state (self, FALSE);
-+ gtk_label_set_text (GTK_LABEL (self->notification_label),
-+ _("Couldn't get Home server address"));
-+ gtk_widget_show (self->matrix_homeserver_entry);
-+ gtk_entry_grab_focus_without_selecting (GTK_ENTRY (self->matrix_homeserver_entry));
-+ gtk_editable_set_position (GTK_EDITABLE (self->matrix_homeserver_entry), -1);
-+ }
-
-- g_clear_handle_id (&self->revealer_timeout_id, g_source_remove);
-- gtk_label_set_text (GTK_LABEL (self->notification_label),
-- _("Couldn't get Home server address"));
- gtk_revealer_set_reveal_child (GTK_REVEALER (self->notification_revealer), TRUE);
- self->revealer_timeout_id = g_timeout_add_seconds (5, dialog_notification_timeout_cb, self);
--
-- gtk_widget_show (self->matrix_homeserver_entry);
-- gtk_entry_grab_focus_without_selecting (GTK_ENTRY (self->matrix_homeserver_entry));
-- gtk_editable_set_position (GTK_EDITABLE (self->matrix_homeserver_entry), -1);
-+ return;
- }
-+
-+ account = chatty_ma_account_new_from_client (CM_CLIENT (object));
-+ chatty_manager_save_account_async (chatty_manager_get_default (), CHATTY_ACCOUNT (account),
-+ NULL, settings_save_account_cb, self);
- }
-
-+/* static void */
-+/* chatty_settings_save_matrix (ChattySettingsDialog *self, */
-+/* const char *user_id, */
-+/* const char *password); */
-+/* static void */
-+/* matrix_home_server_got_cb (GObject *object, */
-+/* GAsyncResult *result, */
-+/* gpointer user_data) */
-+/* { */
-+/* ChattySettingsDialog *self = user_data; */
-+/* g_autoptr(ChattyMaAccount) account = NULL; */
-+/* const char *home_server = NULL; */
-+
-+/* g_assert (CHATTY_IS_SETTINGS_DIALOG (self)); */
-+
-+/* home_server = cm_client_get_homeserver_finish (CM_CLIENT (object), result, NULL); */
-+
-+/* if (g_cancellable_is_cancelled (self->cancellable)) { */
-+/* settings_dialog_set_save_state (self, FALSE); */
-+/* return; */
-+/* } */
-+
-+/* if (home_server && *home_server) { */
-+/* const char *username, *password; */
-+
-+/* username = gtk_entry_get_text (GTK_ENTRY (self->new_account_id_entry)); */
-+/* password = gtk_entry_get_text (GTK_ENTRY (self->new_password_entry)); */
-+
-+/* gtk_entry_set_text (GTK_ENTRY (self->matrix_homeserver_entry), home_server); */
-+/* chatty_settings_save_matrix (self, username, password); */
-+/* } else { */
-+/* settings_dialog_set_save_state (self, FALSE); */
-+/* gtk_widget_set_sensitive (self->add_button, FALSE); */
-+
-+/* g_clear_handle_id (&self->revealer_timeout_id, g_source_remove); */
-+/* gtk_label_set_text (GTK_LABEL (self->notification_label), */
-+/* _("Couldn't get Home server address")); */
-+/* gtk_revealer_set_reveal_child (GTK_REVEALER (self->notification_revealer), TRUE); */
-+/* self->revealer_timeout_id = g_timeout_add_seconds (5, dialog_notification_timeout_cb, self); */
-+
-+/* gtk_widget_show (self->matrix_homeserver_entry); */
-+/* gtk_entry_grab_focus_without_selecting (GTK_ENTRY (self->matrix_homeserver_entry)); */
-+/* gtk_editable_set_position (GTK_EDITABLE (self->matrix_homeserver_entry), -1); */
-+/* } */
-+/* } */
-+
-+/* static void */
-+/* settings_matrix_login_cb (GObject *obj, */
-+/* GAsyncResult *result, */
-+/* gpointer user_data) */
-+/* { */
-+/* ChattySettingsDialog *self = user_data; */
-+/* CmClient *cm_client = CM_CLIENT (obj); */
-+/* g_autoptr(ChattyMaAccount) account = NULL; */
-+/* g_autoptr(GError) error = NULL; */
-+/* const char *username, *password, *server; */
-+/* const char *action; */
-+
-+/* g_assert (CHATTY_IS_SETTINGS_DIALOG (self)); */
-+
-+/* settings_dialog_set_save_state (self, FALSE); */
-+/* cm_client_login_finish (CM_CLIENT (obj), result, &error); */
-+
-+/* if (g_cancellable_is_cancelled (self->cancellable)) */
-+/* return; */
-+
-+/* action = g_object_get_data (G_OBJECT (result), "action"); */
-+
-+/* if (error && g_strcmp0 (action, "get-homeserver") == 0) { */
-+/* gtk_widget_set_sensitive (self->add_button, FALSE); */
-+/* gtk_widget_show (self->matrix_homeserver_entry); */
-+/* gtk_entry_grab_focus_without_selecting (GTK_ENTRY (self->matrix_homeserver_entry)); */
-+/* gtk_editable_set_position (GTK_EDITABLE (self->matrix_homeserver_entry), -1); */
-+/* return; */
-+/* } else if (error && g_strcmp0 (action, "verify-homeserver") == 0) { */
-+/* g_clear_handle_id (&self->revealer_timeout_id, g_source_remove); */
-+/* gtk_label_set_text (GTK_LABEL (self->notification_label), */
-+/* _("Failed to verify server")); */
-+/* gtk_revealer_set_reveal_child (GTK_REVEALER (self->notification_revealer), TRUE); */
-+/* self->revealer_timeout_id = g_timeout_add_seconds (5, dialog_notification_timeout_cb, self); */
-+
-+/* gtk_widget_set_sensitive (self->add_button, FALSE); */
-+/* settings_apply_style (self->matrix_homeserver_entry, "error"); */
-+/* gtk_entry_grab_focus_without_selecting (GTK_ENTRY (self->matrix_homeserver_entry)); */
-+/* return; */
-+/* } else if (error) { */
-+/* g_warning ("Error: %s", error->message); */
-+/* return; */
-+/* } */
-+
-+/* account = chatty_ma_account_new_from_client (cm_client); */
-+/* chatty_manager_save_account_async (chatty_manager_get_default (), CHATTY_ACCOUNT (account), */
-+/* NULL, settings_save_account_cb, self); */
-+
-+/* } */
-+
- static void
- chatty_settings_save_matrix (ChattySettingsDialog *self,
- const char *user_id,
- const char *password)
- {
-+ g_autoptr(CmClient) cm_client = NULL;
- GtkEntry *entry;
- const char *uri;
-
-@@ -332,12 +404,14 @@ chatty_settings_save_matrix (ChattySettingsDialog *self,
- entry = GTK_ENTRY (self->matrix_homeserver_entry);
- uri = gtk_entry_get_text (entry);
-
-- if (uri && *uri)
-- matrix_utils_verify_homeserver_async (uri, 30, self->cancellable,
-- matrix_home_server_verify_cb, self);
-- else
-- matrix_utils_get_homeserver_async (user_id, 10, self->cancellable,
-- matrix_home_server_got_cb, self);
-+ cm_client = chatty_manager_matrix_client_new (chatty_manager_get_default ());
-+ cm_client_set_user_id (cm_client, user_id);
-+ cm_client_set_login_id (cm_client, user_id);
-+ cm_client_set_homeserver (cm_client, uri);
-+ cm_client_set_password (cm_client, password);
-+ cm_client_get_homeserver_async (cm_client, self->cancellable,
-+ matrix_home_server_verify_cb,
-+ self);
- }
-
- static void
-diff --git a/src/matrix/chatty-ma-account.c b/src/matrix/chatty-ma-account.c
-index 54cc9a61..ba4838fd 100644
---- a/src/matrix/chatty-ma-account.c
-+++ b/src/matrix/chatty-ma-account.c
-@@ -1,7 +1,7 @@
- /* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
- /* chatty-ma-account.c
- *
-- * Copyright 2020 Purism SPC
-+ * Copyright 2020, 2022 Purism SPC
- *
- * Author(s):
- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-@@ -18,9 +18,6 @@
-
- #include "chatty-secret-store.h"
- #include "chatty-history.h"
--#include "matrix-api.h"
--#include "matrix-enc.h"
--#include "matrix-db.h"
- #include "matrix-utils.h"
- #include "chatty-utils.h"
- #include "chatty-ma-chat.h"
-@@ -42,33 +39,27 @@ struct _ChattyMaAccount
-
- char *name;
-
-- MatrixApi *matrix_api;
-- MatrixEnc *matrix_enc;
-- MatrixDb *matrix_db;
-+ CmMatrix *cm_matrix;
-+ CmClient *cm_client;
-+
- HdyValueObject *device_fp;
-
- ChattyHistory *history_db;
-
-- char *pickle_key;
-- char *next_batch;
--
- GListStore *chat_list;
-- /* this will be moved to chat_list after login succeeds */
-- GPtrArray *db_chat_list;
- GdkPixbuf *avatar;
- ChattyFileInfo *avatar_file;
-
- ChattyStatus status;
-- gboolean homeserver_valid;
-- gboolean account_enabled;
-+ /* Temporarely store the account enabled status */
-+ gboolean account_enabled_in_store;
-
- gboolean avatar_is_loading;
- /* @is_loading is set when the account is loading
- * from db and set to not save the change to db.
- */
- gboolean is_loading;
-- gboolean save_account_pending;
-- gboolean save_password_pending;
-+ gboolean save_pending;
-
- /* for sending events, incremented for each event */
- int event_id;
-@@ -83,7 +74,7 @@ G_DEFINE_TYPE (ChattyMaAccount, chatty_ma_account, CHATTY_TYPE_ACCOUNT)
- if (self->status != _status) { \
- self->status = _status; \
- g_object_notify (G_OBJECT (self), "status"); \
-- CHATTY_TRACE (matrix_api_get_username (self->matrix_api), \
-+ CHATTY_TRACE (cm_client_get_user_id (self->cm_client), \
- "status changed, connected: %s, user:", \
- _status == CHATTY_CONNECTING ? "connecting" : \
- CHATTY_LOG_BOOL (_status == CHATTY_CONNECTED)); \
-@@ -113,22 +104,6 @@ ma_account_get_avatar_pixbuf_cb (GObject *object,
- }
- }
-
--static void
--ma_account_get_avatar_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(ChattyMaAccount) self = user_data;
--
-- self->avatar_is_loading = FALSE;
--
-- if (matrix_api_get_file_finish (self->matrix_api, result, NULL)) {
-- g_clear_object (&self->avatar);
-- g_signal_emit_by_name (self, "avatar-changed");
-- chatty_history_update_user (self->history_db, CHATTY_ACCOUNT (self));
-- }
--}
--
- static ChattyMaChat *
- matrix_find_chat_with_id (ChattyMaAccount *self,
- const char *room_id,
-@@ -157,37 +132,6 @@ matrix_find_chat_with_id (ChattyMaAccount *self,
- return NULL;
- }
-
--static void
--matrix_parse_device_data (ChattyMaAccount *self,
-- JsonObject *to_device)
--{
-- JsonObject *object;
-- JsonArray *array;
-- guint length = 0;
--
-- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-- g_assert (to_device);
--
-- array = matrix_utils_json_object_get_array (to_device, "events");
-- if (array)
-- length = json_array_get_length (array);
--
-- if (length)
-- CHATTY_TRACE_MSG ("Got %d to-device events", length);
--
-- for (guint i = 0; i < length; i++) {
-- const char *type;
--
-- object = json_array_get_object_element (array, i);
-- type = matrix_utils_json_object_get_string (object, "type");
--
-- CHATTY_TRACE_MSG ("parsing to-device event, type: %s", type);
--
-- if (g_strcmp0 (type, "m.room.encrypted") == 0)
-- matrix_enc_handle_room_encrypted (self->matrix_enc, object);
-- }
--}
--
- static void
- matrix_parse_room_data (ChattyMaAccount *self,
- JsonObject *rooms)
-@@ -214,17 +158,7 @@ matrix_parse_room_data (ChattyMaAccount *self,
-
- CHATTY_TRACE (room_id->data, "joined room, new: %d, room:", !!chat);
-
-- if (!chat) {
-- chat = g_object_new (CHATTY_TYPE_MA_CHAT, "room-id", room_id->data, NULL);
-- chatty_ma_chat_set_matrix_db (chat, self->matrix_db);
-- chatty_ma_chat_set_history_db (chat, self->history_db);
-- /* TODO */
-- /* chatty_ma_chat_set_last_batch (chat, self->next_batch); */
-- chatty_ma_chat_set_data (chat, CHATTY_ACCOUNT (self), self->matrix_api, self->matrix_enc);
-- g_object_set (chat, "json-data", room_data, NULL);
-- g_list_store_append (self->chat_list, chat);
-- g_object_unref (chat);
-- } else if (room_data) {
-+ if (chat && room_data) {
- g_object_set (chat, "json-data", room_data, NULL);
- g_list_model_items_changed (G_LIST_MODEL (self->chat_list), index, 1, 1);
- }
-@@ -262,7 +196,8 @@ handle_get_homeserver (ChattyMaAccount *self,
-
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
- g_warning ("Couldn't connect to ‘/.well-known/matrix/client’ ");
-- matrix_api_set_homeserver (self->matrix_api, "https://chat.librem.one");
-+ cm_client_set_homeserver (self->cm_client, "https://chat.librem.one");
-+ cm_client_start_sync (self->cm_client);
- }
- }
-
-@@ -286,10 +221,10 @@ handle_password_login (ChattyMaAccount *self,
-
- /* If no error, Api is informing us that logging in succeeded.
- * Let’s update matrix_enc & set device keys to upload */
-- if (g_error_matches (error, MATRIX_ERROR, M_BAD_PASSWORD)) {
-- GtkWidget *dialog, *content, *header_bar;
-+ if (g_error_matches (error, CM_ERROR, M_BAD_PASSWORD)) {
-+ GtkWidget *dialog, *content, *header_bar, *label;
- GtkWidget *cancel_btn, *ok_btn, *entry;
-- g_autofree char *label = NULL;
-+ g_autofree char *message = NULL;
- const char *password;
- int response;
-
-@@ -303,9 +238,12 @@ handle_password_login (ChattyMaAccount *self,
- content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
- gtk_container_set_border_width (GTK_CONTAINER (content), 18);
- gtk_box_set_spacing (GTK_BOX (content), 12);
-- label = g_strdup_printf (_("Please enter password for “%s”"),
-- matrix_api_get_login_username (self->matrix_api));
-- gtk_container_add (GTK_CONTAINER (content), gtk_label_new (label));
-+ message = g_strdup_printf (_("Please enter password for “%s”, homeserver: %s"),
-+ cm_client_get_login_id (self->cm_client),
-+ cm_client_get_homeserver (self->cm_client));
-+ label = gtk_label_new (message);
-+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
-+ gtk_container_add (GTK_CONTAINER (content), label);
- entry = gtk_entry_new ();
- gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
- gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
-@@ -334,7 +272,7 @@ handle_password_login (ChattyMaAccount *self,
- if (response != GTK_RESPONSE_ACCEPT || !password || !*password) {
- chatty_account_set_enabled (CHATTY_ACCOUNT (self), FALSE);
- } else {
-- matrix_api_set_password (self->matrix_api, password);
-+ cm_client_set_password (self->cm_client, password);
- self->is_loading = TRUE;
- chatty_account_set_enabled (CHATTY_ACCOUNT (self), FALSE);
- self->is_loading = FALSE;
-@@ -345,49 +283,12 @@ handle_password_login (ChattyMaAccount *self,
- }
-
- if (!error) {
-- self->save_password_pending = TRUE;
-- chatty_account_save (CHATTY_ACCOUNT (self));
-+ self->save_pending = TRUE;
-
-- ma_account_update_status (self, CHATTY_CONNECTED);
-- }
--}
--
--static void
--handle_upload_key (ChattyMaAccount *self,
-- JsonObject *object,
-- GError *error)
--{
-- g_assert (CHATTY_IS_MA_ACCOUNT (self));
--
-- if (object) {
-- /* XXX: check later */
-- matrix_enc_publish_one_time_keys (self->matrix_enc);
--
-- self->save_account_pending = TRUE;
- chatty_account_save (CHATTY_ACCOUNT (self));
-- }
--}
--
--static ChattyMaChat *
--ma_account_find_chat (ChattyMaAccount *self,
-- const char *room_id)
--{
-- GPtrArray *chats = self->db_chat_list;
--
-- g_assert (CHATTY_IS_MA_ACCOUNT (self));
--
-- if (!room_id || !*room_id || !chats)
-- return NULL;
-
-- for (guint i = 0; i < chats->len; i++) {
-- const char *chat_name;
--
-- chat_name = chatty_chat_get_chat_name (chats->pdata[i]);
-- if (g_strcmp0 (chat_name, room_id) == 0)
-- return g_object_ref (chats->pdata[i]);
-+ ma_account_update_status (self, CHATTY_CONNECTED);
- }
--
-- return NULL;
- }
-
- static void
-@@ -395,31 +296,6 @@ handle_get_joined_rooms (ChattyMaAccount *self,
- JsonObject *object,
- GError *error)
- {
-- JsonArray *array;
-- guint length = 0;
--
-- g_assert (CHATTY_IS_MA_ACCOUNT (self));
--
-- array = matrix_utils_json_object_get_array (object, "joined_rooms");
--
-- if (array)
-- length = json_array_get_length (array);
--
-- for (guint i = 0; i < length; i++) {
-- g_autoptr(ChattyMaChat) chat = NULL;
-- const char *room_id;
--
-- room_id = json_array_get_string_element (array, i);
-- chat = ma_account_find_chat (self, room_id);
-- if (!chat)
-- chat = g_object_new (CHATTY_TYPE_MA_CHAT, "room-id", room_id, NULL);
-- chatty_ma_chat_set_matrix_db (chat, self->matrix_db);
-- chatty_ma_chat_set_history_db (chat, self->history_db);
-- chatty_ma_chat_set_data (chat, CHATTY_ACCOUNT (self), self->matrix_api, self->matrix_enc);
-- g_list_store_append (self->chat_list, chat);
-- }
--
-- g_clear_pointer (&self->db_chat_list, g_ptr_array_unref);
- }
-
- static void
-@@ -436,28 +312,25 @@ handle_red_pill (ChattyMaAccount *self,
-
- ma_account_update_status (self, CHATTY_CONNECTED);
-
-- object = matrix_utils_json_object_get_object (root, "to_device");
-- if (object)
-- matrix_parse_device_data (self, object);
--
- object = matrix_utils_json_object_get_object (root, "rooms");
- if (object)
- matrix_parse_room_data (self, object);
--
-- self->save_account_pending = TRUE;
-- chatty_account_save (CHATTY_ACCOUNT (self));
- }
-
- static void
--matrix_account_sync_cb (ChattyMaAccount *self,
-- MatrixApi *api,
-- MatrixAction action,
-- JsonObject *object,
-- GError *error)
--{
-+cm_account_sync_cb (ChattyMaAccount *self,
-+ CmClient *cm_client,
-+ CmAction action,
-+ const char *event,
-+ const char *json,
-+ GError *error)
-+{
-+ g_autoptr(JsonNode) node = NULL;
-+ JsonObject *object;
-+
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-- g_assert (MATRIX_IS_API (api));
-- g_assert (self->matrix_api == api);
-+ g_assert (CM_IS_CLIENT (self->cm_client));
-+ g_assert (self->cm_client == cm_client);
-
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- return;
-@@ -478,46 +351,58 @@ matrix_account_sync_cb (ChattyMaAccount *self,
- return;
- }
-
-- if (!error && !matrix_api_is_sync (self->matrix_api) &&
-- action != MATRIX_GET_JOINED_ROOMS) {
-- ma_account_update_status (self, CHATTY_DISCONNECTED);
-- return;
-+ /* TODO */
-+ /* if (!error && !cm_client_is_sync (self->cm_client) && */
-+ /* action != CM_GET_JOINED_ROOMS) { */
-+ /* ma_account_update_status (self, CHATTY_DISCONNECTED); */
-+ /* return; */
-+ /* } */
-+
-+ if (json) {
-+ node = json_from_string (json, &error);
-+
-+ if (error || !JSON_NODE_HOLDS_OBJECT (node)) {
-+ if (error)
-+ g_warning ("Warning parsing json: %s", error->message);
-+ else
-+ g_warning ("JsonNode doesn't hold an object");
-+ return;
-+ };
-+
-+ object = json_node_get_object (node);
- }
-
- switch (action) {
-- case MATRIX_BLUE_PILL:
-+ case CM_BLUE_PILL:
- return;
-
-- case MATRIX_GET_HOMESERVER:
-+ case CM_GET_HOMESERVER:
- handle_get_homeserver (self, object, error);
- return;
-
-- case MATRIX_VERIFY_HOMESERVER:
-+ case CM_VERIFY_HOMESERVER:
- handle_verify_homeserver (self, object, error);
- return;
-
-- case MATRIX_PASSWORD_LOGIN:
-+ case CM_PASSWORD_LOGIN:
- handle_password_login (self, object, error);
- return;
-
-- case MATRIX_UPLOAD_KEY:
-- handle_upload_key (self, object, error);
-- return;
--
-- case MATRIX_GET_JOINED_ROOMS:
-+ case CM_GET_JOINED_ROOMS:
- handle_get_joined_rooms (self, object, error);
- return;
-
-- case MATRIX_RED_PILL:
-+ case CM_RED_PILL:
- handle_red_pill (self, object, error);
- return;
-
-- case MATRIX_ACCESS_TOKEN_LOGIN:
-- case MATRIX_SET_TYPING:
-- case MATRIX_SEND_MESSAGE:
-- case MATRIX_SEND_IMAGE:
-- case MATRIX_SEND_VIDEO:
-- case MATRIX_SEND_FILE:
-+ case CM_UPLOAD_KEY:
-+ case CM_ACCESS_TOKEN_LOGIN:
-+ case CM_SET_TYPING:
-+ case CM_SEND_MESSAGE:
-+ case CM_SEND_IMAGE:
-+ case CM_SEND_VIDEO:
-+ case CM_SEND_FILE:
- default:
- break;
- }
-@@ -546,7 +431,7 @@ chatty_ma_account_get_enabled (ChattyAccount *account)
-
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- return self->account_enabled;
-+ return cm_client_get_enabled (self->cm_client);
- }
-
- static void
-@@ -556,40 +441,16 @@ chatty_ma_account_set_enabled (ChattyAccount *account,
- ChattyMaAccount *self = (ChattyMaAccount *)account;
-
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-+ g_assert (self->cm_client);
-+ g_assert (self->cm_matrix);
-
-- if (self->account_enabled == enable)
-- return;
--
-- g_clear_handle_id (&self->connect_id, g_source_remove);
--
-- if (!self->matrix_enc && enable) {
-- CHATTY_TRACE_MSG ("Create new enc. user: %s has pickle: %d, has key: %d",
-- chatty_item_get_username (CHATTY_ITEM (account)), FALSE, FALSE);
-- self->matrix_enc = matrix_enc_new (self->matrix_db, NULL, NULL);
-- matrix_api_set_enc (self->matrix_api, self->matrix_enc);
-- }
--
-- self->account_enabled = enable;
-- CHATTY_TRACE (chatty_item_get_username (CHATTY_ITEM (account)),
-- "Enable account: %d, is loading: %d, user:",
-- enable, self->is_loading);
-+ cm_client_set_enabled (self->cm_client, enable);
-
-- if (self->account_enabled &&
-- chatty_ma_account_can_connect (self)) {
-- ma_account_update_status (self, CHATTY_CONNECTING);
-- matrix_api_start_sync (self->matrix_api);
-- } else if (!self->account_enabled){
-- ma_account_update_status (self, CHATTY_DISCONNECTED);
-- matrix_api_stop_sync (self->matrix_api);
-- }
-+ self->save_pending = TRUE;
-+ chatty_account_save (account);
-
- g_object_notify (G_OBJECT (self), "enabled");
- g_object_notify (G_OBJECT (self), "status");
--
-- if (!self->is_loading) {
-- self->save_account_pending = TRUE;
-- chatty_account_save (account);
-- }
- }
-
- static const char *
-@@ -600,7 +461,7 @@ chatty_ma_account_get_password (ChattyAccount *account)
-
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- password = matrix_api_get_password (self->matrix_api);
-+ password = cm_client_get_password (self->cm_client);
-
- if (password)
- return password;
-@@ -616,13 +477,21 @@ chatty_ma_account_set_password (ChattyAccount *account,
-
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- if (g_strcmp0 (password, matrix_api_get_password (self->matrix_api)) == 0)
-+
-+ if (self->cm_client)
-+ {
-+ if (cm_client_get_logging_in (self->cm_client) ||
-+ cm_client_get_logged_in (self->cm_client))
-+ return;
-+ }
-+
-+ if (g_strcmp0 (password, cm_client_get_password (self->cm_client)) == 0)
- return;
-
-- matrix_api_set_password (self->matrix_api, password);
-+ cm_client_set_password (self->cm_client, password);
-
-- if (matrix_api_get_homeserver (self->matrix_api)) {
-- self->save_password_pending = TRUE;
-+ if (cm_client_get_homeserver (self->cm_client)) {
-+ self->save_pending = TRUE;
- chatty_account_save (account);
- }
- }
-@@ -635,8 +504,7 @@ account_connect (gpointer user_data)
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
- self->connect_id = 0;
-- matrix_api_start_sync (self->matrix_api);
-- ma_account_update_status (self, CHATTY_CONNECTING);
-+ cm_client_start_sync (self->cm_client);
-
- return G_SOURCE_REMOVE;
- }
-@@ -652,7 +520,7 @@ chatty_ma_account_connect (ChattyAccount *account,
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
- if (!chatty_account_get_enabled (account)) {
-- CHATTY_TRACE (matrix_api_get_login_username (self->matrix_api),
-+ CHATTY_TRACE (cm_client_get_login_id (self->cm_client),
- "Trying to connect disabled account, username:");
- return;
- }
-@@ -675,7 +543,7 @@ chatty_ma_account_disconnect (ChattyAccount *account)
-
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- matrix_api_stop_sync (self->matrix_api);
-+ cm_client_stop_sync (self->cm_client);
- ma_account_update_status (self, CHATTY_DISCONNECTED);
- }
-
-@@ -692,7 +560,7 @@ chatty_ma_account_save (ChattyAccount *account)
- ChattyMaAccount *self = (ChattyMaAccount *)account;
-
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-- g_return_if_fail (matrix_api_get_login_username (self->matrix_api));
-+ g_return_if_fail (cm_client_get_login_id (self->cm_client));
-
- chatty_ma_account_save_async (self, FALSE, NULL, NULL, NULL);
- }
-@@ -713,15 +581,15 @@ chatty_ma_account_get_device_fp (ChattyAccount *account)
-
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- device_id = matrix_api_get_device_id (self->matrix_api);
-+ device_id = cm_client_get_device_id (self->cm_client);
- g_clear_object (&self->device_fp);
-
-- if (!self->device_fp && device_id) {
-+ if (device_id) {
- g_autoptr(GString) fp = NULL;
- const char *str;
-
- fp = g_string_new (NULL);
-- str = matrix_enc_get_ed25519_key (self->matrix_enc);
-+ str = cm_client_get_ed25519_key (self->cm_client);
-
- while (str && *str) {
- g_autofree char *chunk = g_strndup (str, 4);
-@@ -755,7 +623,7 @@ ma_account_leave_chat_cb (GObject *object,
- chat = g_task_get_task_data (task);
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- success = matrix_api_leave_chat_finish (self->matrix_api, result, &error);
-+ success = cm_room_leave_finish (CM_ROOM (object), result, &error);
- CHATTY_TRACE_MSG ("Leaving chat: %s(%s), success: %d",
- chatty_item_get_name (CHATTY_ITEM (chat)),
- chatty_chat_get_chat_name (chat),
-@@ -810,10 +678,10 @@ chatty_ma_account_leave_chat_async (ChattyAccount *account,
- GINT_TO_POINTER (chatty_item_get_state (CHATTY_ITEM (chat))));
- chatty_item_set_state (CHATTY_ITEM (chat), CHATTY_ITEM_HIDDEN);
- chatty_history_update_chat (self->history_db, chat);
-- matrix_api_leave_chat_async (self->matrix_api,
-- chatty_chat_get_chat_name (chat),
-- ma_account_leave_chat_cb,
-- g_steal_pointer (&task));
-+ cm_room_leave_async (chatty_ma_chat_get_cm_room (CHATTY_MA_CHAT (chat)),
-+ NULL,
-+ ma_account_leave_chat_cb,
-+ g_steal_pointer (&task));
- }
-
- static ChattyProtocol
-@@ -854,8 +722,8 @@ chatty_ma_account_get_username (ChattyItem *item)
-
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- if (matrix_api_get_username (self->matrix_api))
-- return matrix_api_get_username (self->matrix_api);
-+ if (self->cm_client && cm_client_get_user_id (self->cm_client))
-+ return cm_client_get_user_id (self->cm_client);
-
- return "";
- }
-@@ -868,11 +736,11 @@ chatty_ma_account_set_username (ChattyItem *item,
-
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- matrix_api_set_login_username (self->matrix_api, username);
-+ cm_client_set_login_id (self->cm_client, username);
-
- /* If in test, also set username */
- if (g_test_initialized ())
-- matrix_api_set_username (self->matrix_api, username);
-+ cm_client_set_user_id (self->cm_client, username);
- }
-
- static ChattyFileInfo *
-@@ -913,11 +781,6 @@ chatty_ma_account_get_avatar (ChattyItem *item)
- ma_account_get_avatar_pixbuf_cb,
- g_object_ref (self));
-
-- } else {
-- matrix_api_get_file_async (self->matrix_api, NULL, self->avatar_file,
-- NULL, NULL,
-- ma_account_get_avatar_cb,
-- g_object_ref (self));
- }
-
- return NULL;
-@@ -937,7 +800,7 @@ ma_account_set_user_avatar_cb (GObject *object,
- self = g_task_get_source_object (task);
- g_assert (CHATTY_MA_ACCOUNT (self));
-
-- matrix_api_set_user_avatar_finish (self->matrix_api, result, &error);
-+ cm_account_set_user_avatar_finish (CM_ACCOUNT (object), result, &error);
-
- if (error)
- g_task_return_error (task, error);
-@@ -971,6 +834,7 @@ chatty_ma_account_set_avatar_async (ChattyItem *item,
- {
- ChattyMaAccount *self = (ChattyMaAccount *)item;
- g_autoptr(GTask) task = NULL;
-+ GFile *file;
-
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-@@ -982,7 +846,9 @@ chatty_ma_account_set_avatar_async (ChattyItem *item,
- return;
- }
-
-- matrix_api_set_user_avatar_async (self->matrix_api, file_name, cancellable,
-+ file = g_file_new_for_path (file_name);
-+ cm_account_set_user_avatar_async (cm_client_get_account (self->cm_client),
-+ file, cancellable,
- ma_account_set_user_avatar_cb,
- g_steal_pointer (&task));
- }
-@@ -995,19 +861,13 @@ chatty_ma_account_finalize (GObject *object)
- g_clear_handle_id (&self->connect_id, g_source_remove);
- g_list_store_remove_all (self->chat_list);
-
-- g_clear_object (&self->matrix_api);
-- g_clear_object (&self->matrix_enc);
- g_clear_object (&self->device_fp);
- g_clear_object (&self->chat_list);
- g_clear_object (&self->avatar);
-- g_clear_object (&self->matrix_db);
- g_clear_object (&self->history_db);
-- g_clear_pointer (&self->db_chat_list, g_ptr_array_unref);
- g_clear_pointer (&self->avatar_file, chatty_file_info_free);
-
- g_free (self->name);
-- g_free (self->pickle_key);
-- g_free (self->next_batch);
-
- G_OBJECT_CLASS (chatty_ma_account_parent_class)->finalize (object);
- }
-@@ -1049,10 +909,60 @@ static void
- chatty_ma_account_init (ChattyMaAccount *self)
- {
- self->chat_list = g_list_store_new (CHATTY_TYPE_MA_CHAT);
-+}
-+
-+static void
-+joined_rooms_changed (ChattyMaAccount *self,
-+ int position,
-+ int removed,
-+ int added,
-+ GListModel *model)
-+{
-+ g_autoptr(GPtrArray) items = NULL;
-+
-+ g_assert (CHATTY_IS_MA_ACCOUNT (self));
-+ g_assert (G_IS_LIST_MODEL (model));
-+
-+ for (guint i = position; i < position + added; i++)
-+ {
-+ g_autoptr(CmRoom) room = NULL;
-+ ChattyMaChat *chat;
-+
-+ if (!items)
-+ items = g_ptr_array_new_with_free_func (g_object_unref);
-+
-+ room = g_list_model_get_item (model, i);
-+ chat = chatty_ma_chat_new_with_room (room);
-+ chatty_ma_chat_set_history_db (chat, self->history_db);
-+ chatty_ma_chat_set_data (chat, CHATTY_ACCOUNT (self), self->cm_client);
-+ g_ptr_array_add (items, chat);
-+ }
-
-- self->matrix_api = matrix_api_new (NULL);
-- matrix_api_set_sync_callback (self->matrix_api,
-- (MatrixCallback)matrix_account_sync_cb, self);
-+ g_list_store_splice (self->chat_list, position, removed,
-+ items ? items->pdata : NULL, added);
-+}
-+
-+static void
-+ma_account_set_client (ChattyMaAccount *self,
-+ CmClient *client)
-+{
-+ GListModel *joined_rooms;
-+
-+ g_assert (CHATTY_IS_MA_ACCOUNT (self));
-+ g_assert (CM_IS_CLIENT (client));
-+ g_assert (!self->cm_client);
-+
-+ self->cm_client = client;
-+ cm_client_set_device_name (client, "Chatty");
-+ cm_client_set_sync_callback (client,
-+ (CmCallback)cm_account_sync_cb,
-+ self, NULL);
-+
-+ joined_rooms = cm_client_get_joined_rooms (client);
-+ g_signal_connect_object (joined_rooms, "items-changed",
-+ G_CALLBACK (joined_rooms_changed), self,
-+ G_CONNECT_SWAPPED);
-+ joined_rooms_changed (self, 0, 0, g_list_model_get_n_items (joined_rooms), joined_rooms);
- }
-
- ChattyMaAccount *
-@@ -1064,6 +974,8 @@ chatty_ma_account_new (const char *username,
- g_return_val_if_fail (username, NULL);
-
- self = g_object_new (CHATTY_TYPE_MA_ACCOUNT, NULL);
-+ ma_account_set_client (self, g_object_new (CM_TYPE_CLIENT, NULL));
-+ cm_client_set_user_id (self->cm_client, username);
-
- chatty_item_set_username (CHATTY_ITEM (self), username);
- chatty_account_set_password (CHATTY_ACCOUNT (self), password);
-@@ -1072,12 +984,25 @@ chatty_ma_account_new (const char *username,
- return self;
- }
-
-+ChattyMaAccount *
-+chatty_ma_account_new_from_client (CmClient *cm_client)
-+{
-+ ChattyMaAccount *self;
-+
-+ g_return_val_if_fail (CM_IS_CLIENT (cm_client), NULL);
-+
-+ self = g_object_new (CHATTY_TYPE_MA_ACCOUNT, NULL);
-+ ma_account_set_client (self, g_object_ref (cm_client));
-+
-+ return self;
-+}
-+
- gboolean
- chatty_ma_account_can_connect (ChattyMaAccount *self)
- {
- g_return_val_if_fail (CHATTY_IS_MA_ACCOUNT (self), FALSE);
-
-- return matrix_api_can_connect (self->matrix_api);
-+ return cm_client_can_connect (self->cm_client);
- }
-
- /**
-@@ -1098,7 +1023,7 @@ chatty_ma_account_get_login_username (ChattyMaAccount *self)
- {
- g_return_val_if_fail (CHATTY_IS_MA_ACCOUNT (self), "");
-
-- return matrix_api_get_login_username (self->matrix_api);
-+ return cm_client_get_login_id (self->cm_client);
- }
-
- static char *
-@@ -1131,8 +1056,27 @@ ma_account_get_value (const char *str,
- return NULL;
- }
-
-+static void
-+client_status_changed_cb (ChattyMaAccount *self)
-+{
-+ ChattyStatus status = CHATTY_DISCONNECTED;
-+
-+ g_assert (CHATTY_IS_MA_ACCOUNT (self));
-+
-+ if (!cm_client_get_enabled (self->cm_client))
-+ status = CHATTY_DISCONNECTED;
-+ else if (cm_client_is_sync (self->cm_client))
-+ status = CHATTY_CONNECTED;
-+ else if (cm_client_get_logging_in (self->cm_client) ||
-+ cm_client_get_logged_in (self->cm_client))
-+ status = CHATTY_CONNECTING;
-+
-+ ma_account_update_status (self, status);
-+}
-+
- ChattyMaAccount *
--chatty_ma_account_new_secret (gpointer secret_retrievable)
-+chatty_ma_account_new_secret (gpointer secret_retrievable,
-+ CmMatrix *cm_matrix)
- {
- ChattyMaAccount *self = NULL;
- g_autoptr(GHashTable) attributes = NULL;
-@@ -1142,8 +1086,11 @@ chatty_ma_account_new_secret (gpointer secret_retrievable)
- const char *username, *login_username;
- char *password, *token, *device_id;
- char *password_str, *token_str = NULL;
-+ g_autofree char *enabled = NULL;
-
- g_return_val_if_fail (SECRET_IS_RETRIEVABLE (item), NULL);
-+ g_return_val_if_fail (CM_IS_MATRIX (cm_matrix), NULL);
-+ g_return_val_if_fail (cm_matrix_is_ready (cm_matrix), NULL);
-
- value = secret_retrievable_retrieve_secret_sync (item, NULL, NULL);
-
-@@ -1161,21 +1108,41 @@ chatty_ma_account_new_secret (gpointer secret_retrievable)
- g_return_val_if_fail (password, NULL);
- password_str = g_strcompress (password);
-
-- self = chatty_ma_account_new (login_username, password_str);
- token = ma_account_get_value (credentials, "\"access-token\"");
- device_id = ma_account_get_value (credentials, "\"device-id\"");
- username = ma_account_get_value (credentials, "\"username\"");
-
-- if (username && *username)
-- matrix_api_set_username (self->matrix_api, username);
-- chatty_ma_account_set_homeserver (self, homeserver);
--
- if (token)
- token_str = g_strcompress (token);
-
-+ self = g_object_new (CHATTY_TYPE_MA_ACCOUNT, NULL);
-+ ma_account_set_client (self, cm_matrix_client_new (cm_matrix));
-+ chatty_ma_account_set_matrix (self, cm_matrix);
-+ cm_client_set_homeserver (self->cm_client, homeserver);
-+ cm_client_set_login_id (self->cm_client, login_username);
-+ cm_client_set_user_id (self->cm_client, username);
-+ cm_client_set_password (self->cm_client, password_str);
-+ cm_client_set_device_id (self->cm_client, device_id);
-+ enabled = ma_account_get_value (credentials, "\"enabled\"");
-+
-+ if (g_strcmp0 (enabled, "true") == 0)
-+ self->account_enabled_in_store = TRUE;
-+
-+ /* DEBUG */
-+ cm_client_set_access_token (self->cm_client, token_str);
-+
-+ g_signal_connect_object (self->cm_client, "status-changed",
-+ G_CALLBACK (client_status_changed_cb),
-+ self, G_CONNECT_SWAPPED);
-+
-+ chatty_ma_account_set_homeserver (self, homeserver);
-+
-+
- if (token && device_id) {
-- self->pickle_key = ma_account_get_value (credentials, "\"pickle-key\"");
-- matrix_api_set_access_token (self->matrix_api, token_str, device_id);
-+ g_autofree char *pickle = NULL;
-+
-+ pickle = ma_account_get_value (credentials, "\"pickle-key\"");
-+ cm_client_set_pickle_key (self->cm_client, pickle);
- }
-
- matrix_utils_free_buffer (device_id);
-@@ -1187,80 +1154,27 @@ chatty_ma_account_new_secret (gpointer secret_retrievable)
- return self;
- }
-
--static void
--db_load_account_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
-+void
-+chatty_ma_account_set_matrix (ChattyMaAccount *self,
-+ CmMatrix *cm_matrix)
- {
-- ChattyMaAccount *self = user_data;
-- GTask *task = (GTask *)result;
-- g_autoptr(GError) error = NULL;
-- gboolean enabled;
--
-- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-- g_assert (G_IS_TASK (task));
--
-- if (!self->matrix_enc) {
-- const char *pickle;
--
-- pickle = g_object_get_data (G_OBJECT (task), "pickle");
-- CHATTY_TRACE (chatty_item_get_username (CHATTY_ITEM (self)),
-- "Create new enc. has pickle: %d, has key: %d, user:",
-- !!pickle, !!self->pickle_key);
-- self->matrix_enc = matrix_enc_new (self->matrix_db, pickle, self->pickle_key);
-- matrix_api_set_enc (self->matrix_api, self->matrix_enc);
-- if (!pickle)
-- matrix_api_set_access_token (self->matrix_api, NULL, NULL);
-- g_clear_pointer (&self->pickle_key, matrix_utils_free_buffer);
-- }
--
-- if (!matrix_db_load_account_finish (self->matrix_db, result, &error)) {
-- if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- g_warning ("Error loading account %s: %s",
-- chatty_item_get_username (CHATTY_ITEM (self)),
-- error->message);
-- return;
-- }
--
-- enabled = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "enabled"));
-- self->next_batch = g_strdup (g_object_get_data (G_OBJECT (task), "batch"));
-- CHATTY_TRACE (chatty_item_get_username (CHATTY_ITEM (self)),
-- "Loaded from db. enabled: %d, has next-batch: %d, user:",
-- !!enabled, !!self->next_batch);
--
-- self->is_loading = TRUE;
-+ g_return_if_fail (CHATTY_IS_MA_ACCOUNT (self));
-+ g_return_if_fail (CM_IS_MATRIX (cm_matrix));
-+ g_return_if_fail (self->cm_client);
-
-- matrix_api_set_next_batch (self->matrix_api, self->next_batch);
-- chatty_account_set_enabled (CHATTY_ACCOUNT (self), enabled);
-- self->is_loading = FALSE;
-+ if (!self->cm_matrix)
-+ self->cm_matrix = g_object_ref (cm_matrix);
- }
-
--static void
--db_load_chats_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
-+void
-+chatty_ma_account_load (ChattyMaAccount *self)
- {
-- ChattyMaAccount *self = user_data;
-- GTask *task = (GTask *)result;
-- GPtrArray *chats = NULL;
-- g_autoptr(GError) error = NULL;
--
-- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-- g_assert (G_IS_TASK (task));
--
-- chats = chatty_history_get_chats_finish (self->history_db, result, &error);
-- self->db_chat_list = chats;
-- CHATTY_TRACE (chatty_item_get_username (CHATTY_ITEM (self)),
-- "Loaded %u chats from db, user:",
-- !chats ? 0 : chats->len);
--
-- if (error)
-- g_warning ("Error getting chats: %s", error->message);
-+ g_return_if_fail (CHATTY_IS_MA_ACCOUNT (self));
-+ g_return_if_fail (self->cm_client);
-
-+ cm_client_start_sync (self->cm_client);
-
-- matrix_db_load_account_async (self->matrix_db, CHATTY_ACCOUNT (self),
-- matrix_api_get_device_id (self->matrix_api),
-- db_load_account_cb, self);
-+ g_object_notify (G_OBJECT (self), "status");
- }
-
- static void
-@@ -1277,7 +1191,8 @@ history_db_load_account_cb (GObject *object,
-
- chatty_history_load_account_finish (self->history_db, result, &error);
-
-- if (error)
-+ /* It's a valid case for the item to not be in db */
-+ if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
- g_warning ("error loading account: %s", error->message);
-
- name = g_object_get_data (G_OBJECT (result), "name");
-@@ -1292,58 +1207,23 @@ history_db_load_account_cb (GObject *object,
- file->path = g_strdup (avatar_path);
- self->avatar_file = file;
-
-- chatty_history_get_chats_async (self->history_db, CHATTY_ACCOUNT (self),
-- db_load_chats_cb, self);
-+ cm_client_set_enabled (self->cm_client, self->account_enabled_in_store);
- }
-
- void
- chatty_ma_account_set_db (ChattyMaAccount *self,
-- gpointer matrix_db,
- gpointer history_db)
- {
- g_return_if_fail (CHATTY_IS_MA_ACCOUNT (self));
-- g_return_if_fail (MATRIX_IS_DB (matrix_db));
- g_return_if_fail (CHATTY_IS_HISTORY (history_db));
-- g_return_if_fail (!self->matrix_db);
- g_return_if_fail (!self->history_db);
-
-- self->matrix_db = g_object_ref (matrix_db);
- self->history_db = g_object_ref (history_db);
- chatty_history_load_account_async (self->history_db, CHATTY_ACCOUNT (self),
- history_db_load_account_cb,
- g_object_ref (self));
- }
-
--static void
--ma_account_db_save_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- ChattyMaAccount *self;
-- g_autoptr(GTask) task = user_data;
-- GError *error = NULL;
-- gboolean status;
--
-- g_assert (G_IS_ASYNC_RESULT (result));
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (CHATTY_IS_MA_ACCOUNT (self));
--
-- status = matrix_db_save_account_finish (self->matrix_db, result, &error);
-- if (error || !status)
-- CHATTY_TRACE_MSG ("Saving %s failed",
-- chatty_item_get_username (CHATTY_ITEM (self)));
--
-- if (error || !status)
-- self->save_account_pending = TRUE;
--
-- if (error)
-- g_task_return_error (task, error);
-- else
-- g_task_return_boolean (task, status);
--}
--
- static void
- ma_account_save_cb (GObject *object,
- GAsyncResult *result,
-@@ -1363,23 +1243,10 @@ ma_account_save_cb (GObject *object,
- status = chatty_secret_store_save_finish (result, &error);
-
- if (error || !status)
-- self->save_password_pending = TRUE;
-+ self->save_pending = TRUE;
-
- if (error) {
- g_task_return_error (task, error);
-- } else if (self->save_account_pending) {
-- char *pickle = NULL;
--
-- if (matrix_api_get_access_token (self->matrix_api))
-- pickle = matrix_enc_get_account_pickle (self->matrix_enc);
--
-- self->save_account_pending = FALSE;
-- matrix_db_save_account_async (self->matrix_db, CHATTY_ACCOUNT (self),
-- chatty_account_get_enabled (CHATTY_ACCOUNT (self)),
-- pickle,
-- matrix_api_get_device_id (self->matrix_api),
-- matrix_api_get_next_batch (self->matrix_api),
-- ma_account_db_save_cb, g_steal_pointer (&task));
- } else {
- g_task_return_boolean (task, status);
- }
-@@ -1404,31 +1271,18 @@ chatty_ma_account_save_async (ChattyMaAccount *self,
- g_return_if_fail (*chatty_ma_account_get_homeserver (self));
-
- task = g_task_new (self, cancellable, callback, user_data);
-- if (self->save_password_pending || force) {
-+ if (self->save_pending || force) {
- char *key = NULL;
-
-- if (self->matrix_enc && matrix_api_get_access_token (self->matrix_api))
-- key = matrix_enc_get_pickle_key (self->matrix_enc);
-+ if (cm_client_get_access_token (self->cm_client))
-+ key = g_strdup (cm_client_get_pickle_key (self->cm_client));
-
-- self->save_password_pending = FALSE;
-+ self->save_pending = FALSE;
- chatty_secret_store_save_async (CHATTY_ACCOUNT (self),
-- g_strdup (matrix_api_get_access_token (self->matrix_api)),
-- matrix_api_get_device_id (self->matrix_api),
-+ g_strdup (cm_client_get_access_token (self->cm_client)),
-+ cm_client_get_device_id (self->cm_client),
- key, cancellable,
- ma_account_save_cb, task);
-- } else if (self->save_account_pending) {
-- char *pickle = NULL;
--
-- if (matrix_api_get_access_token (self->matrix_api))
-- pickle = matrix_enc_get_account_pickle (self->matrix_enc);
--
-- self->save_account_pending = FALSE;
-- matrix_db_save_account_async (self->matrix_db, CHATTY_ACCOUNT (self),
-- chatty_account_get_enabled (CHATTY_ACCOUNT (self)),
-- pickle,
-- matrix_api_get_device_id (self->matrix_api),
-- matrix_api_get_next_batch (self->matrix_api),
-- ma_account_db_save_cb, task);
- }
- }
-
-@@ -1450,7 +1304,7 @@ chatty_ma_account_get_homeserver (ChattyMaAccount *self)
-
- g_return_val_if_fail (CHATTY_IS_MA_ACCOUNT (self), "");
-
-- homeserver = matrix_api_get_homeserver (self->matrix_api);
-+ homeserver = cm_client_get_homeserver (self->cm_client);
-
- if (homeserver)
- return homeserver;
-@@ -1464,7 +1318,7 @@ chatty_ma_account_set_homeserver (ChattyMaAccount *self,
- {
- g_return_if_fail (CHATTY_IS_MA_ACCOUNT (self));
-
-- matrix_api_set_homeserver (self->matrix_api, server_url);
-+ cm_client_set_homeserver (self->cm_client, server_url);
- }
-
- const char *
-@@ -1473,7 +1327,7 @@ chatty_ma_account_get_device_id (ChattyMaAccount *self)
- const char *device_id;
- g_return_val_if_fail (CHATTY_IS_MA_ACCOUNT (self), "");
-
-- device_id = matrix_api_get_device_id (self->matrix_api);
-+ device_id = cm_client_get_device_id (self->cm_client);
-
- if (device_id)
- return device_id;
-@@ -1504,7 +1358,6 @@ ma_get_details_cb (GObject *object,
- {
- ChattyMaAccount *self;
- g_autoptr(GTask) task = user_data;
-- char *name, *avatar_url;
- GError *error = NULL;
-
- g_assert (G_IS_TASK (task));
-@@ -1512,9 +1365,8 @@ ma_get_details_cb (GObject *object,
- self = g_task_get_source_object (task);
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- matrix_api_get_user_info_finish (self->matrix_api,
-- &name, &avatar_url,
-- result, &error);
-+ cm_user_load_info_finish (CM_USER (object),
-+ result, &error);
-
- if (error)
- g_task_return_error (task, error);
-@@ -1522,16 +1374,16 @@ ma_get_details_cb (GObject *object,
- ChattyFileInfo *file;
-
- CHATTY_TRACE_MSG ("Got user info for %s",
-- matrix_api_get_username (self->matrix_api));
-+ cm_client_get_user_id (self->cm_client));
-
- g_free (self->name);
-- self->name = name;
-+ self->name = g_strdup (cm_user_get_display_name (CM_USER (object)));
- file = self->avatar_file;
-
-- if (g_strcmp0 (file->url, avatar_url) != 0) {
-+ if (g_strcmp0 (file->url, cm_user_get_avatar_url (CM_USER (object))) != 0) {
- g_clear_pointer (&file->path, g_free);
- g_free (file->url);
-- file->url = avatar_url;
-+ file->url = g_strdup (cm_user_get_avatar_url (CM_USER (object)));
- }
-
- chatty_history_update_user (self->history_db, CHATTY_ACCOUNT (self));
-@@ -1547,18 +1399,20 @@ chatty_ma_account_get_details_async (ChattyMaAccount *self,
- gpointer user_data)
- {
- g_autoptr(GTask) task = NULL;
-+ CmAccount *account;
-
- g_return_if_fail (CHATTY_IS_MA_ACCOUNT (self));
- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
-
- task = g_task_new (self, cancellable, callback, user_data);
-+ account = cm_client_get_account (self->cm_client);
-
- if (self->name)
- g_task_return_boolean (task, TRUE);
- else
-- matrix_api_get_user_info_async (self->matrix_api, NULL, cancellable,
-- ma_get_details_cb,
-- g_steal_pointer (&task));
-+ cm_user_load_info_async (CM_USER (account), cancellable,
-+ ma_get_details_cb,
-+ g_steal_pointer (&task));
- }
-
- gboolean
-@@ -1586,7 +1440,9 @@ ma_set_name_cb (GObject *object,
- self = g_task_get_source_object (task);
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- matrix_api_set_name_finish (self->matrix_api, result, &error);
-+ cm_account_set_display_name_finish (CM_ACCOUNT (object), result, &error);
-+ CHATTY_TRACE (chatty_item_get_username (CHATTY_ITEM (self)),
-+ "Setting name %s user:", CHATTY_LOG_SUCESS (!error));
-
- if (error)
- g_task_return_error (task, error);
-@@ -1618,8 +1474,9 @@ chatty_ma_account_set_name_async (ChattyMaAccount *self,
- task = g_task_new (self, cancellable, callback, user_data);
- g_task_set_task_data (task, g_strdup (name), g_free);
-
-- matrix_api_set_name_async (self->matrix_api, name, cancellable,
-- ma_set_name_cb, task);
-+ cm_account_set_display_name_async (cm_client_get_account (self->cm_client),
-+ name, cancellable,
-+ ma_set_name_cb, task);
- }
-
- gboolean
-@@ -1648,9 +1505,9 @@ ma_get_3pid_cb (GObject *object,
- self = g_task_get_source_object (task);
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- matrix_api_get_3pid_finish (self->matrix_api,
-- &emails, &phones,
-- result, &error);
-+ cm_account_get_3pids_finish (CM_ACCOUNT (object),
-+ &emails, &phones,
-+ result, &error);
-
- if (error)
- g_task_return_error (task, error);
-@@ -1677,9 +1534,10 @@ chatty_ma_account_get_3pid_async (ChattyMaAccount *self,
-
- task = g_task_new (self, cancellable, callback, user_data);
-
-- matrix_api_get_3pid_async (self->matrix_api, cancellable,
-- ma_get_3pid_cb,
-- g_steal_pointer (&task));
-+ cm_account_get_3pids_async (cm_client_get_account (self->cm_client),
-+ cancellable,
-+ ma_get_3pid_cb,
-+ g_steal_pointer (&task));
- }
-
- gboolean
-@@ -1714,7 +1572,7 @@ ma_delete_3pid_cb (GObject *object,
- self = g_task_get_source_object (task);
- g_assert (CHATTY_IS_MA_ACCOUNT (self));
-
-- matrix_api_delete_3pid_finish (self->matrix_api, result, &error);
-+ cm_account_delete_3pid_finish (CM_ACCOUNT (object), result, &error);
-
- if (error)
- g_task_return_error (task, error);
-@@ -1731,14 +1589,19 @@ chatty_ma_account_delete_3pid_async (ChattyMaAccount *self,
- gpointer user_data)
- {
- GTask *task = NULL;
-+ const char *type_str = NULL;
-
- g_return_if_fail (CHATTY_IS_MA_ACCOUNT (self));
- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
-
- task = g_task_new (self, cancellable, callback, user_data);
-
-- matrix_api_delete_3pid_async (self->matrix_api,
-- value, type, cancellable,
-+ if (type == CHATTY_ID_PHONE)
-+ type_str = "msisdn";
-+ else
-+ type_str = "email";
-+ cm_account_delete_3pid_async (cm_client_get_account (self->cm_client),
-+ value, type_str, cancellable,
- ma_delete_3pid_cb, task);
- }
-
-@@ -1761,6 +1624,6 @@ chatty_ma_account_add_chat (ChattyMaAccount *self,
- g_return_if_fail (CHATTY_IS_MA_CHAT (chat));
-
- chatty_ma_chat_set_data (CHATTY_MA_CHAT (chat), CHATTY_ACCOUNT (self),
-- self->matrix_api, self->matrix_enc);
-+ self->cm_client);
- g_list_store_append (self->chat_list, chat);
- }
-diff --git a/src/matrix/chatty-ma-account.h b/src/matrix/chatty-ma-account.h
-index 310bb61e..852b0a3c 100644
---- a/src/matrix/chatty-ma-account.h
-+++ b/src/matrix/chatty-ma-account.h
-@@ -12,6 +12,8 @@
- #pragma once
-
- #include <glib-object.h>
-+#define CMATRIX_USE_EXPERIMENTAL_API
-+#include "cmatrix.h"
-
- #include "chatty-chat.h"
- #include "chatty-enums.h"
-@@ -25,11 +27,15 @@ G_DECLARE_FINAL_TYPE (ChattyMaAccount, chatty_ma_account, CHATTY, MA_ACCOUNT, Ch
-
- ChattyMaAccount *chatty_ma_account_new (const char *username,
- const char *password);
--gboolean chatty_ma_account_can_connect (ChattyMaAccount *self);
-+ChattyMaAccount *chatty_ma_account_new_from_client (CmClient *cm_client);
-+void chatty_ma_account_load (ChattyMaAccount *self);
-+gboolean chatty_ma_account_can_connect (ChattyMaAccount *self);
- const char *chatty_ma_account_get_login_username (ChattyMaAccount *self);
--ChattyMaAccount *chatty_ma_account_new_secret (gpointer secret_retrievable);
-+ChattyMaAccount *chatty_ma_account_new_secret (gpointer secret_retrievable,
-+ CmMatrix *cm_matrix);
-+void chatty_ma_account_set_matrix (ChattyMaAccount *self,
-+ CmMatrix *cm_matrix);
- void chatty_ma_account_set_db (ChattyMaAccount *self,
-- gpointer matrix_db,
- gpointer history_db);
- void chatty_ma_account_save_async (ChattyMaAccount *self,
- gboolean force,
-diff --git a/src/matrix/chatty-ma-buddy.c b/src/matrix/chatty-ma-buddy.c
-index 81b55674..dc025122 100644
---- a/src/matrix/chatty-ma-buddy.c
-+++ b/src/matrix/chatty-ma-buddy.c
-@@ -1,7 +1,7 @@
- /* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
- /* chatty-ma-buddy.c
- *
-- * Copyright 2020 Purism SPC
-+ * Copyright 2020, 2022 Purism SPC
- *
- * Author(s):
- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-@@ -24,10 +24,9 @@ struct _ChattyMaBuddy
-
- char *matrix_id;
- char *name;
-- GList *devices;
-
-- MatrixApi *matrix_api;
-- MatrixEnc *matrix_enc;
-+ CmUser *cm_user;
-+ CmClient *cm_client;
-
- /* generated using g_str_hash for faster comparison */
- guint id_hash;
-@@ -57,20 +56,6 @@ enum {
-
- static guint signals[N_SIGNALS];
-
--static void
--chatty_ma_device_free (BuddyDevice *device)
--{
-- if (!device)
-- return;
--
-- g_free (device->device_id);
-- g_free (device->device_name);
-- g_free (device->curve_key);
-- g_free (device->ed_key);
-- g_free (device->one_time_key);
-- g_free (device);
--}
--
- static ChattyProtocol
- chatty_ma_buddy_get_protocols (ChattyItem *item)
- {
-@@ -143,6 +128,9 @@ chatty_ma_buddy_get_username (ChattyItem *item)
-
- g_assert (CHATTY_IS_MA_BUDDY (self));
-
-+ if (self->cm_user)
-+ return cm_user_get_id (self->cm_user);
-+
- if (self->matrix_id)
- return self->matrix_id;
-
-@@ -167,11 +155,8 @@ chatty_ma_buddy_dispose (GObject *object)
- g_clear_pointer (&self->matrix_id, g_free);
- g_clear_pointer (&self->name, g_free);
-
-- g_clear_object (&self->matrix_api);
-- g_clear_object (&self->matrix_enc);
--
-- g_list_free_full (self->devices, (GDestroyNotify)chatty_ma_device_free);
-- self->devices = NULL;
-+ g_clear_object (&self->cm_user);
-+ g_clear_object (&self->cm_client);
-
- G_OBJECT_CLASS (chatty_ma_buddy_parent_class)->dispose (object);
- }
-@@ -213,197 +198,52 @@ chatty_ma_buddy_init (ChattyMaBuddy *self)
-
- ChattyMaBuddy *
- chatty_ma_buddy_new (const char *matrix_id,
-- MatrixApi *api,
-- MatrixEnc *enc)
-+ CmClient *client)
- {
- ChattyMaBuddy *self;
-
- g_return_val_if_fail (matrix_id && *matrix_id == '@', NULL);
-- g_return_val_if_fail (MATRIX_IS_API (api), NULL);
-- g_return_val_if_fail (MATRIX_IS_ENC (enc), NULL);
-+ g_return_val_if_fail (CM_IS_CLIENT (client), NULL);
-
- self = g_object_new (CHATTY_TYPE_MA_BUDDY, NULL);
- self->matrix_id = g_strdup (matrix_id);
-- self->matrix_api = g_object_ref (api);
-- self->matrix_enc = g_object_ref (enc);
-+ self->cm_client = g_object_ref (client);
-
-- if (g_str_equal (matrix_id, matrix_api_get_username (api)))
-+ if (g_str_equal (matrix_id, cm_client_get_user_id (client)))
- self->is_self = TRUE;
-
- return self;
- }
-
--guint
--chatty_ma_buddy_get_id_hash (ChattyMaBuddy *self)
--{
-- g_return_val_if_fail (CHATTY_IS_MA_BUDDY (self), 0);
--
-- if (!self->id_hash && self->matrix_id)
-- self->id_hash = g_str_hash (self->matrix_id);
--
-- return self->id_hash;
--}
--
--void
--chatty_ma_buddy_add_devices (ChattyMaBuddy *self,
-- JsonObject *root)
--{
-- g_autoptr(GList) members = NULL;
-- JsonObject *object, *child;
-- BuddyDevice *device;
--
-- g_return_if_fail (CHATTY_IS_MA_BUDDY (self));
-- g_return_if_fail (root);
--
-- members = json_object_get_members (root);
--
-- for (GList *member = members; member; member = member->next) {
-- g_autofree char *device_name = NULL;
-- const char *device_id, *user, *key;
-- JsonArray *array;
-- char *key_name;
--
-- child = matrix_utils_json_object_get_object (root, member->data);
-- device_id = matrix_utils_json_object_get_string (child, "device_id");
-- user = matrix_utils_json_object_get_string (child, "user_id");
--
-- if (g_strcmp0 (user, self->matrix_id) != 0) {
-- g_warning ("‘%s’ and ‘%s’ are not the same users", user, self->matrix_id);
-- continue;
-- }
--
-- if (self->is_self &&
-- g_strcmp0 (device_id, matrix_api_get_device_id (self->matrix_api)) == 0)
-- continue;
--
-- if (g_strcmp0 (member->data, device_id) != 0) {
-- g_warning ("‘%s’ and ‘%s’ are not the same device", (char *)member->data, device_id);
-- continue;
-- }
--
-- object = matrix_utils_json_object_get_object (child, "unsigned");
-- device_name = g_strdup (matrix_utils_json_object_get_string (object, "device_display_name"));
--
-- key_name = g_strconcat ("ed25519:", device_id, NULL);
-- object = matrix_utils_json_object_get_object (child, "keys");
-- key = matrix_utils_json_object_get_string (object, key_name);
-- g_free (key_name);
--
-- if (!matrix_enc_verify (self->matrix_enc, child, self->matrix_id, device_id, key)) {
-- g_warning ("failed to verify signature for %s with device %s", self->matrix_id, device_id);
-- continue;
-- }
--
-- device = g_new0 (BuddyDevice, 1);
-- device->device_id = g_strdup (device_id);
-- device->device_name = g_steal_pointer (&device_name);
-- device->ed_key = g_strdup (key);
--
-- key_name = g_strconcat ("curve25519:", device_id, NULL);
-- object = matrix_utils_json_object_get_object (child, "keys");
-- key = matrix_utils_json_object_get_string (object, key_name);
-- device->curve_key = g_strdup (key);
-- g_free (key_name);
--
-- array = matrix_utils_json_object_get_array (child, "algorithms");
-- for (guint i = 0; array && i < json_array_get_length (array); i++) {
-- const char *algorithm;
--
-- algorithm = json_array_get_string_element (array, i);
-- if (g_strcmp0 (algorithm, ALGORITHM_MEGOLM) == 0)
-- device->meagolm_v1 = TRUE;
-- else if (g_strcmp0 (algorithm, ALGORITHM_OLM) == 0)
-- device->olm_v1 = TRUE;
-- }
--
-- self->devices = g_list_prepend (self->devices, device);
-- }
--}
--
--GList *
--chatty_ma_buddy_get_devices (ChattyMaBuddy *self)
--{
-- g_return_val_if_fail (CHATTY_IS_MA_BUDDY (self), NULL);
--
-- return g_list_copy (self->devices);
--}
--
--/**
-- * chatty_ma_buddy_device_key_json:
-- * @self: A #ChattyMaBuddy
-- *
-- * Get A JSON object with all the devices
-- * that we don't have an one time key for.
-- *
-- * The JSON created will have the following format:
-- *
-- * {
-- * "@alice:example.com": {
-- * "JLAFKJWSCS": "signed_curve25519"
-- * },
-- * "@bob:example.com": {
-- * "JOJOAEWBZY": "signed_curve25519"
-- * }
-- *
-- * Returns: (transfer full): A #JsonObject
-- */
--JsonObject *
--chatty_ma_buddy_device_key_json (ChattyMaBuddy *self)
-+ChattyMaBuddy *
-+chatty_ma_buddy_new_with_user (CmUser *user,
-+ CmClient *client)
- {
-- JsonObject *object;
--
-- g_return_val_if_fail (CHATTY_IS_MA_BUDDY (self), NULL);
--
-- if (!self->devices)
-- return NULL;
-+ ChattyMaBuddy *self;
-
-- object = json_object_new ();
-+ g_return_val_if_fail (CM_IS_USER (user), NULL);
-+ g_return_val_if_fail (CM_IS_CLIENT (client), NULL);
-
-- for (GList *node = self->devices; node; node = node->next) {
-- BuddyDevice *device = node->data;
-+ self = g_object_new (CHATTY_TYPE_MA_BUDDY, NULL);
-+ self->cm_user = g_object_ref (user);
-+ self->cm_client = g_object_ref (client);
-
-- if (!device->one_time_key)
-- json_object_set_string_member (object, device->device_id, "signed_curve25519");
-- }
-+ if (g_strcmp0 (cm_user_get_id (user),
-+ cm_client_get_user_id (client)) == 0)
-+ self->is_self = TRUE;
-
-- return object;
-+ return self;
- }
-
--void
--chatty_ma_buddy_add_one_time_keys (ChattyMaBuddy *self,
-- JsonObject *root)
-+guint
-+chatty_ma_buddy_get_id_hash (ChattyMaBuddy *self)
- {
-- JsonObject *object, *child;
--
-- g_return_if_fail (CHATTY_IS_MA_BUDDY (self));
-- g_return_if_fail (root);
--
-- for (GList *item = self->devices; item; item = item->next) {
-- g_autoptr(GList) members = NULL;
-- BuddyDevice *device = item->data;
--
-- child = matrix_utils_json_object_get_object (root, device->device_id);
--
-- if (!child) {
-- g_warning ("device '%s' not found", device->device_id);
-- continue;
-- }
--
-- members = json_object_get_members (child);
--
-- for (GList *node = members; node; node = node->next) {
-- object = matrix_utils_json_object_get_object (child, node->data);
-+ g_return_val_if_fail (CHATTY_IS_MA_BUDDY (self), 0);
-
-- if (matrix_enc_verify (self->matrix_enc, object, self->matrix_id,
-- device->device_id, device->ed_key)) {
-- const char *key;
-+ if (!self->id_hash && self->matrix_id)
-+ self->id_hash = g_str_hash (self->matrix_id);
-
-- key = matrix_utils_json_object_get_string (object, "key");
-- g_free (device->one_time_key);
-- device->one_time_key = g_strdup (key);
-- }
-- }
-- }
-+ return self->id_hash;
- }
-
- const char *
-diff --git a/src/matrix/chatty-ma-buddy.h b/src/matrix/chatty-ma-buddy.h
-index fc0e65f2..94de6b52 100644
---- a/src/matrix/chatty-ma-buddy.h
-+++ b/src/matrix/chatty-ma-buddy.h
-@@ -13,10 +13,10 @@
-
- #include <glib-object.h>
- #include <json-glib/json-glib.h>
-+#define CMATRIX_USE_EXPERIMENTAL_API
-+#include "cmatrix.h"
-
- #include "chatty-item.h"
--#include "matrix-api.h"
--#include "matrix-enc.h"
-
- G_BEGIN_DECLS
-
-@@ -27,16 +27,11 @@ typedef struct _BuddyDevice BuddyDevice;
- G_DECLARE_FINAL_TYPE (ChattyMaBuddy, chatty_ma_buddy, CHATTY, MA_BUDDY, ChattyItem)
-
- ChattyMaBuddy *chatty_ma_buddy_new (const char *matrix_id,
-- MatrixApi *api,
-- MatrixEnc *enc);
-+ CmClient *client);
-+ChattyMaBuddy *chatty_ma_buddy_new_with_user (CmUser *user,
-+ CmClient *client);
- const char *chatty_ma_buddy_get_id (ChattyMaBuddy *self);
- guint chatty_ma_buddy_get_id_hash (ChattyMaBuddy *self);
--void chatty_ma_buddy_add_devices (ChattyMaBuddy *self,
-- JsonObject *root);
--GList *chatty_ma_buddy_get_devices (ChattyMaBuddy *self);
--JsonObject *chatty_ma_buddy_device_key_json (ChattyMaBuddy *self);
--void chatty_ma_buddy_add_one_time_keys (ChattyMaBuddy *self,
-- JsonObject *root);
-
- const char *chatty_ma_device_get_id (BuddyDevice *device);
- const char *chatty_ma_device_get_ed_key (BuddyDevice *device);
-diff --git a/src/matrix/chatty-ma-chat.c b/src/matrix/chatty-ma-chat.c
-index e6bd91a7..892a9e0a 100644
---- a/src/matrix/chatty-ma-chat.c
-+++ b/src/matrix/chatty-ma-chat.c
-@@ -16,20 +16,17 @@
- #endif
-
- #include <glib/gi18n.h>
-+#define CMATRIX_USE_EXPERIMENTAL_API
-+#include "cmatrix.h"
-
- #include "contrib/gtk.h"
- #include "chatty-history.h"
- #include "chatty-utils.h"
--#include "matrix-api.h"
--#include "matrix-db.h"
--#include "matrix-enc.h"
- #include "matrix-utils.h"
- #include "chatty-ma-buddy.h"
- #include "chatty-ma-chat.h"
- #include "chatty-log.h"
-
--#define CHATTY_COLOR_BLUE "4A8FD9"
--
- /**
- * SECTION: chatty-chat
- * @title: ChattyChat
-@@ -48,7 +45,6 @@ struct _ChattyMaChat
- char *generated_name;
- char *room_id;
- char *encryption;
-- char *prev_batch;
- char *last_batch;
- GdkPixbuf *avatar;
- ChattyFileInfo *avatar_file;
-@@ -58,15 +54,10 @@ struct _ChattyMaChat
- GListStore *message_list;
- GtkSortListModel *sorted_message_list;
-
-- /* Pending messages to be sent. Queue messages here when
-- @self is busy (eg: claiming keys for encrypted chat) */
-- GQueue *message_queue;
--
- JsonObject *json_data;
- ChattyAccount *account;
-- MatrixApi *matrix_api;
-- MatrixEnc *matrix_enc;
-- MatrixDb *matrix_db;
-+ CmClient *cm_client;
-+ CmRoom *cm_room;
- ChattyHistory *history_db;
-
- ChattyItemState visibility_state;
-@@ -74,30 +65,14 @@ struct _ChattyMaChat
- int unread_count;
- int room_name_update_ts;
-
-- int message_timeout_id;
-- guint is_sending_message : 1;
- guint notification_shown : 1;
-
-- guint user_list_loading : 1;
-- guint user_list_loaded : 1;
-- guint state_is_sync : 1;
-- guint state_is_syncing : 1;
-- /* Set if the complete buddy list is loaded */
-- guint claiming_keys : 1;
-- guint keys_claimed : 1;
- guint prev_batch_loading : 1;
- guint history_is_loading : 1;
- guint avatar_is_loading : 1;
-- guint saving_room_to_db : 1;
-- guint room_db_loaded : 1;
-
- guint room_name_loaded : 1;
- guint buddy_typing : 1;
-- /* Set if server says we are typing */
-- guint self_typing : 1;
-- /* The time when self_typing was updated */
-- /* Uses g_get_monotonic_time(), we only need the interval */
-- gint64 self_typing_set_time;
- };
-
- G_DEFINE_TYPE (ChattyMaChat, chatty_ma_chat, CHATTY_TYPE_CHAT)
-@@ -111,8 +86,6 @@ enum {
-
- static GParamSpec *properties[N_PROPS];
-
--static void matrix_send_message_from_queue (ChattyMaChat *self);
--
- static int
- sort_message (gconstpointer a,
- gconstpointer b,
-@@ -148,21 +121,18 @@ ma_chat_find_buddy (ChattyMaChat *self,
- guint *index)
- {
- guint n_items;
-- guint id_hash;
-
- g_assert (CHATTY_IS_MA_CHAT (self));
- g_assert (G_IS_LIST_MODEL (model));
- g_return_val_if_fail (matrix_id && *matrix_id, NULL);
-
- n_items = g_list_model_get_n_items (model);
-- id_hash = g_str_hash (matrix_id);
-
- for (guint i = 0; i < n_items; i++) {
- g_autoptr(ChattyMaBuddy) buddy = NULL;
-
- buddy = g_list_model_get_item (model, i);
-- if (id_hash == chatty_ma_buddy_get_id_hash (buddy) &&
-- g_str_equal (chatty_item_get_username (CHATTY_ITEM (buddy)), matrix_id)) {
-+ if (g_str_equal (chatty_item_get_username (CHATTY_ITEM (buddy)), matrix_id)) {
- if (index)
- *index = i;
-
-@@ -185,9 +155,7 @@ ma_chat_add_buddy (ChattyMaChat *self,
- if (!matrix_id || *matrix_id != '@')
- g_return_val_if_reached (NULL);
-
-- buddy = chatty_ma_buddy_new (matrix_id,
-- self->matrix_api,
-- self->matrix_enc);
-+ buddy = chatty_ma_buddy_new (matrix_id, self->cm_client);
- g_list_store_append (store, buddy);
-
- return buddy;
-@@ -217,22 +185,6 @@ ma_chat_get_avatar_pixbuf_cb (GObject *object,
- self->avatar_is_loading = FALSE;
- }
-
--#if 0
--static void
--chat_got_room_avatar_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(ChattyMaChat) self = user_data;
--
-- if (matrix_api_get_file_finish (self->matrix_api, result, NULL)) {
-- g_clear_object (&self->avatar);
-- g_signal_emit_by_name (self, "avatar-changed");
-- chatty_history_update_chat (self->history_db, CHATTY_CHAT (self));
-- }
--}
--#endif
--
- static ChattyFileInfo *
- ma_chat_new_file (ChattyMaChat *self,
- JsonObject *object,
-@@ -248,9 +200,7 @@ ma_chat_new_file (ChattyMaChat *self,
- if (url && g_str_has_prefix (url, "mxc://")) {
- file = g_new0 (ChattyFileInfo, 1);
-
-- url = url + strlen ("mxc://");
-- file->url = g_strconcat (matrix_api_get_homeserver (self->matrix_api),
-- "/_matrix/media/r0/download/", url, NULL);
-+ file->url = g_strdup (url);
- file->file_name = g_strdup (matrix_utils_json_object_get_string (object, "body"));
- object = matrix_utils_json_object_get_object (content, "info");
- file->mime_type = g_strdup (matrix_utils_json_object_get_string (object, "mimetype"));
-@@ -262,155 +212,6 @@ ma_chat_new_file (ChattyMaChat *self,
- return file;
- }
-
--static void
--handle_m_room_member (ChattyMaChat *self,
-- JsonObject *object)
--{
-- GListModel *model;
-- ChattyMaBuddy *buddy;
-- JsonObject *content;
-- const char *membership, *sender, *name;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
-- g_assert (object);
--
-- sender = matrix_utils_json_object_get_string (object, "sender");
-- content = matrix_utils_json_object_get_object (object, "content");
-- membership = matrix_utils_json_object_get_string (content, "membership");
--
-- model = G_LIST_MODEL (self->buddy_list);
-- buddy = ma_chat_find_buddy (self, model, sender, NULL);
-- name = matrix_utils_json_object_get_string (content, "displayname");
--
-- if (g_strcmp0 (membership, "join") == 0) {
-- if (!buddy)
-- buddy = ma_chat_add_buddy (self, self->buddy_list, sender);
-- chatty_item_set_name (CHATTY_ITEM (buddy), name);
-- self->keys_claimed = FALSE;
-- } else if (buddy && g_strcmp0 (membership, "leave") == 0) {
-- chatty_utils_remove_list_item (self->buddy_list, buddy);
-- g_clear_pointer (&self->generated_name, g_free);
-- self->keys_claimed = FALSE;
-- }
--}
--
--static void
--handle_m_room_name (ChattyMaChat *self,
-- JsonObject *root)
--{
-- JsonObject *content;
-- const char *name;
--
-- g_assert (CHATTY_MA_CHAT (self));
--
-- content = matrix_utils_json_object_get_object (root, "content");
-- name = matrix_utils_json_object_get_string (content, "name");
--
-- if (name && g_strcmp0 (name, self->room_name) != 0) {
-- g_free (self->room_name);
-- self->room_name = g_strdup (name);
-- g_object_notify (G_OBJECT (self), "name");
-- g_signal_emit_by_name (self, "avatar-changed");
-- }
--}
--
--static void
--handle_m_room_encryption (ChattyMaChat *self,
-- JsonObject *root)
--{
-- JsonObject *content;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- if (!root || self->encryption)
-- return;
--
-- content = matrix_utils_json_object_get_object (root, "content");
-- self->encryption = g_strdup (matrix_utils_json_object_get_string (content, "algorithm"));
--
-- if (self->encryption)
-- g_object_notify (G_OBJECT (self), "encrypt");
--}
--
--#if 0
--static void
--handle_m_room_avatar (ChattyMaChat *self,
-- JsonObject *root)
--{
-- JsonObject *content;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- g_clear_pointer (&self->avatar_file, chatty_file_info_free);
-- content = matrix_utils_json_object_get_object (root, "content");
-- self->avatar_file = ma_chat_new_file (self, content, content);
--
-- g_cancellable_cancel (self->avatar_cancellable);
-- g_clear_object (&self->avatar_cancellable);
-- self->avatar_cancellable = g_cancellable_new ();
--
-- matrix_api_get_file_async (self->matrix_api, NULL, self->avatar_file,
-- NULL, NULL,
-- chat_got_room_avatar_cb,
-- g_object_ref (self));
--}
--#endif
--
--static void
--ma_chat_download_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GError) error = NULL;
-- ChattyMaChat *self = user_data;
-- GTask *task = G_TASK (result);
-- ChattyMessage *message;
-- ChattyFileInfo *file;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- file = g_object_get_data (G_OBJECT (task), "file");
-- message = g_object_get_data (G_OBJECT (task), "message");
-- g_return_if_fail (file);
-- g_return_if_fail (message);
--
-- if (matrix_api_get_file_finish (self->matrix_api, result, &error))
-- file->status = CHATTY_FILE_DOWNLOADED;
-- else
-- file->status = CHATTY_FILE_ERROR;
--
-- chatty_history_add_message (self->history_db, CHATTY_CHAT (self), message);
-- chatty_message_emit_updated (message);
--}
--
--static void
--ma_chat_parse_base64_value (guchar **out,
-- gsize *out_len,
-- const char *value)
--{
-- g_autofree char *base64 = NULL;
-- gsize len, padded_len;
--
-- g_assert (out);
-- g_assert (out_len);
--
-- if (!value)
-- return;
--
-- len = strlen (value);
-- /* base64 is always multiple of 4, so add space for padding */
-- if (len % 4)
-- padded_len = len + 4 - len % 4;
-- else
-- padded_len = len;
-- base64 = malloc (padded_len + 1);
-- strcpy (base64, value);
-- memset (base64 + len, '=', padded_len - len);
-- base64[padded_len] = '\0';
--
-- *out = g_base64_decode (base64, out_len);
--}
--
- static void
- chat_handle_m_media (ChattyMaChat *self,
- ChattyMessage *message,
-@@ -444,42 +245,6 @@ chat_handle_m_media (ChattyMaChat *self,
-
- file = ma_chat_new_file (self, object, content);
-
-- if (encrypted && file) {
-- g_autoptr(MatrixFileEncInfo) info = NULL;
-- JsonObject *json_key;
--
-- object = matrix_utils_json_object_get_object (content, "file");
-- json_key = matrix_utils_json_object_get_object (object, "key");
--
-- if (g_strcmp0 (matrix_utils_json_object_get_string (object, "v"), "v2") != 0 ||
-- g_strcmp0 (matrix_utils_json_object_get_string (json_key, "alg"), "A256CTR") != 0 ||
-- !matrix_utils_json_object_get_bool (json_key, "ext") ||
-- g_strcmp0 (matrix_utils_json_object_get_string (json_key, "kty"), "oct") != 0)
-- return;
--
-- info = g_new0 (MatrixFileEncInfo, 1);
-- info->aes_iv_base64 = g_strdup (matrix_utils_json_object_get_string (object, "iv"));
-- info->aes_key_base64 = g_strdup (matrix_utils_json_object_get_string (json_key, "k"));
-- /* XXX: update doc: uses basae64url */
-- g_strdelimit (info->aes_key_base64, "_", '/');
-- g_strdelimit (info->aes_key_base64, "-", '+');
--
-- object = matrix_utils_json_object_get_object (object, "hashes");
-- info->sha256_base64 = g_strdup (matrix_utils_json_object_get_string (object, "sha256"));
--
-- ma_chat_parse_base64_value (&info->aes_iv, &info->aes_iv_len, info->aes_iv_base64);
-- ma_chat_parse_base64_value (&info->aes_key, &info->aes_key_len, info->aes_key_base64);
-- ma_chat_parse_base64_value (&info->sha256, &info->sha256_len, info->sha256_base64);
--
-- if (info->aes_iv_len == 16 && info->aes_key_len == 32 && info->sha256_len == 32)
-- file->user_data = g_steal_pointer (&info);
--
-- if (file->user_data)
-- matrix_db_save_file_url_async (self->matrix_db, message, file, 2,
-- CHATTY_ALGORITHM_A256CTR, CHATTY_KEY_TYPE_OCT, TRUE,
-- NULL, NULL);
-- }
--
- if (!file)
- return;
-
-@@ -593,18 +358,15 @@ handle_m_room_encrypted (ChattyMaChat *self,
- JsonObject *root)
- {
- g_autofree char *plaintext = NULL;
-- JsonObject *content;
-+ g_autofree char *json_str = NULL;
-
- g_assert (CHATTY_IS_MA_CHAT (self));
-
- if (!root)
- return;
-
-- content = matrix_utils_json_object_get_object (root, "content");
-- if (content)
-- plaintext = matrix_enc_handle_join_room_encrypted (self->matrix_enc,
-- self->room_id,
-- content);
-+ json_str = matrix_utils_json_object_to_string (root, FALSE);
-+ plaintext = cm_room_decrypt_content (self->cm_room, json_str);
-
- if (plaintext) {
- g_autoptr(JsonObject) message = NULL;
-@@ -614,79 +376,6 @@ handle_m_room_encrypted (ChattyMaChat *self,
- }
- }
-
--static gboolean
--chat_resend_message (gpointer user_data)
--{
-- ChattyMaChat *self = user_data;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- self->message_timeout_id = 0;
-- matrix_send_message_from_queue (self);
--
-- return G_SOURCE_REMOVE;
--}
--
--static void
--ma_chat_send_message_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(ChattyMaChat) self = user_data;
-- g_autoptr(GError) error = NULL;
-- ChattyMessage *message;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- self->is_sending_message = FALSE;
--
-- matrix_api_send_message_finish (self->matrix_api, result, &error);
-- message = g_object_get_data (G_OBJECT (result), "message");
--
-- if (error) {
-- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- g_warning ("Error sending message: %s", error->message);
--
-- if (g_error_matches (error, MATRIX_ERROR, M_LIMIT_EXCEEDED) &&
-- !self->message_timeout_id) {
-- int timeout;
--
-- timeout = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (result), "retry-after"));
--
-- if (!timeout)
-- timeout = 2000;
--
-- self->message_timeout_id = g_timeout_add (timeout, chat_resend_message, self);
-- }
--
-- g_queue_push_head (self->message_queue, g_object_ref (message));
-- return;
-- }
--
-- matrix_send_message_from_queue (self);
--}
--
--static void
--matrix_send_message_from_queue (ChattyMaChat *self)
--{
-- g_autoptr(ChattyMessage) message = NULL;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- if (self->is_sending_message ||
-- !self->message_queue ||
-- !self->message_queue->length ||
-- self->message_timeout_id)
-- return;
--
-- message = g_queue_pop_head (self->message_queue);
-- self->is_sending_message = TRUE;
-- matrix_api_send_message_async (self->matrix_api, CHATTY_CHAT (self),
-- self->room_id, message,
-- ma_chat_send_message_cb,
-- g_object_ref (self));
--}
--
- static void
- ma_chat_handle_ephemeral (ChattyMaChat *self,
- JsonObject *root)
-@@ -725,338 +414,28 @@ ma_chat_handle_ephemeral (ChattyMaChat *self,
-
- /* Handle the first item so that we don’t have to
- handle buddy_typing in the loop */
-- username = matrix_api_get_username (self->matrix_api);
-- if (typing_count)
-- name = json_array_get_string_element (array, 0);
--
-- if (g_strcmp0 (name, username) == 0)
-- self_typing = TRUE;
-- else if (typing_count)
-- buddy_typing = TRUE;
--
-- /* Check if the server says we are typing too */
-- for (guint i = 0; !self_typing && i < typing_count; i++)
-- if (g_str_equal (json_array_get_string_element (array, i), username))
-- self_typing = TRUE;
--
-- if (self->self_typing != self_typing) {
-- self->self_typing = self_typing;
-- self->self_typing_set_time = g_get_monotonic_time ();
-- }
--
-- if (self->buddy_typing != buddy_typing) {
-- self->buddy_typing = buddy_typing;
-- g_object_notify (G_OBJECT (self), "buddy-typing");
-- }
-- }
-- }
-- }
-- }
--}
--
--static void
--upload_out_group_key_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- ChattyMaChat *self = user_data;
-- g_autoptr(GError) error = NULL;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- self->claiming_keys = FALSE;
-- if (matrix_api_upload_group_keys_finish (self->matrix_api, result, &error))
-- self->keys_claimed = TRUE;
--
-- if (error) {
-- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- g_warning ("error uploading group keys: %s", error->message);
-- return;
-- }
--
-- matrix_send_message_from_queue (self);
--}
--
--static void
--claim_key_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- ChattyMaChat *self = user_data;
-- g_autoptr(JsonObject) root = NULL;
-- g_autoptr(GList) members = NULL;
-- g_autoptr(GError) error = NULL;
-- JsonObject *object;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- root = matrix_api_claim_keys_finish (self->matrix_api, result, &error);
--
-- if (error) {
-- self->claiming_keys = FALSE;
-- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- g_warning ("error: %s", error->message);
-- return;
-- }
--
-- object = matrix_utils_json_object_get_object (root, "one_time_keys");
-- if (object)
-- members = json_object_get_members (object);
--
-- for (GList *member = members; member; member = member->next) {
-- ChattyMaBuddy *buddy;
-- JsonObject *keys;
--
-- buddy = ma_chat_find_buddy (self, G_LIST_MODEL (self->buddy_list),
-- member->data, NULL);
--
-- if (!buddy) {
-- g_warning ("‘%s’ not found in buddy list", (char *)member->data);
-- continue;
-- }
--
-- keys = matrix_utils_json_object_get_object (object, member->data);
-- chatty_ma_buddy_add_one_time_keys (buddy, keys);
-- }
--
-- matrix_api_upload_group_keys_async (self->matrix_api,
-- self->room_id,
-- G_LIST_MODEL (self->buddy_list),
-- upload_out_group_key_cb,
-- self);
--}
--
--static void
--query_key_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- ChattyMaChat *self = user_data;
-- g_autoptr(JsonObject) root = NULL;
-- g_autoptr(GList) members = NULL;
-- g_autoptr(GError) error = NULL;
-- JsonObject *object;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
-- g_return_if_fail (!self->keys_claimed);
--
-- root = matrix_api_query_keys_finish (self->matrix_api, result, &error);
--
-- if (error) {
-- self->claiming_keys = FALSE;
-- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- g_warning ("error: %s", error->message);
-- return;
-- }
--
-- object = matrix_utils_json_object_get_object (root, "device_keys");
-- if (object)
-- members = json_object_get_members (object);
--
-- /* TODO: avoid blocked devices (once we implement blocking) */
-- for (GList *member = members; member; member = member->next) {
-- ChattyMaBuddy *buddy;
-- JsonObject *device;
--
-- buddy = ma_chat_find_buddy (self, G_LIST_MODEL (self->buddy_list),
-- member->data, NULL);
--
-- if (!buddy) {
-- g_warning ("‘%s’ not found in buddy list", (char *)member->data);
-- continue;
-- }
--
-- device = matrix_utils_json_object_get_object (object, member->data);
-- chatty_ma_buddy_add_devices (buddy, device);
-- }
--
-- matrix_api_claim_keys_async (self->matrix_api,
-- G_LIST_MODEL (self->buddy_list),
-- claim_key_cb, self);
--}
--
--static void
--get_chat_users_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(ChattyMaChat) self = user_data;
-- g_autoptr(JsonObject) object = NULL;
-- g_autoptr(GList) members = NULL;
-- g_autoptr(GError) error = NULL;
-- JsonObject *joined;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- object = matrix_api_get_room_users_finish (self->matrix_api, result, &error);
--
-- self->user_list_loading = FALSE;
-- self->user_list_loaded = !error;
--
-- if (error) {
-- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- g_warning ("Error loading chat members: %s", error->message);
--
-- return;
-- }
--
-- joined = matrix_utils_json_object_get_object (object, "joined");
-- members = json_object_get_members (joined);
--
-- for (GList *member = members; member; member = member->next) {
-- ChattyMaBuddy *buddy;
-- JsonObject *data;
-- const char *name;
--
-- buddy = ma_chat_find_buddy (self, G_LIST_MODEL (self->buddy_list), member->data, NULL);
-- if (!buddy)
-- buddy = ma_chat_add_buddy (self, self->buddy_list, member->data);
--
-- data = json_object_get_object_member (joined, member->data);
-- name = matrix_utils_json_object_get_string (data, "display_name");
-- chatty_item_set_name (CHATTY_ITEM (buddy), name);
-- };
--
-- self->claiming_keys = TRUE;
-- matrix_api_query_keys_async (self->matrix_api,
-- G_LIST_MODEL (self->buddy_list),
-- NULL, query_key_cb, self);
--}
--
--#if 0
--static void
--get_room_state_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- ChattyMaChat *self = user_data;
-- g_autoptr(GError) error = NULL;
-- g_autoptr(JsonArray) array = NULL;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- array = matrix_api_get_room_state_finish (self->matrix_api, result, &error);
-- self->state_is_syncing = FALSE;
--
-- CHATTY_TRACE_MSG ("Got room state, room: %s (%s), success: %d",
-- self->room_id, chatty_item_get_name (CHATTY_ITEM (self)), !error);
-- if (error) {
-- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- g_warning ("error: %s", error->message);
-- return;
-- }
--
-- if (json_array_get_length (array) == 0)
-- return;
--
-- self->state_is_sync = TRUE;
-- for (guint i = 0; i < json_array_get_length (array); i++) {
-- JsonObject *object;
-- const char *type;
--
-- object = json_array_get_object_element (array, i);
-- type = matrix_utils_json_object_get_string (object, "type");
--
-- if (!type || !*type)
-- continue;
--
-- if (g_str_equal (type, "m.room.member"))
-- handle_m_room_member (self, object, self->buddy_list);
-- else if (g_str_equal (type, "m.room.name"))
-- handle_m_room_name (self, object);
-- else if (g_str_equal (type, "m.room.encryption"))
-- handle_m_room_encryption (self, object);
-- else if (g_str_equal (type, "m.room.avatar"))
-- handle_m_room_avatar (self, object);
-- /* TODO */
-- /* else if (g_str_equal (type, "m.room.power_levels")) */
-- /* handle_m_room_power_levels (self, object); */
-- /* else if (g_str_equal (type, "m.room.guest_access")) */
-- /* handle_m_room_guest_access (self, object); */
-- /* else if (g_str_equal (type, "m.room.create")) */
-- /* handle_m_room_create (self, object); */
-- /* else if (g_str_equal (type, "m.room.history_visibility")) */
-- /* handle_m_room_history_visibility (self, object); */
-- /* else if (g_str_equal (type, "m.room.join_rules")) */
-- /* handle_m_room_join_rules (self, object); */
-- /* else */
-- /* g_warn_if_reached (); */
-- }
--
-- /* Clear pointer so that it’s generated when requested */
-- g_clear_pointer (&self->generated_name, g_free);
-- g_object_notify (G_OBJECT (self), "name");
--
-- if (self->message_queue->length > 0) {
-- if (!self->claiming_keys)
-- matrix_api_query_keys_async (self->matrix_api,
-- G_LIST_MODEL (self->buddy_list),
-- NULL, query_key_cb, self);
-- else if (self->keys_claimed)
-- matrix_send_message_from_queue (self);
-- }
--
-- g_object_notify (G_OBJECT (self), "name");
-- g_signal_emit_by_name (self, "avatar-changed");
--
-- chatty_history_update_chat (self->history_db, CHATTY_CHAT (self));
--}
--#endif
--
--static void
--get_room_name_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- ChattyMaChat *self = user_data;
-- g_autoptr(GError) error = NULL;
-- g_autoptr(JsonObject) object = NULL;
-- const char *name;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
-- self->state_is_sync = TRUE;
-- self->state_is_syncing = FALSE;
--
-- object = matrix_api_get_room_name_finish (self->matrix_api, result, &error);
--
-- if (error) {
-- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
-- !g_error_matches (error, MATRIX_ERROR, M_NOT_FOUND))
-- g_warning ("error getting room name: %s", error->message);
-- return;
-- }
--
-- name = matrix_utils_json_object_get_string (object, "name");
-- g_free (self->room_name);
-- self->room_name = g_strdup (name);
-- chatty_history_update_chat (self->history_db, CHATTY_CHAT (self));
--
-- CHATTY_TRACE (self->room_id, "Got room name, room:");
--
-- g_object_notify (G_OBJECT (self), "name");
--}
--
--static void
--get_room_encryption_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- ChattyMaChat *self = user_data;
-- g_autoptr(GError) error = NULL;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
-+ username = cm_client_get_user_id (self->cm_client);
-+ if (typing_count)
-+ name = json_array_get_string_element (array, 0);
-
-- self->encryption = matrix_api_get_room_encryption_finish (self->matrix_api, result, &error);
-+ if (g_strcmp0 (name, username) == 0)
-+ self_typing = TRUE;
-+ else if (typing_count)
-+ buddy_typing = TRUE;
-
-- CHATTY_TRACE (self->room_id, "Got room encryption state: encrypted: %d, room:",
-- !!self->encryption);
-- g_object_notify (G_OBJECT (self), "encrypt");
-+ /* Check if the server says we are typing too */
-+ for (guint i = 0; !self_typing && i < typing_count; i++)
-+ if (g_str_equal (json_array_get_string_element (array, i), username))
-+ self_typing = TRUE;
-
-- CHATTY_TRACE (self->room_id, "Getting room name for");
-- matrix_api_get_room_name_async (self->matrix_api,
-- self->room_id,
-- get_room_name_cb,
-- self);
-+ if (self->buddy_typing != buddy_typing) {
-+ self->buddy_typing = buddy_typing;
-+ g_object_notify (G_OBJECT (self), "buddy-typing");
-+ }
-+ }
-+ }
-+ }
-+ }
- }
-
- static void
-@@ -1092,16 +471,10 @@ parse_chat_array (ChattyMaChat *self,
- g_strcmp0 (sender, chatty_item_get_username (CHATTY_ITEM (self))) == 0)
- g_set_object (&self->self_buddy, buddy);
-
-- if (g_str_equal (type, "m.room.name")) {
-- handle_m_room_name (self, object);
-- } else if (g_str_equal (type, "m.room.message")) {
-+ if (g_str_equal (type, "m.room.message")) {
- matrix_add_message_from_data (self, buddy, NULL, object, FALSE);
-- } else if (g_str_equal (type, "m.room.encryption")) {
-- handle_m_room_encryption (self, object);
- } else if (g_str_equal (type, "m.room.encrypted")) {
- handle_m_room_encrypted (self, buddy, object);
-- } else if (g_str_equal (type, "m.room.member")) {
-- handle_m_room_member (self, object);
- }
- }
-
-@@ -1135,9 +508,6 @@ matrix_chat_set_json_data (ChattyMaChat *self,
- object = matrix_utils_json_object_get_object (self->json_data, "timeline");
- parse_chat_array (self, matrix_utils_json_object_get_array (object, "events"));
-
-- if (object && matrix_utils_json_object_get_bool (object, "limited"))
-- chatty_ma_chat_set_prev_batch (self, g_strdup (matrix_utils_json_object_get_string (object, "prev_batch")));
--
- object = matrix_utils_json_object_get_object (self->json_data, "unread_notifications");
- if (object) {
- guint old_count;
-@@ -1160,91 +530,31 @@ get_messages_cb (GObject *obj,
- {
- ChattyMaChat *self;
- g_autoptr(GTask) task = user_data;
-- g_autoptr(JsonObject) root = NULL;
-+ g_autoptr(JsonNode) node = NULL;
- g_autoptr(GError) error = NULL;
-+ JsonObject *root = NULL;
-+ g_autofree char *json_str;
-
- g_assert (G_IS_TASK (task));
-
- self = g_task_get_source_object (task);
- g_assert (CHATTY_IS_MA_CHAT (self));
-
-- root = matrix_api_load_prev_batch_finish (self->matrix_api, result, &error);
-+ json_str = cm_room_load_prev_batch_finish (self->cm_room, result, &error);
- self->prev_batch_loading = FALSE;
- self->history_is_loading = FALSE;
- g_object_notify (G_OBJECT (self), "loading-history");
-
-- if (error) {
-- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-+ if (!json_str) {
-+ if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- g_warning ("error: %s", error->message);
- g_task_return_boolean (task, FALSE);
- return;
- }
-
-+ node = json_from_string (json_str, &error);
-+ root = json_node_get_object (node);
- parse_chat_array (self, matrix_utils_json_object_get_array (root, "chunk"));
--
-- /* If start and end are same, we no longer have events to load */
-- if (g_strcmp0 (matrix_utils_json_object_get_string (root, "end"),
-- matrix_utils_json_object_get_string (root, "start")) == 0)
-- chatty_ma_chat_set_prev_batch (self, NULL);
-- else
-- chatty_ma_chat_set_prev_batch (self, g_strdup (matrix_utils_json_object_get_string (root, "end")));
--
-- if (self->prev_batch) {
-- GListModel *model;
-- guint message_count;
--
-- model = G_LIST_MODEL (chatty_chat_get_messages (CHATTY_CHAT (self)));
-- message_count = GPOINTER_TO_UINT(g_object_get_data (G_OBJECT (task), "count"));
--
-- /* Load more items if no message was loaded. This can happen
-- * when no event in the loaded events was a room message.
-- */
-- if (chatty_chat_get_encryption (CHATTY_CHAT (self)) != CHATTY_ENCRYPTION_ENABLED &&
-- g_list_model_get_n_items (model) == message_count)
-- chatty_chat_load_past_messages (CHATTY_CHAT (self), -1);
-- }
--}
--
--static void
--db_room_room_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- ChattyMaChat *self;
-- g_autoptr(GTask) task = user_data;
-- g_autoptr(GError) error = NULL;
--
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- g_object_freeze_notify (G_OBJECT (self));
--
-- self->room_db_loaded = TRUE;
-- self->history_is_loading = FALSE;
-- g_object_notify (G_OBJECT (self), "loading-history");
--
-- g_free (self->prev_batch);
-- self->prev_batch = matrix_db_load_room_finish (self->matrix_db, result, &error);
-- CHATTY_TRACE (self->room_id, "Load from db, success: %d, has prev-batch: %d, chat:",
-- !error, !!self->prev_batch);
--
-- if (error)
-- g_warning ("Error loading prev batch: %s", error->message);
--
-- if (self->prev_batch) {
-- self->history_is_loading = TRUE;
-- g_object_notify (G_OBJECT (self), "loading-history");
-- matrix_api_load_prev_batch_async (self->matrix_api,
-- self->room_id,
-- self->prev_batch,
-- self->last_batch,
-- get_messages_cb,
-- g_steal_pointer (&task));
-- }
--
-- g_object_thaw_notify (G_OBJECT (self));
- }
-
- static void
-@@ -1268,7 +578,9 @@ ma_chat_load_db_messages_cb (GObject *object,
- self->history_is_loading = FALSE;
- g_object_notify (G_OBJECT (self), "loading-history");
-
-- if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-+ if (error &&
-+ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
-+ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
- g_warning ("Error fetching messages from db: %s,", error->message);
-
- CHATTY_TRACE_MSG ("Messages loaded from db: %u", !messages ? 0 : messages->len);
-@@ -1278,24 +590,16 @@ ma_chat_load_db_messages_cb (GObject *object,
- chatty_chat_show_notification (CHATTY_CHAT (self), NULL);
- g_signal_emit_by_name (self, "changed", 0);
- g_task_return_boolean (task, TRUE);
-- } else if (!messages && self->prev_batch) {
-+ } else if (!messages && !self->prev_batch_loading) {
- self->history_is_loading = TRUE;
-+ self->prev_batch_loading = TRUE;
- g_object_notify (G_OBJECT (self), "loading-history");
-- matrix_api_load_prev_batch_async (self->matrix_api,
-- self->room_id,
-- self->prev_batch,
-- self->last_batch,
-- get_messages_cb,
-- g_steal_pointer (&task));
-- } else if (!self->room_db_loaded &&
-- matrix_api_get_device_id (self->matrix_api)) {
-- self->history_is_loading = TRUE;
-- g_object_notify (G_OBJECT (self), "loading-history");
-- matrix_db_load_room_async (self->matrix_db, self->account,
-- matrix_api_get_device_id (self->matrix_api),
-- self->room_id,
-- db_room_room_cb,
-- g_steal_pointer (&task));
-+ cm_room_load_prev_batch_async (self->cm_room, NULL,
-+ get_messages_cb,
-+ g_steal_pointer (&task));
-+ } else {
-+ /* TODO */
-+ /* g_task_return_boolean (); */
- }
-
- g_object_thaw_notify (G_OBJECT (self));
-@@ -1307,6 +611,12 @@ chatty_ma_chat_is_im (ChattyChat *chat)
- return TRUE;
- }
-
-+static gboolean
-+chatty_ma_chat_has_file_upload (ChattyChat *chat)
-+{
-+ return TRUE;
-+}
-+
- static const char *
- chatty_ma_chat_get_chat_name (ChattyChat *chat)
- {
-@@ -1387,7 +697,7 @@ chatty_ma_chat_get_encryption (ChattyChat *chat)
-
- g_assert (CHATTY_IS_MA_CHAT (self));
-
-- if (self->encryption)
-+ if (self->cm_room && cm_room_is_encrypted (self->cm_room))
- return CHATTY_ENCRYPTION_ENABLED;
-
- return CHATTY_ENCRYPTION_DISABLED;
-@@ -1408,16 +718,13 @@ ma_chat_set_encryption_cb (GObject *object,
- self = g_task_get_source_object (task);
- g_assert (CHATTY_IS_MA_CHAT (self));
-
-- ret = matrix_api_set_room_encryption_finish (self->matrix_api, result, &error);
-+ ret = cm_room_enable_encryption_finish (self->cm_room, result, &error);
- CHATTY_DEBUG (self->room_id, "Setting encryption, success: %d, room:", ret);
-
- if (error) {
- g_warning ("Failed to set encryption: %s", error->message);
- g_task_return_error (task, error);
- } else {
-- if (ret)
-- self->encryption = g_strdup ("encrypted");
--
- g_object_notify (G_OBJECT (self), "encrypt");
- g_task_return_boolean (task, ret);
- }
-@@ -1433,7 +740,7 @@ chatty_ma_chat_set_encryption_async (ChattyChat *chat,
- g_autoptr(GTask) task = NULL;
-
- g_assert (CHATTY_IS_MA_CHAT (self));
-- g_assert (self->matrix_api);
-+ g_assert (self->cm_client);
-
- task = g_task_new (self, NULL, callback, user_data);
-
-@@ -1445,18 +752,10 @@ chatty_ma_chat_set_encryption_async (ChattyChat *chat,
- return;
- }
-
-- if (enable &&
-- chatty_chat_get_encryption (chat) == CHATTY_ENCRYPTION_ENABLED) {
-- g_debug ("Encryption is already enabled");
-- g_task_return_boolean (task, TRUE);
--
-- return;
-- }
--
- CHATTY_DEBUG (self->room_id, "Setting encryption for room:");
-- matrix_api_set_room_encryption_async (self->matrix_api, self->room_id,
-- ma_chat_set_encryption_cb,
-- g_steal_pointer (&task));
-+ cm_room_enable_encryption_async (self->cm_room, NULL,
-+ ma_chat_set_encryption_cb,
-+ g_steal_pointer (&task));
- }
-
- static const char *
-@@ -1500,7 +799,7 @@ chat_set_read_marker_cb (GObject *object,
-
- g_assert (CHATTY_IS_MA_CHAT (self));
-
-- if (matrix_api_set_read_marker_finish (self->matrix_api, result, &error)) {
-+ if (cm_room_set_read_marker_finish (self->cm_room, result, &error)) {
- self->unread_count = 0;
- g_signal_emit_by_name (self, "changed", 0);
- } else if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-@@ -1530,8 +829,10 @@ chatty_ma_chat_set_unread_count (ChattyChat *chat,
- return;
-
- message = g_list_model_get_item (model, n_items - 1);
-- matrix_api_set_read_marker_async (self->matrix_api, self->room_id, message,
-- chat_set_read_marker_cb, self);
-+ cm_room_set_read_marker_async (self->cm_room,
-+ chatty_message_get_uid (message),
-+ chatty_message_get_uid (message),
-+ chat_set_read_marker_cb, self);
- } else {
- self->unread_count = unread_count;
- chatty_chat_show_notification (CHATTY_CHAT (chat), NULL);
-@@ -1539,6 +840,34 @@ chatty_ma_chat_set_unread_count (ChattyChat *chat,
- }
- }
-
-+static void
-+ma_chage_send_message_cb (GObject *object,
-+ GAsyncResult *result,
-+ gpointer user_data)
-+{
-+ ChattyMaChat *self;
-+ g_autoptr(GTask) task = user_data;
-+ g_autofree char *event_id = NULL;
-+ ChattyMessage *message;
-+
-+ g_assert (G_IS_TASK (task));
-+
-+ self = g_task_get_source_object (task);
-+ message = g_task_get_task_data (task);
-+ g_assert (CHATTY_IS_MA_CHAT (self));
-+ g_assert (CHATTY_IS_MESSAGE (message));
-+
-+ event_id = cm_room_send_text_finish (self->cm_room, result, NULL);
-+
-+ /* We add only failed to send messages. If sending succeeded,
-+ * we shall get the same via the /sync responses */
-+ if (event_id) {
-+ chatty_message_set_status (message, CHATTY_STATUS_SENT, 0);
-+ } else {
-+ chatty_message_set_status (message, CHATTY_STATUS_SENDING_FAILED, 0);
-+ }
-+}
-+
- static void
- chatty_ma_chat_send_message_async (ChattyChat *chat,
- ChattyMessage *message,
-@@ -1546,6 +875,10 @@ chatty_ma_chat_send_message_async (ChattyChat *chat,
- gpointer user_data)
- {
- ChattyMaChat *self = (ChattyMaChat *)chat;
-+ const char *event_id;
-+ GList *files = NULL;
-+ GFile *file = NULL;
-+ GTask *task;
-
- g_assert (CHATTY_IS_MA_CHAT (self));
- g_assert (CHATTY_IS_MESSAGE (message));
-@@ -1553,22 +886,133 @@ chatty_ma_chat_send_message_async (ChattyChat *chat,
- chatty_message_set_user (message, CHATTY_ITEM (self->self_buddy));
- chatty_message_set_status (message, CHATTY_STATUS_SENDING, 0);
-
-+ task = g_task_new (self, NULL, callback, user_data);
-+ g_task_set_task_data (task, g_object_ref (message), g_object_unref);
- g_list_store_append (self->message_list, message);
-- g_queue_push_tail (self->message_queue, g_object_ref (message));
--
-- if (chatty_chat_get_encryption (chat) != CHATTY_ENCRYPTION_ENABLED ||
-- self->keys_claimed)
-- matrix_send_message_from_queue (self);
-- else if (!self->user_list_loaded && !self->user_list_loading) {
-- self->user_list_loading = TRUE;
-- matrix_api_get_room_users_async (self->matrix_api, self->room_id,
-- get_chat_users_cb,
-- g_object_ref (self));
-- } else if (!self->state_is_syncing && !self->claiming_keys) {
-- self->claiming_keys = TRUE;
-- matrix_api_query_keys_async (self->matrix_api,
-- G_LIST_MODEL (self->buddy_list),
-- NULL, query_key_cb, self);
-+
-+ files = chatty_message_get_files (message);
-+
-+ if (files) {
-+ ChattyFileInfo *file_info;
-+ file_info = files->data;
-+
-+ if (file_info && file_info->path)
-+ file = g_file_new_for_path (file_info->path);
-+
-+ }
-+
-+ if (file)
-+ event_id = cm_room_send_file_async (self->cm_room, file, NULL,
-+ NULL, NULL, NULL,
-+ ma_chage_send_message_cb, task);
-+ else
-+ event_id = cm_room_send_text_async (self->cm_room,
-+ chatty_message_get_text (message),
-+ NULL,
-+ ma_chage_send_message_cb, task);
-+ g_object_set_data_full (G_OBJECT (message), "event-id", g_strdup (event_id), g_free);
-+}
-+
-+static void
-+ma_download_file_stream_cb (GObject *obj,
-+ GAsyncResult *result,
-+ gpointer user_data)
-+{
-+ ChattyMaChat *self;
-+ g_autoptr(GTask) task = user_data;
-+ ChattyMessage *message;
-+ ChattyFileInfo *file;
-+ GError *error = NULL;
-+
-+ g_assert (G_IS_TASK (task));
-+
-+ self = g_task_get_source_object (task);
-+ g_assert (CHATTY_IS_MA_CHAT (self));
-+
-+ g_output_stream_splice_finish (G_OUTPUT_STREAM (obj), result, &error);
-+ message = g_object_get_data (user_data, "message");
-+ file = g_object_get_data (user_data, "file");
-+
-+ if (error) {
-+ file->status = CHATTY_FILE_ERROR;
-+ g_task_return_error (task, error);
-+ } else {
-+ g_autofree char *file_name = NULL;
-+ g_autoptr(GFile) parent = NULL;
-+ GFile *out_file;
-+
-+ out_file = g_object_get_data (user_data, "out-file");
-+ parent = g_file_new_build_filename (g_get_user_cache_dir (), "chatty", NULL);
-+
-+ file_name = g_path_get_basename (file->url);
-+ file->path = g_file_get_relative_path (parent, out_file);
-+ file->status = CHATTY_FILE_DOWNLOADED;
-+
-+ g_task_return_boolean (task, TRUE);
-+ }
-+
-+ chatty_history_add_message (self->history_db, CHATTY_CHAT (self), message);
-+ chatty_message_emit_updated (message);
-+}
-+
-+static void
-+ma_chat_download_cb (GObject *object,
-+ GAsyncResult *result,
-+ gpointer user_data)
-+{
-+ ChattyMaChat *self;
-+ g_autoptr(GTask) task = user_data;
-+ g_autoptr(GError) error = NULL;
-+ g_autoptr(GInputStream) istream = NULL;
-+ ChattyMessage *message;
-+ ChattyFileInfo *file;
-+
-+ g_assert (G_IS_TASK (task));
-+
-+ self = g_task_get_source_object (task);
-+ g_assert (CHATTY_IS_MA_CHAT (self));
-+
-+ file = g_object_get_data (G_OBJECT (task), "file");
-+ message = g_object_get_data (G_OBJECT (task), "message");
-+ g_return_if_fail (file);
-+ g_return_if_fail (message);
-+
-+ istream = cm_client_get_file_finish (self->cm_client, result, &error);
-+
-+ if (istream) {
-+ GOutputStream *out_stream;
-+ g_autofree char *file_name = NULL;
-+ GFile *out_file;
-+
-+ file_name = g_path_get_basename (file->url);
-+ out_file = g_file_new_build_filename (g_get_user_cache_dir (), "chatty", "matrix",
-+ "files", file_name, NULL);
-+ out_stream = (GOutputStream *)g_file_create (out_file, G_FILE_CREATE_NONE, NULL, &error);
-+ g_object_set_data_full (user_data, "out-file", out_file, g_object_unref);
-+
-+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS))
-+ {
-+ GFileIOStream *io_stream;
-+
-+ io_stream = g_file_open_readwrite (out_file, NULL, NULL);
-+ out_stream = g_io_stream_get_output_stream (G_IO_STREAM (io_stream));
-+ }
-+
-+ if (out_stream) {
-+ g_output_stream_splice_async (G_OUTPUT_STREAM (out_stream), istream,
-+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
-+ G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
-+ 0, NULL,
-+ ma_download_file_stream_cb,
-+ g_steal_pointer (&task));
-+ } else {
-+ g_task_return_boolean (task, FALSE);
-+ }
-+ } else {
-+ file->status = CHATTY_FILE_UNKNOWN;
-+
-+ chatty_history_add_message (self->history_db, CHATTY_CHAT (self), message);
-+ chatty_message_emit_updated (message);
- }
- }
-
-@@ -1578,15 +1022,41 @@ chatty_ma_chat_get_files_async (ChattyChat *chat,
- GAsyncReadyCallback callback,
- gpointer user_data)
- {
-+ g_autoptr(GTask) task = NULL;
- ChattyMaChat *self = CHATTY_MA_CHAT (chat);
-+ ChattyFileInfo *file;
- GList *files;
-
- g_assert (CHATTY_IS_MA_CHAT (self));
- g_assert (CHATTY_IS_MESSAGE (message));
-
-+ task = g_task_new (self, NULL, callback, user_data);
-+ g_object_set_data_full (G_OBJECT (task), "message", g_object_ref (message), g_object_unref);
-+
- files = chatty_message_get_files (message);
-- matrix_api_get_file_async (self->matrix_api, message, files->data, NULL, NULL,
-- ma_chat_download_cb, self);
-+ if (!files)
-+ {
-+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
-+ "No file found in message");
-+ return;
-+ }
-+
-+
-+ file = files->data;
-+ if (!file->url || file->status != CHATTY_FILE_UNKNOWN)
-+ {
-+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
-+ "File URL missing or invalid file state");
-+ return;
-+ }
-+
-+ g_object_set_data (G_OBJECT (task), "file", file);
-+
-+ file->status = CHATTY_FILE_DOWNLOADING;
-+ chatty_message_emit_updated (message);
-+ cm_client_get_file_async (self->cm_client, file->url, NULL,
-+ ma_chat_download_cb,
-+ g_steal_pointer (&task));
- }
-
- static gboolean
-@@ -1607,13 +1077,7 @@ chatty_ma_chat_set_typing (ChattyChat *chat,
-
- g_assert (CHATTY_IS_MA_CHAT (self));
-
-- if (self->self_typing == is_typing &&
-- (g_get_monotonic_time () - self->self_typing_set_time) < G_TIME_SPAN_SECOND * 5)
-- return;
--
-- self->self_typing = is_typing;
-- self->self_typing_set_time = g_get_monotonic_time ();
-- matrix_api_set_typing (self->matrix_api, self->room_id, is_typing);
-+ cm_room_set_typing_notice_async (self->cm_room, is_typing, NULL, NULL, NULL);
- }
-
- static void
-@@ -1634,9 +1098,14 @@ static const char *
- chatty_ma_chat_get_name (ChattyItem *item)
- {
- ChattyMaChat *self = (ChattyMaChat *)item;
-+ const char *name;
-
- g_assert (CHATTY_IS_MA_CHAT (self));
-
-+ name = cm_room_get_name (self->cm_room);
-+ if (name && *name)
-+ return name;
-+
- if (self->room_name)
- return self->room_name;
-
-@@ -1662,7 +1131,7 @@ chatty_ma_chat_get_username (ChattyItem *item)
-
- g_assert (CHATTY_IS_MA_CHAT (self));
-
-- return matrix_api_get_username (self->matrix_api);
-+ return cm_client_get_user_id (self->cm_client);
- }
-
- static ChattyItemState
-@@ -1755,8 +1224,6 @@ chatty_ma_chat_finalize (GObject *object)
- {
- ChattyMaChat *self = (ChattyMaChat *)object;
-
-- g_clear_handle_id (&self->message_timeout_id, g_source_remove);
--
- if (self->avatar_cancellable)
- g_cancellable_cancel (self->avatar_cancellable);
- g_clear_object (&self->avatar_cancellable);
-@@ -1766,23 +1233,17 @@ chatty_ma_chat_finalize (GObject *object)
- g_clear_object (&self->message_list);
- g_clear_object (&self->sorted_message_list);
- g_clear_object (&self->buddy_list);
-- g_clear_object (&self->matrix_api);
-- g_clear_object (&self->matrix_enc);
- g_clear_object (&self->self_buddy);
- g_clear_pointer (&self->avatar_file, chatty_file_info_free);
- g_clear_object (&self->avatar);
-
-- g_clear_object (&self->matrix_db);
- g_clear_object (&self->history_db);
-
- g_clear_pointer (&self->json_data, json_object_unref);
-- g_queue_free_full (self->message_queue, g_object_unref);
-
- g_free (self->room_name);
- g_free (self->generated_name);
- g_free (self->room_id);
-- g_free (self->encryption);
-- g_free (self->prev_batch);
- g_free (self->last_batch);
-
- G_OBJECT_CLASS (chatty_ma_chat_parent_class)->finalize (object);
-@@ -1807,6 +1268,7 @@ chatty_ma_chat_class_init (ChattyMaChatClass *klass)
- item_class->get_avatar = chatty_ma_chat_get_avatar;
-
- chat_class->is_im = chatty_ma_chat_is_im;
-+ chat_class->has_file_upload = chatty_ma_chat_has_file_upload;
- chat_class->get_chat_name = chatty_ma_chat_get_chat_name;
- chat_class->load_past_messages = chatty_ma_chat_real_past_messages;
- chat_class->is_loading_history = chatty_ma_chat_is_loading_history;
-@@ -1850,7 +1312,6 @@ chatty_ma_chat_init (ChattyMaChat *self)
- self->message_list = g_list_store_new (CHATTY_TYPE_MESSAGE);
- self->sorted_message_list = gtk_sort_list_model_new (G_LIST_MODEL (self->message_list), sorter);
- self->buddy_list = g_list_store_new (CHATTY_TYPE_MA_BUDDY);
-- self->message_queue = g_queue_new ();
- self->avatar_cancellable = g_cancellable_new ();
- }
-
-@@ -1868,12 +1329,93 @@ chatty_ma_chat_new (const char *room_id,
- "room-id", room_id, NULL);
- self->room_name = g_strdup (name);
- self->avatar_file = avatar;
-- if (encrypted)
-- self->encryption = g_strdup ("encrypted");
-
- return self;
- }
-
-+static void
-+ma_chat_name_changed_cb (ChattyMaChat *self)
-+{
-+ g_assert (CHATTY_IS_MA_CHAT (self));
-+
-+ g_object_notify (G_OBJECT (self), "name");
-+ g_signal_emit_by_name (self, "avatar-changed");
-+}
-+
-+static void
-+ma_chat_encryption_changed_cb (ChattyMaChat *self)
-+{
-+ g_assert (CHATTY_IS_MA_CHAT (self));
-+
-+ g_object_notify (G_OBJECT (self), "encrypt");
-+}
-+
-+static void
-+joined_members_changed_cb (ChattyMaChat *self,
-+ guint position,
-+ guint removed,
-+ guint added,
-+ GListModel *model)
-+{
-+ g_autoptr(GPtrArray) items = NULL;
-+
-+ g_assert (CHATTY_IS_CHAT (self));
-+ g_assert (G_IS_LIST_MODEL (model));
-+
-+ for (guint i = position; i < position + added; i++)
-+ {
-+ g_autoptr(CmUser) user = NULL;
-+ ChattyMaBuddy *buddy;
-+
-+ if (!items)
-+ items = g_ptr_array_new_with_free_func (g_object_unref);
-+
-+ user = g_list_model_get_item (model, i);
-+ buddy = chatty_ma_buddy_new_with_user (user, self->cm_client);
-+ g_ptr_array_add (items, buddy);
-+ }
-+
-+ g_list_store_splice (self->buddy_list, position, removed,
-+ items ? items->pdata : NULL, added);
-+}
-+
-+ChattyMaChat *
-+chatty_ma_chat_new_with_room (CmRoom *room)
-+{
-+ ChattyMaChat *self;
-+ GListModel *members;
-+
-+ g_return_val_if_fail (CM_IS_ROOM (room), NULL);
-+
-+ self = g_object_new (CHATTY_TYPE_MA_CHAT,
-+ "room-id", cm_room_get_id (room), NULL);
-+ self->cm_room = g_object_ref (room);
-+ g_signal_connect_object (room, "notify::name",
-+ G_CALLBACK (ma_chat_name_changed_cb),
-+ self, G_CONNECT_SWAPPED);
-+ g_signal_connect_object (room, "notify::encrypted",
-+ G_CALLBACK (ma_chat_encryption_changed_cb),
-+ self, G_CONNECT_SWAPPED);
-+
-+ members = cm_room_get_joined_members (room);
-+ g_signal_connect_object (members, "items-changed",
-+ G_CALLBACK (joined_members_changed_cb),
-+ self, G_CONNECT_SWAPPED);
-+ joined_members_changed_cb (self, 0, 0,
-+ g_list_model_get_n_items (members),
-+ members);
-+
-+ return self;
-+}
-+
-+CmRoom *
-+chatty_ma_chat_get_cm_room (ChattyMaChat *self)
-+{
-+ g_return_val_if_fail (CHATTY_IS_MA_CHAT (self), FALSE);
-+
-+ return self->cm_room;
-+}
-+
- void
- chatty_ma_chat_set_history_db (ChattyMaChat *self,
- gpointer history_db)
-@@ -1885,23 +1427,11 @@ chatty_ma_chat_set_history_db (ChattyMaChat *self,
- self->history_db = g_object_ref (history_db);
- }
-
--void
--chatty_ma_chat_set_matrix_db (ChattyMaChat *self,
-- gpointer matrix_db)
--{
-- g_return_if_fail (CHATTY_IS_MA_CHAT (self));
-- g_return_if_fail (MATRIX_IS_DB (matrix_db));
-- g_return_if_fail (!self->matrix_db);
--
-- self->matrix_db = g_object_ref (matrix_db);
--}
--
- /**
- * chatty_ma_chat_set_data:
- * @self: a #ChattyMaChat
- * @account: A #ChattyMaAccount
-- * @api: A #MatrixApi
-- * @enc: A #MatrixEnc for E2E
-+ * @client: A #CmClient
- *
- * Use this function to set internal data required
- * to connect to a matrix server.
-@@ -1909,25 +1439,13 @@ chatty_ma_chat_set_matrix_db (ChattyMaChat *self,
- void
- chatty_ma_chat_set_data (ChattyMaChat *self,
- ChattyAccount *account,
-- gpointer api,
-- gpointer enc)
-+ gpointer client)
- {
- g_return_if_fail (CHATTY_IS_MA_CHAT (self));
-- g_return_if_fail (MATRIX_IS_API (api));
-+ g_return_if_fail (CM_IS_CLIENT (client));
-
- g_set_weak_pointer (&self->account, account);
-- g_set_object (&self->matrix_api, api);
-- g_set_object (&self->matrix_enc, enc);
--
-- if (!self->state_is_sync && !self->state_is_syncing &&
-- self->matrix_api && self->matrix_enc) {
-- self->state_is_syncing = TRUE;
-- CHATTY_TRACE (self->room_id, "Getting encryption state for");
-- matrix_api_get_room_encryption_async (self->matrix_api,
-- self->room_id,
-- get_room_encryption_cb,
-- self);
-- }
-+ g_set_object (&self->cm_client, client);
- }
-
- gboolean
-@@ -1942,58 +1460,6 @@ chatty_ma_chat_matches_id (ChattyMaChat *self,
- return g_strcmp0 (self->room_id, room_id) == 0;
- }
-
--static void
--db_room_saved_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(ChattyMaChat) self = user_data;
--
-- g_assert (CHATTY_IS_MA_CHAT (self));
--
-- self->saving_room_to_db = FALSE;
--}
--
--void
--chatty_ma_chat_set_prev_batch (ChattyMaChat *self,
-- char *prev_batch)
--{
-- g_return_if_fail (CHATTY_IS_MA_CHAT (self));
--
-- g_clear_pointer (&self->prev_batch, g_free);
-- self->prev_batch = prev_batch;
--
-- if (self->saving_room_to_db)
-- return;
--
-- self->saving_room_to_db = TRUE;
-- matrix_db_save_room_async (self->matrix_db, self->account,
-- matrix_api_get_device_id (self->matrix_api),
-- self->room_id, prev_batch,
-- db_room_saved_cb, g_object_ref (self));
--}
--
--/**
-- * chatty_ma_chat_set_last_batch:
-- * @self: A #ChattyMaChat
-- * @last_batch: A string representing time
-- *
-- * The batch which we have already loaded chat
-- * up to. When history is loaded from server,
-- * only items after @last_batch shall be loaded.
-- * This limits only loading history from server
-- * not from database.
-- */
--void
--chatty_ma_chat_set_last_batch (ChattyMaChat *self,
-- const char *last_batch)
--{
-- g_return_if_fail (CHATTY_IS_MA_CHAT (self));
--
-- g_free (self->last_batch);
-- self->last_batch = g_strdup (last_batch);
--}
--
- void
- chatty_ma_chat_add_messages (ChattyMaChat *self,
- GPtrArray *messages)
-diff --git a/src/matrix/chatty-ma-chat.h b/src/matrix/chatty-ma-chat.h
-index 1f6e147b..f485b2b0 100644
---- a/src/matrix/chatty-ma-chat.h
-+++ b/src/matrix/chatty-ma-chat.h
-@@ -12,6 +12,8 @@
- #pragma once
-
- #include <glib-object.h>
-+#define CMATRIX_USE_EXPERIMENTAL_API
-+#include "cmatrix.h"
-
- #include "chatty-item.h"
- #include "chatty-account.h"
-@@ -29,20 +31,15 @@ ChattyMaChat *chatty_ma_chat_new (const char *room_id,
- const char *name,
- ChattyFileInfo *avatar,
- gboolean encrypted);
-+ChattyMaChat *chatty_ma_chat_new_with_room (CmRoom *room);
-+CmRoom *chatty_ma_chat_get_cm_room (ChattyMaChat *self);
- void chatty_ma_chat_set_history_db (ChattyMaChat *self,
- gpointer history_db);
--void chatty_ma_chat_set_matrix_db (ChattyMaChat *self,
-- gpointer matrix_db);
- void chatty_ma_chat_set_data (ChattyMaChat *self,
- ChattyAccount *account,
-- gpointer api,
-- gpointer enc);
-+ gpointer client);
- gboolean chatty_ma_chat_matches_id (ChattyMaChat *self,
- const char *room_id);
--void chatty_ma_chat_set_prev_batch (ChattyMaChat *self,
-- char *prev_batch);
--void chatty_ma_chat_set_last_batch (ChattyMaChat *self,
-- const char *last_batch);
- void chatty_ma_chat_add_messages (ChattyMaChat *self,
- GPtrArray *messages);
-
-diff --git a/src/matrix/chatty-matrix.c b/src/matrix/chatty-matrix.c
-index 25c25071..f492f153 100644
---- a/src/matrix/chatty-matrix.c
-+++ b/src/matrix/chatty-matrix.c
-@@ -16,13 +16,14 @@
- #endif
-
- #include "contrib/gtk.h"
-+#define CMATRIX_USE_EXPERIMENTAL_API
-+#include "cmatrix.h"
-
- #include "chatty-secret-store.h"
- #include "chatty-settings.h"
- #include "chatty-ma-account.h"
- #include "chatty-ma-buddy.h"
- #include "chatty-ma-chat.h"
--#include "matrix-db.h"
- #include "chatty-matrix.h"
- #include "chatty-log.h"
-
-@@ -36,7 +37,7 @@ struct _ChattyMatrix
- GtkFlattenListModel *chat_list;
-
- ChattyHistory *history;
-- MatrixDb *matrix_db;
-+ CmMatrix *cm_matrix;
-
- /* The timeout id for the callback on network changes */
- guint network_change_id;
-@@ -44,12 +45,22 @@ struct _ChattyMatrix
- gboolean has_loaded;
- gboolean disable_auto_login;
- gboolean network_available;
-+ gboolean enabled;
-+ gboolean is_ready;
- };
-
- G_DEFINE_TYPE (ChattyMatrix, chatty_matrix, G_TYPE_OBJECT)
-
- #define RECONNECT_TIMEOUT 1000 /* milliseconds */
-
-+enum {
-+ PROP_0,
-+ PROP_ENABLED,
-+ N_PROPS
-+};
-+
-+static GParamSpec *properties[N_PROPS];
-+
- static gboolean
- matrix_reconnect (gpointer user_data)
- {
-@@ -118,50 +129,66 @@ matrix_secret_load_cb (GObject *object,
- {
- ChattyMatrix *self = user_data;
- g_autoptr(GPtrArray) accounts = NULL;
-+ g_autoptr(GPtrArray) secrets = NULL;
- g_autoptr(GError) error = NULL;
-
- g_assert (CHATTY_IS_MATRIX (self));
-
-- accounts = chatty_secret_load_finish (result, &error);
-+ secrets = chatty_secret_load_finish (result, &error);
- g_info ("Loading accounts from secrets %s", CHATTY_LOG_SUCESS (!error));
-
- if (error)
- g_warning ("Error loading secret accounts: %s", error->message);
-
-+ for (guint i = 0; secrets && i < secrets->len; i++)
-+ {
-+ ChattyMaAccount *account;
-+
-+ if (!accounts)
-+ accounts = g_ptr_array_new_full (5, g_object_unref);
-+
-+ account = chatty_ma_account_new_secret (secrets->pdata[i], self->cm_matrix);
-+
-+ if (account)
-+ g_ptr_array_insert (accounts, -1, account);
-+ }
-+
- if (!accounts)
- return;
-
- g_info ("Loaded %d matrix accounts", accounts ? accounts->len : 0);
-
-- for (guint i = 0; i < accounts->len; i++) {
-+ for (guint i = 0; accounts && i < accounts->len; i++) {
- g_signal_connect_object (accounts->pdata[i], "notify::status",
- G_CALLBACK (matrix_ma_account_changed_cb),
- self, G_CONNECT_SWAPPED);
-+ chatty_ma_account_set_db (accounts->pdata[i], self->history);
-
-- chatty_ma_account_set_db (accounts->pdata[i], self->matrix_db, self->history);
- g_list_store_append (self->list_of_chat_list,
- chatty_ma_account_get_chat_list (accounts->pdata[i]));
- }
-
- g_list_store_splice (self->account_list, 0, 0, accounts->pdata, accounts->len);
-+
- }
-
- static void
--matrix_db_open_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
-+chatty_matrix_get_property (GObject *object,
-+ guint prop_id,
-+ GValue *value,
-+ GParamSpec *pspec)
- {
-- ChattyMatrix *self = user_data;
-- g_autoptr(GError) error = NULL;
--
-- g_assert (CHATTY_IS_MATRIX (self));
-+ ChattyMatrix *self = (ChattyMatrix *)object;
-
-- if (matrix_db_open_finish (self->matrix_db, result, &error))
-- chatty_secret_load_async (NULL, matrix_secret_load_cb, self);
-- else if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- g_warning ("Failed to open Matrix DB: %s", error->message);
-+ switch (prop_id)
-+ {
-+ case PROP_ENABLED:
-+ g_value_set_boolean (value, chatty_matrix_is_enabled (self));
-+ break;
-
-- g_info ("Opening matrix db %s", CHATTY_LOG_SUCESS (!error));
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ }
- }
-
- static void
-@@ -179,7 +206,6 @@ chatty_matrix_finalize (GObject *object)
- g_clear_object (&self->chat_list);
-
- g_clear_object (&self->history);
-- g_clear_object (&self->matrix_db);
-
- G_OBJECT_CLASS (chatty_matrix_parent_class)->finalize (object);
- }
-@@ -190,6 +216,21 @@ chatty_matrix_class_init (ChattyMatrixClass *klass)
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = chatty_matrix_finalize;
-+ object_class->get_property = chatty_matrix_get_property;
-+
-+ /**
-+ * ChattyMatrix:enabled:
-+ *
-+ * Whether matrix is enabled and usable
-+ */
-+ properties[PROP_ENABLED] =
-+ g_param_spec_boolean ("enabled",
-+ "matrix enabled",
-+ "matrix enabled",
-+ FALSE,
-+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-+
-+ g_object_class_install_properties (object_class, N_PROPS, properties);
- }
-
- static void
-@@ -211,6 +252,7 @@ chatty_matrix_init (ChattyMatrix *self)
- G_CALLBACK (matrix_network_changed_cb), self,
- G_CONNECT_AFTER | G_CONNECT_SWAPPED);
-
-+ self->enabled = chatty_settings_get_experimental_features (chatty_settings_get_default ());
- }
-
- ChattyMatrix *
-@@ -228,24 +270,55 @@ chatty_matrix_new (ChattyHistory *history,
- return self;
- }
-
-+gboolean
-+chatty_matrix_is_enabled (ChattyMatrix *self)
-+{
-+ g_return_val_if_fail (CHATTY_IS_MATRIX (self), FALSE);
-+
-+ return self->enabled && self->is_ready;
-+}
-+
-+static void
-+matrix_open_cb (GObject *obj,
-+ GAsyncResult *result,
-+ gpointer user_data)
-+{
-+ g_autoptr(ChattyMatrix) self = user_data;
-+ g_autoptr(GError) error = NULL;
-+
-+ g_assert (CHATTY_IS_MATRIX (self));
-+
-+ cm_matrix_open_finish (self->cm_matrix, result, &error);
-+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ENABLED]);
-+
-+ if (error) {
-+ g_warning ("Error plugging in to the matrix: %s", error->message);
-+ return;
-+ }
-+
-+ chatty_secret_load_async (NULL, matrix_secret_load_cb, self);
-+}
-+
- void
- chatty_matrix_load (ChattyMatrix *self)
- {
-- char *db_path;
-+ g_autofree char *db_path = NULL;
-+ g_autofree char *data_path = NULL;
-+ g_autofree char *cache_path = NULL;
-
-- if (self->has_loaded)
-+ if (self->cm_matrix)
- return;
-
-- self->has_loaded = TRUE;
--
- if (!chatty_settings_get_experimental_features (chatty_settings_get_default ()))
- return;
-
-- self->matrix_db = matrix_db_new ();
-- db_path = g_build_filename (chatty_utils_get_purple_dir (), "chatty", "db", NULL);
-- matrix_db_open_async (self->matrix_db, db_path, "matrix.db",
-- matrix_db_open_cb, self);
-- g_info ("Opening matrix db");
-+ data_path = g_build_filename (g_get_user_data_dir (), "chatty", "matrix", NULL);
-+ cache_path = g_build_filename (g_get_user_cache_dir (), "chatty", "matrix", NULL);
-+ self->cm_matrix = g_object_new (CM_TYPE_MATRIX, NULL);
-+
-+ db_path = g_build_filename (chatty_utils_get_purple_dir (), "chatty", "db", NULL);
-+ cm_matrix_open_async (self->cm_matrix, db_path, "matrix.db", NULL,
-+ matrix_open_cb, g_object_ref (self));
- }
-
- GListModel *
-@@ -265,34 +338,6 @@ chatty_matrix_get_chat_list (ChattyMatrix *self)
-
- }
-
--static void
--matrix_db_account_delete_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- ChattyMaAccount *account;
-- GError *error = NULL;
-- const char *username;
-- gboolean status;
--
-- g_assert (G_IS_TASK (task));
--
-- status = matrix_db_delete_account_finish (MATRIX_DB (object),
-- result, &error);
--
-- account = g_task_get_task_data (task);
-- username = chatty_item_get_username (CHATTY_ITEM (account));
-- if (!username || !*username)
-- username = chatty_ma_account_get_login_username (account);
-- CHATTY_DEBUG_DETAILED (username, "Deleting %s, account:", CHATTY_LOG_SUCESS (!error));
--
-- if (error)
-- g_task_return_error (task, error);
-- else
-- g_task_return_boolean (task, status);
--}
--
- static void
- matrix_account_delete_cb (GObject *object,
- GAsyncResult *result,
-@@ -322,9 +367,7 @@ matrix_account_delete_cb (GObject *object,
- if (error)
- g_task_return_error (task, error);
- else
-- matrix_db_delete_account_async (self->matrix_db, CHATTY_ACCOUNT (account),
-- matrix_db_account_delete_cb,
-- g_steal_pointer (&task));
-+ chatty_account_delete (CHATTY_ACCOUNT (account));
- }
-
- void
-@@ -397,6 +440,8 @@ matrix_save_account_cb (GObject *object,
-
- if (saved) {
- g_list_store_append (self->account_list, account);
-+ g_list_store_append (self->list_of_chat_list,
-+ chatty_ma_account_get_chat_list (account));
-
- g_signal_connect_object (account, "notify::status",
- G_CALLBACK (matrix_ma_account_changed_cb),
-@@ -424,7 +469,8 @@ chatty_matrix_save_account_async (ChattyMatrix *self,
- CHATTY_DEBUG (chatty_item_get_username (CHATTY_ITEM (account)), "Saving account");
-
- task = g_task_new (self, cancellable, callback, user_data);
-- chatty_ma_account_set_db (CHATTY_MA_ACCOUNT (account), self->matrix_db, self->history);
-+ chatty_ma_account_set_matrix (CHATTY_MA_ACCOUNT (account), self->cm_matrix);
-+ chatty_ma_account_set_db (CHATTY_MA_ACCOUNT (account), self->history);
- chatty_ma_account_save_async (CHATTY_MA_ACCOUNT (account), TRUE, NULL,
- matrix_save_account_cb, task);
- }
-@@ -510,3 +556,11 @@ chatty_matrix_find_chat_with_name (ChattyMatrix *self,
-
- return NULL;
- }
-+
-+CmClient *
-+chatty_matrix_client_new (ChattyMatrix *self)
-+{
-+ g_return_val_if_fail (CHATTY_IS_MATRIX (self), NULL);
-+
-+ return cm_matrix_client_new (self->cm_matrix);
-+}
-diff --git a/src/matrix/chatty-matrix.h b/src/matrix/chatty-matrix.h
-index 3cbe9acc..db3ea494 100644
---- a/src/matrix/chatty-matrix.h
-+++ b/src/matrix/chatty-matrix.h
-@@ -12,6 +12,8 @@
- #pragma once
-
- #include <glib-object.h>
-+#define CMATRIX_USE_EXPERIMENTAL_API
-+#include "cmatrix.h"
-
- #include "chatty-history.h"
-
-@@ -21,9 +23,10 @@ G_BEGIN_DECLS
-
- G_DECLARE_FINAL_TYPE (ChattyMatrix, chatty_matrix, CHATTY, MATRIX, GObject)
-
--ChattyMatrix *chatty_matrix_new (ChattyHistory *history,
-+ChattyMatrix *chatty_matrix_new (ChattyHistory *history,
- gboolean disable_auto_login);
--void chatty_matrix_load (ChattyMatrix *self);
-+gboolean chatty_matrix_is_enabled (ChattyMatrix *self);
-+void chatty_matrix_load (ChattyMatrix *self);
- GListModel *chatty_matrix_get_account_list (ChattyMatrix *self);
- GListModel *chatty_matrix_get_chat_list (ChattyMatrix *self);
- void chatty_matrix_delete_account_async (ChattyMatrix *self,
-@@ -48,5 +51,6 @@ ChattyChat *chatty_matrix_find_chat_with_name (ChattyMatrix *self,
- ChattyProtocol protocol,
- const char *account_id,
- const char *chat_id);
-+CmClient *chatty_matrix_client_new (ChattyMatrix *self);
-
- G_END_DECLS
-diff --git a/src/matrix/matrix-api.c b/src/matrix/matrix-api.c
-deleted file mode 100644
-index 2a37adab..00000000
---- a/src/matrix/matrix-api.c
-+++ /dev/null
-@@ -1,2561 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-api.c
-- *
-- * Copyright 2020 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--#define G_LOG_DOMAIN "chatty-matrix-api"
--
--#ifdef HAVE_CONFIG_H
--# include "config.h"
--#endif
--
--#include <libsoup/soup.h>
--#include <json-glib/json-glib.h>
--#include <olm/olm.h>
--#include <sys/random.h>
--
--#include "chatty-chat.h"
--#include "chatty-ma-buddy.h"
--#include "matrix-enums.h"
--#include "matrix-utils.h"
--#include "matrix-api.h"
--#include "matrix-net.h"
--#include "chatty-log.h"
--
--/**
-- * SECTION: chatty-api
-- * @title: MatrixApi
-- * @short_description: The Matrix HTTP API.
-- * @include: "chatty-api.h"
-- *
-- * This class handles all communications with Matrix server
-- * user REST APIs.
-- */
--
--#define URI_REQUEST_TIMEOUT 60 /* seconds */
--#define SYNC_TIMEOUT 30000 /* milliseconds */
--#define TYPING_TIMEOUT 10000 /* milliseconds */
--#define KEY_TIMEOUT 10000 /* milliseconds */
--
--struct _MatrixApi
--{
-- GObject parent_instance;
--
-- /* The username used to log in. This can be different from
-- * the @username as this can be an email, phone number, etc. */
-- char *login_username;
-- char *username;
-- char *password;
-- char *homeserver;
-- char *device_id;
-- char *access_token;
-- char *key;
--
-- MatrixEnc *matrix_enc;
-- MatrixNet *matrix_net;
-- GSocketAddress *gaddress;
--
-- /* Executed for every request response */
-- MatrixCallback callback;
-- gpointer cb_object;
-- GCancellable *cancellable;
-- char *next_batch;
-- char *filter_id;
-- MatrixAction action;
--
-- /* for sending events, incremented for each event */
-- int event_id;
--
-- guint full_state_loaded : 1;
-- guint is_sync : 1;
-- /* Set when error occurs with sync enabled */
-- guint sync_failed : 1;
-- guint homeserver_verified : 1;
-- guint login_success : 1;
-- guint room_list_loaded : 1;
-- /* Set when @self has tried connecting the network atleast once */
-- guint has_tried_connecting : 1;
--
-- guint resync_id;
--};
--
--G_DEFINE_TYPE (MatrixApi, matrix_api, G_TYPE_OBJECT)
--
--static void matrix_verify_homeserver (MatrixApi *self);
--static void matrix_login (MatrixApi *self);
--static void matrix_upload_key (MatrixApi *self);
--static void matrix_start_sync (MatrixApi *self);
--static void matrix_take_red_pill (MatrixApi *self);
--static gboolean handle_common_errors (MatrixApi *self,
-- GError *error);
--
--static void
--api_set_string_value (char **strp,
-- const char *value)
--{
-- g_assert (strp);
--
-- if (value) {
-- g_free (*strp);
-- *strp = g_strdup (value);
-- }
--}
--
--static void
--api_verify_homeserver_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixApi *self = user_data;
-- g_autoptr(GError) error = NULL;
-- gboolean success;
--
-- g_assert (MATRIX_IS_API (self));
--
-- success = matrix_utils_verify_homeserver_finish (result, &error);
--
-- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- return;
--
-- if (!self->gaddress)
-- self->gaddress = g_object_steal_data (G_OBJECT (result), "address");
-- self->has_tried_connecting = TRUE;
--
-- /* Since GTask can't have timeout, We cancel the cancellable to fake timeout */
-- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT)) {
-- g_clear_object (&self->cancellable);
-- self->cancellable = g_cancellable_new ();
-- }
--
-- if (handle_common_errors (self, error))
-- return;
--
-- if (error) {
-- CHATTY_TRACE_MSG ("Error verifying home server: %s", error->message);
-- self->callback (self->cb_object, self, MATRIX_VERIFY_HOMESERVER, NULL, error);
-- return;
-- }
--
-- if (success) {
-- self->homeserver_verified = TRUE;
-- matrix_start_sync (self);
-- } else {
-- error = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to verify homeserver");
-- self->callback (self->cb_object, self, self->action, NULL, error);
-- }
--}
--
--static void
--api_get_homeserver_cb (gpointer object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixApi *self = user_data;
-- g_autoptr(GError) error = NULL;
-- char *homeserver;
--
-- g_assert (MATRIX_IS_API (self));
--
-- homeserver = matrix_utils_get_homeserver_finish (result, &error);
--
-- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- return;
--
-- CHATTY_TRACE_MSG ("Get home server, has-error: %d, home server: %s",
-- !error, homeserver);
--
-- if (!self->gaddress)
-- self->gaddress = g_object_steal_data (G_OBJECT (result), "address");
-- self->has_tried_connecting = TRUE;
--
-- if (!homeserver) {
-- self->sync_failed = TRUE;
-- self->callback (self->cb_object, self, self->action, NULL, error);
--
-- return;
-- }
--
-- matrix_api_set_homeserver (self, homeserver);
-- matrix_verify_homeserver (self);
--}
--
--static void
--api_send_message_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- g_autoptr(JsonObject) object = NULL;
-- ChattyMessage *message;
-- GError *error = NULL;
-- char *event_id;
-- int retry_after;
--
-- g_assert (G_IS_TASK (task));
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
-- retry_after = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (result), "retry-after"));
-- g_object_set_data (G_OBJECT (task), "retry-after", GINT_TO_POINTER (retry_after));
--
-- message = g_object_get_data (G_OBJECT (task), "message");
-- event_id = g_object_get_data (G_OBJECT (task), "event-id");
--
-- g_debug ("Sending message %s. event-id: %s, retry-after: %d",
-- CHATTY_LOG_SUCESS (!error), event_id, retry_after);
--
-- if (error) {
-- g_debug ("Error sending message: %s", error->message);
-- chatty_message_set_status (message, CHATTY_STATUS_SENDING_FAILED, 0);
-- g_task_return_error (task, error);
-- } else {
-- chatty_message_set_status (message, CHATTY_STATUS_SENT, 0);
-- g_task_return_boolean (task, !!object);
-- }
--}
--
--static void
--api_get_file_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixApi *self;
-- g_autoptr(GTask) task = user_data;
-- GError *error = NULL;
-- gboolean status;
--
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (MATRIX_IS_API (self));
--
-- status = matrix_net_get_file_finish (self->matrix_net, result, &error);
--
-- if (error) {
-- g_task_return_error (task, error);
--
-- return;
-- }
--
-- g_task_return_boolean (task, status);
--}
--
--static void
--matrix_send_typing_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(JsonObject) object = NULL;
-- g_autoptr(GError) error = NULL;
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (error)
-- g_warning ("Error set typing: %s", error->message);
--}
--
--
--static void
--api_set_read_marker_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- g_autoptr(JsonObject) object = NULL;
-- GError *error = NULL;
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- CHATTY_TRACE_MSG ("Mark as read. success: %d", !error);
--
-- if (error) {
-- g_debug ("Error setting read marker: %s", error->message);
-- g_task_return_error (task, error);
-- } else {
-- g_task_return_boolean (task, TRUE);
-- }
--}
--
--static void
--api_upload_group_keys_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- g_autoptr(JsonObject) object = NULL;
-- GError *error = NULL;
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (error) {
-- g_debug ("Error uploading group keys: %s", error->message);
-- g_task_return_error (task, error);
-- } else {
-- g_task_return_boolean (task, TRUE);
-- }
--}
--
--static void
--matrix_get_room_state_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- JsonArray *array;
-- GError *error = NULL;
--
-- g_assert (G_IS_TASK (task));
--
-- array = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (error) {
-- g_debug ("Error getting room state: %s", error->message);
-- g_task_return_error (task, error);
-- } else {
-- g_task_return_pointer (task, array, (GDestroyNotify)json_array_unref);
-- }
--}
--
--static void
--matrix_get_room_name_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- JsonObject *object = NULL;
-- GError *error = NULL;
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (error) {
-- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- CHATTY_TRACE_MSG ("Error getting room name: %s", error->message);
--
-- g_task_return_error (task, error);
-- } else {
-- g_task_return_pointer (task, object, (GDestroyNotify)json_object_unref);
-- }
--}
--
--static void
--matrix_get_room_encryption_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- g_autoptr(JsonObject) object = NULL;
-- const char *encryption;
-- GError *error = NULL;
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (error &&
-- !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
-- !g_error_matches (error, MATRIX_ERROR, M_NOT_FOUND))
-- g_warning ("Error loading encryption state: %s", error->message);
--
-- encryption = matrix_utils_json_object_get_string (object, "algorithm");
-- g_task_return_pointer (task, g_strdup (encryption), g_free);
--}
--
--static void
--matrix_set_room_encryption_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- g_autoptr(JsonObject) object = NULL;
-- const char *event;
-- GError *error = NULL;
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (error &&
-- !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) &&
-- !g_error_matches (error, MATRIX_ERROR, M_NOT_FOUND))
-- g_warning ("Error setting encryption: %s", error->message);
--
-- event = matrix_utils_json_object_get_string (object, "event_id");
-- g_task_return_boolean (task, !!event);
--}
--
--static void
--matrix_get_members_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- JsonObject *object = NULL;
-- GError *error = NULL;
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (error) {
-- g_debug ("Error getting members: %s", error->message);
-- g_task_return_error (task, error);
-- } else {
-- g_task_return_pointer (task, object, (GDestroyNotify)json_object_unref);
-- }
--}
--
--static void
--matrix_get_messages_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- JsonObject *object = NULL;
-- GError *error = NULL;
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (error) {
-- g_warning ("Error getting members: %s", error->message);
-- g_task_return_error (task, error);
-- } else {
-- g_task_return_pointer (task, object, (GDestroyNotify)json_object_unref);
-- }
--}
--
--static void
--matrix_keys_query_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- JsonObject *object = NULL;
-- GError *error = NULL;
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- CHATTY_TRACE_MSG ("Query key complete. success: %d", !error);
--
-- if (error) {
-- g_debug ("Error key query: %s", error->message);
-- g_task_return_error (task, error);
-- } else {
-- g_task_return_pointer (task, object, (GDestroyNotify)json_object_unref);
-- }
--}
--
--static void
--matrix_keys_claim_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- JsonObject *object = NULL;
-- GError *error = NULL;
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (error) {
-- g_debug ("Error key query: %s", error->message);
-- g_task_return_error (task, error);
-- } else {
-- g_task_return_pointer (task, object, (GDestroyNotify)json_object_unref);
-- }
--}
--
--static gboolean
--schedule_resync (gpointer user_data)
--{
-- MatrixApi *self = user_data;
-- gboolean sync_now;
--
-- g_assert (MATRIX_IS_API (self));
-- self->resync_id = 0;
--
-- sync_now = matrix_api_can_connect (self);
-- CHATTY_TRACE (self->username, "Schedule sync. sync now: %d, user: ", sync_now);
--
-- if (sync_now)
-- matrix_start_sync (self);
--
-- return G_SOURCE_REMOVE;
--}
--
--/*
-- * Handle Self fixable errors.
-- *
-- * Returns: %TRUE if @error was handled.
-- * %FALSE otherwise
-- */
--static gboolean
--handle_common_errors (MatrixApi *self,
-- GError *error)
--{
-- if (!error)
-- return FALSE;
--
-- CHATTY_TRACE_MSG ("Error: %s", error->message);
--
-- if (g_error_matches (error, MATRIX_ERROR, M_UNKNOWN_TOKEN)
-- && self->password) {
-- CHATTY_TRACE (self->username ? self->username : self->login_username, "Re-logging in ");
-- self->login_success = FALSE;
-- self->room_list_loaded = FALSE;
-- g_clear_pointer (&self->access_token, matrix_utils_free_buffer);
-- matrix_enc_set_details (self->matrix_enc, NULL, NULL);
-- self->callback (self->cb_object, self, MATRIX_ACCESS_TOKEN_LOGIN, NULL, NULL);
-- matrix_start_sync (self);
--
-- return TRUE;
-- }
--
-- /*
-- * The G_RESOLVER_ERROR may be suggesting that the hostname is wrong, but we don't
-- * know if it's network/DNS/Proxy error. So keep retrying.
-- */
-- if ((error->domain == SOUP_HTTP_ERROR &&
-- error->code <= SOUP_STATUS_TLS_FAILED &&
-- error->code > SOUP_STATUS_CANCELLED) ||
-- g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE) ||
-- g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) ||
-- error->domain == G_RESOLVER_ERROR ||
-- error->domain == JSON_PARSER_ERROR) {
--
-- if (matrix_api_can_connect (self)) {
-- g_clear_handle_id (&self->resync_id, g_source_remove);
--
-- self->sync_failed = TRUE;
-- self->callback (self->cb_object, self, MATRIX_RED_PILL, NULL, NULL);
-- CHATTY_TRACE (self->username, "Schedule sync for user ");
-- self->resync_id = g_timeout_add_seconds (URI_REQUEST_TIMEOUT,
-- schedule_resync, self);
-- return TRUE;
-- }
-- }
--
-- return FALSE;
--}
--
--static gboolean
--handle_one_time_keys (MatrixApi *self,
-- JsonObject *object)
--{
-- size_t count, limit;
--
-- g_assert (MATRIX_IS_API (self));
--
-- if (!object)
-- return FALSE;
--
-- count = matrix_utils_json_object_get_int (object, "signed_curve25519");
-- limit = matrix_enc_max_one_time_keys (self->matrix_enc) / 2;
--
-- /* If we don't have enough onetime keys add some */
-- if (count < limit) {
-- CHATTY_TRACE_MSG ("generating %" G_GSIZE_FORMAT " onetime keys", limit - count);
-- matrix_enc_create_one_time_keys (self->matrix_enc, limit - count);
--
-- if (!self->key)
-- self->key = matrix_enc_get_one_time_keys_json (self->matrix_enc);
-- matrix_upload_key (self);
--
-- return TRUE;
-- }
--
-- return FALSE;
--}
--
--static void
--api_upload_filter_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(MatrixApi) self = user_data;
-- g_autoptr(JsonObject) root = NULL;
-- g_autoptr(GError) error = NULL;
--
-- g_assert (MATRIX_IS_API (self));
-- g_assert (G_IS_TASK (result));
--
-- root = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- return;
--
-- CHATTY_DEBUG (self->username, "Uploading filter %s, user",
-- CHATTY_LOG_SUCESS (!error));
--
-- if (handle_common_errors (self, error))
-- return;
--
-- self->filter_id = g_strdup (matrix_utils_json_object_get_string (root, "filter_id"));
--
-- if (!self->filter_id)
-- self->filter_id = g_strdup ("");
-- matrix_start_sync (self);
--}
--
--static void
--matrix_upload_filter (MatrixApi *self)
--{
-- g_autoptr(GError) error = NULL;
-- g_autoptr(GBytes) data = NULL;
-- const char *data_str = NULL;
-- gsize size;
--
-- data = g_resources_lookup_data ("/sm/puri/Chatty/matrix-filter.json", 0, &error);
--
-- if (error)
-- g_warning ("Error getting filter file: %s", error->message);
-- else if (data)
-- data_str = g_bytes_get_data (data, &size);
--
-- if (!data || !data_str || !size) {
-- self->filter_id = g_strdup ("");
-- matrix_start_sync (self);
-- } else {
-- g_autofree char *uri = NULL;
-- g_autoptr(JsonParser) parser = NULL;
-- JsonObject *filter = NULL;
-- JsonNode *root = NULL;
--
-- CHATTY_DEBUG (self->username, "Uploading filter, user:");
--
-- parser = json_parser_new ();
-- json_parser_load_from_data (parser, data_str, size, &error);
--
-- if (error)
-- g_warning ("Error parsing filter file: %s", error->message);
--
-- if (!error)
-- root = json_parser_get_root (parser);
--
-- if (root)
-- filter = json_node_get_object (root);
--
-- if (error || !root || !filter) {
-- if (error)
-- g_warning ("Error getting filter file: %s", error->message);
--
-- self->filter_id = g_strdup ("");
-- matrix_start_sync (self);
--
-- return;
-- }
--
-- uri = g_strconcat ("/_matrix/client/r0/user/", self->username, "/filter", NULL);
-- matrix_net_send_json_async (self->matrix_net, 2, json_object_ref (filter),
-- uri, SOUP_METHOD_POST,
-- NULL, self->cancellable, api_upload_filter_cb,
-- g_object_ref (self));
-- }
--}
--
--static void
--matrix_login_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(MatrixApi) self = user_data;
-- g_autoptr(JsonObject) root = NULL;
-- g_autoptr(GError) error = NULL;
-- JsonObject *object = NULL;
-- const char *value;
--
-- g_assert (MATRIX_IS_API (self));
-- g_assert (G_IS_TASK (result));
--
-- root = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- return;
--
-- CHATTY_TRACE_MSG ("login %s", CHATTY_LOG_SUCESS (!error));
--
-- if (error) {
-- self->sync_failed = TRUE;
-- /* use a better code to inform invalid password */
-- if (error->code == M_FORBIDDEN)
-- error->code = M_BAD_PASSWORD;
-- self->callback (self->cb_object, self, MATRIX_PASSWORD_LOGIN, NULL, error);
-- g_debug ("Error logging in: %s", error->message);
-- return;
-- }
--
-- self->login_success = TRUE;
--
-- /* https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-l... */
-- value = matrix_utils_json_object_get_string (root, "user_id");
-- api_set_string_value (&self->username, value);
--
-- value = matrix_utils_json_object_get_string (root, "access_token");
-- matrix_utils_free_buffer (self->access_token);
-- self->access_token = g_strdup (value);
-- matrix_net_set_access_token (self->matrix_net, self->access_token);
--
-- value = matrix_utils_json_object_get_string (root, "device_id");
-- api_set_string_value (&self->device_id, value);
--
-- object = matrix_utils_json_object_get_object (root, "well_known");
-- object = matrix_utils_json_object_get_object (object, "m.homeserver");
-- value = matrix_utils_json_object_get_string (object, "base_url");
-- matrix_api_set_homeserver (self, value);
--
-- matrix_enc_set_details (self->matrix_enc, self->username, self->device_id);
-- g_free (self->key);
-- self->key = matrix_enc_get_device_keys_json (self->matrix_enc);
--
-- self->callback (self->cb_object, self, MATRIX_PASSWORD_LOGIN, NULL, NULL);
-- matrix_start_sync (self);
--}
--
--static void
--matrix_upload_key_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(MatrixApi) self = user_data;
-- g_autoptr(JsonObject) root = NULL;
-- g_autoptr(GError) error = NULL;
-- JsonObject *object = NULL;
--
-- g_assert (MATRIX_IS_API (self));
-- g_assert (G_IS_TASK (result));
--
-- root = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (error) {
-- self->sync_failed = TRUE;
-- self->callback (self->cb_object, self, MATRIX_UPLOAD_KEY, NULL, error);
-- g_debug ("Error uploading key: %s", error->message);
-- return;
-- }
--
-- self->callback (self->cb_object, self, MATRIX_UPLOAD_KEY, root, NULL);
--
-- object = matrix_utils_json_object_get_object (root, "one_time_key_counts");
-- CHATTY_TRACE_MSG ("Uploaded %ld keys",
-- matrix_utils_json_object_get_int (object, "signed_curve25519"));
--
-- if (!handle_one_time_keys (self, object) &&
-- self->action != MATRIX_RED_PILL)
-- matrix_take_red_pill (self);
--}
--
--/* sync callback */
--static void
--matrix_take_red_pill_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(MatrixApi) self = user_data;
-- g_autoptr(JsonObject) root = NULL;
-- g_autoptr(GError) error = NULL;
-- JsonObject *object = NULL;
--
-- g_assert (MATRIX_IS_API (self));
-- g_assert (G_IS_TASK (result));
--
-- root = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- return;
--
-- if (!self->next_batch || error || !self->full_state_loaded)
-- g_log (G_LOG_DOMAIN, CHATTY_LOG_LEVEL_TRACE, "sync %s, full-state: %d, next-batch: %s",
-- CHATTY_LOG_SUCESS (!error), !self->full_state_loaded, self->next_batch);
--
-- if (handle_common_errors (self, error))
-- return;
--
-- if (error) {
-- self->sync_failed = TRUE;
-- self->callback (self->cb_object, self, self->action, NULL, error);
-- g_debug ("Error syncing with time %s: %s", self->next_batch, error->message);
-- return;
-- }
--
-- self->login_success = TRUE;
--
-- object = matrix_utils_json_object_get_object (root, "device_one_time_keys_count");
-- handle_one_time_keys (self, object);
--
-- /* XXX: For some reason full state isn't loaded unless we have passed “next_batch”.
-- * So, if we haven’t, don’t mark so.
-- */
-- if (self->next_batch)
-- self->full_state_loaded = TRUE;
--
-- g_free (self->next_batch);
-- self->next_batch = g_strdup (matrix_utils_json_object_get_string (root, "next_batch"));
--
-- self->callback (self->cb_object, self, self->action, root, NULL);
--
-- /* Repeat */
-- matrix_take_red_pill (self);
--}
--
--static void
--matrix_verify_homeserver (MatrixApi *self)
--{
-- g_assert (MATRIX_IS_API (self));
-- g_log (G_LOG_DOMAIN, CHATTY_LOG_LEVEL_TRACE,
-- "verifying homeserver %s", self->homeserver);
--
-- self->action = MATRIX_VERIFY_HOMESERVER;
-- matrix_utils_verify_homeserver_async (self->homeserver, URI_REQUEST_TIMEOUT,
-- self->cancellable,
-- api_verify_homeserver_cb, self);
--}
--
--static void
--matrix_login (MatrixApi *self)
--{
-- JsonObject *object, *child;
--
-- g_assert (MATRIX_IS_API (self));
-- g_assert (self->login_username);
-- g_assert (self->homeserver);
-- g_assert (!self->access_token);
-- g_assert (self->password && *self->password);
--
-- CHATTY_TRACE (self->login_username, "logging on server %s, account", self->homeserver);
--
-- /* https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-l... */
-- object = json_object_new ();
-- json_object_set_string_member (object, "type", "m.login.password");
-- json_object_set_string_member (object, "password", self->password);
-- json_object_set_string_member (object, "initial_device_display_name", "Chatty");
--
-- child = json_object_new ();
--
-- if (chatty_utils_username_is_valid (self->login_username, CHATTY_PROTOCOL_EMAIL)) {
-- json_object_set_string_member (child, "type", "m.id.thirdparty");
-- json_object_set_string_member (child, "medium", "email");
-- json_object_set_string_member (child, "address", self->login_username);
-- } else {
-- json_object_set_string_member (child, "type", "m.id.user");
-- json_object_set_string_member (child, "user", self->login_username);
-- }
--
-- json_object_set_object_member (object, "identifier", child);
--
-- matrix_net_send_json_async (self->matrix_net, 2, object,
-- "/_matrix/client/r0/login", SOUP_METHOD_POST,
-- NULL, self->cancellable, matrix_login_cb,
-- g_object_ref (self));
--}
--
--static void
--matrix_upload_key (MatrixApi *self)
--{
-- char *key;
--
-- g_assert (MATRIX_IS_API (self));
-- g_assert (self->key);
--
-- key = g_steal_pointer (&self->key);
--
-- matrix_net_send_data_async (self->matrix_net, 2, key, strlen (key),
-- "/_matrix/client/r0/keys/upload", SOUP_METHOD_POST,
-- NULL, self->cancellable, matrix_upload_key_cb,
-- g_object_ref (self));
--}
--
--static void
--get_joined_rooms_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(MatrixApi) self = user_data;
-- g_autoptr(JsonObject) root = NULL;
-- g_autoptr(GError) error = NULL;
--
-- g_assert (MATRIX_IS_API (self));
-- g_assert (G_IS_TASK (result));
--
-- root = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- return;
--
-- CHATTY_TRACE_MSG ("Getting joined rooms %s", CHATTY_LOG_SUCESS (!error));
--
-- if (handle_common_errors (self, error))
-- return;
--
-- self->callback (self->cb_object, self, MATRIX_GET_JOINED_ROOMS, root, error);
--
-- if (!error) {
-- self->room_list_loaded = TRUE;
-- matrix_start_sync (self);
-- }
--}
--
--static void
--matrix_get_joined_rooms (MatrixApi *self)
--{
-- g_assert (MATRIX_IS_API (self));
-- g_assert (!self->room_list_loaded);
--
-- CHATTY_TRACE_MSG ("Getting joined rooms");
-- matrix_net_send_json_async (self->matrix_net, 0, NULL,
-- "/_matrix/client/r0/joined_rooms", SOUP_METHOD_GET,
-- NULL, self->cancellable, get_joined_rooms_cb,
-- g_object_ref (self));
--}
--
--static void
--matrix_start_sync (MatrixApi *self)
--{
-- g_assert (MATRIX_IS_API (self));
--
-- self->is_sync = TRUE;
-- self->sync_failed = FALSE;
-- g_clear_handle_id (&self->resync_id, g_source_remove);
--
-- if (!self->homeserver) {
-- self->action = MATRIX_GET_HOMESERVER;
-- if (!matrix_utils_username_is_complete (self->login_username)) {
-- g_autoptr(GError) error = NULL;
--
-- g_debug ("Error: No Homeserver provided");
-- self->sync_failed = TRUE;
-- error = g_error_new (MATRIX_ERROR, M_NO_HOME_SERVER, "No Homeserver provided");
-- self->callback (self->cb_object, self, self->action, NULL, error);
-- } else {
-- g_debug ("Fetching home server details from username");
-- matrix_utils_get_homeserver_async (self->login_username, URI_REQUEST_TIMEOUT, self->cancellable,
-- (GAsyncReadyCallback)api_get_homeserver_cb,
-- self);
-- }
-- } else if (!self->homeserver_verified) {
-- matrix_verify_homeserver (self);
-- } else if (!self->password){
-- g_autoptr(GError) error = NULL;
--
-- error = g_error_new (MATRIX_ERROR, M_BAD_PASSWORD, "Empty password");
-- self->callback (self->cb_object, self, MATRIX_PASSWORD_LOGIN, NULL, error);
-- } else if (!self->access_token) {
-- matrix_login (self);
-- } else if (!self->filter_id){
-- matrix_upload_filter (self);
-- } else if (!self->room_list_loaded) {
-- matrix_get_joined_rooms (self);
-- } else {
-- matrix_take_red_pill (self);
-- }
--}
--
--static void
--matrix_take_red_pill (MatrixApi *self)
--{
-- GHashTable *query;
--
-- g_assert (MATRIX_IS_API (self));
--
-- self->action = MATRIX_RED_PILL;
-- query = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
--
-- if (self->login_success)
-- g_hash_table_insert (query, g_strdup ("timeout"), g_strdup_printf ("%u", SYNC_TIMEOUT));
-- else
-- g_hash_table_insert (query, g_strdup ("timeout"), g_strdup_printf ("%u", SYNC_TIMEOUT / 1000));
--
-- if (self->next_batch)
-- g_hash_table_insert (query, g_strdup ("since"), g_strdup (self->next_batch));
-- if (!self->full_state_loaded)
-- g_hash_table_insert (query, g_strdup ("full_state"), g_strdup ("true"));
--
-- matrix_net_send_json_async (self->matrix_net, 2, NULL,
-- "/_matrix/client/r0/sync", SOUP_METHOD_GET,
-- query, self->cancellable, matrix_take_red_pill_cb,
-- g_object_ref (self));
--}
--
--static void
--matrix_api_finalize (GObject *object)
--{
-- MatrixApi *self = (MatrixApi *)object;
--
-- if (self->cancellable)
-- g_cancellable_cancel (self->cancellable);
-- g_clear_object (&self->cancellable);
--
-- g_clear_object (&self->matrix_enc);
-- g_clear_object (&self->matrix_net);
-- g_clear_object (&self->gaddress);
--
-- g_clear_handle_id (&self->resync_id, g_source_remove);
--
-- g_free (self->username);
-- g_free (self->login_username);
-- g_free (self->homeserver);
-- g_free (self->device_id);
-- g_free (self->filter_id);
-- matrix_utils_free_buffer (self->password);
-- matrix_utils_free_buffer (self->access_token);
--
-- g_free (self->next_batch);
--
-- G_OBJECT_CLASS (matrix_api_parent_class)->finalize (object);
--}
--
--static void
--matrix_api_class_init (MatrixApiClass *klass)
--{
-- GObjectClass *object_class = G_OBJECT_CLASS (klass);
--
-- object_class->finalize = matrix_api_finalize;
--}
--
--
--static void
--matrix_api_init (MatrixApi *self)
--{
-- self->cancellable = g_cancellable_new ();
-- self->matrix_net = matrix_net_new ();
--}
--
--/**
-- * matrix_api_new:
-- * @username: (nullable): A valid matrix user id
-- *
-- * Create a new #MatrixApi for @username. For the
-- * #MatrixApi to be usable password/access token
-- * and sync_callback should be set.
-- *
-- * If @username is not in full form (ie,
-- * @user:example.com) or an email or phone
-- * number, homeserver should be set with
-- * matrix_api_set_homeserver()
-- *
-- * Returns: (transfer full): A new #MatrixApi.
-- * Free with g_object_unref().
-- */
--MatrixApi *
--matrix_api_new (const char *username)
--{
-- MatrixApi *self;
--
-- self = g_object_new (MATRIX_TYPE_API, NULL);
-- self->login_username = g_strdup (username);
--
-- return self;
--}
--
--void
--matrix_api_set_enc (MatrixApi *self,
-- MatrixEnc *enc)
--{
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (MATRIX_IS_ENC (enc));
-- g_return_if_fail (!self->matrix_enc);
--
-- g_set_object (&self->matrix_enc, enc);
--
-- if (self->username && self->device_id)
-- matrix_enc_set_details (self->matrix_enc, self->username, self->device_id);
--}
--
--/**
-- * matrix_api_can_connect:
-- * @self: A #MatrixApi
-- *
-- * Check if @self can be connected to homeserver with current
-- * network state. This function is a bit dumb: returning
-- * %TRUE shall not ensure that the @self is connectable.
-- * But if %FALSE is returned, @self shall not be
-- * able to connect.
-- */
--gboolean
--matrix_api_can_connect (MatrixApi *self)
--{
-- GNetworkMonitor *nm;
-- GInetAddress *inet;
--
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
--
-- /* If never tried, assume we can connect */
-- if (!self->has_tried_connecting)
-- return TRUE;
--
-- nm = g_network_monitor_get_default ();
--
-- if (!self->gaddress || !G_IS_INET_SOCKET_ADDRESS (self->gaddress))
-- goto end;
--
-- inet = g_inet_socket_address_get_address ((GInetSocketAddress *)self->gaddress);
--
-- if (g_inet_address_get_is_loopback (inet) ||
-- g_inet_address_get_is_site_local (inet))
-- return g_network_monitor_can_reach (nm, G_SOCKET_CONNECTABLE (self->gaddress), NULL, NULL);
--
-- end:
-- /* Distributions may advertise to have full network support event
-- * when connected only to local network, so this isn't always right */
-- return g_network_monitor_get_connectivity (nm) == G_NETWORK_CONNECTIVITY_FULL;
--}
--
--/**
-- * matrix_api_get_username:
-- * @self: A #MatrixApi
-- *
-- * Get the username of @self. This will be a fully
-- * qualified Matrix ID (eg: @user:example.com) if
-- * @self has succeeded in synchronizing with the
-- * server, otherwise NULL is returned
-- *
-- * Please note that this can return a different value
-- * than the one set with matrix_api_set_login_username().
-- *
-- * Returns: (nullable): The matrix username.
-- */
--const char *
--matrix_api_get_username (MatrixApi *self)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
--
-- return self->username;
--}
--
--void
--matrix_api_set_username (MatrixApi *self,
-- const char *username)
--{
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (!self->username);
--
-- if (chatty_utils_username_is_valid (username, CHATTY_PROTOCOL_MATRIX))
-- self->username = g_strdup (username);
--}
--
--/**
-- * matrix_api_get_login_username:
-- * @self: A #MatrixApi
-- *
-- * Get the username as set with
-- * matrix_api_set_login_username().
-- *
-- * Returns: The matrix username.
-- */
--const char *
--matrix_api_get_login_username (MatrixApi *self)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), "");
--
-- return self->login_username;
--}
--
--/**
-- * matrix_api_set_login_username:
-- * @self: A #MatrixApi
-- * @userame: The usernamed to use for login
-- *
-- * Set the username of @self. This is not required to
-- * be a fully qualified Matrix ID like @user:example.com
-- * and can also be an email ID or phone number.
-- *
-- * username can be set only once.
-- */
--void
--matrix_api_set_login_username (MatrixApi *self,
-- const char *username)
--{
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (!self->login_username);
--
-- self->login_username = g_strdup (username);
--}
--
--/**
-- * matrix_api_get_password:
-- * @self: A #MatrixApi
-- *
-- * Get the password of @self.
-- *
-- * Returns: (nullable): The matrix username.
-- */
--const char *
--matrix_api_get_password (MatrixApi *self)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
--
-- return self->password;
--}
--
--/**
-- * matrix_api_set_password:
-- * @self: A #MatrixApi
-- * @password: A valid password string
-- *
-- * Set the password for @self.
-- */
--void
--matrix_api_set_password (MatrixApi *self,
-- const char *password)
--{
-- g_return_if_fail (MATRIX_IS_API (self));
--
-- if (!password || !*password)
-- return;
--
-- matrix_utils_free_buffer (self->password);
-- self->password = g_strdup (password);
--}
--
--/**
-- * matrix_api_set_sync_callback:
-- * @self: A #MatrixApi
-- * @callback: A #MatriCallback
-- * @object: A #GObject
-- *
-- * Set sync callback. It’s allowed to set callback
-- * only once.
-- *
-- * @object should be a #GObject (derived) object.
-- *
-- * callback shall run as `callback(@object, ...)`
-- *
-- * @callback shall be run for every event that’s worth
-- * informing (Say, the callback won’t be run if the
-- * sync response is empty).
-- *
-- * The @callback may run with a %NULL #GAsyncResult
-- * argument. Check the sync state before handling
-- * the #GAsyncResult. See matrix_api_get_sync_state().
-- */
--void
--matrix_api_set_sync_callback (MatrixApi *self,
-- MatrixCallback callback,
-- gpointer object)
--{
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (callback);
-- g_return_if_fail (G_IS_OBJECT (object));
-- g_return_if_fail (!self->callback);
--
-- self->callback = callback;
-- g_set_weak_pointer (&self->cb_object, object);
--}
--
--const char *
--matrix_api_get_homeserver (MatrixApi *self)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
--
-- return self->homeserver;
--}
--
--void
--matrix_api_set_homeserver (MatrixApi *self,
-- const char *homeserver)
--{
-- g_autoptr(SoupURI) uri = NULL;
-- GString *host;
--
-- g_return_if_fail (MATRIX_IS_API (self));
--
-- uri = soup_uri_new (homeserver);
-- if (!homeserver || !uri ||
-- !SOUP_URI_VALID_FOR_HTTP (uri))
-- return;
--
-- host = g_string_new (NULL);
-- g_string_append (host, soup_uri_get_scheme (uri));
-- g_string_append (host, "://");
-- g_string_append (host, uri->host);
-- if (!soup_uri_uses_default_port (uri))
-- g_string_append_printf (host, ":%d", soup_uri_get_port (uri));
--
-- g_free (self->homeserver);
-- self->homeserver = g_string_free (host, FALSE);
--
-- matrix_net_set_homeserver (self->matrix_net, self->homeserver);
--
-- if (self->is_sync &&
-- self->sync_failed &&
-- self->action == MATRIX_GET_HOMESERVER) {
-- self->sync_failed = FALSE;
-- matrix_verify_homeserver (self);
-- }
--}
--
--/**
-- * matrix_api_get_device_id:
-- * @self: A #MatrixApi
-- *
-- * Get the device ID of @self. If the
-- * account login succeeded, the device
-- * ID provided by the server is returned.
-- * Otherwise, the one set with @self is
-- * returned.
-- *
-- * Please not that the user login is done
-- * only if @self has no access-token set,
-- * or if the acces-token is invalid.
-- *
-- * Returns: (nullable): The Device ID.
-- */
--const char *
--matrix_api_get_device_id (MatrixApi *self)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
--
-- return self->device_id;
--}
--
--const char *
--matrix_api_get_access_token (MatrixApi *self)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
--
-- return self->access_token;
--}
--
--void
--matrix_api_set_access_token (MatrixApi *self,
-- const char *access_token,
-- const char *device_id)
--{
-- g_return_if_fail (MATRIX_IS_API (self));
--
-- g_clear_pointer (&self->access_token, matrix_utils_free_buffer);
-- g_clear_pointer (&self->device_id, g_free);
--
-- if (!access_token || !device_id)
-- return;
--
-- self->access_token = g_strdup (access_token);
-- self->device_id = g_strdup (device_id);
-- matrix_net_set_access_token (self->matrix_net, self->access_token);
--
-- if (self->matrix_enc && self->username)
-- matrix_enc_set_details (self->matrix_enc, self->username, self->device_id);
--}
--
--const char *
--matrix_api_get_next_batch (MatrixApi *self)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
--
-- return self->next_batch;
--}
--
--void
--matrix_api_set_next_batch (MatrixApi *self,
-- const char *next_batch)
--{
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (!self->next_batch);
--
-- if (next_batch)
-- self->full_state_loaded = TRUE;
--
-- self->next_batch = g_strdup (next_batch);
--}
--
--/**
-- * matrix_api_start_sync:
-- * @self: A #MatrixApi
-- *
-- * Start synchronizing with the matrix server.
-- *
-- * If a sync process is already in progress
-- * this function simply returns.
-- *
-- * The process is:
-- * 1. Get home server (if required)
-- * 2. Verify homeserver Server-Client API
-- * 3. If access token set, start sync
-- * 4. Else login with password
-- */
--void
--matrix_api_start_sync (MatrixApi *self)
--{
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (self->callback);
-- g_return_if_fail (self->login_username);
--
-- if (self->is_sync && !self->sync_failed)
-- return;
--
-- if (g_cancellable_is_cancelled (self->cancellable)) {
-- g_object_unref (self->cancellable);
-- self->cancellable = g_cancellable_new ();
-- }
--
-- matrix_start_sync (self);
--}
--
--gboolean
--matrix_api_is_sync (MatrixApi *self)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
--
-- return self->access_token && self->login_success &&
-- self->is_sync && !self->sync_failed;
--}
--
--void
--matrix_api_stop_sync (MatrixApi *self)
--{
-- g_return_if_fail (MATRIX_IS_API (self));
--
-- g_clear_handle_id (&self->resync_id, g_source_remove);
-- g_cancellable_cancel (self->cancellable);
-- self->is_sync = FALSE;
-- self->sync_failed = FALSE;
--}
--
--void
--matrix_api_set_upload_key (MatrixApi *self,
-- char *key)
--{
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (key && *key);
--
-- g_free (self->key);
-- self->key = key;
--
-- if (self->is_sync && self->action == MATRIX_RED_PILL)
-- matrix_upload_key (self);
--}
--
--void
--matrix_api_set_typing (MatrixApi *self,
-- const char *room_id,
-- gboolean is_typing)
--{
-- g_autofree char *uri = NULL;
-- JsonObject *object;
--
-- g_return_if_fail (MATRIX_IS_API (self));
--
-- CHATTY_TRACE_MSG ("Update typing: %d", !!is_typing);
-- /* https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-ro... */
-- object = json_object_new ();
-- json_object_set_boolean_member (object, "typing", !!is_typing);
-- if (is_typing)
-- json_object_set_int_member (object, "timeout", TYPING_TIMEOUT);
--
-- uri = g_strconcat (self->homeserver, "/_matrix/client/r0/rooms/",
-- room_id, "/typing/", self->username, NULL);
--
-- matrix_net_send_json_async (self->matrix_net, 0, object, uri, SOUP_METHOD_PUT,
-- NULL, self->cancellable, matrix_send_typing_cb, NULL);
--}
--
--void
--matrix_api_get_room_state_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *uri = NULL;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (room_id && *room_id);
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
--
-- uri = g_strconcat ("/_matrix/client/r0/rooms/", room_id, "/state", NULL);
-- matrix_net_send_json_async (self->matrix_net, -1, NULL, uri, SOUP_METHOD_GET,
-- NULL, self->cancellable, matrix_get_room_state_cb, task);
--}
--
--JsonArray *
--matrix_api_get_room_state_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
-- g_return_val_if_fail (G_IS_TASK (result), NULL);
-- g_return_val_if_fail (!error || !*error, NULL);
--
-- return g_task_propagate_pointer (G_TASK (result), error);
--}
--
--static void
--matrix_get_room_users_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- JsonObject *object;
-- GError *error = NULL;
--
-- g_assert (G_IS_TASK (task));
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- if (error) {
-- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- g_debug ("Error getting room members: %s", error->message);
-- g_task_return_error (task, error);
-- } else {
-- g_task_return_pointer (task, object, (GDestroyNotify)json_object_unref);
-- }
--}
--
--void
--matrix_api_get_room_users_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *uri = NULL;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (room_id && *room_id);
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
--
-- uri = g_strconcat ("/_matrix/client/r0/rooms/", room_id, "/joined_members", NULL);
-- matrix_net_send_json_async (self->matrix_net, -1, NULL, uri, SOUP_METHOD_GET,
-- NULL, self->cancellable, matrix_get_room_users_cb, task);
--}
--
--JsonObject *
--matrix_api_get_room_users_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
-- g_return_val_if_fail (G_IS_TASK (result), NULL);
-- g_return_val_if_fail (!error || !*error, NULL);
--
-- return g_task_propagate_pointer (G_TASK (result), error);
--}
--
--void
--matrix_api_get_room_name_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *uri = NULL;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (room_id && *room_id);
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
-- uri = g_strconcat ("/_matrix/client/r0/rooms/", room_id, "/state/m.room.name", NULL);
-- matrix_net_send_json_async (self->matrix_net, -1, NULL, uri, SOUP_METHOD_GET,
-- NULL, self->cancellable, matrix_get_room_name_cb, task);
--}
--
--JsonObject *
--matrix_api_get_room_name_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
-- g_return_val_if_fail (G_IS_TASK (result), NULL);
-- g_return_val_if_fail (!error || !*error, NULL);
--
-- return g_task_propagate_pointer (G_TASK (result), error);
--}
--
--void
--matrix_api_get_room_encryption_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *uri = NULL;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (room_id && *room_id);
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
-- uri = g_strconcat ("/_matrix/client/r0/rooms/", room_id, "/state/m.room.encryption", NULL);
-- matrix_net_send_json_async (self->matrix_net, -1, NULL, uri, SOUP_METHOD_GET,
-- NULL, self->cancellable, matrix_get_room_encryption_cb, task);
--}
--
--char *
--matrix_api_get_room_encryption_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
-- g_return_val_if_fail (G_IS_TASK (result), NULL);
-- g_return_val_if_fail (!error || !*error, NULL);
--
-- return g_task_propagate_pointer (G_TASK (result), error);
--}
--
--/**
-- * matrix_api_set_room_encryption_async:
-- * @self: A #MatrixApi
-- * @room_id: The room id to set encryption for
-- * @callback: A #GAsyncReadyCallback
-- * @user_data: user data passed to @callback
-- *
-- * Calling this method shall enable encryption.
-- * There is no way to disable encryption once
-- * enabled.
-- *
-- * To get the result, finish the call with
-- * matrix_api_set_room_encryption_finish()
-- */
--void
--matrix_api_set_room_encryption_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *uri = NULL;
-- JsonObject *object;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (room_id && *room_id);
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
-- object = json_object_new ();
-- json_object_set_string_member (object, "algorithm", ALGORITHM_MEGOLM);
-- uri = g_strconcat ("/_matrix/client/r0/rooms/", room_id, "/state/m.room.encryption", NULL);
-- matrix_net_send_json_async (self->matrix_net, 2, object, uri, SOUP_METHOD_PUT,
-- NULL, self->cancellable, matrix_set_room_encryption_cb, task);
--}
--
--gboolean
--matrix_api_set_room_encryption_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--void
--matrix_api_get_members_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *uri = NULL;
-- GHashTable *query;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
--
-- query = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
-- (GDestroyNotify)matrix_utils_free_buffer);
-- g_hash_table_insert (query, g_strdup ("membership"), g_strdup ("join"));
--
-- if (self->next_batch)
-- g_hash_table_insert (query, g_strdup ("since"), g_strdup (self->next_batch));
--
-- /* https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-ro... */
-- uri = g_strconcat ("/_matrix/client/r0/rooms/", room_id, "/members", NULL);
-- matrix_net_send_json_async (self->matrix_net, -1, NULL, uri, SOUP_METHOD_GET,
-- query, self->cancellable, matrix_get_members_cb, task);
--}
--
--JsonObject *
--matrix_api_get_members_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
-- g_return_val_if_fail (G_IS_TASK (result), NULL);
-- g_return_val_if_fail (!error || !*error, NULL);
--
-- return g_task_propagate_pointer (G_TASK (result), error);
--}
--
--void
--matrix_api_load_prev_batch_async (MatrixApi *self,
-- const char *room_id,
-- char *prev_batch,
-- char *last_batch,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *uri = NULL;
-- GHashTable *query;
-- GTask *task;
--
-- if (!prev_batch)
-- return;
--
-- g_return_if_fail (MATRIX_IS_API (self));
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
--
-- /* Create a query to get past 30 messages */
-- query = g_hash_table_new_full (g_str_hash, g_str_equal, free,
-- (GDestroyNotify)matrix_utils_free_buffer);
-- g_hash_table_insert (query, g_strdup ("from"), g_strdup (prev_batch));
-- g_hash_table_insert (query, g_strdup ("dir"), g_strdup ("b"));
-- g_hash_table_insert (query, g_strdup ("limit"), g_strdup ("30"));
-- if (last_batch)
-- g_hash_table_insert (query, g_strdup ("to"), g_strdup (last_batch));
--
-- CHATTY_TRACE_MSG ("Load prev-batch");
-- /* https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-ro... */
-- uri = g_strconcat ("/_matrix/client/r0/rooms/", room_id, "/messages", NULL);
-- matrix_net_send_json_async (self->matrix_net, 0, NULL, uri, SOUP_METHOD_GET,
-- query, self->cancellable, matrix_get_messages_cb, task);
--}
--
--JsonObject *
--matrix_api_load_prev_batch_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
-- g_return_val_if_fail (G_IS_TASK (result), NULL);
-- g_return_val_if_fail (!error || !*error, NULL);
--
-- return g_task_propagate_pointer (G_TASK (result), error);
--}
--
--/**
-- * matrix_api_query_keys_async:
-- * @self: A #MatrixApi
-- * @member_list: A #GListModel of #ChattyMaBuddy
-- * @token: (nullable): A 'since' token string
-- * @callback: A #GAsyncReadyCallback
-- * @user_data: user data passed to @callback
-- *
-- * Get identity keys of all devices in @member_list.
-- * Pass in @token (obtained via the "since" in /sync)
-- * if only the device changes since the corresponding
-- * /sync is needed.
-- *
-- * Finish the call with matrix_api_query_keys_finish()
-- * to get the result.
-- */
--void
--matrix_api_query_keys_async (MatrixApi *self,
-- GListModel *member_list,
-- const char *token,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- JsonObject *object, *child;
-- GTask *task;
-- guint n_items;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (G_IS_LIST_MODEL (member_list));
-- g_return_if_fail (g_list_model_get_item_type (member_list) == CHATTY_TYPE_MA_BUDDY);
-- g_return_if_fail (g_list_model_get_n_items (member_list) > 0);
--
-- /* https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-k... */
-- object = json_object_new ();
-- json_object_set_int_member (object, "timeout", KEY_TIMEOUT);
-- if (token)
-- json_object_set_string_member (object, "token", token);
--
-- n_items = g_list_model_get_n_items (member_list);
-- child = json_object_new ();
--
-- for (guint i = 0; i < n_items; i++) {
-- g_autoptr(ChattyMaBuddy) buddy = NULL;
--
-- buddy = g_list_model_get_item (member_list, i);
-- json_object_set_array_member (child,
-- chatty_item_get_username (CHATTY_ITEM (buddy)),
-- json_array_new ());
-- }
--
-- json_object_set_object_member (object, "device_keys", child);
-- CHATTY_TRACE_MSG ("Query keys of %u members", n_items);
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
--
-- matrix_net_send_json_async (self->matrix_net, 0, object,
-- "/_matrix/client/r0/keys/query", SOUP_METHOD_POST,
-- NULL, self->cancellable, matrix_keys_query_cb, task);
--}
--
--JsonObject *
--matrix_api_query_keys_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
-- g_return_val_if_fail (G_IS_TASK (result), NULL);
-- g_return_val_if_fail (!error || !*error, NULL);
--
-- return g_task_propagate_pointer (G_TASK (result), error);
--}
--
--/**
-- * matrix_api_claim_keys_async:
-- * @self: A #MatrixApi
-- * @member_list: A #GListModel of #ChattyMaBuddy
-- * @callback: A #GAsyncReadyCallback
-- * @user_data: user data passed to @callback
-- *
-- * Claim a key for all devices of @members_list
-- */
--void
--matrix_api_claim_keys_async (MatrixApi *self,
-- GListModel *member_list,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- JsonObject *object, *child;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (G_IS_LIST_MODEL (member_list));
-- g_return_if_fail (g_list_model_get_item_type (member_list) == CHATTY_TYPE_MA_BUDDY);
-- g_return_if_fail (g_list_model_get_n_items (member_list) > 0);
--
-- /* https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-k... */
-- object = json_object_new ();
-- json_object_set_int_member (object, "timeout", KEY_TIMEOUT);
--
-- child = json_object_new ();
--
-- for (guint i = 0; i < g_list_model_get_n_items (member_list); i++) {
-- g_autoptr(ChattyMaBuddy) buddy = NULL;
-- JsonObject *key_json;
--
-- buddy = g_list_model_get_item (member_list, i);
-- key_json = chatty_ma_buddy_device_key_json (buddy);
--
-- if (key_json)
-- json_object_set_object_member (child,
-- chatty_item_get_username (CHATTY_ITEM (buddy)),
-- key_json);
-- }
--
-- json_object_set_object_member (object, "one_time_keys", child);
-- CHATTY_TRACE_MSG ("Claiming keys");
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
--
-- matrix_net_send_json_async (self->matrix_net, 0, object,
-- "/_matrix/client/r0/keys/claim", SOUP_METHOD_POST,
-- NULL, self->cancellable, matrix_keys_claim_cb, task);
--}
--
--JsonObject *
--matrix_api_claim_keys_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), NULL);
-- g_return_val_if_fail (G_IS_TASK (result), NULL);
-- g_return_val_if_fail (!error || !*error, NULL);
--
-- return g_task_propagate_pointer (G_TASK (result), error);
--}
--
--void
--matrix_api_get_file_async (MatrixApi *self,
-- ChattyMessage *message,
-- ChattyFileInfo *file,
-- GCancellable *cancellable,
-- GFileProgressCallback progress_callback,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = NULL;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (!message || CHATTY_IS_MESSAGE (message));
--
-- if (message)
-- g_object_ref (message);
--
-- task = g_task_new (self, cancellable, callback, user_data);
--
-- g_object_set_data (G_OBJECT (task), "file", file);
-- g_object_set_data_full (G_OBJECT (task), "message", message, g_object_unref);
--
-- if (file->status != CHATTY_FILE_UNKNOWN) {
-- g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
-- "Download not required");
-- return;
-- }
--
-- matrix_net_get_file_async (self->matrix_net, message,
-- file, cancellable,
-- progress_callback,
-- api_get_file_cb,
-- g_steal_pointer (&task));
--}
--
--gboolean
--matrix_api_get_file_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--static void
--api_send_message_encrypted (MatrixApi *self,
-- const char *room_id,
-- ChattyMessage *message,
-- JsonObject *content,
-- GTask *task)
--{
-- g_autofree char *text = NULL;
-- g_autofree char *uri = NULL;
-- JsonObject *root;
-- char *id;
--
-- g_assert (MATRIX_IS_API (self));
-- g_assert (content);
--
-- root = json_object_new ();
-- json_object_set_string_member (root, "type", "m.room.message");
-- json_object_set_string_member (root, "room_id", room_id);
-- json_object_set_object_member (root, "content", content);
--
-- text = matrix_utils_json_object_to_string (root, FALSE);
-- json_object_unref (root);
-- root = matrix_enc_encrypt_for_chat (self->matrix_enc, room_id, text);
--
-- self->event_id++;
-- id = g_strdup_printf ("m%"G_GINT64_FORMAT".%d",
-- g_get_real_time () / G_TIME_SPAN_MILLISECOND,
-- self->event_id);
-- g_object_set_data_full (G_OBJECT (message), "event-id", id, g_free);
--
-- g_object_set_data_full (G_OBJECT (task), "message", g_object_ref (message),
-- g_object_unref);
-- CHATTY_DEBUG (room_id, "Sending encrypted message. event id: %s, room:", id);
--
-- uri = g_strdup_printf ("/_matrix/client/r0/rooms/%s/send/m.room.encrypted/%s", room_id, id);
--
-- matrix_net_send_json_async (self->matrix_net, 0, root, uri, SOUP_METHOD_PUT,
-- NULL, self->cancellable, api_send_message_cb, task);
--}
--
--static void
--api_send_message (MatrixApi *self,
-- const char *room_id,
-- ChattyMessage *message,
-- JsonObject *content,
-- GTask *task)
--{
-- g_autofree char *uri = NULL;
-- char *id;
--
-- g_assert (MATRIX_IS_API (self));
-- g_assert (content);
--
-- self->event_id++;
-- id = g_strdup_printf ("m%"G_GINT64_FORMAT".%d",
-- g_get_real_time () / G_TIME_SPAN_MILLISECOND,
-- self->event_id);
-- g_object_set_data_full (G_OBJECT (message), "event-id", id, g_free);
--
-- g_object_set_data_full (G_OBJECT (task), "message", g_object_ref (message),
-- g_object_unref);
--
-- CHATTY_DEBUG (room_id, "Sending message. event id: %s, room:", id);
--
-- /* https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-ro... */
-- uri = g_strdup_printf ("/_matrix/client/r0/rooms/%s/send/m.room.message/%s", room_id, id);
-- matrix_net_send_json_async (self->matrix_net, 0, content, uri, SOUP_METHOD_PUT,
-- NULL, self->cancellable, api_send_message_cb, task);
--}
--
--void
--matrix_api_send_message_async (MatrixApi *self,
-- ChattyChat *chat,
-- const char *room_id,
-- ChattyMessage *message,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- JsonObject *object;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (CHATTY_IS_MESSAGE (message));
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
-- object = json_object_new ();
-- json_object_set_string_member (object, "msgtype", "m.text");
-- json_object_set_string_member (object, "body", chatty_message_get_text (message));
--
-- if (chatty_chat_get_encryption (chat) == CHATTY_ENCRYPTION_ENABLED)
-- api_send_message_encrypted (self, room_id, message, object, task);
-- else
-- api_send_message (self, room_id, message, object, task);
--}
--
--gboolean
--matrix_api_send_message_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--void
--matrix_api_set_read_marker_async (MatrixApi *self,
-- const char *room_id,
-- ChattyMessage *message,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *uri = NULL;
-- JsonObject *root;
-- const char *id;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (CHATTY_IS_MESSAGE (message));
--
-- id = chatty_message_get_uid (message);
-- root = json_object_new ();
-- json_object_set_string_member (root, "m.fully_read", id);
-- json_object_set_string_member (root, "m.read", id);
--
-- CHATTY_TRACE_MSG ("Marking is read, message id: %s", id);
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
--
-- uri = g_strdup_printf ("/_matrix/client/r0/rooms/%s/read_markers", room_id);
-- matrix_net_send_json_async (self->matrix_net, 0, root, uri, SOUP_METHOD_POST,
-- NULL, self->cancellable, api_set_read_marker_cb, task);
--}
--
--gboolean
--matrix_api_set_read_marker_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--void
--matrix_api_upload_group_keys_async (MatrixApi *self,
-- const char *room_id,
-- GListModel *member_list,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *uri = NULL;
-- JsonObject *root, *object;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (G_IS_LIST_MODEL (member_list));
-- g_return_if_fail (g_list_model_get_item_type (member_list) == CHATTY_TYPE_MA_BUDDY);
-- g_return_if_fail (g_list_model_get_n_items (member_list) > 0);
--
-- root = json_object_new ();
-- object = matrix_enc_create_out_group_keys (self->matrix_enc, room_id, member_list);
-- json_object_set_object_member (root, "messages", object);
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
--
-- self->event_id++;
-- uri = g_strdup_printf ("/_matrix/client/r0/sendToDevice/m.room.encrypted/m%"G_GINT64_FORMAT".%d",
-- g_get_real_time () / G_TIME_SPAN_MILLISECOND,
-- self->event_id);
-- matrix_net_send_json_async (self->matrix_net, 0, root, uri, SOUP_METHOD_PUT,
-- NULL, self->cancellable, api_upload_group_keys_cb, task);
--}
--
--gboolean
--matrix_api_upload_group_keys_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--static void
--api_leave_room_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixApi *self;
-- g_autoptr(GTask) task = user_data;
-- g_autoptr(JsonObject) object = NULL;
-- GError *error = NULL;
--
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (MATRIX_IS_API (self));
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- CHATTY_DEBUG (g_task_get_task_data (G_TASK (task)),
-- "Leaving room %s", CHATTY_LOG_SUCESS (!error));
--
-- if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- g_debug ("Error leaving room: %s", error->message);
--
-- if (error)
-- g_task_return_error (task, error);
-- else
-- g_task_return_boolean (task, TRUE);
--}
--
--void
--matrix_api_leave_chat_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GTask *task;
-- g_autofree char *uri = NULL;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (room_id && *room_id == '!');
--
-- CHATTY_DEBUG (room_id, "Leaving room");
--
-- task = g_task_new (self, self->cancellable, callback, user_data);
-- g_task_set_task_data (task, g_strdup (room_id), g_free);
-- uri = g_strdup_printf ("/_matrix/client/r0/rooms/%s/leave", room_id);
-- matrix_net_send_json_async (self->matrix_net, 1, NULL, uri, SOUP_METHOD_POST,
-- NULL, self->cancellable, api_leave_room_cb, task);
--}
--
--gboolean
--matrix_api_leave_chat_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--static void
--api_get_user_info_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixApi *self;
-- g_autoptr(GTask) task = user_data;
-- const char *name, *avatar_url;
-- GError *error = NULL;
-- g_autoptr(JsonObject) object = NULL;
--
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (MATRIX_IS_API (self));
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- CHATTY_TRACE_MSG ("Getting user info. success: %d", !error);
--
-- if (error) {
-- g_task_return_error (task, error);
-- return;
-- }
--
-- name = matrix_utils_json_object_get_string (object, "displayname");
-- avatar_url = matrix_utils_json_object_get_string (object, "avatar_url");
--
-- g_object_set_data_full (G_OBJECT (task), "name", g_strdup (name), g_free);
-- g_object_set_data_full (G_OBJECT (task), "avatar-url", g_strdup (avatar_url), g_free);
--
-- g_task_return_boolean (task, TRUE);
--}
--
--void
--matrix_api_get_user_info_async (MatrixApi *self,
-- const char *user_id,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *uri = NULL;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
--
-- if (!user_id)
-- user_id = self->username;
--
-- task = g_task_new (self, cancellable, callback, user_data);
--
-- if (!user_id) {
-- g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
-- "No user id provided");
-- return;
-- }
--
-- CHATTY_TRACE (user_id, "Getting user info: ");
--
-- g_task_set_task_data (task, g_strdup (user_id), g_free);
-- uri = g_strdup_printf ("/_matrix/client/r0/profile/%s", user_id);
-- matrix_net_send_json_async (self->matrix_net, 1, NULL, uri, SOUP_METHOD_GET,
-- NULL, self->cancellable, api_get_user_info_cb, task);
--}
--
--gboolean
--matrix_api_get_user_info_finish (MatrixApi *self,
-- char **name,
-- char **avatar_url,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- *name = g_strdup (g_object_get_data (G_OBJECT (result), "name"));
-- *avatar_url = g_strdup (g_object_get_data (G_OBJECT (result), "avatar-url"));
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--static void
--api_set_name_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixApi *self;
-- g_autoptr(GTask) task = user_data;
-- g_autoptr(JsonObject) object = NULL;
-- GError *error = NULL;
--
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (MATRIX_IS_API (self));
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- CHATTY_DEBUG (self->username, "Setting name to '%s' %s for user",
-- (char *)g_task_get_task_data (task), CHATTY_LOG_SUCESS (!error));
--
-- if (error)
-- g_task_return_error (task, error);
-- else
-- g_task_return_boolean (task, TRUE);
--}
--
--void
--matrix_api_set_name_async (MatrixApi *self,
-- const char *name,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *uri = NULL;
-- JsonObject *root = NULL;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
--
-- CHATTY_DEBUG (self->username, "Setting name to '%s' for user", name);
--
-- if (name && *name) {
-- root = json_object_new ();
-- json_object_set_string_member (root, "displayname", name);
-- }
--
-- task = g_task_new (self, cancellable, callback, user_data);
-- g_task_set_task_data (task, g_strdup (name), g_free);
--
-- uri = g_strdup_printf ("/_matrix/client/r0/profile/%s/displayname", self->username);
-- matrix_net_send_json_async (self->matrix_net, 1, root, uri, SOUP_METHOD_PUT,
-- NULL, self->cancellable, api_set_name_cb, task);
--}
--
--gboolean
--matrix_api_set_name_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--static void
--api_set_user_avatar_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixApi *self;
-- g_autoptr(GTask) task = user_data;
-- g_autoptr(JsonObject) object = NULL;
-- GError *error = NULL;
--
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (MATRIX_IS_API (self));
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- CHATTY_DEBUG (self->username, "Setting avatar %s, user:", CHATTY_LOG_SUCESS (!error));
--
-- if (error)
-- g_task_return_error (task, error);
-- else
-- g_task_return_boolean (task, TRUE);
--}
--
--void
--matrix_api_set_user_avatar_async (MatrixApi *self,
-- const char *file_name,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = NULL;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
--
-- task = g_task_new (self, cancellable, callback, user_data);
--
-- if (!file_name) {
-- g_autofree char *uri = NULL;
-- const char *data;
--
-- data = "{\"avatar_url\":\"\"}";
-- uri = g_strdup_printf ("/_matrix/client/r0/profile/%s/avatar_url", self->username);
-- matrix_net_send_data_async (self->matrix_net, 2, g_strdup (data), strlen (data),
-- uri, SOUP_METHOD_PUT, NULL, self->cancellable,
-- api_set_user_avatar_cb, g_steal_pointer (&task));
-- } else {
-- g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
-- "Setting new user avatar not implemented");
-- }
--}
--
--gboolean
--matrix_api_set_user_avatar_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--static void
--api_get_3pid_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixApi *self;
-- g_autoptr(GTask) task = user_data;
-- GPtrArray *emails, *phones;
-- GError *error = NULL;
-- g_autoptr(JsonObject) object = NULL;
-- JsonArray *array;
-- guint length;
--
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (MATRIX_IS_API (self));
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
-- array = matrix_utils_json_object_get_array (object, "threepids");
--
-- CHATTY_DEBUG (self->username, "Getting 3pid %s, user:", CHATTY_LOG_SUCESS (!error));
--
-- if (!array) {
-- if (error)
-- g_task_return_error (task, error);
-- else
-- g_task_return_boolean (task, FALSE);
--
-- return;
-- }
--
-- emails = g_ptr_array_new_full (1, g_free);
-- phones = g_ptr_array_new_full (1, g_free);
--
-- length = json_array_get_length (array);
--
-- for (guint i = 0; i < length; i++) {
-- const char *type, *value;
--
-- object = json_array_get_object_element (array, i);
-- value = matrix_utils_json_object_get_string (object, "address");
-- type = matrix_utils_json_object_get_string (object, "medium");
--
-- if (g_strcmp0 (type, "email") == 0)
-- g_ptr_array_add (emails, g_strdup (value));
-- else if (g_strcmp0 (type, "msisdn") == 0)
-- g_ptr_array_add (phones, g_strdup (value));
-- }
--
-- g_object_set_data_full (G_OBJECT (task), "email", emails,
-- (GDestroyNotify)g_ptr_array_unref);
-- g_object_set_data_full (G_OBJECT (task), "phone", phones,
-- (GDestroyNotify)g_ptr_array_unref);
--
-- g_task_return_boolean (task, TRUE);
--}
--
--void
--matrix_api_get_3pid_async (MatrixApi *self,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
--
-- task = g_task_new (self, cancellable, callback, user_data);
--
-- if (!self->username) {
-- g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
-- "user hasn't logged in yet");
-- return;
-- }
--
-- CHATTY_DEBUG (self->username, "Getting 3pid of user");
--
-- matrix_net_send_json_async (self->matrix_net, 1, NULL,
-- "/_matrix/client/r0/account/3pid", SOUP_METHOD_GET,
-- NULL, self->cancellable, api_get_3pid_cb, task);
--}
--
--gboolean
--matrix_api_get_3pid_finish (MatrixApi *self,
-- GPtrArray **emails,
-- GPtrArray **phones,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- if (emails)
-- *emails = g_object_steal_data (G_OBJECT (result), "email");
-- if (phones)
-- *phones = g_object_steal_data (G_OBJECT (result), "phone");
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--static void
--api_delete_3pid_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixApi *self;
-- g_autoptr(GTask) task = user_data;
-- GError *error = NULL;
-- g_autoptr(JsonObject) object = NULL;
--
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (MATRIX_IS_API (self));
--
-- object = g_task_propagate_pointer (G_TASK (result), &error);
--
-- CHATTY_DEBUG (self->username, "Deleting 3pid %s", CHATTY_LOG_SUCESS (!error));
--
-- if (error) {
-- g_task_return_error (task, error);
-- return;
-- }
--
-- g_task_return_boolean (task, TRUE);
--}
--
--void
--matrix_api_delete_3pid_async (MatrixApi *self,
-- const char *value,
-- ChattyIdType type,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- JsonObject *root;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_API (self));
-- g_return_if_fail (value && *value);
-- g_return_if_fail (type == CHATTY_ID_EMAIL || type == CHATTY_ID_PHONE);
-- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
--
-- if (chatty_log_get_verbosity () > 2) {
-- g_autoptr(GString) str = NULL;
--
-- str = g_string_new (NULL);
-- g_string_append (str, "user: ");
-- chatty_log_anonymize_value (str, self->username);
-- g_string_append (str, " value: ");
-- chatty_log_anonymize_value (str, value);
--
-- g_debug ("Deleting 3pid, %s", str->str);
-- }
--
-- root = json_object_new ();
-- json_object_set_string_member (root, "address", value);
-- if (type == CHATTY_ID_PHONE)
-- json_object_set_string_member (root, "medium", "msisdn");
-- else
-- json_object_set_string_member (root, "medium", "email");
--
-- task = g_task_new (self, cancellable, callback, user_data);
-- g_object_set_data (G_OBJECT (task), "type", GINT_TO_POINTER (type));
-- g_object_set_data_full (G_OBJECT (task), "value",
-- g_strdup (value), g_free);
--
-- matrix_net_send_json_async (self->matrix_net, 2, root,
-- "/_matrix/client/r0/account/3pid/delete", SOUP_METHOD_POST,
-- NULL, cancellable, api_delete_3pid_cb, task);
--}
--
--gboolean
--matrix_api_delete_3pid_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_API (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
-diff --git a/src/matrix/matrix-api.h b/src/matrix/matrix-api.h
-deleted file mode 100644
-index 6d003971..00000000
---- a/src/matrix/matrix-api.h
-+++ /dev/null
-@@ -1,235 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-api.h
-- *
-- * Copyright 2020 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--#pragma once
--
--#include <glib-object.h>
--
--#include "chatty-chat.h"
--#include "chatty-account.h"
--#include "chatty-message.h"
--#include "matrix-enc.h"
--#include "matrix-enums.h"
--
--G_BEGIN_DECLS
--
--#define MATRIX_TYPE_API (matrix_api_get_type ())
--
--G_DECLARE_FINAL_TYPE (MatrixApi, matrix_api, MATRIX, API, GObject)
--
--typedef void (*MatrixCallback) (gpointer object,
-- MatrixApi *self,
-- MatrixAction action,
-- JsonObject *jobject,
-- GError *err);
--
--MatrixApi *matrix_api_new (const char *username);
--void matrix_api_set_enc (MatrixApi *self,
-- MatrixEnc *enc);
--gboolean matrix_api_can_connect (MatrixApi *self);
--
--const char *matrix_api_get_username (MatrixApi *self);
--void matrix_api_set_username (MatrixApi *self,
-- const char *username);
--const char *matrix_api_get_login_username (MatrixApi *self);
--void matrix_api_set_login_username (MatrixApi *self,
-- const char *username);
--
--const char *matrix_api_get_password (MatrixApi *self);
--void matrix_api_set_password (MatrixApi *self,
-- const char *password);
--
--const char *matrix_api_get_homeserver (MatrixApi *self);
--void matrix_api_set_homeserver (MatrixApi *self,
-- const char *homeserver);
--const char *matrix_api_get_device_id (MatrixApi *self);
--const char *matrix_api_get_access_token (MatrixApi *self);
--void matrix_api_set_access_token (MatrixApi *self,
-- const char *access_token,
-- const char *device_id);
--const char *matrix_api_get_next_batch (MatrixApi *self);
--void matrix_api_set_next_batch (MatrixApi *self,
-- const char *next_batch);
--void matrix_api_set_sync_callback (MatrixApi *self,
-- MatrixCallback callback,
-- gpointer object);
--gboolean matrix_api_is_sync (MatrixApi *self);
--void matrix_api_start_sync (MatrixApi *self);
--void matrix_api_stop_sync (MatrixApi *self);
--void matrix_api_set_upload_key (MatrixApi *self,
-- char *key);
--void matrix_api_set_typing (MatrixApi *self,
-- const char *room_id,
-- gboolean is_typing);
--void matrix_api_get_room_state_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--JsonArray *matrix_api_get_room_state_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_get_room_users_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--JsonObject *matrix_api_get_room_users_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_get_room_name_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--JsonObject *matrix_api_get_room_name_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_get_room_encryption_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--char *matrix_api_get_room_encryption_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_set_room_encryption_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_set_room_encryption_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--
--void matrix_api_get_members_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--JsonObject *matrix_api_get_members_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_load_prev_batch_async (MatrixApi *self,
-- const char *room_id,
-- char *prev_batch,
-- char *last_batch,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--JsonObject *matrix_api_load_prev_batch_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_query_keys_async (MatrixApi *self,
-- GListModel *members_list,
-- const char *token,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--JsonObject *matrix_api_query_keys_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_claim_keys_async (MatrixApi *self,
-- GListModel *member_list,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--JsonObject *matrix_api_claim_keys_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_get_file_async (MatrixApi *self,
-- ChattyMessage *message,
-- ChattyFileInfo *file,
-- GCancellable *cancellable,
-- GFileProgressCallback progress_callback,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_get_file_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_send_file_async (MatrixApi *self,
-- ChattyChat *chat,
-- const char *file_name,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_send_file_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_send_message_async (MatrixApi *self,
-- ChattyChat *chat,
-- const char *room_id,
-- ChattyMessage *message,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_send_message_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_set_read_marker_async (MatrixApi *self,
-- const char *room_id,
-- ChattyMessage *message,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_set_read_marker_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_upload_group_keys_async (MatrixApi *self,
-- const char *room_id,
-- GListModel *member_list,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_upload_group_keys_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_leave_chat_async (MatrixApi *self,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_leave_chat_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_get_user_info_async (MatrixApi *self,
-- const char *user_id,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_get_user_info_finish (MatrixApi *self,
-- char **name,
-- char **avatar_url,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_set_name_async (MatrixApi *self,
-- const char *name,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_set_name_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_set_user_avatar_async (MatrixApi *self,
-- const char *file_name,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_set_user_avatar_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_get_3pid_async (MatrixApi *self,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_get_3pid_finish (MatrixApi *self,
-- GPtrArray **emails,
-- GPtrArray **phones,
-- GAsyncResult *result,
-- GError **error);
--void matrix_api_delete_3pid_async (MatrixApi *self,
-- const char *value,
-- ChattyIdType type,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_api_delete_3pid_finish (MatrixApi *self,
-- GAsyncResult *result,
-- GError **error);
--
--G_END_DECLS
-diff --git a/src/matrix/matrix-db.c b/src/matrix/matrix-db.c
-deleted file mode 100644
-index d0e57319..00000000
---- a/src/matrix/matrix-db.c
-+++ /dev/null
-@@ -1,1320 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-db.c
-- *
-- * Copyright 2020 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--/* This is heavily based on chatty-history */
--
--#define G_LOG_DOMAIN "matrix-db"
--
--#ifdef HAVE_CONFIG_H
--# include "config.h"
--#endif
--
--#include <glib.h>
--#include <fcntl.h>
--#include <sqlite3.h>
--
--#include "chatty-utils.h"
--#include "matrix-enc.h"
--#include "matrix-db.h"
--
--struct _MatrixDb
--{
-- GObject parent_instance;
--
-- GAsyncQueue *queue;
-- GThread *worker_thread;
-- sqlite3 *db;
--};
--
--/*
-- * MatrixDb->db should never be accessed nor modified in main thread
-- * except for checking if it’s %NULL. Any operation should be done only
-- * in @worker_thread. Don't reuse the same #MatrixDb once closed.
-- */
--
--typedef void (*MatrixDbCallback) (MatrixDb *self,
-- GTask *task);
--
--G_DEFINE_TYPE (MatrixDb, matrix_db, G_TYPE_OBJECT)
--
--static void
--warn_if_sql_error (int status,
-- const char *message)
--{
-- if (status == SQLITE_OK || status == SQLITE_ROW || status == SQLITE_DONE)
-- return;
--
-- g_warning ("Error %s. errno: %d, message: %s", message, status, sqlite3_errstr (status));
--}
--
--static void
--matrix_bind_text (sqlite3_stmt *statement,
-- guint position,
-- const char *bind_value,
-- const char *message)
--{
-- guint status;
--
-- status = sqlite3_bind_text (statement, position, bind_value, -1, SQLITE_TRANSIENT);
-- warn_if_sql_error (status, message);
--}
--
--static void
--matrix_bind_int (sqlite3_stmt *statement,
-- guint position,
-- int bind_value,
-- const char *message)
--{
-- guint status;
--
-- status = sqlite3_bind_int (statement, position, bind_value);
-- warn_if_sql_error (status, message);
--}
--
--static int
--matrix_db_create_schema (MatrixDb *self,
-- GTask *task)
--{
-- const char *sql;
-- char *error = NULL;
-- int status;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (G_IS_TASK (task));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (self->db);
--
-- sql = "BEGIN TRANSACTION;"
--
-- "CREATE TABLE IF NOT EXISTS devices ("
-- "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
-- "device TEXT NOT NULL UNIQUE);"
--
-- "CREATE TABLE IF NOT EXISTS users ("
-- "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
-- "username TEXT NOT NULL, "
-- "device_id INTEGER REFERENCES devices(id), "
-- "UNIQUE (username, device_id));"
--
-- "CREATE TABLE IF NOT EXISTS accounts ("
-- "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
-- "user_id INTEGER NOT NULL REFERENCES users(id), "
-- "next_batch TEXT, "
-- "pickle TEXT, "
-- "enabled INTEGER DEFAULT 0, "
-- "UNIQUE (user_id));"
--
-- "CREATE TABLE IF NOT EXISTS rooms ("
-- "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
-- "account_id INTEGER NOT NULL REFERENCES accounts(id), "
-- "room_name TEXT NOT NULL, "
-- "prev_batch TEXT, "
-- "UNIQUE (account_id, room_name));"
--
-- "CREATE TABLE IF NOT EXISTS encryption_keys ("
-- "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
-- "file_url TEXT NOT NULL, "
-- "file_sha256 TEXT, "
-- /* Initialization vector: iv in JSON */
-- "iv TEXT NOT NULL, "
-- /* v in JSON */
-- "version INT DEFAULT 2 NOT NULL, "
-- /* alg in JSON */
-- "algorithm INT NOT NULL, "
-- /* k in JSON */
-- "key TEXT NOT NULL, "
-- /* kty in JSON */
-- "type INT NOT NULL, "
-- /* ext in JSON */
-- "extractable INT DEFAULT 1 NOT NULL, "
-- "UNIQUE (file_url));"
--
-- /* TODO: Someday */
-- "CREATE TABLE IF NOT EXISTS session ("
-- "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
-- "account_id INTEGER NOT NULL REFERENCES accounts(id), "
-- "sender_key TEXT NOT NULL, "
-- "session_id TEXT NOT NULL, "
-- "type INTEGER NOT NULL, "
-- "pickle TEXT NOT NULL, "
-- "time INT, "
-- "UNIQUE (account_id, sender_key, session_id));"
--
-- "COMMIT;";
--
-- status = sqlite3_exec (self->db, sql, NULL, NULL, &error);
--
-- if (status != SQLITE_OK) {
-- g_task_return_new_error (task,
-- G_IO_ERROR,
-- G_IO_ERROR_FAILED,
-- "Error creating chatty_im table. errno: %d, desc: %s. %s",
-- status, sqlite3_errmsg (self->db), error);
-- return status;
-- }
--
-- return status;
--}
--
--
--static void
--matrix_open_db (MatrixDb *self,
-- GTask *task)
--{
-- const char *dir, *file_name;
-- g_autofree char *db_path = NULL;
-- sqlite3 *db;
-- int status;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (G_IS_TASK (task));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (!self->db);
--
-- dir = g_object_get_data (G_OBJECT (task), "dir");
-- file_name = g_object_get_data (G_OBJECT (task), "file-name");
-- g_assert (dir && *dir);
-- g_assert (file_name && *file_name);
--
-- g_mkdir_with_parents (dir, S_IRWXU);
-- db_path = g_build_filename (dir, file_name, NULL);
--
-- status = sqlite3_open (db_path, &db);
--
-- if (status == SQLITE_OK) {
-- self->db = db;
-- status = matrix_db_create_schema (self, task);
--
-- if (status == SQLITE_OK)
-- g_task_return_boolean (task, TRUE);
-- } else {
-- g_task_return_new_error (task,
-- G_IO_ERROR,
-- G_IO_ERROR_FAILED,
-- "Database could not be opened. errno: %d, desc: %s",
-- status, sqlite3_errmsg (db));
-- sqlite3_close (db);
-- }
--}
--
--static void
--matrix_close_db (MatrixDb *self,
-- GTask *task)
--{
-- sqlite3 *db;
-- int status;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (G_IS_TASK (task));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (self->db);
--
-- db = self->db;
-- self->db = NULL;
-- status = sqlite3_close (db);
--
-- if (status == SQLITE_OK) {
-- /*
-- * We can’t know when will @self associated with the task will
-- * be unref. So matrix_db_get_default() called immediately
-- * after this may return the @self that is yet to be free. But
-- * as the worker_thread is exited after closing the database, any
-- * actions with the same @self will not execute, and so the tasks
-- * will take ∞ time to complete.
-- *
-- * So Instead of relying on GObject to free the object, Let’s
-- * explicitly run dispose
-- */
-- g_object_run_dispose (G_OBJECT (self));
-- g_debug ("Database closed successfully");
-- g_task_return_boolean (task, TRUE);
-- } else {
-- g_task_return_new_error (task,
-- G_IO_ERROR,
-- G_IO_ERROR_FAILED,
-- "Database could not be closed. errno: %d, desc: %s",
-- status, sqlite3_errmsg (db));
-- }
--}
--
--static void
--matrix_db_save_account (MatrixDb *self,
-- GTask *task)
--{
-- sqlite3_stmt *stmt;
-- const char *device, *pickle, *username, *batch;
-- int status, device_id = 0, user_id = 0;
-- gboolean enabled;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (G_IS_TASK (task));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (self->db);
--
-- batch = g_object_get_data (G_OBJECT (task), "batch");
-- pickle = g_object_get_data (G_OBJECT (task), "pickle");
-- device = g_object_get_data (G_OBJECT (task), "device");
-- enabled = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "enabled"));
-- username = g_object_get_data (G_OBJECT (task), "username");
--
-- if (device) {
-- sqlite3_prepare_v2 (self->db,
-- "INSERT OR IGNORE INTO devices(device) VALUES(?1)",
-- -1, &stmt, NULL);
--
-- matrix_bind_text (stmt, 1, device, "binding when updating device");
-- sqlite3_step (stmt);
-- sqlite3_finalize (stmt);
--
-- sqlite3_prepare_v2 (self->db,
-- "SELECT id FROM devices WHERE device=?",
-- -1, &stmt, NULL);
-- matrix_bind_text (stmt, 1, device, "binding when getting device id");
--
-- if (sqlite3_step (stmt) == SQLITE_ROW)
-- device_id = sqlite3_column_int (stmt, 0);
-- sqlite3_finalize (stmt);
-- }
--
--
-- /* Find user id with no device id set and have an associated account */
-- sqlite3_prepare_v2 (self->db,
-- "SELECT users.id FROM users "
-- "INNER JOIN accounts ON user_id=users.id "
-- "WHERE username=?1 AND device_id IS NULL LIMIT 1",
-- -1, &stmt, NULL);
-- matrix_bind_text (stmt, 1, username, "binding when getting user");
--
-- if (sqlite3_step (stmt) == SQLITE_ROW)
-- user_id = sqlite3_column_int (stmt, 0);
--
-- if (user_id) {
-- sqlite3_prepare_v2 (self->db,
-- "UPDATE users SET device_id=? WHERE users.id=?",
-- -1, &stmt, NULL);
-- if (device_id)
-- matrix_bind_int (stmt, 1, device_id, "binding when updating existing user");
-- matrix_bind_int (stmt, 2, user_id, "binding when updating existing user");
-- user_id = 0;
-- } else {
-- sqlite3_prepare_v2 (self->db,
-- "INSERT OR IGNORE INTO users(username,device_id) VALUES(?1,?2)",
-- -1, &stmt, NULL);
-- matrix_bind_text (stmt, 1, username, "binding when updating user");
-- if (device_id)
-- matrix_bind_int (stmt, 2, device_id, "binding when updating user");
-- }
--
-- sqlite3_step (stmt);
-- sqlite3_finalize (stmt);
--
-- sqlite3_prepare_v2 (self->db,
-- "SELECT id FROM users WHERE username=?1 AND (device_id=?2 "
-- "OR (device_id IS NULL AND ?2 IS NULL)) LIMIT 1",
-- -1, &stmt, NULL);
-- matrix_bind_text (stmt, 1, username, "binding when getting user id");
-- if (device_id)
-- matrix_bind_int (stmt, 2, device_id, "binding when getting user id");
--
-- if (sqlite3_step (stmt) == SQLITE_ROW)
-- user_id = sqlite3_column_int (stmt, 0);
-- sqlite3_finalize (stmt);
--
-- sqlite3_prepare_v2 (self->db,
-- "INSERT INTO accounts(user_id,pickle,next_batch,enabled) "
-- "VALUES(?1,?2,?3,?4) "
-- "ON CONFLICT(user_id) "
-- "DO UPDATE SET pickle=?2, next_batch=?3, enabled=?4",
-- -1, &stmt, NULL);
--
-- matrix_bind_int (stmt, 1, user_id, "binding when updating account");
-- if (pickle && *pickle)
-- matrix_bind_text (stmt, 2, pickle, "binding when updating account");
-- matrix_bind_text (stmt, 3, batch, "binding when updating account");
-- matrix_bind_int (stmt, 4, enabled, "binding when updating account");
--
-- status = sqlite3_step (stmt);
-- sqlite3_finalize (stmt);
--
-- if (status == SQLITE_DONE)
-- g_task_return_boolean (task, TRUE);
-- else
-- g_task_return_new_error (task,
-- G_IO_ERROR,
-- G_IO_ERROR_FAILED,
-- "Error saving account. errno: %d, desc: %s",
-- status, sqlite3_errmsg (self->db));
--}
--
--/* Find the account id of matching @username and @device_id,
-- * The item should already be in the db, otherwise it's an
-- * error.
-- */
--static int
--matrix_db_get_account_id (MatrixDb *self,
-- GTask *task,
-- const char *username,
-- const char *device_name)
--{
-- sqlite3_stmt *stmt;
-- const char *error;
-- int status;
--
-- g_assert (username && *username);
-- g_assert (device_name && *device_name);
--
-- sqlite3_prepare_v2 (self->db,
-- "SELECT accounts.id FROM accounts "
-- "INNER JOIN users ON username=? "
-- "INNER JOIN devices ON device_id=users.device_id AND devices.device=? "
-- "WHERE accounts.user_id=users.id",
-- -1, &stmt, NULL);
-- matrix_bind_text (stmt, 1, username, "binding when getting account id");
-- matrix_bind_text (stmt, 2, device_name, "binding when getting account id");
--
-- status = sqlite3_step (stmt);
-- if (status == SQLITE_ROW)
-- return sqlite3_column_int (stmt, 0);
--
-- if (status == SQLITE_DONE)
-- error = "Account not found in db";
-- else
-- error = sqlite3_errmsg (self->db);
--
-- g_task_return_new_error (task,
-- G_IO_ERROR,
-- G_IO_ERROR_FAILED,
-- "Couldn't find user %s. error: %s",
-- username, error);
-- return 0;
--}
--
--static void
--matrix_db_load_account (MatrixDb *self,
-- GTask *task)
--{
-- sqlite3_stmt *stmt;
-- char *username, *device_id;
-- int status;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (G_IS_TASK (task));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (self->db);
--
-- username = g_object_get_data (G_OBJECT (task), "username");
-- device_id = g_object_get_data (G_OBJECT (task), "device");
--
-- status = sqlite3_prepare_v2 (self->db,
-- "SELECT enabled,pickle,next_batch,device "
-- "FROM accounts "
-- "INNER JOIN users "
-- "ON users.username=?1 AND users.id=user_id "
-- "LEFT JOIN devices "
-- "ON device_id=devices.id AND devices.device=?2 "
-- "WHERE (?2 is NULL AND device is NULL) OR (?2 is NOT NULL AND device=?2)",
-- -1, &stmt, NULL);
-- matrix_bind_text (stmt, 1, username, "binding when loading account");
-- matrix_bind_text (stmt, 2, device_id, "binding when loading account");
--
-- status = sqlite3_step (stmt);
--
-- if (status == SQLITE_ROW) {
-- GObject *object = G_OBJECT (task);
--
-- g_object_set_data (object, "enabled", GINT_TO_POINTER (sqlite3_column_int (stmt, 0)));
-- g_object_set_data_full (object, "pickle", g_strdup ((char *)sqlite3_column_text (stmt, 1)), g_free);
-- g_object_set_data_full (object, "batch", g_strdup ((char *)sqlite3_column_text (stmt, 2)), g_free);
-- g_object_set_data_full (object, "device", g_strdup ((char *)sqlite3_column_text (stmt, 3)), g_free);
-- }
--
-- sqlite3_finalize (stmt);
-- g_task_return_boolean (task, status == SQLITE_ROW);
--}
--
--static void
--matrix_db_save_room (MatrixDb *self,
-- GTask *task)
--{
-- sqlite3_stmt *stmt;
-- const char *username, *room_name, *batch, *account_device;
-- int status, account_id;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (G_IS_TASK (task));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (self->db);
--
-- batch = g_object_get_data (G_OBJECT (task), "prev-batch");
-- username = g_object_get_data (G_OBJECT (task), "account-id");
-- room_name = g_object_get_data (G_OBJECT (task), "room");
-- account_device = g_object_get_data (G_OBJECT (task), "account-device");
--
-- account_id = matrix_db_get_account_id (self, task, username, account_device);
--
-- if (!account_id)
-- return;
--
-- sqlite3_prepare_v2 (self->db,
-- "INSERT INTO rooms(account_id,room_name,prev_batch) "
-- "VALUES(?1,?2,?3) "
-- "ON CONFLICT(account_id, room_name) "
-- "DO UPDATE SET prev_batch=?3",
-- -1, &stmt, NULL);
-- matrix_bind_int (stmt, 1, account_id, "binding when saving room");
-- matrix_bind_text (stmt, 2, room_name, "binding when saving room");
-- matrix_bind_text (stmt, 3, batch, "binding when saving room");
--
-- status = sqlite3_step (stmt);
-- sqlite3_finalize (stmt);
-- g_task_return_boolean (task, status == SQLITE_DONE);
--}
--
--static void
--matrix_db_load_room (MatrixDb *self,
-- GTask *task)
--{
-- const char *username, *room_name, *account_device;
-- sqlite3_stmt *stmt;
-- int account_id;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (G_IS_TASK (task));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (self->db);
--
-- username = g_object_get_data (G_OBJECT (task), "account-id");
-- room_name = g_object_get_data (G_OBJECT (task), "room");
-- account_device = g_object_get_data (G_OBJECT (task), "account-device");
--
-- account_id = matrix_db_get_account_id (self, task, username, account_device);
--
-- if (!account_id)
-- return;
--
-- sqlite3_prepare_v2 (self->db,
-- "SELECT prev_batch FROM rooms "
-- "WHERE account_id=? AND room_name=? ",
-- -1, &stmt, NULL);
--
-- matrix_bind_int (stmt, 1, account_id, "binding when loading room");
-- matrix_bind_text (stmt, 2, room_name, "binding when loading room");
--
-- if (sqlite3_step (stmt) == SQLITE_ROW)
-- g_task_return_pointer (task, g_strdup ((char *)sqlite3_column_text (stmt, 0)), g_free);
-- else
-- g_task_return_pointer (task, NULL, NULL);
--
-- sqlite3_finalize (stmt);
--}
--
--static void
--matrix_db_delete_account (MatrixDb *self,
-- GTask *task)
--{
-- sqlite3_stmt *stmt;
-- char *username;
-- int status;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (G_IS_TASK (task));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (self->db);
--
-- username = g_object_get_data (G_OBJECT (task), "username");
--
-- status = sqlite3_prepare_v2 (self->db,
-- "DELETE FROM accounts "
-- "WHERE accounts.id IN ("
-- "SELECT users.id FROM users "
-- "WHERE users.username=?)",
-- -1, &stmt, NULL);
-- matrix_bind_text (stmt, 1, username, "binding when loading account");
--
-- status = sqlite3_step (stmt);
-- sqlite3_finalize (stmt);
--
-- g_task_return_boolean (task, status == SQLITE_ROW);
--}
--
--static void
--matrix_db_add_session (MatrixDb *self,
-- GTask *task)
--{
-- sqlite3_stmt *stmt;
-- const char *username, *account_device, *session_id, *sender_key, *pickle;
-- MatrixSessionType type;
-- int status, account_id;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (G_IS_TASK (task));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (self->db);
--
-- type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "type"));
--
-- pickle = g_object_get_data (G_OBJECT (task), "pickle");
-- username = g_object_get_data (G_OBJECT (task), "account-id");
-- session_id = g_object_get_data (G_OBJECT (task), "session-id");
-- sender_key = g_object_get_data (G_OBJECT (task), "sender-key");
-- account_device = g_object_get_data (G_OBJECT (task), "account-device");
--
-- account_id = matrix_db_get_account_id (self, task, username, account_device);
--
-- if (!account_id)
-- return;
--
-- status = sqlite3_prepare_v2 (self->db,
-- "INSERT INTO session(account_id,sender_key,session_id,type,pickle) "
-- "VALUES(?1,?2,?3,?4,?5)",
-- -1, &stmt, NULL);
--
-- matrix_bind_int (stmt, 1, account_id, "binding when adding session");
-- matrix_bind_text (stmt, 2, sender_key, "binding when adding session");
-- matrix_bind_text (stmt, 3, session_id, "binding when adding session");
-- matrix_bind_int (stmt, 4, type, "binding when adding session");
-- matrix_bind_text (stmt, 5, pickle, "binding when adding session");
--
-- status = sqlite3_step (stmt);
-- sqlite3_finalize (stmt);
-- g_task_return_boolean (task, status == SQLITE_DONE);
--}
--
--static void
--matrix_db_save_file_url (MatrixDb *self,
-- GTask *task)
--{
-- ChattyFileInfo *file;
-- MatrixFileEncInfo *enc;
-- sqlite3_stmt *stmt;
-- int status, version, type, extractable, algorithm;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (G_IS_TASK (task));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (self->db);
--
-- file = g_object_get_data (G_OBJECT (task), "file");
-- g_return_if_fail (file && file->user_data);
-- enc = file->user_data;
--
-- type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "type"));
-- version = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "version"));
-- algorithm = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "algorithm"));
-- extractable = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "extractable"));
--
-- status = sqlite3_prepare_v2 (self->db,
-- "INSERT INTO encryption_keys(file_url,file_sha256,"
-- "iv,version,algorithm,key,type,extractable) "
-- "VALUES(?1,?2,?3,?4,?5,?6,?7,?8)",
-- -1, &stmt, NULL);
--
-- matrix_bind_text (stmt, 1, file->url, "binding when adding file url");
-- matrix_bind_text (stmt, 2, enc->sha256_base64, "binding when adding file url");
-- matrix_bind_text (stmt, 3, enc->aes_iv_base64, "binding when adding file url");
-- matrix_bind_int (stmt, 4, version, "binding when adding file url");
-- matrix_bind_int (stmt, 5, algorithm, "binding when adding file url");
-- matrix_bind_text (stmt, 6, enc->aes_key_base64, "binding when adding file url");
-- matrix_bind_int (stmt, 7, type, "binding when adding file url");
-- matrix_bind_int (stmt, 8, extractable, "binding when adding file url");
--
-- status = sqlite3_step (stmt);
-- sqlite3_finalize (stmt);
--
-- g_task_return_boolean (task, status == SQLITE_DONE);
--}
--
--static void
--db_lookup_session (MatrixDb *self,
-- GTask *task)
--{
-- sqlite3_stmt *stmt;
-- const char *username, *account_device, *session_id, *sender_key;
-- char *pickle = NULL;
-- MatrixSessionType type;
-- int status, account_id;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (G_IS_TASK (task));
--
-- type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "type"));
--
-- pickle = g_object_get_data (G_OBJECT (task), "pickle");
-- username = g_object_get_data (G_OBJECT (task), "account-id");
-- session_id = g_object_get_data (G_OBJECT (task), "session-id");
-- sender_key = g_object_get_data (G_OBJECT (task), "sender-key");
-- account_device = g_object_get_data (G_OBJECT (task), "account-device");
--
-- account_id = matrix_db_get_account_id (self, task, username, account_device);
--
-- if (!account_id)
-- return;
--
-- sqlite3_prepare_v2 (self->db,
-- "SELECT pickle FROM session "
-- "WHERE account_id=? AND sender_key=? AND session_id=? AND type=?",
-- -1, &stmt, NULL);
--
-- matrix_bind_int (stmt, 1, account_id, "binding when adding session");
-- matrix_bind_text (stmt, 2, sender_key, "binding when looking up session");
-- matrix_bind_text (stmt, 3, session_id, "binding when looking up session");
-- matrix_bind_int (stmt, 4, type, "binding when looking up session");
--
-- status = sqlite3_step (stmt);
--
-- if (status == SQLITE_ROW)
-- pickle = g_strdup ((char *)sqlite3_column_text (stmt, 0));
--
-- sqlite3_finalize (stmt);
-- g_task_return_pointer (task, pickle, g_free);
--}
--
--static void
--history_get_olm_sessions (MatrixDb *self,
-- GTask *task)
--{
-- GPtrArray *sessions = NULL;
-- sqlite3_stmt *stmt;
-- int status;
--
-- g_assert (MATRIX_IS_DB (self));
-- g_assert (g_thread_self () == self->worker_thread);
-- g_assert (G_IS_TASK (task));
--
-- status = sqlite3_prepare_v2 (self->db,
-- "SELECT sender,sender_key,session_pickle FROM olm_session "
-- "ORDER BY id DESC LIMIT 100", -1, &stmt, NULL);
--
-- warn_if_sql_error (status, "getting olm sessions");
--
-- while (sqlite3_step (stmt) == SQLITE_ROW) {
-- MatrixDbData *data;
--
-- if (!sessions)
-- sessions = g_ptr_array_new_full (100, NULL);
--
-- data = g_new (MatrixDbData, 1);
-- data->sender = g_strdup ((char *)sqlite3_column_text (stmt, 0));
-- data->sender_key = g_strdup ((char *)sqlite3_column_text (stmt, 1));
-- data->session_pickle = g_strdup ((char *)sqlite3_column_text (stmt, 2));
--
-- g_ptr_array_insert (sessions, 0, data);
-- }
--
-- status = sqlite3_finalize (stmt);
-- warn_if_sql_error (status, "finalizing when getting olm sessions");
--
-- g_task_return_pointer (task, sessions, (GDestroyNotify)g_ptr_array_unref);
--}
--
--static gpointer
--matrix_db_worker (gpointer user_data)
--{
-- MatrixDb *self = user_data;
-- GTask *task;
--
-- g_assert (MATRIX_IS_DB (self));
--
-- while ((task = g_async_queue_pop (self->queue))) {
-- MatrixDbCallback callback;
--
-- g_assert (task);
-- callback = g_task_get_task_data (task);
-- callback (self, task);
-- g_object_unref (task);
--
-- if (callback == matrix_close_db)
-- break;
-- }
--
-- return NULL;
--}
--
--static void
--ma_finish_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GError) error = NULL;
--
-- g_task_propagate_boolean (G_TASK (result), &error);
--
-- if (error)
-- g_warning ("Error: %s", error->message);
--
-- g_task_return_boolean (G_TASK (user_data), !error);
--}
--
--static void
--matrix_db_close (MatrixDb *self)
--{
-- g_autoptr(GTask) task = NULL;
--
-- g_return_if_fail (MATRIX_IS_DB (self));
--
-- if (!self->db)
-- return;
--
-- task = g_task_new (NULL, NULL, NULL, NULL);
-- matrix_db_close_async (self, ma_finish_cb, task);
--
-- /* Wait until the task is completed */
-- while (!g_task_get_completed (task))
-- g_main_context_iteration (NULL, TRUE);
--}
--
--static void
--matrix_db_dispose (GObject *object)
--{
-- MatrixDb *self = (MatrixDb *)object;
--
-- matrix_db_close (self);
--
-- g_clear_pointer (&self->worker_thread, g_thread_unref);
--
-- G_OBJECT_CLASS (matrix_db_parent_class)->dispose (object);
--}
--
--static void
--matrix_db_finalize (GObject *object)
--{
-- MatrixDb *self = (MatrixDb *)object;
--
-- if (self->db)
-- g_warning ("Database not closed");
--
-- g_clear_pointer (&self->queue, g_async_queue_unref);
--
-- G_OBJECT_CLASS (matrix_db_parent_class)->finalize (object);
--}
--
--static void
--matrix_db_class_init (MatrixDbClass *klass)
--{
-- GObjectClass *object_class = G_OBJECT_CLASS (klass);
--
-- object_class->dispose = matrix_db_dispose;
-- object_class->finalize = matrix_db_finalize;
--}
--
--static void
--matrix_db_init (MatrixDb *self)
--{
-- self->queue = g_async_queue_new ();
--}
--
--MatrixDb *
--matrix_db_new (void)
--{
-- return g_object_new (MATRIX_TYPE_DB, NULL);
--}
--
--/**
-- * matrix_db_open_async:
-- * @self: a #MatrixDb
-- * @dir: (transfer full): The database directory
-- * @file_name: The file name of database
-- * @callback: a #GAsyncReadyCallback, or %NULL
-- * @user_data: closure data for @callback
-- *
-- * Open the database file @file_name from path @dir.
-- * Complete with matrix_db_open_finish() to get
-- * the result.
-- */
--void
--matrix_db_open_async (MatrixDb *self,
-- char *dir,
-- const char *file_name,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_DB (self));
-- g_return_if_fail (dir || !*dir);
-- g_return_if_fail (file_name || !*file_name);
--
-- if (self->db) {
-- g_warning ("A DataBase is already open");
-- return;
-- }
--
-- if (!self->worker_thread)
-- self->worker_thread = g_thread_new ("matrix-db-worker",
-- matrix_db_worker,
-- self);
--
-- task = g_task_new (self, NULL, callback, user_data);
-- g_task_set_source_tag (task, matrix_db_open_async);
-- g_task_set_task_data (task, matrix_open_db, NULL);
-- g_object_set_data_full (G_OBJECT (task), "dir", dir, g_free);
-- g_object_set_data_full (G_OBJECT (task), "file-name", g_strdup (file_name), g_free);
--
-- g_async_queue_push (self->queue, task);
--}
--
--/**
-- * matrix_db_open_finish:
-- * @self: a #MatrixDb
-- * @result: a #GAsyncResult provided to callback
-- * @error: a location for a #GError or %NULL
-- *
-- * Completes opening a database started with
-- * matrix_db_open_async().
-- *
-- * Returns: %TRUE if database was opened successfully.
-- * %FALSE otherwise with @error set.
-- */
--gboolean
--matrix_db_open_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_DB (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--/**
-- * matrix_db_is_open:
-- * @self: a #MatrixDb
-- *
-- * Get if the database is open or not
-- *
-- * Returns: %TRUE if a database is open.
-- * %FALSE otherwise.
-- */
--gboolean
--matrix_db_is_open (MatrixDb *self)
--{
-- g_return_val_if_fail (MATRIX_IS_DB (self), FALSE);
--
-- return !!self->db;
--}
--
--/**
-- * matrix_db_close_async:
-- * @self: a #MatrixDb
-- * @callback: a #GAsyncReadyCallback, or %NULL
-- * @user_data: closure data for @callback
-- *
-- * Close the database opened.
-- * Complete with matrix_db_close_finish() to get
-- * the result.
-- */
--void
--matrix_db_close_async (MatrixDb *self,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_DB (self));
--
-- task = g_task_new (self, NULL, callback, user_data);
-- g_task_set_source_tag (task, matrix_db_close_async);
-- g_task_set_task_data (task, matrix_close_db, NULL);
--
-- g_async_queue_push (self->queue, task);
--}
--
--/**
-- * matrix_db_open_finish:
-- * @self: a #MatrixDb
-- * @result: a #GAsyncResult provided to callback
-- * @error: a location for a #GError or %NULL
-- *
-- * Completes closing a database started with
-- * matrix_db_close_async(). @self is
-- * g_object_unref() if closing succeeded.
-- * So @self will be freed if you haven’t kept
-- * your own reference on @self.
-- *
-- * Returns: %TRUE if database was closed successfully.
-- * %FALSE otherwise with @error set.
-- */
--gboolean
--matrix_db_close_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_DB (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--void
--matrix_db_save_account_async (MatrixDb *self,
-- ChattyAccount *account,
-- gboolean enabled,
-- char *pickle,
-- const char *device_id,
-- const char *next_batch,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GObject *object;
-- GTask *task;
-- const char *username;
--
-- g_return_if_fail (MATRIX_IS_DB (self));
-- g_return_if_fail (CHATTY_IS_ACCOUNT (account));
--
-- task = g_task_new (self, NULL, callback, user_data);
-- g_task_set_source_tag (task, matrix_db_save_account_async);
-- g_task_set_task_data (task, matrix_db_save_account, NULL);
--
-- object = G_OBJECT (task);
-- username = chatty_item_get_username (CHATTY_ITEM (account));
--
-- if (g_application_get_default ())
-- g_application_hold (g_application_get_default ());
--
-- if (!username || !*username) {
-- g_task_return_boolean (task, FALSE);
-- return;
-- }
--
-- g_object_set_data (object, "enabled", GINT_TO_POINTER (enabled));
-- g_object_set_data_full (object, "pickle", pickle, g_free);
-- g_object_set_data_full (object, "device", g_strdup (device_id), g_free);
-- g_object_set_data_full (object, "batch", g_strdup (next_batch), g_free);
-- g_object_set_data_full (object, "username", g_strdup (username), g_free);
-- g_object_set_data_full (object, "account", g_object_ref (account), g_object_unref);
--
-- g_async_queue_push (self->queue, task);
--}
--
--gboolean
--matrix_db_save_account_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_DB (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
--
-- if (g_application_get_default ())
-- g_application_release (g_application_get_default ());
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--void
--matrix_db_load_account_async (MatrixDb *self,
-- ChattyAccount *account,
-- const char *device_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GTask *task;
-- const char *username;
--
-- g_return_if_fail (!device_id || *device_id);
-- g_return_if_fail (MATRIX_IS_DB (self));
-- g_return_if_fail (CHATTY_IS_ACCOUNT (account));
--
-- task = g_task_new (self, NULL, callback, user_data);
-- g_task_set_source_tag (task, matrix_db_load_account_async);
-- g_task_set_task_data (task, matrix_db_load_account, NULL);
--
-- username = chatty_item_get_username (CHATTY_ITEM (account));
--
-- if (!username || !*username) {
-- g_task_return_boolean (task, FALSE);
-- return;
-- }
--
-- g_object_set_data_full (G_OBJECT (task), "device", g_strdup (device_id), g_free);
-- g_object_set_data_full (G_OBJECT (task), "username", g_strdup (username), g_free);
-- g_object_set_data_full (G_OBJECT (task), "account", g_object_ref (account), g_object_unref);
--
-- g_async_queue_push (self->queue, task);
--}
--
--gboolean
--matrix_db_load_account_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_DB (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--void
--matrix_db_save_room_async (MatrixDb *self,
-- ChattyAccount *account,
-- const char *account_device,
-- const char *room_id,
-- const char *prev_batch,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GTask *task;
-- const char *username;
--
-- g_return_if_fail (MATRIX_IS_DB (self));
-- g_return_if_fail (CHATTY_IS_ACCOUNT (account));
-- g_return_if_fail (room_id && *room_id == '!');
--
-- task = g_task_new (self, NULL, callback, user_data);
-- g_task_set_source_tag (task, matrix_db_save_room_async);
-- g_task_set_task_data (task, matrix_db_save_room, NULL);
--
-- username = chatty_item_get_username (CHATTY_ITEM (account));
-- g_object_set_data_full (G_OBJECT (task), "room", g_strdup (room_id), g_free);
-- g_object_set_data_full (G_OBJECT (task), "username", g_strdup (username), g_free);
-- g_object_set_data_full (G_OBJECT (task), "account-id", g_strdup (username), g_free);
-- g_object_set_data_full (G_OBJECT (task), "prev-batch", g_strdup (prev_batch), g_free);
-- g_object_set_data_full (G_OBJECT (task), "account", g_object_ref (account), g_object_unref);
-- g_object_set_data_full (G_OBJECT (task), "account-device", g_strdup (account_device), g_free);
--
-- g_async_queue_push (self->queue, task);
--}
--
--gboolean
--matrix_db_save_room_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_DB (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--void
--matrix_db_load_room_async (MatrixDb *self,
-- ChattyAccount *account,
-- const char *account_device,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GTask *task;
-- const char *username;
--
-- g_return_if_fail (MATRIX_IS_DB (self));
-- g_return_if_fail (CHATTY_IS_ACCOUNT (account));
-- g_return_if_fail (room_id && *room_id == '!');
--
-- task = g_task_new (self, NULL, callback, user_data);
-- g_task_set_source_tag (task, matrix_db_load_room_async);
-- g_task_set_task_data (task, matrix_db_load_room, NULL);
--
-- username = chatty_item_get_username (CHATTY_ITEM (account));
-- g_object_set_data_full (G_OBJECT (task), "room", g_strdup (room_id), g_free);
-- g_object_set_data_full (G_OBJECT (task), "username", g_strdup (username), g_free);
-- g_object_set_data_full (G_OBJECT (task), "account-id", g_strdup (username), g_free);
-- g_object_set_data_full (G_OBJECT (task), "account", g_object_ref (account), g_object_unref);
-- g_object_set_data_full (G_OBJECT (task), "account-device", g_strdup (account_device), g_free);
--
-- g_async_queue_push (self->queue, task);
--}
--
--char *
--matrix_db_load_room_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_DB (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
--
-- return g_task_propagate_pointer (G_TASK (result), error);
--}
--
--void
--matrix_db_delete_account_async (MatrixDb *self,
-- ChattyAccount *account,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GTask *task;
-- const char *username;
--
-- g_return_if_fail (MATRIX_IS_DB (self));
-- g_return_if_fail (CHATTY_IS_ACCOUNT (account));
--
-- task = g_task_new (self, NULL, callback, user_data);
-- g_task_set_source_tag (task, matrix_db_delete_account_async);
-- g_task_set_task_data (task, matrix_db_delete_account, NULL);
--
-- username = chatty_item_get_username (CHATTY_ITEM (account));
-- g_object_set_data_full (G_OBJECT (task), "username", g_strdup (username), g_free);
-- g_object_set_data_full (G_OBJECT (task), "account", g_object_ref (account), g_object_unref);
--
-- g_async_queue_push (self->queue, task);
--}
--
--gboolean
--matrix_db_delete_account_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_DB (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
--
--void
--matrix_db_add_session_async (MatrixDb *self,
-- const char *account_id,
-- const char *account_device,
-- const char *room_id,
-- const char *session_id,
-- const char *sender_key,
-- char *pickle,
-- MatrixSessionType type,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GObject *object;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_DB (self));
-- g_return_if_fail (account_id && *account_id);
-- g_return_if_fail (account_device && *account_device);
-- g_return_if_fail (room_id && *room_id);
-- g_return_if_fail (session_id && *session_id);
-- g_return_if_fail (sender_key && *sender_key);
-- g_return_if_fail (pickle && *pickle);
--
-- task = g_task_new (self, NULL, callback, user_data);
-- g_task_set_source_tag (task, matrix_db_add_session_async);
-- g_task_set_task_data (task, matrix_db_add_session, NULL);
-- object = G_OBJECT (task);
--
-- g_object_set_data_full (object, "account-id", g_strdup (account_id), g_free);
-- g_object_set_data_full (object, "account-device", g_strdup (account_device), g_free);
-- g_object_set_data_full (object, "room-id", g_strdup (room_id), g_free);
-- g_object_set_data_full (object, "session-id", g_strdup (session_id), g_free);
-- g_object_set_data_full (object, "sender-key", g_strdup (sender_key), g_free);
-- g_object_set_data_full (object, "pickle", pickle, g_free);
-- g_object_set_data (object, "type", GINT_TO_POINTER (type));
--
-- g_async_queue_push (self->queue, task);
--}
--
--void
--matrix_db_save_file_url_async (MatrixDb *self,
-- ChattyMessage *message,
-- ChattyFileInfo *file,
-- int version,
-- int algorithm,
-- int type,
-- gboolean extractable,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GObject *object;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_DB (self));
-- g_return_if_fail (version == 2);
-- g_return_if_fail (extractable);
--
-- task = g_task_new (self, NULL, callback, user_data);
-- g_task_set_source_tag (task, matrix_db_save_file_url_async);
-- g_task_set_task_data (task, matrix_db_save_file_url, NULL);
-- object = G_OBJECT (task);
--
-- g_object_set_data (object, "file", file);
-- g_object_set_data_full (object, "message", g_object_ref (message), g_object_unref);
--
-- g_object_set_data (object, "type", GINT_TO_POINTER (type));
-- g_object_set_data (object, "version", GINT_TO_POINTER (version));
-- g_object_set_data (object, "algorithm", GINT_TO_POINTER (algorithm));
-- g_object_set_data (object, "extractable", GINT_TO_POINTER (extractable));
--
-- g_async_queue_push (self->queue, task);
--}
--
--char *
--matrix_db_lookup_session (MatrixDb *self,
-- const char *account_id,
-- const char *account_device,
-- const char *session_id,
-- const char *sender_key,
-- MatrixSessionType type)
--{
-- g_autoptr(GTask) task = NULL;
-- g_autoptr(GError) error = NULL;
-- GObject *object;
-- char *pickle;
--
-- g_return_val_if_fail (MATRIX_IS_DB (self), NULL);
-- g_return_val_if_fail (account_id && *account_id, NULL);
-- g_return_val_if_fail (account_device && *account_device, NULL);
-- g_return_val_if_fail (session_id && *session_id, NULL);
-- g_return_val_if_fail (sender_key && *sender_key, NULL);
--
-- task = g_task_new (self, NULL, NULL, NULL);
-- g_object_ref (task);
--
-- g_task_set_source_tag (task, matrix_db_lookup_session);
-- g_task_set_task_data (task, db_lookup_session, NULL);
-- object = G_OBJECT (task);
--
-- g_object_set_data_full (object, "account-id", g_strdup (account_id), g_free);
-- g_object_set_data_full (object, "account-device", g_strdup (account_device), g_free);
-- g_object_set_data_full (object, "session-id", g_strdup (session_id), g_free);
-- g_object_set_data_full (object, "sender-key", g_strdup (sender_key), g_free);
-- g_object_set_data (object, "type", GINT_TO_POINTER (type));
--
-- g_async_queue_push (self->queue, task);
-- g_assert (task);
--
-- /* Wait until the task is completed */
-- while (!g_task_get_completed (task))
-- g_main_context_iteration (NULL, TRUE);
--
-- pickle = g_task_propagate_pointer (task, &error);
--
-- if (error)
-- g_debug ("Error getting session: %s", error->message);
--
-- return pickle;
--}
--
--void
--matrix_db_get_olm_sessions_async (MatrixDb *self,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_DB (self));
--
-- task = g_task_new (self, NULL, callback, user_data);
-- g_task_set_source_tag (task, matrix_db_get_olm_sessions_async);
-- g_task_set_task_data (task, history_get_olm_sessions, NULL);
--
-- g_async_queue_push (self->queue, task);
--}
--
--GPtrArray *
--matrix_db_get_olm_sessions_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_DB (self), NULL);
-- g_return_val_if_fail (G_IS_TASK (result), NULL);
-- g_return_val_if_fail (!error || !*error, NULL);
--
-- return g_task_propagate_pointer (G_TASK (result), error);
--}
-diff --git a/src/matrix/matrix-db.h b/src/matrix/matrix-db.h
-deleted file mode 100644
-index 8a0ed253..00000000
---- a/src/matrix/matrix-db.h
-+++ /dev/null
-@@ -1,165 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-db.h
-- *
-- * Copyright 2020 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--#pragma once
--
--#include <glib.h>
--
--#include "chatty-account.h"
--#include "chatty-message.h"
--
--G_BEGIN_DECLS
--
--typedef struct {
-- char *sender;
-- char *sender_key;
-- char *session_pickle;
--} MatrixDbData;
--
--/* These values shouldn’t be changed. They are used in DB */
--typedef enum {
-- SESSION_OLM_V1_IN = 1,
-- SESSION_OLM_V1_OUT = 2,
-- SESSION_MEGOLM_V1_IN = 3,
-- SESSION_MEGOLM_V1_OUT = 4,
--} MatrixSessionType;
--
--#define CHATTY_ALGORITHM_A256CTR 1
--
--#define CHATTY_KEY_TYPE_OCT 1
--
--#define MATRIX_TYPE_DB (matrix_db_get_type ())
--
--G_DECLARE_FINAL_TYPE (MatrixDb, matrix_db, MATRIX, DB, GObject)
--
--MatrixDb *matrix_db_new (void);
--void matrix_db_open_async (MatrixDb *self,
-- char *dir,
-- const char *file_name,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_db_open_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--gboolean matrix_db_is_open (MatrixDb *self);
--void matrix_db_close_async (MatrixDb *self,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_db_close_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_db_save_account_async (MatrixDb *db,
-- ChattyAccount *account,
-- gboolean enabled,
-- char *pickle,
-- const char *device_id,
-- const char *next_batch,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_db_save_account_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_db_load_account_async (MatrixDb *db,
-- ChattyAccount *account,
-- const char *device_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_db_load_account_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_db_save_room_async (MatrixDb *self,
-- ChattyAccount *account,
-- const char *account_device,
-- const char *room_id,
-- const char *prev_batch,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_db_save_room_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_db_load_room_async (MatrixDb *self,
-- ChattyAccount *account,
-- const char *account_device,
-- const char *room_id,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--char *matrix_db_load_room_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_db_delete_account_async (MatrixDb *self,
-- ChattyAccount *account,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_db_delete_account_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_db_save_file_url_async (MatrixDb *self,
-- ChattyMessage *message,
-- ChattyFileInfo *file,
-- int version,
-- int algorithm,
-- int type,
-- gboolean extractable,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_db_save_file_url_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_db_add_session_async (MatrixDb *self,
-- const char *account_id,
-- const char *account_device,
-- const char *room_id,
-- const char *session_id,
-- const char *sender_key,
-- char *pickle,
-- MatrixSessionType type,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_db_add_session_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--char *matrix_db_lookup_session (MatrixDb *self,
-- const char *account_id,
-- const char *account_device,
-- const char *session_id,
-- const char *sender_key,
-- MatrixSessionType type);
--void matrix_db_get_olm_sessions_async (MatrixDb *self,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--GPtrArray *matrix_db_get_olm_sessions_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_db_add_olm_session_async (MatrixDb *self,
-- const char *sender,
-- const char *sender_key,
-- const char *pickle,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--GPtrArray *matrix_db_get_messages_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_db_get_group_in_sessions_async (MatrixDb *self,
-- guint limit,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--GPtrArray *matrix_db_group_in_sessions_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--void matrix_db_get_group_out_sessions_async (MatrixDb *self,
-- guint limit,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--GPtrArray *matrix_db_get_group_out_sessions_finish (MatrixDb *self,
-- GAsyncResult *result,
-- GError **error);
--
--G_END_DECLS
-diff --git a/src/matrix/matrix-enc.c b/src/matrix/matrix-enc.c
-deleted file mode 100644
-index 145c04c3..00000000
---- a/src/matrix/matrix-enc.c
-+++ /dev/null
-@@ -1,1330 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-enc.c
-- *
-- * Copyright 2020 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--#define G_LOG_DOMAIN "chatty-matrix-enc"
--
--#ifdef HAVE_CONFIG_H
--# include "config.h"
--#endif
--
--#include <json-glib/json-glib.h>
--#include <olm/olm.h>
--#include <sys/random.h>
--
--#include "chatty-settings.h"
--#include "chatty-ma-buddy.h"
--#include "matrix-utils.h"
--#include "matrix-db.h"
--#include "matrix-enc.h"
--#include "chatty-log.h"
--
--#define KEY_LABEL_SIZE 6
--#define STRING_ALLOCATION 512
--
--/**
-- * SECTION: chatty-contact
-- * @title: MatrixEnc
-- * @short_description: An abstraction over #FolksIndividual
-- * @include: "chatty-contact.h"
-- */
--
--/*
-- * Documentations:
-- * https://matrix.org/docs/guides/end-to-end-encryption-implementation-guide
-- *
-- * Other:
-- * * We use g_malloc(size) instead of g_malloc(size * sizeof(type)) for all ‘char’
-- * and ‘[u]int8_t’, unless there is a possibility that the type can change.
-- */
--struct _MatrixEnc
--{
-- GObject parent_instance;
--
-- OlmAccount *account;
-- OlmUtility *utility;
-- char *pickle_key;
--
-- GHashTable *in_olm_sessions;
-- GHashTable *out_olm_sessions;
-- GHashTable *in_group_sessions;
-- GHashTable *out_group_sessions;
--
-- /* Use something better, like sqlite */
-- MatrixDb *matrix_db;
--
-- char *user_id;
-- char *device_id;
--
-- char *curve_key; /* Public part of Curve25519 identity key */
-- char *ed_key; /* Public part of Ed25519 fingerprint key */
--};
--
--G_DEFINE_TYPE (MatrixEnc, matrix_enc, G_TYPE_OBJECT)
--
--static void
--free_olm_session (gpointer data)
--{
-- olm_clear_session (data);
-- g_free (data);
--}
--
--static void
--free_in_group_session (gpointer data)
--{
-- olm_clear_inbound_group_session (data);
-- g_free (data);
--}
--
--static void
--free_out_group_session (gpointer data)
--{
-- olm_clear_outbound_group_session (data);
-- g_free (data);
--}
--
--static void
--free_all_details (MatrixEnc *self)
--{
-- if (self->account)
-- olm_clear_account (self->account);
--
-- g_clear_pointer (&self->account, g_free);
-- g_hash_table_remove_all (self->in_olm_sessions);
-- g_hash_table_remove_all (self->out_olm_sessions);
-- g_hash_table_remove_all (self->in_group_sessions);
-- g_hash_table_remove_all (self->out_group_sessions);
--}
--
--static char *
--ma_olm_encrypt (OlmSession *session,
-- const char *plain_text)
--{
-- g_autofree char *encrypted = NULL;
-- g_autofree void *random = NULL;
-- size_t length, rand_len;
--
-- g_assert (session);
--
-- if (!plain_text)
-- return NULL;
--
-- rand_len = olm_encrypt_random_length (session);
-- random = g_malloc (rand_len);
-- getrandom (random, rand_len, GRND_NONBLOCK);
--
-- length = olm_encrypt_message_length (session, strlen (plain_text));
-- encrypted = g_malloc (length + 1);
-- length = olm_encrypt (session, plain_text, strlen (plain_text),
-- random, rand_len,
-- encrypted, length);
--
-- if (length == olm_error ()) {
-- g_warning ("Error encrypting: %s", olm_session_last_error (session));
--
-- return NULL;
-- }
-- encrypted[length] = '\0';
--
-- return g_steal_pointer (&encrypted);
--}
--
--static OlmSession *
--ma_create_olm_out_session (MatrixEnc *self,
-- const char *curve_key,
-- const char *one_time_key)
--{
-- g_autofree OlmSession *session = NULL;
-- g_autofree void *buffer = NULL;
-- size_t length, error;
--
-- g_assert (MATRIX_ENC (self));
--
-- if (!curve_key || !one_time_key)
-- return NULL;
--
-- session = g_malloc (olm_session_size ());
-- olm_session (session);
--
-- length = olm_create_outbound_session_random_length (session);
-- buffer = g_malloc (length);
-- getrandom (buffer, length, GRND_NONBLOCK);
--
-- error = olm_create_outbound_session (session,
-- self->account,
-- curve_key, strlen (curve_key),
-- one_time_key, strlen (one_time_key),
-- buffer, length);
-- olm_encrypt_message_type (session);
-- if (error == olm_error ()) {
-- g_warning ("Error creating outbound olm session: %s",
-- olm_session_last_error (session));
-- return NULL;
-- }
--
-- return g_steal_pointer (&session);
--}
--
--/*
-- * matrix_enc_load_identity_keys:
-- * @self: A #MatrixEnc
-- *
-- * Load the public part of Ed25519 fingerprint
-- * key pair and Curve25519 identity key pair.
-- */
--static void
--matrix_enc_load_identity_keys (MatrixEnc *self)
--{
-- g_autoptr(JsonParser) parser = NULL;
-- g_autoptr(GError) error = NULL;
-- g_autofree char *key = NULL;
-- JsonObject *object;
-- JsonNode *node;
-- size_t length, err;
--
-- length = olm_account_identity_keys_length (self->account);
-- key = malloc (length + 1);
-- err = olm_account_identity_keys (self->account, key, length);
-- key[length] = '\0';
--
-- if (err == olm_error ()) {
-- g_warning ("error getting identity keys: %s", olm_account_last_error (self->account));
-- return;
-- }
--
-- parser = json_parser_new ();
-- json_parser_load_from_data (parser, key, length, &error);
--
-- if (error) {
-- g_warning ("error parsing keys: %s", error->message);
-- return;
-- }
--
-- node = json_parser_get_root (parser);
-- object = json_node_get_object (node);
--
-- g_free (self->curve_key);
-- g_free (self->ed_key);
--
-- self->curve_key = g_strdup (json_object_get_string_member (object, "curve25519"));
-- self->ed_key = g_strdup (json_object_get_string_member (object, "ed25519"));
--}
--
--static void
--create_new_details (MatrixEnc *self)
--{
-- g_autofree void *buffer = NULL;
-- size_t length, err;
--
-- g_assert (MATRIX_ENC (self));
--
-- CHATTY_TRACE_MSG ("Creating new encryption keys");
--
-- free_all_details (self);
--
-- self->account = g_malloc (olm_account_size ());
-- olm_account (self->account);
--
-- matrix_utils_free_buffer (self->pickle_key);
-- self->pickle_key = g_uuid_string_random ();
--
-- length = olm_create_account_random_length (self->account);
-- buffer = g_malloc (length);
-- getrandom (buffer, length, GRND_NONBLOCK);
-- err = olm_create_account (self->account, buffer, length);
-- if (err == olm_error ())
-- g_warning ("Error creating account: %s", olm_account_last_error (self->account));
--}
--
--static void
--matrix_enc_sign_json_object (MatrixEnc *self,
-- JsonObject *object)
--{
-- g_autoptr(GString) str = NULL;
-- g_autofree char *signature = NULL;
-- g_autofree char *label = NULL;
-- JsonObject *sign, *child;
--
-- g_assert (MATRIX_IS_ENC (self));
-- g_assert (object);
--
-- /* The JSON is in canonical form. Required for signing */
-- /* https://matrix.org/docs/spec/appendices#signing-json */
-- str = matrix_utils_json_get_canonical (object, NULL);
-- signature = matrix_enc_sign_string (self, str->str, str->len);
--
-- sign = json_object_new ();
-- label = g_strconcat ("ed25519:", self->device_id, NULL);
-- json_object_set_string_member (sign, label, signature);
--
-- child = json_object_new ();
-- json_object_set_object_member (child, self->user_id, sign);
-- json_object_set_object_member (object, "signatures", child);
--}
--
--static void
--matrix_enc_finalize (GObject *object)
--{
-- MatrixEnc *self = (MatrixEnc *)object;
--
-- olm_clear_account (self->account);
-- g_free (self->account);
--
-- olm_clear_utility (self->utility);
-- g_free (self->utility);
--
-- g_hash_table_unref (self->in_olm_sessions);
-- g_hash_table_unref (self->out_olm_sessions);
-- g_hash_table_unref (self->in_group_sessions);
-- g_hash_table_unref (self->out_group_sessions);
-- g_free (self->user_id);
-- g_free (self->device_id);
-- matrix_utils_free_buffer (self->pickle_key);
-- matrix_utils_free_buffer (self->curve_key);
-- matrix_utils_free_buffer (self->ed_key);
-- g_clear_object (&self->matrix_db);
--
-- G_OBJECT_CLASS (matrix_enc_parent_class)->finalize (object);
--}
--
--
--static void
--matrix_enc_class_init (MatrixEncClass *klass)
--{
-- GObjectClass *object_class = G_OBJECT_CLASS (klass);
--
-- object_class->finalize = matrix_enc_finalize;
--}
--
--
--static void
--matrix_enc_init (MatrixEnc *self)
--{
-- self->utility = g_malloc (olm_utility_size ());
-- olm_utility (self->utility);
--
-- self->in_olm_sessions = g_hash_table_new_full (g_str_hash, g_str_equal,
-- g_free, free_olm_session);
-- self->out_olm_sessions = g_hash_table_new_full (g_str_hash, g_str_equal,
-- g_free, free_olm_session);
-- self->in_group_sessions = g_hash_table_new_full (g_str_hash, g_str_equal,
-- g_free, free_in_group_session);
-- self->out_group_sessions = g_hash_table_new_full (g_str_hash, g_str_equal,
-- g_free, free_out_group_session);
--}
--
--/**
-- * matrix_enc_new:
-- * @pickle: (nullable): The account pickle
-- * @key: @pickle key, can be %NULL if @pickle is %NULL
-- *
-- * If @pickle is non-null, the olm account is created
-- * using the pickled data. Otherwise a new olm account
-- * is created. If @pickle is non-null and invalid
-- * %NULL is returned.
-- *
-- * For @self to be ready for use, the details of @self
-- * should be set with matrix_enc_set_details().
-- *
-- * Also see matrix_enc_get_pickle().
-- *
-- * Returns: (transfer full) (nullable): A new #MatrixEnc.
-- * Free with g_object_unref()
-- */
--MatrixEnc *
--matrix_enc_new (gpointer matrix_db,
-- const char *pickle,
-- const char *key)
--{
-- g_autoptr(MatrixEnc) self = NULL;
--
-- g_return_val_if_fail (!pickle || (*pickle && key && *key), NULL);
--
-- self = g_object_new (MATRIX_TYPE_ENC, NULL);
-- g_set_object (&self->matrix_db, matrix_db);
--
-- /* Deserialize the pickle to create the account */
-- if (pickle && *pickle) {
-- g_autofree char *duped = NULL;
-- size_t err;
--
-- self->pickle_key = g_strdup (key);
-- self->account = g_malloc (olm_account_size ());
-- olm_account (self->account);
--
-- duped = g_strdup (pickle);
-- err = olm_unpickle_account (self->account, key, strlen (key),
-- duped, strlen (duped));
--
-- if (err == olm_error ()) {
-- g_warning ("Error account unpickle: %s", olm_account_last_error (self->account));
-- return NULL;
-- }
-- } else {
-- create_new_details (self);
-- }
--
-- matrix_enc_load_identity_keys (self);
--
-- return g_steal_pointer (&self);
--}
--
--/**
-- * matrix_enc_set_details:
-- * @self: A #MatrixEnc
-- * @user_id: Fully qualified Matrix user ID
-- * @device_id: The device id string
-- *
-- * Set user id and device id of @self. @user_id
-- * should be fully qualified Matrix user ID
-- * (ie, @user:example.com)
-- */
--void
--matrix_enc_set_details (MatrixEnc *self,
-- const char *user_id,
-- const char *device_id)
--{
-- g_autofree char *old_user = NULL;
-- g_autofree char *old_device = NULL;
--
-- g_return_if_fail (MATRIX_IS_ENC (self));
-- g_return_if_fail (!user_id || *user_id == '@');
--
-- old_user = self->user_id;
-- old_device = self->device_id;
--
-- self->user_id = g_strdup (user_id);
-- self->device_id = g_strdup (device_id);
--
-- if (self->user_id && old_device &&
-- g_strcmp0 (device_id, old_device) == 0) {
-- create_new_details (self);
-- matrix_enc_load_identity_keys (self);
-- }
--}
--
--char *
--matrix_enc_get_account_pickle (MatrixEnc *self)
--{
-- g_autofree char *pickle = NULL;
-- size_t length, err;
--
-- g_return_val_if_fail (MATRIX_IS_ENC (self), NULL);
--
-- length = olm_pickle_account_length (self->account);
-- pickle = malloc (length + 1);
-- err = olm_pickle_account (self->account, self->pickle_key,
-- strlen (self->pickle_key), pickle, length);
-- pickle[length] = '\0';
--
-- if (err == olm_error ()) {
-- g_warning ("Error getting account pickle: %s", olm_account_last_error (self->account));
--
-- return NULL;
-- }
--
-- return g_steal_pointer (&pickle);
--}
--
--char *
--matrix_enc_get_pickle_key (MatrixEnc *self)
--{
-- g_return_val_if_fail (MATRIX_ENC (self), NULL);
--
-- return g_strdup (self->pickle_key);
--}
--
--/**
-- * matrix_enc_sign_string:
-- * @self: A #MatrixEnc
-- * @str: A string to sign
-- * @len: The length of @str, or -1
-- *
-- * Sign @str and return the signature.
-- * Returns %NULL on error.
-- *
-- * Returns: (transfer full): The signature string.
-- * Free with g_free()
-- */
--char *
--matrix_enc_sign_string (MatrixEnc *self,
-- const char *str,
-- size_t len)
--{
-- char *signature;
-- size_t length, err;
--
-- g_return_val_if_fail (MATRIX_IS_ENC (self), NULL);
-- g_return_val_if_fail (str, NULL);
-- g_return_val_if_fail (*str, NULL);
--
-- if (len == (size_t) -1)
-- len = strlen (str);
--
-- length = olm_account_signature_length (self->account);
-- signature = malloc (length + 1);
-- err = olm_account_sign (self->account, str, len, signature, length);
-- signature[length] = '\0';
--
-- if (err == olm_error ()) {
-- g_warning ("Error signing data: %s", olm_account_last_error (self->account));
--
-- return NULL;
-- }
--
-- return signature;
--}
--
--/**
-- * matrix_enc_verify:
-- * @self: A #MatrixEnc
-- * @object: A #JsonObject
-- * @matrix_id: A Fully qualified Matrix ID
-- * @device_id: The device id string.
-- * @ed_key: The ED25519 key of @matrix_id
-- *
-- * Verify if the content in @object is signed by
-- * the user @matrix_id with device @device_id.
-- *
-- * This function may modify @object by removing
-- * "signatures" and "unsigned" members.
-- *
-- * Returns; %TRUE if verification succeeded. Or
-- * %FALSE otherwise.
-- */
--gboolean
--matrix_enc_verify (MatrixEnc *self,
-- JsonObject *object,
-- const char *matrix_id,
-- const char *device_id,
-- const char *ed_key)
--{
-- JsonNode *signatures, *non_signed;
-- g_autoptr(GString) json_str = NULL;
-- g_autofree char *signature = NULL;
-- g_autofree char *key_name = NULL;
-- JsonObject *child;
-- size_t error;
--
-- if (!object)
-- return FALSE;
--
-- g_return_val_if_fail (MATRIX_IS_ENC (self), FALSE);
-- g_return_val_if_fail (matrix_id && *matrix_id == '@', FALSE);
-- g_return_val_if_fail (device_id && *device_id, FALSE);
-- g_return_val_if_fail (ed_key && *ed_key, FALSE);
--
-- /* https://matrix.org/docs/spec/appendices#checking-for-a-signature */
-- key_name = g_strconcat ("ed25519:", device_id, NULL);
-- child = matrix_utils_json_object_get_object (object, "signatures");
-- child = matrix_utils_json_object_get_object (child, matrix_id);
-- signature = g_strdup (matrix_utils_json_object_get_string (child, key_name));
--
-- if (!signature)
-- return FALSE;
--
-- signatures = json_object_dup_member (object, "signatures");
-- non_signed = json_object_dup_member (object, "signatures");
-- json_object_remove_member (object, "signatures");
-- json_object_remove_member (object, "unsigned");
--
-- json_str = matrix_utils_json_get_canonical (object, NULL);
--
-- if (signatures)
-- json_object_set_member (object, "signatures", signatures);
-- if (non_signed)
-- json_object_set_member (object, "unsigned", non_signed);
--
-- error = olm_ed25519_verify (self->utility,
-- ed_key, ED25519_SIZE,
-- json_str->str, json_str->len,
-- signature, strlen (signature));
--
-- /* XXX: the libolm documentation is not much clear on this */
-- if (error == olm_error ()) {
-- g_debug ("Error verifying signature: %s", olm_utility_last_error (self->utility));
-- return FALSE;
-- }
--
-- return TRUE;
--}
--
--/**
-- * matrix_enc_max_one_time_keys:
-- * @self: A #MatrixEnc
-- *
-- * Get the maximum number of one time keys Olm
-- * library can handle.
-- *
-- * Returns: The number of maximum one-time keys.
-- */
--size_t
--matrix_enc_max_one_time_keys (MatrixEnc *self)
--{
-- g_return_val_if_fail (MATRIX_IS_ENC (self), 0);
--
-- return olm_account_max_number_of_one_time_keys (self->account);
--}
--
--/**
-- * matrix_enc_create_one_time_keys:
-- * @self: A #MatrixEnc
-- * @count: A non-zero number
-- *
-- * Generate @count number of curve25519 one time keys.
-- * @count is capped to the half of what Olm library
-- * can handle.
-- *
-- * Returns: The number of one-time keys generated.
-- * It will be <= @count.
-- */
--size_t
--matrix_enc_create_one_time_keys (MatrixEnc *self,
-- size_t count)
--{
-- g_autofree void *buffer = NULL;
-- size_t length, err;
--
-- g_return_val_if_fail (MATRIX_IS_ENC (self), 0);
-- g_return_val_if_fail (count, 0);
--
-- /* doc: The maximum number of active keys supported by libolm
-- is returned by olm_account_max_number_of_one_time_keys.
-- The client should try to maintain about half this number on the homeserver. */
-- count = MIN (count, olm_account_max_number_of_one_time_keys (self->account) / 2);
--
-- length = olm_account_generate_one_time_keys_random_length (self->account, count);
-- buffer = g_malloc (length);
-- getrandom (buffer, length, GRND_NONBLOCK);
-- err = olm_account_generate_one_time_keys (self->account, count, buffer, length);
--
-- if (err == olm_error ()) {
-- g_warning ("Error creating one time keys: %s", olm_account_last_error (self->account));
--
-- return 0;
-- }
--
-- return count;
--}
--
--/**
-- * matrix_enc_publish_one_time_keys:
-- * @self: A #MatrixEnc
-- *
-- * Mark current set of one-time keys as published
-- */
--void
--matrix_enc_publish_one_time_keys (MatrixEnc *self)
--{
--
-- g_return_if_fail (MATRIX_IS_ENC (self));
--
-- olm_account_mark_keys_as_published (self->account);
--}
--
--/**
-- * matrix_enc_get_one_time_keys:
-- * @self: A #MatrixEnc
-- *
-- * Get public part of unpublished Curve25519 one-time keys in @self.
-- *
-- * The returned data is a JSON-formatted object with the single
-- * property curve25519, which is itself an object mapping key id
-- * to base64-encoded Curve25519 key. For example:
-- *
-- * {
-- * "curve25519": {
-- * "AAAAAA": "wo76WcYtb0Vk/pBOdmduiGJ0wIEjW4IBMbbQn7aSnTo",
-- * "AAAAAB": "LRvjo46L1X2vx69sS9QNFD29HWulxrmW11Up5AfAjgU"
-- * }
-- * }
-- *
-- * Returns: (nullable) (transfer full): The unpublished one time keys.
-- * Free with g_free()
-- */
--JsonObject *
--matrix_enc_get_one_time_keys (MatrixEnc *self)
--{
-- g_autoptr(JsonParser) parser = NULL;
-- g_autoptr(GError) error = NULL;
-- g_autofree char *buffer = NULL;
-- size_t length, err;
--
-- g_return_val_if_fail (MATRIX_IS_ENC (self), NULL);
--
-- length = olm_account_one_time_keys_length (self->account);
-- buffer = g_malloc (length + 1);
-- err = olm_account_one_time_keys (self->account, buffer, length);
-- buffer[length] = '\0';
--
-- if (err == olm_error ()) {
-- g_warning ("Error getting one time keys: %s", olm_account_last_error (self->account));
--
-- return NULL;
-- }
--
-- /* Return NULL if there are no keys */
-- if (g_str_equal (buffer, "{\"curve25519\":{}}"))
-- return NULL;
--
-- parser = json_parser_new ();
-- json_parser_load_from_data (parser, buffer, length, &error);
--
-- if (error) {
-- g_warning ("error parsing keys: %s", error->message);
-- return NULL;
-- }
--
-- return json_node_dup_object (json_parser_get_root (parser));
--}
--
--/**
-- * matrix_enc_get_one_time_keys_json:
-- * @self: A #MatrixEnc
-- *
-- * Get the signed Curve25519 one-time keys JSON. The JSON shall
-- * be in the following format:
-- *
-- * {
-- * "signed_curve25519:AAAAHg": {
-- * "key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs",
-- * "signatures": {
-- * "@alice:example.com": {
-- * "ed25519:JLAFKJWSCS": "FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw"
-- * }
-- * }
-- * },
-- * "signed_curve25519:AAAAHQ": {
-- * "key": "j3fR3HemM16M7CWhoI4Sk5ZsdmdfQHsKL1xuSft6MSw",
-- * "signatures": {
-- * "@alice:example.com": {
-- * "ed25519:JLAFKJWSCS": "IQeCEPb9HFk217cU9kw9EOiusC6kMIkoIRnbnfOh5Oc63S1ghgyjShBGpu34blQomoalCyXWyhaaT3MrLZYQAA"
-- * }
-- * }
-- * }
-- * }
-- *
-- * Returns: (transfer full): A JSON encoded string.
-- * Free with g_free()
-- */
--char *
--matrix_enc_get_one_time_keys_json (MatrixEnc *self)
--{
-- g_autoptr(JsonObject) object = NULL;
-- g_autoptr(JsonObject) root = NULL;
-- g_autoptr(GList) members = NULL;
-- JsonObject *keys, *child;
--
-- g_return_val_if_fail (MATRIX_IS_ENC (self), NULL);
--
-- object = matrix_enc_get_one_time_keys (self);
--
-- if (!object)
-- return NULL;
--
-- keys = json_object_new ();
-- object = json_object_get_object_member (object, "curve25519");
-- members = json_object_get_members (object);
--
-- for (GList *item = members; item; item = item->next) {
-- g_autofree char *label = NULL;
-- const char *value;
--
-- child = json_object_new ();
-- value = json_object_get_string_member (object, item->data);
-- json_object_set_string_member (child, "key", value);
-- matrix_enc_sign_json_object (self, child);
--
-- label = g_strconcat ("signed_curve25519:", item->data, NULL);
-- json_object_set_object_member (keys, label, child);
-- }
--
-- root = json_object_new ();
-- json_object_set_object_member (root, "one_time_keys", keys);
--
-- return matrix_utils_json_object_to_string (root, FALSE);
--}
--
--/**
-- * matrix_enc_get_one_time_keys:
-- * @self: A #MatrixEnc
-- *
-- * Get the signed device key JSON. The JSON shall
-- * be in the following format:
-- *
-- * {
-- * "user_id": "@alice:example.com",
-- * "device_id": "JLAFKJWSCS",
-- * "algorithms": [
-- * "m.olm.curve25519-aes-sha256",
-- * "m.megolm.v1.aes-sha2"
-- * ],
-- * "keys": {
-- * "curve25519:JLAFKJWSCS": "3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI",
-- * "ed25519:JLAFKJWSCS": "lEuiRJBit0IG6nUf5pUzWTUEsRVVe/HJkoKuEww9ULI"
-- * },
-- * "signatures": {
-- * "@alice:example.com": {
-- * "ed25519:JLAFKJWSCS": "dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA"
-- * }
-- * }
-- * }
-- *
-- * Returns: (nullable): A JSON encoded string.
-- * Free with g_free()
-- */
--char *
--matrix_enc_get_device_keys_json (MatrixEnc *self)
--{
-- g_autoptr(JsonObject) root = NULL;
-- JsonObject *keys, *device_keys;
-- JsonArray *array;
-- char *label;
--
-- g_return_val_if_fail (MATRIX_IS_ENC (self), NULL);
-- g_return_val_if_fail (self->user_id, NULL);
-- g_return_val_if_fail (self->device_id, NULL);
--
-- device_keys = json_object_new ();
-- json_object_set_string_member (device_keys, "user_id", self->user_id);
-- json_object_set_string_member (device_keys, "device_id", self->device_id);
--
-- array = json_array_new ();
-- json_array_add_string_element (array, ALGORITHM_OLM);
-- json_array_add_string_element (array, ALGORITHM_MEGOLM);
-- json_object_set_array_member (device_keys, "algorithms", array);
--
-- keys = json_object_new ();
--
-- label = g_strconcat ("curve25519:", self->device_id, NULL);
-- json_object_set_string_member (keys, label, self->curve_key);
-- g_free (label);
--
-- label = g_strconcat ("ed25519:", self->device_id, NULL);
-- json_object_set_string_member (keys, label, self->ed_key);
-- g_free (label);
--
-- json_object_set_object_member (device_keys, "keys", keys);
-- matrix_enc_sign_json_object (self, device_keys);
--
-- root = json_object_new ();
-- json_object_set_object_member (root, "device_keys", device_keys);
--
-- return matrix_utils_json_object_to_string (root, FALSE);
--}
--
--static gboolean
--in_olm_matches (gpointer key,
-- gpointer value,
-- gpointer user_data)
--{
-- g_autofree char *body = NULL;
-- size_t match;
--
-- body = g_strdup (user_data);
-- match = olm_matches_inbound_session (value, body, strlen (body));
--
-- if (match == olm_error ()) {
-- g_warning ("Error matching inbound session: %s", olm_session_last_error (key));
-- return FALSE;
-- }
--
-- return match;
--}
--
--static void
--handle_m_room_key (MatrixEnc *self,
-- JsonObject *root,
-- const char *sender_key)
--{
-- g_autofree OlmInboundGroupSession *session = NULL;
-- JsonObject *object;
-- const char *session_key, *session_id, *room_id;
--
-- g_assert (MATRIX_IS_ENC (self));
-- g_assert (root);
--
-- session = g_malloc (olm_inbound_group_session_size ());
-- olm_inbound_group_session (session);
--
-- object = matrix_utils_json_object_get_object (root, "content");
-- session_key = matrix_utils_json_object_get_string (object, "session_key");
-- session_id = matrix_utils_json_object_get_string (object, "session_id");
-- room_id = matrix_utils_json_object_get_string (object, "room_id");
--
-- if (session_key) {
-- size_t error;
--
-- error = olm_init_inbound_group_session (session, (gpointer)session_key,
-- strlen (session_key));
-- if (error == olm_error ())
-- g_warning ("Error creating group session from key: %s", olm_inbound_group_session_last_error (session));
--
-- if (!error) {
-- g_autofree char *pickle = NULL;
-- int length;
--
-- length = olm_pickle_inbound_group_session_length (session);
-- pickle = g_malloc (length + 1);
-- olm_pickle_inbound_group_session (session, self->pickle_key,
-- strlen (self->pickle_key),
-- pickle, length);
-- pickle[length] = '\0';
-- CHATTY_TRACE (room_id, "saving session, room id: ");
-- if (self->matrix_db)
-- matrix_db_add_session_async (self->matrix_db, self->user_id, self->device_id,
-- room_id, session_id, sender_key,
-- g_steal_pointer (&pickle),
-- SESSION_MEGOLM_V1_IN, NULL, NULL);
-- g_hash_table_insert (self->in_group_sessions, g_strdup (session_id),
-- g_steal_pointer (&session));
--
-- }
-- }
--}
--
--void
--matrix_enc_handle_room_encrypted (MatrixEnc *self,
-- JsonObject *object)
--{
-- const char *algorithm, *sender, *sender_key;
-- g_autofree char *plaintext = NULL;
-- g_autofree char *body = NULL;
-- g_autofree char *copy = NULL;
-- OlmSession *session;
-- size_t error, length;
-- int type;
--
-- g_return_if_fail (MATRIX_IS_ENC (self));
-- g_return_if_fail (object);
--
-- sender = matrix_utils_json_object_get_string (object, "sender");
-- object = matrix_utils_json_object_get_object (object, "content");
-- algorithm = matrix_utils_json_object_get_string (object, "algorithm");
-- sender_key = matrix_utils_json_object_get_string (object, "sender_key");
--
-- if (!algorithm || !sender_key || !sender)
-- g_return_if_reached ();
--
-- if (!g_str_equal (algorithm, ALGORITHM_MEGOLM) &&
-- !g_str_equal (algorithm, ALGORITHM_OLM))
-- g_return_if_reached ();
--
-- object = matrix_utils_json_object_get_object (object, "ciphertext");
-- object = matrix_utils_json_object_get_object (object, self->curve_key);
--
-- body = g_strdup (matrix_utils_json_object_get_string (object, "body"));
-- type = matrix_utils_json_object_get_int (object, "type");
--
-- if (!body)
-- return;
--
-- if (type == OLM_MESSAGE_TYPE_PRE_KEY) {
-- session = g_hash_table_find (self->in_olm_sessions, in_olm_matches, body);
-- CHATTY_TRACE_MSG ("message with pre key received, session exits: %d", !!session);
--
-- if (!session) {
-- g_autofree char *body_copy = NULL;
-- session = g_malloc (olm_session_size ());
-- olm_session (session);
--
-- body_copy = g_strdup (body);
-- error = olm_create_inbound_session_from (session, self->account,
-- sender_key, strlen (sender_key),
-- body_copy, strlen (body_copy));
-- if (error == olm_error ()) {
-- g_warning ("Error creating session: %s", olm_session_last_error (session));
-- free_olm_session (session);
--
-- return;
-- }
--
-- /* Remove old used keys */
-- error = olm_remove_one_time_keys (self->account, session);
-- if (error == olm_error ())
-- g_warning ("Error removing key: %s", olm_account_last_error (self->account));
--
-- g_hash_table_insert (self->in_olm_sessions, g_strdup (sender_key), session);
-- }
-- } else {
-- CHATTY_TRACE_MSG ("normal message received ");
--
-- session = g_hash_table_lookup (self->in_olm_sessions, sender_key);
--
-- if (!session)
-- session = g_hash_table_lookup (self->out_olm_sessions, sender_key);
--
-- if (!session) {
-- g_warning ("Couldn't find session for normal message");
-- return;
-- }
-- }
--
-- copy = g_strdup (body);
-- length = olm_decrypt_max_plaintext_length (session, type, copy, strlen (copy));
--
-- if (length == olm_error ()) {
-- g_warning ("Error getting max length: %s", olm_session_last_error (session));
--
-- return;
-- }
--
-- plaintext = g_malloc (length + 1);
-- length = olm_decrypt (session, type, body, strlen (body), plaintext, length);
-- if (length == olm_error ()) {
-- g_warning ("Error decrypt session: %s", olm_session_last_error (session));
--
-- return;
-- }
--
-- plaintext[length] = '\0';
-- if (plaintext) {
-- g_autoptr(JsonObject) content = NULL;
-- const char *message_type;
--
-- content = matrix_utils_string_to_json_object (plaintext);
-- message_type = matrix_utils_json_object_get_string (content, "type");
--
-- CHATTY_TRACE_MSG ("message decrypted. type: %s", message_type);
--
-- if (g_strcmp0 (sender, matrix_utils_json_object_get_string (content, "sender")) != 0) {
-- g_warning ("Sender mismatch in encrypted content");
-- return;
-- }
--
-- if (g_strcmp0 (message_type, "m.room_key") == 0)
-- handle_m_room_key (self, content, sender_key);
-- }
--}
--
--char *
--matrix_enc_handle_join_room_encrypted (MatrixEnc *self,
-- const char *room_id,
-- JsonObject *object)
--{
-- OlmInboundGroupSession *session = NULL;
-- const char *sender_key;
-- const char *ciphertext, *session_id;
-- g_autofree char *plaintext = NULL;
-- char *body;
-- size_t length;
--
-- g_return_val_if_fail (MATRIX_IS_ENC (self), NULL);
-- g_return_val_if_fail (object, NULL);
--
-- sender_key = matrix_utils_json_object_get_string (object, "sender_key");
--
-- ciphertext = matrix_utils_json_object_get_string (object, "ciphertext");
-- session_id = matrix_utils_json_object_get_string (object, "session_id");
-- g_return_val_if_fail (ciphertext, NULL);
--
-- if (session_id)
-- session = g_hash_table_lookup (self->in_group_sessions, session_id);
--
-- CHATTY_TRACE_MSG ("Got room encrypted. session exits: %d", !!session);
--
-- if (!session) {
-- g_autofree char *pickle = NULL;
--
-- if (self->matrix_db)
-- pickle = matrix_db_lookup_session (self->matrix_db, self->user_id,
-- self->device_id, session_id,
-- sender_key, SESSION_MEGOLM_V1_IN);
-- if (pickle) {
-- int err;
-- session = g_malloc (olm_inbound_group_session_size ());
-- err = olm_unpickle_inbound_group_session (session, self->pickle_key,
-- strlen (self->pickle_key),
-- pickle, strlen (pickle));
-- if (err == olm_error ()) {
-- g_debug ("Error in group unpickle: %s", olm_inbound_group_session_last_error (session));
-- g_free (session);
-- session = NULL;
-- } else {
-- g_hash_table_insert (self->in_group_sessions, g_strdup (session_id), session);
-- CHATTY_TRACE_MSG ("Got session from matrix db");
-- }
-- }
-- }
--
-- if (!session)
-- return NULL;
--
-- g_return_val_if_fail (session, NULL);
--
-- body = g_strdup (ciphertext);
-- length = olm_group_decrypt_max_plaintext_length (session, (gpointer)body, strlen (body));
-- g_free (body);
--
-- plaintext = g_malloc (length + 1);
-- body = g_strdup (ciphertext);
-- length = olm_group_decrypt (session, (gpointer)body, strlen (body),
-- (gpointer)plaintext, length, NULL);
-- g_free (body);
--
-- if (length == olm_error ()) {
-- g_warning ("Error decrypting: %s", olm_inbound_group_session_last_error (session));
-- return NULL;
-- }
--
-- plaintext[length] = '\0';
--
-- return g_steal_pointer (&plaintext);
--}
--
--JsonObject *
--matrix_enc_encrypt_for_chat (MatrixEnc *self,
-- const char *room_id,
-- const char *message)
--{
-- OlmOutboundGroupSession *session;
-- g_autofree char *encrypted = NULL;
-- g_autofree char *session_id = NULL;
-- JsonObject *root;
-- size_t message_len, length;
--
-- g_return_val_if_fail (MATRIX_IS_ENC (self), NULL);
-- g_return_val_if_fail (message && *message, NULL);
--
-- session = g_hash_table_lookup (self->out_group_sessions, room_id);
-- g_return_val_if_fail (session, NULL);
--
-- message_len = strlen (message);
-- length = olm_group_encrypt_message_length (session, message_len);
-- encrypted = g_malloc (length + 1);
-- length = olm_group_encrypt (session, (gpointer)message, message_len,
-- (gpointer)encrypted, length);
--
-- if (length == olm_error ()) {
-- g_warning ("Error encryption: %s", olm_outbound_group_session_last_error (session));
-- return NULL;
-- }
--
-- encrypted[length] = '\0';
--
-- length = olm_outbound_group_session_id_length (session);
-- session_id = g_malloc (length + 1);
-- length = olm_outbound_group_session_id (session, (gpointer)session_id, length);
-- session_id[length] = '\0';
--
-- root = json_object_new ();
-- json_object_set_string_member (root, "algorithm", ALGORITHM_MEGOLM);
-- json_object_set_string_member (root, "sender_key", self->curve_key);
-- json_object_set_string_member (root, "ciphertext", encrypted);
-- json_object_set_string_member (root, "session_id", session_id);
-- json_object_set_string_member (root, "device_id", self->device_id);
--
-- return root;
--}
--
--JsonObject *
--matrix_enc_create_out_group_keys (MatrixEnc *self,
-- const char *room_id,
-- GListModel *members_list)
--{
-- g_autofree OlmOutboundGroupSession *session = NULL;
-- g_autofree uint8_t *session_key = NULL;
-- g_autofree uint8_t *session_id = NULL;
-- g_autofree uint8_t *random = NULL;
-- JsonObject *root, *child;
-- BuddyDevice *device;
-- size_t length;
-- size_t error;
--
-- g_return_val_if_fail (MATRIX_IS_ENC (self), FALSE);
--
-- /* Return early if the chat has an existing outbound group session */
-- if (g_hash_table_contains (self->out_group_sessions, room_id))
-- return NULL;
--
-- /* Initialize session */
-- session = g_malloc (olm_outbound_group_session_size ());
-- olm_outbound_group_session (session);
--
-- /* Feed in random bits */
-- length = olm_init_outbound_group_session_random_length (session);
-- random = g_malloc (length);
-- getrandom (random, length, GRND_NONBLOCK);
-- error = olm_init_outbound_group_session (session, random, length);
-- if (error == olm_error ()) {
-- g_warning ("Error init out group session: %s", olm_outbound_group_session_last_error (session));
--
-- return NULL;
-- }
--
-- /* Get session id */
-- length = olm_outbound_group_session_id_length (session);
-- session_id = g_malloc (length + 1);
-- length = olm_outbound_group_session_id (session, session_id, length);
-- if (length == olm_error ()) {
-- g_warning ("Error decrypt session: %s", olm_outbound_group_session_last_error (session));
--
-- return NULL;
-- }
-- session_id[length] = '\0';
--
-- /* Get session key */
-- length = olm_outbound_group_session_key_length (session);
-- session_key = g_malloc (length + 1);
-- length = olm_outbound_group_session_key (session, session_key, length);
-- if (length == olm_error ()) {
-- g_warning ("Error getting session key: %s", olm_outbound_group_session_last_error (session));
--
-- return NULL;
-- }
-- session_key[length] = '\0';
--
-- root = json_object_new ();
--
-- /* https://matrix.org/docs/spec/client_server/r0.6.1#m-room-key */
-- for (guint i = 0; i < g_list_model_get_n_items (members_list); i++) {
-- g_autoptr(ChattyMaBuddy) buddy = NULL;
-- g_autoptr(GList) devices = NULL;
-- const char *curve_key/* , *ed_key */;
-- JsonObject *user;
--
-- buddy = g_list_model_get_item (members_list, i);
-- devices = chatty_ma_buddy_get_devices (buddy);
--
-- user = json_object_new ();
-- json_object_set_object_member (root, chatty_item_get_username (CHATTY_ITEM (buddy)), user);
--
-- for (GList *node = devices; node; node = node->next) {
-- OlmSession *olm_session = NULL;
-- g_autofree char *one_time_key = NULL;
-- JsonObject *content;
--
-- device = node->data;
-- curve_key = chatty_ma_device_get_curve_key (device);
--
-- one_time_key = chatty_ma_device_get_one_time_key (device);
-- olm_session = ma_create_olm_out_session (self, curve_key, one_time_key);
--
-- if (!one_time_key || !curve_key || !olm_session)
-- continue;
--
-- g_hash_table_insert (self->out_olm_sessions, g_strdup (curve_key), olm_session);
--
-- /* Create per device object */
-- child = json_object_new ();
-- json_object_set_object_member (user, chatty_ma_device_get_id (device), child);
--
-- json_object_set_string_member (child, "algorithm", ALGORITHM_OLM);
-- json_object_set_string_member (child, "sender_key", self->curve_key);
-- json_object_set_object_member (child, "ciphertext", json_object_new ());
--
-- content = json_object_new ();
-- child = json_object_get_object_member (child, "ciphertext");
-- g_assert (child);
-- json_object_set_object_member (child, curve_key, content);
--
-- /* Body to be encrypted */
-- {
-- g_autoptr(JsonObject) object = NULL;
-- g_autofree char *encrypted = NULL;
-- g_autofree char *data = NULL;
--
-- /* Create a json object with common data */
-- object = json_object_new ();
-- json_object_set_string_member (object, "type", "m.room_key");
-- json_object_set_string_member (object, "sender", self->user_id);
-- json_object_set_string_member (object, "sender_device", self->device_id);
--
-- child = json_object_new ();
-- json_object_set_string_member (child, "ed25519", self->ed_key);
-- json_object_set_object_member (object, "keys", child);
--
-- child = json_object_new ();
-- json_object_set_string_member (child, "algorithm", "m.megolm.v1.aes-sha2");
-- json_object_set_string_member (child, "room_id", room_id);
-- json_object_set_string_member (child, "session_id", (char *)session_id);
-- json_object_set_string_member (child, "session_key", (char *)session_key);
-- json_object_set_int_member (child, "chain_index", olm_outbound_group_session_message_index (session));
-- json_object_set_object_member (object, "content", child);
--
-- /* User specific data */
-- json_object_set_string_member (object, "recipient", chatty_item_get_username (CHATTY_ITEM (buddy)));
--
-- /* Device specific data */
-- child = json_object_new ();
-- json_object_set_string_member (child, "ed25519", chatty_ma_device_get_ed_key (device));
-- json_object_set_object_member (object, "recipient_keys", child);
--
-- /* Now encrypt the above JSON */
-- data = matrix_utils_json_object_to_string (object, FALSE);
-- encrypted = ma_olm_encrypt (olm_session, data);
--
-- /* Add the encrypted data as the content */
-- json_object_set_int_member (content, "type", olm_encrypt_message_type (olm_session));
-- json_object_set_string_member (content, "body", encrypted);
-- }
-- }
-- }
--
-- /*
-- * We should also create an inbound session with the same key so
-- * that we we'll be able to decrypt the messages we sent (when
-- * we receive them via sync requests)
-- */
-- {
-- OlmInboundGroupSession *in_session;
--
-- in_session = g_malloc (olm_inbound_group_session_size ());
-- olm_inbound_group_session (in_session);
-- olm_init_inbound_group_session (in_session, (gpointer)session_key,
-- strlen ((char *)session_key));
-- g_hash_table_insert (self->in_group_sessions,
-- g_strdup ((char *)session_id), in_session);
-- }
--
-- g_hash_table_insert (self->out_group_sessions,
-- g_strdup (room_id), g_steal_pointer (&session));
--
-- matrix_utils_clear ((char *)session_key, strlen ((char *)session_key));
-- matrix_utils_clear ((char *)session_id, strlen ((char *)session_id));
--
-- return root;
--}
--
--void
--matrix_file_enc_info_free (MatrixFileEncInfo *enc_info)
--{
-- if (!enc_info)
-- return;
--
-- matrix_utils_free_buffer (enc_info->aes_iv_base64);
-- matrix_utils_free_buffer (enc_info->aes_key_base64);
-- matrix_utils_free_buffer (enc_info->sha256_base64);
--
-- matrix_utils_clear ((char *)enc_info->aes_iv, enc_info->aes_iv_len);
-- matrix_utils_clear ((char *)enc_info->aes_key, enc_info->aes_key_len);
-- matrix_utils_clear ((char *)enc_info->sha256, enc_info->sha256_len);
-- g_free (enc_info->aes_iv);
-- g_free (enc_info->aes_key);
-- g_free (enc_info->sha256);
--
-- g_free (enc_info);
--}
--
--const char *
--matrix_enc_get_curve25519_key (MatrixEnc *self)
--{
-- g_return_val_if_fail (MATRIX_IS_ENC (self), NULL);
--
-- return self->curve_key;
--}
--
--const char *
--matrix_enc_get_ed25519_key (MatrixEnc *self)
--{
-- g_return_val_if_fail (MATRIX_IS_ENC (self), NULL);
--
-- return self->ed_key;
--}
-diff --git a/src/matrix/matrix-enc.h b/src/matrix/matrix-enc.h
-deleted file mode 100644
-index 4acf1c51..00000000
---- a/src/matrix/matrix-enc.h
-+++ /dev/null
-@@ -1,88 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-enc.h
-- *
-- * Copyright 2020 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--#pragma once
--
--#include <json-glib/json-glib.h>
--#include <glib-object.h>
--
--#include "chatty-chat.h"
--
--G_BEGIN_DECLS
--
--typedef struct _MatrixFileEncInfo MatrixFileEncInfo;
--
--struct _MatrixFileEncInfo {
-- guchar *aes_iv;
-- guchar *aes_key;
-- guchar *sha256;
--
-- char *aes_iv_base64;
-- char *aes_key_base64;
-- char *sha256_base64;
--
-- gsize aes_iv_len;
-- gsize aes_key_len;
-- gsize sha256_len;
--};
--
--#define ALGORITHM_MEGOLM "m.megolm.v1.aes-sha2"
--#define ALGORITHM_OLM "m.olm.v1.curve25519-aes-sha2"
--#define CURVE25519_SIZE 43 /* when base64 encoded */
--#define ED25519_SIZE 43 /* when base64 encoded */
--
--#define MATRIX_TYPE_ENC (matrix_enc_get_type ())
--
--G_DECLARE_FINAL_TYPE (MatrixEnc, matrix_enc, MATRIX, ENC, GObject)
--
--MatrixEnc *matrix_enc_new (gpointer matrix_db,
-- const char *pickle,
-- const char *key);
--void matrix_enc_set_details (MatrixEnc *self,
-- const char *user_id,
-- const char *device_id);
--char *matrix_enc_get_account_pickle (MatrixEnc *self);
--char *matrix_enc_get_pickle_key (MatrixEnc *self);
--char *matrix_enc_sign_string (MatrixEnc *self,
-- const char *str,
-- size_t len);
--gboolean matrix_enc_verify (MatrixEnc *self,
-- JsonObject *object,
-- const char *matrix_id,
-- const char *device_id,
-- const char *ed_key);
--size_t matrix_enc_max_one_time_keys (MatrixEnc *self);
--size_t matrix_enc_create_one_time_keys (MatrixEnc *self,
-- size_t count);
--void matrix_enc_publish_one_time_keys (MatrixEnc *self);
--JsonObject *matrix_enc_get_one_time_keys (MatrixEnc *self);
--char *matrix_enc_get_one_time_keys_json (MatrixEnc *self);
--char *matrix_enc_get_device_keys_json (MatrixEnc *self);
--void matrix_enc_handle_room_encrypted (MatrixEnc *self,
-- JsonObject *object);
--char *matrix_enc_handle_join_room_encrypted (MatrixEnc *self,
-- const char *room_id,
-- JsonObject *object);
--JsonObject *matrix_enc_encrypt_for_chat (MatrixEnc *self,
-- const char *room_id,
-- const char *message);
--JsonObject *matrix_enc_create_out_group_keys (MatrixEnc *self,
-- const char *room_id,
-- GListModel *members_list);
--void matrix_file_enc_info_free (MatrixFileEncInfo *enc_info);
--
--G_DEFINE_AUTOPTR_CLEANUP_FUNC (MatrixFileEncInfo, matrix_file_enc_info_free)
--
--/* For tests */
--const char *matrix_enc_get_curve25519_key (MatrixEnc *self);
--const char *matrix_enc_get_ed25519_key (MatrixEnc *self);
--
--G_END_DECLS
-diff --git a/src/matrix/matrix-enums.h b/src/matrix/matrix-enums.h
-deleted file mode 100644
-index ec115796..00000000
---- a/src/matrix/matrix-enums.h
-+++ /dev/null
-@@ -1,83 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-enums.h
-- *
-- * Copyright 2020 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--#pragma once
--
--
--/**
-- * MatrixError:
-- *
-- * The Error returned by the Matrix Server
-- * See https://matrix.org/docs/spec/client_server/r0.6.1#api-standards
-- * for details.
-- */
--typedef enum {
-- M_FORBIDDEN = 1,
-- M_UNKNOWN_TOKEN,
-- M_MISSING_TOKEN,
-- M_BAD_JSON,
-- M_NOT_JSON,
-- M_NOT_FOUND,
-- M_LIMIT_EXCEEDED,
-- M_UNKNOWN,
-- M_UNRECOGNIZED,
-- M_UNAUTHORIZED,
-- M_USER_DEACTIVATED,
-- M_USER_IN_USE,
-- M_INVALID_USERNAME,
-- M_ROOM_IN_USE,
-- M_INVALID_ROOM_STATE,
-- M_THREEPID_IN_USE,
-- M_THREEPID_NOT_FOUND,
-- M_THREEPID_AUTH_FAILED,
-- M_THREEPID_DENIED,
-- M_SERVER_NOT_TRUSTED,
-- M_UNSUPPORTED_ROOM_VERSION,
-- M_INCOMPATIBLE_ROOM_VERSION,
-- M_BAD_STATE,
-- M_GUEST_ACCESS_FORBIDDEN,
-- M_CAPTCHA_NEEDED,
-- M_CAPTCHA_INVALID,
-- M_MISSING_PARAM,
-- M_INVALID_PARAM,
-- M_TOO_LARGE,
-- M_EXCLUSIVE,
-- M_RESOURCE_LIMIT_EXCEEDED,
-- M_CANNOT_LEAVE_SERVER_NOTICE_ROOM,
--
-- /* Local options */
-- M_BAD_PASSWORD,
-- M_NO_HOME_SERVER,
-- M_BAD_HOME_SERVER,
--} MatrixError;
--
--
--/*
-- * MATRIX_BLUE_PILL and MATRIX_RED_PILL
-- * are objects than actions
-- */
--typedef enum {
-- /* When nothing real is happening */
-- MATRIX_BLUE_PILL, /* For no/unknown command */
-- MATRIX_GET_HOMESERVER,
-- MATRIX_VERIFY_HOMESERVER,
-- MATRIX_PASSWORD_LOGIN,
-- MATRIX_ACCESS_TOKEN_LOGIN,
-- MATRIX_UPLOAD_KEY,
-- MATRIX_GET_JOINED_ROOMS,
-- MATRIX_SET_TYPING,
-- MATRIX_SEND_MESSAGE,
-- MATRIX_SEND_IMAGE,
-- MATRIX_SEND_VIDEO,
-- MATRIX_SEND_FILE,
-- /* sync: plugged into the Matrix from real world */
-- MATRIX_RED_PILL,
--} MatrixAction;
-diff --git a/src/matrix/matrix-net.c b/src/matrix/matrix-net.c
-deleted file mode 100644
-index d5305cf5..00000000
---- a/src/matrix/matrix-net.c
-+++ /dev/null
-@@ -1,610 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-api.c
-- *
-- * Copyright 2021 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--#define G_LOG_DOMAIN "chatty-matrix-net"
--
--#ifdef HAVE_CONFIG_H
--# include "config.h"
--#endif
--
--#define GCRYPT_NO_DEPRECATED
--#include <gcrypt.h>
--#include <libsoup/soup.h>
--#include <json-glib/json-glib.h>
--
--#include "chatty-utils.h"
--#include "matrix-utils.h"
--#include "matrix-enums.h"
--#include "matrix-enc.h"
--#include "matrix-net.h"
--#include "chatty-log.h"
--
--/**
-- * SECTION: matrix-net
-- * @title: MatrixNet
-- * @short_description: Matrix Network related methods
-- * @include: "matrix-net.h"
-- */
--
--#define MAX_CONNECTIONS 4
--
--struct _MatrixNet
--{
-- GObject parent_instance;
--
-- SoupSession *soup_session;
-- SoupSession *file_session;
-- GCancellable *cancellable;
-- char *homeserver;
-- char *access_token;
--};
--
--
--G_DEFINE_TYPE (MatrixNet, matrix_net, G_TYPE_OBJECT)
--
--static void
--net_download_stream_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GTask) task = user_data;
-- GCancellable *cancellable;
-- GOutputStream *out_stream = NULL;
-- GError *error = NULL;
-- char *buffer, *secret;
-- gsize n_written;
-- gssize n_read;
--
-- g_assert (G_IS_TASK (task));
--
-- n_read = g_input_stream_read_finish (G_INPUT_STREAM (obj), result, &error);
--
-- if (error) {
-- g_task_return_error (task, error);
--
-- return;
-- }
--
-- cancellable = g_task_get_cancellable (task);
-- buffer = g_task_get_task_data (task);
-- secret = g_object_get_data (user_data, "secret");
-- out_stream = g_object_get_data (user_data, "out-stream");
-- g_assert (out_stream);
--
-- if (secret) {
-- gcry_cipher_hd_t cipher_hd;
-- gcry_error_t err;
--
-- cipher_hd = g_object_get_data (user_data, "cipher");
-- g_assert (cipher_hd);
--
-- err = gcry_cipher_decrypt (cipher_hd, secret, n_read, buffer, n_read);
-- if (!err)
-- buffer = secret;
-- }
--
-- g_output_stream_write_all (out_stream, buffer, n_read, &n_written, NULL, NULL);
-- if (n_read == 0 || n_read == -1) {
-- g_output_stream_close (out_stream, cancellable, NULL);
--
-- if (n_read == 0) {
-- g_autoptr(GFile) parent = NULL;
-- GFile *out_file;
-- ChattyFileInfo *file;
--
-- file = g_object_get_data (user_data, "file");
-- out_file = g_object_get_data (user_data, "out-file");
--
-- /* We don't use absolute directory so that the path is user agnostic */
-- parent = g_file_new_build_filename (g_get_user_cache_dir (), "chatty", NULL);
-- file->path = g_file_get_relative_path (parent, out_file);
-- }
--
-- g_task_return_boolean (task, n_read == 0);
--
-- return;
-- }
--
-- buffer = g_task_get_task_data (task);
-- g_input_stream_read_async (G_INPUT_STREAM (obj), buffer, 1024 * 8, G_PRIORITY_DEFAULT, cancellable,
-- net_download_stream_cb, g_steal_pointer (&task));
--}
--
--static void
--net_get_file_stream_cb (GObject *obj,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixNet *self;
-- g_autoptr(GTask) task = user_data;
-- GCancellable *cancellable;
-- ChattyMessage *message;
-- ChattyFileInfo *file;
-- GInputStream *stream;
-- GError *error = NULL;
-- char *buffer = NULL;
--
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (MATRIX_IS_NET (self));
--
-- stream = soup_session_send_finish (SOUP_SESSION (obj), result, &error);
-- file = g_object_get_data (user_data, "file");
-- message = g_object_get_data (user_data, "message");
-- cancellable = g_task_get_cancellable (task);
--
-- if (!error) {
-- GFileOutputStream *out_stream;
-- GFile *out_file;
-- gboolean is_thumbnail = FALSE;
-- g_autofree char *file_name = NULL;
--
-- if (message &&
-- chatty_message_get_preview (message) == file)
-- is_thumbnail = TRUE;
--
-- file_name = g_path_get_basename (file->url);
--
-- /* If @message is NULL, @file is an avatar image */
-- out_file = g_file_new_build_filename (g_get_user_cache_dir (), "chatty", "matrix",
-- message ? "files" : "avatars",
-- is_thumbnail ? "thumbnail" : "", file_name,
-- NULL);
-- out_stream = g_file_append_to (out_file, 0, cancellable, &error);
-- g_object_set_data_full (user_data, "out-file", out_file, g_object_unref);
-- g_object_set_data_full (user_data, "out-stream", out_stream, g_object_unref);
-- }
--
-- if (error) {
-- g_task_return_error (task, error);
-- return;
-- }
--
-- buffer = g_malloc (1024 * 8);
-- g_task_set_task_data (task, buffer, g_free);
--
-- if (message &&
-- chatty_message_get_encrypted (message) && file->user_data) {
-- MatrixFileEncInfo *key;
-- gcry_cipher_hd_t cipher_hd;
-- gcry_error_t err;
--
-- key = file->user_data;
-- err = gcry_cipher_open (&cipher_hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, 0);
--
-- if (!err)
-- err = gcry_cipher_setkey (cipher_hd, key->aes_key, key->aes_key_len);
--
-- if (!err)
-- err = gcry_cipher_setctr (cipher_hd, key->aes_iv, key->aes_iv_len);
--
-- if (!err) {
-- char *secret = g_malloc (1024 * 8);
-- g_object_set_data_full (user_data, "secret", secret, g_free);
-- g_object_set_data_full (user_data, "cipher", cipher_hd,
-- (GDestroyNotify)gcry_cipher_close);
-- }
-- }
--
-- g_input_stream_read_async (stream, buffer, 1024 * 8, G_PRIORITY_DEFAULT, cancellable,
-- net_download_stream_cb, g_steal_pointer (&task));
--}
--
--static void
--net_load_from_stream_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixNet *self;
-- JsonParser *parser = JSON_PARSER (object);
-- g_autoptr(GTask) task = user_data;
-- JsonNode *root = NULL;
-- GError *error = NULL;
--
-- g_assert (JSON_IS_PARSER (parser));
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (MATRIX_IS_NET (self));
--
-- json_parser_load_from_stream_finish (parser, result, &error);
--
-- if (!error) {
-- root = json_parser_get_root (parser);
-- error = matrix_utils_json_node_get_error (root);
-- }
--
-- if (error) {
-- if (g_error_matches (error, MATRIX_ERROR, M_LIMIT_EXCEEDED) &&
-- root &&
-- JSON_NODE_HOLDS_OBJECT (root)) {
-- JsonObject *obj;
-- guint retry;
--
-- obj = json_node_get_object (root);
-- retry = matrix_utils_json_object_get_int (obj, "retry_after_ms");
-- g_object_set_data (G_OBJECT (task), "retry-after", GINT_TO_POINTER (retry));
-- } else {
-- CHATTY_DEBUG_MSG ("Error loading from stream: %s", error->message);
-- }
--
-- g_task_return_error (task, error);
-- return;
-- }
--
-- if (JSON_NODE_HOLDS_OBJECT (root))
-- g_task_return_pointer (task, json_node_dup_object (root),
-- (GDestroyNotify)json_object_unref);
-- else if (JSON_NODE_HOLDS_ARRAY (root))
-- g_task_return_pointer (task, json_node_dup_array (root),
-- (GDestroyNotify)json_array_unref);
-- else
-- g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
-- "Received invalid data");
--}
--
--static void
--session_send_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- MatrixNet *self;
-- g_autoptr(GTask) task = user_data;
-- g_autoptr(GInputStream) stream = NULL;
-- g_autoptr(JsonParser) parser = NULL;
-- GCancellable *cancellable;
-- GError *error = NULL;
--
-- g_assert (G_IS_TASK (task));
--
-- self = g_task_get_source_object (task);
-- g_assert (MATRIX_IS_NET (self));
--
-- stream = soup_session_send_finish (self->soup_session, result, &error);
--
-- if (error) {
-- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
-- CHATTY_TRACE_MSG ("Error session send: %s", error->message);
-- g_task_return_error (task, error);
-- return;
-- }
--
-- cancellable = g_task_get_cancellable (task);
-- parser = json_parser_new ();
-- json_parser_load_from_stream_async (parser, stream, cancellable,
-- net_load_from_stream_cb,
-- g_steal_pointer (&task));
--}
--
--/*
-- * queue_data:
-- * @data: (transfer full)
-- * @size: non-zero if @data is not %NULL
-- * @task: (transfer full)
-- */
--static void
--queue_data (MatrixNet *self,
-- char *data,
-- gsize size,
-- const char *uri_path,
-- const char *method, /* interned */
-- GHashTable *query,
-- GTask *task)
--{
-- g_autoptr(SoupMessage) message = NULL;
-- g_autoptr(SoupURI) uri = NULL;
-- GCancellable *cancellable;
-- SoupMessagePriority msg_priority;
-- int priority = 0;
--
-- g_assert (MATRIX_IS_NET (self));
-- g_assert (uri_path && *uri_path);
-- g_assert (method && *method);
-- g_return_if_fail (self->homeserver && *self->homeserver);
--
-- g_assert (method == SOUP_METHOD_GET ||
-- method == SOUP_METHOD_POST ||
-- method == SOUP_METHOD_PUT);
--
-- uri = soup_uri_new (self->homeserver);
-- soup_uri_set_path (uri, uri_path);
--
-- if (self->access_token) {
-- if (!query)
-- query = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
-- (GDestroyNotify)matrix_utils_free_buffer);
--
-- g_hash_table_replace (query, g_strdup ("access_token"), g_strdup (self->access_token));
-- soup_uri_set_query_from_form (uri, query);
-- g_hash_table_unref (query);
-- }
--
-- message = soup_message_new_from_uri (method, uri);
-- soup_message_headers_append (message->request_headers, "Accept-Encoding", "gzip");
--
-- priority = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "priority"));
--
-- if (priority <= -2)
-- msg_priority = SOUP_MESSAGE_PRIORITY_VERY_LOW;
-- else if (priority == -1)
-- msg_priority = SOUP_MESSAGE_PRIORITY_LOW;
-- else if (priority == 1)
-- msg_priority = SOUP_MESSAGE_PRIORITY_HIGH;
-- else if (priority >= 2)
-- msg_priority = SOUP_MESSAGE_PRIORITY_VERY_HIGH;
-- else
-- msg_priority = SOUP_MESSAGE_PRIORITY_NORMAL;
--
-- soup_message_set_priority (message, msg_priority);
--
-- if (data)
-- soup_message_set_request (message, "application/json", SOUP_MEMORY_TAKE, data, size);
--
-- cancellable = g_task_get_cancellable (task);
-- g_task_set_task_data (task, g_object_ref (message), g_object_unref);
-- soup_session_send_async (self->soup_session, message, cancellable,
-- session_send_cb, task);
--}
--
--static void
--matrix_net_finalize (GObject *object)
--{
-- MatrixNet *self = (MatrixNet *)object;
--
-- if (self->cancellable)
-- g_cancellable_cancel (self->cancellable);
--
-- soup_session_abort (self->soup_session);
-- soup_session_abort (self->file_session);
--
-- g_clear_object (&self->cancellable);
-- g_clear_object (&self->soup_session);
-- g_clear_object (&self->file_session);
--
-- g_free (self->homeserver);
--
-- matrix_utils_free_buffer (self->access_token);
-- G_OBJECT_CLASS (matrix_net_parent_class)->finalize (object);
--}
--
--static void
--matrix_net_class_init (MatrixNetClass *klass)
--{
-- GObjectClass *object_class = G_OBJECT_CLASS (klass);
--
-- object_class->finalize = matrix_net_finalize;
--}
--
--static void
--matrix_net_init (MatrixNet *self)
--{
-- self->soup_session = g_object_new (SOUP_TYPE_SESSION,
-- "max-conns-per-host", MAX_CONNECTIONS,
-- NULL);
-- self->file_session = g_object_new (SOUP_TYPE_SESSION,
-- "max-conns-per-host", MAX_CONNECTIONS,
-- NULL);
-- self->cancellable = g_cancellable_new ();
--}
--
--MatrixNet *
--matrix_net_new (void)
--{
-- return g_object_new (MATRIX_TYPE_NET, NULL);
--}
--
--void
--matrix_net_set_homeserver (MatrixNet *self,
-- const char *homeserver)
--{
-- g_return_if_fail (MATRIX_IS_NET (self));
-- g_return_if_fail (homeserver && *homeserver);
--
-- g_free (self->homeserver);
-- self->homeserver = g_strdup (homeserver);
--}
--
--void
--matrix_net_set_access_token (MatrixNet *self,
-- const char *access_token)
--{
-- g_return_if_fail (MATRIX_IS_NET (self));
--
-- matrix_utils_free_buffer (self->access_token);
-- self->access_token = g_strdup (access_token);
--}
--
--/**
-- * matrix_net_send_data_async:
-- * @self: A #MatrixNet
-- * @priority: The priority of request, 0 for default
-- * @data: (nullable) (transfer full): The data to send
-- * @size: The @data size in bytes
-- * @uri_path: A string of the matrix uri path
-- * @method: An interned string for GET, PUT, POST, etc.
-- * @query: (nullable): A query to pass to internal #SoupURI
-- * @cancellable: (nullable): A #GCancellable
-- * @callback: The callback to run when completed
-- * @user_data: user data for @callback
-- *
-- * Send a JSON data @object to the @uri_path endpoint.
-- * @method should be one of %SOUP_METHOD_GET, %SOUP_METHOD_PUT
-- * or %SOUP_METHOD_POST.
-- * If @cancellable is %NULL, the internal cancellable
-- * shall be used
-- */
--void
--matrix_net_send_data_async (MatrixNet *self,
-- int priority,
-- char *data,
-- gsize size,
-- const char *uri_path,
-- const char *method, /* interned */
-- GHashTable *query,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_NET (self));
-- g_return_if_fail (uri_path && *uri_path);
-- g_return_if_fail (method && *method);
-- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
-- g_return_if_fail (callback);
-- g_return_if_fail (self->homeserver && *self->homeserver);
--
-- if (data && *data)
-- g_return_if_fail (size);
--
-- if (!cancellable)
-- cancellable = self->cancellable;
--
-- task = g_task_new (self, cancellable, callback, user_data);
-- g_object_set_data (G_OBJECT (task), "priority", GINT_TO_POINTER (priority));
--
-- queue_data (self, data, size, uri_path, method, query, task);
--}
--
--/**
-- * matrix_net_send_json_async:
-- * @self: A #MatrixNet
-- * @priority: The priority of request, 0 for default
-- * @object: (nullable) (transfer full): The data to send
-- * @uri_path: A string of the matrix uri path
-- * @method: An interned string for GET, PUT, POST, etc.
-- * @query: (nullable): A query to pass to internal #SoupURI
-- * @cancellable: (nullable): A #GCancellable
-- * @callback: The callback to run when completed
-- * @user_data: user data for @callback
-- *
-- * Send a JSON data @object to the @uri_path endpoint.
-- * @method should be one of %SOUP_METHOD_GET, %SOUP_METHOD_PUT
-- * or %SOUP_METHOD_POST.
-- * If @cancellable is %NULL, the internal cancellable
-- * shall be used
-- */
--void
--matrix_net_send_json_async (MatrixNet *self,
-- int priority,
-- JsonObject *object,
-- const char *uri_path,
-- const char *method, /* interned */
-- GHashTable *query,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- GTask *task;
-- char *data = NULL;
-- gsize size = 0;
--
-- g_return_if_fail (MATRIX_IS_NET (self));
-- g_return_if_fail (uri_path && *uri_path);
-- g_return_if_fail (method && *method);
-- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
-- g_return_if_fail (callback);
-- g_return_if_fail (self->homeserver && *self->homeserver);
--
-- if (object) {
-- data = matrix_utils_json_object_to_string (object, FALSE);
-- json_object_unref (object);
-- }
--
-- if (data && *data)
-- size = strlen (data);
--
-- if (!cancellable)
-- cancellable = self->cancellable;
--
-- task = g_task_new (self, cancellable, callback, user_data);
-- g_object_set_data (G_OBJECT (task), "priority", GINT_TO_POINTER (priority));
--
-- queue_data (self, data, size, uri_path, method, query, task);
--}
--
--/**
-- * matrix_net_get_file_async:
-- * @self: A #MatrixNet
-- * @message: (nullable) (transfer full): A #ChattyMessage
-- * @file: A #ChattyFileInfo
-- * @cancellable: (nullable): A #GCancellable
-- * @progress_callback: (nullable): A #GFileProgressCallback
-- * @callback: The callback to run when completed
-- * @user_data: user data for @callback
-- *
-- * Download the file @file. @file path shall be updated
-- * after download is completed, and if @file is encrypted
-- * and has keys to decrypt the file, the file shall be
-- * stored decrypted.
-- */
--void
--matrix_net_get_file_async (MatrixNet *self,
-- ChattyMessage *message,
-- ChattyFileInfo *file,
-- GCancellable *cancellable,
-- GFileProgressCallback progress_callback,
-- GAsyncReadyCallback callback,
-- gpointer user_data)
--{
-- g_autofree char *url = NULL;
-- SoupMessage *msg;
-- GTask *task;
--
-- g_return_if_fail (MATRIX_IS_NET (self));
-- g_return_if_fail (!message || CHATTY_IS_MESSAGE (message));
-- g_return_if_fail (file && file->url);
--
-- if (message)
-- g_object_ref (message);
--
-- if (!cancellable)
-- cancellable = self->cancellable;
--
-- if (g_str_has_prefix (file->url, "mxc://")) {
-- const char *file_url;
--
-- file_url = file->url + strlen ("mxc://");
-- url = g_strconcat (self->homeserver,
-- "/_matrix/media/r0/download/", file_url, NULL);
-- }
--
-- if (!url)
-- url = g_strdup (file->url);
--
-- msg = soup_message_new (SOUP_METHOD_GET, url);
--
-- task = g_task_new (self, cancellable, callback, user_data);
-- g_object_set_data (G_OBJECT (task), "progress", progress_callback);
-- g_object_set_data (G_OBJECT (task), "file", file);
-- g_object_set_data_full (G_OBJECT (task), "msg", msg, g_object_unref);
-- g_object_set_data_full (G_OBJECT (task), "message", message, g_object_unref);
--
-- file->status = CHATTY_FILE_DOWNLOADING;
-- if (message)
-- chatty_message_emit_updated (message);
--
-- soup_session_send_async (self->file_session, msg, cancellable,
-- net_get_file_stream_cb, task);
--}
--
--gboolean
--matrix_net_get_file_finish (MatrixNet *self,
-- GAsyncResult *result,
-- GError **error)
--{
-- g_return_val_if_fail (MATRIX_IS_NET (self), FALSE);
-- g_return_val_if_fail (G_IS_TASK (result), FALSE);
-- g_return_val_if_fail (!error || !*error, FALSE);
--
-- return g_task_propagate_boolean (G_TASK (result), error);
--}
-diff --git a/src/matrix/matrix-net.h b/src/matrix/matrix-net.h
-deleted file mode 100644
-index a243f27b..00000000
---- a/src/matrix/matrix-net.h
-+++ /dev/null
-@@ -1,59 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-net.h
-- *
-- * Copyright 2021 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--#pragma once
--
--#include <glib-object.h>
--
--#include "chatty-message.h"
--
--G_BEGIN_DECLS
--
--#define MATRIX_TYPE_NET (matrix_net_get_type ())
--
--G_DECLARE_FINAL_TYPE (MatrixNet, matrix_net, MATRIX, NET, GObject)
--
--MatrixNet *matrix_net_new (void);
--void matrix_net_set_homeserver (MatrixNet *self,
-- const char *homeserver);
--void matrix_net_set_access_token (MatrixNet *self,
-- const char *access_token);
--void matrix_net_send_data_async (MatrixNet *self,
-- int priority,
-- char *data,
-- gsize size,
-- const char *uri_path,
-- const char *method, /* interned */
-- GHashTable *query,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--void matrix_net_send_json_async (MatrixNet *self,
-- int priority,
-- JsonObject *object,
-- const char *uri_path,
-- const char *method, /* interned */
-- GHashTable *query,
-- GCancellable *cancellable,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--void matrix_net_get_file_async (MatrixNet *self,
-- ChattyMessage *message,
-- ChattyFileInfo *file,
-- GCancellable *cancellable,
-- GFileProgressCallback progress_callback,
-- GAsyncReadyCallback callback,
-- gpointer user_data);
--gboolean matrix_net_get_file_finish (MatrixNet *self,
-- GAsyncResult *result,
-- GError **error);
--
--G_END_DECLS
-diff --git a/src/matrix/matrix-utils.c b/src/matrix/matrix-utils.c
-index 8c7b62b0..33c9c320 100644
---- a/src/matrix/matrix-utils.c
-+++ b/src/matrix/matrix-utils.c
-@@ -20,7 +20,6 @@
- #include <string.h>
- #include <glib/gi18n.h>
-
--#include "matrix-enums.h"
- #include "chatty-log.h"
- #include "chatty-utils.h"
- #include "matrix-utils.h"
-diff --git a/src/matrix/matrix-utils.h b/src/matrix/matrix-utils.h
-index 4ad1e1ac..7eff06a4 100644
---- a/src/matrix/matrix-utils.h
-+++ b/src/matrix/matrix-utils.h
-@@ -16,6 +16,8 @@
- #include <json-glib/json-glib.h>
- #include <libsoup/soup.h>
-
-+#include "cm-enums.h"
-+
- #define MATRIX_ERROR (matrix_error_quark ())
-
- GQuark matrix_error_quark (void);
-diff --git a/src/matrix/meson.build b/src/matrix/meson.build
-index 18d77c3e..716fb71b 100644
---- a/src/matrix/meson.build
-+++ b/src/matrix/meson.build
-@@ -2,10 +2,6 @@ src_inc += include_directories('.')
-
- libsrc += files([
- 'chatty-matrix.c',
-- 'matrix-api.c',
-- 'matrix-enc.c',
-- 'matrix-db.c',
-- 'matrix-net.c',
- 'matrix-utils.c',
- 'chatty-ma-account.c',
- 'chatty-ma-buddy.c',
-@@ -13,8 +9,5 @@ libsrc += files([
- ])
-
- chatty_deps += [
-- dependency('libgcrypt'),
-- dependency('libsoup-2.4'),
- dependency('json-glib-1.0'),
-- libolm_dep,
- ]
-diff --git a/src/meson.build b/src/meson.build
-index a133d679..dc5d2b62 100644
---- a/src/meson.build
-+++ b/src/meson.build
-@@ -116,6 +116,7 @@ chatty_deps += [
- libfeedback_dep,
- libm_dep,
- libphonenumber_dep,
-+ libcmatrix_dep,
- ]
-
- gnome = import('gnome')
-diff --git a/subprojects/libcmatrix b/subprojects/libcmatrix
-new file mode 160000
-index 00000000..b46edf36
---- /dev/null
-+++ b/subprojects/libcmatrix
-@@ -0,0 +1 @@
-+Subproject commit b46edf367fdb75a9501fb82d6ab1f413ffeaa40d
-diff --git a/subprojects/libcmatrix.wrap b/subprojects/libcmatrix.wrap
-new file mode 100644
-index 00000000..c06aa654
---- /dev/null
-+++ b/subprojects/libcmatrix.wrap
-@@ -0,0 +1,4 @@
-+[wrap-git]
-+directory=libcmatrix
-+url=https://source.puri.sm/mohammed.sadiq/libcmatrix
-+revision=main
-diff --git a/tests/matrix-api.c b/tests/matrix-api.c
-deleted file mode 100644
-index 8be72fc2..00000000
---- a/tests/matrix-api.c
-+++ /dev/null
-@@ -1,71 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-api.c
-- *
-- * Copyright 2020 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--#include "matrix-api.h"
--
--static void
--test_matrix_api_new (void)
--{
-- MatrixApi *api;
-- const char *name;
--
-- name = "@alice:example.com";
-- api = matrix_api_new (NULL);
-- g_assert (MATRIX_IS_API (api));
-- g_assert_cmpstr (matrix_api_get_username (api), ==, NULL);
-- matrix_api_set_login_username (api, name);
-- g_assert_cmpstr (matrix_api_get_login_username (api), ==, name);
-- g_object_unref (api);
--
-- name = "@alice:example.org";
-- api = matrix_api_new (name);
-- g_assert (MATRIX_IS_API (api));
-- g_assert_cmpstr (matrix_api_get_login_username (api), ==, name);
-- g_assert_cmpstr (matrix_api_get_password (api), ==, NULL);
-- g_assert_cmpstr (matrix_api_get_homeserver (api), ==, NULL);
--
-- matrix_api_set_password (api, "hunter2");
-- g_assert_cmpstr (matrix_api_get_password (api), ==, "hunter2");
-- matrix_api_set_password (api, NULL);
-- g_assert_cmpstr (matrix_api_get_password (api), ==, "hunter2");
--
-- matrix_api_set_homeserver (api, "example.net");
-- g_assert_cmpstr (matrix_api_get_homeserver (api), ==, NULL);
-- matrix_api_set_homeserver (api, "https://example.com");
-- g_assert_cmpstr (matrix_api_get_homeserver (api), ==, "https://example.com");
-- matrix_api_set_homeserver (api, NULL);
-- g_assert_cmpstr (matrix_api_get_homeserver (api), ==, "https://example.com");
-- matrix_api_set_homeserver (api, "https://example.org/");
-- g_assert_cmpstr (matrix_api_get_homeserver (api), ==, "https://example.org");
-- matrix_api_set_homeserver (api, "https://chat.example.net/page");
-- g_assert_cmpstr (matrix_api_get_homeserver (api), ==, "https://chat.example.net");
-- matrix_api_set_homeserver (api, "http://talk.example.com");
-- g_assert_cmpstr (matrix_api_get_homeserver (api), ==, "http://talk.example.com");
-- matrix_api_set_homeserver (api, "http://example.com:80");
-- g_assert_cmpstr (matrix_api_get_homeserver (api), ==, "http://example.com");
-- matrix_api_set_homeserver (api, "http://example.com:80");
-- g_assert_cmpstr (matrix_api_get_homeserver (api), ==, "http://example.com");
-- matrix_api_set_homeserver (api, "https://talk.example.net:80");
-- g_assert_cmpstr (matrix_api_get_homeserver (api), ==, "https://talk.example.net:80");
--
-- g_object_unref (api);
--}
--
--int
--main (int argc,
-- char *argv[])
--{
-- g_test_init (&argc, &argv, NULL);
--
-- g_test_add_func ("/matrix/api/new", test_matrix_api_new);
--
-- return g_test_run ();
--}
-diff --git a/tests/matrix-db.c b/tests/matrix-db.c
-deleted file mode 100644
-index 2ddd6685..00000000
---- a/tests/matrix-db.c
-+++ /dev/null
-@@ -1,230 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-db.c
-- *
-- * Copyright 2020 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--#undef NDEBUG
--#undef G_DISABLE_ASSERT
--#undef G_DISABLE_CHECKS
--#undef G_DISABLE_CAST_CHECKS
--#undef G_LOG_DOMAIN
--
--#include <glib/gstdio.h>
--#include <sqlite3.h>
--
--#include "chatty-ma-account.h"
--#include "matrix-db.h"
--
--static void
--finish_bool_cb (GObject *object,
-- GAsyncResult *result,
-- gpointer user_data)
--{
-- g_autoptr(GError) error = NULL;
-- GTask *task = user_data;
-- GObject *obj;
-- gboolean status;
--
-- g_assert_true (G_IS_TASK (task));
--
-- status = g_task_propagate_boolean (G_TASK (result), &error);
-- g_assert_no_error (error);
--
-- obj = G_OBJECT (result);
-- g_object_set_data (user_data, "enabled", g_object_get_data (obj, "enabled"));
-- g_object_set_data_full (user_data, "pickle", g_object_steal_data (obj, "pickle"), g_free);
-- g_object_set_data_full (user_data, "device", g_object_steal_data (obj, "device"), g_free);
-- g_object_set_data_full (user_data, "username", g_object_steal_data (obj, "username"), g_free);
-- g_task_return_boolean (task, status);
--}
--
--static gboolean
--account_matches_username (gconstpointer account,
-- gconstpointer username)
--{
-- const char *id = username;
--
-- g_assert_true (CHATTY_IS_MA_ACCOUNT ((gpointer)account));
-- g_assert_true (id && *id);
--
-- return g_strcmp0 (id, chatty_item_get_username ((gpointer)account)) == 0;
--}
--
--static void
--add_matrix_account (MatrixDb *db,
-- GPtrArray *account_array,
-- const char *username,
-- const char *pickle,
-- const char *device_id,
-- gboolean enabled)
--{
-- ChattyMaAccount *account;
-- GObject *object;
-- GTask *task;
-- GError *error = NULL;
-- gboolean success;
-- guint i;
--
-- g_assert_true (MATRIX_IS_DB (db));
-- g_assert_nonnull (account_array);
-- g_assert_nonnull (username);
--
-- if (g_ptr_array_find_with_equal_func (account_array, username,
-- account_matches_username, &i)) {
-- account = account_array->pdata[i];
-- } else {
-- account = chatty_ma_account_new (username, NULL);
-- g_ptr_array_add (account_array, account);
-- }
--
-- g_assert_true (CHATTY_IS_MA_ACCOUNT (account));
-- object = G_OBJECT (account);
--
-- g_object_set_data (object, "enabled", GINT_TO_POINTER (enabled));
-- g_object_set_data_full (object, "pickle", g_strdup (pickle), g_free);
-- g_object_set_data_full (object, "device", g_strdup (device_id), g_free);
--
-- task = g_task_new (NULL, NULL, NULL, NULL);
-- matrix_db_save_account_async (db, CHATTY_ACCOUNT (account), enabled, g_strdup (pickle), device_id,
-- NULL, finish_bool_cb, task);
--
-- while (!g_task_get_completed (task))
-- g_main_context_iteration (NULL, TRUE);
--
-- success = g_task_propagate_boolean (task, &error);
-- g_assert_no_error (error);
-- g_assert_true (success);
-- g_clear_object (&task);
--
-- g_assert_true (g_ptr_array_find (account_array, account, &i));
-- account = account_array->pdata[i];
-- task = g_task_new (NULL, NULL, NULL, NULL);
-- matrix_db_load_account_async (db, CHATTY_ACCOUNT (account), device_id, finish_bool_cb, task);
--
-- while (!g_task_get_completed (task))
-- g_main_context_iteration (NULL, TRUE);
--
-- success = g_task_propagate_boolean (task, &error);
-- g_assert_no_error (error);
-- g_assert_true (success);
-- g_assert_cmpstr (g_object_get_data (G_OBJECT (task), "username"), ==,
-- chatty_item_get_username (CHATTY_ITEM (account)));
-- g_assert_cmpint (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "enabled")),
-- ==, GPOINTER_TO_INT (g_object_get_data (object, "enabled")));
-- g_assert_cmpstr (g_object_get_data (G_OBJECT (task), "pickle"), ==,
-- g_object_get_data (object, "pickle"));
-- g_assert_cmpstr (g_object_get_data (G_OBJECT (task), "device"), ==,
-- g_object_get_data (object, "device"));
-- g_clear_object (&task);
--}
--
--static void
--test_matrix_db_account (void)
--{
-- GTask *task;
-- MatrixDb *db;
-- gboolean status;
-- GPtrArray *account_array;
--
-- g_remove (g_test_get_filename (G_TEST_BUILT, "test-matrix.db", NULL));
--
-- db = matrix_db_new ();
-- task = g_task_new (NULL, NULL, NULL, NULL);
-- matrix_db_open_async (db, g_strdup (g_test_get_dir (G_TEST_BUILT)),
-- "test-matrix.db", finish_bool_cb, task);
--
-- while (!g_task_get_completed (task))
-- g_main_context_iteration (NULL, TRUE);
--
-- status = g_task_propagate_boolean (task, NULL);
-- g_assert_finalize_object (task);
-- g_assert_true (status);
--
-- account_array = g_ptr_array_new ();
-- g_ptr_array_set_free_func (account_array, (GDestroyNotify)g_object_unref);
--
-- add_matrix_account (db, account_array, "@alice:example.org",
-- NULL, NULL, TRUE);
-- add_matrix_account (db, account_array, "@alice:example.org",
-- NULL, NULL, FALSE);
-- add_matrix_account (db, account_array, "@alice:example.com",
-- NULL, "XXAABBDD", FALSE);
-- add_matrix_account (db, account_array, "@alice:example.com",
-- "Some Pickle", "XXAABBDD", TRUE);
-- add_matrix_account (db, account_array, "@alice:example.org",
-- NULL, NULL, TRUE);
--
-- add_matrix_account (db, account_array, "@bob:example.org",
-- NULL, NULL, FALSE);
-- add_matrix_account (db, account_array, "@alice:example.org",
-- NULL, NULL, FALSE);
-- add_matrix_account (db, account_array, "@bob:example.org",
-- NULL, NULL, TRUE);
--
-- add_matrix_account (db, account_array, "@alice:example.net",
-- NULL, NULL, TRUE);
-- add_matrix_account (db, account_array, "@alice:example.com",
-- NULL, NULL, FALSE);
--
-- g_ptr_array_unref (account_array);
--}
--
--static void
--test_matrix_db_new (void)
--{
-- const char *file_name;
-- MatrixDb *db;
-- GTask *task;
-- gboolean status;
--
-- file_name = g_test_get_filename (G_TEST_BUILT, "test-matrix.db", NULL);
-- g_remove (file_name);
-- g_assert_false (g_file_test (file_name, G_FILE_TEST_EXISTS));
--
-- db = matrix_db_new ();
-- task = g_task_new (NULL, NULL, NULL, NULL);
-- matrix_db_open_async (db, g_strdup (g_test_get_dir (G_TEST_BUILT)),
-- "test-matrix.db", finish_bool_cb, task);
--
-- while (!g_task_get_completed (task))
-- g_main_context_iteration (NULL, TRUE);
--
-- status = g_task_propagate_boolean (task, NULL);
-- g_assert_true (g_file_test (file_name, G_FILE_TEST_IS_REGULAR));
-- g_assert_true (matrix_db_is_open (db));
-- g_assert_true (status);
-- g_clear_object (&task);
--
-- task = g_task_new (NULL, NULL, NULL, NULL);
-- matrix_db_close_async (db, finish_bool_cb, task);
--
-- while (!g_task_get_completed (task))
-- g_main_context_iteration (NULL, TRUE);
--
-- status = g_task_propagate_boolean (task, NULL);
-- g_assert_true (status);
-- g_assert_false (matrix_db_is_open (db));
-- g_clear_object (&db);
-- g_clear_object (&task);
--
-- g_remove (file_name);
-- g_assert_false (g_file_test (file_name, G_FILE_TEST_EXISTS));
--}
--
--int
--main (int argc,
-- char *argv[])
--{
-- g_test_init (&argc, &argv, NULL);
--
-- g_test_add_func ("/matrix-db/new", test_matrix_db_new);
-- g_test_add_func ("/matrix-db/account", test_matrix_db_account);
--
-- return g_test_run ();
--}
-diff --git a/tests/matrix-enc.c b/tests/matrix-enc.c
-deleted file mode 100644
-index c1ad7c55..00000000
---- a/tests/matrix-enc.c
-+++ /dev/null
-@@ -1,186 +0,0 @@
--/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
--/* matrix-utils.c
-- *
-- * Copyright 2020 Purism SPC
-- *
-- * Author(s):
-- * Mohammed Sadiq <sadiq(a)sadiqpk.org>
-- *
-- * SPDX-License-Identifier: GPL-3.0-or-later
-- */
--
--#undef NDEBUG
--#undef G_DISABLE_ASSERT
--#undef G_DISABLE_CHECKS
--#undef G_DISABLE_CAST_CHECKS
--#undef G_LOG_DOMAIN
--
--#ifdef HAVE_CONFIG_H
--# include "config.h"
--#endif
--
--#include <glib.h>
--#include <olm/olm.h>
--#include <sys/random.h>
--
--#include "matrix-utils.h"
--#include "matrix-enc.h"
--
--typedef struct EncData {
-- char *user_id;
-- char *device_id;
-- char *pickle_key;
-- char *olm2_pickle;
-- char *olm3_pickle;
-- char *olm3_v4_pickle;
-- char *curve_key;
-- char *ed_key;
-- /* These are not marked as published */
-- char *one_time_key1;
-- char *one_time_key2;
-- char *one_time_key3;
--} EncData;
--
--EncData enc[] = {
-- {
-- "@neo:example.com",
-- "JOJOAREBZY",
-- "cefdef40-3b16-4d71-8685-2740833c3297",
-- "HoxM0prMq/t3pGK6OLSet1h/1H8bnILjY1fp2Colr/ATOFevqulWPpiyktCJ0Cw1KZGQvHzHI481s2n2xu7yJkVC4TxrX5gKNTQ2QevZpVKD4PEmRaq40twVWOBjuAoxch16LCZs7CjNCYGtR7vhO2M6s5YchJhMFXJmH0Seik+yP5vyPJDx7nLcS6PZWEYGtr5U3VFUf4pj453NxrX7bAy7HRQOY642Vqkd1F06w6367naS0/0cgMj1aWDSK+z+a+F7TNfOaKky+90hLTYtkyM8VbFx8e6BmrmTyheCxpGKC1JQnj0QGCKb8cxAgV3FIaol8lOoFngA1Q7m6aEvkh3PyEqCUHqXlt70E0zHZy021tavDG2g1+GaCar9hOPayfVNpPZdFrL+avUJnTQ6DnxiGcBpobv+JiBjdOMb7rpG80P9nkPwre1D+JTvbCKgI+kZHUX3+Xs6YX01JJ8gmArl9GT1k4WkDi3iR74AAynXAASJRuwD6oKUbt/R5Ey3eqcmMh1IrwI",
-- "uugdtov1PcB8ZVO+OqXztUUImU/22WTIMYZnvzzCuTmHFLZkUtfha8QSMaoiyL0UGZSAmiaN4lF2k4+QtwYtdUBWUaWlOZd4ZTsacs7L6PkqpZvo491a6SYzHs/kNt/K23/x4BM7H/GBM2u0UOeekep+9IkI6d/j2vYSFYAIPj9nWQRTIfO9jCtwu1XcgzG/HcH5PRwq3F/Xq92VGrgv+AftnHH8XR1cK8OPkkL+Rm6J5VtfZgS3ygMOLy4j12+8Wo+BA8zxbBO8RKgD1c9doGX+MpYB7hgfkI+3S2Z2RTZq363mn+/sCu84ZXmkMfc+tvPS9W+65OugYCIm3sQtnM2Rz9xnFbZ+cJ4uX//3JCUmZJhvoSiPfMGu6XjU3HYsBlNViVMUYlNFpWCONCf+fiV2XjxOVrTZ3+8kPsKasZ7awWr3FLI/HhN0Wc7Wt8vTJwygV5654rR3dwvawhZpz+48J6hGBmUPiEKCDQZPfttOZhgo1bOiCPXgTI80/c1R7WxdDZVVOGopvuFDxwSn+ToalT81x0jVddOApLDpQtONB7NBfRqzK8nnLPmsj8a50Ljpv4G2gciYzZ3gO/ZRBrm5N5H90Vyf6AYR3PAWyJX8rnkSpVTu8rMhkGCIxvhkdc/HzcQUD1NlLTwlJxIxdDn0B33kju3jscDRvHgEWDy0Q2J5aDJTcf2ih13tVo530dSJXheEMeA",
-- "QGOyeIAqk194dXBsXQdUIgSJu26hM89GPmgVQua87AlU51A+R03h+1cg/x4LoaYAa+ej6l71ewk4XwgH0BqAEjiDK8VCabijqhsABECxFuC1zgK+Q2QMuZ8YJT5Vgf/0Igy+X7S4odxnd0OhF30nsr9Osj44sl8PgsuSLRtSqXGZ4TZ4UVC2AXj/q/g5vIEse30Fu4NVDJjPek0NytM6MeCo8x18QzzXjD5wIO/QGkW09AdbzOu7V9a1zrjzv7GIxTRYmzkfgVDqQw51kP2aJpW6RORhaomulpLD3GStpQCe5zrkXtGbyfJxtozY4KvefSpBBcob9U1PAI2qKoDKqSQYlzRVUXwFivaavnAxcXVk4HY/qvC6accDsIxHcHsBA7vUwRrN+BSLHE1VKyBSyzTPxKwk7xvh7mHx5UG+sQzCz54iCG59PRLN9RcmBnb77G981MqM4lfRvH+ypdyQGsnxeQaQV28rXWg5h12BShB8bKTxROJ/2sStka+H/nO5iHiDsN2EItY",
-- "UpcUBGKMHofzYsMwU5yBM79kL8dAMYXuPav+V1hZnkc",
-- "w33QBdjIgxJtP8jnFVCdAgjuCXy0XXT5eIPHJwvmbJw",
-- "YbFN9bWf0dfQCbsxsx5Lo779zXKAD/ctCN4qEj8G0T8",
-- "zNejRv4W41qroEyRmfxmwc2A9fliPsqcpJTb2E5woR0",
-- "OeS+WTn5e8k6C1jH4Mw1Otl3of0t+jPvWh2GusmlfBY",
-- },
-- {
-- "@neo:example.org",
-- "JDFVAREDFE",
-- "bc80e9a7-f175-4352-9b07-7178b63546ff",
-- "GeRh9PcLuV4diHtRBPngRcVVz54++xGLCvYuHKD0kMCpKHejUodLlpxCfI3Ax25E3nAqN7/k++BWywscZRyNqxVJ0J/w46RgiBrAm2+K3u1ylpSxREf0DwYGXSlMBEA7En5FdZkpcGcM83CiSs/3IqmTOMfMq66u7Uoe8wQ9ZJ6KiYMpv9lswkS0xypC0LnEQQWY8A57QKg9zqXhKvQPwQ1AhxaxWGxYaLQ5yYJZFwd+on3mpK+j7Q4BlM1fqA6hrTTBJ/UldBd8Algc5O6UIpB2Xp31ZDmLb9/D76P2/WD12I61x2T1V6WgmNneKRCXTN4PkPCbk+06QXAjL6OAKoK9TH17Hdu2uNGc83ye5reK1ZSfiHklU5NeyCI/ttJn/Pa0I6VnfhcgisxL+TgsXbgqHmi7GD6tvRaeVVr3x9QCOPyGFehaLF20TUZDm8EtbjupMbCTFWb5LU07yT4wM/mU/OsHVgJ1gQCCHrdGuZomyS9XZnkVLGQo+kT+VnUOeTmLznSROV0",
-- "DvyR7WJRCvvj1DaM7lJmCcnOUTHL3fPUJwgXjt8euKRO0JGY7pN4anP/z2BavTCLNpzKmXkkOYuBgQiEKU5jT8He/Meadx4udZrlxyacoEXt8PJH3spIoM8NaycuvYTwIVTvvvBVlnYME5M/Wwy0xd5cmJsAHth6mHTLnk5Hn1+i6fbxvLPvDmpm8D16X7z+t8eXEEoPckcjsWkXjoOFKHFGmqc5+K4gRt22xMJh0inZamzIb6sXy2Ov5h0d2V1gfOjYwdObKRjA/yTZQ1N5iR430H3jFuVl+BfG9VtL0EQH/w/N6q4C8wAVPwNDvsLEoII3uOtn/+ARKR7AJGhwzfq8k8WWEx1joWTKjKXb3Nm6RlLT/u4K3qVdSquOUV2efKEFhFAz8bH5D1T+XyXOPHgVIpDFMmwgnFxKCGFPqQrv6qeFrrmmHPxPNgmcNjiplDW1lTYr2TjOughLJbQpR/bVGI+9r0PMZHI0g18WgBGsf4Kv8t3x0K+Ui6ZJWL4eYhkvVRFw9kHew/nIisqBAqU4CpWlXips+52xoVXOQXTvtAzArmY5YLg2GxqlidEuRstK+oydg1NCfzqfcBNLu4ux5mNatgBLOCCrt6VIpM0FENZvihPku6/NA+YMpi0PuT2lsaOc94NE/AhDvuMx4z09dPWkywNK/d1yecmRbcdTHYoeZ51NS309OBD1KnoUT4NS6bBV0xQ",
-- "RDRByiOPGFYfs0fkyjEfA9Bva91+KPk7qptp1VGp1L8y3Mx9aMlzusNlPa3T9UFFoQV3J8cXY9fz7cZxMU8p52QDZQbBR5Fp6wp4Gt45xDr6w55ZuCRDI6NbUL6aNrg/5o3SgxpIzo6KVd797EYF+8IU2+Qnbp3+mN4zljclN/+PiCUox0UOjJE6TuQjbCNKenL5R+MbmnypBQDd9z2Ou7HeB1N4xgoe646cPUk8xBUJRZsnI+EA6odjN9Tzoq6d2np+yGezW8GTEoRwri8Up7DzjpdtFqGVbgKQBNec5srxFDcr/7vctE2KzxiPorQSv7FdaLweHR+0XOHmynQk0syKbq6nk7Iq0baB7wPTQUIuilq7zy0iOTVjYLdgfnpisdSKA9WGvJn3DQQer2mFGXZ6xc+CPbNqfKk9zltuzfzrqqDXVNSOX65T1swFvR70MKxQHWuTU2UsnPsl/VyvTEWkPr/FYTbnnWNnQnZfXXDmdQxl3BelnxqC7V01562s2ZRWvG9w3ss",
-- "FMXixHL3B/8xYAOs6MK4EeghAXZppZgNjb8o9UK4NSg",
-- "mnfxCgqI0trldd23vrz1SGbqQDW8TXcKKRlo9M3Mj64",
-- "d9lE1FD5s9I0gT4kT5jgQYDSDvNKQuBAQM/5LaSVtms",
-- "cq0RN7usZJobRbTAl/7f+ynywnCuaefwQeMmEZJHMwA",
-- "/a/OrFWpizYc+OgFz4GrGqsFpyHZhRsC2w3vw1I8wTk",
-- },
--};
--
--
--static void
--test_matrix_enc_verify (void)
--{
-- g_autoptr(MatrixEnc) enc1 = NULL;
-- g_autoptr(MatrixEnc) enc2 = NULL;
-- JsonObject *object, *root;
-- char *sign, *json, *key_label;
-- const char *message;
-- EncData data;
--
-- data = enc[0];
-- enc1 = matrix_enc_new (NULL, enc[0].olm2_pickle, enc[0].pickle_key);
-- enc2 = matrix_enc_new (NULL, enc[1].olm2_pickle, enc[1].pickle_key);
-- g_assert (MATRIX_IS_ENC (enc1));
-- g_assert (MATRIX_IS_ENC (enc2));
--
-- /* @message is in canonical form */
-- message = "{\"timeout\":20000,\"type\":\"m.message\"}";
-- sign = matrix_enc_sign_string (enc1, message, -1);
-- g_assert_nonnull (sign);
--
-- root = matrix_utils_string_to_json_object (message);
-- g_assert_nonnull (root);
--
-- json_object_set_object_member (root, "signatures", json_object_new ());
-- object = json_object_get_object_member (root, "signatures");
-- json_object_set_object_member (object, data.user_id, json_object_new ());
-- object = json_object_get_object_member (object, data.user_id);
-- g_assert (object);
--
-- key_label = g_strconcat ("ed25519:", data.device_id, NULL);
-- json_object_set_string_member (object, key_label, sign);
-- json = matrix_utils_json_object_to_string (root, FALSE);
-- g_assert_nonnull (json);
-- g_free (sign);
-- g_free (key_label);
-- json_object_unref (root);
--
-- root = matrix_utils_string_to_json_object (json);
-- g_assert_nonnull (root);
--
-- g_assert_true (matrix_enc_verify (enc1, root, data.user_id,
-- data.device_id, data.ed_key));
-- g_assert_true (matrix_enc_verify (enc2, root, data.user_id,
-- data.device_id, data.ed_key));
-- g_assert_false (matrix_enc_verify (enc1, root, data.user_id,
-- data.device_id, data.curve_key));
-- g_assert_false (matrix_enc_verify (enc1, root, enc[1].user_id,
-- data.device_id, data.ed_key));
-- json_object_unref (root);
-- g_free (json);
--}
--
--static void
--test_matrix_enc_new (void)
--{
-- const char *value;
-- char *pickle;
-- EncData data;
--
-- for (guint i = 0; i < G_N_ELEMENTS (enc); i++) {
-- g_autoptr(MatrixEnc) matrix_enc = NULL;
--
-- data = enc[i];
--
--#ifdef HAVE_OLM3
-- matrix_enc = matrix_enc_new (NULL, data.olm3_pickle, data.pickle_key);
-- g_assert (MATRIX_IS_ENC (matrix_enc));
--
-- pickle = matrix_enc_get_account_pickle (matrix_enc);
--# ifdef OLM_ACCOUNT_PICKLE_V4
-- g_assert_cmpstr (pickle, ==, data.olm3_v4_pickle);
--# else
-- g_assert_cmpstr (pickle, ==, data.olm3_pickle);
--# endif
-- g_clear_pointer (&pickle, g_free);
-- g_object_unref (matrix_enc);
--#endif
--
-- matrix_enc = matrix_enc_new (NULL, data.olm2_pickle, data.pickle_key);
-- g_assert (MATRIX_IS_ENC (matrix_enc));
--
-- value = matrix_enc_get_curve25519_key (matrix_enc);
-- g_assert_cmpstr (value, ==, data.curve_key);
--
-- value = matrix_enc_get_ed25519_key (matrix_enc);
-- g_assert_cmpstr (value, ==, data.ed_key);
--
-- pickle = matrix_enc_get_account_pickle (matrix_enc);
--#ifdef HAVE_OLM3
--# ifdef OLM_ACCOUNT_PICKLE_V4
-- g_assert_cmpstr (pickle, ==, data.olm3_v4_pickle);
--# else
-- g_assert_cmpstr (pickle, ==, data.olm3_pickle);
--# endif
--#else
-- g_assert_cmpstr (pickle, ==, data.olm2_pickle);
--#endif
-- g_clear_pointer (&pickle, g_free);
-- }
--}
--
--int
--main (int argc,
-- char *argv[])
--{
-- g_test_init (&argc, &argv, NULL);
--
-- g_test_add_func ("/matrix/enc/new", test_matrix_enc_new);
-- g_test_add_func ("/matrix/enc/verify", test_matrix_enc_verify);
--
-- return g_test_run ();
--}
-diff --git a/tests/meson.build b/tests/meson.build
-index 4d46d99f..6ec5f688 100644
---- a/tests/meson.build
-+++ b/tests/meson.build
-@@ -21,9 +21,6 @@ test_items = [
- 'history',
- 'settings',
- 'utils',
-- 'matrix-api',
-- 'matrix-db',
-- 'matrix-enc',
- 'matrix-utils',
- 'message-text-item',
- 'mm-account',
---
-GitLab
-
diff --git a/chatty-0.6.7-migrate-to-libsoup-3.0.patch b/chatty-0.6.7-migrate-to-libsoup-3.0.patch
deleted file mode 100644
index 878b692..0000000
--- a/chatty-0.6.7-migrate-to-libsoup-3.0.patch
+++ /dev/null
@@ -1,165 +0,0 @@
-diff --git a/src/dialogs/chatty-settings-dialog.c b/src/dialogs/chatty-settings-dialog.c
-index a2dbd1c..1b677d1 100644
---- a/src/dialogs/chatty-settings-dialog.c
-+++ b/src/dialogs/chatty-settings-dialog.c
-@@ -693,13 +693,13 @@ settings_homeserver_entry_changed (ChattySettingsDialog *self,
- server = gtk_entry_get_text (entry);
-
- if (server && *server) {
-- g_autoptr(SoupURI) uri = NULL;
-+ g_autoptr(GUri) uri = NULL;
-
-- uri = soup_uri_new (gtk_entry_get_text (entry));
-+ uri = g_uri_parse (gtk_entry_get_text (entry), SOUP_HTTP_URI_FLAGS, NULL);
-
-- valid = SOUP_URI_VALID_FOR_HTTP (uri);
-+ valid = !!uri;
- /* We need an absolute path URI */
-- valid = valid && *uri->host && g_str_equal (soup_uri_get_path (uri), "/");
-+ valid = valid && *g_uri_get_host(uri) && g_str_equal (g_uri_get_path (uri), "/");
- }
-
- if (valid)
-diff --git a/src/matrix/chatty-ma-account.c b/src/matrix/chatty-ma-account.c
-index ba4838f..d9d8337 100644
---- a/src/matrix/chatty-ma-account.c
-+++ b/src/matrix/chatty-ma-account.c
-@@ -340,9 +340,8 @@ cm_account_sync_cb (ChattyMaAccount *self,
- error->code, error->message);
-
- if (error &&
-- ((error->domain == SOUP_HTTP_ERROR &&
-- error->code <= SOUP_STATUS_TLS_FAILED &&
-- error->code > SOUP_STATUS_CANCELLED) ||
-+ (error->domain == SOUP_TLD_ERROR ||
-+ error->domain == G_TLS_ERROR ||
- g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NETWORK_UNREACHABLE) ||
- g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) ||
- error->domain == G_RESOLVER_ERROR ||
-diff --git a/src/matrix/matrix-utils.c b/src/matrix/matrix-utils.c
-index 33c9c32..aec49f4 100644
---- a/src/matrix/matrix-utils.c
-+++ b/src/matrix/matrix-utils.c
-@@ -362,37 +362,6 @@ matrix_utils_json_object_get_array (JsonObject *object,
- return NULL;
- }
-
--JsonObject *
--matrix_utils_get_message_json_object (SoupMessage *message,
-- const char *member)
--{
-- g_autoptr(JsonParser) parser = NULL;
-- g_autoptr(SoupBuffer) buffer = NULL;
-- JsonObject *object = NULL;
-- gboolean is_json;
--
-- if (!message || !message->response_body)
-- return NULL;
--
-- buffer = soup_message_body_flatten (message->response_body);
-- parser = json_parser_new ();
-- is_json = json_parser_load_from_data (parser, buffer->data, buffer->length, NULL);
--
-- if (is_json) {
-- JsonNode *root;
--
-- root = json_parser_get_root (parser);
--
-- if (root && JSON_NODE_HOLDS_OBJECT (root))
-- object = json_node_get_object (root);
--
-- if (member && object)
-- object = json_object_get_object_member (object, member);
-- }
--
-- return object ? json_object_ref (object) : NULL;
--}
--
- static gboolean
- cancel_read_uri (gpointer user_data)
- {
-@@ -446,16 +415,17 @@ matrix_utils_handle_ssl_error (SoupMessage *message)
- GApplication *app;
- GtkWidget *dialog;
- GtkWindow *window = NULL;
-- SoupURI *uri;
-+ GUri *uri;
- g_autofree char *msg = NULL;
- const char *host;
- GTlsCertificateFlags err_flags;
- gboolean cancelled = FALSE;
-
- if (!SOUP_IS_MESSAGE (message) ||
-- !soup_message_get_https_status (message, &cert, &err_flags) ||
-- !err_flags)
-+ !(err_flags = soup_message_get_tls_peer_certificate_errors (message)))
- return cancelled;
-+
-+ cert = soup_message_get_tls_peer_certificate(message);
-
- app = g_application_get_default ();
- if (app)
-@@ -465,7 +435,7 @@ matrix_utils_handle_ssl_error (SoupMessage *message)
- return cancelled;
-
- uri = soup_message_get_uri (message);
-- host = soup_uri_get_host (uri);
-+ host = g_uri_get_host (uri);
-
- switch (err_flags) {
- case G_TLS_CERTIFICATE_UNKNOWN_CA:
-@@ -548,11 +518,8 @@ uri_file_read_cb (GObject *object,
- return;
- }
-
-- soup_message_get_https_status (message, NULL, &err_flags);
--
- if (message &&
-- soup_message_get_https_status (message, NULL, &err_flags) &&
-- err_flags) {
-+ (err_flags = soup_message_get_tls_peer_certificate_errors (message))) {
- guint timeout_id, timeout;
-
- timeout = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (task), "timeout"));
-@@ -594,6 +561,14 @@ message_network_event_cb (SoupMessage *msg,
- g_object_set_data_full (user_data, "address", address, g_object_unref);
- }
-
-+static gboolean
-+accept_certificate_callback (SoupMessage *msg, GTlsCertificate *certificate,
-+ GTlsCertificateFlags tls_errors, gpointer user_data)
-+{
-+ // Returning TRUE trusts it anyway.
-+ return TRUE;
-+}
-+
- void
- matrix_utils_read_uri_async (const char *uri,
- guint timeout,
-@@ -640,9 +615,10 @@ matrix_utils_read_uri_async (const char *uri,
- G_CALLBACK (message_network_event_cb), task,
- G_CONNECT_AFTER);
- session = soup_session_new ();
-- g_object_set (G_OBJECT (session), SOUP_SESSION_SSL_STRICT, FALSE, NULL);
-+ /* Accept invalid certificates */
-+ g_signal_connect (message, "accept-certificate", G_CALLBACK (accept_certificate_callback), NULL);
-
-- soup_session_send_async (session, message, cancel,
-+ soup_session_send_async (session, message, 0, cancel,
- uri_file_read_cb,
- g_steal_pointer (&task));
- }
-diff --git a/src/matrix/matrix-utils.h b/src/matrix/matrix-utils.h
-index 7eff06a..2451581 100644
---- a/src/matrix/matrix-utils.h
-+++ b/src/matrix/matrix-utils.h
-@@ -43,9 +43,6 @@ JsonObject *matrix_utils_json_object_get_object (JsonObject *object,
- JsonArray *matrix_utils_json_object_get_array (JsonObject *object,
- const char *member);
-
--JsonObject *matrix_utils_get_message_json_object (SoupMessage *message,
-- const char *member);
--
- void matrix_utils_read_uri_async (const char *uri,
- guint timeout,
- GCancellable *cancellable,
diff --git a/chatty.spec b/chatty.spec
index d49a73b..32d01d8 100644
--- a/chatty.spec
+++ b/chatty.spec
@@ -3,13 +3,13 @@
%global libcmatrix_commit 702b894675f12ecd43439b3b3eee66cc74899b82
Name: chatty
-Version: 0.8.0~rc0
+Version: 0.8.0
Release: 1%{?dist}
Summary: A libpurple messaging client
License: GPL-3.0-or-later AND LGPL-2.1-or-later
-URL: https://source.puri.sm/Librem5/chatty
-Source0: https://source.puri.sm/Librem5/%{name}/-/archive/v0.8.0_rc0/%{name}-v0.8....
+URL: https://gitlab.gnome.org/World/Chatty
+Source0: %{url}/-/archive/v%{version}/Chatty-v%{version}.tar.gz
Source1: https://source.puri.sm/Librem5/libcmatrix/-/archive/%{libcmatrix_commit}/...
# Chatty links against a libpurple private library (libjabber).
@@ -20,36 +20,36 @@ Source1: https://source.puri.sm/Librem5/libcmatrix/-/archive/%{libcmatrix_commit
Patch0: 0001-hacky-hack.patch
# Temporary. Test failure on ppc64le
-ExcludeArch: ppc64le
-ExcludeArch: i686
+ExcludeArch: ppc64le
+ExcludeArch: i686
BuildRequires: gcc
BuildRequires: meson
BuildRequires: cmake
BuildRequires: gcc-c++
BuildRequires: dbus-daemon
-BuildRequires: dbus-x11
-BuildRequires: itstool
+BuildRequires: dbus-x11
+BuildRequires: itstool
BuildRequires: pkgconfig(libebook-contacts-1.2)
BuildRequires: pkgconfig(libebook-1.2) >= 3.42.0
BuildRequires: pkgconfig(libfeedback-0.0)
-BuildRequires: pkgconfig(libadwaita-1) >= 1.2
-BuildRequires: pkgconfig(gtk4) >= 4.6
-BuildRequires: pkgconfig(gio-2.0) >= 2.66
-BuildRequires: pkgconfig(gio-unix-2.0) >= 2.62
+BuildRequires: pkgconfig(libadwaita-1) >= 1.2
+BuildRequires: pkgconfig(gtk4) >= 4.8
+BuildRequires: pkgconfig(gio-2.0) >= 2.66
+BuildRequires: pkgconfig(gio-unix-2.0) >= 2.62
BuildRequires: pkgconfig(purple)
BuildRequires: pkgconfig(sqlite3) >= 3.26.0
BuildRequires: pkgconfig(gee-0.8)
BuildRequires: pkgconfig(folks)
BuildRequires: pkgconfig(gsettings-desktop-schemas)
-BuildRequires: pkgconfig(gnome-desktop-3.0)
+BuildRequires: pkgconfig(gnome-desktop-4) >= 43
BuildRequires: pkgconfig(libgcrypt)
BuildRequires: pkgconfig(libsoup-3.0)
BuildRequires: pkgconfig(json-glib-1.0)
BuildRequires: pkgconfig(mm-glib) >= 1.12.0
-BuildRequires: gspell-devel
+BuildRequires: gspell-devel
BuildRequires: libolm-devel
-BuildRequires: openssl1.1-devel
+BuildRequires: openssl1.1-devel
BuildRequires: libphonenumber-devel
BuildRequires: protobuf-devel
BuildRequires: libsecret-devel
@@ -57,7 +57,7 @@ BuildRequires: libappstream-glib
BuildRequires: desktop-file-utils
BuildRequires: /usr/bin/xvfb-run
BuildRequires: /usr/bin/xauth
-BuildRequires: at-spi2-core
+BuildRequires: at-spi2-core
Requires: hicolor-icon-theme
@@ -76,7 +76,7 @@ works best with the phosh mobile DE.
# Copy private libjabber library in so we can build against it
cp `pkg-config --variable=plugindir purple`/libjabber.so.0 /tmp/libjabber.so
-%setup -a1 -n %{name}-v0.8.0_rc0
+%setup -a1 -n Chatty-v%{version}
%patch -P 0 -p1
rm -rf subprojects/libcmatrix
diff --git a/sources b/sources
index 482db1e..1fc51ac 100644
--- a/sources
+++ b/sources
@@ -1,2 +1,2 @@
-SHA512 (chatty-v0.8.0_rc0.tar.gz) = 6d30a2917a3dc838934d02a6862769f99114dc67513be92e281164970fd46bfb08e0513c18c51e40778e4851631341fef8196ac13590ff2b92a436df48b8ff2a
+SHA512 (Chatty-v0.8.0.tar.gz) = 4fdba6f4f3787ddae37e52000cd9d882431a333520e8df07bc3f4e6f192894998600f5c6ff6a482eb0d7b4bd9c33cf541240e4aad87fe4dc79c82e3b630c7e48
SHA512 (libcmatrix-702b894675f12ecd43439b3b3eee66cc74899b82.tar.gz) = 9fc66c3f5115c54af76cf90f191c4b7dd78d22ba160feadefefa32590deea01a51aa670fa34b1f849de35dbf95ab4a4c0dc2160db827636e89bd7a2e22b0a188
commit cb0ea20167c5733451c7b0aaea0b435be237ae27
Author: Tomi Lähteenmäki <lihis(a)lihis.net>
Date: Fri Dec 22 11:33:30 2023 +0200
Convert license to SPDX
diff --git a/chatty.spec b/chatty.spec
index 0ccdbe5..d49a73b 100644
--- a/chatty.spec
+++ b/chatty.spec
@@ -7,7 +7,7 @@ Version: 0.8.0~rc0
Release: 1%{?dist}
Summary: A libpurple messaging client
-License: GPLv3+
+License: GPL-3.0-or-later AND LGPL-2.1-or-later
URL: https://source.puri.sm/Librem5/chatty
Source0: https://source.puri.sm/Librem5/%{name}/-/archive/v0.8.0_rc0/%{name}-v0.8....
Source1: https://source.puri.sm/Librem5/libcmatrix/-/archive/%{libcmatrix_commit}/...
1 month, 3 weeks
[Report] Packages Restricting Arches
by root
New package excluding arches (2)
============================
- keydb
ExcludeArch: %{ix86}
- llama-cpp
ExclusiveArch: x86_64 aarch64
Package no longer excluding arches (1)
==================================
- celestia
List of packages currently excluding arches (2154)
===========================================
- 0ad
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64 ppc64le
- 389-ds-base
ExcludeArch: i686
- 4ti2
ExcludeArch: %{ix86}
- 90-Second-Portraits
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc64le riscv64
- AcetoneISO
ExcludeArch: ppc %{power64} s390x
- Agda
ExcludeArch: %{ix86} armv7hl
- Agda-stdlib
ExcludeArch: armv7hl %{ix86}
- BareBonesBrowserLaunch
ExclusiveArch: %{java_arches} noarch
- CFR
ExclusiveArch: %{java_arches} noarch
- COPASI
ExcludeArch: %{ix86}
- CardManager
ExclusiveArch: %{java_arches} noarch
- CuraEngine
ExcludeArch: %{ix86}
- E
ExcludeArch: %{ix86}
- GAPDoc
ExcludeArch: %{ix86}
- GoldenCheetah
ExclusiveArch: %{qt5_qtwebengine_arches}
- GtkAda
ExclusiveArch: %{GPRbuild_arches}
- GtkAda3
ExclusiveArch: %{GPRbuild_arches}
- HPCombi
ExclusiveArch: x86_64 %{arm64}
- IPAddress
ExclusiveArch: %{java_arches} noarch
- IQmol
ExcludeArch: %{ix86}
- JUnitParams
ExclusiveArch: %{java_arches} noarch
- L-function
ExcludeArch: %{ix86}
- LabPlot
ExcludeArch: sparc64 s390 s390x
- MUSIC
ExcludeArch: %{ix86}
- Macaulay2
ExcludeArch: %{ix86} ppc64le
- Maelstrom
ExcludeArch: %{ix86}
- Mars
ExclusiveArch: %{java_arches} noarch
- NiaAML-GUI
ExcludeArch: %{ix86}
- OpenColorIO
ExcludeArch: i686
ExclusiveArch: x86_64 ppc64le
- OpenImageIO
ExcludeArch: i686
ExclusiveArch: x86_64 ppc64le
- OpenMolcas
ExclusiveArch: x86_64 aarch64 ppc64le s390x
- OpenStego
ExclusiveArch: %{java_arches} noarch
- Pencil2D
ExcludeArch: %{ix86}
- PragmARC
ExclusiveArch: %{GPRbuild_arches}
- ProDy
ExcludeArch: ppc64 s390x
- R-IRkernel
ExcludeArch: %{ix86}
- R-V8
ExclusiveArch: %{nodejs_arches}
- R-ape
ExcludeArch: %{ix86}
- R-igraph
ExcludeArch: %{ix86}
- R-kernlab
ExcludeArch: %{ix86} s390x
- R-rJava
ExclusiveArch: %{java_arches}
- Random123
ExcludeArch: mips64r2 mips32r2 s390
- RdRand
ExclusiveArch: %{ix86} x86_64
- RediSearch
ExclusiveArch: x86_64
- SLOF
ExclusiveArch: ppc64le
- Singular
ExcludeArch: %{ix86}
- TOPCOM
ExcludeArch: %{ix86}
- VulkanMemoryAllocator
ExcludeArch: %{ix86}
- WoeUSB
ExcludeArch: s390x
- YafaRay
ExclusiveArch: %{ix86} x86_64
- Zim
ExcludeArch: %{ix86}
- aardvark-dns
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- abiword
ExcludeArch: %{ix86}
- abrt-java-connector
ExcludeArch: %{ix86}
- accel-config
ExclusiveArch: %{ix86} x86_64
- acpica-tools
ExcludeArch: i686 armv7hl
- acpid
ExclusiveArch: ia64 x86_64 %{ix86} %{arm} aarch64 riscv64
- act
ExcludeArch: %{ix86}
- admeshgui
ExcludeArch: %{ix86}
- aemu
ExcludeArch: %{ix86} %{power64} s390x
- agenda
ExcludeArch: %{ix86}
- ahven
ExclusiveArch: %{GPRbuild_arches}
- algobox
ExclusiveArch: %{qt5_qtwebengine_arches}
- alienarena
ExcludeArch: s390x
- alizams
ExcludeArch: %{power64} %{ix86} s390x
- alt-ergo
ExcludeArch: %{ix86}
- american-fuzzy-lop
ExclusiveArch: x86_64 s390x
- amg4psblas
ExcludeArch: %{ix86}
- android-tools
ExcludeArch: ppc ppc64 s390x ppc64le
- anet
ExclusiveArch: %{GPRbuild_arches}
- ansible-collection-microsoft-sql
ExcludeArch: i686
- ant
ExclusiveArch: %{java_arches} noarch
- ant-antunit
ExclusiveArch: %{java_arches} noarch
- ant-contrib
ExclusiveArch: %{java_arches} noarch
- antlr
ExclusiveArch: %{java_arches}
- antlr3
ExclusiveArch: %{java_arches}
- antlr4-project
ExclusiveArch: %{java_arches}
- antlrworks
ExclusiveArch: %{java_arches} noarch
- aopalliance
ExclusiveArch: %{java_arches} noarch
- apache-commons-beanutils
ExclusiveArch: %{java_arches} noarch
- apache-commons-cli
ExclusiveArch: %{java_arches} noarch
- apache-commons-codec
ExclusiveArch: %{java_arches} noarch
- apache-commons-collections
ExclusiveArch: %{java_arches} noarch
- apache-commons-collections4
ExclusiveArch: %{java_arches} noarch
- apache-commons-compress
ExclusiveArch: %{java_arches} noarch
- apache-commons-configuration
ExclusiveArch: %{java_arches} noarch
- apache-commons-digester
ExclusiveArch: %{java_arches} noarch
- apache-commons-exec
ExclusiveArch: %{java_arches} noarch
- apache-commons-io
ExclusiveArch: %{java_arches} noarch
- apache-commons-jexl
ExclusiveArch: %{java_arches} noarch
- apache-commons-jxpath
ExclusiveArch: %{java_arches} noarch
- apache-commons-lang3
ExclusiveArch: %{java_arches} noarch
- apache-commons-logging
ExclusiveArch: %{java_arches} noarch
- apache-commons-math
ExclusiveArch: %{java_arches} noarch
- apache-commons-modeler
ExclusiveArch: %{java_arches} noarch
- apache-commons-net
ExclusiveArch: %{java_arches} noarch
- apache-commons-parent
ExclusiveArch: %{java_arches} noarch
- apache-commons-pool
ExclusiveArch: %{java_arches} noarch
- apache-commons-vfs
ExclusiveArch: %{java_arches} noarch
- apache-ivy
ExclusiveArch: %{java_arches} noarch
- apache-logging-parent
ExclusiveArch: %{java_arches} noarch
- apache-parent
ExclusiveArch: %{java_arches} noarch
- apache-resource-bundles
ExclusiveArch: %{java_arches} noarch
- apache-sshd
ExclusiveArch: %{java_arches} noarch
- apiguardian
ExclusiveArch: %{java_arches} noarch
- apmd
ExclusiveArch: %{ix86}
- appeditor
ExcludeArch: %{ix86}
- appstream-generator
ExclusiveArch: %{ldc_arches}
- apricots
ExcludeArch: ppc64le aarch64
- apron
ExcludeArch: %{ix86}
- aqute-bnd
ExclusiveArch: %{java_arches} noarch
- arbor
ExcludeArch: mips64r2 mips32r2 s390x %{ix86}
- arc-theme
ExcludeArch: %{ix86}
- args4j
ExclusiveArch: %{java_arches} noarch
- arianna
ExclusiveArch: %{qt6_qtwebengine_arches}
- arm-none-eabi-binutils-cs
ExcludeArch: %{ix86}
- arm-none-eabi-gcc-cs
ExcludeArch: %{ix86}
- arm-trusted-firmware
ExclusiveArch: aarch64
- arpwatch
ExcludeArch: %{ix86}
- asahi-installer
ExcludeArch: s390x
- asdcplib
ExcludeArch: %{ix86} %{arm}
- asmjit
ExclusiveArch: aarch64 x86_64
- assertj-core
ExclusiveArch: %{java_arches} noarch
- astromenace
ExcludeArch: ppc64 s390x
- astrometry-tycho2
ExcludeArch: s390x
- asv
ExcludeArch: %{ix86}
- atinject
ExclusiveArch: %{java_arches} noarch
- atlantik
ExcludeArch: %{ix86}
- atomic-queue
ExcludeArch: %{ix86}
- aubit4gl
ExcludeArch: i686 s390x ppc64le
- audacity
ExcludeArch: %{ix86} s390x
- audiocd-kio
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- aunit
ExclusiveArch: %GPRbuild_arches
- auryn
ExcludeArch: %{ix86}
- auto
ExclusiveArch: %{java_arches} noarch
- autolink-java
ExclusiveArch: noarch %{java_arches}
- avgtime
ExclusiveArch: %{ldc_arches}
- aws
ExclusiveArch: %GPRbuild_arches
- awscli2
ExcludeArch: s390x
- azove
ExcludeArch: %{ix86}
- azure-cli
ExclusiveArch: %{java_arches} noarch
- batik
ExclusiveArch: %{java_arches} noarch
- bcal
ExclusiveArch: x86_64 aarch64 ia64 ppc64 ppc64le s390x riscv64
- bcc
ExclusiveArch: x86_64 %{power64} aarch64 s390x armv7hl riscv64
- bcel
ExclusiveArch: %{java_arches} noarch
- bcftools
ExcludeArch: s390x
- bcm283x-firmware
ExclusiveArch: aarch64
- beansbinding
ExclusiveArch: %{java_arches} noarch
- bear
ExcludeArch: %{ix86}
- bear-factory
ExcludeArch: ppc64le
- berusky2
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64 %{mips} riscv64
- beust-jcommander
ExclusiveArch: %{java_arches} noarch
- bibletime
ExclusiveArch: %{java_arches}
- bigloo
ExcludeArch: %{ix86}
- binaryen
ExcludeArch: ppc64 s390x
- binutils
ExcludeArch: aarch64-linux-gnu aarch64-redhat-linux
ExcludeArch: ppc64le-linux-gnu ppc64le-redhat-linux
ExcludeArch: s390x-linux-gnu s390x-redhat-linux
ExcludeArch: x86_64-linux-gnu x86_64-redhat-linux i686-linux-gnu i686-redhat-linux
- biosdevname
ExclusiveArch: %{ix86} x86_64
- blake3
ExcludeArch: %{ix86}
- blend2d
ExcludeArch: s390x
- blender
ExcludeArch: %{ix86} %{arm}
- bless
ExclusiveArch: %mono_arches
- bliss
ExcludeArch: %{ix86}
- blueprint-compiler
ExcludeArch: s390x
- bluez-hcidump
ExcludeArch: s390 s390x
- bochs
ExcludeArch: s390x i686
- bodhi-server
ExclusiveArch: %{golang_arches_future}
- boinc-client
ExcludeArch: s390x
- bolzplatz2006
ExclusiveArch: %{java_arches}
- bootc
ExcludeArch: %{ix86}
- bottles
ExcludeArch: s390x
- bouncycastle
ExclusiveArch: %{java_arches} noarch
- bout++
ExcludeArch: %{ix86}
- bowtie
ExcludeArch: i686 armv7hl
- bowtie2
ExcludeArch: %{ix86} %{arm} s390x
- box64
ExclusiveArch: aarch64 riscv64 ppc64le x86_64
- boxes
ExcludeArch: %{ix86}
- bpftrace
ExclusiveArch: x86_64 %{power64} aarch64 s390x
- brazil
ExclusiveArch: %{java_arches} noarch
- breakid
ExcludeArch: %{ix86}
- brewtarget
ExcludeArch: %{ix86}
- brial
ExcludeArch: %{ix86}
- bsf
ExclusiveArch: %{java_arches} noarch
- bsh
ExclusiveArch: %{java_arches} noarch
- build-helper-maven-plugin
ExclusiveArch: %{java_arches} noarch
- buildah
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- busybox
ExcludeArch: i686 s390x
- bwping
ExcludeArch: %{ix86}
- byebyebios
ExclusiveArch: x86_64
- byte-buddy
ExclusiveArch: %{java_arches} noarch
- byteman
ExclusiveArch: %{java_arches} noarch
- cachelib
ExclusiveArch: x86_64 aarch64 ppc64le
- caddy
ExclusiveArch: %{golang_arches}
ExclusiveArch: %{golang_arches_future}
- cadical
ExcludeArch: %{ix86}
- caffe
ExclusiveArch: x86_64 aarch64 ppc64le
- calamares
ExclusiveArch: %{ix86} x86_64 aarch64 riscv64
- calc
ExcludeArch: s390x
- calibre
ExclusiveArch: aarch64 x86_64
- calligra
ExcludeArch: %{ix86}
- cambozola
ExclusiveArch: %{java_arches} noarch
- canl-java
ExclusiveArch: %{java_arches} noarch
- cantera
ExcludeArch: %{ix86}
- carat
ExcludeArch: %{ix86}
- casc
ExcludeArch: %{ix86}
- cataclysm-dda
ExcludeArch: i686
- catatonit
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- ccdciel
ExclusiveArch: %{fpc_arches}
ExcludeArch: %{ix86}
- ccluster
ExcludeArch: %{ix86}
- cdcollect
ExclusiveArch: %{mono_arches}
- cdi-api
ExclusiveArch: %{java_arches} noarch
- cdrdao
ExcludeArch: s390 s390x
- ceph
ExcludeArch: i686 armv7hl
ExclusiveArch: x86_64 aarch64 ppc64le s390x
- ceres-solver
ExcludeArch: ppc64
- cfn-lint
ExcludeArch: %{ix86}
- cglib
ExclusiveArch: %{java_arches} noarch
- cgreen
ExcludeArch: s390x
- chatterino2
ExcludeArch: %{ix86}
- chatty
ExcludeArch: i686
- checkpointctl
ExclusiveArch: %{golang_arches_future}
- chromium
ExclusiveArch: x86_64
ExclusiveArch: x86_64 aarch64 ppc64le
ExclusiveArch: x86_64 aarch64
- cinnamon
ExcludeArch: %{ix86}
- cinnamon-control-center
ExcludeArch: %{ix86}
- cinnamon-desktop
ExcludeArch: %{ix86}
- cinnamon-menus
ExcludeArch: %{ix86}
- cinnamon-screensaver
ExcludeArch: %{ix86}
- cinnamon-session
ExcludeArch: %{ix86}
- cinnamon-settings-daemon
ExcludeArch: %{ix86}
- cjdns
ExclusiveArch: %{nodejs_arches}
- cjs
ExcludeArch: %{ix86}
- classloader-leak-test-framework
ExclusiveArch: %{java_arches} noarch
- classpathless-compiler
ExclusiveArch: %{java_arches} noarch
- cld2
ExcludeArch: ppc64 s390x
- clevis-pin-tpm2
ExclusiveArch: %{rust_arches}
- clibs-list
ExcludeArch: %{ix86}
- clojure
ExclusiveArch: %{java_arches} noarch
- clojure-core-specs-alpha
ExclusiveArch: %{java_arches} noarch
- clojure-maven-plugin
ExclusiveArch: %{java_arches} noarch
- clojure-spec-alpha
ExclusiveArch: %{java_arches} noarch
- cloudcompare
ExcludeArch: %{ix86}
- clover2
ExcludeArch: armv7hl
- cmospwd
ExclusiveArch: %{ix86} x86_64
- cmrt
ExclusiveArch: %{ix86} x86_64 ia64
- coan
ExcludeArch: ppc64 s390x
- coccinelle
ExcludeArch: %{ix86}
- cocoalib
ExcludeArch: %{ix86}
- codeblocks
ExcludeArch: %{ix86}
- codehaus-parent
ExclusiveArch: %{java_arches} noarch
- cohomCalg
ExcludeArch: %{ix86}
- coin-or-Alps
ExcludeArch: %{ix86}
- coin-or-Bcp
ExcludeArch: %{ix86}
- coin-or-Bcps
ExcludeArch: %{ix86}
- coin-or-Blis
ExcludeArch: %{ix86}
- coin-or-Bonmin
ExcludeArch: %{ix86}
- coin-or-CoinMP
ExcludeArch: %{ix86}
- coin-or-Couenne
ExcludeArch: %{ix86}
- coin-or-Dip
ExcludeArch: %{ix86}
- coin-or-FlopC++
ExcludeArch: %{ix86}
- coin-or-HiGHS
ExcludeArch: %{ix86}
- coin-or-Ipopt
ExcludeArch: %{ix86}
- coin-or-OS
ExcludeArch: %{ix86}
- coin-or-SYMPHONY
ExcludeArch: %{ix86}
- coin-or-lemon
ExcludeArch: %{ix86}
- colorful
ExclusiveArch: %{fpc_arches}
- colossus
ExclusiveArch: %{java_arches} noarch
- compiz-plugins-experimental
ExcludeArch: s390 s390x
- conmon
ExclusiveArch: %{golang_arches_future}
- console-image-viewer
ExclusiveArch: %{java_arches} noarch
- containernetworking-plugins
ExclusiveArch: %{golang_arches}
- containers-common
ExclusiveArch: %{golang_arches} noarch
- contour-terminal
ExclusiveArch: x86_64 aarch64
- contractor
ExcludeArch: %{ix86}
- conu
ExcludeArch: ppc64
- coolreader
ExcludeArch: %{ix86}
- coq
ExclusiveArch: %{ocaml_native_compiler}
- corectrl
ExcludeArch: %{ix86}
- cortado
ExclusiveArch: %{java_arches} noarch
- coxeter
ExcludeArch: %{ix86}
- cpp-hocon
ExcludeArch: %{ix86}
- cpu-x
ExclusiveArch: i686 x86_64
- cpufetch
ExclusiveArch: %{arm} aarch64 x86_64 ppc ppc64 ppc64le
- cpuid
ExclusiveArch: %{ix86} x86_64
- cpuinfo
ExclusiveArch: x86_64 aarch64
- cqrlog
ExclusiveArch: %{fpc_arches}
- cramjam-cli
ExcludeArch: %{ix86}
- crash
ExclusiveArch: %{ix86} ia64 x86_64 ppc ppc64 s390 s390x %{arm} aarch64 ppc64le
- crash-gcore-command
ExclusiveArch: aarch64 ppc64le x86_64
- crash-trace-command
ExclusiveArch: aarch64 ppc64le s390x x86_64
- credentials-fetcher
ExclusiveArch: x86_64 aarch64 s390x
- crest
ExcludeArch: s390x
- cri-o
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
- cri-tools
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
- criu
ExclusiveArch: x86_64 %{arm} ppc64le aarch64 s390x
- crun
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le riscv64 s390x x86_64
- cryfs
ExcludeArch: i686
- cryptlib
ExclusiveArch: x86_64 aarch64 ppc64le
- crypto-policies
ExclusiveArch: %{java_arches} noarch
- cryptobone
ExclusiveArch: x86_64 ppc64le aarch64
- cryptominisat
ExcludeArch: %{ix86}
- csdp
ExcludeArch: %{ix86}
- csslint
ExclusiveArch: %{nodejs_arches} noarch
- cura
ExcludeArch: %{ix86}
- cura-fdm-materials
ExcludeArch: %{ix86}
- cvc5
ExcludeArch: %{ix86}
- cxsc
ExcludeArch: %{ix86}
- daggy
ExcludeArch: s390x
- dapl
ExcludeArch: s390, armv7hl
- daq
ExclusiveArch: x86_64 aarch64
- darktable
ExcludeArch: armv7hl i686 s390x
ExcludeArch: aarch64
- dbus-parsec
ExcludeArch: ppc64le s390x
- dbus-sharp
ExclusiveArch: %mono_arches
- dbus-sharp-glib
ExclusiveArch: %mono_arches
- ddccontrol
ExcludeArch: s390 s390x
- ddcutil
ExcludeArch: s390 s390x
- ddd
ExcludeArch: %{ix86}
- ddnet
ExcludeArch: s390x
- decentxml
ExclusiveArch: %{java_arches} noarch
- deepin-daemon
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
- deepin-desktop-schemas
ExclusiveArch: %{go_arches}
- dhall
ExcludeArch: %{ix86}
- dhall-json
ExcludeArch: %{ix86}
- dialect
ExcludeArch: s390x
- diffoscope
ExcludeArch: %{ix86}
- dippi
ExcludeArch: %{ix86}
- directory-maven-plugin
ExclusiveArch: %{java_arches} noarch
- dirgra
ExclusiveArch: %{java_arches} noarch
- disruptor
ExclusiveArch: %{java_arches} noarch
- ditaa
ExclusiveArch: %{java_arches} noarch
- dl_poly
ExcludeArch: i686
- dlib
ExcludeArch: ppc64le
- dlm
ExclusiveArch: i686 x86_64
- dmidecode
ExclusiveArch: %{ix86} x86_64 ia64 aarch64
- dmtcp
ExclusiveArch: x86_64
- dnsdist
ExcludeArch: %{ix86} #1994125
ExcludeArch: armv7hl #1994125
- docker-distribution
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
- dogtag-pki
ExclusiveArch: %{java_arches}
ExcludeArch: i686
- dolfin
ExcludeArch: %{ix86}
- dolphin-emu
ExclusiveArch: x86_64 aarch64
- dom4j
ExclusiveArch: %{java_arches} noarch
- dosbox-staging
ExcludeArch: %{ix86}
- dotnet6.0
ExclusiveArch: aarch64 x86_64 s390x
ExclusiveArch: x86_64
- dotnet8.0
ExclusiveArch: aarch64 ppc64le s390x x86_64
- doublecmd
ExclusiveArch: %{ix86} x86_64
- dpdk
ExclusiveArch: x86_64 i686 aarch64 ppc64le
- dragonbox
ExcludeArch: %{ix86}
- drat-trim
ExcludeArch: %{ix86}
- drat2er
ExcludeArch: %{ix86}
- dub
ExclusiveArch: %{ldc_arches}
- duperemove
ExcludeArch: %{ix86}
- dvdauthor
ExcludeArch: %{ix86}
- dvgrab
ExcludeArch: s390 s390x
- dxvk-native
ExclusiveArch: %{ix86} x86_64
- dyninst
ExclusiveArch: %{ix86} x86_64 ppc64le aarch64
- e-antic
ExcludeArch: %{ix86}
- e00compr
ExcludeArch: %{ix86}
- e3
ExclusiveArch: %{ix86} x86_64
- easymock
ExclusiveArch: %{java_arches} noarch
- eccodes
ExcludeArch: i686
- ecj
ExclusiveArch: %{java_arches} noarch
- eclib
ExcludeArch: %{ix86}
- eclipse-swt
ExclusiveArch: %{java_arches}
- ed25519-java
ExclusiveArch: %{java_arches} noarch
- edac-utils
ExcludeArch: %{ix86}
- edflib
ExcludeArch: s390x %{ix86}
- edk2
ExclusiveArch: x86_64 aarch64 riscv64
- edwin-fonts
ExcludeArch: %{ix86}
- eegdev
ExcludeArch: %{ix86}
- eegview
ExcludeArch: %{ix86}
- efax
ExcludeArch: s390 s390x
- efibootmgr
ExclusiveArch: %{efi}
- efifs
ExclusiveArch: %{efi}
- efitools
ExclusiveArch: %{efi}
- efivar
ExclusiveArch: %{efi}
- electron-cash
ExcludeArch: %{ix86}
- electrum
ExcludeArch: %{ix86}
- elk
ExclusiveArch: x86_64 %{ix86}
ExclusiveArch: x86_64 aarch64 %{arm} %{power64}
ExclusiveArch: x86_64 %{ix86} aarch64 %{arm} %{power64}
- emacs-common-proofgeneral
ExcludeArch: %{ix86}
- emacs-company-mode
ExcludeArch: %{ix86}
- emacs-iedit
ExcludeArch: %{ix86}
- emacs-slime
ExclusiveArch: %{arm} %{ix86} x86_64 ppc sparcv9 aarch64
- embree
ExclusiveArch: aarch64 x86_64
- embree3
ExclusiveArch: aarch64 x86_64
- enjarify
ExclusiveArch: %{java_arches} noarch
- enki
ExclusiveArch: %{qt5_qtwebengine_arches} noarch
- envytools
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64 riscv64
- eot-utils
ExcludeArch: %{ix86}
- ergo
ExcludeArch: %{ix86}
- eric
ExclusiveArch: %{qt6_qtwebengine_arches} noarch
- erlang-corba
ExclusiveArch: %{java_arches}
- esmi_ib_library
ExclusiveArch: x86_64
- espresso
ExcludeArch: s390x i686 armv7hl
- eth-tools
ExclusiveArch: x86_64
- exec-maven-plugin
ExclusiveArch: %{java_arches} noarch
- external-editor-revived
ExclusiveArch: %{rust_arches}
- extra-enforcer-rules
ExclusiveArch: %{java_arches} noarch
- fasterxml-oss-parent
ExclusiveArch: %{java_arches} noarch
- fb303
ExclusiveArch: x86_64 aarch64 ppc64le
- fbreader
ExcludeArch: %{ix86}
ExcludeArch: armv7hl
- fbthrift
ExclusiveArch: x86_64 aarch64 ppc64le
- fcitx-libpinyin
ExclusiveArch: %{qt5_qtwebengine_arches}
- fcitx5-mozc
ExcludeArch: ppc ppc64 sparcv9 sparc64 s390x
- fcoe-utils
ExcludeArch: ppc s390
ExcludeArch: %{ix86}
- fedora-dockerfiles
ExclusiveArch: %{go_arches}
ExcludeArch: ppc64
- felix-parent
ExclusiveArch: %{java_arches} noarch
- felix-utils
ExclusiveArch: %{java_arches} noarch
- fernflower
ExclusiveArch: %{java_arches} noarch
- fes
ExclusiveArch: %{ix86} x86_64
- fido-device-onboard
ExcludeArch: %{ix86}
- filedrop
ExclusiveArch: %{java_arches} noarch
- filezilla
ExcludeArch: s390x
- firecracker
ExclusiveArch: aarch64 x86_64
- firefox
ExcludeArch: i686
- fishbowl
ExclusiveArch: %{java_arches} noarch
- fizz
ExclusiveArch: x86_64 aarch64 ppc64le
- flang
ExcludeArch: i686 s390x
- flashrom
ExcludeArch: s390 s390x
- flatbuffers
ExcludeArch: %{ix86}
- flatpak
ExcludeArch: %{ix86}
- flatpak-builder
ExcludeArch: %{ix86}
- flatpak-module-tools
ExcludeArch: i386 i686
- flexmark-java
ExclusiveArch: noarch %{java_arches}
- flickcurl
ExcludeArch: %{ix86}
- flint
ExcludeArch: %{ix86}
- flocq
ExclusiveArch: %{ocaml_native_compiler}
- floppy-support
ExcludeArch: %{arm} aarch64 s390x
- florist
ExclusiveArch: %{GPRbuild_arches}
- flterm
ExcludeArch: s390 s390x sparcv9
- fluent-bit
ExclusiveArch: x86_64 aarch64
- flute
ExclusiveArch: %{java_arches} noarch
- fmidi
ExcludeArch: %{ix86}
- folly
ExclusiveArch: x86_64 aarch64 ppc64le
- fop
ExclusiveArch: %{java_arches} noarch
- forge-parent
ExclusiveArch: %{java_arches} noarch
- fotocx
ExcludeArch: %{ix86}
- foxi
ExclusiveArch: x86_64 aarch64
- fpc
ExclusiveArch: %{arm} aarch64 %{ix86} x86_64 ppc64le
- fprintd
ExcludeArch: s390 s390x
- fractal
ExcludeArch: %{ix86}
- fragments
ExcludeArch: %{ix86}
- frama-c
ExclusiveArch: %{ocaml_native_compiler}
- free42
ExcludeArch: %{ix86}
- freecol
ExclusiveArch: %{java_arches} noarch
- freedink
ExcludeArch: s390x
- freedink-dfarc
ExcludeArch: s390x
- freefem++
ExcludeArch: %{ix86}
- freemarker
ExclusiveArch: %{java_arches} noarch
- freerouting
ExclusiveArch: %{java_arches} noarch
- freetennis
ExcludeArch: sparc64 s390 s390x %{ix86}
- frescobaldi
ExclusiveArch: %{qt5_qtwebengine_arches}
- frysk
ExclusiveArch: x86_64 ppc64
- fuse-overlayfs
ExclusiveArch: %{arm64} ppc64le s390x x86_64 riscv64
- fusesource-pom
ExclusiveArch: %{java_arches} noarch
- fwts
ExclusiveArch: x86_64 %{arm} aarch64 s390x riscv64 %{power64}
- fwupd-efi
ExclusiveArch: x86_64 aarch64
- ga
ExcludeArch: %{ix86}
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64 ppc64le
- gambas3
ExcludeArch: i686
- gap
ExcludeArch: %{ix86}
- gap-pkg-ace
ExcludeArch: %{ix86}
- gap-pkg-aclib
ExcludeArch: %{ix86}
- gap-pkg-alnuth
ExcludeArch: %{ix86}
- gap-pkg-atlasrep
ExcludeArch: %{ix86}
- gap-pkg-autodoc
ExcludeArch: %{ix86}
- gap-pkg-automata
ExcludeArch: %{ix86}
- gap-pkg-autpgrp
ExcludeArch: %{ix86}
- gap-pkg-browse
ExcludeArch: %{ix86}
- gap-pkg-caratinterface
ExcludeArch: %{ix86}
- gap-pkg-circle
ExcludeArch: %{ix86}
- gap-pkg-cohomolo
ExcludeArch: %{ix86}
- gap-pkg-congruence
ExcludeArch: %{ix86}
- gap-pkg-corelg
ExcludeArch: %{ix86}
- gap-pkg-crime
ExcludeArch: %{ix86}
- gap-pkg-crisp
ExcludeArch: %{ix86}
- gap-pkg-crypting
ExcludeArch: %{ix86}
- gap-pkg-cryst
ExcludeArch: %{ix86}
- gap-pkg-crystcat
ExcludeArch: %{ix86}
- gap-pkg-ctbllib
ExcludeArch: %{ix86}
- gap-pkg-curlinterface
ExcludeArch: %{ix86}
- gap-pkg-cvec
ExcludeArch: %{ix86}
- gap-pkg-datastructures
ExcludeArch: %{ix86}
- gap-pkg-design
ExcludeArch: %{ix86}
- gap-pkg-digraphs
ExcludeArch: %{ix86}
- gap-pkg-edim
ExcludeArch: %{ix86}
- gap-pkg-factint
ExcludeArch: %{ix86}
- gap-pkg-ferret
ExcludeArch: %{ix86}
- gap-pkg-fga
ExcludeArch: %{ix86}
- gap-pkg-fining
ExcludeArch: %{ix86}
- gap-pkg-float
ExcludeArch: %{ix86}
- gap-pkg-format
ExcludeArch: %{ix86}
- gap-pkg-forms
ExcludeArch: %{ix86}
- gap-pkg-fr
ExcludeArch: %{ix86}
- gap-pkg-francy
ExcludeArch: %{ix86}
- gap-pkg-gbnp
ExcludeArch: %{ix86}
- gap-pkg-genss
ExcludeArch: %{ix86}
- gap-pkg-grape
ExcludeArch: %{ix86}
- gap-pkg-groupoids
ExcludeArch: %{ix86}
- gap-pkg-grpconst
ExcludeArch: %{ix86}
- gap-pkg-guava
ExcludeArch: %{ix86}
- gap-pkg-hap
ExcludeArch: %{ix86}
- gap-pkg-hapcryst
ExcludeArch: %{ix86}
- gap-pkg-hecke
ExcludeArch: %{ix86}
- gap-pkg-images
ExcludeArch: %{ix86}
- gap-pkg-io
ExcludeArch: %{ix86}
- gap-pkg-irredsol
ExcludeArch: %{ix86}
- gap-pkg-json
ExcludeArch: %{ix86}
- gap-pkg-jupyterkernel
ExcludeArch: %{ix86}
- gap-pkg-jupyterviz
ExcludeArch: %{ix86}
- gap-pkg-laguna
ExcludeArch: %{ix86}
- gap-pkg-liealgdb
ExcludeArch: %{ix86}
- gap-pkg-liepring
ExcludeArch: %{ix86}
- gap-pkg-liering
ExcludeArch: %{ix86}
- gap-pkg-loops
ExcludeArch: %{ix86}
- gap-pkg-lpres
ExcludeArch: %{ix86}
- gap-pkg-mapclass
ExcludeArch: %{ix86}
- gap-pkg-nautytracesinterface
ExcludeArch: %{ix86}
- gap-pkg-nq
ExcludeArch: %{ix86}
- gap-pkg-openmath
ExcludeArch: %{ix86}
- gap-pkg-orb
ExcludeArch: %{ix86}
- gap-pkg-polenta
ExcludeArch: %{ix86}
- gap-pkg-polycyclic
ExcludeArch: %{ix86}
- gap-pkg-polymaking
ExcludeArch: %{ix86}
- gap-pkg-primgrp
ExcludeArch: %{ix86}
- gap-pkg-profiling
ExcludeArch: %{ix86}
- gap-pkg-qpa
ExcludeArch: %{ix86}
- gap-pkg-quagroup
ExcludeArch: %{ix86}
- gap-pkg-radiroot
ExcludeArch: %{ix86}
- gap-pkg-recog
ExcludeArch: %{ix86}
- gap-pkg-repsn
ExcludeArch: %{ix86}
- gap-pkg-resclasses
ExcludeArch: %{ix86}
- gap-pkg-scscp
ExcludeArch: %{ix86}
- gap-pkg-semigroups
ExcludeArch: %{ix86}
- gap-pkg-singular
ExcludeArch: %{ix86}
- gap-pkg-sla
ExcludeArch: %{ix86}
- gap-pkg-smallgrp
ExcludeArch: %{ix86}
- gap-pkg-smallsemi
ExcludeArch: %{ix86}
- gap-pkg-sonata
ExcludeArch: %{ix86}
- gap-pkg-sophus
ExcludeArch: %{ix86}
- gap-pkg-spinsym
ExcludeArch: %{ix86}
- gap-pkg-standardff
ExcludeArch: %{ix86}
- gap-pkg-tomlib
ExcludeArch: %{ix86}
- gap-pkg-toric
ExcludeArch: %{ix86}
- gap-pkg-transgrp
ExcludeArch: %{ix86}
- gap-pkg-utils
ExcludeArch: %{ix86}
- gap-pkg-uuid
ExcludeArch: %{ix86}
- gap-pkg-xmod
ExcludeArch: %{ix86}
- gap-pkg-zeromqinterface
ExcludeArch: %{ix86}
- gappa
ExcludeArch: %{ix86}
- gappalib-coq
ExclusiveArch: %{ocaml_native_compiler}
- gauche
ExcludeArch: armv7hl
- gbrainy
ExclusiveArch: %mono_arches
- gcl
ExcludeArch: s390x
- gdb
ExclusiveArch: %{ix86} x86_64
ExcludeArch: aarch64
- gdb-exploitable
ExclusiveArch: x86_64 i386
ExclusiveArch: x86_64 noarch
- gdl
ExcludeArch: %{ix86}
- gearhead1
ExclusiveArch: %{fpc_arches}
- gearhead2
ExclusiveArch: %{fpc_arches}
- gearmand
ExcludeArch: ppc
- geeqie
ExcludeArch: %{ix86}
- gfan
ExcludeArch: %{ix86}
- gfs2-utils
ExcludeArch: %{ix86}
- gfxstream
ExcludeArch: %{ix86} %{power64} s390x
- ghc
ExcludeArch: armv7hl
- ghc-cborg
ExcludeArch: %{ix86}
- ghc-cborg-json
ExcludeArch: %{ix86}
- ghc-gi-gtk
ExcludeArch: armv7hl
- ghc-serialise
ExcludeArch: %{ix86}
- ghc9.10
ExcludeArch: armv7hl
- ghc9.2
ExcludeArch: armv7hl
- ghc9.4
ExcludeArch: armv7hl
- ghc9.6
ExcludeArch: armv7hl
- ghc9.8
ExcludeArch: armv7hl
- ghdl
ExclusiveArch: %{GNAT_arches}
ExcludeArch: armv7hl %{ix86}
- ghostwriter
ExclusiveArch: %{qt6_qtwebengine_arches}
- gimp-fourier-plugin
ExcludeArch: %{ix86}
- gio-sharp
ExclusiveArch: %mono_arches
- gir-to-d
ExclusiveArch: %{ldc_arches}
- git-lfs
ExcludeArch: %{ix86}
- git-octopus
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
- gitqlient
ExclusiveArch: %{qt5_qtwebengine_arches}
- giver
ExclusiveArch: %{mono_arches}
- gkeyfile-sharp
ExclusiveArch: %mono_arches
- gkrellm-wifi
ExcludeArch: s390 s390x
- glava
ExcludeArch: %{ix86}
- glibc32
ExclusiveArch: x86_64
- glibd
ExclusiveArch: %{ldc_arches}
- gloo
ExcludeArch: i686
- glycin-loaders
ExcludeArch: %{ix86}
- gmult
ExcludeArch: %{ix86}
- gn
ExcludeArch: %{ix86}
- gnatcoll
ExclusiveArch: %{GPRbuild_arches}
- gnatcoll-bindings
ExclusiveArch: %{GPRbuild_arches}
- gnatcoll-db
ExclusiveArch: %{GPRbuild_arches}
ExcludeArch: s390x
- gnofract4d
ExcludeArch: %{ix86}
- gnome-applets
ExcludeArch: %{ix86}
- gnome-bluetooth
ExcludeArch: s390 s390x
- gnome-bluetooth3.34
ExcludeArch: s390 s390x
- gnome-boxes
ExclusiveArch: x86_64
- gnome-chemistry-utils
ExcludeArch: %{ix86}
- gnome-desktop-sharp
ExclusiveArch: %mono_arches
- gnome-do
ExclusiveArch: %mono_arches
ExcludeArch: armv7hl
- gnome-flashback
ExcludeArch: %{ix86}
- gnome-hexgl
ExcludeArch: i686
- gnome-initial-setup
ExcludeArch: %{ix86}
- gnome-keyring-sharp
ExclusiveArch: %mono_arches
- gnome-monitor-config
ExcludeArch: %{ix86}
- gnome-panel
ExcludeArch: %{ix86}
- gnome-rdp
ExclusiveArch: %{mono_arches}
ExcludeArch: %{ix86}
- gnome-session
ExcludeArch: %{ix86}
- gnome-sharp
ExclusiveArch: %mono_arches
- gnome-shell
ExcludeArch: %{ix86}
- gnome-software
ExcludeArch: %{ix86}
- gnome-subtitles
ExclusiveArch: %mono_arches
- gnome-terminal
ExcludeArch: %{ix86}
- gnu-efi
ExclusiveArch: %{efi}
- gnucash
ExcludeArch: ppc64 s390x
- gnumeric
ExcludeArch: %{ix86}
- go-bindata
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
- godep
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
- godot
ExcludeArch: s390x
- godot3
ExcludeArch: ppc64 ppc64le s390x
- goffice
ExcludeArch: %{ix86}
- golang
ExclusiveArch: %{golang_arches}
- golang-entgo-ent
ExcludeArch: %{arm32} %{ix86}
- golang-github-ebitengine-purego
ExcludeArch: ppc64le s390x
- golang-github-elliotchance-orderedmap
ExcludeArch: aarch64
ExcludeArch: ppc64le
ExcludeArch: s390x
- golang-github-facebookincubator-nvdtools
ExcludeArch: i686 armv7hl
- golang-github-google-goterm
ExcludeArch: ppc64le s390x
- golang-helm-3
ExcludeArch: armv7hl aarch64
- golang-tinygo-x-llvm
ExcludeArch: %{ix86}
- goldendict-ng
ExclusiveArch: aarch64 x86_64
- google-compute-engine-guest-configs
ExcludeArch: %{ix86}
- google-cpu_features
ExcludeArch: s390x
- google-gson
ExclusiveArch: %{java_arches} noarch
- google-guest-agent
ExcludeArch: ppc64le
ExcludeArch: s390x
- google-guice
ExclusiveArch: %{java_arches} noarch
- google-osconfig-agent
ExcludeArch: ppc64le s390x
- gotcha
ExcludeArch: %{ix86}
- gotun
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
ExclusiveArch: x86_64
- gource
ExcludeArch: ppc64le
- goverlay
ExclusiveArch: %{fpc_arches}
- gpaste
ExcludeArch: %{ix86}
- gpaw
ExcludeArch: ppc64
ExcludeArch: %{ix86}
- gperftools
ExcludeArch: s390
- gprbuild
ExclusiveArch: %{GPRbuild_arches}
- gprolog
ExclusiveArch: x86_64 %{ix86} ppc alpha aarch64
- gr-air-modes
ExcludeArch: %{ix86}
- grafana
ExclusiveArch: %{grafana_arches}
- grafana-pcp
ExclusiveArch: %{grafanapcp_arches}
- greenboot
ExcludeArch: s390x
- gretl
ExcludeArch: %{ix86}
- gromacs
ExcludeArch: i686 armv7hl s390x
- grub-customizer
ExcludeArch: s390 s390x %{arm}
- grub2
ExcludeArch: s390 s390x %{ix86}
- grub2-breeze-theme
ExcludeArch: s390 s390x %{arm}
- grubby
ExcludeArch: %{ix86}
- gsequencer
ExcludeArch: i686
- gthree
ExcludeArch: i686
- gthumb
ExcludeArch: s390x
- gtk-sharp-beans
ExclusiveArch: %mono_arches
- gtk-sharp2
ExclusiveArch: %mono_arches
- gtk-sharp3
ExclusiveArch: %{mono_arches}
- gtkd
ExclusiveArch: %{ldc_arches}
- gtkhash
ExcludeArch: %{ix86}
- gtkwave
ExcludeArch: s390x
- guava
ExclusiveArch: %{java_arches} noarch
- gudev-sharp
ExclusiveArch: %mono_arches
- guestfs-tools
ExclusiveArch: %{kernel_arches}
ExcludeArch: %{power64}
- gvisor-tap-vsock
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- hamcrest
ExclusiveArch: %{java_arches} noarch
- harec
ExclusiveArch: x86_64 aarch64 riscv64
- harmonyseq
ExcludeArch: %{ix86}
- harvey
ExcludeArch: %{ix86}
- hashcat
ExcludeArch: ppc64 s390x
- hawtjni
ExclusiveArch: %{java_arches} noarch
- haxe
ExcludeArch: %{ix86}
- hcloud
ExcludeArch: %{ix86}
- heaptrack
ExcludeArch: s390 s390x
- hedgewars
ExclusiveArch: %{fpc_arches}
ExcludeArch: ppc64le
- hevea
ExcludeArch: %{ix86}
- hibernate-jpa-2.0-api
ExclusiveArch: %{java_arches} noarch
- hid4java
ExclusiveArch: %{java_arches} noarch
- highfive
ExcludeArch: %{ix86}
- hipblas
ExclusiveArch: x86_64
- hipcub
ExclusiveArch: x86_64
- hipfft
ExclusiveArch: x86_64
- hipify
ExclusiveArch: x86_64
- hiprand
ExclusiveArch: x86_64
- hipsolver
ExclusiveArch: x86_64
- hipsparse
ExclusiveArch: x86_64
- hmmer
ExcludeArch: aarch64 ppc64le s390x
- honggfuzz
ExcludeArch: %{arm} %{power64} s390 s390x
- howl
ExcludeArch: ppc64le s390x
ExcludeArch: %{ix86}
- hsakmt
ExclusiveArch: x86_64 aarch64 ppc64le
- httpcomponents-client
ExclusiveArch: %{java_arches} noarch
- httpcomponents-core
ExclusiveArch: %{java_arches} noarch
- httpcomponents-project
ExclusiveArch: %{java_arches} noarch
- hydrapaper
ExcludeArch: s390x
- hyena
ExclusiveArch: %{mono_arches}
- hyperhdr
ExcludeArch: %{ix86}
- hyperrogue
ExcludeArch: armv7hl
- hyperscan
ExclusiveArch: x86_64
- hyperv-daemons
ExclusiveArch: i686 x86_64 aarch64
- hyprcursor
ExcludeArch: %{ix86}
- hyprland
ExcludeArch: %{ix86}
- hyprlang
ExcludeArch: %{ix86}
- i2c-tools
ExcludeArch: s390 s390x
- ibsim
ExcludeArch: s390 %{arm}
- ibus-typing-booster
ExcludeArch: ppc64 s390x
- icecat
ExcludeArch: %{arm}
ExcludeArch: s390x
- icedtea-web
ExclusiveArch: %{java_arches}
- icu4j
ExclusiveArch: %{java_arches} noarch
- ignition
ExcludeArch: %{ix86}
- iir1
ExcludeArch: %{ix86}
- ilua
ExcludeArch: %{ix86}
- imagej
ExclusiveArch: %{java_arches} noarch
- imhex
ExclusiveArch: x86_64 %{arm64}
- iml
ExcludeArch: %{ix86}
- imvirt
ExclusiveArch: %{ix86} x86_64 ia64
- indistarter
ExclusiveArch: %{fpc_arches}
- infinipath-psm
ExclusiveArch: x86_64
- intel-cm-compiler
ExclusiveArch: i686 x86_64
- intel-cmt-cat
ExclusiveArch: x86_64
- intel-compute-runtime
ExclusiveArch: x86_64
- intel-gmmlib
ExcludeArch: s390x ppc64le
- intel-igc
ExclusiveArch: x86_64
- intel-ipp-crypto-mb
ExclusiveArch: x86_64
- intel-ipsec-mb
ExclusiveArch: x86_64
- intel-lpmd
ExclusiveArch: x86_64
- intel-media-driver-free
ExclusiveArch: i686 x86_64
- intel-mediasdk
ExclusiveArch: x86_64
- intel-metee
ExclusiveArch: x86_64
- intel-undervolt
ExclusiveArch: i386 x86_64
- ioport
ExclusiveArch: %{ix86} x86_64
- ipe
ExcludeArch: %{ix86}
- ipmctl
ExclusiveArch: x86_64
- irda-utils
ExcludeArch: s390 s390x
- irqbalance
ExcludeArch: s390 s390x
- isa-l
ExcludeArch: %{ix86}
- ispc
ExclusiveArch: x86_64 aarch64
- iucode-tool
ExclusiveArch: %{ix86} x86_64
- iyfct
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc64le
- jFormatString
ExclusiveArch: %{java_arches} noarch
- jack-mixer
ExcludeArch: armv7hl
ExcludeArch: i686
- jackson-annotations
ExclusiveArch: %{java_arches} noarch
- jackson-bom
ExclusiveArch: %{java_arches} noarch
- jackson-core
ExclusiveArch: %{java_arches} noarch
- jackson-databind
ExclusiveArch: %{java_arches} noarch
- jackson-jaxrs-providers
ExclusiveArch: %{java_arches} noarch
- jackson-modules-base
ExclusiveArch: %{java_arches} noarch
- jackson-parent
ExclusiveArch: %{java_arches} noarch
- jacoco
ExclusiveArch: %{java_arches} noarch
- jacop
ExclusiveArch: %{java_arches} noarch
- jakarta-activation
ExclusiveArch: %{java_arches} noarch
- jakarta-activation1
ExclusiveArch: %{java_arches} noarch
- jakarta-annotations
ExclusiveArch: %{java_arches} noarch
- jakarta-el
ExclusiveArch: %{java_arches} noarch
- jakarta-interceptors
ExclusiveArch: %{java_arches} noarch
- jakarta-json
ExclusiveArch: %{java_arches} noarch
- jakarta-mail
ExclusiveArch: %{java_arches} noarch
- jakarta-mail1
ExclusiveArch: %{java_arches} noarch
- jakarta-oro
ExclusiveArch: %{java_arches} noarch
- jakarta-saaj
ExclusiveArch: %{java_arches} noarch
- jakarta-server-pages
ExclusiveArch: %{java_arches} noarch
- jakarta-servlet
ExclusiveArch: %{java_arches} noarch
- jakarta-xml-ws
ExclusiveArch: %{java_arches} noarch
- janino
ExclusiveArch: %{java_arches} noarch
- jansi
ExclusiveArch: %{java_arches}
- jansi-native
ExclusiveArch: %{java_arches}
- jansi1
ExclusiveArch: %{java_arches} noarch
- java-1.8.0-openjdk
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-1.8.0-openjdk-portable
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-11-openjdk
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-11-openjdk-portable
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-17-openjdk
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-17-openjdk-portable
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-21-openjdk
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-21-openjdk-portable
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-diff-utils
ExclusiveArch: %{java_arches} noarch
- java-dirq
ExclusiveArch: %{java_arches} noarch
- java-jd-decompiler
ExclusiveArch: %{java_arches} noarch
- java-latest-openjdk
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-latest-openjdk-portable
ExclusiveArch: %{java_arches}
ExcludeArch: %{ix86}
- java-runtime-decompiler
ExclusiveArch: %{java_arches} noarch
- java-scrypt
ExclusiveArch: %{java_arches} noarch
- java_cup
ExclusiveArch: %{java_arches} noarch
- javacc
ExclusiveArch: %{java_arches} noarch
- javacc-maven-plugin
ExclusiveArch: %{java_arches} noarch
- javaewah
ExclusiveArch: %{java_arches} noarch
- javapackages-bootstrap
ExclusiveArch: %{java_arches}
- javaparser
ExclusiveArch: %{java_arches} noarch
- javapoet
ExclusiveArch: %{java_arches} noarch
- javassist
ExclusiveArch: %{java_arches} noarch
- jaxb
ExclusiveArch: %{java_arches} noarch
- jaxb-api
ExclusiveArch: %{java_arches} noarch
- jaxb-api2
ExclusiveArch: %{java_arches} noarch
- jaxb-dtd-parser
ExclusiveArch: %{java_arches} noarch
- jaxb-fi
ExclusiveArch: %{java_arches} noarch
- jaxb-istack-commons
ExclusiveArch: %{java_arches} noarch
- jaxb-stax-ex
ExclusiveArch: %{java_arches} noarch
- jaxen
ExclusiveArch: %{java_arches} noarch
- jblas
ExcludeArch: %{ix86}
- jboss-jaxrs-2.0-api
ExclusiveArch: %{java_arches} noarch
- jboss-logging
ExclusiveArch: %{java_arches} noarch
- jboss-logging-tools
ExclusiveArch: %{java_arches} noarch
- jboss-parent
ExclusiveArch: %{java_arches} noarch
- jchardet
ExclusiveArch: %{java_arches} noarch
- jcip-annotations
ExclusiveArch: %{java_arches} noarch
- jctools
ExclusiveArch: %{java_arches} noarch
- jcuber
ExclusiveArch: %{java_arches} noarch
- jdeparser
ExclusiveArch: %{java_arches} noarch
- jdepend
ExclusiveArch: %{java_arches} noarch
- jdependency
ExclusiveArch: %{java_arches} noarch
- jdom
ExclusiveArch: %{java_arches} noarch
- jdom2
ExclusiveArch: %{java_arches} noarch
- jedit
ExclusiveArch: %{java_arches} noarch
- jericho-html
ExclusiveArch: %{java_arches} noarch
- jetbrains-annotations
ExclusiveArch: noarch %{java_arches}
- jetty
ExclusiveArch: %{java_arches} noarch
- jflex
ExclusiveArch: %{java_arches} noarch
- jfreechart
ExclusiveArch: %{java_arches} noarch
- jgit
ExclusiveArch: %{java_arches} noarch
- jglobus
ExclusiveArch: %{java_arches} noarch
- jgoodies-common
ExclusiveArch: %{java_arches} noarch
- jgoodies-forms
ExclusiveArch: %{java_arches} noarch
- jgoodies-looks
ExclusiveArch: %{java_arches} noarch
- jigawatts
ExclusiveArch: x86_64 %{arm} ppc64le aarch64 s390x
- jline
ExclusiveArch: %{java_arches}
- jline2
ExclusiveArch: %{java_arches} noarch
- jmock
ExclusiveArch: %{java_arches} noarch
- jmol
ExclusiveArch: %{java_arches} noarch
- jna
ExclusiveArch: %{java_arches}
- jneuroml-core
ExclusiveArch: %{java_arches} noarch
- jni-inchi
ExclusiveArch: %{java_arches}
- jo
ExcludeArch: %{ix86}
- jol
ExclusiveArch: %{java_arches} noarch
- jolokia-jvm-agent
ExclusiveArch: %{java_arches} noarch
- jopt-simple
ExclusiveArch: %{java_arches} noarch
- jorbis
ExclusiveArch: %{java_arches} noarch
- jowl
ExclusiveArch: %{nodejs_arches} noarch
- jpanoramamaker
ExclusiveArch: %{java_arches} noarch
- jpilot
ExcludeArch: s390, s390x
- jpilot-backup
ExcludeArch: s390 s390x
- jsch
ExclusiveArch: %{java_arches} noarch
- jsch-agent-proxy
ExclusiveArch: %{java_arches} noarch
- json_simple
ExclusiveArch: %{java_arches} noarch
- jsoup
ExclusiveArch: %{java_arches} noarch
- jsr-305
ExclusiveArch: %{java_arches} noarch
- jss
ExclusiveArch: %{java_arches}
ExcludeArch: i686
- jssc
ExclusiveArch: %{java_arches}
- jtidy
ExclusiveArch: %{java_arches} noarch
- julia
ExclusiveArch: x86_64
- junit
ExclusiveArch: %{java_arches} noarch
- junit5
ExclusiveArch: %{java_arches} noarch
- juniversalchardet
ExclusiveArch: %{java_arches} noarch
- jzlib
ExclusiveArch: %{java_arches} noarch
- kaffeine
ExcludeArch: %{ix86}
- kaidan
ExclusiveArch: %{qt5_qtwebengine_arches}
ExcludeArch: %{ix86}
- kata-containers
ExcludeArch: %{arm} %{ix86} s390 s390x
- kawa
ExcludeArch: i686
- kchmviewer
ExclusiveArch: %{qt5_qtwebengine_arches}
- kcm_wacomtablet
ExcludeArch: s390 s390x
- kcov
ExcludeArch: s390 s390x
- kdenlive
ExcludeArch: %{ix86}
- keepass
ExclusiveArch: %{mono_arches}
ExcludeArch: armv7hl
- keepassxc
ExcludeArch: s390x
- kernel
ExclusiveArch: noarch x86_64 s390x aarch64 ppc64le
ExclusiveArch: noarch i386 i686 x86_64 s390x aarch64 ppc64le
- kernelshark
ExcludeArch: %{ix86} %{arm}
- keydb
ExcludeArch: %{ix86}
- keylime-agent-rust
ExclusiveArch: %{rust_arches}
- keyring-ima-signer
ExclusiveArch: %{rust_arches}
- kf5-akonadi-search
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-kblog
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-kcalendarcore
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-kcalendarutils
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-kitinerary
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-ktnef
ExclusiveArch: x86_64 ppc64le aarch64 %{arm}
- kf5-libkdcraw
ExclusiveArch: x86_64 ppc64le %{arm}
- khelpcenter
ExclusiveArch: %{qt6_qtwebengine_arches}
- kicad
ExclusiveArch: x86_64 aarch64 ppc64le
- kissat
ExcludeArch: %{ix86}
- kitty
ExcludeArch: %{ix86}
- kiwix-desktop
ExclusiveArch: %{qt5_qtwebengine_arches}
- knot-resolver
ExclusiveArch: %{ix86} x86_64
ExclusiveArch: %{arm} aarch64 %{ix86} x86_64
- kokkos
ExcludeArch: i686 armv7hl
- komikku
ExcludeArch: s390x
- kpilot
ExcludeArch: s390 s390x
- krita
ExcludeArch: %{ix86}
- ksensors
ExcludeArch: s390 s390x
- kubernetes
ExclusiveArch: x86_64 aarch64 ppc64le s390x %{arm}
- ladspa-autotalent-plugins
ExcludeArch: %{ix86}
- laf-plugin
ExclusiveArch: %{java_arches} noarch
- latte-integrale
ExcludeArch: %{ix86}
- lazarus
ExclusiveArch: %{fpc_arches}
- lazpaint
ExclusiveArch: %{fpc_arches}
- lcd4linux
ExcludeArch: s390 s390x
- ldapjdk
ExclusiveArch: %{java_arches} noarch
- ldc
ExclusiveArch: %{ldc_arches} ppc64le
- ledmon
ExcludeArch: %{ix86}
- leland-fonts
ExcludeArch: %{ix86}
- lfortran
ExclusiveArch: x86_64
- lfsc
ExcludeArch: %{ix86}
- lib3mf
ExcludeArch: %{ix86}
- libCombine
ExcludeArch: %{ix86}
- libaiff
ExcludeArch: %{ix86}
- libarcus
ExcludeArch: %{ix86}
- libarrow
ExcludeArch: %{ix86} %{arm}
- libavc1394
ExcludeArch: s390 s390x
- libbase
ExclusiveArch: %{java_arches} noarch
- libcamera
ExcludeArch: s390x ppc64le
- libcamera-apps
ExcludeArch: %{power64} s390x
- libcint
ExcludeArch: %{power64}
- libcircle
ExcludeArch: %{ix86}
- libcpuid
ExcludeArch: aarch64 %arm ppc64le ppc64 s390x
- libcrystalhd
ExcludeArch: s390 s390x
- libcxl
ExclusiveArch: %{power64}
- libcxx
ExcludeArch: ppc64 ppc64le
- libdc1394
ExcludeArch: s390 s390x
- libdfp
ExclusiveArch: ppc ppc64 ppc64le s390 s390x x86_64
- libdigidocpp
ExcludeArch: %{ix86}
- libdispatch
ExclusiveArch: x86_64 aarch64 ppc64le
- libffado
ExcludeArch: s390 s390x
- libfilezilla
ExcludeArch: s390x
- libfonts
ExclusiveArch: %{java_arches} noarch
- libformula
ExclusiveArch: %{java_arches} noarch
- libfprint
ExcludeArch: s390 s390x
- libguestfs
ExcludeArch: %{ix86}
ExclusiveArch: %{kernel_arches}
ExcludeArch: %{power64}
- libhomfly
ExcludeArch: %{ix86}
- libibcommon
ExcludeArch: s390 s390x
- libica
ExclusiveArch: s390 s390x
- libiec61883
ExcludeArch: s390 s390x
- libinsane
ExcludeArch: %{ix86}
- libipt
ExclusiveArch: %{ix86} x86_64
ExclusiveArch: %{ix86} x86_64
- libkrun
ExclusiveArch: x86_64 aarch64
- libkrunfw
ExclusiveArch: x86_64 aarch64
- liblayout
ExclusiveArch: %{java_arches} noarch
- libldac
ExcludeArch: s390x
- libloader
ExclusiveArch: %{java_arches} noarch
- libnuml
ExcludeArch: %{ix86}
- libnxz
ExclusiveArch: ppc64le
- libobjc2
ExcludeArch: armv7hl i686 ppc64le s390x
- libocxl
ExclusiveArch: ppc64le
- libopenshot
ExcludeArch: ppc64le
- libopenshot-audio
ExcludeArch: ppc64le
- liborc
ExcludeArch: i686 armv7hl
- libpoly
ExcludeArch: %{ix86}
- libpsm2
ExclusiveArch: x86_64
- libquentier
ExclusiveArch: %{qt5_qtwebengine_arches}
- libraw1394
ExcludeArch: s390 s390x
- libreoffice
ExcludeArch: %{ix86}
- libreoffice-TexMaths
ExclusiveArch: %{java_arches}
ExcludeArch: aarch64 s390x
- librepository
ExclusiveArch: %{java_arches} noarch
- libretro-desmume2015
ExclusiveArch: i686 x86_64
- libretro-pcsx-rearmed
ExcludeArch: armv7hl
- librtas
ExclusiveArch: %{power64}
- libsavitar
ExcludeArch: %{ix86}
- libsedml
ExcludeArch: %{ix86}
- libsemigroups
ExcludeArch: %{ix86}
- libserializer
ExclusiveArch: %{java_arches} noarch
- libservicelog
ExclusiveArch: ppc %{power64}
- libsmbios
ExclusiveArch: x86_64 %{ix86}
- libsonata
ExcludeArch: %{ix86}
- libtracecmd
ExcludeArch: %{ix86} %{arm}
- libunibreak
ExcludeArch: %{ix86}
- libunicode
ExclusiveArch: x86_64 aarch64
- libunifex
ExcludeArch: i686
- libunwind
ExclusiveArch: %{arm} aarch64 hppa ia64 mips ppc %{power64} s390x %{ix86} x86_64 riscv64
- libva-intel-hybrid-driver
ExclusiveArch: %{ix86} x86_64 ia64
- libva-nvidia-driver
ExclusiveArch: %{x86_64} %{ix86} %{arm64} ppc64le
- libvirt-java
ExclusiveArch: %{java_arches} noarch
- libvma
ExclusiveArch: x86_64 ppc64le ppc64 aarch64
- libvmi
ExclusiveArch: x86_64
- libvpd
ExclusiveArch: %{power64}
- libvpl
ExclusiveArch: x86_64
- libx86
ExcludeArch: ppc %{power64} s390 s390x %{sparc} aarch64 armv7hl
- libxsmm
ExclusiveArch: x86_64
- libzdnn
ExclusiveArch: s390x
- libzfcphbaapi
ExclusiveArch: s390 s390x
- libzpc
ExclusiveArch: s390x
- liferea
ExcludeArch: %{ix86}
- linbox
ExcludeArch: %{ix86}
- linux-system-roles
ExcludeArch: i686
- liquidctl
ExcludeArch: s390 s390x
- lite-xl
ExcludeArch: %{ix86}
- llama-cpp
ExclusiveArch: x86_64 aarch64
- lld13
ExcludeArch: s390x
- lld15
ExcludeArch: s390x
- lld16
ExcludeArch: s390x
- lld17
ExcludeArch: s390x
- llhttp
ExclusiveArch: %{nodejs_arches}
- llvm-bolt
ExcludeArch: s390x ppc64le i686
- log4j
ExclusiveArch: %{java_arches} noarch
- log4net
ExclusiveArch: %mono_arches
- loupe
ExcludeArch: %{ix86}
- love
ExcludeArch: ppc ppc64 s390x
- lrmi
ExclusiveArch: %{ix86}
- lsvpd
ExclusiveArch: %{power64}
- luajit
ExcludeArch: riscv64 ppc64 ppc64le
- lucene
ExclusiveArch: %{java_arches} noarch
- luckybackup
ExcludeArch: %{ix86}
- lujavrite
ExclusiveArch: %{java_arches}
- luminance-hdr
ExcludeArch: %{ix86}
- lusol
ExcludeArch: %{ix86}
- luxcorerender
ExclusiveArch: x86_64
- lzfse
ExcludeArch: s390x
- m4rie
ExcludeArch: %{ix86}
- mactel-boot
ExclusiveArch: x86_64
- magicmirror
ExclusiveArch: %{nodejs_arches} noarch
- magicmirror-module-airnow
ExclusiveArch: %{nodejs_arches} noarch
- magicmirror-module-onthisday
ExclusiveArch: %{nodejs_arches} noarch
- magicmirror-module-singlestock
ExclusiveArch: %{nodejs_arches} noarch
- makemusic-finale-fonts
ExcludeArch: %{ix86}
- mame
ExcludeArch: %{arm} %{ix86}
- manifest-tool
ExclusiveArch: x86_64 aarch64 ppc64le s390x
- mapnik
ExcludeArch: ppc ppc64 s390 s390x
- marcsabatella-campania-fonts
ExcludeArch: %{ix86}
- mariadb-java-client
ExclusiveArch: %{java_arches} noarch
- marked
ExclusiveArch: %{nodejs_arches} noarch
ExclusiveArch: %{ix86} x86_64 %{arm} noarch
- mate-applets
ExcludeArch: i386 i686
- matrix-synapse
ExclusiveArch: %{rust_arches}
- maui-mauikit
ExclusiveArch: %{ix86} s390x aarch64 x86_64
- maven
ExclusiveArch: %{java_arches} noarch
- maven-antrun-plugin
ExclusiveArch: %{java_arches} noarch
- maven-archetype
ExclusiveArch: %{java_arches} noarch
- maven-archiver
ExclusiveArch: %{java_arches} noarch
- maven-artifact-transfer
ExclusiveArch: %{java_arches} noarch
- maven-assembly-plugin
ExclusiveArch: %{java_arches} noarch
- maven-bundle-plugin
ExclusiveArch: %{java_arches} noarch
- maven-clean-plugin
ExclusiveArch: %{java_arches} noarch
- maven-common-artifact-filters
ExclusiveArch: %{java_arches} noarch
- maven-compiler-plugin
ExclusiveArch: %{java_arches} noarch
- maven-dependency-analyzer
ExclusiveArch: %{java_arches} noarch
- maven-dependency-plugin
ExclusiveArch: %{java_arches} noarch
- maven-dependency-tree
ExclusiveArch: %{java_arches} noarch
- maven-doxia
ExclusiveArch: %{java_arches} noarch
- maven-doxia-sitetools
ExclusiveArch: %{java_arches} noarch
- maven-enforcer
ExclusiveArch: %{java_arches} noarch
- maven-file-management
ExclusiveArch: %{java_arches} noarch
- maven-filtering
ExclusiveArch: %{java_arches} noarch
- maven-invoker
ExclusiveArch: %{java_arches} noarch
- maven-invoker-plugin
ExclusiveArch: %{java_arches} noarch
- maven-jar-plugin
ExclusiveArch: %{java_arches} noarch
- maven-mapping
ExclusiveArch: %{java_arches} noarch
- maven-native
ExclusiveArch: %{java_arches} noarch
- maven-parent
ExclusiveArch: %{java_arches} noarch
- maven-patch-plugin
ExclusiveArch: %{java_arches} noarch
- maven-plugin-testing
ExclusiveArch: %{java_arches} noarch
- maven-plugin-tools
ExclusiveArch: %{java_arches} noarch
- maven-remote-resources-plugin
ExclusiveArch: %{java_arches} noarch
- maven-reporting-api
ExclusiveArch: %{java_arches} noarch
- maven-reporting-impl
ExclusiveArch: %{java_arches} noarch
- maven-resolver
ExclusiveArch: %{java_arches} noarch
- maven-resources-plugin
ExclusiveArch: %{java_arches} noarch
- maven-script-interpreter
ExclusiveArch: %{java_arches} noarch
- maven-shade-plugin
ExclusiveArch: %{java_arches} noarch
- maven-shared-incremental
ExclusiveArch: %{java_arches} noarch
- maven-shared-io
ExclusiveArch: %{java_arches} noarch
- maven-shared-utils
ExclusiveArch: %{java_arches} noarch
- maven-source-plugin
ExclusiveArch: %{java_arches} noarch
- maven-surefire
ExclusiveArch: %{java_arches} noarch
- maven-verifier
ExclusiveArch: %{java_arches} noarch
- maven-verifier-plugin
ExclusiveArch: %{java_arches} noarch
- maven-wagon
ExclusiveArch: %{java_arches} noarch
- maxima
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc sparcv9
ExclusiveArch: %{ix86} x86_64 ppc sparcv9
- mbpfan
ExclusiveArch: x86_64
- mcelog
ExclusiveArch: i686 x86_64
- mcqd
ExcludeArch: %{ix86}
- mcrouter
ExclusiveArch: x86_64 aarch64 ppc64le
- mecab-java
ExclusiveArch: %java_arches
- mediaconch
ExclusiveArch: %{qt5_qtwebengine_arches}
- mellowplayer
ExclusiveArch: %{qt5_qtwebengine_arches}
- memkind
ExclusiveArch: x86_64 ppc64 ppc64le s390x aarch64
- memtest86+
ExclusiveArch: x86_64 %{ix86}
- merkuro
ExclusiveArch: %{qt6_qtwebengine_arches}
- meshlab
ExclusiveArch: aarch64 x86_64
ExcludeArch: %{ix86}
- metamath
ExcludeArch: %{ix86}
- mfem
ExcludeArch: %{ix86}
- microcode_ctl
ExclusiveArch: %{ix86} x86_64
- micropython
ExclusiveArch: %{arm} x86_64 riscv64
- miglayout
ExclusiveArch: %{java_arches} noarch
- mine_detector
ExclusiveArch: %{GPRbuild_arches}
- minetest
ExclusiveArch: %{ix86} x86_64
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips} aarch64
- mingw-libidn2
ExclusiveArch: %{ix86} x86_64 %{arm}
- mingw-qt6-qtlocation
ExcludeArch: s390x
- mingw-wine-gecko
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64
- miopen
ExclusiveArch: x86_64
- mirrormanager2
ExcludeArch: %{ix86}
- mkbootdisk
ExclusiveArch: %{ix86} sparc sparc64 x86_64
- mlir
ExcludeArch: i686
- mlpack
ExcludeArch: s390
- mmapper
ExcludeArch: %{ix86}
- mmlib
ExcludeArch: %{ix86}
- moby-engine
ExclusiveArch: %{golang_arches}
- mockito
ExclusiveArch: %{java_arches} noarch
- mod_gnutls
ExcludeArch: %{ix86} %{arm}
- mod_mono
ExclusiveArch: %mono_arches
- mod_proxy_cluster
ExcludeArch: i686 i386
- modello
ExclusiveArch: %{java_arches} noarch
- moditect
ExclusiveArch: %{java_arches} noarch
- module-build-service
ExclusiveArch: %{ix86} x86_64 noarch
- modulemaker-maven-plugin
ExclusiveArch: %{java_arches} noarch
- mojo-executor
ExclusiveArch: %{java_arches} noarch
- mojo-parent
ExclusiveArch: %{java_arches} noarch
- mokutil
ExclusiveArch: %{ix86} x86_64 aarch64 %{arm}
- mold
ExcludeArch: %{ix86}
- mono
ExclusiveArch: %mono_arches
- mono-addins
ExclusiveArch: %mono_arches
- mono-basic
ExclusiveArch: %{mono_arches}
- mono-bouncycastle
ExclusiveArch: %mono_arches
ExcludeArch: armv7hl
- mono-cecil
ExclusiveArch: %mono_arches
- mono-cecil-flowanalysis
ExclusiveArch: %mono_arches
- mono-reflection
ExclusiveArch: %mono_arches
- mono-tools
ExclusiveArch: %mono_arches
- mono-zeroconf
ExclusiveArch: %mono_arches
- monodevelop
ExclusiveArch: %mono_arches
ExcludeArch: armv7hl
- monodevelop-debugger-gdb
ExclusiveArch: %{mono_arches}
ExcludeArch: armv7hl
- moose
ExcludeArch: s390x
- morphio
ExcludeArch: %{ix86}
- mozc
ExcludeArch: ppc ppc64 sparcv9 sparc64 s390x
- mozilla-ublock-origin
ExcludeArch: ppc64 s390x
- mp
ExcludeArch: %{ix86}
- mpark-patterns
ExcludeArch: %{ix86}
- mpi4py
ExcludeArch: %{ix86}
- mpibash
ExcludeArch: %{ix86}
- mpris-scrobbler
ExcludeArch: s390x
- mpsolve
ExcludeArch: %{ix86}
- mrchem
ExcludeArch: s390x
- mrcpp
ExcludeArch: s390x
- mrrescue
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc64le
- msolve
ExcludeArch: %{ix86}
- msr-tools
ExclusiveArch: %{ix86} x86_64
- mstflint
ExcludeArch: s390 s390x %{arm}
- msv
ExclusiveArch: %{java_arches} noarch
- mt32emu
ExcludeArch: %{ix86}
- muffin
ExcludeArch: %{ix86}
- mumble
ExcludeArch: %{ix86}
- mupen64plus
ExcludeArch: s390x
- musescore
ExcludeArch: %{ix86}
- musl
ExcludeArch: s390
- mvfst
ExclusiveArch: x86_64 aarch64 ppc64le
- mxparser
ExclusiveArch: %{java_arches} noarch
- mysql-connector-java
ExclusiveArch: %{java_arches} noarch
- mysql-connector-net
ExclusiveArch: %{mono_arches}
- naev
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips} aarch64
ExcludeArch: %{ix86}
- naga
ExclusiveArch: %{java_arches} noarch
- nagios-plugins-check-updates
ExcludeArch: %{ix86}
- nant
ExclusiveArch: %mono_arches
ExcludeArch: armv7hl
- nativejit
ExclusiveArch: x86_64
- nbc
ExclusiveArch: %{fpc_arches}
- nbdkit
ExcludeArch: i686
- ncl
ExcludeArch: %{ix86}
- ndesk-dbus
ExclusiveArch: %{mono_arches}
- ndesk-dbus-glib
ExclusiveArch: %{mono_arches}
- nekohtml
ExclusiveArch: %{java_arches} noarch
- nemo
ExcludeArch: %{ix86}
- nemo-extensions
ExcludeArch: %{ix86}
- nest
ExcludeArch: %{ix86}
- netatalk
ExcludeArch: aarch64 s390x
- netavark
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- netcdf-fortran
ExcludeArch: %{ix86}
- netdata
ExcludeArch: s390x
- neuron
ExcludeArch: mips64r2 mips32r2
ExcludeArch: %{ix86}
- newtonsoft-json
ExclusiveArch: %{mono_arches}
ExcludeArch: armv7hl
- nextcloud-client
ExcludeArch: %{ix86}
ExcludeArch: ppc64 ppc64le s390x
- nodejs-acorn-object-spread
ExclusiveArch: %{nodejs_arches} noarch
ExclusiveArch: %{ix86} x86_64 %{arm} noarch
- nodejs-backbone
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-bash-language-server
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-buble
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-cjs-module-lexer
ExclusiveArch: %{nodejs_arches} noarch
ExclusiveArch: %{ix86} x86_64 aarch64 ppc64le riscv64 noarch
- nodejs-colors
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-less
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-linefix
ExclusiveArch: %{nodejs_arches} noarch
ExclusiveArch: %{ix86} x86_64 %{arm} noarch
- nodejs-nodemon
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-packaging
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-replace-require-self
ExclusiveArch: %{nodejs_arches} noarch
- nodejs-underscore
ExclusiveArch: %{nodejs_arches} noarch
ExclusiveArch: %{ix86} x86_64 %{arm} noarch
- nodejs-undici
ExclusiveArch: %{ix86} x86_64 aarch64 ppc64le riscv64 noarch
- nodejs18
ExclusiveArch: %{nodejs_arches}
- nodejs20
ExclusiveArch: %{nodejs_arches}
- nom-tam-fits
ExclusiveArch: %{java_arches} noarch
- normaliz
ExcludeArch: %{ix86}
- not-ocamlfind
ExcludeArch: %{ix86}
- notejot
ExcludeArch: %{ix86}
- notify-sharp
ExclusiveArch: %{mono_arches}
- notify-sharp3
ExclusiveArch: %{mono_arches}
- ntfs2btrfs
ExcludeArch: ppc64 s390x
- nuget
ExclusiveArch: %{mono_arches}
- numactl
ExcludeArch: s390 %{arm}
- numatop
ExclusiveArch: x86_64 ppc64le
- numptyphysics
ExcludeArch: ppc64le
- nunit
ExclusiveArch: %{mono_arches}
- nunit2
ExclusiveArch: %{mono_arches}
ExcludeArch: armv7hl
- nut
ExcludeArch: s390 s390x
- nvml
ExclusiveArch: x86_64 ppc64le
- nwchem
ExcludeArch: %{ix86} s390x
ExcludeArch: s390x
- objectweb-asm
ExclusiveArch: %{java_arches} noarch
- objenesis
ExclusiveArch: %{java_arches} noarch
- obs-cef
ExclusiveArch: x86_64 aarch64
- obs-service-rust2rpm
ExclusiveArch: %{rust_arches} noarch
- obs-studio-plugin-vkcapture
ExcludeArch: s390x
- ocaml
ExcludeArch: %{ix86}
- ocaml-SDL
ExcludeArch: %{ix86}
- ocaml-alcotest
ExcludeArch: %{ix86}
- ocaml-astring
ExcludeArch: %{ix86}
- ocaml-atd
ExcludeArch: %{ix86}
- ocaml-augeas
ExcludeArch: %{ix86}
- ocaml-autoconf
ExcludeArch: %{ix86}
- ocaml-base
ExcludeArch: %{ix86}
- ocaml-base64
ExcludeArch: %{ix86}
- ocaml-benchmark
ExcludeArch: %{ix86}
- ocaml-bigarray-compat
ExcludeArch: %{ix86}
- ocaml-bin-prot
ExcludeArch: %{ix86}
- ocaml-biniou
ExcludeArch: %{ix86}
- ocaml-bisect-ppx
ExcludeArch: %{ix86}
- ocaml-bos
ExcludeArch: %{ix86}
- ocaml-cairo
ExcludeArch: %{ix86}
- ocaml-calendar
ExcludeArch: %{ix86}
- ocaml-camlbz2
ExcludeArch: %{ix86}
- ocaml-camlidl
ExcludeArch: %{ix86}
- ocaml-camlimages
ExcludeArch: %{ix86}
- ocaml-camlp-streams
ExcludeArch: %{ix86}
- ocaml-camlp5
ExcludeArch: %{ix86}
- ocaml-camlp5-buildscripts
ExcludeArch: %{ix86}
- ocaml-camomile
ExcludeArch: %{ix86}
- ocaml-cinaps
ExcludeArch: %{ix86}
- ocaml-cmdliner
ExcludeArch: %{ix86}
- ocaml-compiler-libs-janestreet
ExcludeArch: %{ix86}
- ocaml-cppo
ExcludeArch: %{ix86}
- ocaml-crunch
ExcludeArch: %{ix86}
- ocaml-cryptokit
ExcludeArch: %{ix86}
- ocaml-csexp
ExcludeArch: %{ix86}
- ocaml-csv
ExcludeArch: %{ix86}
- ocaml-ctypes
ExcludeArch: %{ix86}
- ocaml-cudf
ExcludeArch: %{ix86}
- ocaml-curl
ExcludeArch: %{ix86}
- ocaml-curses
ExcludeArch: %{ix86}
- ocaml-dbus
ExcludeArch: %{ix86}
- ocaml-dose3
ExcludeArch: %{ix86}
- ocaml-dune
ExcludeArch: %{ix86}
- ocaml-easy-format
ExcludeArch: %{ix86}
- ocaml-expat
ExcludeArch: %{ix86}
- ocaml-extlib
ExcludeArch: %{ix86}
- ocaml-facile
ExcludeArch: %{ix86}
- ocaml-fieldslib
ExcludeArch: %{ix86}
- ocaml-fileutils
ExcludeArch: %{ix86}
- ocaml-findlib
ExcludeArch: %{ix86}
- ocaml-fmt
ExcludeArch: %{ix86}
- ocaml-fpath
ExcludeArch: %{ix86}
- ocaml-gen
ExcludeArch: %{ix86}
- ocaml-gettext
ExcludeArch: %{ix86}
- ocaml-graphics
ExcludeArch: %{ix86}
- ocaml-gsl
ExcludeArch: %{ix86}
ExcludeArch: armv7hl
- ocaml-integers
ExcludeArch: %{ix86}
- ocaml-jane-street-headers
ExcludeArch: %{ix86}
- ocaml-jst-config
ExcludeArch: %{ix86}
- ocaml-lablgl
ExcludeArch: %{ix86}
- ocaml-lablgtk
ExcludeArch: %{ix86}
- ocaml-lablgtk3
ExcludeArch: %{ix86}
- ocaml-labltk
ExcludeArch: %{ix86}
- ocaml-lacaml
ExcludeArch: %{ix86}
- ocaml-lambda-term
ExcludeArch: %{ix86}
- ocaml-libvirt
ExcludeArch: %{ix86}
- ocaml-logs
ExcludeArch: %{ix86}
- ocaml-luv
ExcludeArch: %{ix86}
- ocaml-lwt
ExcludeArch: %{ix86}
- ocaml-markup
ExcludeArch: %{ix86}
- ocaml-mccs
ExcludeArch: %{ix86}
- ocaml-mdx
ExcludeArch: %{ix86}
- ocaml-menhir
ExcludeArch: %{ix86}
- ocaml-merlin
ExcludeArch: %{ix86}
- ocaml-mew
ExcludeArch: %{ix86}
- ocaml-mew-vi
ExcludeArch: %{ix86}
- ocaml-mlgmpidl
ExcludeArch: %{ix86}
- ocaml-mlmpfr
ExcludeArch: %{ix86}
- ocaml-mtime
ExcludeArch: %{ix86}
- ocaml-mysql
ExcludeArch: %{ix86}
- ocaml-num
ExcludeArch: %{ix86}
- ocaml-obuild
ExcludeArch: %{ix86}
- ocaml-ocamlbuild
ExcludeArch: %{ix86}
- ocaml-ocamlgraph
ExcludeArch: %{ix86}
- ocaml-ocamlnet
ExcludeArch: %{ix86}
- ocaml-ocp-indent
ExcludeArch: %{ix86}
- ocaml-ocplib-endian
ExcludeArch: %{ix86}
- ocaml-ocplib-simplex
ExcludeArch: %{ix86}
- ocaml-octavius
ExcludeArch: %{ix86}
- ocaml-odoc
ExcludeArch: %{ix86}
- ocaml-omake
ExcludeArch: %{ix86}
- ocaml-opam-file-format
ExcludeArch: %{ix86}
- ocaml-ounit
ExcludeArch: %{ix86}
- ocaml-parmap
ExcludeArch: %{ix86}
- ocaml-parsexp
ExcludeArch: %{ix86}
- ocaml-pcre
ExcludeArch: %{ix86}
- ocaml-pcre2
ExcludeArch: %{ix86}
- ocaml-perl4caml
ExcludeArch: %{ix86}
- ocaml-postgresql
ExcludeArch: %{ix86}
- ocaml-pp
ExcludeArch: %{ix86}
- ocaml-ppx-assert
ExcludeArch: %{ix86}
- ocaml-ppx-base
ExcludeArch: %{ix86}
- ocaml-ppx-cold
ExcludeArch: %{ix86}
- ocaml-ppx-compare
ExcludeArch: %{ix86}
- ocaml-ppx-custom-printf
ExcludeArch: %{ix86}
- ocaml-ppx-derivers
ExcludeArch: %{ix86}
- ocaml-ppx-deriving
ExcludeArch: %{ix86}
- ocaml-ppx-deriving-yaml
ExcludeArch: %{ix86}
- ocaml-ppx-deriving-yojson
ExcludeArch: %{ix86}
- ocaml-ppx-enumerate
ExcludeArch: %{ix86}
- ocaml-ppx-expect
ExcludeArch: %{ix86}
- ocaml-ppx-fields-conv
ExcludeArch: %{ix86}
- ocaml-ppx-globalize
ExcludeArch: %{ix86}
- ocaml-ppx-hash
ExcludeArch: %{ix86}
- ocaml-ppx-here
ExcludeArch: %{ix86}
- ocaml-ppx-import
ExcludeArch: %{ix86}
- ocaml-ppx-inline-test
ExcludeArch: %{ix86}
- ocaml-ppx-js-style
ExcludeArch: %{ix86}
- ocaml-ppx-let
ExcludeArch: %{ix86}
- ocaml-ppx-optcomp
ExcludeArch: %{ix86}
- ocaml-ppx-sexp-conv
ExcludeArch: %{ix86}
- ocaml-ppx-stable-witness
ExcludeArch: %{ix86}
- ocaml-ppx-variants-conv
ExcludeArch: %{ix86}
- ocaml-ppxlib
ExcludeArch: %{ix86}
- ocaml-psmt2-frontend
ExcludeArch: %{ix86}
- ocaml-ptime
ExcludeArch: %{ix86}
- ocaml-ptmap
ExcludeArch: %{ix86}
- ocaml-pyml
ExcludeArch: %{ix86}
- ocaml-qcheck
ExcludeArch: %{ix86}
- ocaml-qtest
ExcludeArch: %{ix86}
- ocaml-re
ExcludeArch: %{ix86}
- ocaml-react
ExcludeArch: %{ix86}
- ocaml-res
ExcludeArch: %{ix86}
- ocaml-result
ExcludeArch: %{ix86}
- ocaml-rresult
ExcludeArch: %{ix86}
- ocaml-sedlex
ExcludeArch: %{ix86}
- ocaml-sexplib
ExcludeArch: %{ix86}
- ocaml-sexplib0
ExcludeArch: %{ix86}
- ocaml-sha
ExcludeArch: %{ix86}
- ocaml-sqlite
ExcludeArch: %{ix86}
- ocaml-ssl
ExcludeArch: %{ix86}
- ocaml-stdcompat
ExcludeArch: %{ix86}
- ocaml-stdio
ExcludeArch: %{ix86}
- ocaml-stdlib-random
ExcludeArch: %{ix86}
- ocaml-time-now
ExcludeArch: %{ix86}
- ocaml-topkg
ExcludeArch: %{ix86}
- ocaml-trie
ExcludeArch: %{ix86}
- ocaml-tyxml
ExcludeArch: %{ix86}
- ocaml-unionfind
ExcludeArch: %{ix86}
- ocaml-uucd
ExcludeArch: %{ix86}
- ocaml-uucp
ExcludeArch: %{ix86}
- ocaml-uunf
ExcludeArch: %{ix86}
- ocaml-uuseg
ExcludeArch: %{ix86}
- ocaml-uutf
ExcludeArch: %{ix86}
- ocaml-variantslib
ExcludeArch: %{ix86}
- ocaml-version
ExcludeArch: %{ix86}
- ocaml-xml-light
ExcludeArch: %{ix86}
- ocaml-xmlm
ExcludeArch: %{ix86}
- ocaml-xmlrpc-light
ExcludeArch: %{ix86}
- ocaml-yaml
ExcludeArch: %{ix86}
- ocaml-yojson
ExcludeArch: %{ix86}
- ocaml-zarith
ExcludeArch: %{ix86}
- ocaml-zed
ExcludeArch: %{ix86}
- ocaml-zip
ExcludeArch: %{ix86}
- ocaml-zmq
ExcludeArch: %{ix86}
- ocamlify
ExcludeArch: %{ix86}
- ocamlmod
ExcludeArch: %{ix86}
- oci-seccomp-bpf-hook
ExclusiveArch: x86_64 %{power64} aarch64 s390x armv7hl
ExclusiveArch: %{golang_arches_future}
- ocrmypdf
ExcludeArch: %{ix86}
- octave-communications
ExcludeArch: s390x
- octave-iso2mesh
ExcludeArch: armv7hl
- octave-signal
ExcludeArch: s390x
- odio-sacd
ExcludeArch: ppc64le
- oidc-agent
ExcludeArch: %{ix86}
- oidn
ExclusiveArch: x86_64
- oneVPL
ExclusiveArch: x86_64
- oneVPL-intel-gpu
ExclusiveArch: x86_64
- oneapi-level-zero
ExclusiveArch: x86_64
- onednn
ExclusiveArch: x86_64 aarch64 ppc64le s390x
- onedrive
ExclusiveArch: %{ldc_arches}
- ongres-scram
ExclusiveArch: %{java_arches} noarch
- ongres-stringprep
ExclusiveArch: %{java_arches} noarch
- onnx
ExcludeArch: s390x
- onnxruntime
ExcludeArch: s390x %{arm} %{ix86}
- oomd
ExcludeArch: i686 armv7hl
- opae
ExclusiveArch: x86_64
- opal-prd
ExclusiveArch: ppc64le
- opam
ExcludeArch: %{ix86}
- open-vm-tools
ExclusiveArch: x86_64 aarch64
ExclusiveArch: %{ix86} x86_64 aarch64
ExclusiveArch: x86_64
- openblas
ExclusiveArch: %{openblas_arches}
- opencsg
ExcludeArch: %{ix86}
- opengrm-ngram
ExcludeArch: %{ix86}
- openjdk-asmtools
ExclusiveArch: %{java_arches} noarch
- openjdk-asmtools7
ExclusiveArch: %{java_arches} noarch
- openjfx
ExclusiveArch: %{java_arches}
- openjfx8
ExclusiveArch: x86_64
- openlibm
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 %{power64}
- openmeeg
ExcludeArch: s390x
- openmpi
ExcludeArch: %{ix86}
- openms
ExclusiveArch: %{qt5_qtwebengine_arches}
ExcludeArch: %{ix86}
- openni
ExclusiveArch: x86_64 %{arm}
- openni-primesense
ExclusiveArch: x86_64 %{arm}
- openobex
ExcludeArch: s390 s390x
- openoffice.org-diafilter
ExclusiveArch: %{java_arches}
- openpgl
ExclusiveArch: aarch64 x86_64
- openrgb
ExcludeArch: %{ix86}
- openscad
ExcludeArch: %{ix86}
- openshadinglanguage
ExcludeArch: %{ix86} %{arm}
- openshot
ExcludeArch: ppc64le
- opensm
ExcludeArch: s390 %{arm}
- openssl-ibmca
ExclusiveArch: s390 s390x
- openstack-java-sdk
ExclusiveArch: %{java_arches} noarch
- opentest4j
ExclusiveArch: %{java_arches} noarch
- opentype-sanitizer
ExcludeArch: %{ix86}
- openvdb
ExcludeArch: i686
- openvkl
ExclusiveArch: aarch64 x86_64
- optee_client
ExclusiveArch: aarch64
- optee_os
ExclusiveArch: aarch64
- options
ExclusiveArch: %{java_arches} noarch
- orthorobot
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc64le
- os-autoinst
ExcludeArch: %{arm}
- osbuild-composer
ExcludeArch: i686 armv7hl
- osgi-annotation
ExclusiveArch: %{java_arches} noarch
- osgi-compendium
ExclusiveArch: %{java_arches} noarch
- osgi-core
ExclusiveArch: %{java_arches} noarch
- osm2pgsql
ExcludeArch: %{ix86}
- osslsigncode
ExcludeArch: i686
- ostree
ExcludeArch: %{ix86}
- otf2
ExcludeArch: i686 s390x
- oz
ExcludeArch: %{ix86}
- pacemaker
ExclusiveArch: aarch64 i686 ppc64le s390x x86_64 %{arm}
ExclusiveArch: aarch64 i686 ppc64le s390x x86_64
- pageedit
ExclusiveArch: %{qt5_qtwebengine_arches}
- paperwork
ExcludeArch: %{ix86}
- papi
ExcludeArch: s390 s390x
- papilo
ExcludeArch: %{ix86}
- paraview
ExcludeArch: %{ix86}
- pari-nftables
ExcludeArch: %{ix86}
- parlaylib
ExcludeArch: aarch64 s390x arm-hfp ppc64le i686
- parserng
ExclusiveArch: %{java_arches} noarch
- pasdoc
ExclusiveArch: %{fpc_arches}
- pcc
ExclusiveArch: %{ix86} x86_64
- pcem
ExcludeArch: armv7hl i686 ppc64le s390x
- pcfi
ExclusiveArch: %{java_arches} noarch
- pcg-cpp
ExcludeArch: %{ix86}
- pcm
ExclusiveArch: %{ix86} x86_64
- pcp
ExcludeArch: %{ix86}
- pcp2pdf
ExcludeArch: %{ix86}
- pdbg
ExclusiveArch: ppc64le
- pdfarranger
ExcludeArch: %{ix86}
- pdfbox
ExclusiveArch: %{java_arches} noarch
- pdfmod
ExclusiveArch: %mono_arches
- pdftk-java
ExclusiveArch: %{java_arches} noarch
- pdns
ExcludeArch: %{arm} %{ix86}
- pdns-recursor
ExcludeArch: %{arm} %{ix86}
- pdqsort
ExcludeArch: %{ix86}
- pengupop
ExcludeArch: s390x
- pentaho-libxml
ExclusiveArch: %{java_arches} noarch
- pentaho-reporting-flow-engine
ExclusiveArch: %{java_arches} noarch
- perftest
ExcludeArch: s390 %{arm}
- perl-Dumbbench
ExclusiveArch: %{ix86} x86_64 noarch
- perl-LMDB_File
ExcludeArch: armv7hl i686
- perl-Math-Int128
ExcludeArch: %{arm32} %{ix86}
- perl-MaxMind-DB-Reader-XS
ExcludeArch: %{arm} %{ix86}
- perl-MongoDB
ExcludeArch: ppc %{sparc} s390
- perl-Net-Works
ExcludeArch: %{arm32} %{ix86}
- perl-Parse-DMIDecode
ExclusiveArch: %{ix86} x86_64 ia64 aarch64
- perl-threads-lite
ExcludeArch: aarch64 ppc ppc64 ppc64le
- permlib
ExcludeArch: %{ix86}
- pesign
ExclusiveArch: %{ix86} x86_64 ia64 aarch64 %{arm}
- pesign-test-app
ExclusiveArch: x86_64
- pf-bb-config
ExcludeArch: s390x
- pgadmin4
ExcludeArch: i686 armv7hl s390x ppc64le
- phd2
ExcludeArch: %{ix86}
- phosh
ExcludeArch: i686
- phosh-mobile-settings
ExcludeArch: i686
- php-pecl-mongodb
ExcludeArch: %{ix86}
- picard
ExcludeArch: ppc64
- picocli
ExclusiveArch: %{java_arches} noarch
- pigeonascent
ExcludeArch: ppc64le
ExcludeArch: s390x
- pilot-link
ExcludeArch: s390 s390x
- pinta
ExclusiveArch: %mono_arches
ExcludeArch: armv7hl
- pioneer
ExclusiveArch: %{ix86} x86_64
- pl
ExcludeArch: %{ix86}
- planets
ExcludeArch: %{ix86}
- plantri
ExcludeArch: %{ix86}
- plantuml
ExclusiveArch: %{java_arches} noarch
- plasma-dialer
ExclusiveArch: %{java_arches}
- playonlinux
ExclusiveArch: %{arm} aarch64 %{ix86} x86_64
- plee-the-bear
ExcludeArch: %{power64}
- plexus-archiver
ExclusiveArch: %{java_arches} noarch
- plexus-build-api
ExclusiveArch: %{java_arches} noarch
- plexus-build-api0
ExclusiveArch: %{java_arches} noarch
- plexus-cipher
ExclusiveArch: %{java_arches} noarch
- plexus-classworlds
ExclusiveArch: %{java_arches} noarch
- plexus-compiler
ExclusiveArch: %{java_arches} noarch
- plexus-component-api
ExclusiveArch: %{java_arches} noarch
- plexus-components-pom
ExclusiveArch: %{java_arches} noarch
- plexus-containers
ExclusiveArch: %{java_arches} noarch
- plexus-i18n
ExclusiveArch: %{java_arches} noarch
- plexus-interpolation
ExclusiveArch: %{java_arches} noarch
- plexus-io
ExclusiveArch: %{java_arches} noarch
- plexus-languages
ExclusiveArch: %{java_arches} noarch
- plexus-pom
ExclusiveArch: %{java_arches} noarch
- plexus-resources
ExclusiveArch: %{java_arches} noarch
- plexus-sec-dispatcher
ExclusiveArch: %{java_arches} noarch
- plexus-testing
ExclusiveArch: %{java_arches} noarch
- plexus-utils
ExclusiveArch: %{java_arches} noarch
- plexus-velocity
ExclusiveArch: %{java_arches} noarch
- plexus-xml
ExclusiveArch: %{java_arches} noarch
- pmix
ExcludeArch: %{ix86}
- pngcheck
ExcludeArch: %{ix86}
- podman
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- polymake
ExcludeArch: %{ix86}
- polyml
ExcludeArch: %{ix86}
- poppler-sharp
ExclusiveArch: %mono_arches
- popub
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
- postgresql-jdbc
ExclusiveArch: %{java_arches} noarch
- postgresql-pgpool-II
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
- powerpc-utils
ExclusiveArch: ppc %{power64}
- powerstat
ExclusiveArch: %{ix86} x86_64
- ppc64-diag
ExclusiveArch: ppc %{power64}
- ppl
ExcludeArch: %{ix86}
- pplite
ExcludeArch: %{ix86}
- prestopalette
ExcludeArch: i686
- printer-driver-brlaser
ExcludeArch: %{ix86}
- procdump
ExcludeArch: ppc64le
- procyon
ExclusiveArch: %{java_arches} noarch
ExclusiveArch: %{java_arches} noarch
ExclusiveArch: %{java_arches} noarch
ExclusiveArch: %{java_arches} noarch
ExclusiveArch: %{java_arches} noarch
ExclusiveArch: %{java_arches} noarch
- proguard
ExclusiveArch: %{java_arches} noarch
- prometheus-jmx-exporter
ExclusiveArch: %{java_arches} noarch
- prometheus-simpleclient-java
ExclusiveArch: %{java_arches} noarch
- prooftree
ExcludeArch: %{ix86}
- proxmark3
ExcludeArch: ppc64le s390x
- proxygen
ExclusiveArch: x86_64 aarch64 ppc64le
- proxysql
ExcludeArch: %{power64} s390x
- prrte
ExcludeArch: %{ix86}
- prusa-slicer
ExcludeArch: %{ix86}
- psblas3
ExcludeArch: %{ix86}
- purple-telegram
ExcludeArch: s390x
ExcludeArch: ppc64
- pveclib
ExclusiveArch: ppc %{power64}
- pygrib
ExcludeArch: i686
ExcludeArch: armv7hl
- pygsl
ExcludeArch: %{ix86}
- pyosmium
ExcludeArch: %{ix86}
- pypy
ExcludeArch: %{ix86}
- pypy3.10
ExcludeArch: %{ix86}
- pypy3.9
ExcludeArch: %{ix86}
- pyqtwebengine
ExclusiveArch: %{qt5_qtwebengine_arches}
- python-ZEO
ExcludeArch: %{ix86}
- python-ZODB3
ExcludeArch: %{ix86}
- python-aioresponses
ExcludeArch: s390x
- python-ast-monitor
ExclusiveArch: %{qt6_qtwebengine_arches} noarch
- python-astroplan
ExcludeArch: %{ix86}
- python-astroscrappy
ExcludeArch: %{ix86}
- python-asyncmy
ExcludeArch: %{ix86}
- python-aws-sam-translator
ExcludeArch: %{ix86}
- python-awscrt
ExcludeArch: s390x
- python-bitstruct
ExcludeArch: s390x
- python-blosc2
ExcludeArch: %{ix86}
- python-bluepyopt
ExcludeArch: s390x %{ix86} %{power64}
- python-chaospy
ExcludeArch: %{ix86} %{arm32}
- python-colorcet
ExcludeArch: %{ix86}
- python-colorthief
ExcludeArch: %{ix86}
- python-compreffor
ExcludeArch: %{ix86}
- python-contextualbandits
ExcludeArch: %{ix86}
- python-cradox
ExcludeArch: i686 armv7hl
- python-cryptography
ExclusiveArch: %{rust_arches}
- python-cvxopt
ExcludeArch: %{ix86}
- python-cyipopt
ExcludeArch: %{ix86}
- python-dask
ExcludeArch: %{ix86}
- python-databases
ExcludeArch: %{ix86}
- python-devicely
ExcludeArch: s390x
- python-dijitso
ExcludeArch: i686
- python-dipy
ExcludeArch: %{ix86} s390x
- python-ducc0
ExcludeArch: %{ix86}
- python-earthpy
ExcludeArch: %{ix86}
- python-eccodes
ExcludeArch: i686
ExcludeArch: armv7hl
- python-efel
ExcludeArch: s390x
- python-elephant
ExcludeArch: s390x
ExcludeArch: %{ix86}
- python-ephyviewer
ExcludeArch: s390x %{ix86}
- python-etcd
ExclusiveArch: noarch %{ix86} x86_64 %{arm} aarch64 ppc64le s390x riscv64
- python-fastavro
ExcludeArch: %{arm32} %{ix86}
- python-folium
ExcludeArch: %{ix86}
- python-formulaic
ExcludeArch: %{ix86}
- python-fsleyes
ExcludeArch: %{ix86}
- python-fsleyes-props
ExcludeArch: %{ix86}
- python-fslpy
ExcludeArch: %{ix86}
- python-gbinder
ExcludeArch: %{ix86}
- python-giacpy
ExcludeArch: aarch64 %{power64} s390x
- python-graph-tool
ExcludeArch: %{ix86}
- python-hdfs
ExcludeArch: %{ix86}
- python-healpy
ExcludeArch: %{ix86} %{arm}
- python-heapdict
ExcludeArch: %{ix86}
- python-img2pdf
ExcludeArch: s390x
- python-intbitset
ExcludeArch: s390x
- python-javaobj
ExclusiveArch: %{java_arches} noarch
- python-jnius
ExclusiveArch: %{java_arches}
ExclusiveArch: %{java_arches}
- python-json-minify
ExcludeArch: %{ix86}
- python-jupymake
ExcludeArch: %{ix86}
- python-jupyter-c-kernel
ExcludeArch: %{ix86}
- python-jupyter-kernel-singular
ExcludeArch: %{ix86}
- python-jupyter-polymake
ExcludeArch: %{ix86}
- python-jupyter-sphinx
ExcludeArch: %{ix86}
- python-lazy-ops
ExcludeArch: %{ix86}
- python-lfpy
ExcludeArch: mips64r2 mips32r2
ExcludeArch: %{power64} %{ix86} armv7hl
- python-mapnik
ExcludeArch: ppc ppc64 s390 s390x
- python-missingno
ExcludeArch: %{ix86}
- python-mne
ExcludeArch: %{ix86}
- python-mne-bids
ExcludeArch: %{ix86}
- python-mplcairo
ExcludeArch: %{ix86}
- python-mplcursors
ExcludeArch: %{ix86}
- python-music21
ExcludeArch: %{ix86}
- python-ndindex
ExcludeArch: %{ix86}
- python-neatdend
ExcludeArch: %{ix86}
- python-neo
ExcludeArch: s390x
- python-netpyne
ExcludeArch: %{ix86}
- python-neurom
ExcludeArch: %{ix86}
- python-neurotune
ExcludeArch: %{ix86}
- python-numpoly
ExcludeArch: %{ix86}
- python-octave-kernel
ExcludeArch: %{ix86}
- python-openoffice
ExclusiveArch: noarch x86_64
- python-openpaperwork-core
ExcludeArch: %{ix86}
- python-openpaperwork-gtk
ExcludeArch: %{ix86}
- python-opentype-sanitizer
ExcludeArch: %{ix86}
- python-pandas-flavor
ExcludeArch: %{ix86}
- python-papermill
ExcludeArch: %{ix86}
- python-paperwork-backend
ExcludeArch: %{ix86}
- python-param
ExcludeArch: %{ix86}
- python-pari-jupyter
ExcludeArch: %{ix86}
- python-pep8-naming
ExcludeArch: %{ix86}
- python-phyghtmap
ExcludeArch: %{ix86}
- python-pingouin
ExcludeArch: %{ix86}
- python-plotnine
ExcludeArch: %{ix86}
- python-pplpy
ExcludeArch: %{ix86}
- python-primecountpy
ExcludeArch: %{ix86}
- python-psycopg3
ExcludeArch: %{ix86}
- python-pyahocorasick
ExclusiveArch: x86_64 %{arm64} ppc64le riscv64
- python-pybids
ExcludeArch: %{ix86}
- python-pybv
ExcludeArch: %{ix86}
- python-pyct
ExcludeArch: %{ix86}
- python-pyedflib
ExcludeArch: s390x
- python-pyfastnoisesimd
ExcludeArch: %{ix86}
- python-pyfiglet
ExcludeArch: %{ix86}
- python-pykdtree
ExcludeArch: %{ix86}
- python-pyliblzfse
ExcludeArch: s390x
- python-pymapvbvd
ExcludeArch: s390x
- python-pymatreader
ExcludeArch: %{ix86}
ExcludeArch: s390x
- python-pynn
ExcludeArch: mips64r2 mips32r2 s390x %{ix86}
- python-pyocr
ExcludeArch: %{ix86}
- python-pypet
ExcludeArch: %{ix86}
ExcludeArch: s390x
- python-pyphi
ExcludeArch: s390x
- python-pypillowfight
ExcludeArch: %{ix86}
- python-pyqt6-webengine
ExclusiveArch: %{qt6_qtwebengine_arches}
- python-pyroaring
ExcludeArch: %{ix86}
- python-pyscf
ExcludeArch: %{power64}
- python-pyshtools
ExcludeArch: %{ix86}
- python-pysingular
ExcludeArch: %{ix86}
- python-pyswarms
ExcludeArch: %{ix86}
- python-pyswip
ExcludeArch: %{ix86}
- python-pytest-arraydiff
ExcludeArch: %{ix86}
- python-pytest-tornado
ExcludeArch: %{ix86}
- python-pyvat
ExcludeArch: %{ix86}
- python-ratinabox
ExcludeArch: %{ix86}
- python-recordclass
ExcludeArch: %{ix86}
- python-reproject
ExcludeArch: %{ix86}
- python-ruffus
ExcludeArch: %{ix86}
- python-scikit-learn
ExcludeArch: %{ix86}
- python-sgp4
ExcludeArch: %{ix86}
- python-simplebayes
ExcludeArch: %{ix86}
- python-sklearn-genetic-opt
ExcludeArch: %{ix86}
- python-statsmodels
ExcludeArch: %{ix86}
- python-steps
ExcludeArch: %{ix86}
- python-tables
ExcludeArch: %{ix86}
- python-tdlib
ExcludeArch: %{ix86}
- python-tensile
ExclusiveArch: x86_64
- python-tkrzw
ExcludeArch: i686
- python-torch
ExclusiveArch: x86_64 aarch64
- python-torchdata
ExclusiveArch: x86_64 aarch64
- python-torchvision
ExclusiveArch: x86_64 aarch64
- python-traitsui
ExcludeArch: ppc64le
- python-trimesh
ExcludeArch: %{ix86}
- python-uranium
ExcludeArch: %{ix86}
- python-willow
ExcludeArch: %{ix86}
- python-xattr
ExcludeArch: %{ix86}
- python-xbout
ExcludeArch: %{ix86}
- python-xmp-toolkit
ExcludeArch: %{ix86}
- python-zeep
ExcludeArch: s390x
- python-zict
ExcludeArch: %{ix86}
- q4wine
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64
- qalculate-qt
ExcludeArch: %{ix86}
- qatengine
ExclusiveArch: x86_64
- qatlib
ExcludeArch: %{arm} aarch64 %{power64} s390x i686
- qatzip
ExclusiveArch: x86_64
- qbe
ExclusiveArch: x86_64 aarch64 riscv64
- qbittorrent
ExcludeArch: %{ix86}
- qbs
ExcludeArch: i686
- qcas
ExcludeArch: aarch64 %{power64} s390x
- qcint
ExclusiveArch: x86_64
- qclib
ExclusiveArch: s390 s390x
- qdigidoc
ExcludeArch: %{ix86}
- qdox
ExclusiveArch: %{java_arches} noarch
- qemu-sanity-check
ExclusiveArch: %{kernel_arches}
ExcludeArch: %{power64}
- qevercloud
ExclusiveArch: %{qt5_qtwebengine_arches}
- qflipper
ExcludeArch: %{ix86}
- qmapshack
ExclusiveArch: %{qt5_qtwebengine_arches}
- qoauth
ExcludeArch: ppc64
- qownnotes
ExcludeArch: %{ix86}
- qpdfview
ExcludeArch: s390x
- qperf
ExcludeArch: %{arm}
- qsopt-ex
ExcludeArch: %{ix86}
- qt4pas
ExclusiveArch: %{fpc_arches}
- qt5-qtwebengine
ExclusiveArch: %{qt5_qtwebengine_arches}
- qt6-qtwebengine
ExclusiveArch: aarch64 x86_64
- qt6-qtwebview
ExclusiveArch: aarch64 x86_64
- qt6ct
ExcludeArch: s390x
- qtile
ExcludeArch: %{ix86}
- quantum-espresso
ExclusiveArch: x86_64 aarch64 %{power64}
- quentier
ExclusiveArch: %{qt5_qtwebengine_arches}
- rEFInd
ExclusiveArch: %{efi}
ExcludeArch: %{arm32}
- racket
ExcludeArch: %{arm} s390x
ExcludeArch: ppc64le
- rasdaemon
ExcludeArch: s390 s390x
- rdma-core
ExcludeArch: %{arm}
- realtime-tests
ExcludeArch: %{arm}
- rear
ExclusiveArch: %ix86 x86_64 ppc ppc64 ppc64le ia64 s390x
- redeclipse
ExcludeArch: %{ix86}
- reflections
ExclusiveArch: %{java_arches} noarch
- reg
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 aarch64 %{arm}}
- regexp
ExclusiveArch: %{java_arches} noarch
- relaxng-datatype-java
ExclusiveArch: %{java_arches} noarch
- remake
ExcludeArch: %{ix86}
- renderdoc
ExclusiveArch: x86_64 aarch64
- replacer
ExclusiveArch: %{java_arches} noarch
- reptyr
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64
- rescene
ExclusiveArch: %{mono_arches}
- resteasy
ExclusiveArch: %{java_arches} noarch
- restool
ExclusiveArch: aarch64
- restsharp
ExclusiveArch: %{mono_arches}
ExcludeArch: armv7hl
- retroarch
ExcludeArch: %{ix86}
ExcludeArch: s390x
- retsnoop
ExclusiveArch: %{rust_arches}
ExcludeArch: armv7hl
- rhino
ExclusiveArch: %{java_arches} noarch
ExcludeArch: %{ix86}
- rhythmbox
ExcludeArch: s390 s390x
- rhythmbox-alternative-toolbar
ExcludeArch: s390 s390x
- rhythmbox-ampache
ExcludeArch: s390 s390x
- river
ExclusiveArch: %{zig_arches}
- rkcommon
ExclusiveArch: x86_64 aarch64
- rocalution
ExclusiveArch: x86_64
- rocblas
ExclusiveArch: x86_64
- rocclr
ExclusiveArch: x86_64
- rocfft
ExclusiveArch: x86_64
- rocm-compilersupport
ExclusiveArch: x86_64 aarch64 ppc64le
- rocm-core
ExclusiveArch: x86_64
- rocm-device-libs
ExclusiveArch: x86_64 aarch64 ppc64le
- rocm-rpm-macros
ExclusiveArch: x86_64
- rocm-runtime
ExclusiveArch: x86_64 aarch64 ppc64le
- rocm-smi
ExclusiveArch: x86_64 aarch64 ppc64le riscv64
- rocminfo
ExclusiveArch: x86_64 aarch64 ppc64le
- rocprim
ExclusiveArch: x86_64
- rocrand
ExclusiveArch: x86_64
- rocsolver
ExclusiveArch: x86_64
- rocsparse
ExclusiveArch: x86_64
- rocthrust
ExclusiveArch: x86_64
- roctracer
ExclusiveArch: x86_64
- rpi-imager
ExcludeArch: s390x
- rpm-ostree
ExclusiveArch: %{rust_arches}
ExcludeArch: %{ix86}
- rr
ExclusiveArch: %{ix86} x86_64 aarch64
- rssguard
ExclusiveArch: %{qt6_qtwebengine_arches}
- rstudio
ExclusiveArch: %{java_arches}
- rsyntaxtextarea
ExclusiveArch: %{java_arches} noarch
- rubiks
ExcludeArch: %{ix86}
- rubygem-childprocess
ExclusiveArch: %{ix86} x86_64 noarch
- ruff
ExcludeArch: %{ix86}
- ruff-lsp
ExcludeArch: %{ix86}
- runc
ExclusiveArch: %{golang_arches_future}
- rundoc
ExclusiveArch: %{java_arches} noarch
- rust
ExclusiveArch: %{rust_arches}
- rust-bankstown-lv2
ExcludeArch: ppc64le s390x
- rust-below
ExcludeArch: %{arm32} %{ix86}
- rust-below-btrfs
ExcludeArch: %{arm32} %{ix86}
- rust-below-config
ExcludeArch: %{arm32} %{ix86}
- rust-below-dump
ExcludeArch: %{arm32} %{ix86}
- rust-below-model
ExcludeArch: %{arm32} %{ix86}
- rust-compress-tools
ExclusiveArch: %{rust_arches}
- rust-crypto-auditing-agent
ExcludeArch: i386 i686
- rust-ct-logs
ExcludeArch: ppc64le s390x
- rust-ctr
ExclusiveArch: %{rust_arches}
- rust-dashmap4
ExclusiveArch: %{rust_arches}
- rust-deflate
ExclusiveArch: %{rust_arches}
- rust-deflate0.8
ExclusiveArch: %{rust_arches}
- rust-getch
ExclusiveArch: %{rust_arches}
- rust-gzip-header
ExclusiveArch: %{rust_arches}
- rust-hamming
ExclusiveArch: %{rust_arches}
- rust-hidapi
ExclusiveArch: %{rust_arches}
- rust-httparse
ExclusiveArch: %{rust_arches}
- rust-humantime-serde
ExclusiveArch: %{rust_arches}
- rust-hyperlocal
ExclusiveArch: %{rust_arches}
- rust-inflate
ExclusiveArch: %{rust_arches}
- rust-k9
ExclusiveArch: %{rust_arches}
- rust-krunvm
ExclusiveArch: x86_64 aarch64
- rust-kstring
ExclusiveArch: %{rust_arches}
- rust-kvm-bindings
ExcludeArch: %{ix86}
- rust-kvm-ioctls
ExclusiveArch: x86_64 aarch64
- rust-lebe
ExclusiveArch: %{rust_arches}
- rust-lv2
ExcludeArch: ppc64le s390x
- rust-lv2-atom
ExcludeArch: ppc64le s390x
- rust-lv2-core
ExcludeArch: ppc64le s390x
- rust-lv2-midi
ExcludeArch: ppc64le s390x
- rust-lv2-state
ExcludeArch: ppc64le s390x
- rust-lv2-sys
ExcludeArch: ppc64le s390x
- rust-lv2-time
ExcludeArch: ppc64le s390x
- rust-lv2-units
ExcludeArch: ppc64le s390x
- rust-lv2-urid
ExcludeArch: ppc64le s390x
- rust-lv2-worker
ExcludeArch: ppc64le s390x
- rust-msru
ExclusiveArch: x86_64
- rust-nanorand
ExclusiveArch: %{rust_arches}
- rust-netstat2
ExclusiveArch: %{rust_arches}
- rust-nu
ExcludeArch: %{ix86}
- rust-oci-spec
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
ExcludeArch: %{ix86}
- rust-onig
ExclusiveArch: %{rust_arches}
- rust-openat-ext
ExclusiveArch: %{rust_arches}
- rust-os_type
ExclusiveArch: %{rust_arches}
- rust-pager
ExclusiveArch: %{rust_arches}
- rust-pathsearch
ExclusiveArch: %{rust_arches}
- rust-prefixdevname
ExcludeArch: %{ix86}
- rust-pretty-bytes
ExclusiveArch: %{rust_arches}
- rust-primal-bit
ExclusiveArch: %{rust_arches}
- rust-primal-check
ExclusiveArch: %{rust_arches}
- rust-primal-estimate
ExclusiveArch: %{rust_arches}
- rust-probe
ExcludeArch: ppc64le s390x
- rust-procfs0.9
ExclusiveArch: %{rust_arches}
- rust-psl-types
ExclusiveArch: %{rust_arches}
- rust-psm
ExclusiveArch: %{rust_arches}
- rust-pwd
ExclusiveArch: %{rust_arches}
- rust-rand_core
ExclusiveArch: %{rust_arches}
- rust-schemafy_core
ExclusiveArch: %{rust_arches}
- rust-schemafy_lib
ExclusiveArch: %{rust_arches}
- rust-scx_layered
ExcludeArch: %{ix86}
- rust-scx_rustland
ExcludeArch: %{ix86}
- rust-scx_rusty
ExcludeArch: %{ix86}
- rust-scx_utils
ExcludeArch: %{ix86}
- rust-seahash
ExclusiveArch: %{rust_arches}
- rust-sequoia-octopus-librnp
ExcludeArch: %{ix86} %{arm} s390x
- rust-serde_yaml0.8
ExclusiveArch: %{rust_arches}
- rust-sev
ExclusiveArch: x86_64
- rust-sevctl
ExclusiveArch: x86_64
- rust-sinit
ExclusiveArch: %{rust_arches}
- rust-snphost
ExclusiveArch: x86_64
- rust-ssh-key-dir
ExclusiveArch: %{rust_arches}
- rust-stacker
ExclusiveArch: %{rust_arches}
- rust-structopt
ExclusiveArch: %{rust_arches}
- rust-tiny-dfr
ExcludeArch: %{ix86}
- rust-totp-lite
ExclusiveArch: %{rust_arches}
- rust-tower-layer
ExclusiveArch: %{rust_arches}
- rust-tpm2-policy
ExclusiveArch: %{rust_arches}
- rust-unicode-normalization
ExclusiveArch: %{rust_arches}
- rust-unicode-xid
ExclusiveArch: %{rust_arches}
- rust-uriparse
ExclusiveArch: %{rust_arches}
- rust-varlink_generator
ExclusiveArch: %{rust_arches}
- rust-varlink_parser
ExclusiveArch: %{rust_arches}
- rust-vhost-device-scmi
ExcludeArch: s390x
- rust-virtio-bindings
ExclusiveArch: x86_64 aarch64 ppc64le riscv64
- rust-virtio-queue
ExcludeArch: i686
- rust-vm-memory
ExcludeArch: %{ix86}
- rust-vmm-sys-util
ExclusiveArch: x86_64 aarch64 ppc64le riscv64
- rust-vtparse
ExclusiveArch: %{rust_arches}
- rust-web-ext-native-messaging
ExclusiveArch: %{rust_arches}
- rust-wezterm-color-types
ExclusiveArch: %{rust_arches}
- rust-wezterm-dynamic
ExclusiveArch: %{rust_arches}
- rust-wezterm-dynamic-derive
ExclusiveArch: %{rust_arches}
- rust-zbus1
ExclusiveArch: %{rust_arches}
- rust-zbus_macros1
ExclusiveArch: %{rust_arches}
- rust-zincati
ExcludeArch: armv7hl i686
- rust-zvariant2
ExclusiveArch: %{rust_arches}
- rust-zvariant_derive2
ExclusiveArch: %{rust_arches}
- rustup
ExclusiveArch: x86_64 aarch64
- rutabaga-gfx-ffi
ExclusiveArch: x86_64 aarch64
- s390utils
ExcludeArch: %{ix86}
- sac
ExclusiveArch: %{java_arches} noarch
- safeint
ExcludeArch: %{ix86}
- safetyblanket
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc64le
- sandia-omega-h
ExcludeArch: %{ix86} s390x
- sat4j
ExclusiveArch: %{java_arches} noarch
- sayonara
ExcludeArch: %{ix86}
- sbcl
ExclusiveArch: %{ix86} x86_64 aarch64 %{power64}
- sbd
ExclusiveArch: i686 x86_64 s390x aarch64 ppc64le
- sblim-cim-client
ExclusiveArch: %{java_arches} noarch
- sblim-cim-client2
ExclusiveArch: %{java_arches} noarch
- sbsigntools
ExclusiveArch: x86_64 aarch64 %{arm} %{ix86}
- scala
ExclusiveArch: %{java_arches} noarch
- scalasca
ExcludeArch: s390 s390x armv7hl i686
- scannotation
ExclusiveArch: %{java_arches} noarch
- scip
ExcludeArch: %{ix86}
- scorep
ExcludeArch: s390 s390x armv7hl i686
- sdljava
ExclusiveArch: %{java_arches}
- sdrangel
ExclusiveArch: %{qt5_qtwebengine_arches}
- sdsl-lite
ExclusiveArch: %{power64} x86_64 aarch64
- sdubby
ExclusiveArch: %{efi}
- seabios
ExclusiveArch: x86_64
- seadrive-gui
ExclusiveArch: %{qt5_qtwebengine_arches}
- seafile-client
ExclusiveArch: %{qt6_qtwebengine_arches}
- seamonkey
ExclusiveArch: x86_64
- sedutil
ExcludeArch: ppc ppc64 s390 s390x
- sentencepiece
ExcludeArch: s390x
- seqan3
ExclusiveArch: %{power64} x86_64 aarch64
- sequeler
ExcludeArch: %{ix86}
- sequence-library
ExclusiveArch: %{java_arches} noarch
- servicelog
ExclusiveArch: ppc %{power64}
- setserial
ExcludeArch: s390 s390x
- sfnt2woff-zopfli
ExcludeArch: %{ix86}
- sharedmeataxe
ExcludeArch: %{ix86}
- sharpfont
ExclusiveArch: %mono_arches
- sharpziplib
ExclusiveArch: %{mono_arches}
- shim
ExclusiveArch: %{efi}
ExcludeArch: %{ix86}
ExcludeArch: %{arm}
- shim-unsigned-aarch64
ExclusiveArch: aarch64
- shim-unsigned-x64
ExclusiveArch: x86_64
- sigil
ExclusiveArch: %{qt5_qtwebengine_arches}
ExcludeArch: %{ix86}
- sigul
ExclusiveArch: x86_64
ExcludeArch: %{ix86}
- simdutf
ExcludeArch: s390 s390x
- singularity-ce
ExclusiveArch: %{go_arches}
ExcludeArch: %{ix86}
- sirocco
ExcludeArch: %{ix86}
- sisu
ExclusiveArch: %{java_arches} noarch
- sisu-mojos
ExclusiveArch: %{java_arches} noarch
- ski
ExcludeArch: %{ix86}
ExcludeArch: aarch64
- skopeo
ExclusiveArch: %{golang_arches_future}
ExclusiveArch: aarch64 ppc64le s390x x86_64
- skychart
ExclusiveArch: %{fpc_arches}
ExcludeArch: %{ix86}
- slapi-nis
ExcludeArch: %{ix86}
- sleef
ExcludeArch: %{ix86}
- slf4j
ExclusiveArch: %{java_arches} noarch
- slic3r
ExcludeArch: %{ix86}
ExcludeArch: ppc ppc64 s390 s390x %{ix86}
ExcludeArch: ppc ppc64 s390 s390x
- slick-greeter
ExcludeArch: %{ix86}
- slimdata
ExcludeArch: ppc64 ppc sparcv9 sparc64
- slirp4netns
ExclusiveArch: %{golang_arches_future}
- slurm
ExcludeArch: armv7hl
ExcludeArch: i686
- snakeyaml
ExclusiveArch: %{java_arches} noarch
- snapd
ExclusiveArch: %{?golang_arches}%{!?golang_arches:%{ix86} x86_64 %{arm} aarch64 ppc64le s390x}
- snapshot
ExcludeArch: %{ix86}
- snip
ExclusiveArch: %{java_arches} noarch
- softnet-stat
ExclusiveArch: %{rust_arches}
- soplex
ExcludeArch: %{ix86}
- sound-juicer
ExcludeArch: s390 s390x
- soup-sharp
ExclusiveArch: %{mono_arches}
- sourcextractor++
ExcludeArch: %{ix86}
- spacebar
ExclusiveArch: %{java_arches}
- sparkleshare
ExclusiveArch: %{mono_arches}
ExcludeArch: %{ix86}
- spasm
ExcludeArch: %{ix86}
- spec-version-maven-plugin
ExclusiveArch: %{java_arches} noarch
- speed-dreams
ExcludeArch: s390x
- spicctrl
ExclusiveArch: %{ix86} x86_64
- spice
ExclusiveArch: x86_64
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64 riscv64
- spice-parent
ExclusiveArch: %{java_arches} noarch
- springlobby
ExclusiveArch: %{ix86} x86_64
- spyder
ExcludeArch: %{ix86}
ExclusiveArch: %{qt5_qtwebengine_arches} noarch
- squeekboard
ExclusiveArch: %{rust_arches}
ExcludeArch: ppc64le
ExcludeArch: s390x
- squirrel
ExcludeArch: %{ix86}
- startdde
ExclusiveArch: %{?go_arches:%{go_arches}}%{!?go_arches:%{ix86} x86_64 %{arm}}
- stats-collect
ExclusiveArch: %{ix86} x86_64 noarch
- statsd
ExclusiveArch: %{nodejs_arches} noarch
- statserial
ExcludeArch: s390 s390x
- steinberg-bravura-fonts
ExcludeArch: %{ix86}
- steinberg-petaluma-fonts
ExcludeArch: %{ix86}
- stellarium
ExcludeArch: armv7hl
- stlsplit
ExcludeArch: %{ix86}
- stp
ExcludeArch: %{ix86}
- stratis-cli
ExclusiveArch: %{rust_arches} noarch
ExcludeArch: i686
- stratisd
ExclusiveArch: %{rust_arches}
ExcludeArch: i686
ExclusiveArch: %{rust_arches}
ExcludeArch: i686
ExclusiveArch: %{rust_arches}
ExcludeArch: i686
- string-template-maven-plugin
ExclusiveArch: %{java_arches} noarch
- stringtemplate
ExclusiveArch: %{java_arches} noarch
- stringtemplate4
ExclusiveArch: %{java_arches} noarch
- stripesnoop
ExclusiveArch: %{ix86} x86_64
- subscription-manager-cockpit
ExclusiveArch: %{nodejs_arches} noarch
- supercollider
ExclusiveArch: %{qt5_qtwebengine_arches}
- supermin
ExcludeArch: %{ix86}
ExclusiveArch: %{kernel_arches}
ExcludeArch: %{power64}
- supertux
ExcludeArch: s390x
- suricata
ExcludeArch: ppc64le i686
- svt-vp9
ExclusiveArch: x86_64
- swift-lang
ExclusiveArch: x86_64 aarch64
- swiftlint
ExclusiveArch: x86_64 aarch64
- swing-layout
ExclusiveArch: %{java_arches} noarch
- symfpu
ExcludeArch: %{ix86}
- symmetrica
ExcludeArch: %{ix86}
- sympol
ExcludeArch: %{ix86}
- sympow
ExcludeArch: %{ix86}
- synfig
ExcludeArch: ppc64le
- synfigstudio
ExcludeArch: ppc64le
- sysbench
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips}
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips} aarch64
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips} aarch64 ppc64le s390x
- syslinux
ExclusiveArch: %{ix86} x86_64
ExclusiveArch: %{ix86} x86_64
- system-rules
ExclusiveArch: %{java_arches} noarch
- systemd-boot
ExclusiveArch: %efi
- t-digest
ExclusiveArch: %{java_arches} noarch
- taglib-sharp
ExclusiveArch: %{mono_arches}
- tagsoup
ExclusiveArch: %{java_arches} noarch
- tarantool
ExclusiveArch: %{ix86} x86_64
- tboot
ExclusiveArch: %{ix86} x86_64
- tcmu-runner
ExcludeArch: i686 armv7hl
- tdlib
ExclusiveArch: x86_64 aarch64
- teem
ExcludeArch: %{ix86}
- templates_parser
ExclusiveArch: %GPRbuild_arches
- terminology
ExcludeArch: s390x
- terminus-fonts
ExcludeArch: %{grub2_exclude_arches}
- ternimal
ExclusiveArch: %{rust_arches}
- testcloud
ExclusiveArch: %{kernel_arches} noarch
- testng
ExclusiveArch: %{java_arches} noarch
- texlive
ExclusiveArch: %{java_arches} noarch
- texmaker
ExclusiveArch: %{qt6_qtwebengine_arches}
ExcludeArch: ppc64 ppc64le s390x
- thermald
ExclusiveArch: %{ix86} x86_64
- thunderbird
ExcludeArch: armv7hl
ExcludeArch: s390x
- tiled
ExcludeArch: %{ix86}
- tilix
ExclusiveArch: %{ldc_arches}
- tinygo
ExcludeArch: ppc64le s390x
ExcludeArch: %{ix86}
- tokodon
ExclusiveArch: %{qt6_qtwebengine_arches}
- tomboy
ExclusiveArch: %{mono_arches}
- tomcat
ExclusiveArch: %{java_arches} noarch
- tomcat-jakartaee-migration
ExclusiveArch: %{java_arches} noarch
- tomcat-native
ExclusiveArch: %{java_arches}
- tomcat-taglibs-parent
ExclusiveArch: %{java_arches} noarch
- torbrowser-launcher
ExclusiveArch: %{ix86} x86_64
- trace-cmd
ExcludeArch: %{ix86} %{arm}
- trafficserver
ExcludeArch: %{arm} %{ix86} s390x
- treelayout
ExclusiveArch: %{java_arches} noarch
- trilead-ssh2
ExclusiveArch: %{java_arches} noarch
- trojita
ExcludeArch: ppc64 ppc64le s390x
- trunk
ExcludeArch: %{ix86}
- truth
ExclusiveArch: %{java_arches} noarch
- tth
ExcludeArch: %{ix86}
- tuned-profiles-nfv-host-bin
ExclusiveArch: %{ix86} x86_64
- tuxguitar
ExcludeArch: s390 %{arm} %{ix86}
- tvtime
ExcludeArch: s390 s390x
- typescript
ExclusiveArch: %{nodejs_arches} noarch
- tzdata
ExcludeArch: i686
- uClibc
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips}
- uboot-tools
ExcludeArch: s390x
- ucx
ExclusiveArch: aarch64 ppc64le x86_64
- uglify-js
ExclusiveArch: %{nodejs_arches} noarch
- ugrep
ExcludeArch: %{ix86}
- umr
ExclusiveArch: x86_64 aarch64 ppc64le
- unetbootin
ExclusiveArch: %{ix86} x86_64
- unicorn
ExcludeArch: s390x
- univocity-parsers
ExclusiveArch: %{java_arches} noarch
- ursa-major
ExclusiveArch: noarch aarch64 ppc64le s390x x86_64
- usbip
ExcludeArch: s390x
- usd
ExclusiveArch: aarch64 x86_64
- usnic-tools
ExcludeArch: %{arm}
- utop
ExcludeArch: %{ix86}
- v-hacd
ExcludeArch: %{ix86}
- v8-314
ExclusiveArch: %{ix86} x86_64 %{arm} mips mipsel ppc ppc64
- vakzination
ExclusiveArch: %{java_arches}
- valgrind
ExclusiveArch: %{ix86} x86_64 ppc ppc64 ppc64le s390x armv7hl aarch64
- vboot-utils
ExclusiveArch: %{arm} aarch64 %{ix86} x86_64
- vdr-tvscraper
ExcludeArch: armv7hl
- vecmath1.2
ExclusiveArch: %{java_arches} noarch
- velocity
ExclusiveArch: %{java_arches} noarch
- viking
ExcludeArch: s390 s390x
- vim-go
ExclusiveArch: %{?golang_arches}%{!?golang_arches:%{ix86} x86_64 %{arm}}
- vim-syntastic
ExclusiveArch: %{java_arches} noarch
- vinci
ExcludeArch: %{ix86}
- virt-p2v
ExclusiveArch: x86_64
- virt-top
ExcludeArch: %{ix86}
ExcludeArch: %{power64}
- virt-v2v
ExcludeArch: %{ix86}
ExclusiveArch: x86_64
- virtiofsd
ExclusiveArch: %{rust_arches}
ExcludeArch: i686
- virtualbox-guest-additions
ExclusiveArch: i686 x86_64
- visidata
ExcludeArch: %{ix86}
- visualboyadvance-m
ExcludeArch: %{ix86}
- vkd3d
ExclusiveArch: %{ix86} x86_64 %{arm}
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64
- vkmark
ExcludeArch: s390x
- vmaf
ExclusiveArch: x86_64
- voms-api-java
ExclusiveArch: %{java_arches} noarch
- voms-clients-java
ExclusiveArch: %{java_arches} noarch
- votca
ExcludeArch: %{ix86}
- vrq
ExclusiveArch: %{ix86} x86_64
- wangle
ExclusiveArch: x86_64 aarch64 ppc64le
- warsow
ExclusiveArch: %{ix86} x86_64 %{arm}
- warsow-data
ExclusiveArch: %{ix86} x86_64 %{arm} noarch
ExclusiveArch: %{ix86} x86_64 %{arm}
- warzone2100
ExcludeArch: %{ix86}
- wasmedge
ExclusiveArch: x86_64 aarch64
- watchman
ExclusiveArch: x86_64 aarch64 ppc64le
- wdt
ExclusiveArch: x86_64 aarch64 ppc64le
- webkit2-sharp
ExclusiveArch: %mono_arches
- weld-parent
ExclusiveArch: %{java_arches} noarch
- whatip
ExcludeArch: s390x
- whipper
ExcludeArch: s390x
- whisper-cpp
ExclusiveArch: x86_64 aarch64 ppc64le
- why3
ExclusiveArch: %{ocaml_native_compiler}
- widevine-installer
ExclusiveArch: aarch64
- wildcard
ExcludeArch: %{ix86} s390x
- wine
ExclusiveArch: %{ix86} x86_64 aarch64
ExclusiveArch: %{ix86} x86_64
ExclusiveArch: %{ix86}
- wine-dxvk
ExclusiveArch: %{ix86} x86_64
- wine-mono
ExcludeArch: %{power64} s390x s390
- winetricks
ExclusiveArch: %{ix86} x86_64 %{arm} aarch64
ExcludeArch: ppc64 ppc64le
- woff
ExcludeArch: %{ix86}
- workrave
ExcludeArch: %{ix86}
- ws-commons-util
ExclusiveArch: %{java_arches} noarch
- wsdl4j
ExclusiveArch: %{java_arches} noarch
- wult
ExclusiveArch: x86_64
- wxMaxima
ExclusiveArch: %{arm} %{ix86} x86_64 aarch64 ppc sparcv9
- x2goclient
ExclusiveArch: x86_64
- x2gokdrive
ExcludeArch: %{ix86}
- x86-simd-sort
ExclusiveArch: x86_64
- xalan-j2
ExclusiveArch: %{java_arches} noarch
- xapps
ExcludeArch: %{ix86}
- xbean
ExclusiveArch: %{java_arches} noarch
- xbyak
ExclusiveArch: x86_64
- xbyak_aarch64
ExclusiveArch: aarch64
- xdg-desktop-portal
ExcludeArch: %{ix86}
- xdg-desktop-portal-gnome
ExcludeArch: %{ix86}
- xdg-desktop-portal-gtk
ExcludeArch: %{ix86}
- xdg-desktop-portal-hyprland
ExcludeArch: %{ix86}
- xe-guest-utilities-latest
ExclusiveArch: %{ix86} x86_64
- xed
ExcludeArch: %{ix86}
- xen
ExclusiveArch: x86_64 aarch64
- xephem
ExcludeArch: %{ix86}
- xerces-j2
ExclusiveArch: %{java_arches} noarch
- xeus
ExcludeArch: %{ix86}
- xeus-zmq
ExcludeArch: %{ix86}
- xfce4-sensors-plugin
ExcludeArch: s390 s390x
- xgap
ExcludeArch: %{ix86}
- xiphos
ExcludeArch: ppc64
- xml-commons-apis
ExclusiveArch: %{java_arches} noarch
- xml-commons-resolver
ExclusiveArch: %{java_arches} noarch
- xml-maven-plugin
ExclusiveArch: %{java_arches} noarch
- xmlada
ExclusiveArch: %{GPRbuild_arches}
- xmlgraphics-commons
ExclusiveArch: %{java_arches} noarch
- xmlpull
ExclusiveArch: %{java_arches} noarch
- xmlstreambuffer
ExclusiveArch: %{java_arches} noarch
- xmlunit
ExclusiveArch: %{java_arches} noarch
- xmvn
ExclusiveArch: %{java_arches} noarch
- xmvn-connector-ivy
ExclusiveArch: %{java_arches} noarch
- xmvn-generator
ExclusiveArch: %{java_arches}
- xnnpack
ExclusiveArch: x86_64 aarch64
- xnvme
ExcludeArch: %{ix86}
- xorg-x11-drv-amdgpu
ExcludeArch: s390 s390x
- xorg-x11-drv-armsoc
ExclusiveArch: %{arm} aarch64
- xorg-x11-drv-ati
ExcludeArch: s390 s390x
- xorg-x11-drv-fbdev
ExcludeArch: s390 s390x
- xorg-x11-drv-intel
ExclusiveArch: %{ix86} x86_64
- xorg-x11-drv-nouveau
ExcludeArch: s390 s390x
- xorg-x11-drv-openchrome
ExclusiveArch: %{ix86} x86_64
- xorg-x11-drv-qxl
ExcludeArch: s390 s390x
- xorg-x11-drv-synaptics
ExcludeArch: s390 s390x
- xorg-x11-drv-vesa
ExclusiveArch: %{ix86} x86_64
- xorg-x11-drv-vmware
ExclusiveArch: %{ix86} x86_64 ia64
- xreader
ExcludeArch: %{ix86}
- xsensors
ExcludeArch: %{ix86}
- xsp
ExclusiveArch: %mono_arches
- xstream
ExclusiveArch: %{java_arches} noarch
- xtb
ExcludeArch: s390x
- xtensor-python
ExcludeArch: armv7hl ppc64le s390x
- xz-java
ExclusiveArch: %{java_arches} noarch
- yarnpkg
ExclusiveArch: %{nodejs_arches}
- yices
ExcludeArch: %{ix86}
- yle-dl
ExcludeArch: %{ix86}
- yosys
ExcludeArch: %{ix86}
ExcludeArch: s390x
- zcfan
ExclusiveArch: x86_64
- zeal
ExclusiveArch: aarch64 x86_64
- zenon
ExclusiveArch: %{ocaml_native_compiler}
- zeromq-ada
ExclusiveArch: %{GPRbuild_arches}
- zfs-fuse
ExcludeArch: s390 s390x aarch64
- zig
ExclusiveArch: %{zig_arches}
- zile
ExcludeArch: ppc64le
- zimpl
ExcludeArch: %{ix86}
- zlib-ada
ExclusiveArch: %{GPRbuild_arches}
- zola
ExclusiveArch: %{rust_arches}
- zstr
ExcludeArch: %{ix86}
- zxcvbn-c
ExcludeArch: %{ix86}
- zycore-c
ExcludeArch: s390x
- zydis
ExcludeArch: s390x
1 month, 3 weeks
Architecture specific change in rpms/haxe.git
by githook-noreply@fedoraproject.org
The package rpms/haxe.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/haxe.git/commit/?id=731990683e028....
Change:
+ExcludeArch: %{ix86}
Thanks.
Full change:
============
commit 8fea9b9cf333ccdd89ed9c0e65b902add8765caa
Merge: be49314 4ee090f
Author: Andy Li <andy(a)onthewings.net>
Date: Sat Mar 23 23:04:16 2024 +0000
Merge branch 'rawhide' into f38
diff --cc haxe.spec
index 265d68b,dc54fcb..8743c95
--- a/haxe.spec
+++ b/haxe.spec
@@@ -123,14 -123,38 +123,17 @@@ pop
%{_datadir}/%{name}/
%changelog
+ * Tue Mar 05 2024 Andy Li <andy(a)onthewings.net> - 4.3.4-1
+ - New upstream version 4.3.4. (RHBZ#2267830)
+
-* Wed Jan 24 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 4.3.3-5
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
-
-* Sat Jan 20 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 4.3.3-4
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
-
-* Mon Dec 18 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.3-3
-- OCaml 5.1.1 + s390x code gen fix for Fedora 40
-
-* Tue Dec 12 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.3-2
-- OCaml 5.1.1 rebuild for Fedora 40
-
* Sun Nov 19 2023 Andy Li <andy(a)onthewings.net> - 4.3.3-1
- New upstream version 4.3.3. (RHBZ#2250370)
-- Drop haxe-ocaml5.patch which is no longer needed.
-* Thu Oct 05 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.2-2
-- OCaml 5.1 rebuild for Fedora 40
+* Wed Sep 13 2023 Andy Li <andy(a)onthewings.net> - 4.3.2-2
+- Use the properly built haxelib. (RHBZ#2237112)
-* Fri Sep 15 2023 Andy Li <andy(a)onthewings.net> - 4.3.2-1
+* Sat Sep 09 2023 Andy Li <andy(a)onthewings.net> - 4.3.2-1
- New upstream version 4.3.2. (RHBZ#2237112)
-- Use the properly built haxelib. (RHBZ#2129517)
-- Add haxe-ocaml5.patch from upstream for OCaml 5 compat. (RHBZ#2218692)
-
-* Thu Jul 20 2023 Fedora Release Engineering <releng(a)fedoraproject.org> - 4.3.1-3
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
-
-* Wed Jul 12 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.1-2
-- OCaml 5.0 rebuild for Fedora 39
* Sun Apr 30 2023 Andy Li <andy(a)onthewings.net> - 4.3.1-1
- New upstream version 4.3.1. (RHBZ#2185083, RHBZ#2128307)
commit 4ee090fe295e379159cffc65feeb5e8ddb1d3dd5
Author: Andy Li <andy(a)onthewings.net>
Date: Tue Mar 5 22:13:26 2024 +0000
New upstream version 4.3.4. (RHBZ#2267830)
diff --git a/.gitignore b/.gitignore
index 24b35f5..ee81255 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,4 @@
/haxe-4.3.1.tar.gz
/haxe-4.3.2.tar.gz
/haxe-4.3.3.tar.gz
+/haxe-4.3.4.tar.gz
diff --git a/haxe.spec b/haxe.spec
index 2407e8b..dc54fcb 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -5,8 +5,8 @@ ExcludeArch: %{ix86}
%global commit_hx3compat f1f18201e5c0479cb5adf5f6028788b37f37b730
Name: haxe
-Version: 4.3.3
-Release: 5%{?dist}
+Version: 4.3.4
+Release: 1%{?dist}
Summary: Multi-target universal programming language
# As described in https://haxe.org/foundation/open-source.html:
@@ -123,6 +123,9 @@ popd
%{_datadir}/%{name}/
%changelog
+* Tue Mar 05 2024 Andy Li <andy(a)onthewings.net> - 4.3.4-1
+- New upstream version 4.3.4. (RHBZ#2267830)
+
* Wed Jan 24 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 4.3.3-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
diff --git a/sources b/sources
index b31e539..1116e1d 100644
--- a/sources
+++ b/sources
@@ -1,3 +1,3 @@
-SHA512 (haxe-4.3.3.tar.gz) = 72fd7370f4a42d3524bad78e4ab2b4e839e4d9db6f4e8a942bdddfbe93f97c11ee8e7e96c524b5f8ab0a37a0e151cdeb4dd1d085f6093b70adb555cab6113b0b
+SHA512 (haxe-4.3.4.tar.gz) = 4993a7aaa2e9feb01e60ba52c3ce936b319265a4285c9fe2832d6b815ff657efaaeb7d14137a3a00640ec1a1ff9c83441c1531fa9f8a96d894267b5cc6daed2f
SHA512 (haxelib-f17fffa97554b1bdba37750e3418051f017a5bc2.tar.gz) = adc80c20833062a6639f352861a950a4289a06ba97dcc57e327186cec8aa7988e17b5f4df518ced9a371ae4f0fd7d065bd79f400aa48045081066fa784c6b837
SHA512 (hx3compat-f1f18201e5c0479cb5adf5f6028788b37f37b730.tar.gz) = d3df767744c073715a5deb9e1b602006aded8335d7afe28686e9440c4d9fabe6eb29314beb7b929bb7a76de68a815a9a7c7a49d2a92183e9a5331923f70249ff
commit d354a34563b86ffacc4aa2c877134e272f3029fb
Author: Andy Li <andy(a)onthewings.net>
Date: Tue Mar 5 21:41:54 2024 +0000
haxe-ocaml5.patch was removed
diff --git a/haxe-ocaml5.patch b/haxe-ocaml5.patch
deleted file mode 100644
index ed19f22..0000000
--- a/haxe-ocaml5.patch
+++ /dev/null
@@ -1,1356 +0,0 @@
-From 87ada5e2afa288c136fc1963c5d2c126dcd7241d Mon Sep 17 00:00:00 2001
-From: Rudy Ges <k(a)klabz.org>
-Date: Thu, 14 Sep 2023 20:37:45 +0200
-Subject: [PATCH] OCaml 5 compatibility (#11272)
-
----
- .github/workflows/main.yml | 15 ++++--
- Earthfile | 3 ++
- extra/github-actions/cache-opam-windows.yml | 6 ---
- extra/github-actions/cache-opam.yml | 6 ---
- extra/github-actions/workflows/main.yml | 27 +++++++++--
- haxe.opam | 5 +-
- libs/extc/extc_stubs.c | 42 ++++++++---------
- libs/extc/process_stubs.c | 4 +-
- libs/extlib-leftovers/uTF8.ml | 2 +-
- libs/ilib/peReader.ml | 4 +-
- libs/objsize/c_objsize.c | 31 ++++++++++--
- libs/swflib/swfParser.ml | 2 +-
- libs/swflib/swfPic.ml | 2 +-
- libs/ttflib/tTFParser.ml | 2 +-
- libs/ziplib/zip.ml | 16 +++----
- src/codegen/dotnet.ml | 4 +-
- src/codegen/java.ml | 2 +-
- src/codegen/javaModern.ml | 2 +-
- src/codegen/swfLoader.ml | 2 +-
- src/compiler/displayProcessing.ml | 2 +-
- src/context/display/displayException.ml | 16 +++----
- src/context/display/documentSymbols.ml | 2 +-
- src/context/typecore.ml | 8 ++--
- src/core/path.ml | 4 +-
- src/dune | 2 +-
- src/generators/gencpp.ml | 4 +-
- src/generators/genhl.ml | 4 +-
- src/generators/genphp7.ml | 52 ++++++++++-----------
- src/generators/genswf9.ml | 2 +-
- src/generators/hl2c.ml | 2 +-
- src/generators/hlinterp.ml | 12 ++---
- src/macro/eval/evalJit.ml | 2 +-
- src/macro/eval/evalStdLib.ml | 28 +++++------
- src/optimization/inlineConstructors.ml | 4 +-
- src/typing/matcher.ml | 2 +-
- src/typing/typeloadCheck.ml | 2 +-
- src/typing/typeloadParse.ml | 2 +-
- 37 files changed, 185 insertions(+), 142 deletions(-)
- delete mode 100644 extra/github-actions/cache-opam-windows.yml
- delete mode 100644 extra/github-actions/cache-opam.yml
-
-diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
-index 5c13a228f..f9378961b 100644
---- a/.github/workflows/main.yml
-+++ b/.github/workflows/main.yml
-@@ -259,6 +259,10 @@ jobs:
- env:
- PLATFORM: linux64
- OPAMYES: 1
-+ strategy:
-+ fail-fast: false
-+ matrix:
-+ ocaml: ["4.08.1", "5.0.0"]
- steps:
- - uses: actions/checkout@main
- with:
-@@ -269,7 +273,7 @@ jobs:
- uses: actions/cache(a)v3.0.11
- with:
- path: ~/.opam/
-- key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}-2
-+ key: ${{ runner.os }}-${{ matrix.ocaml }}-${{ hashFiles('./haxe.opam', './libs/') }}
-
- - name: Install Neko from S3
- run: |
-@@ -303,6 +307,7 @@ jobs:
- set -ex
- opam init # --disable-sandboxing
- opam update
-+ opam switch create ${{ matrix.ocaml }}
- opam pin add haxe . --no-action
- opam install haxe --deps-only --assume-depexts
- opam list
-@@ -343,11 +348,12 @@ jobs:
- - name: Upload artifact
- uses: actions/upload-artifact@v3
- with:
-- name: linuxBinaries
-+ name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
- path: out
-
- - name: Upload xmldoc artifact
- uses: actions/upload-artifact@v3
-+ if: matrix.ocaml == '4.08.1'
- with:
- name: xmldoc
- path: extra/doc
-@@ -363,6 +369,7 @@ jobs:
- strategy:
- fail-fast: false
- matrix:
-+ ocaml: ["4.08.1", "5.0.0"]
- target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash, neko]
- include:
- - target: hl
-@@ -379,7 +386,7 @@ jobs:
- submodules: recursive
- - uses: actions/download-artifact@v3
- with:
-- name: linuxBinaries
-+ name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
- path: linuxBinaries
-
- - name: Install Neko from S3
-@@ -586,7 +593,7 @@ jobs:
- uses: actions/cache(a)v3.0.11
- with:
- path: ~/.opam/
-- key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}-2
-+ key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}
-
- - name: Install Neko from S3
- run: |
-diff --git a/Earthfile b/Earthfile
-index 8f399bb10..dda473f6c 100644
---- a/Earthfile
-+++ b/Earthfile
-@@ -93,6 +93,9 @@ devcontainer:
- # Install OCaml libraries
- COPY haxe.opam .
- RUN opam init --disable-sandboxing
-+ RUN opam switch create 4.08.1
-+ RUN eval $(opam env)
-+ RUN opam env
- RUN opam install . --yes --deps-only --no-depexts
- RUN opam list
- RUN ocamlopt -v
-diff --git a/extra/github-actions/cache-opam-windows.yml b/extra/github-actions/cache-opam-windows.yml
-deleted file mode 100644
-index 5270fbf1f..000000000
---- a/extra/github-actions/cache-opam-windows.yml
-+++ /dev/null
-@@ -1,6 +0,0 @@
--- name: Cache opam
-- id: cache-opam
-- uses: actions/cache(a)v3.0.11
-- with:
-- path: D:\.opam
-- key: ${{ runner.os }}${{ env.ARCH }}-${{ hashFiles('./haxe.opam', './libs/') }}
-diff --git a/extra/github-actions/cache-opam.yml b/extra/github-actions/cache-opam.yml
-deleted file mode 100644
-index faaee00b7..000000000
---- a/extra/github-actions/cache-opam.yml
-+++ /dev/null
-@@ -1,6 +0,0 @@
--- name: Cache opam
-- id: cache-opam
-- uses: actions/cache(a)v3.0.11
-- with:
-- path: ~/.opam/
-- key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}-2
-diff --git a/extra/github-actions/workflows/main.yml b/extra/github-actions/workflows/main.yml
-index 629d1bd64..5dbff6761 100644
---- a/extra/github-actions/workflows/main.yml
-+++ b/extra/github-actions/workflows/main.yml
-@@ -57,12 +57,22 @@ jobs:
- env:
- PLATFORM: linux64
- OPAMYES: 1
-+ strategy:
-+ fail-fast: false
-+ matrix:
-+ ocaml: ["4.08.1", "5.0.0"]
- steps:
- - uses: actions/checkout@main
- with:
- submodules: recursive
-
-- @import cache-opam.yml
-+ - name: Cache opam
-+ id: cache-opam
-+ uses: actions/cache(a)v3.0.11
-+ with:
-+ path: ~/.opam/
-+ key: ${{ runner.os }}-${{ matrix.ocaml }}-${{ hashFiles('./haxe.opam', './libs/') }}
-+
- @import install-neko-unix.yml
-
- - name: Install dependencies
-@@ -79,6 +89,7 @@ jobs:
- set -ex
- opam init # --disable-sandboxing
- opam update
-+ opam switch create ${{ matrix.ocaml }}
- opam pin add haxe . --no-action
- opam install haxe --deps-only --assume-depexts
- opam list
-@@ -119,11 +130,12 @@ jobs:
- - name: Upload artifact
- uses: actions/upload-artifact@v3
- with:
-- name: linuxBinaries
-+ name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
- path: out
-
- - name: Upload xmldoc artifact
- uses: actions/upload-artifact@v3
-+ if: matrix.ocaml == '4.08.1'
- with:
- name: xmldoc
- path: extra/doc
-@@ -139,6 +151,7 @@ jobs:
- strategy:
- fail-fast: false
- matrix:
-+ ocaml: ["4.08.1", "5.0.0"]
- target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash, neko]
- include:
- - target: hl
-@@ -155,7 +168,7 @@ jobs:
- submodules: recursive
- - uses: actions/download-artifact@v3
- with:
-- name: linuxBinaries
-+ name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
- path: linuxBinaries
-
- @import install-neko-unix.yml
-@@ -325,7 +338,13 @@ jobs:
- with:
- submodules: recursive
-
-- @import cache-opam.yml
-+ - name: Cache opam
-+ id: cache-opam
-+ uses: actions/cache(a)v3.0.11
-+ with:
-+ path: ~/.opam/
-+ key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}
-+
- @import install-neko-unix.yml
- @import build-mac.yml
-
-diff --git a/haxe.opam b/haxe.opam
-index 60e1671fe..6da637e95 100644
---- a/haxe.opam
-+++ b/haxe.opam
-@@ -19,15 +19,16 @@ build: [
- install: [make "install" "INSTALL_DIR=%{prefix}%"]
- remove: [make "uninstall" "INSTALL_DIR=%{prefix}%"]
- depends: [
-- "ocaml" {>= "4.08"}
-+ ("ocaml" {>= "5.0"} & ("camlp5" {build}))
-+ | ("ocaml" {>= "4.08" & < "5.0"} & ("camlp5" {build & = "8.00"}))
- "ocamlfind" {build}
- "dune" {>= "1.11"}
-- "camlp5" {build & = "8.00"}
- "sedlex" {>= "2.0"}
- "xml-light"
- "extlib" {>= "1.7.8"}
- "ptmap" {>= "2.0.0"}
- "sha"
-+ "camlp-streams"
- "conf-libpcre2-8"
- "conf-zlib"
- "conf-neko"
-diff --git a/libs/extc/extc_stubs.c b/libs/extc/extc_stubs.c
-index 30dc986d5..92faa58aa 100644
---- a/libs/extc/extc_stubs.c
-+++ b/libs/extc/extc_stubs.c
-@@ -92,7 +92,7 @@ int Zflush_val(value zflush_val) {
- case 4: return Z_FINISH;
- // TODO: support Z_BLOCK and Z_TREE
- // TODO: append the received value
-- default: failwith("Error in `Zflush_val` (extc_stubs.c): Unknown zflush value");
-+ default: caml_failwith("Error in `Zflush_val` (extc_stubs.c): Unknown zflush value");
- }
- assert(0);
- }
-@@ -222,14 +222,14 @@ CAMLprim value zlib_deflate_init2(value level_val, value window_bits_val) {
- break;
- case Z_STREAM_ERROR:
- // TODO: use stream->msg to get _zlib_'s text message
-- failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_STREAM_ERROR");
-+ caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_STREAM_ERROR");
- break;
- case Z_VERSION_ERROR:
- // TODO: use stream->msg to get _zlib_'s text message
-- failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_VERSION_ERROR");
-+ caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_VERSION_ERROR");
- break;
- default:
-- failwith("Error in `zlib_deflate_init2` (extc_stubs.c): unknown return code from `deflateInit2`");
-+ caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): unknown return code from `deflateInit2`");
- }
- assert(0);
- }
-@@ -275,7 +275,7 @@ CAMLprim value zlib_deflate(value stream_val, value src, value spos, value slen,
- if (deflate_result == Z_OK || deflate_result == Z_STREAM_END) {
- stream->next_in = NULL;
- stream->next_out = NULL;
-- value zresult = alloc_small(3, 0);
-+ value zresult = caml_alloc_small(3, 0);
- // z_finish
- Field(zresult, 0) = Val_bool(deflate_result == Z_STREAM_END);
- // z_read
-@@ -291,14 +291,14 @@ CAMLprim value zlib_deflate(value stream_val, value src, value spos, value slen,
- break;
- case Z_STREAM_ERROR:
- // TODO: use stream->msg to get _zlib_'s text message
-- failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_STREAM_ERROR");
-+ caml_failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_STREAM_ERROR");
- break;
- case Z_BUF_ERROR:
- // TODO: use stream->msg to get _zlib_'s text message
-- failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_BUF_ERROR");
-+ caml_failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_BUF_ERROR");
- break;
- default:
-- failwith("Error in `zlib_deflate` (extc_stubs.c): unknown return code from `deflate`");
-+ caml_failwith("Error in `zlib_deflate` (extc_stubs.c): unknown return code from `deflate`");
- }
- assert(0);
- }
-@@ -309,14 +309,14 @@ CAMLprim value zlib_deflate_bytecode(value *arg, int nargs) {
-
- CAMLprim value zlib_deflate_end(value zv) {
- if( deflateEnd(ZStreamP_val(zv)) != 0 )
-- failwith("zlib_deflate_end");
-+ caml_failwith("zlib_deflate_end");
- return Val_unit;
- }
-
- CAMLprim value zlib_inflate_init(value wbits) {
- value z = zlib_new_stream();
- if( inflateInit2(ZStreamP_val(z),Int_val(wbits)) != Z_OK )
-- failwith("zlib_inflate_init");
-+ caml_failwith("zlib_inflate_init");
- return z;
- }
-
-@@ -330,12 +330,12 @@ CAMLprim value zlib_inflate( value zv, value src, value spos, value slen, value
- z->avail_in = Int_val(slen);
- z->avail_out = Int_val(dlen);
- if( (r = inflate(z,Int_val(flush))) < 0 )
-- failwith("zlib_inflate");
-+ caml_failwith("zlib_inflate");
-
- z->next_in = NULL;
- z->next_out = NULL;
-
-- res = alloc_small(3, 0);
-+ res = caml_alloc_small(3, 0);
- Field(res, 0) = Val_bool(r == Z_STREAM_END);
- Field(res, 1) = Val_int(Int_val(slen) - z->avail_in);
- Field(res, 2) = Val_int(Int_val(dlen) - z->avail_out);
-@@ -348,7 +348,7 @@ CAMLprim value zlib_inflate_bytecode(value * arg, int nargs) {
-
- CAMLprim value zlib_inflate_end(value zv) {
- if( inflateEnd(ZStreamP_val(zv)) != 0 )
-- failwith("zlib_inflate_end");
-+ caml_failwith("zlib_inflate_end");
- return Val_unit;
- }
-
-@@ -368,13 +368,13 @@ CAMLprim value executable_path(value u) {
- #ifdef _WIN32
- char path[MAX_PATH];
- if( GetModuleFileName(NULL,path,MAX_PATH) == 0 )
-- failwith("executable_path");
-+ caml_failwith("executable_path");
- return caml_copy_string(path);
- #elif __APPLE__
- char path[MAXPATHLEN+1];
- uint32_t path_len = MAXPATHLEN;
- if ( _NSGetExecutablePath(path, &path_len) )
-- failwith("executable_path");
-+ caml_failwith("executable_path");
- return caml_copy_string(path);
- #elif __FreeBSD__
- char path[PATH_MAX];
-@@ -387,7 +387,7 @@ CAMLprim value executable_path(value u) {
- len = sizeof(path);
- error = sysctl(name, 4, path, &len, NULL, 0);
- if( error < 0 )
-- failwith("executable_path");
-+ caml_failwith("executable_path");
- return caml_copy_string(path);
- #else
- char path[PATH_MAX];
-@@ -397,7 +397,7 @@ CAMLprim value executable_path(value u) {
- if( p != NULL )
- return caml_copy_string(p);
- else
-- failwith("executable_path");
-+ caml_failwith("executable_path");
- }
- path[length] = '\0';
- return caml_copy_string(path);
-@@ -408,12 +408,12 @@ CAMLprim value get_full_path( value f ) {
- #ifdef _WIN32
- char path[MAX_PATH];
- if( GetFullPathName(String_val(f),MAX_PATH,path,NULL) == 0 )
-- failwith("get_full_path");
-+ caml_failwith("get_full_path");
- return caml_copy_string(path);
- #else
- char path[4096];
- if( realpath(String_val(f),path) == NULL )
-- failwith("get_full_path");
-+ caml_failwith("get_full_path");
- return caml_copy_string(path);
- #endif
- }
-@@ -428,7 +428,7 @@ CAMLprim value get_real_path( value path ) {
-
- // this will ensure the full class path with proper casing
- if( GetFullPathName(String_val(path),MAX_PATH,out,NULL) == 0 )
-- failwith("get_real_path");
-+ caml_failwith("get_real_path");
-
- len = strlen(out);
- i = 0;
-@@ -501,7 +501,7 @@ CAMLprim value sys_time() {
- ULARGE_INTEGER ui;
- GetSystemTime(&t);
- if( !SystemTimeToFileTime(&t,&ft) )
-- failwith("sys_cpu_time");
-+ caml_failwith("sys_cpu_time");
- ui.LowPart = ft.dwLowDateTime;
- ui.HighPart = ft.dwHighDateTime;
- return caml_copy_double( ((double)ui.QuadPart) / 10000000.0 - EPOCH_DIFF );
-diff --git a/libs/extc/process_stubs.c b/libs/extc/process_stubs.c
-index c17c7a4f5..1f42c0fd1 100644
---- a/libs/extc/process_stubs.c
-+++ b/libs/extc/process_stubs.c
-@@ -67,10 +67,10 @@
- #define val_null Val_int(0)
- #define val_some(v) Field(v,0)
- #define val_int(v) Int_val(v)
--#define neko_error() failwith(__FUNCTION__)
-+#define neko_error() caml_failwith(__FUNCTION__)
-
- static value alloc_private( int size ) {
-- return alloc((size + sizeof(value) - 1) / sizeof(value), Abstract_tag);
-+ return caml_alloc((size + sizeof(value) - 1) / sizeof(value), Abstract_tag);
- }
-
- // --- buffer api
-diff --git a/libs/extlib-leftovers/uTF8.ml b/libs/extlib-leftovers/uTF8.ml
-index ef61364de..ec25bd7ae 100644
---- a/libs/extlib-leftovers/uTF8.ml
-+++ b/libs/extlib-leftovers/uTF8.ml
-@@ -177,7 +177,7 @@ let rec iter_aux proc s i =
-
- let iter proc s = iter_aux proc s 0
-
--let compare s1 s2 = Pervasives.compare s1 s2
-+let compare s1 s2 = Stdlib.compare s1 s2
-
- exception Malformed_code
-
-diff --git a/libs/ilib/peReader.ml b/libs/ilib/peReader.ml
-index fc79151e5..4d2e4aadb 100644
---- a/libs/ilib/peReader.ml
-+++ b/libs/ilib/peReader.ml
-@@ -25,7 +25,7 @@ open ExtList;;
- exception Error_message of string
-
- type reader_ctx = {
-- ch : Pervasives.in_channel;
-+ ch : Stdlib.in_channel;
- i : IO.input;
- verbose : bool;
- }
-@@ -42,7 +42,7 @@ let seek r pos =
- seek_in r.ch pos
-
- let pos r =
-- Pervasives.pos_in r.ch
-+ Stdlib.pos_in r.ch
-
- let info r msg =
- if r.verbose then
-diff --git a/libs/objsize/c_objsize.c b/libs/objsize/c_objsize.c
-index 5f222e072..4a3167531 100644
---- a/libs/objsize/c_objsize.c
-+++ b/libs/objsize/c_objsize.c
-@@ -12,6 +12,11 @@
- #include "util.h"
-
- #include <caml/memory.h>
-+#include <caml/version.h>
-+
-+#if OCAML_VERSION_MAJOR >= 5
-+#include <caml/address_class.h>
-+#endif
-
- // FROM byterun/gc.h
- #define Caml_white (0 << 8)
-@@ -38,6 +43,7 @@
- #define In_static_data 4
- #define In_code_area 8
-
-+#if OCAML_VERSION_MAJOR < 5
- #ifdef ARCH_SIXTYFOUR
-
- // 64 bits: Represent page table as a sparse hash table
-@@ -63,6 +69,23 @@ CAMLextern unsigned char * caml_page_table[Pagetable1_size];
-
- #define Is_in_heap_or_young(a) (Classify_addr(a) & (In_heap | In_young))
-
-+void store_explicit(header_t hd, value v, int col)
-+ {
-+ Hd_val(v) = Coloredhd_hd(hd, col);
-+ }
-+
-+#else
-+
-+void store_explicit(header_t hd, value v, int col)
-+ {
-+ atomic_store_explicit(
-+ Hp_atomic_val(v),
-+ Coloredhd_hd(hd, col),
-+ memory_order_release);
-+ }
-+
-+#endif
-+
- //--------------------------------------------------------
-
-
-@@ -352,7 +375,7 @@ void c_rec_objsize(value v, size_t depth)
-
- DBG(printf("COL: w %08lx %i\n", v, col));
-
-- Hd_val(v) = Coloredhd_hd(hd, Col_blue);
-+ store_explicit(hd, v, Col_blue);
-
- if (Tag_val(v) < No_scan_tag)
- {
-@@ -378,7 +401,7 @@ void restore_colors(value v)
-
- col = readcolor();
- DBG(printf("COL: r %08lx %i\n", v, col));
-- Hd_val(v) = Coloredhd_hd(Hd_val(v), col);
-+ store_explicit(Hd_val(v), v, col);
-
- if (Tag_val(v) < No_scan_tag)
- {
-@@ -417,7 +440,7 @@ int c_objsize(value v, value scan, value reach, size_t* headers, size_t* data, s
- head = Field(head,1);
- if( col == Col_blue ) continue;
- writecolor(col);
-- Hd_val(v) = Coloredhd_hd(hd, Col_blue);
-+ store_explicit(hd, v, Col_blue);
- }
-
- acc_data = 0;
-@@ -444,7 +467,7 @@ int c_objsize(value v, value scan, value reach, size_t* headers, size_t* data, s
- head = Field(head,1);
- if( Colornum_hd(Hd_val(v)) != Col_blue ) continue;
- col = readcolor();
-- Hd_val(v) = Coloredhd_hd(Hd_val(v), col);
-+ store_explicit(Hd_val(v), v, col);
- }
-
- while( COND_BLOCK(reach) ) {
-diff --git a/libs/swflib/swfParser.ml b/libs/swflib/swfParser.ml
-index 2f6474532..8006c81ae 100644
---- a/libs/swflib/swfParser.ml
-+++ b/libs/swflib/swfParser.ml
-@@ -444,7 +444,7 @@ and tag_length t =
- (* READ PRIMS *)
-
- let skip ch n =
-- seek_in ch ((Pervasives.pos_in ch) + n)
-+ seek_in ch ((Stdlib.pos_in ch) + n)
-
- let read_rgba ch =
- let r = read_byte ch in
-diff --git a/libs/swflib/swfPic.ml b/libs/swflib/swfPic.ml
-index 7e69e28eb..613260d18 100644
---- a/libs/swflib/swfPic.ml
-+++ b/libs/swflib/swfPic.ml
-@@ -59,7 +59,7 @@ let load_picture file id =
- let len = String.length file in
- let p = (try String.rindex file '.' with Not_found -> len) in
- let ext = String.sub file (p + 1) (len - (p + 1)) in
-- match String.uppercase ext with
-+ match ExtString.String.uppercase ext with
- | "PNG" ->
- let png , header, data = (try
- let p = Png.parse ch in
-diff --git a/libs/ttflib/tTFParser.ml b/libs/ttflib/tTFParser.ml
-index 68d1e2632..9b3468ac7 100644
---- a/libs/ttflib/tTFParser.ml
-+++ b/libs/ttflib/tTFParser.ml
-@@ -24,7 +24,7 @@ open TTFData
- open IO
-
- type ctx = {
-- file : Pervasives.in_channel;
-+ file : Stdlib.in_channel;
- ch : input;
- mutable entry : entry;
- }
-diff --git a/libs/ziplib/zip.ml b/libs/ziplib/zip.ml
-index 9245f0d00..0e5edc1eb 100644
---- a/libs/ziplib/zip.ml
-+++ b/libs/ziplib/zip.ml
-@@ -62,7 +62,7 @@ type entry =
-
- type in_file =
- { if_filename: string;
-- if_channel: Pervasives.in_channel;
-+ if_channel: Stdlib.in_channel;
- if_entries: entry list;
- if_directory: (string, entry) Hashtbl.t;
- if_comment: string }
-@@ -72,7 +72,7 @@ let comment ifile = ifile.if_comment
-
- type out_file =
- { of_filename: string;
-- of_channel: Pervasives.out_channel;
-+ of_channel: Stdlib.out_channel;
- mutable of_entries: entry list;
- of_comment: string }
-
-@@ -217,7 +217,7 @@ let read_cd filename ic cd_entries cd_offset cd_bound =
- (* Open a ZIP file for reading *)
-
- let open_in filename =
-- let ic = Pervasives.open_in_bin filename in
-+ let ic = Stdlib.open_in_bin filename in
- let (cd_entries, cd_size, cd_offset, cd_comment) = read_ecd filename ic in
- let entries =
- read_cd filename ic cd_entries cd_offset (Int32.add cd_offset cd_size) in
-@@ -232,7 +232,7 @@ let open_in filename =
- (* Close a ZIP file opened for reading *)
-
- let close_in ifile =
-- Pervasives.close_in ifile.if_channel
-+ Stdlib.close_in ifile.if_channel
-
- (* Return the info associated with an entry *)
-
-@@ -369,7 +369,7 @@ let open_out ?(comment = "") filename =
- if String.length comment >= 0x10000 then
- raise(Error(filename, "", "comment too long"));
- { of_filename = filename;
-- of_channel = Pervasives.open_out_bin filename;
-+ of_channel = Stdlib.open_out_bin filename;
- of_entries = [];
- of_comment = comment }
-
-@@ -416,7 +416,7 @@ let close_out ofile =
- write4_int oc start_cd; (* offset of central dir *)
- write2 oc (String.length ofile.of_comment); (* length of comment *)
- writestring oc ofile.of_comment; (* comment *)
-- Pervasives.close_out oc
-+ Stdlib.close_out oc
-
- (* Write a local file header and return the corresponding entry *)
-
-@@ -552,9 +552,9 @@ let copy_file_to_entry infilename ofile ?(extra = "") ?(comment = "")
- with Unix.Unix_error(_,_,_) -> None in
- try
- copy_channel_to_entry ic ofile ~extra ~comment ~level ?mtime:mtime' name;
-- Pervasives.close_in ic
-+ Stdlib.close_in ic
- with x ->
-- Pervasives.close_in ic; raise x
-+ Stdlib.close_in ic; raise x
-
-
- (* Add an entry whose content will be produced by the caller *)
-diff --git a/src/codegen/dotnet.ml b/src/codegen/dotnet.ml
-index e90cfe955..90bf25ec6 100644
---- a/src/codegen/dotnet.ml
-+++ b/src/codegen/dotnet.ml
-@@ -68,7 +68,7 @@ let cs_unops =
- let netname_to_hx name =
- let len = String.length name in
- let chr = String.get name 0 in
-- String.make 1 (Char.uppercase chr) ^ (String.sub name 1 (len-1))
-+ String.make 1 (Char.uppercase_ascii chr) ^ (String.sub name 1 (len-1))
-
- (* -net-lib implementation *)
-
-@@ -105,7 +105,7 @@ let escape_chars =
-
- let netcl_to_hx cl =
- let cl = if String.length cl > 0 && String.get cl 0 >= 'a' && String.get cl 0 <= 'z' then
-- Char.escaped (Char.uppercase (String.get cl 0)) ^ (String.sub cl 1 (String.length cl - 1))
-+ Char.escaped (Char.uppercase_ascii (String.get cl 0)) ^ (String.sub cl 1 (String.length cl - 1))
- else
- cl
- in
-diff --git a/src/codegen/java.ml b/src/codegen/java.ml
-index ba86b4eea..20906bbec 100644
---- a/src/codegen/java.ml
-+++ b/src/codegen/java.ml
-@@ -46,7 +46,7 @@ let is_haxe_keyword = function
- let jname_to_hx name =
- let name =
- if name <> "" && (String.get name 0 < 'A' || String.get name 0 > 'Z') then
-- Char.escaped (Char.uppercase (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
-+ Char.escaped (Char.uppercase_ascii (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
- else
- name
- in
-diff --git a/src/codegen/javaModern.ml b/src/codegen/javaModern.ml
-index 5908c19a0..7a298292c 100644
---- a/src/codegen/javaModern.ml
-+++ b/src/codegen/javaModern.ml
-@@ -555,7 +555,7 @@ module PathConverter = struct
- let jname_to_hx name =
- let name =
- if name <> "" && (String.get name 0 < 'A' || String.get name 0 > 'Z') then
-- Char.escaped (Char.uppercase (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
-+ Char.escaped (Char.uppercase_ascii (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
- else
- name
- in
-diff --git a/src/codegen/swfLoader.ml b/src/codegen/swfLoader.ml
-index 6b7ef3b67..6588dffde 100644
---- a/src/codegen/swfLoader.ml
-+++ b/src/codegen/swfLoader.ml
-@@ -33,7 +33,7 @@ let lowercase_pack pack =
- let name =
- let fchar = String.get name 0 in
- if fchar >= 'A' && fchar <= 'Z' then
-- (String.make 1 (Char.lowercase fchar)) ^ String.sub name 1 (String.length name - 1)
-+ (String.make 1 (Char.lowercase_ascii fchar)) ^ String.sub name 1 (String.length name - 1)
- else
- name
- in
-diff --git a/src/compiler/displayProcessing.ml b/src/compiler/displayProcessing.ml
-index 7cec1d9d7..e32f7fcac 100644
---- a/src/compiler/displayProcessing.ml
-+++ b/src/compiler/displayProcessing.ml
-@@ -268,7 +268,7 @@ let maybe_load_display_file_before_typing tctx display_file_dot_path = match dis
-
- let handle_display_after_typing ctx tctx display_file_dot_path =
- let com = ctx.com in
-- if ctx.com.display.dms_kind = DMNone & ctx.has_error then raise Abort;
-+ if ctx.com.display.dms_kind = DMNone && ctx.has_error then raise Abort;
- begin match ctx.com.display.dms_kind,!Parser.delayed_syntax_completion with
- | DMDefault,Some(kind,subj) -> DisplayOutput.handle_syntax_completion com kind subj
- | _ -> ()
-diff --git a/src/context/display/displayException.ml b/src/context/display/displayException.ml
-index a731f9a1d..661bb1bd1 100644
---- a/src/context/display/displayException.ml
-+++ b/src/context/display/displayException.ml
-@@ -23,9 +23,9 @@ let max_completion_items = ref 0
- let filter_somehow ctx items kind subj =
- let subject = match subj.s_name with
- | None -> ""
-- | Some name-> String.lowercase name
-+ | Some name-> ExtString.String.lowercase name
- in
-- let subject_length = String.length subject in
-+ let subject_length = ExtString.String.length subject in
- let determine_cost s =
- let get_initial_cost o =
- if o = 0 then
-@@ -33,7 +33,7 @@ let filter_somehow ctx items kind subj =
- else begin
- (* Consider `.` as anchors and determine distance from closest one. Penalize starting distance by factor 2. *)
- try
-- let last_anchor = String.rindex_from s o '.' in
-+ let last_anchor = ExtString.String.rindex_from s o '.' in
- (o - (last_anchor + 1)) * 2
- with Not_found ->
- o * 2
-@@ -54,12 +54,12 @@ let filter_somehow ctx items kind subj =
- let o',new_cost = index_from o subject.[i] in
- loop (i + 1) o' (cost + new_cost)
- end else
-- cost + (if o = String.length s - 1 then 0 else 1) (* Slightly penalize for not-exact matches. *)
-+ cost + (if o = ExtString.String.length s - 1 then 0 else 1) (* Slightly penalize for not-exact matches. *)
- in
- if subject_length = 0 then
- 0
- else try
-- let o = String.index s subject.[0] in
-+ let o = ExtString.String.index s subject.[0] in
- loop 1 o (get_initial_cost o);
- with Not_found | Invalid_argument _ ->
- -1
-@@ -67,7 +67,7 @@ let filter_somehow ctx items kind subj =
- let rec loop acc items index =
- match items with
- | item :: items ->
-- let name = String.lowercase (get_filter_name item) in
-+ let name = ExtString.String.lowercase (get_filter_name item) in
- let cost = determine_cost name in
- let acc = if cost >= 0 then
- (item,index,cost) :: acc
-@@ -102,8 +102,8 @@ let patch_completion_subject subj =
- match subj.s_name with
- | Some name ->
- let delta = p.pmax - p.pmin in
-- let name = if delta > 0 && delta < String.length name then
-- String.sub name 0 delta
-+ let name = if delta > 0 && delta < ExtString.String.length name then
-+ ExtString.String.sub name 0 delta
- else
- name
- in
-diff --git a/src/context/display/documentSymbols.ml b/src/context/display/documentSymbols.ml
-index 705c8be1d..4d61a6ae4 100644
---- a/src/context/display/documentSymbols.ml
-+++ b/src/context/display/documentSymbols.ml
-@@ -56,7 +56,7 @@ let collect_module_symbols mname with_locals (pack,decls) =
- | FFun f ->
- add_field (
- if fst cff_name = "new" then Constructor
-- else if ((parent_kind = EnumAbstract or parent_kind = Abstract) && Meta.has_one_of [Meta.Op; Meta.ArrayAccess; Meta.Resolve] cff_meta) then Operator
-+ else if ((parent_kind = EnumAbstract || parent_kind = Abstract) && Meta.has_one_of [Meta.Op; Meta.ArrayAccess; Meta.Resolve] cff_meta) then Operator
- else Method
- );
- if with_locals then func field_parent f
-diff --git a/src/context/typecore.ml b/src/context/typecore.ml
-index 22ccc8a00..fc2b33ba6 100644
---- a/src/context/typecore.ml
-+++ b/src/context/typecore.ml
-@@ -602,7 +602,7 @@ let merge_core_doc ctx mt =
-
- let field_to_type_path com e =
- let rec loop e pack name = match e with
-- | EField(e,f,_),p when Char.lowercase (String.get f 0) <> String.get f 0 -> (match name with
-+ | EField(e,f,_),p when Char.lowercase_ascii (String.get f 0) <> String.get f 0 -> (match name with
- | [] | _ :: [] ->
- loop e pack (f :: name)
- | _ -> (* too many name paths *)
-@@ -614,7 +614,7 @@ let field_to_type_path com e =
- let pack, name, sub = match name with
- | [] ->
- let fchar = String.get f 0 in
-- if Char.uppercase fchar = fchar then
-+ if Char.uppercase_ascii fchar = fchar then
- pack, f, None
- else begin
- display_error com "A class name must start with an uppercase letter" (snd e);
-@@ -664,12 +664,12 @@ let s_field_call_candidate fcc =
- let relative_path ctx file =
- let slashes path = String.concat "/" (ExtString.String.nsplit path "\\") in
- let fpath = slashes (Path.get_full_path file) in
-- let fpath_lower = String.lowercase fpath in
-+ let fpath_lower = String.lowercase_ascii fpath in
- let flen = String.length fpath_lower in
- let rec loop = function
- | [] -> file
- | path :: l ->
-- let spath = String.lowercase (slashes path) in
-+ let spath = String.lowercase_ascii (slashes path) in
- let slen = String.length spath in
- if slen > 0 && slen < flen && String.sub fpath_lower 0 slen = spath then String.sub fpath slen (flen - slen) else loop l
- in
-diff --git a/src/core/path.ml b/src/core/path.ml
-index c5bf6d74d..119908524 100644
---- a/src/core/path.ml
-+++ b/src/core/path.ml
-@@ -223,7 +223,7 @@ end = struct
-
- let create =
- if Globals.is_windows then
-- (fun f -> String.lowercase (get_full_path f))
-+ (fun f -> ExtString.String.lowercase (get_full_path f))
- else
- get_full_path
-
-@@ -378,7 +378,7 @@ let full_dot_path pack mname tname =
-
- let file_extension file =
- match List.rev (ExtString.String.nsplit file ".") with
-- | e :: _ -> String.lowercase e
-+ | e :: _ -> ExtString.String.lowercase e
- | [] -> ""
-
- module FilePath = struct
-diff --git a/src/dune b/src/dune
-index 6e21a11d4..f0175d635 100644
---- a/src/dune
-+++ b/src/dune
-@@ -9,7 +9,7 @@
- (library
- (name haxe)
- (libraries
-- extc extproc extlib_leftovers ilib javalib mbedtls neko objsize pcre2 swflib ttflib ziplib
-+ extc extproc extlib_leftovers ilib javalib mbedtls neko objsize pcre2 camlp-streams swflib ttflib ziplib
- json
- unix str bigarray threads dynlink
- xml-light extlib ptmap sha
-diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml
-index a8ff59cf2..8156bfe83 100644
---- a/src/generators/gencpp.ml
-+++ b/src/generators/gencpp.ml
-@@ -7030,8 +7030,8 @@ let write_build_options common_ctx filename defines =
- | _ -> write_define name (escape_command value)) defines;
- let pin,pid = Process_helper.open_process_args_in_pid "haxelib" [|"haxelib"; "path"; "hxcpp"|] in
- set_binary_mode_in pin false;
-- write_define "hxcpp" (Pervasives.input_line pin);
-- Pervasives.ignore (Process_helper.close_process_in_pid (pin,pid));
-+ write_define "hxcpp" (Stdlib.input_line pin);
-+ Stdlib.ignore (Process_helper.close_process_in_pid (pin,pid));
- writer#close;;
-
- let create_member_types common_ctx =
-diff --git a/src/generators/genhl.ml b/src/generators/genhl.ml
-index e8ffa87cd..12518a9ad 100644
---- a/src/generators/genhl.ml
-+++ b/src/generators/genhl.ml
-@@ -4059,7 +4059,7 @@ let add_types ctx types =
- | Method MethNormal when not (List.exists (fun (m,_,_) -> m = Meta.HlNative) f.cf_meta) ->
- (match f.cf_expr with
- | Some { eexpr = TFunction { tf_expr = { eexpr = TBlock ([] | [{ eexpr = TReturn (Some { eexpr = TConst _ })}]) } } } | None ->
-- let name = prefix ^ String.lowercase (Str.global_replace (Str.regexp "[A-Z]+") "_\\0" f.cf_name) in
-+ let name = prefix ^ String.lowercase_ascii (Str.global_replace (Str.regexp "[A-Z]+") "_\\0" f.cf_name) in
- f.cf_meta <- (Meta.HlNative, [(EConst (String(lib,SDoubleQuotes)),p);(EConst (String(name,SDoubleQuotes)),p)], p) :: f.cf_meta;
- | _ -> ())
- | _ -> ()
-@@ -4149,7 +4149,7 @@ let generate com =
- in
-
- if Path.file_extension com.file = "c" then begin
-- let gnames = Array.create (Array.length code.globals) "" in
-+ let gnames = Array.make (Array.length code.globals) "" in
- PMap.iter (fun n i -> gnames.(i) <- n) ctx.cglobals.map;
- if not (Common.defined com Define.SourceHeader) then begin
- let version_major = com.version / 1000 in
-diff --git a/src/generators/genphp7.ml b/src/generators/genphp7.ml
-index 6d6b53941..9109993ef 100644
---- a/src/generators/genphp7.ml
-+++ b/src/generators/genphp7.ml
-@@ -15,8 +15,8 @@ open Sourcemaps
- *)
- let escape_bin s =
- let b = Buffer.create 0 in
-- for i = 0 to String.length s - 1 do
-- match Char.code (String.unsafe_get s i) with
-+ for i = 0 to ExtString.String.length s - 1 do
-+ match Char.code (ExtString.String.unsafe_get s i) with
- | c when c = Char.code('\\') || c = Char.code('"') || c = Char.code('$') ->
- Buffer.add_string b "\\";
- Buffer.add_char b (Char.chr c)
-@@ -46,7 +46,7 @@ let write_resource dir name data =
- *)
- let copy_file src dst =
- let buffer_size = 8192 in
-- let buffer = String.create buffer_size in
-+ let buffer = ExtString.String.create buffer_size in
- let fd_in = Unix.openfile src [O_RDONLY] 0 in
- let fd_out = Unix.openfile dst [O_WRONLY; O_CREAT; O_TRUNC] 0o644 in
- let rec copy_loop () =
-@@ -196,7 +196,7 @@ end
- (**
- Check if specified string is a reserved word in PHP
- *)
--let is_keyword str = Hashtbl.mem php_keywords_tbl (String.lowercase str)
-+let is_keyword str = Hashtbl.mem php_keywords_tbl (ExtString.String.lowercase str)
-
- (**
- Check if specified type is php.NativeArray
-@@ -531,10 +531,10 @@ let get_full_type_name ?(escape=false) ?(omit_first_slash=false) (type_path:path
- else
- "" :: get_real_path module_path
- in
-- (String.concat "\\" parts) ^ "\\" ^ type_name
-+ (ExtString.String.concat "\\" parts) ^ "\\" ^ type_name
- in
- if escape then
-- String.escaped name
-+ ExtString.String.escaped name
- else
- name
-
-@@ -618,7 +618,7 @@ let fix_call_args callee_type exprs =
- Escapes all "$" chars and encloses `str` into double quotes
- *)
- let quote_string str =
-- "\"" ^ (Str.global_replace (Str.regexp "\\$") "\\$" (String.escaped str)) ^ "\""
-+ "\"" ^ (Str.global_replace (Str.regexp "\\$") "\\$" (ExtString.String.escaped str)) ^ "\""
-
- (**
- Check if specified field is a var with non-constant expression
-@@ -1296,21 +1296,21 @@ class code_writer (ctx:php_generator_context) hx_type_path php_name =
- Decrease indentation by one level
- *)
- method indent_less =
-- indentation <- String.make ((String.length indentation) - 1) '\t';
-+ indentation <- ExtString.String.make ((ExtString.String.length indentation) - 1) '\t';
- (**
- Set indentation level (starting from zero for no indentation)
- *)
- method indent level =
-- indentation <- String.make level '\t';
-+ indentation <- ExtString.String.make level '\t';
- (**
- Get indentation level (starting from zero for no indentation)
- *)
-- method get_indentation = String.length indentation
-+ method get_indentation = ExtString.String.length indentation
- (**
- Set indentation level (starting from zero for no indentation)
- *)
- method set_indentation level =
-- indentation <- String.make level '\t'
-+ indentation <- ExtString.String.make level '\t'
- (**
- Specify local var name declared in current scope
- *)
-@@ -1326,7 +1326,7 @@ class code_writer (ctx:php_generator_context) hx_type_path php_name =
- else if get_type_name type_path = "" then
- match get_module_path type_path with
- | [] -> "\\"
-- | module_path -> "\\" ^ (String.concat "\\" (get_real_path module_path)) ^ "\\"
-+ | module_path -> "\\" ^ (ExtString.String.concat "\\" (get_real_path module_path)) ^ "\\"
- else begin
- let orig_type_path = type_path in
- let type_path = match type_path with (pack, name) -> (pack, get_real_name name) in
-@@ -1942,7 +1942,7 @@ class code_writer (ctx:php_generator_context) hx_type_path php_name =
- set_sourcemap_pointer sourcemap sm_pointer_before_body;
- let locals = vars#pop_captured in
- if List.length locals > 0 then begin
-- self#write ("unset($" ^ (String.concat ", $" locals) ^ ");\n");
-+ self#write ("unset($" ^ (ExtString.String.concat ", $" locals) ^ ");\n");
- self#write_indentation
- end;
- self#write_bypassing_sourcemap body;
-@@ -2999,7 +2999,7 @@ class virtual type_builder ctx (wrapper:type_wrapper) =
- Returns generated file contents
- *)
- method get_contents =
-- if (String.length contents) = 0 then begin
-+ if (ExtString.String.length contents) = 0 then begin
- self#write_declaration;
- writer#write_line " {"; (** opening bracket for a class *)
- self#write_body;
-@@ -3016,7 +3016,7 @@ class virtual type_builder ctx (wrapper:type_wrapper) =
- writer#write_statement ("require_once __DIR__.'/" ^ polyfills_file ^ "'");
- writer#write_statement (boot_class ^ "::__hx__init()")
- end;
-- let haxe_class = match wrapper#get_type_path with (path, name) -> String.concat "." (path @ [name]) in
-+ let haxe_class = match wrapper#get_type_path with (path, name) -> ExtString.String.concat "." (path @ [name]) in
- writer#write_statement (boot_class ^ "::registerClass(" ^ (self#get_name) ^ "::class, '" ^ haxe_class ^ "')");
- self#write_rtti_meta;
- self#write_pre_hx_init;
-@@ -3051,7 +3051,7 @@ class virtual type_builder ctx (wrapper:type_wrapper) =
- writer#write "\n";
- let namespace = self#get_namespace in
- if List.length namespace > 0 then
-- writer#write_line ("namespace " ^ (String.concat "\\" namespace) ^ ";\n");
-+ writer#write_line ("namespace " ^ (ExtString.String.concat "\\" namespace) ^ ";\n");
- writer#write_use
- (**
- Generates PHP docblock and attributes to output buffer.
-@@ -3082,11 +3082,11 @@ class virtual type_builder ctx (wrapper:type_wrapper) =
- Writes description section of docblocks
- *)
- method write_doc_description (doc:string) =
-- let lines = Str.split (Str.regexp "\n") (String.trim doc)
-+ let lines = Str.split (Str.regexp "\n") (ExtString.String.trim doc)
- and write_line line =
-- let trimmed = String.trim line in
-- if String.length trimmed > 0 then (
-- if String.get trimmed 0 = '*' then
-+ let trimmed = ExtString.String.trim line in
-+ if ExtString.String.length trimmed > 0 then (
-+ if ExtString.String.get trimmed 0 = '*' then
- writer#write_line (" " ^ trimmed)
- else
- writer#write_line (" * " ^ trimmed)
-@@ -3554,7 +3554,7 @@ class class_builder ctx (cls:tclass) =
- cls.cl_implements
- in
- let interfaces = List.map use_interface unique in
-- writer#write (String.concat ", " interfaces);
-+ writer#write (ExtString.String.concat ", " interfaces);
- end;
- (**
- Returns either user-defined constructor or creates empty constructor if instance initialization is required.
-@@ -3667,7 +3667,7 @@ class class_builder ctx (cls:tclass) =
- List.iter
- (fun field ->
- if not !required then
-- required := (String.lowercase field.cf_name = String.lowercase self#get_name)
-+ required := (ExtString.String.lowercase field.cf_name = ExtString.String.lowercase self#get_name)
- )
- (cls.cl_ordered_statics @ cls.cl_ordered_fields);
- !required
-@@ -3676,10 +3676,10 @@ class class_builder ctx (cls:tclass) =
- Writes `-D php-prefix` value as class constant PHP_PREFIX
- *)
- method private write_php_prefix () =
-- let prefix = String.concat "\\" ctx.pgc_prefix in
-+ let prefix = ExtString.String.concat "\\" ctx.pgc_prefix in
- let indentation = writer#get_indentation in
- writer#indent 1;
-- writer#write_statement ("const PHP_PREFIX = \"" ^ (String.escaped prefix) ^ "\"");
-+ writer#write_statement ("const PHP_PREFIX = \"" ^ (ExtString.String.escaped prefix) ^ "\"");
- writer#indent indentation
- (**
- Writes expressions for `__hx__init` method
-@@ -3998,8 +3998,8 @@ class generator (ctx:php_generator_context) =
- if front_dirs <> [] then
- ignore(create_dir_recursive (root_dir :: front_dirs));
- let lib_path =
-- (String.concat "" (List.fold_left (fun acc s -> if s <> "." then "../" :: acc else acc) [] front_dirs))
-- ^ (String.concat "/" self#get_lib_path)
-+ (ExtString.String.concat "" (List.fold_left (fun acc s -> if s <> "." then "../" :: acc else acc) [] front_dirs))
-+ ^ (ExtString.String.concat "/" self#get_lib_path)
- in
- let channel = open_out (root_dir ^ "/" ^ filename) in
- output_string channel "<?php\n";
-diff --git a/src/generators/genswf9.ml b/src/generators/genswf9.ml
-index 9bbd0ae6a..c2027e574 100644
---- a/src/generators/genswf9.ml
-+++ b/src/generators/genswf9.ml
-@@ -645,7 +645,7 @@ let begin_switch ctx =
- constructs := (tag,ctx.infos.ipos) :: !constructs;
- in
- let fend() =
-- let cases = Array.create (!max + 1) 1 in
-+ let cases = Array.make (!max + 1) 1 in
- List.iter (fun (tag,pos) -> Array.set cases tag (pos - switch_pos)) !constructs;
- DynArray.set ctx.code switch_index (HSwitch (1,Array.to_list cases));
- branch();
-diff --git a/src/generators/hl2c.ml b/src/generators/hl2c.ml
-index af03a2617..2304debb0 100644
---- a/src/generators/hl2c.ml
-+++ b/src/generators/hl2c.ml
-@@ -1134,7 +1134,7 @@ let make_types_idents htypes =
- try
- PMap.find vp (!types_descs)
- with Not_found ->
-- let arr = Array.create (Array.length vp.vfields) ("",DSimple HVoid) in
-+ let arr = Array.make (Array.length vp.vfields) ("",DSimple HVoid) in
- let td = DVirtual arr in
- types_descs := PMap.add vp td (!types_descs);
- Array.iteri (fun i (f,_,t) -> arr.(i) <- (f,make_desc t)) vp.vfields;
-diff --git a/src/generators/hlinterp.ml b/src/generators/hlinterp.ml
-index f6fc7f32f..2b5bc247a 100644
---- a/src/generators/hlinterp.ml
-+++ b/src/generators/hlinterp.ml
-@@ -1111,7 +1111,7 @@ let interp ctx f args =
- (match rtype r with
- | HEnum e ->
- let _, _, fl = e.efields.(f) in
-- let vl = Array.create (Array.length fl) VUndef in
-+ let vl = Array.make (Array.length fl) VUndef in
- set r (VEnum (e, f, vl))
- | _ -> Globals.die "" __LOC__
- )
-@@ -1257,7 +1257,7 @@ let load_native ctx lib name t =
- | _ -> Globals.die "" __LOC__)
- | "alloc_array" ->
- (function
-- | [VType t;VInt i] -> VArray (Array.create (int i) (default t),t)
-+ | [VType t;VInt i] -> VArray (Array.make (int i) (default t),t)
- | _ -> Globals.die "" __LOC__)
- | "alloc_obj" ->
- (function
-@@ -1347,7 +1347,7 @@ let load_native ctx lib name t =
- | "math_asin" -> (function [VFloat f] -> VFloat (asin f) | _ -> Globals.die "" __LOC__)
- | "math_atan" -> (function [VFloat f] -> VFloat (atan f) | _ -> Globals.die "" __LOC__)
- | "math_atan2" -> (function [VFloat a; VFloat b] -> VFloat (atan2 a b) | _ -> Globals.die "" __LOC__)
-- | "math_log" -> (function [VFloat f] -> VFloat (Pervasives.log f) | _ -> Globals.die "" __LOC__)
-+ | "math_log" -> (function [VFloat f] -> VFloat (Stdlib.log f) | _ -> Globals.die "" __LOC__)
- | "math_exp" -> (function [VFloat f] -> VFloat (exp f) | _ -> Globals.die "" __LOC__)
- | "math_pow" -> (function [VFloat a; VFloat b] -> VFloat (a ** b) | _ -> Globals.die "" __LOC__)
- | "parse_int" ->
-@@ -1539,7 +1539,7 @@ let load_native ctx lib name t =
- | "Darwin" -> "Mac"
- | n -> n
- ) in
-- Pervasives.ignore (Process_helper.close_process_in_pid (ic, pid));
-+ Stdlib.ignore (Process_helper.close_process_in_pid (ic, pid));
- cached_sys_name := Some uname;
- uname)
- | "Win32" | "Cygwin" -> "Windows"
-@@ -2147,7 +2147,7 @@ let add_code ctx code =
- ctx.t_globals <- globals;
- (* expand function table *)
- let nfunctions = Array.length code.functions + Array.length code.natives in
-- let functions = Array.create nfunctions (FNativeFun ("",(fun _ -> Globals.die "" __LOC__),HDyn)) in
-+ let functions = Array.make nfunctions (FNativeFun ("",(fun _ -> Globals.die "" __LOC__),HDyn)) in
- Array.blit ctx.t_functions 0 functions 0 (Array.length ctx.t_functions);
- let rec loop i =
- if i = Array.length code.natives then () else
-@@ -2191,7 +2191,7 @@ let add_code ctx code =
- (* ------------------------------- CHECK ---------------------------------------------- *)
-
- let check code macros =
-- let ftypes = Array.create (Array.length code.natives + Array.length code.functions) HVoid in
-+ let ftypes = Array.make (Array.length code.natives + Array.length code.functions) HVoid in
- let is_native_fun = Hashtbl.create 0 in
-
- let check_fun f =
-diff --git a/src/macro/eval/evalJit.ml b/src/macro/eval/evalJit.ml
-index 6218f394f..d2b5f3c15 100644
---- a/src/macro/eval/evalJit.ml
-+++ b/src/macro/eval/evalJit.ml
-@@ -230,7 +230,7 @@ and jit_expr jit return e =
- let hasret = jit_closure.has_nonfinal_return in
- let eci = get_env_creation jit_closure false tf.tf_expr.epos.pfile (EKLocalFunction jit.num_closures) in
- let captures = Hashtbl.fold (fun vid (i,declared) acc -> (i,vid,declared) :: acc) jit_closure.captures [] in
-- let captures = List.sort (fun (i1,_,_) (i2,_,_) -> Pervasives.compare i1 i2) captures in
-+ let captures = List.sort (fun (i1,_,_) (i2,_,_) -> Stdlib.compare i1 i2) captures in
- (* Check if the out-of-scope var is in the outer scope because otherwise we have to promote outwards. *)
- List.iter (fun var -> ignore(get_capture_slot jit var)) jit_closure.captures_outside_scope;
- let captures = ExtList.List.filter_map (fun (i,vid,declared) ->
-diff --git a/src/macro/eval/evalStdLib.ml b/src/macro/eval/evalStdLib.ml
-index 501387567..935733b53 100644
---- a/src/macro/eval/evalStdLib.ml
-+++ b/src/macro/eval/evalStdLib.ml
-@@ -289,7 +289,7 @@ module StdBytes = struct
- let compare = vifun1 (fun vthis other ->
- let this = this vthis in
- let other = decode_bytes other in
-- vint (Pervasives.compare this other)
-+ vint (Stdlib.compare this other)
- )
-
- let fastGet = vfun2 (fun b pos ->
-@@ -1694,13 +1694,13 @@ module StdMath = struct
- let ceil = vfun1 (fun v -> match v with VInt32 _ -> v | _ -> vint32 (to_int (ceil (num v))))
- let cos = vfun1 (fun v -> vfloat (cos (num v)))
- let exp = vfun1 (fun v -> vfloat (exp (num v)))
-- let fceil = vfun1 (fun v -> vfloat (Pervasives.ceil (num v)))
-- let ffloor = vfun1 (fun v -> vfloat (Pervasives.floor (num v)))
-+ let fceil = vfun1 (fun v -> vfloat (Stdlib.ceil (num v)))
-+ let ffloor = vfun1 (fun v -> vfloat (Stdlib.floor (num v)))
- let floor = vfun1 (fun v -> match v with VInt32 _ -> v | _ -> vint32 (to_int (floor (num v))))
-- let fround = vfun1 (fun v -> vfloat (Pervasives.floor (num v +. 0.5)))
-+ let fround = vfun1 (fun v -> vfloat (Stdlib.floor (num v +. 0.5)))
- let isFinite = vfun1 (fun v -> vbool (match v with VFloat f -> f <> infinity && f <> neg_infinity && f = f | _ -> true))
- let isNaN = vfun1 (fun v -> vbool (match v with VFloat f -> f <> f | VInt32 _ -> false | _ -> true))
-- let log = vfun1 (fun v -> vfloat (Pervasives.log (num v)))
-+ let log = vfun1 (fun v -> vfloat (Stdlib.log (num v)))
-
- let max = vfun2 (fun a b ->
- let a = num a in
-@@ -1716,7 +1716,7 @@ module StdMath = struct
-
- let pow = vfun2 (fun a b -> vfloat ((num a) ** (num b)))
- let random = vfun0 (fun () -> vfloat (Random.State.float random 1.))
-- let round = vfun1 (fun v -> match v with VInt32 _ -> v | _ -> vint32 (to_int (Pervasives.floor (num v +. 0.5))))
-+ let round = vfun1 (fun v -> match v with VInt32 _ -> v | _ -> vint32 (to_int (Stdlib.floor (num v +. 0.5))))
- let sin = vfun1 (fun v -> vfloat (sin (num v)))
-
- let sqrt = vfun1 (fun v ->
-@@ -2690,7 +2690,7 @@ module StdSys = struct
- | "Darwin" -> "Mac"
- | n -> n
- ) in
-- Pervasives.ignore (Process_helper.close_process_in_pid (ic, pid));
-+ Stdlib.ignore (Process_helper.close_process_in_pid (ic, pid));
- cached_sys_name := Some uname;
- uname)
- | "Win32" | "Cygwin" -> "Windows"
-@@ -2735,10 +2735,12 @@ module StdThread = struct
- vnull
- )
-
-- let kill = vifun0 (fun vthis ->
-- Thread.kill (this vthis).tthread;
-- vnull
-- )
-+ (* Thread.kill has been marked deprecated (because unstable or even not working at all) for a while, and removed in ocaml 5 *)
-+ (* See also https://github.com/HaxeFoundation/haxe/issues/5800 *)
-+ (* let kill = vifun0 (fun vthis -> *)
-+ (* Thread.kill (this vthis).tthread; *)
-+ (* vnull *)
-+ (* ) *)
-
- let self = vfun0 (fun () ->
- let eval = get_eval (get_ctx()) in
-@@ -3064,7 +3066,7 @@ module StdUtf8 = struct
- let compare = vfun2 (fun a b ->
- let a = decode_string a in
- let b = decode_string b in
-- vint (Pervasives.compare a b)
-+ vint (Stdlib.compare a b)
- )
-
- let decode = vfun1 (fun s ->
-@@ -3730,7 +3732,7 @@ let init_standard_library builtins =
- "id",StdThread.id;
- "get_events",StdThread.get_events;
- "set_events",StdThread.set_events;
-- "kill",StdThread.kill;
-+ (* "kill",StdThread.kill; *)
- "sendMessage",StdThread.sendMessage;
- ];
- init_fields builtins (["sys";"thread"],"Tls") [] [
-diff --git a/src/optimization/inlineConstructors.ml b/src/optimization/inlineConstructors.ml
-index 8df1b5d79..de9b666cf 100644
---- a/src/optimization/inlineConstructors.ml
-+++ b/src/optimization/inlineConstructors.ml
-@@ -499,7 +499,7 @@ let inline_constructors ctx original_e =
- | IOFInlineMethod(io,io_var,c,tl,cf,tf) ->
- let argvs, pl = analyze_call_args call_args in
- io.io_dependent_vars <- io.io_dependent_vars @ argvs;
-- io.io_has_untyped <- io.io_has_untyped or (Meta.has Meta.HasUntyped cf.cf_meta);
-+ io.io_has_untyped <- io.io_has_untyped || (Meta.has Meta.HasUntyped cf.cf_meta);
- begin match Inline.type_inline ctx cf tf (mk (TLocal io_var.iv_var) (TInst (c,tl)) e.epos) pl e.etype None e.epos true with
- | Some e ->
- let e = mark_ctors e in
-@@ -727,4 +727,4 @@ let inline_constructors ctx original_e =
- end
- ) !vars;
- e
-- end
-\ No newline at end of file
-+ end
-diff --git a/src/typing/matcher.ml b/src/typing/matcher.ml
-index 72f2a5e3a..6ca7e9a35 100644
---- a/src/typing/matcher.ml
-+++ b/src/typing/matcher.ml
-@@ -1461,7 +1461,7 @@ module TexprConverter = struct
- in
- let s = match unmatched with
- | [] -> "_"
-- | _ -> String.concat " | " (List.sort Pervasives.compare sl)
-+ | _ -> String.concat " | " (List.sort Stdlib.compare sl)
- in
- typing_error (Printf.sprintf "Unmatched patterns: %s" (s_subject v_lookup s e_subject)) e_subject.epos
-
-diff --git a/src/typing/typeloadCheck.ml b/src/typing/typeloadCheck.ml
-index 616be2ec1..6e649860f 100644
---- a/src/typing/typeloadCheck.ml
-+++ b/src/typing/typeloadCheck.ml
-@@ -318,7 +318,7 @@ let check_module_types ctx m p t =
- let t = t_infos t in
- try
- let path2 = ctx.com.type_to_module#find t.mt_path in
-- if m.m_path <> path2 && String.lowercase (s_type_path path2) = String.lowercase (s_type_path m.m_path) then typing_error ("Module " ^ s_type_path path2 ^ " is loaded with a different case than " ^ s_type_path m.m_path) p;
-+ if m.m_path <> path2 && String.lowercase_ascii (s_type_path path2) = String.lowercase_ascii (s_type_path m.m_path) then typing_error ("Module " ^ s_type_path path2 ^ " is loaded with a different case than " ^ s_type_path m.m_path) p;
- let m2 = ctx.com.module_lut#find path2 in
- let hex1 = Digest.to_hex m.m_extra.m_sign in
- let hex2 = Digest.to_hex m2.m_extra.m_sign in
-diff --git a/src/typing/typeloadParse.ml b/src/typing/typeloadParse.ml
-index fcc192381..066443ada 100644
---- a/src/typing/typeloadParse.ml
-+++ b/src/typing/typeloadParse.ml
-@@ -102,7 +102,7 @@ let resolve_module_file com m remap p =
- with Not_found ->
- Common.find_file com (compose_path true)
- in
-- let file = (match String.lowercase (snd m) with
-+ let file = (match ExtString.String.lowercase (snd m) with
- | "con" | "aux" | "prn" | "nul" | "com1" | "com2" | "com3" | "lpt1" | "lpt2" | "lpt3" when Sys.os_type = "Win32" ->
- (* these names are reserved by the OS - old DOS legacy, such files cannot be easily created but are reported as visible *)
- if (try (Unix.stat file).Unix.st_size with _ -> 0) > 0 then file else raise Not_found
---
-2.42.0.windows.2
-
commit 895d29e9f757e831cbb4fe5057b5ba501af7851c
Author: Fedora Release Engineering <releng(a)fedoraproject.org>
Date: Wed Jan 24 21:33:22 2024 +0000
Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
diff --git a/haxe.spec b/haxe.spec
index 1fed374..2407e8b 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -6,7 +6,7 @@ ExcludeArch: %{ix86}
Name: haxe
Version: 4.3.3
-Release: 4%{?dist}
+Release: 5%{?dist}
Summary: Multi-target universal programming language
# As described in https://haxe.org/foundation/open-source.html:
@@ -123,6 +123,9 @@ popd
%{_datadir}/%{name}/
%changelog
+* Wed Jan 24 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 4.3.3-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
* Sat Jan 20 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 4.3.3-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
commit a908adbe75a5450b2b438614dfd44881b9bd273b
Author: Fedora Release Engineering <releng(a)fedoraproject.org>
Date: Sat Jan 20 21:59:34 2024 +0000
Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
diff --git a/haxe.spec b/haxe.spec
index d5a060b..1fed374 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -6,7 +6,7 @@ ExcludeArch: %{ix86}
Name: haxe
Version: 4.3.3
-Release: 3%{?dist}
+Release: 4%{?dist}
Summary: Multi-target universal programming language
# As described in https://haxe.org/foundation/open-source.html:
@@ -123,6 +123,9 @@ popd
%{_datadir}/%{name}/
%changelog
+* Sat Jan 20 2024 Fedora Release Engineering <releng(a)fedoraproject.org> - 4.3.3-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
* Mon Dec 18 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.3-3
- OCaml 5.1.1 + s390x code gen fix for Fedora 40
commit 4b8606100e8993f5ec89163cb5d4b1e6f2bf3249
Author: Richard W.M. Jones <rjones(a)redhat.com>
Date: Mon Dec 18 19:28:44 2023 +0000
OCaml 5.1.1 + s390x code gen fix for Fedora 40
diff --git a/haxe.spec b/haxe.spec
index 1c180a3..d5a060b 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -6,7 +6,7 @@ ExcludeArch: %{ix86}
Name: haxe
Version: 4.3.3
-Release: 2%{?dist}
+Release: 3%{?dist}
Summary: Multi-target universal programming language
# As described in https://haxe.org/foundation/open-source.html:
@@ -123,6 +123,9 @@ popd
%{_datadir}/%{name}/
%changelog
+* Mon Dec 18 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.3-3
+- OCaml 5.1.1 + s390x code gen fix for Fedora 40
+
* Tue Dec 12 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.3-2
- OCaml 5.1.1 rebuild for Fedora 40
commit e90137048950a6fb075491dfa97e0a6673aa5d63
Author: Richard W.M. Jones <rjones(a)redhat.com>
Date: Tue Dec 12 22:06:25 2023 +0000
OCaml 5.1.1 rebuild for Fedora 40
diff --git a/haxe.spec b/haxe.spec
index acde4b9..1c180a3 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -6,7 +6,7 @@ ExcludeArch: %{ix86}
Name: haxe
Version: 4.3.3
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Multi-target universal programming language
# As described in https://haxe.org/foundation/open-source.html:
@@ -123,6 +123,9 @@ popd
%{_datadir}/%{name}/
%changelog
+* Tue Dec 12 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.3-2
+- OCaml 5.1.1 rebuild for Fedora 40
+
* Sun Nov 19 2023 Andy Li <andy(a)onthewings.net> - 4.3.3-1
- New upstream version 4.3.3. (RHBZ#2250370)
- Drop haxe-ocaml5.patch which is no longer needed.
commit dfb562e16da3daa58c2f8f326b637cef610946c0
Author: Andy Li <andy(a)onthewings.net>
Date: Sun Nov 19 16:19:28 2023 +0000
commit sources
diff --git a/.gitignore b/.gitignore
index 286ac5c..24b35f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,4 @@
/haxelib-f17fffa97554b1bdba37750e3418051f017a5bc2.tar.gz
/haxe-4.3.1.tar.gz
/haxe-4.3.2.tar.gz
+/haxe-4.3.3.tar.gz
diff --git a/sources b/sources
index 71dbfdf..b31e539 100644
--- a/sources
+++ b/sources
@@ -1,3 +1,3 @@
-SHA512 (haxe-4.3.2.tar.gz) = 78d9cba573582dcfec7f1be413bb6061b90375432ede498f2d28fa8d8262d1eaa4760337ca40eb8439149aead9e00c5471d0badef58dd62bf59516be57fcbf65
+SHA512 (haxe-4.3.3.tar.gz) = 72fd7370f4a42d3524bad78e4ab2b4e839e4d9db6f4e8a942bdddfbe93f97c11ee8e7e96c524b5f8ab0a37a0e151cdeb4dd1d085f6093b70adb555cab6113b0b
SHA512 (haxelib-f17fffa97554b1bdba37750e3418051f017a5bc2.tar.gz) = adc80c20833062a6639f352861a950a4289a06ba97dcc57e327186cec8aa7988e17b5f4df518ced9a371ae4f0fd7d065bd79f400aa48045081066fa784c6b837
SHA512 (hx3compat-f1f18201e5c0479cb5adf5f6028788b37f37b730.tar.gz) = d3df767744c073715a5deb9e1b602006aded8335d7afe28686e9440c4d9fabe6eb29314beb7b929bb7a76de68a815a9a7c7a49d2a92183e9a5331923f70249ff
commit f6a3d0c1d24b4bc5341e77d09b27cc98c8e2b7e5
Author: Andy Li <andy(a)onthewings.net>
Date: Sun Nov 19 15:50:08 2023 +0000
New upstream version 4.3.3. (RHBZ#2250370)
diff --git a/haxe.spec b/haxe.spec
index cea23dd..acde4b9 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -5,8 +5,8 @@ ExcludeArch: %{ix86}
%global commit_hx3compat f1f18201e5c0479cb5adf5f6028788b37f37b730
Name: haxe
-Version: 4.3.2
-Release: 2%{?dist}
+Version: 4.3.3
+Release: 1%{?dist}
Summary: Multi-target universal programming language
# As described in https://haxe.org/foundation/open-source.html:
@@ -26,7 +26,6 @@ URL: https://haxe.org/
Source0: https://github.com/HaxeFoundation/%{name}/archive/%{version}.tar.gz#/%{na...
Source1: https://github.com/HaxeFoundation/haxelib/archive/%{commit_haxelib}.tar.g...
Source2: https://github.com/HaxeFoundation/hx3compat/archive/%{commit_hx3compat}.t...
-Patch0: haxe-ocaml5.patch
BuildRequires: make
BuildRequires: nekovm-devel >= 2.3.0
@@ -66,7 +65,6 @@ by the Haxe compiler.
%prep
%setup -q
-%patch 0 -p1
pushd extra/haxelib_src && tar -xf %{SOURCE1} --strip-components=1 && popd
pushd extra/haxelib_src/hx3compat && tar -xf %{SOURCE2} --strip-components=1 && popd
@@ -125,6 +123,10 @@ popd
%{_datadir}/%{name}/
%changelog
+* Sun Nov 19 2023 Andy Li <andy(a)onthewings.net> - 4.3.3-1
+- New upstream version 4.3.3. (RHBZ#2250370)
+- Drop haxe-ocaml5.patch which is no longer needed.
+
* Thu Oct 05 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.2-2
- OCaml 5.1 rebuild for Fedora 40
commit ae9bc364eb9a0c531285e6655cf6047086515a27
Author: Richard W.M. Jones <rjones(a)redhat.com>
Date: Thu Oct 5 21:48:14 2023 +0100
OCaml 5.1 rebuild for Fedora 40
diff --git a/haxe.spec b/haxe.spec
index 727a060..cea23dd 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -6,7 +6,7 @@ ExcludeArch: %{ix86}
Name: haxe
Version: 4.3.2
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Multi-target universal programming language
# As described in https://haxe.org/foundation/open-source.html:
@@ -125,6 +125,9 @@ popd
%{_datadir}/%{name}/
%changelog
+* Thu Oct 05 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.2-2
+- OCaml 5.1 rebuild for Fedora 40
+
* Fri Sep 15 2023 Andy Li <andy(a)onthewings.net> - 4.3.2-1
- New upstream version 4.3.2. (RHBZ#2237112)
- Use the properly built haxelib. (RHBZ#2129517)
commit 774aa47babf8ded2e73b8b72b7d5fe6105293263
Author: Jerry James <loganjerry(a)gmail.com>
Date: Wed Oct 4 23:23:54 2023 -0600
Package notes no longer have to be avoided
diff --git a/haxe.spec b/haxe.spec
index 2495170..727a060 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -1,7 +1,6 @@
# OCaml packages not built on i686 since OCaml 5 / Fedora 39.
ExcludeArch: %{ix86}
-%undefine _package_note_flags
%global commit_haxelib f17fffa97554b1bdba37750e3418051f017a5bc2
%global commit_hx3compat f1f18201e5c0479cb5adf5f6028788b37f37b730
commit ba5f4dd6bbd608e03ef748a9e9f73b95ec5162d2
Author: Andy Li <andy(a)onthewings.net>
Date: Fri Sep 15 15:48:31 2023 +0000
add haxe-ocaml5.patch
diff --git a/haxe-ocaml5.patch b/haxe-ocaml5.patch
new file mode 100644
index 0000000..ed19f22
--- /dev/null
+++ b/haxe-ocaml5.patch
@@ -0,0 +1,1356 @@
+From 87ada5e2afa288c136fc1963c5d2c126dcd7241d Mon Sep 17 00:00:00 2001
+From: Rudy Ges <k(a)klabz.org>
+Date: Thu, 14 Sep 2023 20:37:45 +0200
+Subject: [PATCH] OCaml 5 compatibility (#11272)
+
+---
+ .github/workflows/main.yml | 15 ++++--
+ Earthfile | 3 ++
+ extra/github-actions/cache-opam-windows.yml | 6 ---
+ extra/github-actions/cache-opam.yml | 6 ---
+ extra/github-actions/workflows/main.yml | 27 +++++++++--
+ haxe.opam | 5 +-
+ libs/extc/extc_stubs.c | 42 ++++++++---------
+ libs/extc/process_stubs.c | 4 +-
+ libs/extlib-leftovers/uTF8.ml | 2 +-
+ libs/ilib/peReader.ml | 4 +-
+ libs/objsize/c_objsize.c | 31 ++++++++++--
+ libs/swflib/swfParser.ml | 2 +-
+ libs/swflib/swfPic.ml | 2 +-
+ libs/ttflib/tTFParser.ml | 2 +-
+ libs/ziplib/zip.ml | 16 +++----
+ src/codegen/dotnet.ml | 4 +-
+ src/codegen/java.ml | 2 +-
+ src/codegen/javaModern.ml | 2 +-
+ src/codegen/swfLoader.ml | 2 +-
+ src/compiler/displayProcessing.ml | 2 +-
+ src/context/display/displayException.ml | 16 +++----
+ src/context/display/documentSymbols.ml | 2 +-
+ src/context/typecore.ml | 8 ++--
+ src/core/path.ml | 4 +-
+ src/dune | 2 +-
+ src/generators/gencpp.ml | 4 +-
+ src/generators/genhl.ml | 4 +-
+ src/generators/genphp7.ml | 52 ++++++++++-----------
+ src/generators/genswf9.ml | 2 +-
+ src/generators/hl2c.ml | 2 +-
+ src/generators/hlinterp.ml | 12 ++---
+ src/macro/eval/evalJit.ml | 2 +-
+ src/macro/eval/evalStdLib.ml | 28 +++++------
+ src/optimization/inlineConstructors.ml | 4 +-
+ src/typing/matcher.ml | 2 +-
+ src/typing/typeloadCheck.ml | 2 +-
+ src/typing/typeloadParse.ml | 2 +-
+ 37 files changed, 185 insertions(+), 142 deletions(-)
+ delete mode 100644 extra/github-actions/cache-opam-windows.yml
+ delete mode 100644 extra/github-actions/cache-opam.yml
+
+diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
+index 5c13a228f..f9378961b 100644
+--- a/.github/workflows/main.yml
++++ b/.github/workflows/main.yml
+@@ -259,6 +259,10 @@ jobs:
+ env:
+ PLATFORM: linux64
+ OPAMYES: 1
++ strategy:
++ fail-fast: false
++ matrix:
++ ocaml: ["4.08.1", "5.0.0"]
+ steps:
+ - uses: actions/checkout@main
+ with:
+@@ -269,7 +273,7 @@ jobs:
+ uses: actions/cache(a)v3.0.11
+ with:
+ path: ~/.opam/
+- key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}-2
++ key: ${{ runner.os }}-${{ matrix.ocaml }}-${{ hashFiles('./haxe.opam', './libs/') }}
+
+ - name: Install Neko from S3
+ run: |
+@@ -303,6 +307,7 @@ jobs:
+ set -ex
+ opam init # --disable-sandboxing
+ opam update
++ opam switch create ${{ matrix.ocaml }}
+ opam pin add haxe . --no-action
+ opam install haxe --deps-only --assume-depexts
+ opam list
+@@ -343,11 +348,12 @@ jobs:
+ - name: Upload artifact
+ uses: actions/upload-artifact@v3
+ with:
+- name: linuxBinaries
++ name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+ path: out
+
+ - name: Upload xmldoc artifact
+ uses: actions/upload-artifact@v3
++ if: matrix.ocaml == '4.08.1'
+ with:
+ name: xmldoc
+ path: extra/doc
+@@ -363,6 +369,7 @@ jobs:
+ strategy:
+ fail-fast: false
+ matrix:
++ ocaml: ["4.08.1", "5.0.0"]
+ target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash, neko]
+ include:
+ - target: hl
+@@ -379,7 +386,7 @@ jobs:
+ submodules: recursive
+ - uses: actions/download-artifact@v3
+ with:
+- name: linuxBinaries
++ name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+ path: linuxBinaries
+
+ - name: Install Neko from S3
+@@ -586,7 +593,7 @@ jobs:
+ uses: actions/cache(a)v3.0.11
+ with:
+ path: ~/.opam/
+- key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}-2
++ key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}
+
+ - name: Install Neko from S3
+ run: |
+diff --git a/Earthfile b/Earthfile
+index 8f399bb10..dda473f6c 100644
+--- a/Earthfile
++++ b/Earthfile
+@@ -93,6 +93,9 @@ devcontainer:
+ # Install OCaml libraries
+ COPY haxe.opam .
+ RUN opam init --disable-sandboxing
++ RUN opam switch create 4.08.1
++ RUN eval $(opam env)
++ RUN opam env
+ RUN opam install . --yes --deps-only --no-depexts
+ RUN opam list
+ RUN ocamlopt -v
+diff --git a/extra/github-actions/cache-opam-windows.yml b/extra/github-actions/cache-opam-windows.yml
+deleted file mode 100644
+index 5270fbf1f..000000000
+--- a/extra/github-actions/cache-opam-windows.yml
++++ /dev/null
+@@ -1,6 +0,0 @@
+-- name: Cache opam
+- id: cache-opam
+- uses: actions/cache(a)v3.0.11
+- with:
+- path: D:\.opam
+- key: ${{ runner.os }}${{ env.ARCH }}-${{ hashFiles('./haxe.opam', './libs/') }}
+diff --git a/extra/github-actions/cache-opam.yml b/extra/github-actions/cache-opam.yml
+deleted file mode 100644
+index faaee00b7..000000000
+--- a/extra/github-actions/cache-opam.yml
++++ /dev/null
+@@ -1,6 +0,0 @@
+-- name: Cache opam
+- id: cache-opam
+- uses: actions/cache(a)v3.0.11
+- with:
+- path: ~/.opam/
+- key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}-2
+diff --git a/extra/github-actions/workflows/main.yml b/extra/github-actions/workflows/main.yml
+index 629d1bd64..5dbff6761 100644
+--- a/extra/github-actions/workflows/main.yml
++++ b/extra/github-actions/workflows/main.yml
+@@ -57,12 +57,22 @@ jobs:
+ env:
+ PLATFORM: linux64
+ OPAMYES: 1
++ strategy:
++ fail-fast: false
++ matrix:
++ ocaml: ["4.08.1", "5.0.0"]
+ steps:
+ - uses: actions/checkout@main
+ with:
+ submodules: recursive
+
+- @import cache-opam.yml
++ - name: Cache opam
++ id: cache-opam
++ uses: actions/cache(a)v3.0.11
++ with:
++ path: ~/.opam/
++ key: ${{ runner.os }}-${{ matrix.ocaml }}-${{ hashFiles('./haxe.opam', './libs/') }}
++
+ @import install-neko-unix.yml
+
+ - name: Install dependencies
+@@ -79,6 +89,7 @@ jobs:
+ set -ex
+ opam init # --disable-sandboxing
+ opam update
++ opam switch create ${{ matrix.ocaml }}
+ opam pin add haxe . --no-action
+ opam install haxe --deps-only --assume-depexts
+ opam list
+@@ -119,11 +130,12 @@ jobs:
+ - name: Upload artifact
+ uses: actions/upload-artifact@v3
+ with:
+- name: linuxBinaries
++ name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+ path: out
+
+ - name: Upload xmldoc artifact
+ uses: actions/upload-artifact@v3
++ if: matrix.ocaml == '4.08.1'
+ with:
+ name: xmldoc
+ path: extra/doc
+@@ -139,6 +151,7 @@ jobs:
+ strategy:
+ fail-fast: false
+ matrix:
++ ocaml: ["4.08.1", "5.0.0"]
+ target: [macro, js, hl, cpp, 'java,jvm', cs, php, python, lua, flash, neko]
+ include:
+ - target: hl
+@@ -155,7 +168,7 @@ jobs:
+ submodules: recursive
+ - uses: actions/download-artifact@v3
+ with:
+- name: linuxBinaries
++ name: linuxBinaries${{ (matrix.ocaml == '5.0.0' && '_ocaml5') || '' }}
+ path: linuxBinaries
+
+ @import install-neko-unix.yml
+@@ -325,7 +338,13 @@ jobs:
+ with:
+ submodules: recursive
+
+- @import cache-opam.yml
++ - name: Cache opam
++ id: cache-opam
++ uses: actions/cache(a)v3.0.11
++ with:
++ path: ~/.opam/
++ key: ${{ runner.os }}-${{ hashFiles('./haxe.opam', './libs/') }}
++
+ @import install-neko-unix.yml
+ @import build-mac.yml
+
+diff --git a/haxe.opam b/haxe.opam
+index 60e1671fe..6da637e95 100644
+--- a/haxe.opam
++++ b/haxe.opam
+@@ -19,15 +19,16 @@ build: [
+ install: [make "install" "INSTALL_DIR=%{prefix}%"]
+ remove: [make "uninstall" "INSTALL_DIR=%{prefix}%"]
+ depends: [
+- "ocaml" {>= "4.08"}
++ ("ocaml" {>= "5.0"} & ("camlp5" {build}))
++ | ("ocaml" {>= "4.08" & < "5.0"} & ("camlp5" {build & = "8.00"}))
+ "ocamlfind" {build}
+ "dune" {>= "1.11"}
+- "camlp5" {build & = "8.00"}
+ "sedlex" {>= "2.0"}
+ "xml-light"
+ "extlib" {>= "1.7.8"}
+ "ptmap" {>= "2.0.0"}
+ "sha"
++ "camlp-streams"
+ "conf-libpcre2-8"
+ "conf-zlib"
+ "conf-neko"
+diff --git a/libs/extc/extc_stubs.c b/libs/extc/extc_stubs.c
+index 30dc986d5..92faa58aa 100644
+--- a/libs/extc/extc_stubs.c
++++ b/libs/extc/extc_stubs.c
+@@ -92,7 +92,7 @@ int Zflush_val(value zflush_val) {
+ case 4: return Z_FINISH;
+ // TODO: support Z_BLOCK and Z_TREE
+ // TODO: append the received value
+- default: failwith("Error in `Zflush_val` (extc_stubs.c): Unknown zflush value");
++ default: caml_failwith("Error in `Zflush_val` (extc_stubs.c): Unknown zflush value");
+ }
+ assert(0);
+ }
+@@ -222,14 +222,14 @@ CAMLprim value zlib_deflate_init2(value level_val, value window_bits_val) {
+ break;
+ case Z_STREAM_ERROR:
+ // TODO: use stream->msg to get _zlib_'s text message
+- failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_STREAM_ERROR");
++ caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_STREAM_ERROR");
+ break;
+ case Z_VERSION_ERROR:
+ // TODO: use stream->msg to get _zlib_'s text message
+- failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_VERSION_ERROR");
++ caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): call to `deflateInit2` failed: Z_VERSION_ERROR");
+ break;
+ default:
+- failwith("Error in `zlib_deflate_init2` (extc_stubs.c): unknown return code from `deflateInit2`");
++ caml_failwith("Error in `zlib_deflate_init2` (extc_stubs.c): unknown return code from `deflateInit2`");
+ }
+ assert(0);
+ }
+@@ -275,7 +275,7 @@ CAMLprim value zlib_deflate(value stream_val, value src, value spos, value slen,
+ if (deflate_result == Z_OK || deflate_result == Z_STREAM_END) {
+ stream->next_in = NULL;
+ stream->next_out = NULL;
+- value zresult = alloc_small(3, 0);
++ value zresult = caml_alloc_small(3, 0);
+ // z_finish
+ Field(zresult, 0) = Val_bool(deflate_result == Z_STREAM_END);
+ // z_read
+@@ -291,14 +291,14 @@ CAMLprim value zlib_deflate(value stream_val, value src, value spos, value slen,
+ break;
+ case Z_STREAM_ERROR:
+ // TODO: use stream->msg to get _zlib_'s text message
+- failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_STREAM_ERROR");
++ caml_failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_STREAM_ERROR");
+ break;
+ case Z_BUF_ERROR:
+ // TODO: use stream->msg to get _zlib_'s text message
+- failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_BUF_ERROR");
++ caml_failwith("Error in `zlib_deflate` (extc_stubs.c): call to `deflate` failed: Z_BUF_ERROR");
+ break;
+ default:
+- failwith("Error in `zlib_deflate` (extc_stubs.c): unknown return code from `deflate`");
++ caml_failwith("Error in `zlib_deflate` (extc_stubs.c): unknown return code from `deflate`");
+ }
+ assert(0);
+ }
+@@ -309,14 +309,14 @@ CAMLprim value zlib_deflate_bytecode(value *arg, int nargs) {
+
+ CAMLprim value zlib_deflate_end(value zv) {
+ if( deflateEnd(ZStreamP_val(zv)) != 0 )
+- failwith("zlib_deflate_end");
++ caml_failwith("zlib_deflate_end");
+ return Val_unit;
+ }
+
+ CAMLprim value zlib_inflate_init(value wbits) {
+ value z = zlib_new_stream();
+ if( inflateInit2(ZStreamP_val(z),Int_val(wbits)) != Z_OK )
+- failwith("zlib_inflate_init");
++ caml_failwith("zlib_inflate_init");
+ return z;
+ }
+
+@@ -330,12 +330,12 @@ CAMLprim value zlib_inflate( value zv, value src, value spos, value slen, value
+ z->avail_in = Int_val(slen);
+ z->avail_out = Int_val(dlen);
+ if( (r = inflate(z,Int_val(flush))) < 0 )
+- failwith("zlib_inflate");
++ caml_failwith("zlib_inflate");
+
+ z->next_in = NULL;
+ z->next_out = NULL;
+
+- res = alloc_small(3, 0);
++ res = caml_alloc_small(3, 0);
+ Field(res, 0) = Val_bool(r == Z_STREAM_END);
+ Field(res, 1) = Val_int(Int_val(slen) - z->avail_in);
+ Field(res, 2) = Val_int(Int_val(dlen) - z->avail_out);
+@@ -348,7 +348,7 @@ CAMLprim value zlib_inflate_bytecode(value * arg, int nargs) {
+
+ CAMLprim value zlib_inflate_end(value zv) {
+ if( inflateEnd(ZStreamP_val(zv)) != 0 )
+- failwith("zlib_inflate_end");
++ caml_failwith("zlib_inflate_end");
+ return Val_unit;
+ }
+
+@@ -368,13 +368,13 @@ CAMLprim value executable_path(value u) {
+ #ifdef _WIN32
+ char path[MAX_PATH];
+ if( GetModuleFileName(NULL,path,MAX_PATH) == 0 )
+- failwith("executable_path");
++ caml_failwith("executable_path");
+ return caml_copy_string(path);
+ #elif __APPLE__
+ char path[MAXPATHLEN+1];
+ uint32_t path_len = MAXPATHLEN;
+ if ( _NSGetExecutablePath(path, &path_len) )
+- failwith("executable_path");
++ caml_failwith("executable_path");
+ return caml_copy_string(path);
+ #elif __FreeBSD__
+ char path[PATH_MAX];
+@@ -387,7 +387,7 @@ CAMLprim value executable_path(value u) {
+ len = sizeof(path);
+ error = sysctl(name, 4, path, &len, NULL, 0);
+ if( error < 0 )
+- failwith("executable_path");
++ caml_failwith("executable_path");
+ return caml_copy_string(path);
+ #else
+ char path[PATH_MAX];
+@@ -397,7 +397,7 @@ CAMLprim value executable_path(value u) {
+ if( p != NULL )
+ return caml_copy_string(p);
+ else
+- failwith("executable_path");
++ caml_failwith("executable_path");
+ }
+ path[length] = '\0';
+ return caml_copy_string(path);
+@@ -408,12 +408,12 @@ CAMLprim value get_full_path( value f ) {
+ #ifdef _WIN32
+ char path[MAX_PATH];
+ if( GetFullPathName(String_val(f),MAX_PATH,path,NULL) == 0 )
+- failwith("get_full_path");
++ caml_failwith("get_full_path");
+ return caml_copy_string(path);
+ #else
+ char path[4096];
+ if( realpath(String_val(f),path) == NULL )
+- failwith("get_full_path");
++ caml_failwith("get_full_path");
+ return caml_copy_string(path);
+ #endif
+ }
+@@ -428,7 +428,7 @@ CAMLprim value get_real_path( value path ) {
+
+ // this will ensure the full class path with proper casing
+ if( GetFullPathName(String_val(path),MAX_PATH,out,NULL) == 0 )
+- failwith("get_real_path");
++ caml_failwith("get_real_path");
+
+ len = strlen(out);
+ i = 0;
+@@ -501,7 +501,7 @@ CAMLprim value sys_time() {
+ ULARGE_INTEGER ui;
+ GetSystemTime(&t);
+ if( !SystemTimeToFileTime(&t,&ft) )
+- failwith("sys_cpu_time");
++ caml_failwith("sys_cpu_time");
+ ui.LowPart = ft.dwLowDateTime;
+ ui.HighPart = ft.dwHighDateTime;
+ return caml_copy_double( ((double)ui.QuadPart) / 10000000.0 - EPOCH_DIFF );
+diff --git a/libs/extc/process_stubs.c b/libs/extc/process_stubs.c
+index c17c7a4f5..1f42c0fd1 100644
+--- a/libs/extc/process_stubs.c
++++ b/libs/extc/process_stubs.c
+@@ -67,10 +67,10 @@
+ #define val_null Val_int(0)
+ #define val_some(v) Field(v,0)
+ #define val_int(v) Int_val(v)
+-#define neko_error() failwith(__FUNCTION__)
++#define neko_error() caml_failwith(__FUNCTION__)
+
+ static value alloc_private( int size ) {
+- return alloc((size + sizeof(value) - 1) / sizeof(value), Abstract_tag);
++ return caml_alloc((size + sizeof(value) - 1) / sizeof(value), Abstract_tag);
+ }
+
+ // --- buffer api
+diff --git a/libs/extlib-leftovers/uTF8.ml b/libs/extlib-leftovers/uTF8.ml
+index ef61364de..ec25bd7ae 100644
+--- a/libs/extlib-leftovers/uTF8.ml
++++ b/libs/extlib-leftovers/uTF8.ml
+@@ -177,7 +177,7 @@ let rec iter_aux proc s i =
+
+ let iter proc s = iter_aux proc s 0
+
+-let compare s1 s2 = Pervasives.compare s1 s2
++let compare s1 s2 = Stdlib.compare s1 s2
+
+ exception Malformed_code
+
+diff --git a/libs/ilib/peReader.ml b/libs/ilib/peReader.ml
+index fc79151e5..4d2e4aadb 100644
+--- a/libs/ilib/peReader.ml
++++ b/libs/ilib/peReader.ml
+@@ -25,7 +25,7 @@ open ExtList;;
+ exception Error_message of string
+
+ type reader_ctx = {
+- ch : Pervasives.in_channel;
++ ch : Stdlib.in_channel;
+ i : IO.input;
+ verbose : bool;
+ }
+@@ -42,7 +42,7 @@ let seek r pos =
+ seek_in r.ch pos
+
+ let pos r =
+- Pervasives.pos_in r.ch
++ Stdlib.pos_in r.ch
+
+ let info r msg =
+ if r.verbose then
+diff --git a/libs/objsize/c_objsize.c b/libs/objsize/c_objsize.c
+index 5f222e072..4a3167531 100644
+--- a/libs/objsize/c_objsize.c
++++ b/libs/objsize/c_objsize.c
+@@ -12,6 +12,11 @@
+ #include "util.h"
+
+ #include <caml/memory.h>
++#include <caml/version.h>
++
++#if OCAML_VERSION_MAJOR >= 5
++#include <caml/address_class.h>
++#endif
+
+ // FROM byterun/gc.h
+ #define Caml_white (0 << 8)
+@@ -38,6 +43,7 @@
+ #define In_static_data 4
+ #define In_code_area 8
+
++#if OCAML_VERSION_MAJOR < 5
+ #ifdef ARCH_SIXTYFOUR
+
+ // 64 bits: Represent page table as a sparse hash table
+@@ -63,6 +69,23 @@ CAMLextern unsigned char * caml_page_table[Pagetable1_size];
+
+ #define Is_in_heap_or_young(a) (Classify_addr(a) & (In_heap | In_young))
+
++void store_explicit(header_t hd, value v, int col)
++ {
++ Hd_val(v) = Coloredhd_hd(hd, col);
++ }
++
++#else
++
++void store_explicit(header_t hd, value v, int col)
++ {
++ atomic_store_explicit(
++ Hp_atomic_val(v),
++ Coloredhd_hd(hd, col),
++ memory_order_release);
++ }
++
++#endif
++
+ //--------------------------------------------------------
+
+
+@@ -352,7 +375,7 @@ void c_rec_objsize(value v, size_t depth)
+
+ DBG(printf("COL: w %08lx %i\n", v, col));
+
+- Hd_val(v) = Coloredhd_hd(hd, Col_blue);
++ store_explicit(hd, v, Col_blue);
+
+ if (Tag_val(v) < No_scan_tag)
+ {
+@@ -378,7 +401,7 @@ void restore_colors(value v)
+
+ col = readcolor();
+ DBG(printf("COL: r %08lx %i\n", v, col));
+- Hd_val(v) = Coloredhd_hd(Hd_val(v), col);
++ store_explicit(Hd_val(v), v, col);
+
+ if (Tag_val(v) < No_scan_tag)
+ {
+@@ -417,7 +440,7 @@ int c_objsize(value v, value scan, value reach, size_t* headers, size_t* data, s
+ head = Field(head,1);
+ if( col == Col_blue ) continue;
+ writecolor(col);
+- Hd_val(v) = Coloredhd_hd(hd, Col_blue);
++ store_explicit(hd, v, Col_blue);
+ }
+
+ acc_data = 0;
+@@ -444,7 +467,7 @@ int c_objsize(value v, value scan, value reach, size_t* headers, size_t* data, s
+ head = Field(head,1);
+ if( Colornum_hd(Hd_val(v)) != Col_blue ) continue;
+ col = readcolor();
+- Hd_val(v) = Coloredhd_hd(Hd_val(v), col);
++ store_explicit(Hd_val(v), v, col);
+ }
+
+ while( COND_BLOCK(reach) ) {
+diff --git a/libs/swflib/swfParser.ml b/libs/swflib/swfParser.ml
+index 2f6474532..8006c81ae 100644
+--- a/libs/swflib/swfParser.ml
++++ b/libs/swflib/swfParser.ml
+@@ -444,7 +444,7 @@ and tag_length t =
+ (* READ PRIMS *)
+
+ let skip ch n =
+- seek_in ch ((Pervasives.pos_in ch) + n)
++ seek_in ch ((Stdlib.pos_in ch) + n)
+
+ let read_rgba ch =
+ let r = read_byte ch in
+diff --git a/libs/swflib/swfPic.ml b/libs/swflib/swfPic.ml
+index 7e69e28eb..613260d18 100644
+--- a/libs/swflib/swfPic.ml
++++ b/libs/swflib/swfPic.ml
+@@ -59,7 +59,7 @@ let load_picture file id =
+ let len = String.length file in
+ let p = (try String.rindex file '.' with Not_found -> len) in
+ let ext = String.sub file (p + 1) (len - (p + 1)) in
+- match String.uppercase ext with
++ match ExtString.String.uppercase ext with
+ | "PNG" ->
+ let png , header, data = (try
+ let p = Png.parse ch in
+diff --git a/libs/ttflib/tTFParser.ml b/libs/ttflib/tTFParser.ml
+index 68d1e2632..9b3468ac7 100644
+--- a/libs/ttflib/tTFParser.ml
++++ b/libs/ttflib/tTFParser.ml
+@@ -24,7 +24,7 @@ open TTFData
+ open IO
+
+ type ctx = {
+- file : Pervasives.in_channel;
++ file : Stdlib.in_channel;
+ ch : input;
+ mutable entry : entry;
+ }
+diff --git a/libs/ziplib/zip.ml b/libs/ziplib/zip.ml
+index 9245f0d00..0e5edc1eb 100644
+--- a/libs/ziplib/zip.ml
++++ b/libs/ziplib/zip.ml
+@@ -62,7 +62,7 @@ type entry =
+
+ type in_file =
+ { if_filename: string;
+- if_channel: Pervasives.in_channel;
++ if_channel: Stdlib.in_channel;
+ if_entries: entry list;
+ if_directory: (string, entry) Hashtbl.t;
+ if_comment: string }
+@@ -72,7 +72,7 @@ let comment ifile = ifile.if_comment
+
+ type out_file =
+ { of_filename: string;
+- of_channel: Pervasives.out_channel;
++ of_channel: Stdlib.out_channel;
+ mutable of_entries: entry list;
+ of_comment: string }
+
+@@ -217,7 +217,7 @@ let read_cd filename ic cd_entries cd_offset cd_bound =
+ (* Open a ZIP file for reading *)
+
+ let open_in filename =
+- let ic = Pervasives.open_in_bin filename in
++ let ic = Stdlib.open_in_bin filename in
+ let (cd_entries, cd_size, cd_offset, cd_comment) = read_ecd filename ic in
+ let entries =
+ read_cd filename ic cd_entries cd_offset (Int32.add cd_offset cd_size) in
+@@ -232,7 +232,7 @@ let open_in filename =
+ (* Close a ZIP file opened for reading *)
+
+ let close_in ifile =
+- Pervasives.close_in ifile.if_channel
++ Stdlib.close_in ifile.if_channel
+
+ (* Return the info associated with an entry *)
+
+@@ -369,7 +369,7 @@ let open_out ?(comment = "") filename =
+ if String.length comment >= 0x10000 then
+ raise(Error(filename, "", "comment too long"));
+ { of_filename = filename;
+- of_channel = Pervasives.open_out_bin filename;
++ of_channel = Stdlib.open_out_bin filename;
+ of_entries = [];
+ of_comment = comment }
+
+@@ -416,7 +416,7 @@ let close_out ofile =
+ write4_int oc start_cd; (* offset of central dir *)
+ write2 oc (String.length ofile.of_comment); (* length of comment *)
+ writestring oc ofile.of_comment; (* comment *)
+- Pervasives.close_out oc
++ Stdlib.close_out oc
+
+ (* Write a local file header and return the corresponding entry *)
+
+@@ -552,9 +552,9 @@ let copy_file_to_entry infilename ofile ?(extra = "") ?(comment = "")
+ with Unix.Unix_error(_,_,_) -> None in
+ try
+ copy_channel_to_entry ic ofile ~extra ~comment ~level ?mtime:mtime' name;
+- Pervasives.close_in ic
++ Stdlib.close_in ic
+ with x ->
+- Pervasives.close_in ic; raise x
++ Stdlib.close_in ic; raise x
+
+
+ (* Add an entry whose content will be produced by the caller *)
+diff --git a/src/codegen/dotnet.ml b/src/codegen/dotnet.ml
+index e90cfe955..90bf25ec6 100644
+--- a/src/codegen/dotnet.ml
++++ b/src/codegen/dotnet.ml
+@@ -68,7 +68,7 @@ let cs_unops =
+ let netname_to_hx name =
+ let len = String.length name in
+ let chr = String.get name 0 in
+- String.make 1 (Char.uppercase chr) ^ (String.sub name 1 (len-1))
++ String.make 1 (Char.uppercase_ascii chr) ^ (String.sub name 1 (len-1))
+
+ (* -net-lib implementation *)
+
+@@ -105,7 +105,7 @@ let escape_chars =
+
+ let netcl_to_hx cl =
+ let cl = if String.length cl > 0 && String.get cl 0 >= 'a' && String.get cl 0 <= 'z' then
+- Char.escaped (Char.uppercase (String.get cl 0)) ^ (String.sub cl 1 (String.length cl - 1))
++ Char.escaped (Char.uppercase_ascii (String.get cl 0)) ^ (String.sub cl 1 (String.length cl - 1))
+ else
+ cl
+ in
+diff --git a/src/codegen/java.ml b/src/codegen/java.ml
+index ba86b4eea..20906bbec 100644
+--- a/src/codegen/java.ml
++++ b/src/codegen/java.ml
+@@ -46,7 +46,7 @@ let is_haxe_keyword = function
+ let jname_to_hx name =
+ let name =
+ if name <> "" && (String.get name 0 < 'A' || String.get name 0 > 'Z') then
+- Char.escaped (Char.uppercase (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
++ Char.escaped (Char.uppercase_ascii (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
+ else
+ name
+ in
+diff --git a/src/codegen/javaModern.ml b/src/codegen/javaModern.ml
+index 5908c19a0..7a298292c 100644
+--- a/src/codegen/javaModern.ml
++++ b/src/codegen/javaModern.ml
+@@ -555,7 +555,7 @@ module PathConverter = struct
+ let jname_to_hx name =
+ let name =
+ if name <> "" && (String.get name 0 < 'A' || String.get name 0 > 'Z') then
+- Char.escaped (Char.uppercase (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
++ Char.escaped (Char.uppercase_ascii (String.get name 0)) ^ String.sub name 1 (String.length name - 1)
+ else
+ name
+ in
+diff --git a/src/codegen/swfLoader.ml b/src/codegen/swfLoader.ml
+index 6b7ef3b67..6588dffde 100644
+--- a/src/codegen/swfLoader.ml
++++ b/src/codegen/swfLoader.ml
+@@ -33,7 +33,7 @@ let lowercase_pack pack =
+ let name =
+ let fchar = String.get name 0 in
+ if fchar >= 'A' && fchar <= 'Z' then
+- (String.make 1 (Char.lowercase fchar)) ^ String.sub name 1 (String.length name - 1)
++ (String.make 1 (Char.lowercase_ascii fchar)) ^ String.sub name 1 (String.length name - 1)
+ else
+ name
+ in
+diff --git a/src/compiler/displayProcessing.ml b/src/compiler/displayProcessing.ml
+index 7cec1d9d7..e32f7fcac 100644
+--- a/src/compiler/displayProcessing.ml
++++ b/src/compiler/displayProcessing.ml
+@@ -268,7 +268,7 @@ let maybe_load_display_file_before_typing tctx display_file_dot_path = match dis
+
+ let handle_display_after_typing ctx tctx display_file_dot_path =
+ let com = ctx.com in
+- if ctx.com.display.dms_kind = DMNone & ctx.has_error then raise Abort;
++ if ctx.com.display.dms_kind = DMNone && ctx.has_error then raise Abort;
+ begin match ctx.com.display.dms_kind,!Parser.delayed_syntax_completion with
+ | DMDefault,Some(kind,subj) -> DisplayOutput.handle_syntax_completion com kind subj
+ | _ -> ()
+diff --git a/src/context/display/displayException.ml b/src/context/display/displayException.ml
+index a731f9a1d..661bb1bd1 100644
+--- a/src/context/display/displayException.ml
++++ b/src/context/display/displayException.ml
+@@ -23,9 +23,9 @@ let max_completion_items = ref 0
+ let filter_somehow ctx items kind subj =
+ let subject = match subj.s_name with
+ | None -> ""
+- | Some name-> String.lowercase name
++ | Some name-> ExtString.String.lowercase name
+ in
+- let subject_length = String.length subject in
++ let subject_length = ExtString.String.length subject in
+ let determine_cost s =
+ let get_initial_cost o =
+ if o = 0 then
+@@ -33,7 +33,7 @@ let filter_somehow ctx items kind subj =
+ else begin
+ (* Consider `.` as anchors and determine distance from closest one. Penalize starting distance by factor 2. *)
+ try
+- let last_anchor = String.rindex_from s o '.' in
++ let last_anchor = ExtString.String.rindex_from s o '.' in
+ (o - (last_anchor + 1)) * 2
+ with Not_found ->
+ o * 2
+@@ -54,12 +54,12 @@ let filter_somehow ctx items kind subj =
+ let o',new_cost = index_from o subject.[i] in
+ loop (i + 1) o' (cost + new_cost)
+ end else
+- cost + (if o = String.length s - 1 then 0 else 1) (* Slightly penalize for not-exact matches. *)
++ cost + (if o = ExtString.String.length s - 1 then 0 else 1) (* Slightly penalize for not-exact matches. *)
+ in
+ if subject_length = 0 then
+ 0
+ else try
+- let o = String.index s subject.[0] in
++ let o = ExtString.String.index s subject.[0] in
+ loop 1 o (get_initial_cost o);
+ with Not_found | Invalid_argument _ ->
+ -1
+@@ -67,7 +67,7 @@ let filter_somehow ctx items kind subj =
+ let rec loop acc items index =
+ match items with
+ | item :: items ->
+- let name = String.lowercase (get_filter_name item) in
++ let name = ExtString.String.lowercase (get_filter_name item) in
+ let cost = determine_cost name in
+ let acc = if cost >= 0 then
+ (item,index,cost) :: acc
+@@ -102,8 +102,8 @@ let patch_completion_subject subj =
+ match subj.s_name with
+ | Some name ->
+ let delta = p.pmax - p.pmin in
+- let name = if delta > 0 && delta < String.length name then
+- String.sub name 0 delta
++ let name = if delta > 0 && delta < ExtString.String.length name then
++ ExtString.String.sub name 0 delta
+ else
+ name
+ in
+diff --git a/src/context/display/documentSymbols.ml b/src/context/display/documentSymbols.ml
+index 705c8be1d..4d61a6ae4 100644
+--- a/src/context/display/documentSymbols.ml
++++ b/src/context/display/documentSymbols.ml
+@@ -56,7 +56,7 @@ let collect_module_symbols mname with_locals (pack,decls) =
+ | FFun f ->
+ add_field (
+ if fst cff_name = "new" then Constructor
+- else if ((parent_kind = EnumAbstract or parent_kind = Abstract) && Meta.has_one_of [Meta.Op; Meta.ArrayAccess; Meta.Resolve] cff_meta) then Operator
++ else if ((parent_kind = EnumAbstract || parent_kind = Abstract) && Meta.has_one_of [Meta.Op; Meta.ArrayAccess; Meta.Resolve] cff_meta) then Operator
+ else Method
+ );
+ if with_locals then func field_parent f
+diff --git a/src/context/typecore.ml b/src/context/typecore.ml
+index 22ccc8a00..fc2b33ba6 100644
+--- a/src/context/typecore.ml
++++ b/src/context/typecore.ml
+@@ -602,7 +602,7 @@ let merge_core_doc ctx mt =
+
+ let field_to_type_path com e =
+ let rec loop e pack name = match e with
+- | EField(e,f,_),p when Char.lowercase (String.get f 0) <> String.get f 0 -> (match name with
++ | EField(e,f,_),p when Char.lowercase_ascii (String.get f 0) <> String.get f 0 -> (match name with
+ | [] | _ :: [] ->
+ loop e pack (f :: name)
+ | _ -> (* too many name paths *)
+@@ -614,7 +614,7 @@ let field_to_type_path com e =
+ let pack, name, sub = match name with
+ | [] ->
+ let fchar = String.get f 0 in
+- if Char.uppercase fchar = fchar then
++ if Char.uppercase_ascii fchar = fchar then
+ pack, f, None
+ else begin
+ display_error com "A class name must start with an uppercase letter" (snd e);
+@@ -664,12 +664,12 @@ let s_field_call_candidate fcc =
+ let relative_path ctx file =
+ let slashes path = String.concat "/" (ExtString.String.nsplit path "\\") in
+ let fpath = slashes (Path.get_full_path file) in
+- let fpath_lower = String.lowercase fpath in
++ let fpath_lower = String.lowercase_ascii fpath in
+ let flen = String.length fpath_lower in
+ let rec loop = function
+ | [] -> file
+ | path :: l ->
+- let spath = String.lowercase (slashes path) in
++ let spath = String.lowercase_ascii (slashes path) in
+ let slen = String.length spath in
+ if slen > 0 && slen < flen && String.sub fpath_lower 0 slen = spath then String.sub fpath slen (flen - slen) else loop l
+ in
+diff --git a/src/core/path.ml b/src/core/path.ml
+index c5bf6d74d..119908524 100644
+--- a/src/core/path.ml
++++ b/src/core/path.ml
+@@ -223,7 +223,7 @@ end = struct
+
+ let create =
+ if Globals.is_windows then
+- (fun f -> String.lowercase (get_full_path f))
++ (fun f -> ExtString.String.lowercase (get_full_path f))
+ else
+ get_full_path
+
+@@ -378,7 +378,7 @@ let full_dot_path pack mname tname =
+
+ let file_extension file =
+ match List.rev (ExtString.String.nsplit file ".") with
+- | e :: _ -> String.lowercase e
++ | e :: _ -> ExtString.String.lowercase e
+ | [] -> ""
+
+ module FilePath = struct
+diff --git a/src/dune b/src/dune
+index 6e21a11d4..f0175d635 100644
+--- a/src/dune
++++ b/src/dune
+@@ -9,7 +9,7 @@
+ (library
+ (name haxe)
+ (libraries
+- extc extproc extlib_leftovers ilib javalib mbedtls neko objsize pcre2 swflib ttflib ziplib
++ extc extproc extlib_leftovers ilib javalib mbedtls neko objsize pcre2 camlp-streams swflib ttflib ziplib
+ json
+ unix str bigarray threads dynlink
+ xml-light extlib ptmap sha
+diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml
+index a8ff59cf2..8156bfe83 100644
+--- a/src/generators/gencpp.ml
++++ b/src/generators/gencpp.ml
+@@ -7030,8 +7030,8 @@ let write_build_options common_ctx filename defines =
+ | _ -> write_define name (escape_command value)) defines;
+ let pin,pid = Process_helper.open_process_args_in_pid "haxelib" [|"haxelib"; "path"; "hxcpp"|] in
+ set_binary_mode_in pin false;
+- write_define "hxcpp" (Pervasives.input_line pin);
+- Pervasives.ignore (Process_helper.close_process_in_pid (pin,pid));
++ write_define "hxcpp" (Stdlib.input_line pin);
++ Stdlib.ignore (Process_helper.close_process_in_pid (pin,pid));
+ writer#close;;
+
+ let create_member_types common_ctx =
+diff --git a/src/generators/genhl.ml b/src/generators/genhl.ml
+index e8ffa87cd..12518a9ad 100644
+--- a/src/generators/genhl.ml
++++ b/src/generators/genhl.ml
+@@ -4059,7 +4059,7 @@ let add_types ctx types =
+ | Method MethNormal when not (List.exists (fun (m,_,_) -> m = Meta.HlNative) f.cf_meta) ->
+ (match f.cf_expr with
+ | Some { eexpr = TFunction { tf_expr = { eexpr = TBlock ([] | [{ eexpr = TReturn (Some { eexpr = TConst _ })}]) } } } | None ->
+- let name = prefix ^ String.lowercase (Str.global_replace (Str.regexp "[A-Z]+") "_\\0" f.cf_name) in
++ let name = prefix ^ String.lowercase_ascii (Str.global_replace (Str.regexp "[A-Z]+") "_\\0" f.cf_name) in
+ f.cf_meta <- (Meta.HlNative, [(EConst (String(lib,SDoubleQuotes)),p);(EConst (String(name,SDoubleQuotes)),p)], p) :: f.cf_meta;
+ | _ -> ())
+ | _ -> ()
+@@ -4149,7 +4149,7 @@ let generate com =
+ in
+
+ if Path.file_extension com.file = "c" then begin
+- let gnames = Array.create (Array.length code.globals) "" in
++ let gnames = Array.make (Array.length code.globals) "" in
+ PMap.iter (fun n i -> gnames.(i) <- n) ctx.cglobals.map;
+ if not (Common.defined com Define.SourceHeader) then begin
+ let version_major = com.version / 1000 in
+diff --git a/src/generators/genphp7.ml b/src/generators/genphp7.ml
+index 6d6b53941..9109993ef 100644
+--- a/src/generators/genphp7.ml
++++ b/src/generators/genphp7.ml
+@@ -15,8 +15,8 @@ open Sourcemaps
+ *)
+ let escape_bin s =
+ let b = Buffer.create 0 in
+- for i = 0 to String.length s - 1 do
+- match Char.code (String.unsafe_get s i) with
++ for i = 0 to ExtString.String.length s - 1 do
++ match Char.code (ExtString.String.unsafe_get s i) with
+ | c when c = Char.code('\\') || c = Char.code('"') || c = Char.code('$') ->
+ Buffer.add_string b "\\";
+ Buffer.add_char b (Char.chr c)
+@@ -46,7 +46,7 @@ let write_resource dir name data =
+ *)
+ let copy_file src dst =
+ let buffer_size = 8192 in
+- let buffer = String.create buffer_size in
++ let buffer = ExtString.String.create buffer_size in
+ let fd_in = Unix.openfile src [O_RDONLY] 0 in
+ let fd_out = Unix.openfile dst [O_WRONLY; O_CREAT; O_TRUNC] 0o644 in
+ let rec copy_loop () =
+@@ -196,7 +196,7 @@ end
+ (**
+ Check if specified string is a reserved word in PHP
+ *)
+-let is_keyword str = Hashtbl.mem php_keywords_tbl (String.lowercase str)
++let is_keyword str = Hashtbl.mem php_keywords_tbl (ExtString.String.lowercase str)
+
+ (**
+ Check if specified type is php.NativeArray
+@@ -531,10 +531,10 @@ let get_full_type_name ?(escape=false) ?(omit_first_slash=false) (type_path:path
+ else
+ "" :: get_real_path module_path
+ in
+- (String.concat "\\" parts) ^ "\\" ^ type_name
++ (ExtString.String.concat "\\" parts) ^ "\\" ^ type_name
+ in
+ if escape then
+- String.escaped name
++ ExtString.String.escaped name
+ else
+ name
+
+@@ -618,7 +618,7 @@ let fix_call_args callee_type exprs =
+ Escapes all "$" chars and encloses `str` into double quotes
+ *)
+ let quote_string str =
+- "\"" ^ (Str.global_replace (Str.regexp "\\$") "\\$" (String.escaped str)) ^ "\""
++ "\"" ^ (Str.global_replace (Str.regexp "\\$") "\\$" (ExtString.String.escaped str)) ^ "\""
+
+ (**
+ Check if specified field is a var with non-constant expression
+@@ -1296,21 +1296,21 @@ class code_writer (ctx:php_generator_context) hx_type_path php_name =
+ Decrease indentation by one level
+ *)
+ method indent_less =
+- indentation <- String.make ((String.length indentation) - 1) '\t';
++ indentation <- ExtString.String.make ((ExtString.String.length indentation) - 1) '\t';
+ (**
+ Set indentation level (starting from zero for no indentation)
+ *)
+ method indent level =
+- indentation <- String.make level '\t';
++ indentation <- ExtString.String.make level '\t';
+ (**
+ Get indentation level (starting from zero for no indentation)
+ *)
+- method get_indentation = String.length indentation
++ method get_indentation = ExtString.String.length indentation
+ (**
+ Set indentation level (starting from zero for no indentation)
+ *)
+ method set_indentation level =
+- indentation <- String.make level '\t'
++ indentation <- ExtString.String.make level '\t'
+ (**
+ Specify local var name declared in current scope
+ *)
+@@ -1326,7 +1326,7 @@ class code_writer (ctx:php_generator_context) hx_type_path php_name =
+ else if get_type_name type_path = "" then
+ match get_module_path type_path with
+ | [] -> "\\"
+- | module_path -> "\\" ^ (String.concat "\\" (get_real_path module_path)) ^ "\\"
++ | module_path -> "\\" ^ (ExtString.String.concat "\\" (get_real_path module_path)) ^ "\\"
+ else begin
+ let orig_type_path = type_path in
+ let type_path = match type_path with (pack, name) -> (pack, get_real_name name) in
+@@ -1942,7 +1942,7 @@ class code_writer (ctx:php_generator_context) hx_type_path php_name =
+ set_sourcemap_pointer sourcemap sm_pointer_before_body;
+ let locals = vars#pop_captured in
+ if List.length locals > 0 then begin
+- self#write ("unset($" ^ (String.concat ", $" locals) ^ ");\n");
++ self#write ("unset($" ^ (ExtString.String.concat ", $" locals) ^ ");\n");
+ self#write_indentation
+ end;
+ self#write_bypassing_sourcemap body;
+@@ -2999,7 +2999,7 @@ class virtual type_builder ctx (wrapper:type_wrapper) =
+ Returns generated file contents
+ *)
+ method get_contents =
+- if (String.length contents) = 0 then begin
++ if (ExtString.String.length contents) = 0 then begin
+ self#write_declaration;
+ writer#write_line " {"; (** opening bracket for a class *)
+ self#write_body;
+@@ -3016,7 +3016,7 @@ class virtual type_builder ctx (wrapper:type_wrapper) =
+ writer#write_statement ("require_once __DIR__.'/" ^ polyfills_file ^ "'");
+ writer#write_statement (boot_class ^ "::__hx__init()")
+ end;
+- let haxe_class = match wrapper#get_type_path with (path, name) -> String.concat "." (path @ [name]) in
++ let haxe_class = match wrapper#get_type_path with (path, name) -> ExtString.String.concat "." (path @ [name]) in
+ writer#write_statement (boot_class ^ "::registerClass(" ^ (self#get_name) ^ "::class, '" ^ haxe_class ^ "')");
+ self#write_rtti_meta;
+ self#write_pre_hx_init;
+@@ -3051,7 +3051,7 @@ class virtual type_builder ctx (wrapper:type_wrapper) =
+ writer#write "\n";
+ let namespace = self#get_namespace in
+ if List.length namespace > 0 then
+- writer#write_line ("namespace " ^ (String.concat "\\" namespace) ^ ";\n");
++ writer#write_line ("namespace " ^ (ExtString.String.concat "\\" namespace) ^ ";\n");
+ writer#write_use
+ (**
+ Generates PHP docblock and attributes to output buffer.
+@@ -3082,11 +3082,11 @@ class virtual type_builder ctx (wrapper:type_wrapper) =
+ Writes description section of docblocks
+ *)
+ method write_doc_description (doc:string) =
+- let lines = Str.split (Str.regexp "\n") (String.trim doc)
++ let lines = Str.split (Str.regexp "\n") (ExtString.String.trim doc)
+ and write_line line =
+- let trimmed = String.trim line in
+- if String.length trimmed > 0 then (
+- if String.get trimmed 0 = '*' then
++ let trimmed = ExtString.String.trim line in
++ if ExtString.String.length trimmed > 0 then (
++ if ExtString.String.get trimmed 0 = '*' then
+ writer#write_line (" " ^ trimmed)
+ else
+ writer#write_line (" * " ^ trimmed)
+@@ -3554,7 +3554,7 @@ class class_builder ctx (cls:tclass) =
+ cls.cl_implements
+ in
+ let interfaces = List.map use_interface unique in
+- writer#write (String.concat ", " interfaces);
++ writer#write (ExtString.String.concat ", " interfaces);
+ end;
+ (**
+ Returns either user-defined constructor or creates empty constructor if instance initialization is required.
+@@ -3667,7 +3667,7 @@ class class_builder ctx (cls:tclass) =
+ List.iter
+ (fun field ->
+ if not !required then
+- required := (String.lowercase field.cf_name = String.lowercase self#get_name)
++ required := (ExtString.String.lowercase field.cf_name = ExtString.String.lowercase self#get_name)
+ )
+ (cls.cl_ordered_statics @ cls.cl_ordered_fields);
+ !required
+@@ -3676,10 +3676,10 @@ class class_builder ctx (cls:tclass) =
+ Writes `-D php-prefix` value as class constant PHP_PREFIX
+ *)
+ method private write_php_prefix () =
+- let prefix = String.concat "\\" ctx.pgc_prefix in
++ let prefix = ExtString.String.concat "\\" ctx.pgc_prefix in
+ let indentation = writer#get_indentation in
+ writer#indent 1;
+- writer#write_statement ("const PHP_PREFIX = \"" ^ (String.escaped prefix) ^ "\"");
++ writer#write_statement ("const PHP_PREFIX = \"" ^ (ExtString.String.escaped prefix) ^ "\"");
+ writer#indent indentation
+ (**
+ Writes expressions for `__hx__init` method
+@@ -3998,8 +3998,8 @@ class generator (ctx:php_generator_context) =
+ if front_dirs <> [] then
+ ignore(create_dir_recursive (root_dir :: front_dirs));
+ let lib_path =
+- (String.concat "" (List.fold_left (fun acc s -> if s <> "." then "../" :: acc else acc) [] front_dirs))
+- ^ (String.concat "/" self#get_lib_path)
++ (ExtString.String.concat "" (List.fold_left (fun acc s -> if s <> "." then "../" :: acc else acc) [] front_dirs))
++ ^ (ExtString.String.concat "/" self#get_lib_path)
+ in
+ let channel = open_out (root_dir ^ "/" ^ filename) in
+ output_string channel "<?php\n";
+diff --git a/src/generators/genswf9.ml b/src/generators/genswf9.ml
+index 9bbd0ae6a..c2027e574 100644
+--- a/src/generators/genswf9.ml
++++ b/src/generators/genswf9.ml
+@@ -645,7 +645,7 @@ let begin_switch ctx =
+ constructs := (tag,ctx.infos.ipos) :: !constructs;
+ in
+ let fend() =
+- let cases = Array.create (!max + 1) 1 in
++ let cases = Array.make (!max + 1) 1 in
+ List.iter (fun (tag,pos) -> Array.set cases tag (pos - switch_pos)) !constructs;
+ DynArray.set ctx.code switch_index (HSwitch (1,Array.to_list cases));
+ branch();
+diff --git a/src/generators/hl2c.ml b/src/generators/hl2c.ml
+index af03a2617..2304debb0 100644
+--- a/src/generators/hl2c.ml
++++ b/src/generators/hl2c.ml
+@@ -1134,7 +1134,7 @@ let make_types_idents htypes =
+ try
+ PMap.find vp (!types_descs)
+ with Not_found ->
+- let arr = Array.create (Array.length vp.vfields) ("",DSimple HVoid) in
++ let arr = Array.make (Array.length vp.vfields) ("",DSimple HVoid) in
+ let td = DVirtual arr in
+ types_descs := PMap.add vp td (!types_descs);
+ Array.iteri (fun i (f,_,t) -> arr.(i) <- (f,make_desc t)) vp.vfields;
+diff --git a/src/generators/hlinterp.ml b/src/generators/hlinterp.ml
+index f6fc7f32f..2b5bc247a 100644
+--- a/src/generators/hlinterp.ml
++++ b/src/generators/hlinterp.ml
+@@ -1111,7 +1111,7 @@ let interp ctx f args =
+ (match rtype r with
+ | HEnum e ->
+ let _, _, fl = e.efields.(f) in
+- let vl = Array.create (Array.length fl) VUndef in
++ let vl = Array.make (Array.length fl) VUndef in
+ set r (VEnum (e, f, vl))
+ | _ -> Globals.die "" __LOC__
+ )
+@@ -1257,7 +1257,7 @@ let load_native ctx lib name t =
+ | _ -> Globals.die "" __LOC__)
+ | "alloc_array" ->
+ (function
+- | [VType t;VInt i] -> VArray (Array.create (int i) (default t),t)
++ | [VType t;VInt i] -> VArray (Array.make (int i) (default t),t)
+ | _ -> Globals.die "" __LOC__)
+ | "alloc_obj" ->
+ (function
+@@ -1347,7 +1347,7 @@ let load_native ctx lib name t =
+ | "math_asin" -> (function [VFloat f] -> VFloat (asin f) | _ -> Globals.die "" __LOC__)
+ | "math_atan" -> (function [VFloat f] -> VFloat (atan f) | _ -> Globals.die "" __LOC__)
+ | "math_atan2" -> (function [VFloat a; VFloat b] -> VFloat (atan2 a b) | _ -> Globals.die "" __LOC__)
+- | "math_log" -> (function [VFloat f] -> VFloat (Pervasives.log f) | _ -> Globals.die "" __LOC__)
++ | "math_log" -> (function [VFloat f] -> VFloat (Stdlib.log f) | _ -> Globals.die "" __LOC__)
+ | "math_exp" -> (function [VFloat f] -> VFloat (exp f) | _ -> Globals.die "" __LOC__)
+ | "math_pow" -> (function [VFloat a; VFloat b] -> VFloat (a ** b) | _ -> Globals.die "" __LOC__)
+ | "parse_int" ->
+@@ -1539,7 +1539,7 @@ let load_native ctx lib name t =
+ | "Darwin" -> "Mac"
+ | n -> n
+ ) in
+- Pervasives.ignore (Process_helper.close_process_in_pid (ic, pid));
++ Stdlib.ignore (Process_helper.close_process_in_pid (ic, pid));
+ cached_sys_name := Some uname;
+ uname)
+ | "Win32" | "Cygwin" -> "Windows"
+@@ -2147,7 +2147,7 @@ let add_code ctx code =
+ ctx.t_globals <- globals;
+ (* expand function table *)
+ let nfunctions = Array.length code.functions + Array.length code.natives in
+- let functions = Array.create nfunctions (FNativeFun ("",(fun _ -> Globals.die "" __LOC__),HDyn)) in
++ let functions = Array.make nfunctions (FNativeFun ("",(fun _ -> Globals.die "" __LOC__),HDyn)) in
+ Array.blit ctx.t_functions 0 functions 0 (Array.length ctx.t_functions);
+ let rec loop i =
+ if i = Array.length code.natives then () else
+@@ -2191,7 +2191,7 @@ let add_code ctx code =
+ (* ------------------------------- CHECK ---------------------------------------------- *)
+
+ let check code macros =
+- let ftypes = Array.create (Array.length code.natives + Array.length code.functions) HVoid in
++ let ftypes = Array.make (Array.length code.natives + Array.length code.functions) HVoid in
+ let is_native_fun = Hashtbl.create 0 in
+
+ let check_fun f =
+diff --git a/src/macro/eval/evalJit.ml b/src/macro/eval/evalJit.ml
+index 6218f394f..d2b5f3c15 100644
+--- a/src/macro/eval/evalJit.ml
++++ b/src/macro/eval/evalJit.ml
+@@ -230,7 +230,7 @@ and jit_expr jit return e =
+ let hasret = jit_closure.has_nonfinal_return in
+ let eci = get_env_creation jit_closure false tf.tf_expr.epos.pfile (EKLocalFunction jit.num_closures) in
+ let captures = Hashtbl.fold (fun vid (i,declared) acc -> (i,vid,declared) :: acc) jit_closure.captures [] in
+- let captures = List.sort (fun (i1,_,_) (i2,_,_) -> Pervasives.compare i1 i2) captures in
++ let captures = List.sort (fun (i1,_,_) (i2,_,_) -> Stdlib.compare i1 i2) captures in
+ (* Check if the out-of-scope var is in the outer scope because otherwise we have to promote outwards. *)
+ List.iter (fun var -> ignore(get_capture_slot jit var)) jit_closure.captures_outside_scope;
+ let captures = ExtList.List.filter_map (fun (i,vid,declared) ->
+diff --git a/src/macro/eval/evalStdLib.ml b/src/macro/eval/evalStdLib.ml
+index 501387567..935733b53 100644
+--- a/src/macro/eval/evalStdLib.ml
++++ b/src/macro/eval/evalStdLib.ml
+@@ -289,7 +289,7 @@ module StdBytes = struct
+ let compare = vifun1 (fun vthis other ->
+ let this = this vthis in
+ let other = decode_bytes other in
+- vint (Pervasives.compare this other)
++ vint (Stdlib.compare this other)
+ )
+
+ let fastGet = vfun2 (fun b pos ->
+@@ -1694,13 +1694,13 @@ module StdMath = struct
+ let ceil = vfun1 (fun v -> match v with VInt32 _ -> v | _ -> vint32 (to_int (ceil (num v))))
+ let cos = vfun1 (fun v -> vfloat (cos (num v)))
+ let exp = vfun1 (fun v -> vfloat (exp (num v)))
+- let fceil = vfun1 (fun v -> vfloat (Pervasives.ceil (num v)))
+- let ffloor = vfun1 (fun v -> vfloat (Pervasives.floor (num v)))
++ let fceil = vfun1 (fun v -> vfloat (Stdlib.ceil (num v)))
++ let ffloor = vfun1 (fun v -> vfloat (Stdlib.floor (num v)))
+ let floor = vfun1 (fun v -> match v with VInt32 _ -> v | _ -> vint32 (to_int (floor (num v))))
+- let fround = vfun1 (fun v -> vfloat (Pervasives.floor (num v +. 0.5)))
++ let fround = vfun1 (fun v -> vfloat (Stdlib.floor (num v +. 0.5)))
+ let isFinite = vfun1 (fun v -> vbool (match v with VFloat f -> f <> infinity && f <> neg_infinity && f = f | _ -> true))
+ let isNaN = vfun1 (fun v -> vbool (match v with VFloat f -> f <> f | VInt32 _ -> false | _ -> true))
+- let log = vfun1 (fun v -> vfloat (Pervasives.log (num v)))
++ let log = vfun1 (fun v -> vfloat (Stdlib.log (num v)))
+
+ let max = vfun2 (fun a b ->
+ let a = num a in
+@@ -1716,7 +1716,7 @@ module StdMath = struct
+
+ let pow = vfun2 (fun a b -> vfloat ((num a) ** (num b)))
+ let random = vfun0 (fun () -> vfloat (Random.State.float random 1.))
+- let round = vfun1 (fun v -> match v with VInt32 _ -> v | _ -> vint32 (to_int (Pervasives.floor (num v +. 0.5))))
++ let round = vfun1 (fun v -> match v with VInt32 _ -> v | _ -> vint32 (to_int (Stdlib.floor (num v +. 0.5))))
+ let sin = vfun1 (fun v -> vfloat (sin (num v)))
+
+ let sqrt = vfun1 (fun v ->
+@@ -2690,7 +2690,7 @@ module StdSys = struct
+ | "Darwin" -> "Mac"
+ | n -> n
+ ) in
+- Pervasives.ignore (Process_helper.close_process_in_pid (ic, pid));
++ Stdlib.ignore (Process_helper.close_process_in_pid (ic, pid));
+ cached_sys_name := Some uname;
+ uname)
+ | "Win32" | "Cygwin" -> "Windows"
+@@ -2735,10 +2735,12 @@ module StdThread = struct
+ vnull
+ )
+
+- let kill = vifun0 (fun vthis ->
+- Thread.kill (this vthis).tthread;
+- vnull
+- )
++ (* Thread.kill has been marked deprecated (because unstable or even not working at all) for a while, and removed in ocaml 5 *)
++ (* See also https://github.com/HaxeFoundation/haxe/issues/5800 *)
++ (* let kill = vifun0 (fun vthis -> *)
++ (* Thread.kill (this vthis).tthread; *)
++ (* vnull *)
++ (* ) *)
+
+ let self = vfun0 (fun () ->
+ let eval = get_eval (get_ctx()) in
+@@ -3064,7 +3066,7 @@ module StdUtf8 = struct
+ let compare = vfun2 (fun a b ->
+ let a = decode_string a in
+ let b = decode_string b in
+- vint (Pervasives.compare a b)
++ vint (Stdlib.compare a b)
+ )
+
+ let decode = vfun1 (fun s ->
+@@ -3730,7 +3732,7 @@ let init_standard_library builtins =
+ "id",StdThread.id;
+ "get_events",StdThread.get_events;
+ "set_events",StdThread.set_events;
+- "kill",StdThread.kill;
++ (* "kill",StdThread.kill; *)
+ "sendMessage",StdThread.sendMessage;
+ ];
+ init_fields builtins (["sys";"thread"],"Tls") [] [
+diff --git a/src/optimization/inlineConstructors.ml b/src/optimization/inlineConstructors.ml
+index 8df1b5d79..de9b666cf 100644
+--- a/src/optimization/inlineConstructors.ml
++++ b/src/optimization/inlineConstructors.ml
+@@ -499,7 +499,7 @@ let inline_constructors ctx original_e =
+ | IOFInlineMethod(io,io_var,c,tl,cf,tf) ->
+ let argvs, pl = analyze_call_args call_args in
+ io.io_dependent_vars <- io.io_dependent_vars @ argvs;
+- io.io_has_untyped <- io.io_has_untyped or (Meta.has Meta.HasUntyped cf.cf_meta);
++ io.io_has_untyped <- io.io_has_untyped || (Meta.has Meta.HasUntyped cf.cf_meta);
+ begin match Inline.type_inline ctx cf tf (mk (TLocal io_var.iv_var) (TInst (c,tl)) e.epos) pl e.etype None e.epos true with
+ | Some e ->
+ let e = mark_ctors e in
+@@ -727,4 +727,4 @@ let inline_constructors ctx original_e =
+ end
+ ) !vars;
+ e
+- end
+\ No newline at end of file
++ end
+diff --git a/src/typing/matcher.ml b/src/typing/matcher.ml
+index 72f2a5e3a..6ca7e9a35 100644
+--- a/src/typing/matcher.ml
++++ b/src/typing/matcher.ml
+@@ -1461,7 +1461,7 @@ module TexprConverter = struct
+ in
+ let s = match unmatched with
+ | [] -> "_"
+- | _ -> String.concat " | " (List.sort Pervasives.compare sl)
++ | _ -> String.concat " | " (List.sort Stdlib.compare sl)
+ in
+ typing_error (Printf.sprintf "Unmatched patterns: %s" (s_subject v_lookup s e_subject)) e_subject.epos
+
+diff --git a/src/typing/typeloadCheck.ml b/src/typing/typeloadCheck.ml
+index 616be2ec1..6e649860f 100644
+--- a/src/typing/typeloadCheck.ml
++++ b/src/typing/typeloadCheck.ml
+@@ -318,7 +318,7 @@ let check_module_types ctx m p t =
+ let t = t_infos t in
+ try
+ let path2 = ctx.com.type_to_module#find t.mt_path in
+- if m.m_path <> path2 && String.lowercase (s_type_path path2) = String.lowercase (s_type_path m.m_path) then typing_error ("Module " ^ s_type_path path2 ^ " is loaded with a different case than " ^ s_type_path m.m_path) p;
++ if m.m_path <> path2 && String.lowercase_ascii (s_type_path path2) = String.lowercase_ascii (s_type_path m.m_path) then typing_error ("Module " ^ s_type_path path2 ^ " is loaded with a different case than " ^ s_type_path m.m_path) p;
+ let m2 = ctx.com.module_lut#find path2 in
+ let hex1 = Digest.to_hex m.m_extra.m_sign in
+ let hex2 = Digest.to_hex m2.m_extra.m_sign in
+diff --git a/src/typing/typeloadParse.ml b/src/typing/typeloadParse.ml
+index fcc192381..066443ada 100644
+--- a/src/typing/typeloadParse.ml
++++ b/src/typing/typeloadParse.ml
+@@ -102,7 +102,7 @@ let resolve_module_file com m remap p =
+ with Not_found ->
+ Common.find_file com (compose_path true)
+ in
+- let file = (match String.lowercase (snd m) with
++ let file = (match ExtString.String.lowercase (snd m) with
+ | "con" | "aux" | "prn" | "nul" | "com1" | "com2" | "com3" | "lpt1" | "lpt2" | "lpt3" when Sys.os_type = "Win32" ->
+ (* these names are reserved by the OS - old DOS legacy, such files cannot be easily created but are reported as visible *)
+ if (try (Unix.stat file).Unix.st_size with _ -> 0) > 0 then file else raise Not_found
+--
+2.42.0.windows.2
+
commit 6cb4c0807c2162b538525bf4d9b99bebd2b1ad05
Author: Andy Li <andy(a)onthewings.net>
Date: Fri Sep 15 15:40:01 2023 +0000
New upstream version 4.3.2. (RHBZ#2237112)
Use the properly built haxelib. (RHBZ#2129517)
Add haxe-ocaml5.patch from upstream for OCaml 5 compat. (RHBZ#2218692)
diff --git a/.gitignore b/.gitignore
index 17f5266..286ac5c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,4 @@
/haxe-4.3.0.tar.gz
/haxelib-f17fffa97554b1bdba37750e3418051f017a5bc2.tar.gz
/haxe-4.3.1.tar.gz
+/haxe-4.3.2.tar.gz
diff --git a/haxe.spec b/haxe.spec
index fd37d46..2495170 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -6,8 +6,8 @@ ExcludeArch: %{ix86}
%global commit_hx3compat f1f18201e5c0479cb5adf5f6028788b37f37b730
Name: haxe
-Version: 4.3.1
-Release: 3%{?dist}
+Version: 4.3.2
+Release: 1%{?dist}
Summary: Multi-target universal programming language
# As described in https://haxe.org/foundation/open-source.html:
@@ -27,6 +27,7 @@ URL: https://haxe.org/
Source0: https://github.com/HaxeFoundation/%{name}/archive/%{version}.tar.gz#/%{na...
Source1: https://github.com/HaxeFoundation/haxelib/archive/%{commit_haxelib}.tar.g...
Source2: https://github.com/HaxeFoundation/hx3compat/archive/%{commit_hx3compat}.t...
+Patch0: haxe-ocaml5.patch
BuildRequires: make
BuildRequires: nekovm-devel >= 2.3.0
@@ -34,6 +35,7 @@ BuildRequires: ocaml
BuildRequires: ocaml-findlib
BuildRequires: ocaml-dune
BuildRequires: ocaml-camlp5-devel
+BuildRequires: ocaml-camlp-streams
BuildRequires: ocaml-sedlex-devel >= 2.0
BuildRequires: ocaml-xml-light-devel
BuildRequires: ocaml-extlib-devel >= 1.7.8
@@ -65,6 +67,7 @@ by the Haxe compiler.
%prep
%setup -q
+%patch 0 -p1
pushd extra/haxelib_src && tar -xf %{SOURCE1} --strip-components=1 && popd
pushd extra/haxelib_src/hx3compat && tar -xf %{SOURCE2} --strip-components=1 && popd
@@ -72,9 +75,18 @@ pushd extra/haxelib_src/hx3compat && tar -xf %{SOURCE2} --strip-components=1 &&
# note that the Makefile does not support parallel building
make
-# Compile haxelib
-%cmake -S extra/haxelib_src -DHAXE_COMPILER="$(realpath haxe)" -DCMAKE_BINARY_DIR="$(pwd)"
+# Recompile haxelib.
+#
+# In the default Makefile, haxelib is built using `nekotools boot ...`.
+# It produces haxelib by concatenating the neko binary with haxelib neko bytecode.
+# https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.o...
+#
+# Instead, use the haxelib CMake, which use `nekotools boot -c ...`
+# to produce a C source code and build it with standard C toolchain.
+rm ./haxelib
+%cmake -S extra/haxelib_src -DHAXE_COMPILER="$(realpath haxe)"
%cmake_build
+mv %__cmake_builddir/haxelib .
chmod 755 haxe haxelib
@@ -114,6 +126,11 @@ popd
%{_datadir}/%{name}/
%changelog
+* Fri Sep 15 2023 Andy Li <andy(a)onthewings.net> - 4.3.2-1
+- New upstream version 4.3.2. (RHBZ#2237112)
+- Use the properly built haxelib. (RHBZ#2129517)
+- Add haxe-ocaml5.patch from upstream for OCaml 5 compat. (RHBZ#2218692)
+
* Thu Jul 20 2023 Fedora Release Engineering <releng(a)fedoraproject.org> - 4.3.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
diff --git a/sources b/sources
index efc0092..71dbfdf 100644
--- a/sources
+++ b/sources
@@ -1,3 +1,3 @@
-SHA512 (haxe-4.3.1.tar.gz) = 3c531ad9f7c496a718b1b6232cc570a2390c83ea152cf107fc8794a8581dc23f786f6c42cc7efe29b0e94733ad22f587cd58cfb794ca8657315d67699c67a761
+SHA512 (haxe-4.3.2.tar.gz) = 78d9cba573582dcfec7f1be413bb6061b90375432ede498f2d28fa8d8262d1eaa4760337ca40eb8439149aead9e00c5471d0badef58dd62bf59516be57fcbf65
SHA512 (haxelib-f17fffa97554b1bdba37750e3418051f017a5bc2.tar.gz) = adc80c20833062a6639f352861a950a4289a06ba97dcc57e327186cec8aa7988e17b5f4df518ced9a371ae4f0fd7d065bd79f400aa48045081066fa784c6b837
SHA512 (hx3compat-f1f18201e5c0479cb5adf5f6028788b37f37b730.tar.gz) = d3df767744c073715a5deb9e1b602006aded8335d7afe28686e9440c4d9fabe6eb29314beb7b929bb7a76de68a815a9a7c7a49d2a92183e9a5331923f70249ff
commit 8dd63ae27b48ed139e455f82afba69b2bd54322a
Author: Fedora Release Engineering <releng(a)fedoraproject.org>
Date: Thu Jul 20 06:10:01 2023 +0000
Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
Signed-off-by: Fedora Release Engineering <releng(a)fedoraproject.org>
diff --git a/haxe.spec b/haxe.spec
index a035448..fd37d46 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -7,7 +7,7 @@ ExcludeArch: %{ix86}
Name: haxe
Version: 4.3.1
-Release: 2%{?dist}
+Release: 3%{?dist}
Summary: Multi-target universal programming language
# As described in https://haxe.org/foundation/open-source.html:
@@ -114,6 +114,9 @@ popd
%{_datadir}/%{name}/
%changelog
+* Thu Jul 20 2023 Fedora Release Engineering <releng(a)fedoraproject.org> - 4.3.1-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
+
* Wed Jul 12 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.1-2
- OCaml 5.0 rebuild for Fedora 39
commit 996ac4c31721aefd3e33dc24c73004a49cc4a0be
Author: Richard W.M. Jones <rjones(a)redhat.com>
Date: Wed Jul 12 14:01:05 2023 +0100
OCaml 5.0 rebuild for Fedora 39
diff --git a/haxe.spec b/haxe.spec
index 6fb22dc..a035448 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -7,7 +7,7 @@ ExcludeArch: %{ix86}
Name: haxe
Version: 4.3.1
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Multi-target universal programming language
# As described in https://haxe.org/foundation/open-source.html:
@@ -114,6 +114,9 @@ popd
%{_datadir}/%{name}/
%changelog
+* Wed Jul 12 2023 Richard W.M. Jones <rjones(a)redhat.com> - 4.3.1-2
+- OCaml 5.0 rebuild for Fedora 39
+
* Sun Apr 30 2023 Andy Li <andy(a)onthewings.net> - 4.3.1-1
- New upstream version 4.3.1. (RHBZ#2185083, RHBZ#2128307)
- Update haxelib to 4.1.0.
commit 731990683e0287e77b001c219fdb893472f543c8
Author: Richard W.M. Jones <rjones(a)redhat.com>
Date: Tue Jul 11 11:36:26 2023 +0100
ExcludeArch i686 (https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.o...)
diff --git a/haxe.spec b/haxe.spec
index 64bc49c..6fb22dc 100644
--- a/haxe.spec
+++ b/haxe.spec
@@ -1,3 +1,6 @@
+# OCaml packages not built on i686 since OCaml 5 / Fedora 39.
+ExcludeArch: %{ix86}
+
%undefine _package_note_flags
%global commit_haxelib f17fffa97554b1bdba37750e3418051f017a5bc2
%global commit_hx3compat f1f18201e5c0479cb5adf5f6028788b37f37b730
1 month, 3 weeks
Architecture specific change in rpms/keydb.git
by githook-noreply@fedoraproject.org
The package rpms/keydb.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/keydb.git/commit/?id=1bb8f6ae0f97....
Change:
+%ifarch ppc64le aarch64
Thanks.
Full change:
============
commit 1bb8f6ae0f979285da05a6055a0e0bbb2bba4b3f
Author: Jonathan Wright <jonathan(a)almalinux.org>
Date: Sat Mar 23 12:48:56 2024 -0500
initial commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1114fde
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/keydb-6.3.4.tar.gz
diff --git a/README.md b/README.md
deleted file mode 100644
index ebee892..0000000
--- a/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# keydb
-
-The keydb package
diff --git a/keydb-limit-systemd b/keydb-limit-systemd
new file mode 100644
index 0000000..a792937
--- /dev/null
+++ b/keydb-limit-systemd
@@ -0,0 +1,14 @@
+# If you need to change max open file limit
+# for example, when you change maxclient in configuration
+# you can change the LimitNOFILE value below.
+# See "man systemd.exec" for more information.
+
+# Slave nodes on large system may take lot of time to start.
+# You may need to uncomment TimeoutStartSec and TimeoutStopSec
+# directives below and raise their value.
+# See "man systemd.service" for more information.
+
+[Service]
+LimitNOFILE=10240
+#TimeoutStartSec=90s
+#TimeoutStopSec=90s
diff --git a/keydb-sentinel.service b/keydb-sentinel.service
new file mode 100644
index 0000000..dc50506
--- /dev/null
+++ b/keydb-sentinel.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=KeyDB Sentinel
+After=network.target
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+EnvironmentFile=-/etc/sysconfig/keydb
+ExecStart=/usr/bin/keydb-sentinel /etc/keydb/sentinel.conf --daemonize no --supervised systemd $OPTIONS
+Type=notify
+User=keydb
+Group=keydb
+RuntimeDirectory=keydb
+RuntimeDirectoryMode=0755
+
+[Install]
+WantedBy=multi-user.target
diff --git a/keydb-sentinel.sysconfig b/keydb-sentinel.sysconfig
new file mode 100644
index 0000000..88b923b
--- /dev/null
+++ b/keydb-sentinel.sysconfig
@@ -0,0 +1 @@
+OPTIONS="--logfile /var/log/keydb/sentinel.log --unixsocket /var/run/keydb/sentinel.sock --pidfile /var/run/keydb/sentinel.pid"
diff --git a/keydb.logrotate b/keydb.logrotate
new file mode 100644
index 0000000..0ed7ae3
--- /dev/null
+++ b/keydb.logrotate
@@ -0,0 +1,9 @@
+/var/log/keydb/*.log {
+ weekly
+ rotate 10
+ copytruncate
+ delaycompress
+ compress
+ notifempty
+ missingok
+}
diff --git a/keydb.service b/keydb.service
new file mode 100644
index 0000000..bd77611
--- /dev/null
+++ b/keydb.service
@@ -0,0 +1,18 @@
+[Unit]
+Description=KeyDB persistent key-value database
+After=network.target
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+EnvironmentFile=-/etc/sysconfig/keydb
+ExecStart=/usr/bin/keydb-server /etc/keydb/keydb.conf --daemonize no --supervised systemd $OPTIONS
+Type=notify
+User=keydb
+Group=keydb
+RuntimeDirectory=keydb
+RuntimeDirectoryMode=0755
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/keydb.spec b/keydb.spec
new file mode 100644
index 0000000..53c7b38
--- /dev/null
+++ b/keydb.spec
@@ -0,0 +1,227 @@
+%bcond_with tests
+
+Name: keydb
+Version: 6.3.4
+Release: 1%{?dist}
+Summary: Multithreaded Fork of Redis
+
+ExcludeArch: %{ix86}
+
+License: BSD-3-Clause AND BSD-2-Clause AND MIT
+# hiredis: BSD-3-Clause
+# hdrhistogram, jemalloc, linenoise: BSD-2-Clause
+# lua: MIT
+URL: https://keydb.dev/
+Source0: https://github.com/snapchat/keydb/archive/v%{version}/%{name}-%{version}....
+Source1: %{name}.logrotate
+Source2: %{name}-sentinel.service
+Source3: %{name}.service
+Source4: %{name}.sysusers
+# could have pulled this out of unpacked sources but
+# our copy has additional options pre-programmed in
+Source5: %{name}-limit-systemd
+Source6: %{name}.sysconfig
+Source7: %{name}-sentinel.sysconfig
+
+BuildRequires: gcc-c++
+BuildRequires: libuuid-devel
+BuildRequires: openssl-devel
+BuildRequires: systemd-devel
+BuildRequires: libatomic
+BuildRequires: zlib-devel
+BuildRequires: lz4-devel
+BuildRequires: libzstd-devel
+BuildRequires: snappy-devel
+BuildRequires: bzip2-devel
+BuildRequires: systemd-rpm-macros
+# for tests
+%if %{with tests}
+BuildRequires: tcl
+BuildRequires: procps-ng
+%endif
+
+Requires: logrotate
+
+Patch: use_destdir_var.patch
+
+# from deps/hiredis/hiredis.h
+Provides: bundled(hiredis) = 1.0.0
+# from deps/jemalloc/VERSION
+Provides: bundled(jemalloc) = 5.2.1
+# from deps/lua/src/lua.h
+Provides: bundled(lua-libs) = 5.1.5
+# from deps/linenoise/linenoise.h
+Provides: bundled(linenoise) = 1.0
+# from deps/hdr_histogram/README.md
+Provides: bundled(hdr_histogram) = 0.11.0
+# from deps/memkind/src/src/memkind.c
+Provides: bundled(memkind) = 1.8.0
+# from deps/rocksdb/include/rocksdb/version.h
+Provides: bundled(rocksdb) = 7.9.2
+# no version listed
+Provides: bundled(concurrentqueue)
+
+%description
+KeyDB is a multi-threaded fork of Redis, an advanced key-value store.
+It is often referred to as a data structure server since keys can contain
+strings, hashes, lists, sets and sorted sets.
+
+You can run atomic operations on these types, like appending to a string;
+incrementing the value in a hash; pushing to a list; computing set
+intersection, union and difference; or getting the member with highest
+ranking in a sorted set.
+
+In order to achieve its outstanding performance, Redis works with an
+in-memory dataset. Depending on your use case, you can persist it either
+by dumping the dataset to disk every once in a while, or by appending
+each command to a log.
+
+KeyDB also supports trivial-to-setup master-slave replication, with very
+fast non-blocking first synchronization, auto-reconnection on net split
+and so forth.
+
+Other features include Transactions, Pub/Sub, Lua scripting, Keys with a
+limited time-to-live, and configuration settings to make Redis behave like
+a cache.
+
+You can use Redis from most programming languages also.
+
+
+%package devel
+Summary: Development header for Redis module development
+# Header-Only Library (https://fedoraproject.org/wiki/Packaging:Guidelines)
+Provides: %{name}-static = %{version}-%{release}
+Conflicts: redis-devel
+
+%description devel
+Header file required for building loadable KeyDB modules.
+
+
+%prep
+%autosetup -n KeyDB-%{version} -p1
+# these deps don't see to be used
+rm -rf deps/cpp-statsd-client
+
+mv deps/lua/COPYRIGHT COPYRIGHT-lua
+mv deps/jemalloc/COPYING COPYING-jemalloc
+mv deps/hiredis/COPYING COPYING-hiredis
+mv deps/hdr_histogram/LICENSE.txt LICENSE-hdrhistogram
+mv deps/hdr_histogram/COPYING.txt COPYING-hdrhistogram
+
+
+# See https://bugzilla.redhat.com/2240293
+# See https://src.fedoraproject.org/rpms/jemalloc/blob/rawhide/f/jemalloc.spec#_34
+%ifarch ppc64le aarch64
+sed -e 's/--with-lg-quantum/--with-lg-page=16 --with-lg-quantum/' -i deps/Makefile
+%endif
+
+
+%build
+# due to makefile weirdness these flags need to be on build and install
+%make_build USE_SYSTEMD=yes PREFIX=%{_prefix} NO_MOTD=yes
+
+
+%install
+# due to makefile weirdness these flags need to be on build and install
+%make_install USE_SYSTEMD=yes PREFIX=%{_prefix} NO_MOTD=yes
+
+install -p -D -m 0644 %{S:4} %{buildroot}%{_sysusersdir}/%{name}.conf
+
+install -d %{buildroot}%{_sharedstatedir}/%{name}
+install -d %{buildroot}%{_localstatedir}/log/%{name}
+install -d %{buildroot}%{_localstatedir}/run/%{name}
+
+# Install logrotate file.
+install -pDm644 %{S:1} %{buildroot}%{_sysconfdir}/logrotate.d/%{name}
+
+# Install configuration files.
+install -pDm640 %{name}.conf %{buildroot}%{_sysconfdir}/%{name}/%{name}.conf
+install -pDm640 sentinel.conf %{buildroot}%{_sysconfdir}/%{name}/sentinel.conf
+
+# Install systemd unit files.
+mkdir -p %{buildroot}%{_unitdir}
+install -pm644 %{S:3} %{buildroot}%{_unitdir}
+install -pm644 %{S:2} %{buildroot}%{_unitdir}
+
+# Install man pages
+built_man_dir="pkg/rpm/%{name}_build/%{name}_rpm%{_mandir}"
+for page in ${built_man_dir}/*/*; do
+ manx=$(basename $(dirname "$page"))
+ target_dir="%{buildroot}%{_mandir}/$manx"
+ mkdir -p "$target_dir"
+ install -Dpm 644 "$page" "$target_dir/"
+done
+
+# Install keydb module header
+install -Dpm 644 src/redismodule.h %{buildroot}%{_includedir}/redismodule.h
+
+# Install systemd limit files (requires systemd >= 204)
+install -Dpm 644 %{S:5} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/limit.conf
+install -Dpm 644 %{S:5} %{buildroot}%{_sysconfdir}/systemd/system/%{name}-sentinel.service.d/limit.conf
+
+# Install sysconfig files
+install -Dpm 644 %{S:6} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
+install -Dpm 644 %{S:7} %{buildroot}%{_sysconfdir}/sysconfig/%{name}-sentinel
+
+%pre
+%sysusers_create_compat %{S:4}
+
+
+%post
+%systemd_post %{name}.service
+%systemd_post %{name}-sentinel.service
+
+
+%preun
+%systemd_preun %{name}.service
+%systemd_preun %{name}-sentinel.service
+
+
+%postun
+%systemd_postun_with_restart %{name}.service
+%systemd_postun_with_restart %{name}-sentinel.service
+
+
+%check
+%if %{with tests}
+make test
+%endif
+
+
+%files
+%license COPYING
+%license COPYRIGHT-lua
+%license COPYING-jemalloc
+%license COPYING-hiredis
+%license LICENSE-hdrhistogram
+%license COPYING-hdrhistogram
+%doc README.md BUGS 00-RELEASENOTES
+%{_bindir}/%{name}-*
+%config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
+%attr(0750, keydb, root) %dir %{_sysconfdir}/%{name}
+%attr(0640, keydb, root) %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf
+%attr(0640, keydb, root) %config(noreplace) %{_sysconfdir}/%{name}/sentinel.conf
+%{_unitdir}/%{name}.service
+%{_unitdir}/%{name}-sentinel.service
+%dir %attr(0750, keydb, keydb) %{_sharedstatedir}/%{name}
+%dir %attr(0750, keydb, keydb) %{_localstatedir}/log/%{name}
+%{_sysusersdir}/%{name}.conf
+%{_mandir}/man1/%{name}*
+%{_mandir}/man5/%{name}*
+%dir %attr(0755, keydb, keydb) %ghost %{_localstatedir}/run/%{name}
+%dir %{_sysconfdir}/systemd/system/%{name}.service.d
+%config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/limit.conf
+%dir %{_sysconfdir}/systemd/system/%{name}-sentinel.service.d
+%config(noreplace) %{_sysconfdir}/systemd/system/%{name}-sentinel.service.d/limit.conf
+%{_sysconfdir}/sysconfig/%{name}
+%{_sysconfdir}/sysconfig/%{name}-sentinel
+
+
+%files devel
+%license COPYING
+%{_includedir}/redismodule.h
+
+
+%changelog
+* Wed Mar 20 2024 Jonathan Wright <jonathan(a)almalinux.org> - 6.3.4-1
+- Initial package build
diff --git a/keydb.sysconfig b/keydb.sysconfig
new file mode 100644
index 0000000..3d5b747
--- /dev/null
+++ b/keydb.sysconfig
@@ -0,0 +1 @@
+OPTIONS="--logfile /var/log/keydb/keydb.log --dir /var/lib/keydb --unixsocket /var/run/keydb/keydb.sock --enable-motd no --pidfile /var/run/keydb/keydb.pid"
diff --git a/keydb.sysusers b/keydb.sysusers
new file mode 100644
index 0000000..2477fc2
--- /dev/null
+++ b/keydb.sysusers
@@ -0,0 +1 @@
+u keydb - "KeyDB Database Server" /dev/null /sbin/nologin
diff --git a/sources b/sources
new file mode 100644
index 0000000..7db3f01
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+SHA512 (keydb-6.3.4.tar.gz) = 6ac5060dc60df878668830336821cac740690be5525bc8c4a31a522c629b73df2da49f6d53fe8ebfec171efef258c9253d91243fe57a470aaabeddea2ac5247b
diff --git a/use_destdir_var.patch b/use_destdir_var.patch
new file mode 100644
index 0000000..2e21134
--- /dev/null
+++ b/use_destdir_var.patch
@@ -0,0 +1,272 @@
+diff -uNr KeyDB-6.2.2.orig/src/Makefile KeyDB-6.2.2/src/Makefile
+--- KeyDB-6.2.2.orig/src/Makefile 2022-09-22 17:20:16.255466414 -0500
++++ KeyDB-6.2.2/src/Makefile 2022-09-22 17:25:02.043958294 -0500
+@@ -512,13 +512,13 @@
+ @../utils/generate-command-help.rb > help.h
+
+ install: all
+- @mkdir -p $(INSTALL_BIN)
+- $(call MAKE_INSTALL,$(REDIS_SERVER_NAME),$(INSTALL_BIN))
+- $(call MAKE_INSTALL,$(REDIS_BENCHMARK_NAME),$(INSTALL_BIN))
+- $(call MAKE_INSTALL,$(REDIS_CLI_NAME),$(INSTALL_BIN))
+- @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_CHECK_RDB_NAME)
+- @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_CHECK_AOF_NAME)
+- @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_SENTINEL_NAME)
++ @mkdir -p $(DESTDIR)$(INSTALL_BIN)
++ $(call MAKE_INSTALL,$(REDIS_SERVER_NAME),$(DESTDIR)$(INSTALL_BIN))
++ $(call MAKE_INSTALL,$(REDIS_BENCHMARK_NAME),$(DESTDIR)$(INSTALL_BIN))
++ $(call MAKE_INSTALL,$(REDIS_CLI_NAME),$(DESTDIR)$(INSTALL_BIN))
++ @ln -sf $(REDIS_SERVER_NAME) $(DESTDIR)$(INSTALL_BIN)/$(REDIS_CHECK_RDB_NAME)
++ @ln -sf $(REDIS_SERVER_NAME) $(DESTDIR)$(INSTALL_BIN)/$(REDIS_CHECK_AOF_NAME)
++ @ln -sf $(REDIS_SERVER_NAME) $(DESTDIR)$(INSTALL_BIN)/$(REDIS_SENTINEL_NAME)
+
+ uninstall:
+- rm -f $(INSTALL_BIN)/{$(REDIS_SERVER_NAME),$(REDIS_BENCHMARK_NAME),$(REDIS_CLI_NAME),$(REDIS_CHECK_RDB_NAME),$(REDIS_CHECK_AOF_NAME),$(REDIS_SENTINEL_NAME),$(KEYDB_DIAGNOSTIC_NAME)}
++ rm -f $(DESTDIR)$(INSTALL_BIN)/{$(REDIS_SERVER_NAME),$(REDIS_BENCHMARK_NAME),$(REDIS_CLI_NAME),$(REDIS_CHECK_RDB_NAME),$(REDIS_CHECK_AOF_NAME),$(REDIS_SENTINEL_NAME),$(KEYDB_DIAGNOSTIC_NAME)}
+diff -uNr KeyDB-6.2.2.orig/tests/test_helper.tcl KeyDB-6.2.2/tests/test_helper.tcl
+--- KeyDB-6.2.2.orig/tests/test_helper.tcl 2022-09-22 17:20:16.261466487 -0500
++++ KeyDB-6.2.2/tests/test_helper.tcl 2022-09-22 17:44:21.039374195 -0500
+@@ -68,7 +68,6 @@
+ unit/limits
+ unit/obuf-limits
+ unit/bitops
+- unit/bitfield
+ unit/geo
+ unit/memefficiency
+ unit/hyperloglog
+diff -uNr KeyDB-6.2.2.orig/tests/unit/bitfield.tcl KeyDB-6.2.2/tests/unit/bitfield.tcl
+--- KeyDB-6.2.2.orig/tests/unit/bitfield.tcl 2022-09-22 17:20:16.263466511 -0500
++++ KeyDB-6.2.2/tests/unit/bitfield.tcl 1969-12-31 18:00:00.000000000 -0600
+@@ -1,232 +0,0 @@
+-start_server {tags {"bitops"}} {
+- test {BITFIELD signed SET and GET basics} {
+- r del bits
+- set results {}
+- lappend results [r bitfield bits set i8 0 -100]
+- lappend results [r bitfield bits set i8 0 101]
+- lappend results [r bitfield bits get i8 0]
+- set results
+- } {0 -100 101}
+-
+- test {BITFIELD unsigned SET and GET basics} {
+- r del bits
+- set results {}
+- lappend results [r bitfield bits set u8 0 255]
+- lappend results [r bitfield bits set u8 0 100]
+- lappend results [r bitfield bits get u8 0]
+- set results
+- } {0 255 100}
+-
+- test {BITFIELD #<idx> form} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 65
+- r bitfield bits set u8 #1 66
+- r bitfield bits set u8 #2 67
+- r get bits
+- } {ABC}
+-
+- test {BITFIELD basic INCRBY form} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 10
+- lappend results [r bitfield bits incrby u8 #0 100]
+- lappend results [r bitfield bits incrby u8 #0 100]
+- set results
+- } {110 210}
+-
+- test {BITFIELD chaining of multiple commands} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 10
+- lappend results [r bitfield bits incrby u8 #0 100 incrby u8 #0 100]
+- set results
+- } {{110 210}}
+-
+- test {BITFIELD unsigned overflow wrap} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 100
+- lappend results [r bitfield bits overflow wrap incrby u8 #0 257]
+- lappend results [r bitfield bits get u8 #0]
+- lappend results [r bitfield bits overflow wrap incrby u8 #0 255]
+- lappend results [r bitfield bits get u8 #0]
+- } {101 101 100 100}
+-
+- test {BITFIELD unsigned overflow sat} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 100
+- lappend results [r bitfield bits overflow sat incrby u8 #0 257]
+- lappend results [r bitfield bits get u8 #0]
+- lappend results [r bitfield bits overflow sat incrby u8 #0 -255]
+- lappend results [r bitfield bits get u8 #0]
+- } {255 255 0 0}
+-
+- test {BITFIELD signed overflow wrap} {
+- r del bits
+- set results {}
+- r bitfield bits set i8 #0 100
+- lappend results [r bitfield bits overflow wrap incrby i8 #0 257]
+- lappend results [r bitfield bits get i8 #0]
+- lappend results [r bitfield bits overflow wrap incrby i8 #0 255]
+- lappend results [r bitfield bits get i8 #0]
+- } {101 101 100 100}
+-
+- test {BITFIELD signed overflow sat} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 100
+- lappend results [r bitfield bits overflow sat incrby i8 #0 257]
+- lappend results [r bitfield bits get i8 #0]
+- lappend results [r bitfield bits overflow sat incrby i8 #0 -255]
+- lappend results [r bitfield bits get i8 #0]
+- } {127 127 -128 -128}
+-
+- test {BITFIELD overflow detection fuzzing} {
+- for {set j 0} {$j < 1000} {incr j} {
+- set bits [expr {[randomInt 64]+1}]
+- set sign [randomInt 2]
+- set range [expr {2**$bits}]
+- if {$bits == 64} {set sign 1} ; # u64 is not supported by BITFIELD.
+- if {$sign} {
+- set min [expr {-($range/2)}]
+- set type "i$bits"
+- } else {
+- set min 0
+- set type "u$bits"
+- }
+- set max [expr {$min+$range-1}]
+-
+- # Compare Tcl vs Redis
+- set range2 [expr {$range*2}]
+- set value [expr {($min*2)+[randomInt $range2]}]
+- set increment [expr {($min*2)+[randomInt $range2]}]
+- if {$value > 9223372036854775807} {
+- set value 9223372036854775807
+- }
+- if {$value < -9223372036854775808} {
+- set value -9223372036854775808
+- }
+- if {$increment > 9223372036854775807} {
+- set increment 9223372036854775807
+- }
+- if {$increment < -9223372036854775808} {
+- set increment -9223372036854775808
+- }
+-
+- set overflow 0
+- if {$value > $max || $value < $min} {set overflow 1}
+- if {($value + $increment) > $max} {set overflow 1}
+- if {($value + $increment) < $min} {set overflow 1}
+-
+- r del bits
+- set res1 [r bitfield bits overflow fail set $type 0 $value]
+- set res2 [r bitfield bits overflow fail incrby $type 0 $increment]
+-
+- if {$overflow && [lindex $res1 0] ne {} &&
+- [lindex $res2 0] ne {}} {
+- fail "OW not detected where needed: $type $value+$increment"
+- }
+- if {!$overflow && ([lindex $res1 0] eq {} ||
+- [lindex $res2 0] eq {})} {
+- fail "OW detected where NOT needed: $type $value+$increment"
+- }
+- }
+- }
+-
+- test {BITFIELD overflow wrap fuzzing} {
+- for {set j 0} {$j < 1000} {incr j} {
+- set bits [expr {[randomInt 64]+1}]
+- set sign [randomInt 2]
+- set range [expr {2**$bits}]
+- if {$bits == 64} {set sign 1} ; # u64 is not supported by BITFIELD.
+- if {$sign} {
+- set min [expr {-($range/2)}]
+- set type "i$bits"
+- } else {
+- set min 0
+- set type "u$bits"
+- }
+- set max [expr {$min+$range-1}]
+-
+- # Compare Tcl vs Redis
+- set range2 [expr {$range*2}]
+- set value [expr {($min*2)+[randomInt $range2]}]
+- set increment [expr {($min*2)+[randomInt $range2]}]
+- if {$value > 9223372036854775807} {
+- set value 9223372036854775807
+- }
+- if {$value < -9223372036854775808} {
+- set value -9223372036854775808
+- }
+- if {$increment > 9223372036854775807} {
+- set increment 9223372036854775807
+- }
+- if {$increment < -9223372036854775808} {
+- set increment -9223372036854775808
+- }
+-
+- r del bits
+- r bitfield bits overflow wrap set $type 0 $value
+- r bitfield bits overflow wrap incrby $type 0 $increment
+- set res [lindex [r bitfield bits get $type 0] 0]
+-
+- set expected 0
+- if {$sign} {incr expected [expr {$max+1}]}
+- incr expected $value
+- incr expected $increment
+- set expected [expr {$expected % $range}]
+- if {$sign} {incr expected $min}
+-
+- if {$res != $expected} {
+- fail "WRAP error: $type $value+$increment = $res, should be $expected"
+- }
+- }
+- }
+-
+- test {BITFIELD regression for #3221} {
+- r set bits 1
+- r bitfield bits get u1 0
+- } {0}
+-
+- test {BITFIELD regression for #3564} {
+- for {set j 0} {$j < 10} {incr j} {
+- r del mystring
+- set res [r BITFIELD mystring SET i8 0 10 SET i8 64 10 INCRBY i8 10 99900]
+- assert {$res eq {0 0 60}}
+- }
+- r del mystring
+- }
+-}
+-
+-start_server {tags {"repl"}} {
+- start_server {} {
+- set master [srv -1 client]
+- set master_host [srv -1 host]
+- set master_port [srv -1 port]
+- set slave [srv 0 client]
+-
+- test {BITFIELD: setup slave} {
+- $slave slaveof $master_host $master_port
+- wait_for_condition 50 100 {
+- [s 0 master_link_status] eq {up}
+- } else {
+- fail "Replication not started."
+- }
+- }
+-
+- test {BITFIELD: write on master, read on slave} {
+- $master del bits
+- assert_equal 0 [$master bitfield bits set u8 0 255]
+- assert_equal 255 [$master bitfield bits set u8 0 100]
+- wait_for_ofs_sync $master $slave
+- assert_equal 100 [$slave bitfield_ro bits get u8 0]
+- }
+-
+- test {BITFIELD_RO fails when write option is used} {
+- catch {$slave bitfield_ro bits set u8 0 100 get u8 0} err
+- assert_match {*ERR BITFIELD_RO only supports the GET subcommand*} $err
+- }
+- }
+-}
1 month, 3 weeks
Architecture specific change in rpms/keydb.git
by githook-noreply@fedoraproject.org
The package rpms/keydb.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/keydb.git/commit/?id=1bb8f6ae0f97....
Change:
+%ifarch ppc64le aarch64
Thanks.
Full change:
============
commit 1bb8f6ae0f979285da05a6055a0e0bbb2bba4b3f
Author: Jonathan Wright <jonathan(a)almalinux.org>
Date: Sat Mar 23 12:48:56 2024 -0500
initial commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1114fde
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/keydb-6.3.4.tar.gz
diff --git a/README.md b/README.md
deleted file mode 100644
index ebee892..0000000
--- a/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# keydb
-
-The keydb package
diff --git a/keydb-limit-systemd b/keydb-limit-systemd
new file mode 100644
index 0000000..a792937
--- /dev/null
+++ b/keydb-limit-systemd
@@ -0,0 +1,14 @@
+# If you need to change max open file limit
+# for example, when you change maxclient in configuration
+# you can change the LimitNOFILE value below.
+# See "man systemd.exec" for more information.
+
+# Slave nodes on large system may take lot of time to start.
+# You may need to uncomment TimeoutStartSec and TimeoutStopSec
+# directives below and raise their value.
+# See "man systemd.service" for more information.
+
+[Service]
+LimitNOFILE=10240
+#TimeoutStartSec=90s
+#TimeoutStopSec=90s
diff --git a/keydb-sentinel.service b/keydb-sentinel.service
new file mode 100644
index 0000000..dc50506
--- /dev/null
+++ b/keydb-sentinel.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=KeyDB Sentinel
+After=network.target
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+EnvironmentFile=-/etc/sysconfig/keydb
+ExecStart=/usr/bin/keydb-sentinel /etc/keydb/sentinel.conf --daemonize no --supervised systemd $OPTIONS
+Type=notify
+User=keydb
+Group=keydb
+RuntimeDirectory=keydb
+RuntimeDirectoryMode=0755
+
+[Install]
+WantedBy=multi-user.target
diff --git a/keydb-sentinel.sysconfig b/keydb-sentinel.sysconfig
new file mode 100644
index 0000000..88b923b
--- /dev/null
+++ b/keydb-sentinel.sysconfig
@@ -0,0 +1 @@
+OPTIONS="--logfile /var/log/keydb/sentinel.log --unixsocket /var/run/keydb/sentinel.sock --pidfile /var/run/keydb/sentinel.pid"
diff --git a/keydb.logrotate b/keydb.logrotate
new file mode 100644
index 0000000..0ed7ae3
--- /dev/null
+++ b/keydb.logrotate
@@ -0,0 +1,9 @@
+/var/log/keydb/*.log {
+ weekly
+ rotate 10
+ copytruncate
+ delaycompress
+ compress
+ notifempty
+ missingok
+}
diff --git a/keydb.service b/keydb.service
new file mode 100644
index 0000000..bd77611
--- /dev/null
+++ b/keydb.service
@@ -0,0 +1,18 @@
+[Unit]
+Description=KeyDB persistent key-value database
+After=network.target
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+EnvironmentFile=-/etc/sysconfig/keydb
+ExecStart=/usr/bin/keydb-server /etc/keydb/keydb.conf --daemonize no --supervised systemd $OPTIONS
+Type=notify
+User=keydb
+Group=keydb
+RuntimeDirectory=keydb
+RuntimeDirectoryMode=0755
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/keydb.spec b/keydb.spec
new file mode 100644
index 0000000..53c7b38
--- /dev/null
+++ b/keydb.spec
@@ -0,0 +1,227 @@
+%bcond_with tests
+
+Name: keydb
+Version: 6.3.4
+Release: 1%{?dist}
+Summary: Multithreaded Fork of Redis
+
+ExcludeArch: %{ix86}
+
+License: BSD-3-Clause AND BSD-2-Clause AND MIT
+# hiredis: BSD-3-Clause
+# hdrhistogram, jemalloc, linenoise: BSD-2-Clause
+# lua: MIT
+URL: https://keydb.dev/
+Source0: https://github.com/snapchat/keydb/archive/v%{version}/%{name}-%{version}....
+Source1: %{name}.logrotate
+Source2: %{name}-sentinel.service
+Source3: %{name}.service
+Source4: %{name}.sysusers
+# could have pulled this out of unpacked sources but
+# our copy has additional options pre-programmed in
+Source5: %{name}-limit-systemd
+Source6: %{name}.sysconfig
+Source7: %{name}-sentinel.sysconfig
+
+BuildRequires: gcc-c++
+BuildRequires: libuuid-devel
+BuildRequires: openssl-devel
+BuildRequires: systemd-devel
+BuildRequires: libatomic
+BuildRequires: zlib-devel
+BuildRequires: lz4-devel
+BuildRequires: libzstd-devel
+BuildRequires: snappy-devel
+BuildRequires: bzip2-devel
+BuildRequires: systemd-rpm-macros
+# for tests
+%if %{with tests}
+BuildRequires: tcl
+BuildRequires: procps-ng
+%endif
+
+Requires: logrotate
+
+Patch: use_destdir_var.patch
+
+# from deps/hiredis/hiredis.h
+Provides: bundled(hiredis) = 1.0.0
+# from deps/jemalloc/VERSION
+Provides: bundled(jemalloc) = 5.2.1
+# from deps/lua/src/lua.h
+Provides: bundled(lua-libs) = 5.1.5
+# from deps/linenoise/linenoise.h
+Provides: bundled(linenoise) = 1.0
+# from deps/hdr_histogram/README.md
+Provides: bundled(hdr_histogram) = 0.11.0
+# from deps/memkind/src/src/memkind.c
+Provides: bundled(memkind) = 1.8.0
+# from deps/rocksdb/include/rocksdb/version.h
+Provides: bundled(rocksdb) = 7.9.2
+# no version listed
+Provides: bundled(concurrentqueue)
+
+%description
+KeyDB is a multi-threaded fork of Redis, an advanced key-value store.
+It is often referred to as a data structure server since keys can contain
+strings, hashes, lists, sets and sorted sets.
+
+You can run atomic operations on these types, like appending to a string;
+incrementing the value in a hash; pushing to a list; computing set
+intersection, union and difference; or getting the member with highest
+ranking in a sorted set.
+
+In order to achieve its outstanding performance, Redis works with an
+in-memory dataset. Depending on your use case, you can persist it either
+by dumping the dataset to disk every once in a while, or by appending
+each command to a log.
+
+KeyDB also supports trivial-to-setup master-slave replication, with very
+fast non-blocking first synchronization, auto-reconnection on net split
+and so forth.
+
+Other features include Transactions, Pub/Sub, Lua scripting, Keys with a
+limited time-to-live, and configuration settings to make Redis behave like
+a cache.
+
+You can use Redis from most programming languages also.
+
+
+%package devel
+Summary: Development header for Redis module development
+# Header-Only Library (https://fedoraproject.org/wiki/Packaging:Guidelines)
+Provides: %{name}-static = %{version}-%{release}
+Conflicts: redis-devel
+
+%description devel
+Header file required for building loadable KeyDB modules.
+
+
+%prep
+%autosetup -n KeyDB-%{version} -p1
+# these deps don't see to be used
+rm -rf deps/cpp-statsd-client
+
+mv deps/lua/COPYRIGHT COPYRIGHT-lua
+mv deps/jemalloc/COPYING COPYING-jemalloc
+mv deps/hiredis/COPYING COPYING-hiredis
+mv deps/hdr_histogram/LICENSE.txt LICENSE-hdrhistogram
+mv deps/hdr_histogram/COPYING.txt COPYING-hdrhistogram
+
+
+# See https://bugzilla.redhat.com/2240293
+# See https://src.fedoraproject.org/rpms/jemalloc/blob/rawhide/f/jemalloc.spec#_34
+%ifarch ppc64le aarch64
+sed -e 's/--with-lg-quantum/--with-lg-page=16 --with-lg-quantum/' -i deps/Makefile
+%endif
+
+
+%build
+# due to makefile weirdness these flags need to be on build and install
+%make_build USE_SYSTEMD=yes PREFIX=%{_prefix} NO_MOTD=yes
+
+
+%install
+# due to makefile weirdness these flags need to be on build and install
+%make_install USE_SYSTEMD=yes PREFIX=%{_prefix} NO_MOTD=yes
+
+install -p -D -m 0644 %{S:4} %{buildroot}%{_sysusersdir}/%{name}.conf
+
+install -d %{buildroot}%{_sharedstatedir}/%{name}
+install -d %{buildroot}%{_localstatedir}/log/%{name}
+install -d %{buildroot}%{_localstatedir}/run/%{name}
+
+# Install logrotate file.
+install -pDm644 %{S:1} %{buildroot}%{_sysconfdir}/logrotate.d/%{name}
+
+# Install configuration files.
+install -pDm640 %{name}.conf %{buildroot}%{_sysconfdir}/%{name}/%{name}.conf
+install -pDm640 sentinel.conf %{buildroot}%{_sysconfdir}/%{name}/sentinel.conf
+
+# Install systemd unit files.
+mkdir -p %{buildroot}%{_unitdir}
+install -pm644 %{S:3} %{buildroot}%{_unitdir}
+install -pm644 %{S:2} %{buildroot}%{_unitdir}
+
+# Install man pages
+built_man_dir="pkg/rpm/%{name}_build/%{name}_rpm%{_mandir}"
+for page in ${built_man_dir}/*/*; do
+ manx=$(basename $(dirname "$page"))
+ target_dir="%{buildroot}%{_mandir}/$manx"
+ mkdir -p "$target_dir"
+ install -Dpm 644 "$page" "$target_dir/"
+done
+
+# Install keydb module header
+install -Dpm 644 src/redismodule.h %{buildroot}%{_includedir}/redismodule.h
+
+# Install systemd limit files (requires systemd >= 204)
+install -Dpm 644 %{S:5} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/limit.conf
+install -Dpm 644 %{S:5} %{buildroot}%{_sysconfdir}/systemd/system/%{name}-sentinel.service.d/limit.conf
+
+# Install sysconfig files
+install -Dpm 644 %{S:6} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
+install -Dpm 644 %{S:7} %{buildroot}%{_sysconfdir}/sysconfig/%{name}-sentinel
+
+%pre
+%sysusers_create_compat %{S:4}
+
+
+%post
+%systemd_post %{name}.service
+%systemd_post %{name}-sentinel.service
+
+
+%preun
+%systemd_preun %{name}.service
+%systemd_preun %{name}-sentinel.service
+
+
+%postun
+%systemd_postun_with_restart %{name}.service
+%systemd_postun_with_restart %{name}-sentinel.service
+
+
+%check
+%if %{with tests}
+make test
+%endif
+
+
+%files
+%license COPYING
+%license COPYRIGHT-lua
+%license COPYING-jemalloc
+%license COPYING-hiredis
+%license LICENSE-hdrhistogram
+%license COPYING-hdrhistogram
+%doc README.md BUGS 00-RELEASENOTES
+%{_bindir}/%{name}-*
+%config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
+%attr(0750, keydb, root) %dir %{_sysconfdir}/%{name}
+%attr(0640, keydb, root) %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf
+%attr(0640, keydb, root) %config(noreplace) %{_sysconfdir}/%{name}/sentinel.conf
+%{_unitdir}/%{name}.service
+%{_unitdir}/%{name}-sentinel.service
+%dir %attr(0750, keydb, keydb) %{_sharedstatedir}/%{name}
+%dir %attr(0750, keydb, keydb) %{_localstatedir}/log/%{name}
+%{_sysusersdir}/%{name}.conf
+%{_mandir}/man1/%{name}*
+%{_mandir}/man5/%{name}*
+%dir %attr(0755, keydb, keydb) %ghost %{_localstatedir}/run/%{name}
+%dir %{_sysconfdir}/systemd/system/%{name}.service.d
+%config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/limit.conf
+%dir %{_sysconfdir}/systemd/system/%{name}-sentinel.service.d
+%config(noreplace) %{_sysconfdir}/systemd/system/%{name}-sentinel.service.d/limit.conf
+%{_sysconfdir}/sysconfig/%{name}
+%{_sysconfdir}/sysconfig/%{name}-sentinel
+
+
+%files devel
+%license COPYING
+%{_includedir}/redismodule.h
+
+
+%changelog
+* Wed Mar 20 2024 Jonathan Wright <jonathan(a)almalinux.org> - 6.3.4-1
+- Initial package build
diff --git a/keydb.sysconfig b/keydb.sysconfig
new file mode 100644
index 0000000..3d5b747
--- /dev/null
+++ b/keydb.sysconfig
@@ -0,0 +1 @@
+OPTIONS="--logfile /var/log/keydb/keydb.log --dir /var/lib/keydb --unixsocket /var/run/keydb/keydb.sock --enable-motd no --pidfile /var/run/keydb/keydb.pid"
diff --git a/keydb.sysusers b/keydb.sysusers
new file mode 100644
index 0000000..2477fc2
--- /dev/null
+++ b/keydb.sysusers
@@ -0,0 +1 @@
+u keydb - "KeyDB Database Server" /dev/null /sbin/nologin
diff --git a/sources b/sources
new file mode 100644
index 0000000..7db3f01
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+SHA512 (keydb-6.3.4.tar.gz) = 6ac5060dc60df878668830336821cac740690be5525bc8c4a31a522c629b73df2da49f6d53fe8ebfec171efef258c9253d91243fe57a470aaabeddea2ac5247b
diff --git a/use_destdir_var.patch b/use_destdir_var.patch
new file mode 100644
index 0000000..2e21134
--- /dev/null
+++ b/use_destdir_var.patch
@@ -0,0 +1,272 @@
+diff -uNr KeyDB-6.2.2.orig/src/Makefile KeyDB-6.2.2/src/Makefile
+--- KeyDB-6.2.2.orig/src/Makefile 2022-09-22 17:20:16.255466414 -0500
++++ KeyDB-6.2.2/src/Makefile 2022-09-22 17:25:02.043958294 -0500
+@@ -512,13 +512,13 @@
+ @../utils/generate-command-help.rb > help.h
+
+ install: all
+- @mkdir -p $(INSTALL_BIN)
+- $(call MAKE_INSTALL,$(REDIS_SERVER_NAME),$(INSTALL_BIN))
+- $(call MAKE_INSTALL,$(REDIS_BENCHMARK_NAME),$(INSTALL_BIN))
+- $(call MAKE_INSTALL,$(REDIS_CLI_NAME),$(INSTALL_BIN))
+- @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_CHECK_RDB_NAME)
+- @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_CHECK_AOF_NAME)
+- @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_SENTINEL_NAME)
++ @mkdir -p $(DESTDIR)$(INSTALL_BIN)
++ $(call MAKE_INSTALL,$(REDIS_SERVER_NAME),$(DESTDIR)$(INSTALL_BIN))
++ $(call MAKE_INSTALL,$(REDIS_BENCHMARK_NAME),$(DESTDIR)$(INSTALL_BIN))
++ $(call MAKE_INSTALL,$(REDIS_CLI_NAME),$(DESTDIR)$(INSTALL_BIN))
++ @ln -sf $(REDIS_SERVER_NAME) $(DESTDIR)$(INSTALL_BIN)/$(REDIS_CHECK_RDB_NAME)
++ @ln -sf $(REDIS_SERVER_NAME) $(DESTDIR)$(INSTALL_BIN)/$(REDIS_CHECK_AOF_NAME)
++ @ln -sf $(REDIS_SERVER_NAME) $(DESTDIR)$(INSTALL_BIN)/$(REDIS_SENTINEL_NAME)
+
+ uninstall:
+- rm -f $(INSTALL_BIN)/{$(REDIS_SERVER_NAME),$(REDIS_BENCHMARK_NAME),$(REDIS_CLI_NAME),$(REDIS_CHECK_RDB_NAME),$(REDIS_CHECK_AOF_NAME),$(REDIS_SENTINEL_NAME),$(KEYDB_DIAGNOSTIC_NAME)}
++ rm -f $(DESTDIR)$(INSTALL_BIN)/{$(REDIS_SERVER_NAME),$(REDIS_BENCHMARK_NAME),$(REDIS_CLI_NAME),$(REDIS_CHECK_RDB_NAME),$(REDIS_CHECK_AOF_NAME),$(REDIS_SENTINEL_NAME),$(KEYDB_DIAGNOSTIC_NAME)}
+diff -uNr KeyDB-6.2.2.orig/tests/test_helper.tcl KeyDB-6.2.2/tests/test_helper.tcl
+--- KeyDB-6.2.2.orig/tests/test_helper.tcl 2022-09-22 17:20:16.261466487 -0500
++++ KeyDB-6.2.2/tests/test_helper.tcl 2022-09-22 17:44:21.039374195 -0500
+@@ -68,7 +68,6 @@
+ unit/limits
+ unit/obuf-limits
+ unit/bitops
+- unit/bitfield
+ unit/geo
+ unit/memefficiency
+ unit/hyperloglog
+diff -uNr KeyDB-6.2.2.orig/tests/unit/bitfield.tcl KeyDB-6.2.2/tests/unit/bitfield.tcl
+--- KeyDB-6.2.2.orig/tests/unit/bitfield.tcl 2022-09-22 17:20:16.263466511 -0500
++++ KeyDB-6.2.2/tests/unit/bitfield.tcl 1969-12-31 18:00:00.000000000 -0600
+@@ -1,232 +0,0 @@
+-start_server {tags {"bitops"}} {
+- test {BITFIELD signed SET and GET basics} {
+- r del bits
+- set results {}
+- lappend results [r bitfield bits set i8 0 -100]
+- lappend results [r bitfield bits set i8 0 101]
+- lappend results [r bitfield bits get i8 0]
+- set results
+- } {0 -100 101}
+-
+- test {BITFIELD unsigned SET and GET basics} {
+- r del bits
+- set results {}
+- lappend results [r bitfield bits set u8 0 255]
+- lappend results [r bitfield bits set u8 0 100]
+- lappend results [r bitfield bits get u8 0]
+- set results
+- } {0 255 100}
+-
+- test {BITFIELD #<idx> form} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 65
+- r bitfield bits set u8 #1 66
+- r bitfield bits set u8 #2 67
+- r get bits
+- } {ABC}
+-
+- test {BITFIELD basic INCRBY form} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 10
+- lappend results [r bitfield bits incrby u8 #0 100]
+- lappend results [r bitfield bits incrby u8 #0 100]
+- set results
+- } {110 210}
+-
+- test {BITFIELD chaining of multiple commands} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 10
+- lappend results [r bitfield bits incrby u8 #0 100 incrby u8 #0 100]
+- set results
+- } {{110 210}}
+-
+- test {BITFIELD unsigned overflow wrap} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 100
+- lappend results [r bitfield bits overflow wrap incrby u8 #0 257]
+- lappend results [r bitfield bits get u8 #0]
+- lappend results [r bitfield bits overflow wrap incrby u8 #0 255]
+- lappend results [r bitfield bits get u8 #0]
+- } {101 101 100 100}
+-
+- test {BITFIELD unsigned overflow sat} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 100
+- lappend results [r bitfield bits overflow sat incrby u8 #0 257]
+- lappend results [r bitfield bits get u8 #0]
+- lappend results [r bitfield bits overflow sat incrby u8 #0 -255]
+- lappend results [r bitfield bits get u8 #0]
+- } {255 255 0 0}
+-
+- test {BITFIELD signed overflow wrap} {
+- r del bits
+- set results {}
+- r bitfield bits set i8 #0 100
+- lappend results [r bitfield bits overflow wrap incrby i8 #0 257]
+- lappend results [r bitfield bits get i8 #0]
+- lappend results [r bitfield bits overflow wrap incrby i8 #0 255]
+- lappend results [r bitfield bits get i8 #0]
+- } {101 101 100 100}
+-
+- test {BITFIELD signed overflow sat} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 100
+- lappend results [r bitfield bits overflow sat incrby i8 #0 257]
+- lappend results [r bitfield bits get i8 #0]
+- lappend results [r bitfield bits overflow sat incrby i8 #0 -255]
+- lappend results [r bitfield bits get i8 #0]
+- } {127 127 -128 -128}
+-
+- test {BITFIELD overflow detection fuzzing} {
+- for {set j 0} {$j < 1000} {incr j} {
+- set bits [expr {[randomInt 64]+1}]
+- set sign [randomInt 2]
+- set range [expr {2**$bits}]
+- if {$bits == 64} {set sign 1} ; # u64 is not supported by BITFIELD.
+- if {$sign} {
+- set min [expr {-($range/2)}]
+- set type "i$bits"
+- } else {
+- set min 0
+- set type "u$bits"
+- }
+- set max [expr {$min+$range-1}]
+-
+- # Compare Tcl vs Redis
+- set range2 [expr {$range*2}]
+- set value [expr {($min*2)+[randomInt $range2]}]
+- set increment [expr {($min*2)+[randomInt $range2]}]
+- if {$value > 9223372036854775807} {
+- set value 9223372036854775807
+- }
+- if {$value < -9223372036854775808} {
+- set value -9223372036854775808
+- }
+- if {$increment > 9223372036854775807} {
+- set increment 9223372036854775807
+- }
+- if {$increment < -9223372036854775808} {
+- set increment -9223372036854775808
+- }
+-
+- set overflow 0
+- if {$value > $max || $value < $min} {set overflow 1}
+- if {($value + $increment) > $max} {set overflow 1}
+- if {($value + $increment) < $min} {set overflow 1}
+-
+- r del bits
+- set res1 [r bitfield bits overflow fail set $type 0 $value]
+- set res2 [r bitfield bits overflow fail incrby $type 0 $increment]
+-
+- if {$overflow && [lindex $res1 0] ne {} &&
+- [lindex $res2 0] ne {}} {
+- fail "OW not detected where needed: $type $value+$increment"
+- }
+- if {!$overflow && ([lindex $res1 0] eq {} ||
+- [lindex $res2 0] eq {})} {
+- fail "OW detected where NOT needed: $type $value+$increment"
+- }
+- }
+- }
+-
+- test {BITFIELD overflow wrap fuzzing} {
+- for {set j 0} {$j < 1000} {incr j} {
+- set bits [expr {[randomInt 64]+1}]
+- set sign [randomInt 2]
+- set range [expr {2**$bits}]
+- if {$bits == 64} {set sign 1} ; # u64 is not supported by BITFIELD.
+- if {$sign} {
+- set min [expr {-($range/2)}]
+- set type "i$bits"
+- } else {
+- set min 0
+- set type "u$bits"
+- }
+- set max [expr {$min+$range-1}]
+-
+- # Compare Tcl vs Redis
+- set range2 [expr {$range*2}]
+- set value [expr {($min*2)+[randomInt $range2]}]
+- set increment [expr {($min*2)+[randomInt $range2]}]
+- if {$value > 9223372036854775807} {
+- set value 9223372036854775807
+- }
+- if {$value < -9223372036854775808} {
+- set value -9223372036854775808
+- }
+- if {$increment > 9223372036854775807} {
+- set increment 9223372036854775807
+- }
+- if {$increment < -9223372036854775808} {
+- set increment -9223372036854775808
+- }
+-
+- r del bits
+- r bitfield bits overflow wrap set $type 0 $value
+- r bitfield bits overflow wrap incrby $type 0 $increment
+- set res [lindex [r bitfield bits get $type 0] 0]
+-
+- set expected 0
+- if {$sign} {incr expected [expr {$max+1}]}
+- incr expected $value
+- incr expected $increment
+- set expected [expr {$expected % $range}]
+- if {$sign} {incr expected $min}
+-
+- if {$res != $expected} {
+- fail "WRAP error: $type $value+$increment = $res, should be $expected"
+- }
+- }
+- }
+-
+- test {BITFIELD regression for #3221} {
+- r set bits 1
+- r bitfield bits get u1 0
+- } {0}
+-
+- test {BITFIELD regression for #3564} {
+- for {set j 0} {$j < 10} {incr j} {
+- r del mystring
+- set res [r BITFIELD mystring SET i8 0 10 SET i8 64 10 INCRBY i8 10 99900]
+- assert {$res eq {0 0 60}}
+- }
+- r del mystring
+- }
+-}
+-
+-start_server {tags {"repl"}} {
+- start_server {} {
+- set master [srv -1 client]
+- set master_host [srv -1 host]
+- set master_port [srv -1 port]
+- set slave [srv 0 client]
+-
+- test {BITFIELD: setup slave} {
+- $slave slaveof $master_host $master_port
+- wait_for_condition 50 100 {
+- [s 0 master_link_status] eq {up}
+- } else {
+- fail "Replication not started."
+- }
+- }
+-
+- test {BITFIELD: write on master, read on slave} {
+- $master del bits
+- assert_equal 0 [$master bitfield bits set u8 0 255]
+- assert_equal 255 [$master bitfield bits set u8 0 100]
+- wait_for_ofs_sync $master $slave
+- assert_equal 100 [$slave bitfield_ro bits get u8 0]
+- }
+-
+- test {BITFIELD_RO fails when write option is used} {
+- catch {$slave bitfield_ro bits set u8 0 100 get u8 0} err
+- assert_match {*ERR BITFIELD_RO only supports the GET subcommand*} $err
+- }
+- }
+-}
1 month, 3 weeks
Architecture specific change in rpms/keydb.git
by githook-noreply@fedoraproject.org
The package rpms/keydb.git has added or updated architecture specific content in its
spec file (ExclusiveArch/ExcludeArch or %ifarch/%ifnarch) in commit(s):
https://src.fedoraproject.org/cgit/rpms/keydb.git/commit/?id=1bb8f6ae0f97....
Change:
+%ifarch ppc64le aarch64
Thanks.
Full change:
============
commit 1bb8f6ae0f979285da05a6055a0e0bbb2bba4b3f
Author: Jonathan Wright <jonathan(a)almalinux.org>
Date: Sat Mar 23 12:48:56 2024 -0500
initial commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1114fde
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/keydb-6.3.4.tar.gz
diff --git a/README.md b/README.md
deleted file mode 100644
index ebee892..0000000
--- a/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# keydb
-
-The keydb package
diff --git a/keydb-limit-systemd b/keydb-limit-systemd
new file mode 100644
index 0000000..a792937
--- /dev/null
+++ b/keydb-limit-systemd
@@ -0,0 +1,14 @@
+# If you need to change max open file limit
+# for example, when you change maxclient in configuration
+# you can change the LimitNOFILE value below.
+# See "man systemd.exec" for more information.
+
+# Slave nodes on large system may take lot of time to start.
+# You may need to uncomment TimeoutStartSec and TimeoutStopSec
+# directives below and raise their value.
+# See "man systemd.service" for more information.
+
+[Service]
+LimitNOFILE=10240
+#TimeoutStartSec=90s
+#TimeoutStopSec=90s
diff --git a/keydb-sentinel.service b/keydb-sentinel.service
new file mode 100644
index 0000000..dc50506
--- /dev/null
+++ b/keydb-sentinel.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=KeyDB Sentinel
+After=network.target
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+EnvironmentFile=-/etc/sysconfig/keydb
+ExecStart=/usr/bin/keydb-sentinel /etc/keydb/sentinel.conf --daemonize no --supervised systemd $OPTIONS
+Type=notify
+User=keydb
+Group=keydb
+RuntimeDirectory=keydb
+RuntimeDirectoryMode=0755
+
+[Install]
+WantedBy=multi-user.target
diff --git a/keydb-sentinel.sysconfig b/keydb-sentinel.sysconfig
new file mode 100644
index 0000000..88b923b
--- /dev/null
+++ b/keydb-sentinel.sysconfig
@@ -0,0 +1 @@
+OPTIONS="--logfile /var/log/keydb/sentinel.log --unixsocket /var/run/keydb/sentinel.sock --pidfile /var/run/keydb/sentinel.pid"
diff --git a/keydb.logrotate b/keydb.logrotate
new file mode 100644
index 0000000..0ed7ae3
--- /dev/null
+++ b/keydb.logrotate
@@ -0,0 +1,9 @@
+/var/log/keydb/*.log {
+ weekly
+ rotate 10
+ copytruncate
+ delaycompress
+ compress
+ notifempty
+ missingok
+}
diff --git a/keydb.service b/keydb.service
new file mode 100644
index 0000000..bd77611
--- /dev/null
+++ b/keydb.service
@@ -0,0 +1,18 @@
+[Unit]
+Description=KeyDB persistent key-value database
+After=network.target
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+EnvironmentFile=-/etc/sysconfig/keydb
+ExecStart=/usr/bin/keydb-server /etc/keydb/keydb.conf --daemonize no --supervised systemd $OPTIONS
+Type=notify
+User=keydb
+Group=keydb
+RuntimeDirectory=keydb
+RuntimeDirectoryMode=0755
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/keydb.spec b/keydb.spec
new file mode 100644
index 0000000..53c7b38
--- /dev/null
+++ b/keydb.spec
@@ -0,0 +1,227 @@
+%bcond_with tests
+
+Name: keydb
+Version: 6.3.4
+Release: 1%{?dist}
+Summary: Multithreaded Fork of Redis
+
+ExcludeArch: %{ix86}
+
+License: BSD-3-Clause AND BSD-2-Clause AND MIT
+# hiredis: BSD-3-Clause
+# hdrhistogram, jemalloc, linenoise: BSD-2-Clause
+# lua: MIT
+URL: https://keydb.dev/
+Source0: https://github.com/snapchat/keydb/archive/v%{version}/%{name}-%{version}....
+Source1: %{name}.logrotate
+Source2: %{name}-sentinel.service
+Source3: %{name}.service
+Source4: %{name}.sysusers
+# could have pulled this out of unpacked sources but
+# our copy has additional options pre-programmed in
+Source5: %{name}-limit-systemd
+Source6: %{name}.sysconfig
+Source7: %{name}-sentinel.sysconfig
+
+BuildRequires: gcc-c++
+BuildRequires: libuuid-devel
+BuildRequires: openssl-devel
+BuildRequires: systemd-devel
+BuildRequires: libatomic
+BuildRequires: zlib-devel
+BuildRequires: lz4-devel
+BuildRequires: libzstd-devel
+BuildRequires: snappy-devel
+BuildRequires: bzip2-devel
+BuildRequires: systemd-rpm-macros
+# for tests
+%if %{with tests}
+BuildRequires: tcl
+BuildRequires: procps-ng
+%endif
+
+Requires: logrotate
+
+Patch: use_destdir_var.patch
+
+# from deps/hiredis/hiredis.h
+Provides: bundled(hiredis) = 1.0.0
+# from deps/jemalloc/VERSION
+Provides: bundled(jemalloc) = 5.2.1
+# from deps/lua/src/lua.h
+Provides: bundled(lua-libs) = 5.1.5
+# from deps/linenoise/linenoise.h
+Provides: bundled(linenoise) = 1.0
+# from deps/hdr_histogram/README.md
+Provides: bundled(hdr_histogram) = 0.11.0
+# from deps/memkind/src/src/memkind.c
+Provides: bundled(memkind) = 1.8.0
+# from deps/rocksdb/include/rocksdb/version.h
+Provides: bundled(rocksdb) = 7.9.2
+# no version listed
+Provides: bundled(concurrentqueue)
+
+%description
+KeyDB is a multi-threaded fork of Redis, an advanced key-value store.
+It is often referred to as a data structure server since keys can contain
+strings, hashes, lists, sets and sorted sets.
+
+You can run atomic operations on these types, like appending to a string;
+incrementing the value in a hash; pushing to a list; computing set
+intersection, union and difference; or getting the member with highest
+ranking in a sorted set.
+
+In order to achieve its outstanding performance, Redis works with an
+in-memory dataset. Depending on your use case, you can persist it either
+by dumping the dataset to disk every once in a while, or by appending
+each command to a log.
+
+KeyDB also supports trivial-to-setup master-slave replication, with very
+fast non-blocking first synchronization, auto-reconnection on net split
+and so forth.
+
+Other features include Transactions, Pub/Sub, Lua scripting, Keys with a
+limited time-to-live, and configuration settings to make Redis behave like
+a cache.
+
+You can use Redis from most programming languages also.
+
+
+%package devel
+Summary: Development header for Redis module development
+# Header-Only Library (https://fedoraproject.org/wiki/Packaging:Guidelines)
+Provides: %{name}-static = %{version}-%{release}
+Conflicts: redis-devel
+
+%description devel
+Header file required for building loadable KeyDB modules.
+
+
+%prep
+%autosetup -n KeyDB-%{version} -p1
+# these deps don't see to be used
+rm -rf deps/cpp-statsd-client
+
+mv deps/lua/COPYRIGHT COPYRIGHT-lua
+mv deps/jemalloc/COPYING COPYING-jemalloc
+mv deps/hiredis/COPYING COPYING-hiredis
+mv deps/hdr_histogram/LICENSE.txt LICENSE-hdrhistogram
+mv deps/hdr_histogram/COPYING.txt COPYING-hdrhistogram
+
+
+# See https://bugzilla.redhat.com/2240293
+# See https://src.fedoraproject.org/rpms/jemalloc/blob/rawhide/f/jemalloc.spec#_34
+%ifarch ppc64le aarch64
+sed -e 's/--with-lg-quantum/--with-lg-page=16 --with-lg-quantum/' -i deps/Makefile
+%endif
+
+
+%build
+# due to makefile weirdness these flags need to be on build and install
+%make_build USE_SYSTEMD=yes PREFIX=%{_prefix} NO_MOTD=yes
+
+
+%install
+# due to makefile weirdness these flags need to be on build and install
+%make_install USE_SYSTEMD=yes PREFIX=%{_prefix} NO_MOTD=yes
+
+install -p -D -m 0644 %{S:4} %{buildroot}%{_sysusersdir}/%{name}.conf
+
+install -d %{buildroot}%{_sharedstatedir}/%{name}
+install -d %{buildroot}%{_localstatedir}/log/%{name}
+install -d %{buildroot}%{_localstatedir}/run/%{name}
+
+# Install logrotate file.
+install -pDm644 %{S:1} %{buildroot}%{_sysconfdir}/logrotate.d/%{name}
+
+# Install configuration files.
+install -pDm640 %{name}.conf %{buildroot}%{_sysconfdir}/%{name}/%{name}.conf
+install -pDm640 sentinel.conf %{buildroot}%{_sysconfdir}/%{name}/sentinel.conf
+
+# Install systemd unit files.
+mkdir -p %{buildroot}%{_unitdir}
+install -pm644 %{S:3} %{buildroot}%{_unitdir}
+install -pm644 %{S:2} %{buildroot}%{_unitdir}
+
+# Install man pages
+built_man_dir="pkg/rpm/%{name}_build/%{name}_rpm%{_mandir}"
+for page in ${built_man_dir}/*/*; do
+ manx=$(basename $(dirname "$page"))
+ target_dir="%{buildroot}%{_mandir}/$manx"
+ mkdir -p "$target_dir"
+ install -Dpm 644 "$page" "$target_dir/"
+done
+
+# Install keydb module header
+install -Dpm 644 src/redismodule.h %{buildroot}%{_includedir}/redismodule.h
+
+# Install systemd limit files (requires systemd >= 204)
+install -Dpm 644 %{S:5} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/limit.conf
+install -Dpm 644 %{S:5} %{buildroot}%{_sysconfdir}/systemd/system/%{name}-sentinel.service.d/limit.conf
+
+# Install sysconfig files
+install -Dpm 644 %{S:6} %{buildroot}%{_sysconfdir}/sysconfig/%{name}
+install -Dpm 644 %{S:7} %{buildroot}%{_sysconfdir}/sysconfig/%{name}-sentinel
+
+%pre
+%sysusers_create_compat %{S:4}
+
+
+%post
+%systemd_post %{name}.service
+%systemd_post %{name}-sentinel.service
+
+
+%preun
+%systemd_preun %{name}.service
+%systemd_preun %{name}-sentinel.service
+
+
+%postun
+%systemd_postun_with_restart %{name}.service
+%systemd_postun_with_restart %{name}-sentinel.service
+
+
+%check
+%if %{with tests}
+make test
+%endif
+
+
+%files
+%license COPYING
+%license COPYRIGHT-lua
+%license COPYING-jemalloc
+%license COPYING-hiredis
+%license LICENSE-hdrhistogram
+%license COPYING-hdrhistogram
+%doc README.md BUGS 00-RELEASENOTES
+%{_bindir}/%{name}-*
+%config(noreplace) %{_sysconfdir}/logrotate.d/%{name}
+%attr(0750, keydb, root) %dir %{_sysconfdir}/%{name}
+%attr(0640, keydb, root) %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf
+%attr(0640, keydb, root) %config(noreplace) %{_sysconfdir}/%{name}/sentinel.conf
+%{_unitdir}/%{name}.service
+%{_unitdir}/%{name}-sentinel.service
+%dir %attr(0750, keydb, keydb) %{_sharedstatedir}/%{name}
+%dir %attr(0750, keydb, keydb) %{_localstatedir}/log/%{name}
+%{_sysusersdir}/%{name}.conf
+%{_mandir}/man1/%{name}*
+%{_mandir}/man5/%{name}*
+%dir %attr(0755, keydb, keydb) %ghost %{_localstatedir}/run/%{name}
+%dir %{_sysconfdir}/systemd/system/%{name}.service.d
+%config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/limit.conf
+%dir %{_sysconfdir}/systemd/system/%{name}-sentinel.service.d
+%config(noreplace) %{_sysconfdir}/systemd/system/%{name}-sentinel.service.d/limit.conf
+%{_sysconfdir}/sysconfig/%{name}
+%{_sysconfdir}/sysconfig/%{name}-sentinel
+
+
+%files devel
+%license COPYING
+%{_includedir}/redismodule.h
+
+
+%changelog
+* Wed Mar 20 2024 Jonathan Wright <jonathan(a)almalinux.org> - 6.3.4-1
+- Initial package build
diff --git a/keydb.sysconfig b/keydb.sysconfig
new file mode 100644
index 0000000..3d5b747
--- /dev/null
+++ b/keydb.sysconfig
@@ -0,0 +1 @@
+OPTIONS="--logfile /var/log/keydb/keydb.log --dir /var/lib/keydb --unixsocket /var/run/keydb/keydb.sock --enable-motd no --pidfile /var/run/keydb/keydb.pid"
diff --git a/keydb.sysusers b/keydb.sysusers
new file mode 100644
index 0000000..2477fc2
--- /dev/null
+++ b/keydb.sysusers
@@ -0,0 +1 @@
+u keydb - "KeyDB Database Server" /dev/null /sbin/nologin
diff --git a/sources b/sources
new file mode 100644
index 0000000..7db3f01
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+SHA512 (keydb-6.3.4.tar.gz) = 6ac5060dc60df878668830336821cac740690be5525bc8c4a31a522c629b73df2da49f6d53fe8ebfec171efef258c9253d91243fe57a470aaabeddea2ac5247b
diff --git a/use_destdir_var.patch b/use_destdir_var.patch
new file mode 100644
index 0000000..2e21134
--- /dev/null
+++ b/use_destdir_var.patch
@@ -0,0 +1,272 @@
+diff -uNr KeyDB-6.2.2.orig/src/Makefile KeyDB-6.2.2/src/Makefile
+--- KeyDB-6.2.2.orig/src/Makefile 2022-09-22 17:20:16.255466414 -0500
++++ KeyDB-6.2.2/src/Makefile 2022-09-22 17:25:02.043958294 -0500
+@@ -512,13 +512,13 @@
+ @../utils/generate-command-help.rb > help.h
+
+ install: all
+- @mkdir -p $(INSTALL_BIN)
+- $(call MAKE_INSTALL,$(REDIS_SERVER_NAME),$(INSTALL_BIN))
+- $(call MAKE_INSTALL,$(REDIS_BENCHMARK_NAME),$(INSTALL_BIN))
+- $(call MAKE_INSTALL,$(REDIS_CLI_NAME),$(INSTALL_BIN))
+- @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_CHECK_RDB_NAME)
+- @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_CHECK_AOF_NAME)
+- @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_SENTINEL_NAME)
++ @mkdir -p $(DESTDIR)$(INSTALL_BIN)
++ $(call MAKE_INSTALL,$(REDIS_SERVER_NAME),$(DESTDIR)$(INSTALL_BIN))
++ $(call MAKE_INSTALL,$(REDIS_BENCHMARK_NAME),$(DESTDIR)$(INSTALL_BIN))
++ $(call MAKE_INSTALL,$(REDIS_CLI_NAME),$(DESTDIR)$(INSTALL_BIN))
++ @ln -sf $(REDIS_SERVER_NAME) $(DESTDIR)$(INSTALL_BIN)/$(REDIS_CHECK_RDB_NAME)
++ @ln -sf $(REDIS_SERVER_NAME) $(DESTDIR)$(INSTALL_BIN)/$(REDIS_CHECK_AOF_NAME)
++ @ln -sf $(REDIS_SERVER_NAME) $(DESTDIR)$(INSTALL_BIN)/$(REDIS_SENTINEL_NAME)
+
+ uninstall:
+- rm -f $(INSTALL_BIN)/{$(REDIS_SERVER_NAME),$(REDIS_BENCHMARK_NAME),$(REDIS_CLI_NAME),$(REDIS_CHECK_RDB_NAME),$(REDIS_CHECK_AOF_NAME),$(REDIS_SENTINEL_NAME),$(KEYDB_DIAGNOSTIC_NAME)}
++ rm -f $(DESTDIR)$(INSTALL_BIN)/{$(REDIS_SERVER_NAME),$(REDIS_BENCHMARK_NAME),$(REDIS_CLI_NAME),$(REDIS_CHECK_RDB_NAME),$(REDIS_CHECK_AOF_NAME),$(REDIS_SENTINEL_NAME),$(KEYDB_DIAGNOSTIC_NAME)}
+diff -uNr KeyDB-6.2.2.orig/tests/test_helper.tcl KeyDB-6.2.2/tests/test_helper.tcl
+--- KeyDB-6.2.2.orig/tests/test_helper.tcl 2022-09-22 17:20:16.261466487 -0500
++++ KeyDB-6.2.2/tests/test_helper.tcl 2022-09-22 17:44:21.039374195 -0500
+@@ -68,7 +68,6 @@
+ unit/limits
+ unit/obuf-limits
+ unit/bitops
+- unit/bitfield
+ unit/geo
+ unit/memefficiency
+ unit/hyperloglog
+diff -uNr KeyDB-6.2.2.orig/tests/unit/bitfield.tcl KeyDB-6.2.2/tests/unit/bitfield.tcl
+--- KeyDB-6.2.2.orig/tests/unit/bitfield.tcl 2022-09-22 17:20:16.263466511 -0500
++++ KeyDB-6.2.2/tests/unit/bitfield.tcl 1969-12-31 18:00:00.000000000 -0600
+@@ -1,232 +0,0 @@
+-start_server {tags {"bitops"}} {
+- test {BITFIELD signed SET and GET basics} {
+- r del bits
+- set results {}
+- lappend results [r bitfield bits set i8 0 -100]
+- lappend results [r bitfield bits set i8 0 101]
+- lappend results [r bitfield bits get i8 0]
+- set results
+- } {0 -100 101}
+-
+- test {BITFIELD unsigned SET and GET basics} {
+- r del bits
+- set results {}
+- lappend results [r bitfield bits set u8 0 255]
+- lappend results [r bitfield bits set u8 0 100]
+- lappend results [r bitfield bits get u8 0]
+- set results
+- } {0 255 100}
+-
+- test {BITFIELD #<idx> form} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 65
+- r bitfield bits set u8 #1 66
+- r bitfield bits set u8 #2 67
+- r get bits
+- } {ABC}
+-
+- test {BITFIELD basic INCRBY form} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 10
+- lappend results [r bitfield bits incrby u8 #0 100]
+- lappend results [r bitfield bits incrby u8 #0 100]
+- set results
+- } {110 210}
+-
+- test {BITFIELD chaining of multiple commands} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 10
+- lappend results [r bitfield bits incrby u8 #0 100 incrby u8 #0 100]
+- set results
+- } {{110 210}}
+-
+- test {BITFIELD unsigned overflow wrap} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 100
+- lappend results [r bitfield bits overflow wrap incrby u8 #0 257]
+- lappend results [r bitfield bits get u8 #0]
+- lappend results [r bitfield bits overflow wrap incrby u8 #0 255]
+- lappend results [r bitfield bits get u8 #0]
+- } {101 101 100 100}
+-
+- test {BITFIELD unsigned overflow sat} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 100
+- lappend results [r bitfield bits overflow sat incrby u8 #0 257]
+- lappend results [r bitfield bits get u8 #0]
+- lappend results [r bitfield bits overflow sat incrby u8 #0 -255]
+- lappend results [r bitfield bits get u8 #0]
+- } {255 255 0 0}
+-
+- test {BITFIELD signed overflow wrap} {
+- r del bits
+- set results {}
+- r bitfield bits set i8 #0 100
+- lappend results [r bitfield bits overflow wrap incrby i8 #0 257]
+- lappend results [r bitfield bits get i8 #0]
+- lappend results [r bitfield bits overflow wrap incrby i8 #0 255]
+- lappend results [r bitfield bits get i8 #0]
+- } {101 101 100 100}
+-
+- test {BITFIELD signed overflow sat} {
+- r del bits
+- set results {}
+- r bitfield bits set u8 #0 100
+- lappend results [r bitfield bits overflow sat incrby i8 #0 257]
+- lappend results [r bitfield bits get i8 #0]
+- lappend results [r bitfield bits overflow sat incrby i8 #0 -255]
+- lappend results [r bitfield bits get i8 #0]
+- } {127 127 -128 -128}
+-
+- test {BITFIELD overflow detection fuzzing} {
+- for {set j 0} {$j < 1000} {incr j} {
+- set bits [expr {[randomInt 64]+1}]
+- set sign [randomInt 2]
+- set range [expr {2**$bits}]
+- if {$bits == 64} {set sign 1} ; # u64 is not supported by BITFIELD.
+- if {$sign} {
+- set min [expr {-($range/2)}]
+- set type "i$bits"
+- } else {
+- set min 0
+- set type "u$bits"
+- }
+- set max [expr {$min+$range-1}]
+-
+- # Compare Tcl vs Redis
+- set range2 [expr {$range*2}]
+- set value [expr {($min*2)+[randomInt $range2]}]
+- set increment [expr {($min*2)+[randomInt $range2]}]
+- if {$value > 9223372036854775807} {
+- set value 9223372036854775807
+- }
+- if {$value < -9223372036854775808} {
+- set value -9223372036854775808
+- }
+- if {$increment > 9223372036854775807} {
+- set increment 9223372036854775807
+- }
+- if {$increment < -9223372036854775808} {
+- set increment -9223372036854775808
+- }
+-
+- set overflow 0
+- if {$value > $max || $value < $min} {set overflow 1}
+- if {($value + $increment) > $max} {set overflow 1}
+- if {($value + $increment) < $min} {set overflow 1}
+-
+- r del bits
+- set res1 [r bitfield bits overflow fail set $type 0 $value]
+- set res2 [r bitfield bits overflow fail incrby $type 0 $increment]
+-
+- if {$overflow && [lindex $res1 0] ne {} &&
+- [lindex $res2 0] ne {}} {
+- fail "OW not detected where needed: $type $value+$increment"
+- }
+- if {!$overflow && ([lindex $res1 0] eq {} ||
+- [lindex $res2 0] eq {})} {
+- fail "OW detected where NOT needed: $type $value+$increment"
+- }
+- }
+- }
+-
+- test {BITFIELD overflow wrap fuzzing} {
+- for {set j 0} {$j < 1000} {incr j} {
+- set bits [expr {[randomInt 64]+1}]
+- set sign [randomInt 2]
+- set range [expr {2**$bits}]
+- if {$bits == 64} {set sign 1} ; # u64 is not supported by BITFIELD.
+- if {$sign} {
+- set min [expr {-($range/2)}]
+- set type "i$bits"
+- } else {
+- set min 0
+- set type "u$bits"
+- }
+- set max [expr {$min+$range-1}]
+-
+- # Compare Tcl vs Redis
+- set range2 [expr {$range*2}]
+- set value [expr {($min*2)+[randomInt $range2]}]
+- set increment [expr {($min*2)+[randomInt $range2]}]
+- if {$value > 9223372036854775807} {
+- set value 9223372036854775807
+- }
+- if {$value < -9223372036854775808} {
+- set value -9223372036854775808
+- }
+- if {$increment > 9223372036854775807} {
+- set increment 9223372036854775807
+- }
+- if {$increment < -9223372036854775808} {
+- set increment -9223372036854775808
+- }
+-
+- r del bits
+- r bitfield bits overflow wrap set $type 0 $value
+- r bitfield bits overflow wrap incrby $type 0 $increment
+- set res [lindex [r bitfield bits get $type 0] 0]
+-
+- set expected 0
+- if {$sign} {incr expected [expr {$max+1}]}
+- incr expected $value
+- incr expected $increment
+- set expected [expr {$expected % $range}]
+- if {$sign} {incr expected $min}
+-
+- if {$res != $expected} {
+- fail "WRAP error: $type $value+$increment = $res, should be $expected"
+- }
+- }
+- }
+-
+- test {BITFIELD regression for #3221} {
+- r set bits 1
+- r bitfield bits get u1 0
+- } {0}
+-
+- test {BITFIELD regression for #3564} {
+- for {set j 0} {$j < 10} {incr j} {
+- r del mystring
+- set res [r BITFIELD mystring SET i8 0 10 SET i8 64 10 INCRBY i8 10 99900]
+- assert {$res eq {0 0 60}}
+- }
+- r del mystring
+- }
+-}
+-
+-start_server {tags {"repl"}} {
+- start_server {} {
+- set master [srv -1 client]
+- set master_host [srv -1 host]
+- set master_port [srv -1 port]
+- set slave [srv 0 client]
+-
+- test {BITFIELD: setup slave} {
+- $slave slaveof $master_host $master_port
+- wait_for_condition 50 100 {
+- [s 0 master_link_status] eq {up}
+- } else {
+- fail "Replication not started."
+- }
+- }
+-
+- test {BITFIELD: write on master, read on slave} {
+- $master del bits
+- assert_equal 0 [$master bitfield bits set u8 0 255]
+- assert_equal 255 [$master bitfield bits set u8 0 100]
+- wait_for_ofs_sync $master $slave
+- assert_equal 100 [$slave bitfield_ro bits get u8 0]
+- }
+-
+- test {BITFIELD_RO fails when write option is used} {
+- catch {$slave bitfield_ro bits set u8 0 100 get u8 0} err
+- assert_match {*ERR BITFIELD_RO only supports the GET subcommand*} $err
+- }
+- }
+-}
1 month, 3 weeks