Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package go-sendxmpp for openSUSE:Factory 
checked in at 2026-07-07 21:04:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/go-sendxmpp (Old)
 and      /work/SRC/openSUSE:Factory/.go-sendxmpp.new.1982 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "go-sendxmpp"

Tue Jul  7 21:04:17 2026 rev:29 rq:1364165 version:0.16.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/go-sendxmpp/go-sendxmpp.changes  2026-05-13 
17:24:07.227193388 +0200
+++ /work/SRC/openSUSE:Factory/.go-sendxmpp.new.1982/go-sendxmpp.changes        
2026-07-07 21:07:09.294491457 +0200
@@ -1,0 +2,23 @@
+Tue Jun 23 05:22:03 UTC 2026 - Michael Vetter <[email protected]>
+
+- Update to 0.16.0:
+  Added:
+  * Add Ox support to http-upload.
+  * Add Ox support for private group chats.
+  * Show error cause if joining MUCs failedi (requires go-xmpp >= v0.3.5).
+  Changed:
+  * Fix --ox-delete-nodes.
+  * Fix receiving of 1-1 messages while joined in a MUC.
+  * Use go-sendxmpp + a random ID as fallback MUC alias.
+  * Strip leading "xmpp:" from recipients.
+  * Strip trailing "?join" from MUC JIDs.
+  * Add context for timeouts in stanza handling.
+  * Check ID for disco items reply (requires go-xmpp >= v0.3.6).
+  * Reduce channel buffer size to 1 where only one item will be returned.
+  * Deprecate legacy PGP.
+  * CVE-2026-1229: The CombinedMult function produces an incorrect value 
(bsc#1265538)
+    Bump circl to 1.6.3
+  * CVE-2026-39821: Failure to reject ASCII-only Punycode-encoded labels 
allows for validation bypass and privilege escalation (bsc#1266617)
+    Bump net to 0.56.0
+
+-------------------------------------------------------------------

Old:
----
  go-sendxmpp-v0.15.8.tar.gz

New:
----
  go-sendxmpp-v0.16.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ go-sendxmpp.spec ++++++
--- /var/tmp/diff_new_pack.fpBMHE/_old  2026-07-07 21:07:10.626537830 +0200
+++ /var/tmp/diff_new_pack.fpBMHE/_new  2026-07-07 21:07:10.626537830 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           go-sendxmpp
-Version:        0.15.8
+Version:        0.16.0
 Release:        0
 Summary:        A little tool to send messages to an XMPP contact or MUC
 License:        BSD-2-Clause

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.fpBMHE/_old  2026-07-07 21:07:10.738541730 +0200
+++ /var/tmp/diff_new_pack.fpBMHE/_new  2026-07-07 21:07:10.754542287 +0200
@@ -1,6 +1,6 @@
-mtime: 1778651892
-commit: 15e740b0889cf05bf7051482dafc10882cf35eff3337bc71f45a16de950180b2
+mtime: 1783404265
+commit: 55e82266f2336aff9f274818472c120c2ec9d17035846b4f25f3d4445124edae
 url: https://src.opensuse.org/xmpp/go-sendxmpp
-revision: 15e740b0889cf05bf7051482dafc10882cf35eff3337bc71f45a16de950180b2
+revision: 55e82266f2336aff9f274818472c120c2ec9d17035846b4f25f3d4445124edae
 projectscmsync: https://src.opensuse.org/xmpp/_ObsPrj.git
 

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-07-07 08:04:25.000000000 +0200
@@ -0,0 +1 @@
+.osc

++++++ go-sendxmpp-v0.15.8.tar.gz -> go-sendxmpp-v0.16.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/CHANGELOG.md 
new/go-sendxmpp-v0.16.0/CHANGELOG.md
--- old/go-sendxmpp-v0.15.8/CHANGELOG.md        2026-05-12 19:59:13.000000000 
+0200
+++ new/go-sendxmpp-v0.16.0/CHANGELOG.md        2026-06-20 09:54:34.000000000 
+0200
@@ -1,4 +1,21 @@
 # Changelog
+## [v0.16.0] 2026-06-20
+### Added
+- Add Ox support to http-upload.
+- Add Ox support for private group chats.
+- Show error cause if joining MUCs failedi (requires go-xmpp >= v0.3.5).
+
+### Changed
+- Fix `--ox-delete-nodes`.
+- Fix receiving of 1-1 messages while joined in a MUC.
+- Use go-sendxmpp + a random ID as fallback MUC alias.
+- Strip leading "xmpp:" from recipients.
+- Strip trailing "?join" from MUC JIDs.
+- Add context for timeouts in stanza handling.
+- Check ID for disco items reply (requires go-xmpp >= v0.3.6).
+- Reduce channel buffer size to 1 where only one item will be returned.
+- Deprecate legacy PGP.
+
 ## [v0.15.8] 2026-05-12
 ### Changed
 - Fix windows build (windows doesn't support syscalls Setgid and Setuid).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/README.md 
new/go-sendxmpp-v0.16.0/README.md
--- old/go-sendxmpp-v0.15.8/README.md   2026-05-12 19:59:13.000000000 +0200
+++ new/go-sendxmpp-v0.16.0/README.md   2026-06-20 09:54:34.000000000 +0200
@@ -96,7 +96,7 @@
  -j, --jserver=value
                     XMPP server address.
      --legacy-pgp   Use "Legacy PGP" encryption using the Ox key infrastructure
-                    (experimental and not encouraged).
+                    (deprecated and not encouraged).
  -l, --listen       Listen for messages and print them to stdout.
  -m, --message=value
                     Set file including the message.
@@ -152,6 +152,8 @@
      --version      Show version information.
 ```
 
+For further information check the manpages 
[go-sendxmpp(1)](https://manpages.debian.org/unstable/go-sendxmpp/go-sendxmpp.1.en.html)
 and 
[go-sendxmpp(5)](https://manpages.debian.org/unstable/go-sendxmpp/go-sendxmpp.5.en.html).
+
 ### examples
 
 Send a message to two recipients using a configuration file.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/const.go 
new/go-sendxmpp-v0.16.0/const.go
--- old/go-sendxmpp-v0.15.8/const.go    2026-05-12 19:59:13.000000000 +0200
+++ new/go-sendxmpp-v0.16.0/const.go    2026-06-20 09:54:34.000000000 +0200
@@ -5,7 +5,7 @@
 package main
 
 const (
-       version = "0.15.8"
+       version = "0.16.0"
        // defaults
        defaultBufferSize      = 100
        defaultConfigColumnSep = 2
@@ -33,6 +33,7 @@
        nsJabberClient    = "jabber:client"
        nsJabberData      = "jabber:x:data"
        nsJabberEncrypted = "jabber:x:encrypted"
+       nsMUCAdmin        = "http://jabber.org/protocol/muc#admin";
        nsOx              = "urn:xmpp:openpgp:0"
        nsOxPubKeys       = "urn:xmpp:openpgp:0:public-keys"
        nsPubsub          = "http://jabber.org/protocol/pubsub";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/go.mod 
new/go-sendxmpp-v0.16.0/go.mod
--- old/go-sendxmpp-v0.15.8/go.mod      2026-05-12 19:59:13.000000000 +0200
+++ new/go-sendxmpp-v0.16.0/go.mod      2026-06-20 09:54:34.000000000 +0200
@@ -8,15 +8,15 @@
        github.com/gabriel-vasile/mimetype v1.4.13
        github.com/google/uuid v1.6.0
        github.com/pborman/getopt/v2 v2.1.0
-       github.com/xmppo/go-xmpp v0.3.4
-       golang.org/x/crypto v0.51.0
-       golang.org/x/net v0.54.0
+       github.com/xmppo/go-xmpp v0.3.6
+       golang.org/x/crypto v0.53.0
+       golang.org/x/net v0.56.0
        salsa.debian.org/mdosch/xmppsrv v0.3.3
 )
 
 require (
        github.com/ProtonMail/go-crypto v1.4.1 // indirect
        github.com/cloudflare/circl v1.6.3 // indirect
-       golang.org/x/sys v0.44.0 // indirect
-       golang.org/x/text v0.37.0 // indirect
+       golang.org/x/sys v0.46.0 // indirect
+       golang.org/x/text v0.38.0 // indirect
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/go.sum 
new/go-sendxmpp-v0.16.0/go.sum
--- old/go-sendxmpp-v0.15.8/go.sum      2026-05-12 19:59:13.000000000 +0200
+++ new/go-sendxmpp-v0.16.0/go.sum      2026-06-20 09:54:34.000000000 +0200
@@ -18,16 +18,16 @@
 github.com/pmezard/go-difflib v1.0.0/go.mod 
h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/testify v1.10.0 
h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.0/go.mod 
h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/xmppo/go-xmpp v0.3.4 h1:w7EBGsEzz2TBGJ2FQcOEn0CDzkuJ9CpUBIA+oJB5EuE=
-github.com/xmppo/go-xmpp v0.3.4/go.mod 
h1:03Za3Szic72CqdDIdlZtnay9R7t2MWJsj6ZpCvxlGDs=
-golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
-golang.org/x/crypto v0.51.0/go.mod 
h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
-golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w=
-golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ=
-golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
-golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
-golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
-golang.org/x/text v0.37.0/go.mod 
h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
+github.com/xmppo/go-xmpp v0.3.6 h1:CbTrXAotlt7UsjGqpqfNIXfmoSziP73eSFqhH4IS8ng=
+github.com/xmppo/go-xmpp v0.3.6/go.mod 
h1:YD5roZgj385upOjjG4RNNQ1kdhk5JtvA944MpMAb+jo=
+golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
+golang.org/x/crypto v0.53.0/go.mod 
h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
+golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
+golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
+golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
+golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
+golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
+golang.org/x/text v0.38.0/go.mod 
h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 salsa.debian.org/mdosch/xmppsrv v0.3.3 
h1:F8FGyw1Q1LkAs/UbIXd6Obd33q2CKWrIxxrzvuLSVuM=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/httpupload.go 
new/go-sendxmpp-v0.16.0/httpupload.go
--- old/go-sendxmpp-v0.15.8/httpupload.go       2026-05-12 19:59:13.000000000 
+0200
+++ new/go-sendxmpp-v0.16.0/httpupload.go       2026-06-20 09:54:34.000000000 
+0200
@@ -6,6 +6,9 @@
 
 import (
        "bytes"
+       "crypto/aes"
+       "crypto/cipher"
+       "crypto/rand"
        "encoding/xml"
        "fmt"
        "log/slog"
@@ -25,12 +28,14 @@
 )
 
 func httpUpload(client *xmpp.Client, iqc chan xmpp.IQ, disc chan 
xmpp.DiscoItems, drc chan xmpp.DiscoResult, slc chan xmpp.Slot,
-       jserver string, filePaths []string, timeout time.Duration, oxPrivKey 
*crypto.Key, keyRing *crypto.KeyRing,
+       jserver string, filePaths []string, timeout time.Duration, oxPrivKey 
*crypto.Key, keyRing *crypto.KeyRing, oxEnc bool,
 ) (urls []string, err error) {
        var (
                uploadComponent string
                maxFileSize     int64
                req             *http.Request
+               aesKey          []byte
+               nonce           []byte
        )
 
        buffer := new(bytes.Buffer)
@@ -116,6 +121,42 @@
                slog.Info("http-upload:", "mime type", mimeType)
                var mimeTypeEscaped bytes.Buffer
                xml.Escape(&mimeTypeEscaped, []byte(mimeType))
+               if oxEnc {
+                       buf, err := readFile(filePath)
+                       if err != nil {
+                               err2 := file.Close()
+                               if err2 != nil {
+                                       slog.Warn("closing file failed", 
"error", err2)
+                               }
+                               return nil, fmt.Errorf("http-upload: %w", err)
+                       }
+
+                       aesKey = make([]byte, 32)
+                       _, err = rand.Read(aesKey)
+                       if err != nil {
+                               return nil, fmt.Errorf("http-upload: ox: 
generating aes key: %w", err)
+                       }
+                       block, err := aes.NewCipher(aesKey)
+                       if err != nil {
+                               return nil, fmt.Errorf("http-upload: ox: 
generating block cipher: %w", err)
+                       }
+                       nonce = make([]byte, 12)
+                       _, err = rand.Read(nonce)
+                       if err != nil {
+                               return nil, fmt.Errorf("http-upload: ox: 
generating nonce: %w", err)
+                       }
+                       aesgcm, err := cipher.NewGCM(block)
+                       if err != nil {
+                               return nil, fmt.Errorf("http-upload: ox: %w", 
err)
+                       }
+                       encBytes := aesgcm.Seal(nil, nonce, buf.Bytes(), nil)
+                       buffer = bytes.NewBuffer(encBytes)
+                       fileSize = int64(buffer.Len())
+                       err = file.Close()
+                       if err != nil {
+                               slog.Warn("closing file failed", "error", err)
+                       }
+               }
                if oxPrivKey != nil {
                        buf, err := readFile(filePath)
                        if err != nil {
@@ -215,7 +256,7 @@
                        httpTransport.Proxy = http.ProxyURL(proxyURL)
                }
                httpClient := &http.Client{Transport: httpTransport}
-               if oxPrivKey != nil {
+               if oxEnc || oxPrivKey != nil {
                        req, err = http.NewRequest(http.MethodPut, 
uploadSlot.Put.Url, buffer)
                } else {
                        req, err = http.NewRequest(http.MethodPut, 
uploadSlot.Put.Url, file)
@@ -276,11 +317,14 @@
                if err != nil {
                        fmt.Println("http-upload: error while closing http 
request body:", err)
                }
-               urls = append(urls, uploadSlot.Get.Url)
-               err = file.Close()
-               if err != nil {
-                       slog.Warn("closing file failed", "error", err)
+               var url string
+               if oxEnc {
+                       url = strings.TrimPrefix(uploadSlot.Get.Url, "https://";)
+                       url = fmt.Sprintf("aesgcm://%s#%x%x", url, nonce, 
aesKey)
+               } else {
+                       url = uploadSlot.Get.Url
                }
+               urls = append(urls, url)
        }
        return urls, nil
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/main.go 
new/go-sendxmpp-v0.16.0/main.go
--- old/go-sendxmpp-v0.15.8/main.go     2026-05-12 19:59:13.000000000 +0200
+++ new/go-sendxmpp-v0.16.0/main.go     2026-06-20 09:54:34.000000000 +0200
@@ -164,7 +164,7 @@
        flagRecipientsFile := getopt.StringLong("recipients", 'r', "", "Read 
recipients from file.")
        flagRetryConnect := getopt.IntLong("retry-connect", 0, 0, "Time to 
retry to connect after failed connection in seconds. (0 = disabled)")
        flagRetryConnectMax := getopt.IntLong("retry-connect-max", 0, 0, 
"Number of maximum retries to perform for '--retry-connect'. (0 = unlimited)")
-       flagLegacyPGP := getopt.BoolLong("legacy-pgp", 0, "Use \"Legacy PGP\" 
encryption using the Ox key infrastructure (experimental and not encouraged).")
+       flagLegacyPGP := getopt.BoolLong("legacy-pgp", 0, "Use \"Legacy PGP\" 
encryption using the Ox key infrastructure (deprecated and not encouraged).")
 
        // Parse command line flags.
        getopt.Parse()
@@ -186,10 +186,8 @@
                os.Exit(0)
                // Quit if Ox (OpenPGP for XMPP) is requested for unsupported 
operations like
                // groupchat, http-upload or listening.
-       case *flagOx && len(*flagHTTPUpload) != 0:
-               log.Fatal("No Ox support for http-upload available.")
-       case (*flagOx || *flagLegacyPGP) && *flagChatroom:
-               log.Fatal("No Ox or legacy PGP support for chat rooms 
available.")
+       case *flagLegacyPGP && *flagChatroom:
+               log.Fatal("No legacy PGP support for chat rooms available.")
        case len(*flagHTTPUpload) != 0 && *flagInteractive:
                log.Fatal("Interactive mode and http upload can't" +
                        " be used at the same time.")
@@ -214,6 +212,11 @@
                slog.SetLogLoggerLevel(slog.LevelDebug)
        }
 
+       if *flagLegacyPGP {
+               slog.Warn("Legacy PGP is deprecated and will be removed in a 
future version, " +
+                       "please use 'OpenPGP for XMPP' (OX) instead.")
+       }
+
        // Print a warning if go-sendxmpp is run by the user root on 
non-windows systems.
        if runtime.GOOS != "windows" && !*flagNoRootWarning {
                // Get the current user.
@@ -343,7 +346,7 @@
        // Use "go-sendxmpp" if no nick is specified via config or command line 
flag.
        case *flagChatroom && alias == "" && *flagAlias == "":
                slog.Info("no alias defined, using go-sendxmpp")
-               alias = "go-sendxmpp"
+               alias = "go-sendxmpp." + getShortID()
                // Overwrite configured alias if a nick is specified via 
command line flag.
        case *flagAlias != "":
                alias = *flagAlias
@@ -603,15 +606,25 @@
        go rcvStanzas(client, ctx, iqc, msgc, prsc, disc, drc, slc)
        for _, r := range recipientsList {
                var re recipientsType
-               re.Jid = r
-               if *flagOx || *flagLegacyPGP {
+               re.Jid = strings.TrimPrefix(strings.ToLower(r), "xmpp:")
+               if *flagChatroom {
+                       re.Jid = strings.TrimSuffix(re.Jid, "?join")
+               }
+               switch {
+               case (*flagOx || *flagLegacyPGP) && !*flagChatroom:
                        slog.Info("requesting OX key for", "JID", re.Jid)
-                       re.OxKeyRing, err = oxGetPublicKeyRing(client, iqc, r)
+                       re.OxKeyRing, err = oxGetPublicKeyRing(client, iqc, 
re.Jid)
                        if err != nil {
                                re.OxKeyRing = nil
-                               fmt.Printf("ox: error fetching key for %s: 
%v\n", r, err)
+                               fmt.Printf("ox: error fetching key for %s: 
%v\n", re.Jid, err)
                                failure = err
                        }
+               case *flagOx && *flagChatroom:
+                       re.OxKeyRing, err = oxGetPublicKeyRingChatroom(client, 
iqc, drc, re.Jid)
+                       if err != nil {
+                               re.OxKeyRing = nil
+                               fmt.Println("Couldn't receive keys for:", 
re.Jid)
+                       }
                }
                recipients = append(recipients, re)
        }
@@ -683,7 +696,7 @@
                        closeAndExit(client, err)
                }
                slog.Info("delete OX pep nodes")
-               err = oxDeleteNodes(validatedOwnJid, client, iqc)
+               err = oxDeleteNodes(validatedOwnJid, client, iqc, disc)
                if err != nil {
                        cancel()
                        closeAndExit(client, err)
@@ -705,10 +718,10 @@
        }
 
        var uploadMessages []string
-       if len(*flagHTTPUpload) != 0 && !*flagLegacyPGP {
+       if len(*flagHTTPUpload) != 0 && !*flagLegacyPGP && !*flagOx {
                slog.Info("http-upload:", "file", *flagHTTPUpload)
                uploadMessages, err = httpUpload(client, iqc, disc, drc, slc,
-                       jserver, *flagHTTPUpload, timeout, nil, nil)
+                       jserver, *flagHTTPUpload, timeout, nil, nil, false)
                if err != nil {
                        cancel()
                        closeAndExit(client, err)
@@ -760,8 +773,8 @@
                        select {
                        case presence = <-pc:
                                if presence.Type == "error" {
-                                       fmt.Printf("Could not join MUC %s\n", 
recipient.Jid)
-                                       failure = fmt.Errorf("failed to join 
one or more MUCs")
+                                       fmt.Printf("Could not join MUC %s: 
%s\n", recipient.Jid, presence.Error)
+                                       failure = fmt.Errorf("failed to join 
one or more MUCs: last error: %s: %s", recipient.Jid, presence.Error)
                                }
                        case <-time.After(60 * time.Second):
                                fmt.Printf("Could not join muc: didn't receive 
a presence from %s\n", recipient.Jid)
@@ -832,7 +845,7 @@
                                        case *flagOx:
                                                slog.Info("encrypting message 
with OX for", "JID", recipient.Jid)
                                                cryptMessage, err = 
oxEncrypt(client, oxPrivKey,
-                                                       recipient.Jid, 
*recipient.OxKeyRing, message, *flagSubject)
+                                                       recipient.Jid, 
*recipient.OxKeyRing, message, *flagSubject, *flagChatroom)
                                                if err != nil {
                                                        fmt.Printf("ox: 
couldn't encrypt to %s: %v\n",
                                                                recipient.Jid, 
err)
@@ -897,7 +910,7 @@
                                var t time.Time
                                if isOx {
                                        slog.Info("message is OX encrypted")
-                                       msg, t, err = oxDecrypt(v, client, iqc, 
user, oxPrivKey)
+                                       msg, t, err = oxDecrypt(v, client, iqc, 
drc, user, oxPrivKey)
                                        if err != nil {
                                                log.Println(err)
                                                continue
@@ -928,8 +941,11 @@
                                default:
                                        bareFrom = strings.Split(v.Remote, 
"/")[0]
                                }
-                               // Print any messages if no recipients are 
specified
-                               if len(recipients) == 0 {
+                               // Print any messages if no recipients are 
specified and if we are not
+                               // joined to a MUC. MUC messages are only 
received when joining them,
+                               // therefore a recipient (MUC) is specified 
even if we did not intend
+                               // to block receiving of other messages.
+                               if len(recipients) == 0 || *flagChatroom {
                                        
fmt.Println(t.In(tz).Format(time.RFC3339), prefix,
                                                bareFrom+":", msg)
                                } else {
@@ -981,7 +997,7 @@
                                break
                        }
                        switch {
-                       case len(*flagHTTPUpload) != 0 && !*flagLegacyPGP:
+                       case len(*flagHTTPUpload) != 0 && !*flagLegacyPGP && 
!*flagOx:
                                for _, message = range uploadMessages {
                                        slog.Info("sending http-upload 
message:", "file", message, "JID", recipient.Jid)
                                        _, err = client.SendOOB(xmpp.Chat{
@@ -993,9 +1009,36 @@
                                                        recipient.Jid)
                                        }
                                }
+                       case len(*flagHTTPUpload) != 0 && *flagOx:
+                               uploadMessages, err = httpUpload(client, iqc, 
disc, drc, slc,
+                                       jserver, *flagHTTPUpload, timeout, nil, 
nil, true)
+                               if err != nil {
+                                       cancel()
+                                       closeAndExit(client, err)
+                               }
+                               if recipient.OxKeyRing == nil {
+                                       continue
+                               }
+                               for _, message = range uploadMessages {
+                                       slog.Info("sending ox encrypted 
http-upload message:", "file", message, "JID", recipient.Jid)
+                                       cryptMessage, err := oxEncrypt(client, 
oxPrivKey,
+                                               recipient.Jid, 
*recipient.OxKeyRing, message, *flagSubject, *flagChatroom)
+                                       if err != nil {
+                                               fmt.Printf("ox: couldn't 
encrypt to %s: %v\n",
+                                                       recipient.Jid, err)
+                                               failure = err
+                                               continue
+                                       }
+                                       _, err = client.SendOrg(cryptMessage)
+                                       if err != nil {
+                                               cancel()
+                                               closeAndExit(client, err)
+                                       }
+                               }
+
                        case len(*flagHTTPUpload) != 0 && *flagLegacyPGP:
                                uploadMessages, err = httpUpload(client, iqc, 
disc, drc, slc,
-                                       jserver, *flagHTTPUpload, timeout, 
oxPrivKey, recipient.OxKeyRing)
+                                       jserver, *flagHTTPUpload, timeout, 
oxPrivKey, recipient.OxKeyRing, false)
                                if err != nil {
                                        cancel()
                                        closeAndExit(client, err)
@@ -1033,7 +1076,7 @@
                                case *flagOx:
                                        slog.Info("encrypting message with OX 
for", "JID", recipient.Jid)
                                        cryptMessage, err = oxEncrypt(client, 
oxPrivKey,
-                                               recipient.Jid, 
*recipient.OxKeyRing, message, *flagSubject)
+                                               recipient.Jid, 
*recipient.OxKeyRing, message, *flagSubject, *flagChatroom)
                                        if err != nil {
                                                fmt.Printf("ox: couldn't 
encrypt to %s: %v\n",
                                                        recipient.Jid, err)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/man/go-sendxmpp.1 
new/go-sendxmpp-v0.16.0/man/go-sendxmpp.1
--- old/go-sendxmpp-v0.15.8/man/go-sendxmpp.1   2026-05-12 19:59:13.000000000 
+0200
+++ new/go-sendxmpp-v0.16.0/man/go-sendxmpp.1   2026-06-20 09:54:34.000000000 
+0200
@@ -1,6 +1,6 @@
 .\" generated with Ronn-NG/v0.10.1
 .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
-.TH "GO\-SENDXMPP" "1" "May 2026" ""
+.TH "GO\-SENDXMPP" "1" "June 2026" ""
 .SH "NAME"
 \fBgo\-sendxmpp\fR \- A tool to send messages to an XMPP contact or MUC\.
 .SH "SYNOPSIS"
@@ -51,7 +51,7 @@
 XMPP server address\.
 .TP
 \fB\-\-legacy\-pgp\fR
-"Legacy PGP" encryption using the Ox key infrastructure\. This means the 
recipient must have an Ox key published and use the same key for legacy PGP\. 
The use of legacy PGP is actually discouraged and only provided as a workaround 
for conversations users\. If the existing key has no ID in the form of 
\fBxmpp:user@example\.org\fR, it can be added by using the tool \fIsq\fR:
+"Legacy PGP" encryption using the Ox key infrastructure\. This means the 
recipient must have an Ox key published and use the same key for legacy PGP\. 
This encryption method is deprecated and will be removed in a future version, 
please consider switching to \fIOpenPGP for XMPP\fR (OX)\. The use of legacy 
PGP is actually discouraged and only provided as a workaround for conversations 
users\. If the existing key has no ID in the form of 
\fBxmpp:user@example\.org\fR, it can be added by using the tool \fIsq\fR:
 .IP "" 4
 .nf
   $ sq key userid add \-u xmpp:user@example\.org \-Bo newkey\.asc oldkey\.asc`
@@ -61,7 +61,7 @@
 This key (\fBnewkey\.asc\fR in the \fIsq\fR example) can than be imported by 
using \fB\-\-ox\-import\-privkey\fR\. Please note that this will store the 
secret key at 
\fB~/\.local/share/go\-sendxmpp/user_at_example_org/oxprivkey\fR\. If you don't 
want to use that account with go\-sendxmpp and only imported the key to upload 
the public key to pubsub you might consider deleting the file\.
 .TP
 \fB\-l\fR, \fB\-\-listen\fR
-Listen for messages and print them to stdout\. If JIDs are specified only 
messages from those contacts are shown\. If no JIDs are specified all received 
messages will be shown\.
+Listen for messages and print them to stdout\. If JIDs are specified only 
messages from those contacts are shown\. If no JIDs are specified or a chat 
room is joined all received messages will be shown\.
 .TP
 \fB\-m\fR, \fB\-\-message\fR=[\fIvalue\fR]
 Set file including the message\.
@@ -81,7 +81,7 @@
 \fB\-\-ox\fR
 Use "OpenPGP for XMPP" encryption (experimental)\.
 .br
-Ox in go\-sendxmpp only supports sending encrypted 1\-1 messages\. Sending to 
groupchats and sending encrypted files is not supported\. There is no check 
whether the recipients key is trusted as there is no local keyring used\. 
Go\-sendxmpp just uses the most recent key that is provided via pubsub and 
checks that it is not expired\. As a user facing client a notification would be 
shown that a new key is available and ask the user whether to use the new key 
or stick to the old one\. As go\-sendxmpp is usually used in scripts it just 
accepts the new key to prevent the user from missing a new notification due to 
changed keys\.
+There is no check whether the recipients key is trusted as there is no local 
keyring used\. Go\-sendxmpp just uses the most recent key that is provided via 
pubsub and checks that it is not expired\. As a user facing client a 
notification would be shown that a new key is available and ask the user 
whether to use the new key or stick to the old one\. As go\-sendxmpp is usually 
used in scripts it just accepts the new key to prevent the user from missing a 
new notification due to changed keys\.
 .TP
 \fB\-\-ox\-delete\-nodes\fR
 Delete existing OpenPGP nodes on the server\.
@@ -165,7 +165,7 @@
 .fi
 .IP "" 0
 .P
-If go\-sendxmpp is run as root it will drop the root privileges before 
connecting to the server\. This means \fBFAST\fR and \fBOX\fR will be disabled 
as go\-sendxmpp will not have the necessary rights to store the necessary data 
(e\.g\. FAST tokes or OX key material) after dropping the privileges\. This is 
just to avoid network connections as root and doesn't mean that running as root 
as a supported use case, in fact it is highly recommended to never run 
go\-sendxmpp as root\.
+If go\-sendxmpp is run as root it will drop the root privileges before 
connecting to the server\. This means \fBFAST\fR and \fBOX\fR will be disabled 
as go\-sendxmpp will not have the necessary rights to store the necessary data 
(e\.g\. FAST tokens or OX key material) after dropping the privileges\. This is 
just to avoid network connections as root and doesn't mean that running as root 
as a supported use case, in fact it is highly recommended to never run 
go\-sendxmpp as root\.
 .SH "SHELL COMPLETIONS"
 .SS "ZSH"
 There are no shell completions yet (contributions welcome) but for zsh it is 
possible to automatically create completions from \fB\-\-help\fR which might 
work good enough\.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/man/go-sendxmpp.1.html 
new/go-sendxmpp-v0.16.0/man/go-sendxmpp.1.html
--- old/go-sendxmpp-v0.15.8/man/go-sendxmpp.1.html      2026-05-12 
19:59:13.000000000 +0200
+++ new/go-sendxmpp-v0.16.0/man/go-sendxmpp.1.html      2026-06-20 
09:54:34.000000000 +0200
@@ -134,6 +134,8 @@
 <dd>XMPP server address.</dd>
 <dt><code>--legacy-pgp</code></dt>
 <dd>"Legacy PGP" encryption using the Ox key infrastructure. This means the 
recipient must have an Ox key published and use the same key for legacy PGP.
+This encryption method is deprecated and will be removed in a future version, 
please consider switching to
+<em>OpenPGP for XMPP</em> (OX).
 The use of legacy PGP is actually discouraged and only provided as a 
workaround for conversations users.
 If the existing key has no ID in the form of 
<code>xmpp:[email protected]</code>, it can be added by using the tool 
<em>sq</em>:
 
@@ -149,7 +151,7 @@
 <code>-l</code>, <code>--listen</code>
 </dt>
 <dd>Listen for messages and print them to stdout. If JIDs are specified only 
messages from those contacts
-are shown. If no JIDs are specified all received messages will be shown.</dd>
+are shown. If no JIDs are specified or a chat room is joined all received 
messages will be shown.</dd>
 <dt>
 <code>-m</code>, <code>--message</code>=[<var>value</var>]</dt>
 <dd>Set file including the message.</dd>
@@ -167,8 +169,6 @@
 <dd>URL to send a file as out of band data.</dd>
 <dt><code>--ox</code></dt>
 <dd>Use "OpenPGP for XMPP" encryption (experimental).  <br>
-Ox in go-sendxmpp only supports sending encrypted 1-1 messages. Sending to 
groupchats and
-sending encrypted files is not supported.
 There is no check whether the recipients key is trusted as there is no local 
keyring used.
 Go-sendxmpp just uses the most recent key that is provided via pubsub and 
checks that it is not
 expired. As a user facing client a notification would be shown that a new key 
is available and
@@ -280,7 +280,7 @@
 
 <p>If go-sendxmpp is run as root it will drop the root privileges before 
connecting to the server.
 This means <strong>FAST</strong> and <strong>OX</strong> will be disabled as 
go-sendxmpp will not have the necessary rights to store
-the necessary data (e.g. FAST tokes or OX key material) after dropping the 
privileges.
+the necessary data (e.g. FAST tokens or OX key material) after dropping the 
privileges.
 This is just to avoid network connections as root and  doesn't mean that 
running as root as a supported use case,
 in fact it is highly recommended to never run go-sendxmpp as root.</p>
 
@@ -327,7 +327,7 @@
 
   <ol class='man-decor man-foot man foot'>
     <li class='tl'></li>
-    <li class='tc'>May 2026</li>
+    <li class='tc'>June 2026</li>
     <li class='tr'>go-sendxmpp(1)</li>
   </ol>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/man/go-sendxmpp.1.ronn 
new/go-sendxmpp-v0.16.0/man/go-sendxmpp.1.ronn
--- old/go-sendxmpp-v0.15.8/man/go-sendxmpp.1.ronn      2026-05-12 
19:59:13.000000000 +0200
+++ new/go-sendxmpp-v0.16.0/man/go-sendxmpp.1.ronn      2026-06-20 
09:54:34.000000000 +0200
@@ -59,6 +59,8 @@
 
 * `--legacy-pgp`:
 "Legacy PGP" encryption using the Ox key infrastructure. This means the 
recipient must have an Ox key published and use the same key for legacy PGP.
+This encryption method is deprecated and will be removed in a future version, 
please consider switching to
+*OpenPGP for XMPP* (OX).
 The use of legacy PGP is actually discouraged and only provided as a 
workaround for conversations users.
 If the existing key has no ID in the form of `xmpp:[email protected]`, it can 
be added by using the tool *sq*:
 
@@ -73,7 +75,7 @@
 
 * `-l`, `--listen`:
 Listen for messages and print them to stdout. If JIDs are specified only 
messages from those contacts
-are shown. If no JIDs are specified all received messages will be shown.
+are shown. If no JIDs are specified or a chat room is joined all received 
messages will be shown.
 
 * `-m`, `--message`=[<value>]:
 Set file including the message.
@@ -92,8 +94,6 @@
 
 * `--ox`:
 Use "OpenPGP for XMPP" encryption (experimental).    
-Ox in go-sendxmpp only supports sending encrypted 1-1 messages. Sending to 
groupchats and
-sending encrypted files is not supported.
 There is no check whether the recipients key is trusted as there is no local 
keyring used.
 Go-sendxmpp just uses the most recent key that is provided via pubsub and 
checks that it is not
 expired. As a user facing client a notification would be shown that a new key 
is available and
@@ -212,7 +212,7 @@
 
 If go-sendxmpp is run as root it will drop the root privileges before 
connecting to the server.
 This means **FAST** and **OX** will be disabled as go-sendxmpp will not have 
the necessary rights to store
-the necessary data (e.g. FAST tokes or OX key material) after dropping the 
privileges.
+the necessary data (e.g. FAST tokens or OX key material) after dropping the 
privileges.
 This is just to avoid network connections as root and  doesn't mean that 
running as root as a supported use case,
 in fact it is highly recommended to never run go-sendxmpp as root.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/man/go-sendxmpp.5 
new/go-sendxmpp-v0.16.0/man/go-sendxmpp.5
--- old/go-sendxmpp-v0.15.8/man/go-sendxmpp.5   2026-05-12 19:59:13.000000000 
+0200
+++ new/go-sendxmpp-v0.16.0/man/go-sendxmpp.5   2026-06-20 09:54:34.000000000 
+0200
@@ -35,7 +35,7 @@
 The client\-to\-server port of the XMPP server, e\.g\. \fB5222\fR\. Should not 
be necessary if the server is set up properly\.
 .TP
 \fBpassword\fR
-Your accounts password, e\.g\. \fBhunter2\fR (please, do not use 
\fBhunter2\fR)\. Use \fB"\fR if your password contains spaces, e\.g\. 
\fB"hunter 2"\fR (please, also do nut use \fBhunter 2\fR)\.
+Your accounts password, e\.g\. \fBhunter2\fR (please, do not use 
\fBhunter2\fR)\. Use \fB"\fR if your password contains spaces, e\.g\. 
\fB"hunter 2"\fR (please, also do not use \fBhunter 2\fR)\.
 .TP
 \fBeval_password\fR
 A command to retrieve the password from a password manager, e\.g\. \fBpass 
xmpp/user@example\.com\fR\.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/man/go-sendxmpp.5.html 
new/go-sendxmpp-v0.16.0/man/go-sendxmpp.5.html
--- old/go-sendxmpp-v0.15.8/man/go-sendxmpp.5.html      2026-05-12 
19:59:13.000000000 +0200
+++ new/go-sendxmpp-v0.16.0/man/go-sendxmpp.5.html      2026-06-20 
09:54:34.000000000 +0200
@@ -113,7 +113,7 @@
 Should not be necessary if the server is set up properly.</dd>
 <dt><code>password</code></dt>
 <dd>Your accounts password, e.g. <strong>hunter2</strong> (please, do not use 
<strong>hunter2</strong>).
-Use <code>"</code> if your password contains spaces, e.g. <strong>"hunter 
2"</strong> (please, also do nut use <strong>hunter 2</strong>).</dd>
+Use <code>"</code> if your password contains spaces, e.g. <strong>"hunter 
2"</strong> (please, also do not use <strong>hunter 2</strong>).</dd>
 <dt><code>eval_password</code></dt>
 <dd>A command to retrieve the password from a password manager, e.g. 
<strong>pass xmpp/[email protected]</strong>.</dd>
 <dt><code>alias</code></dt>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/man/go-sendxmpp.5.ronn 
new/go-sendxmpp-v0.16.0/man/go-sendxmpp.5.ronn
--- old/go-sendxmpp-v0.15.8/man/go-sendxmpp.5.ronn      2026-05-12 
19:59:13.000000000 +0200
+++ new/go-sendxmpp-v0.16.0/man/go-sendxmpp.5.ronn      2026-06-20 
09:54:34.000000000 +0200
@@ -40,7 +40,7 @@
 
 * `password`:
 Your accounts password, e.g. **hunter2** (please, do not use **hunter2**).
-Use `"` if your password contains spaces, e.g. **"hunter 2"** (please, also do 
nut use **hunter 2**).
+Use `"` if your password contains spaces, e.g. **"hunter 2"** (please, also do 
not use **hunter 2**).
 
 * `eval_password`:
 A command to retrieve the password from a password manager, e.g. **pass 
xmpp/[email protected]**.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/ox.go 
new/go-sendxmpp-v0.16.0/ox.go
--- old/go-sendxmpp-v0.15.8/ox.go       2026-05-12 19:59:13.000000000 +0200
+++ new/go-sendxmpp-v0.16.0/ox.go       2026-06-20 09:54:34.000000000 +0200
@@ -9,7 +9,6 @@
        "encoding/base64"
        "fmt"
        "io"
-       "log"
        "log/slog"
        "os"
        "runtime"
@@ -21,40 +20,14 @@
        "github.com/xmppo/go-xmpp"                 // BSD-3-Clause
 )
 
-func oxDeleteNodes(jid string, client *xmpp.Client, iqc chan xmpp.IQ) error {
-       nodeListRequest := etree.NewDocument()
-       nodeListRequest.WriteSettings.AttrSingleQuote = true
-       query := nodeListRequest.CreateElement("query")
-       query.CreateAttr("xmlns", nsDiscoItems)
-       nlr, err := nodeListRequest.WriteToString()
+func oxDeleteNodes(jid string, client *xmpp.Client, iqc chan xmpp.IQ, disc 
chan xmpp.DiscoItems) error {
+       discoItems, err := getDiscoItems(client, disc, jid)
        if err != nil {
                return fmt.Errorf("ox: delete nodes: failed to create node list 
request %w", err)
        }
-       slog.Info("ox: sending IQ to list pep nodes")
-       iqReply, err := sendIQ(client, iqc, jid, "get", nlr)
-       if err != nil {
-               return fmt.Errorf("ox: delete nodes: failure with node list 
request iq: %w", err)
-       }
        slog.Info("ox: parsing reply to IQ")
-       nodeListReply := etree.NewDocument()
-       err = nodeListReply.ReadFromBytes(iqReply.Query)
-       if err != nil {
-               return fmt.Errorf("ox: delete nodes: failed to read node list 
reply iq: %w", err)
-       }
-       query = nodeListReply.SelectElement("query")
-       if query == nil {
-               return fmt.Errorf("ox: error parsing iq reply")
-       }
-       items := query.SelectElements("item")
-       if items == nil {
-               return fmt.Errorf("ox: error parsing iq reply")
-       }
-       for _, item := range items {
-               node := item.SelectAttr("node")
-               if node == nil {
-                       continue
-               }
-               if !strings.Contains(node.Value, nsOx) {
+       for _, item := range discoItems.Items {
+               if !strings.Contains(item.Node, nsOx) {
                        continue
                }
                deleteNodeRequest := etree.NewDocument()
@@ -62,12 +35,12 @@
                pubsub := deleteNodeRequest.CreateElement("pubsub")
                pubsub.CreateAttr("xmlns", nsPubsubOwner)
                del := pubsub.CreateElement("delete")
-               del.CreateAttr("node", node.Value)
+               del.CreateAttr("node", item.Node)
                dnr, err := deleteNodeRequest.WriteToString()
                if err != nil {
                        continue
                }
-               slog.Info("ox: sending IQ to list pep nodes", "node", 
node.Value)
+               slog.Info("ox: sending IQ to list pep nodes", "node", item.Node)
                _, err = sendIQ(client, iqc, jid, "set", dnr)
                if err != nil {
                        continue
@@ -76,8 +49,11 @@
        return nil
 }
 
-func oxDecrypt(m xmpp.Chat, client *xmpp.Client, iqc chan xmpp.IQ, user 
string, oxPrivKey *crypto.Key) (string, time.Time, error) {
+func oxDecrypt(m xmpp.Chat, client *xmpp.Client, iqc chan xmpp.IQ, drc chan 
xmpp.DiscoResult,
+       user string, oxPrivKey *crypto.Key,
+) (string, time.Time, error) {
        var cryptMsgByte []byte
+       var senderKeyRing *crypto.KeyRing
        var err error
        sender := strings.Split(m.Remote, "/")[0]
        for _, r := range m.OtherElem {
@@ -95,9 +71,16 @@
                return strError, time.Now(), err
        }
        slog.Info("ox: decrypting: getting senders key", "sender", sender)
-       senderKeyRing, err := oxGetPublicKeyRing(client, iqc, sender)
-       if err != nil {
-               return strError, time.Now(), err
+       if m.Type == "groupchat" {
+               senderKeyRing, err = oxGetPublicKeyRingChatroom(client, iqc, 
drc, sender)
+               if err != nil {
+                       return strError, time.Now(), err
+               }
+       } else {
+               senderKeyRing, err = oxGetPublicKeyRing(client, iqc, sender)
+               if err != nil {
+                       return strError, time.Now(), err
+               }
        }
        slog.Info("ox: decrypting message")
        pgpDecrypt, err := crypto.PGP().Decryption().
@@ -137,7 +120,7 @@
        jidAttrib := strings.Split(jid.Value, "/")[0]
        slog.Info("ox: decrypting: comparing jid attribute with local user",
                "jid-attribute", jidAttrib, "user", user)
-       if jidAttrib != user {
+       if jidAttrib != user && m.Type != "groupchat" {
                return strError, time.Now(), fmt.Errorf("ox: encrypted for 
wrong user")
        }
        slog.Info("ox: decrypting: checking time element")
@@ -249,7 +232,7 @@
        err = oxStoreKey(location,
                base64.StdEncoding.EncodeToString(keySerialized))
        if err != nil {
-               log.Fatal(err)
+               return fmt.Errorf("ox: import privkey: failed to store private 
key: %w", err)
        }
        slog.Info("ox: importing private key: requesting public key ring")
        pubKeyRing, err := oxGetPublicKeyRing(client, iqc, jid)
@@ -451,12 +434,12 @@
 func oxGetPrivKey(jid string, passphrase string) (*crypto.Key, error) {
        dataFile, err := oxGetPrivKeyLoc(jid)
        if err != nil {
-               log.Fatal(err)
+               return nil, fmt.Errorf("ox: get privkey: failed to get private 
key location: %w", err)
        }
        slog.Info("ox: getting private key:", "file", dataFile)
        keyBuffer, err := readFile(dataFile)
        if err != nil {
-               log.Fatal(err)
+               return nil, fmt.Errorf("ox: get privkey: failed to read private 
key: %w", err)
        }
        keyString := keyBuffer.String()
        slog.Info("ox: getting private key: base64 decoding key")
@@ -473,7 +456,7 @@
                slog.Info("ox: getting private key: unlocking key", 
"passphrase", "REDACTED")
                key, err = key.Unlock([]byte(passphrase))
                if err != nil {
-                       log.Fatal("ox: couldn't unlock private key")
+                       return nil, fmt.Errorf("ox: failed to unlock private 
key: %w", err)
                }
        }
        isLocked, err := key.IsLocked()
@@ -481,7 +464,7 @@
                return nil, fmt.Errorf("ox: get privkey: failed to check 
whether private key is locked: %w", err)
        }
        if isLocked {
-               log.Fatal("ox: private key is locked")
+               return nil, fmt.Errorf("ox: get privkey: failed to unlock 
private key: %w", err)
        }
        slog.Info("ox: getting private  checking if key is expired")
        if key.IsExpired(time.Now().Unix()) {
@@ -549,7 +532,7 @@
        err = oxStoreKey(location,
                base64.StdEncoding.EncodeToString(keySerialized))
        if err != nil {
-               log.Fatal(err)
+               return fmt.Errorf("ox: generate privkey: failed store private 
key: %w", err)
        }
        slog.Info("ox: generating privkey: deriving public key")
        decodedPubKey, err := key.GetPublicKey()
@@ -652,11 +635,11 @@
        oxPubKeyListReqPsItems.CreateAttr("max_items", "1")
        opkl, err := oxPubKeyListReq.WriteToString()
        if err != nil {
-               log.Fatal(err)
+               return nil, fmt.Errorf("ox: %w", err)
        }
        oxPublicKeyList, err := sendIQ(client, iqc, recipient, "get", opkl)
        if err != nil {
-               log.Fatal(err)
+               return nil, fmt.Errorf("ox: %w", err)
        }
        if oxPublicKeyList.Type != strResult {
                return nil, fmt.Errorf("ox: error while requesting public 
openpgp keys for %s",
@@ -776,12 +759,12 @@
        return pubKeyRing, nil
 }
 
-func oxEncrypt(client *xmpp.Client, oxPrivKey *crypto.Key, recipient string, 
keyRing crypto.KeyRing, message string, subject string) (string, error) {
+func oxEncrypt(client *xmpp.Client, oxPrivKey *crypto.Key, recipient string, 
keyRing crypto.KeyRing, message string, subject string, groupchat bool) 
(string, error) {
        if message == "" {
                return "", nil
        }
        ownJid := strings.Split(client.JID(), "/")[0]
-       if recipient != ownJid {
+       if recipient != ownJid && !groupchat {
                opk, err := oxPrivKey.GetPublicKey()
                if err == nil {
                        ownKey, _ := crypto.NewKey(opk)
@@ -826,6 +809,9 @@
        omMessage := om.CreateElement("message")
        omMessage.CreateAttr("to", recipient)
        omMessage.CreateAttr("id", id)
+       if groupchat {
+               omMessage.CreateAttr("type", "groupchat")
+       }
        omMessageStore := omMessage.CreateElement("store")
        omMessageStore.CreateAttr("xmlns", nsHints)
        omMessageEme := omMessage.CreateElement("encryption")
@@ -846,3 +832,74 @@
 
        return oms, nil
 }
+
+func oxGetPublicKeyRingChatroom(client *xmpp.Client, iqc chan xmpp.IQ, drc 
chan xmpp.DiscoResult,
+       chatroom string,
+) (*crypto.KeyRing, error) {
+       keyRing, err := crypto.NewKeyRing(nil)
+       if err != nil {
+               return nil, err
+       }
+       discoResult, err := getDiscoInfo(client, drc, chatroom)
+       if err != nil {
+               return nil, fmt.Errorf("ox: %w", err)
+       }
+       nonAnon := false
+       for _, feature := range discoResult.Features {
+               if feature == "muc_nonanonymous" {
+                       nonAnon = true
+               }
+       }
+       if !nonAnon {
+               return nil, fmt.Errorf("ox: muc is not nonanonymous")
+       }
+       affiliations := [3]string{"admin", "owner", "member"}
+       for _, affiliation := range affiliations {
+               memberlistRequest := etree.NewDocument()
+               query := memberlistRequest.CreateElement("query")
+               query.CreateAttr("xmlns", nsMUCAdmin)
+               item := query.CreateElement("item")
+               item.CreateAttr("affiliation", affiliation)
+               mlr, err := memberlistRequest.WriteToString()
+               if err != nil {
+                       return nil, err
+               }
+               iqReply, err := sendIQ(client, iqc, chatroom, "get", mlr)
+               if err != nil {
+                       return nil, err
+               }
+               memberlist := etree.NewDocument()
+               err = memberlist.ReadFromBytes(iqReply.Query)
+               if err != nil {
+                       return nil, err
+               }
+               query = memberlist.SelectElement("query")
+               if query == nil {
+                       return nil, fmt.Errorf("ox: error during disco info 
query")
+               }
+               items := query.SelectElements("item")
+               if items == nil {
+                       continue
+               }
+               for _, item := range items {
+                       jid := item.SelectAttr("jid")
+                       if jid == nil {
+                               continue
+                       }
+                       memberKeyRing, err := oxGetPublicKeyRing(client, iqc, 
jid.Value)
+                       if err != nil {
+                               continue
+                       }
+                       for _, key := range memberKeyRing.GetKeys() {
+                               err = keyRing.AddKey(key)
+                               if err != nil {
+                                       continue
+                               }
+                       }
+               }
+       }
+       if keyRing == nil {
+               return nil, fmt.Errorf("ox: didn't receive public keys for muc 
members")
+       }
+       return keyRing, nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/go-sendxmpp-v0.15.8/stanzahandling.go 
new/go-sendxmpp-v0.16.0/stanzahandling.go
--- old/go-sendxmpp-v0.15.8/stanzahandling.go   2026-05-12 19:59:13.000000000 
+0200
+++ new/go-sendxmpp-v0.16.0/stanzahandling.go   2026-06-20 09:54:34.000000000 
+0200
@@ -21,8 +21,10 @@
 
 func getDiscoInfo(client *xmpp.Client, drc chan xmpp.DiscoResult, target 
string) (dr xmpp.DiscoResult, err error) {
        id := getID()
-       c := make(chan xmpp.DiscoResult, defaultBufferSize)
-       go getDr(c, drc)
+       c := make(chan xmpp.DiscoResult, 1)
+       ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
+       defer cancel()
+       go getDr(ctx, c, drc)
        slog.Info("stanzahandling: requesting disco info")
        _, err = client.RawInformation(client.JID(), target, id, "get",
                fmt.Sprintf("<query xmlns='%s'/>", nsDiscoInfo))
@@ -32,25 +34,31 @@
        select {
        case dr = <-c:
                slog.Info("stanzahandling: requesting disco info: received 
reply")
-       case <-time.After(60 * time.Second):
+       case <-ctx.Done():
                slog.Info("stanzahandling: requesting disco info: timeout")
                return dr, fmt.Errorf("get disco info: %s didn't reply to disco 
info request", target)
        }
        return dr, err
 }
 
-func getDr(c chan xmpp.DiscoResult, drc chan xmpp.DiscoResult) {
+func getDr(ctx context.Context, c chan xmpp.DiscoResult, drc chan 
xmpp.DiscoResult) {
        for {
-               dr := <-drc
-               c <- dr
-               return
+               select {
+               case <-ctx.Done():
+                       return
+               case dr := <-drc:
+                       c <- dr
+                       return
+               }
        }
 }
 
 func getSlot(client *xmpp.Client, slc chan xmpp.Slot, target, request string) 
(sl xmpp.Slot, err error) {
        id := getID()
-       c := make(chan xmpp.Slot, defaultBufferSize)
-       go getSl(c, slc)
+       c := make(chan xmpp.Slot, 1)
+       ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
+       defer cancel()
+       go getSl(ctx, c, slc)
        slog.Info("stanzahandling: requesting upload slot")
        _, err = client.RawInformation(client.JID(), target, id, "get", request)
        if err != nil {
@@ -59,25 +67,31 @@
        select {
        case sl = <-c:
                slog.Info("stanzahandling: requesting upload slot: received 
reply")
-       case <-time.After(60 * time.Second):
+       case <-ctx.Done():
                slog.Info("stanzahandling: requesting upload slot: timeout")
                return sl, fmt.Errorf("get upload slot: %s didn't reply to 
upload slot request", target)
        }
        return sl, err
 }
 
-func getSl(c chan xmpp.Slot, slc chan xmpp.Slot) {
+func getSl(ctx context.Context, c chan xmpp.Slot, slc chan xmpp.Slot) {
        for {
-               sl := <-slc
-               c <- sl
-               return
+               select {
+               case sl := <-slc:
+                       c <- sl
+                       return
+               case <-ctx.Done():
+                       return
+               }
        }
 }
 
 func getDiscoItems(client *xmpp.Client, disc chan xmpp.DiscoItems, target 
string) (dis xmpp.DiscoItems, err error) {
        id := getID()
-       c := make(chan xmpp.DiscoItems, defaultBufferSize)
-       go getDis(target, c, disc)
+       c := make(chan xmpp.DiscoItems, 1)
+       ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
+       defer cancel()
+       go getDis(ctx, target, id, c, disc)
        slog.Info("stanzahandling: requesting disco items")
        _, err = client.RawInformation(client.JID(), target, id, "get",
                fmt.Sprintf("<query xmlns='%s'/>", nsDiscoItems))
@@ -87,19 +101,22 @@
        select {
        case dis = <-c:
                slog.Info("stanzahandling: requesting disco items: received 
reply")
-       case <-time.After(60 * time.Second):
+       case <-ctx.Done():
                slog.Info("stanzahandling: requesting disco items: timeout")
                return dis, fmt.Errorf("get disco items: %s didn't reply to 
disco items request", target)
        }
        return dis, err
 }
 
-func getDis(jid string, c chan xmpp.DiscoItems, disc chan xmpp.DiscoItems) {
+func getDis(ctx context.Context, jid string, id string, c chan 
xmpp.DiscoItems, disc chan xmpp.DiscoItems) {
        for {
-               dis := <-disc
-               if dis.Jid == jid {
-                       c <- dis
-                       return
+               select {
+               case dis := <-disc:
+                       if dis.Jid == jid && id == dis.ID {
+                               c <- dis
+                               return
+                       }
+               case <-ctx.Done():
                }
        }
 }
@@ -107,8 +124,10 @@
 func sendIQ(client *xmpp.Client, iqc chan xmpp.IQ, target string, iQtype 
string, content string) (xmpp.IQ, error) {
        var iq xmpp.IQ
        id := getID()
-       c := make(chan xmpp.IQ, defaultBufferSize)
-       go getIQ(id, c, iqc)
+       c := make(chan xmpp.IQ, 1)
+       ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
+       defer cancel()
+       go getIQ(ctx, id, c, iqc)
        _, err := client.RawInformation(client.JID(), target, id,
                iQtype, content)
        if err != nil {
@@ -116,17 +135,21 @@
        }
        select {
        case iq = <-c:
-       case <-time.After(60 * time.Second):
+       case <-ctx.Done():
                return iq, fmt.Errorf("send iq: server didn't reply to IQ: %s", 
content)
        }
        return iq, nil
 }
 
-func getIQ(id string, c chan xmpp.IQ, iqc chan xmpp.IQ) {
+func getIQ(ctx context.Context, id string, c chan xmpp.IQ, iqc chan xmpp.IQ) {
        for {
-               iq := <-iqc
-               if iq.ID == id {
-                       c <- iq
+               select {
+               case iq := <-iqc:
+                       if iq.ID == id {
+                               c <- iq
+                               return
+                       }
+               case <-ctx.Done():
                        return
                }
        }

++++++ vendor.tar.zst ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/xmppo/go-xmpp/const.go 
new/vendor/github.com/xmppo/go-xmpp/const.go
--- old/vendor/github.com/xmppo/go-xmpp/const.go        2026-05-12 
19:59:13.000000000 +0200
+++ new/vendor/github.com/xmppo/go-xmpp/const.go        2026-06-20 
09:54:34.000000000 +0200
@@ -2,7 +2,7 @@
 
 const (
        // Version is current go-xmpp software version.
-       Version = "0.3.4"
+       Version = "0.3.6"
 
        // HT_SHA_256_ENDP used in XEP-0484: Fast Authentication Streamlining 
Tokens, https://xmpp.org/extensions/xep-0484.html
        HT_SHA_256_ENDP = "HT-SHA-256-ENDP"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/xmppo/go-xmpp/xmpp.go 
new/vendor/github.com/xmppo/go-xmpp/xmpp.go
--- old/vendor/github.com/xmppo/go-xmpp/xmpp.go 2026-05-12 19:59:13.000000000 
+0200
+++ new/vendor/github.com/xmppo/go-xmpp/xmpp.go 2026-06-20 09:54:34.000000000 
+0200
@@ -932,7 +932,7 @@
                                }
                                switch v := val.(type) {
                                case *streamFeatures:
-                                       // Update the max. stanza size limit if 
provided again as some servers might apply greater limit after auth.
+                                       // Update the max. stanza size and idle 
seconds limit if provided again as some servers might apply greater limit after 
auth.
                                        if v.Limits.MaxBytes != "" {
                                                lim, err := 
strconv.Atoi(v.Limits.MaxBytes)
                                                // Only overwrite if it can be 
parsed successfully, otherwise keep the previous limit.
@@ -940,6 +940,13 @@
                                                        c.LimitMaxBytes = lim
                                                }
                                        }
+                                       if v.Limits.IdleSeconds != "" {
+                                               lim, err := 
strconv.Atoi(v.Limits.IdleSeconds)
+                                               // Only overwrite if it can be 
parsed successfully, otherwise keep the previous limit.
+                                               if err == nil {
+                                                       c.LimitIdleSeconds = lim
+                                               }
+                                       }
                                }
                                if o.Session {
                                        // if server support session, open it
@@ -1227,7 +1234,7 @@
                        }
                        switch v := val.(type) {
                        case *streamFeatures:
-                               // Update the max. stanza size limit if 
provided again as some servers might apply greater limit after auth.
+                               // Update the max. stanza size and idle limits 
if provided again as some servers might apply greater limit after auth.
                                if v.Limits.MaxBytes != "" {
                                        lim, err := 
strconv.Atoi(v.Limits.MaxBytes)
                                        // Only overwrite if it can be parsed 
successfully, otherwise keep the previous limit.
@@ -1235,6 +1242,13 @@
                                                c.LimitMaxBytes = lim
                                        }
                                }
+                               if v.Limits.IdleSeconds != "" {
+                                       lim, err := 
strconv.Atoi(v.Limits.IdleSeconds)
+                                       // Only overwrite if it can be parsed 
successfully, otherwise keep the previous limit.
+                                       if err == nil {
+                                               c.LimitIdleSeconds = lim
+                                       }
+                               }
                        }
                case *saslSuccess:
                        if strings.HasPrefix(mechanism, "SCRAM-SHA") {
@@ -1281,7 +1295,7 @@
                        if f, err = c.startStream(o, domain); err != nil {
                                return err
                        }
-                       // Update the max. stanza size limit if provided again 
as some servers might apply greater limit after auth.
+                       // Update the max. stanza size and idle seconds limits 
if provided again as some servers might apply greater limit after auth.
                        if f.Limits.MaxBytes != "" {
                                lim, err := strconv.Atoi(f.Limits.MaxBytes)
                                // Only overwrite if it can be parsed 
successfully, otherwise keep the previous limit.
@@ -1289,6 +1303,13 @@
                                        c.LimitMaxBytes = lim
                                }
                        }
+                       if f.Limits.IdleSeconds != "" {
+                               lim, err := strconv.Atoi(f.Limits.IdleSeconds)
+                               // Only overwrite if it can be parsed 
successfully, otherwise keep the previous limit.
+                               if err == nil {
+                                       c.LimitIdleSeconds = lim
+                               }
+                       }
                }
                // Make the servers time limit after which it might consider 
the stream idle available.
                if f.Limits.IdleSeconds != "" {
@@ -1525,6 +1546,7 @@
        Affiliation string
        Role        string
        JID         string
+       Error       string
 }
 
 type IQ struct {
@@ -1615,6 +1637,7 @@
                                v.X.Item.Affiliation,
                                v.X.Item.Role,
                                v.X.Item.Jid,
+                               v.Error.Any.Local,
                        }, nil
                case *clientIQ:
                        switch {
@@ -1630,7 +1653,7 @@
                                        var osName string
 
                                        if c.Options.ReportSoftwareOS {
-                                               osName = 
(strings.SplitN(runtime.GOOS, "/", 2))[0]
+                                               osName = 
strings.SplitN(runtime.GOOS, "/", 2)[0]
                                        }
 
                                        id, err := c.IqVersionResponse(
@@ -1710,6 +1733,7 @@
                                        }
 
                                        return DiscoItems{
+                                               ID:    v.ID,
                                                Jid:   v.From,
                                                Items: 
clientDiscoItemsToReturn(itemsQuery.Items),
                                        }, nil
@@ -2289,7 +2313,11 @@
        Show     string `xml:"show"`   // away, chat, dnd, xa
        Status   string `xml:"status"` // sb []clientText
        Priority string `xml:"priority,attr"`
-       Error    *clientError
+       Error    struct {
+               By   string   `xml:"by,attr"`
+               Type string   `xml:"type,attr"`
+               Any  xml.Name `xml:",any"`
+       } `xml:"error"`
 }
 
 type clientIQ struct {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/github.com/xmppo/go-xmpp/xmpp_disco.go 
new/vendor/github.com/xmppo/go-xmpp/xmpp_disco.go
--- old/vendor/github.com/xmppo/go-xmpp/xmpp_disco.go   2026-05-12 
19:59:13.000000000 +0200
+++ new/vendor/github.com/xmppo/go-xmpp/xmpp_disco.go   2026-06-20 
09:54:34.000000000 +0200
@@ -68,6 +68,7 @@
 }
 
 type DiscoItems struct {
+       ID    string
        Jid   string
        Items []DiscoItem
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/crypto/blake2b/go125.go 
new/vendor/golang.org/x/crypto/blake2b/go125.go
--- old/vendor/golang.org/x/crypto/blake2b/go125.go     2026-05-12 
19:59:13.000000000 +0200
+++ new/vendor/golang.org/x/crypto/blake2b/go125.go     1970-01-01 
01:00:00.000000000 +0100
@@ -1,11 +0,0 @@
-// Copyright 2025 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.25
-
-package blake2b
-
-import "hash"
-
-var _ hash.XOF = (*xof)(nil)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu.go 
new/vendor/golang.org/x/sys/cpu/cpu.go
--- old/vendor/golang.org/x/sys/cpu/cpu.go      2026-05-12 19:59:13.000000000 
+0200
+++ new/vendor/golang.org/x/sys/cpu/cpu.go      2026-06-20 09:54:34.000000000 
+0200
@@ -152,13 +152,17 @@
 // The booleans in Loong64 contain the correspondingly named cpu feature bit.
 // The struct is padded to avoid false sharing.
 var Loong64 struct {
-       _         CacheLinePad
-       HasLSX    bool // support 128-bit vector extension
-       HasLASX   bool // support 256-bit vector extension
-       HasCRC32  bool // support CRC instruction
-       HasLAM_BH bool // support AM{SWAP/ADD}[_DB].{B/H} instruction
-       HasLAMCAS bool // support AMCAS[_DB].{B/H/W/D} instruction
-       _         CacheLinePad
+       _              CacheLinePad
+       HasLSX         bool // support 128-bit vector extension
+       HasLASX        bool // support 256-bit vector extension
+       HasCRC32       bool // support CRC instruction
+       HasLAMCAS      bool // support AMCAS[_DB].{B/H/W/D}
+       HasLAM_BH      bool // support AM{SWAP/ADD}[_DB].{B/H} instruction
+       HasLLACQ_SCREL bool // support LLACQ.{W/D}, SCREL.{W/D} instruction
+       HasSCQ         bool // support SC.Q instruction
+       HasDBAR_HINTS  bool // supports finer-grained DBAR hints
+
+       _ CacheLinePad
 }
 
 // MIPS64X contains the supported CPU features of the current mips64/mips64le
@@ -232,6 +236,7 @@
        HasZba            bool // Address generation instructions extension
        HasZbb            bool // Basic bit-manipulation extension
        HasZbs            bool // Single-bit instructions extension
+       HasZbc            bool // Carryless multiplication extension
        HasZvbb           bool // Vector Basic Bit-manipulation
        HasZvbc           bool // Vector Carryless Multiplication
        HasZvkb           bool // Vector Cryptography Bit-manipulation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go 
new/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go
--- old/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go        2026-05-12 
19:59:13.000000000 +0200
+++ new/vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go        2026-06-20 
09:54:34.000000000 +0200
@@ -58,6 +58,7 @@
        riscv_HWPROBE_EXT_ZBA         = 0x8
        riscv_HWPROBE_EXT_ZBB         = 0x10
        riscv_HWPROBE_EXT_ZBS         = 0x20
+       riscv_HWPROBE_EXT_ZBC         = 0x80
        riscv_HWPROBE_EXT_ZVBB        = 0x20000
        riscv_HWPROBE_EXT_ZVBC        = 0x40000
        riscv_HWPROBE_EXT_ZVKB        = 0x80000
@@ -108,6 +109,7 @@
                        RISCV64.HasZba = isSet(v, riscv_HWPROBE_EXT_ZBA)
                        RISCV64.HasZbb = isSet(v, riscv_HWPROBE_EXT_ZBB)
                        RISCV64.HasZbs = isSet(v, riscv_HWPROBE_EXT_ZBS)
+                       RISCV64.HasZbc = isSet(v, riscv_HWPROBE_EXT_ZBC)
                        RISCV64.HasZvbb = isSet(v, riscv_HWPROBE_EXT_ZVBB)
                        RISCV64.HasZvbc = isSet(v, riscv_HWPROBE_EXT_ZVBC)
                        RISCV64.HasZvkb = isSet(v, riscv_HWPROBE_EXT_ZVKB)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu_loong64.go 
new/vendor/golang.org/x/sys/cpu/cpu_loong64.go
--- old/vendor/golang.org/x/sys/cpu/cpu_loong64.go      2026-05-12 
19:59:13.000000000 +0200
+++ new/vendor/golang.org/x/sys/cpu/cpu_loong64.go      2026-06-20 
09:54:34.000000000 +0200
@@ -15,8 +15,13 @@
        cpucfg1_CRC32 = 1 << 25
 
        // CPUCFG2 bits
-       cpucfg2_LAM_BH = 1 << 27
-       cpucfg2_LAMCAS = 1 << 28
+       cpucfg2_LAM_BH      = 1 << 27
+       cpucfg2_LAMCAS      = 1 << 28
+       cpucfg2_LLACQ_SCREL = 1 << 29
+       cpucfg2_SCQ         = 1 << 30
+
+       // CPUCFG3 bits
+       cpucfg3_DBAR_HINTS = 1 << 17
 )
 
 func initOptions() {
@@ -26,6 +31,9 @@
                {Name: "crc32", Feature: &Loong64.HasCRC32},
                {Name: "lam_bh", Feature: &Loong64.HasLAM_BH},
                {Name: "lamcas", Feature: &Loong64.HasLAMCAS},
+               {Name: "llacq_screl", Feature: &Loong64.HasLLACQ_SCREL},
+               {Name: "scq", Feature: &Loong64.HasSCQ},
+               {Name: "dbar_hints", Feature: &Loong64.HasDBAR_HINTS},
        }
 
        // The CPUCFG data on Loong64 only reflects the hardware capabilities,
@@ -37,10 +45,14 @@
        // through CPUCFG
        cfg1 := get_cpucfg(1)
        cfg2 := get_cpucfg(2)
+       cfg3 := get_cpucfg(3)
 
        Loong64.HasCRC32 = cfgIsSet(cfg1, cpucfg1_CRC32)
        Loong64.HasLAMCAS = cfgIsSet(cfg2, cpucfg2_LAMCAS)
        Loong64.HasLAM_BH = cfgIsSet(cfg2, cpucfg2_LAM_BH)
+       Loong64.HasLLACQ_SCREL = cfgIsSet(cfg2, cpucfg2_LLACQ_SCREL)
+       Loong64.HasSCQ = cfgIsSet(cfg2, cpucfg2_SCQ)
+       Loong64.HasDBAR_HINTS = cfgIsSet(cfg3, cpucfg3_DBAR_HINTS)
 }
 
 func get_cpucfg(reg uint32) uint32
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/golang.org/x/sys/cpu/cpu_riscv64.go 
new/vendor/golang.org/x/sys/cpu/cpu_riscv64.go
--- old/vendor/golang.org/x/sys/cpu/cpu_riscv64.go      2026-05-12 
19:59:13.000000000 +0200
+++ new/vendor/golang.org/x/sys/cpu/cpu_riscv64.go      2026-06-20 
09:54:34.000000000 +0200
@@ -16,6 +16,7 @@
                {Name: "zba", Feature: &RISCV64.HasZba},
                {Name: "zbb", Feature: &RISCV64.HasZbb},
                {Name: "zbs", Feature: &RISCV64.HasZbs},
+               {Name: "zbc", Feature: &RISCV64.HasZbc},
                // RISC-V Cryptography Extensions
                {Name: "zvbb", Feature: &RISCV64.HasZvbb},
                {Name: "zvbc", Feature: &RISCV64.HasZvbc},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/vendor/modules.txt new/vendor/modules.txt
--- old/vendor/modules.txt      2026-05-12 19:59:13.000000000 +0200
+++ new/vendor/modules.txt      2026-06-20 09:54:34.000000000 +0200
@@ -63,10 +63,10 @@
 # github.com/pborman/getopt/v2 v2.1.0
 ## explicit; go 1.13
 github.com/pborman/getopt/v2
-# github.com/xmppo/go-xmpp v0.3.4
+# github.com/xmppo/go-xmpp v0.3.6
 ## explicit; go 1.25.0
 github.com/xmppo/go-xmpp
-# golang.org/x/crypto v0.51.0
+# golang.org/x/crypto v0.53.0
 ## explicit; go 1.25.0
 golang.org/x/crypto/argon2
 golang.org/x/crypto/blake2b
@@ -77,15 +77,15 @@
 golang.org/x/crypto/pbkdf2
 golang.org/x/crypto/scrypt
 golang.org/x/crypto/sha3
-# golang.org/x/net v0.54.0
+# golang.org/x/net v0.56.0
 ## explicit; go 1.25.0
 golang.org/x/net/idna
 golang.org/x/net/internal/socks
 golang.org/x/net/proxy
-# golang.org/x/sys v0.44.0
+# golang.org/x/sys v0.46.0
 ## explicit; go 1.25.0
 golang.org/x/sys/cpu
-# golang.org/x/text v0.37.0
+# golang.org/x/text v0.38.0
 ## explicit; go 1.25.0
 golang.org/x/text/secure/bidirule
 golang.org/x/text/transform

Reply via email to