From d575543fc40476c5dd2719ef4ae4c3522b86e18f Mon Sep 17 00:00:00 2001 From: ZNC-Jenkins Date: Mon, 16 Jun 2025 00:26:10 +0000 Subject: [PATCH 1/5] Update translations from Crowdin for bg_BG da_DK de_DE el_GR es_ES fr_FR id_ID it_IT nl_NL pl_PL pt_BR pt_PT ro_RO ru_RU tr_TR --- src/po/znc.bg_BG.po | 12 ++++++------ src/po/znc.da_DK.po | 12 ++++++------ src/po/znc.de_DE.po | 12 ++++++------ src/po/znc.el_GR.po | 12 ++++++------ src/po/znc.es_ES.po | 12 ++++++------ src/po/znc.fr_FR.po | 12 ++++++------ src/po/znc.id_ID.po | 12 ++++++------ src/po/znc.it_IT.po | 12 ++++++------ src/po/znc.nl_NL.po | 12 ++++++------ src/po/znc.pl_PL.po | 12 ++++++------ src/po/znc.pot | 12 ++++++------ src/po/znc.pt_BR.po | 12 ++++++------ src/po/znc.pt_PT.po | 12 ++++++------ src/po/znc.ro_RO.po | 12 ++++++------ src/po/znc.ru_RU.po | 12 ++++++------ src/po/znc.tr_TR.po | 12 ++++++------ 16 files changed, 96 insertions(+), 96 deletions(-) diff --git a/src/po/znc.bg_BG.po b/src/po/znc.bg_BG.po index d5a6a644..9bff99a9 100644 --- a/src/po/znc.bg_BG.po +++ b/src/po/znc.bg_BG.po @@ -54,28 +54,28 @@ msgstr "" "help” и “/msg *status loadmod <module>”). След " "като сте заредили някои уеб модули, менюто ще се разшири." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "Потребителят вече съществува" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL не е включен" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Не може да се намери pem файлът: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 не е включен" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Невалиден порт" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Не може да се върже порт: {1}" diff --git a/src/po/znc.da_DK.po b/src/po/znc.da_DK.po index 8f36b91e..97995a26 100644 --- a/src/po/znc.da_DK.po +++ b/src/po/znc.da_DK.po @@ -51,28 +51,28 @@ msgid "" "code>”). Once you have loaded some Web-enabled modules, the menu will expand." msgstr "" -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "Brugeren eksisterer allerede" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL er ikke aktiveret" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 er ikke aktiveret" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Ugyldig port" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "" diff --git a/src/po/znc.de_DE.po b/src/po/znc.de_DE.po index 038a95ea..bf1590e7 100644 --- a/src/po/znc.de_DE.po +++ b/src/po/znc.de_DE.po @@ -55,28 +55,28 @@ msgstr "" "code>\"). Sobald einige Web-fähige Module geladen wurden, wird das Menü " "größer." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "Benutzer existiert bereits" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL ist nicht aktiviert" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Kann PEM-Datei nicht finden: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 ist nicht aktiviert" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Ungültiger Port" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Kann nicht horchen: {1}" diff --git a/src/po/znc.el_GR.po b/src/po/znc.el_GR.po index aa689680..620aa253 100644 --- a/src/po/znc.el_GR.po +++ b/src/po/znc.el_GR.po @@ -51,28 +51,28 @@ msgid "" "code>”). Once you have loaded some Web-enabled modules, the menu will expand." msgstr "" -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "" diff --git a/src/po/znc.es_ES.po b/src/po/znc.es_ES.po index 4a40f9e1..f12dc46a 100644 --- a/src/po/znc.es_ES.po +++ b/src/po/znc.es_ES.po @@ -54,28 +54,28 @@ msgstr "" "*status help\" y \"/msg *status loadmod <módulo>\"). Una vez lo hayas hecho, el menú se expandirá." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "El usuario ya existe" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL no está habilitado" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "No se ha localizado el fichero pem: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 no está disponible" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Puerto no válido" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Imposible enlazar: {1}" diff --git a/src/po/znc.fr_FR.po b/src/po/znc.fr_FR.po index f6a94829..ec35ebb8 100644 --- a/src/po/znc.fr_FR.po +++ b/src/po/znc.fr_FR.po @@ -55,28 +55,28 @@ msgstr "" "loadmod <module>”). Les modules avec des capacités web " "apparaîtront ci-dessous." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "Cet utilisateur existe déjà" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL n'est pas activé" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Impossible de trouver le fichier pem : {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 n'est pas activé" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Port invalide" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Impossible d'utiliser le port : {1}" diff --git a/src/po/znc.id_ID.po b/src/po/znc.id_ID.po index 22574bc4..9c07c676 100644 --- a/src/po/znc.id_ID.po +++ b/src/po/znc.id_ID.po @@ -55,28 +55,28 @@ msgstr "" "code>\"). Setelah anda memuat beberapa modul Web-enabled, menu ini akan " "diperluas." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "Pengguna sudah ada" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL tidak diaktifkan" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Tidak dapat menemukan berkas pem: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 tidak diaktifkan" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Port tidak valid" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Tidak dapat mengikat: {1}" diff --git a/src/po/znc.it_IT.po b/src/po/znc.it_IT.po index c969bca7..984b9218 100644 --- a/src/po/znc.it_IT.po +++ b/src/po/znc.it_IT.po @@ -55,28 +55,28 @@ msgstr "" "loadmod <nome del modulo>”). Dopo aver caricato alcuni moduli " "abilitati per il web, il menù si espanderà." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "Utente già esistente" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL non è abilitata" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Impossibile localizzare il file pem: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 non è abilitato" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Porta non valida" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Impossibile associare: {1}" diff --git a/src/po/znc.nl_NL.po b/src/po/znc.nl_NL.po index 905c43a2..acd6fd54 100644 --- a/src/po/znc.nl_NL.po +++ b/src/po/znc.nl_NL.po @@ -54,28 +54,28 @@ msgstr "" "msg *status help” en “/msg *status loadmod <module>”). Zodra je deze geladen hebt zal dit menu zich uitbreiden." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "Gebruiker bestaat al" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL is niet ingeschakeld" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Kan PEM bestand niet vinden: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 is niet ingeschakeld" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Ongeldige poort" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Kan niet binden: {1}" diff --git a/src/po/znc.pl_PL.po b/src/po/znc.pl_PL.po index e2287727..0d37658b 100644 --- a/src/po/znc.pl_PL.po +++ b/src/po/znc.pl_PL.po @@ -56,28 +56,28 @@ msgstr "" "msg *status help” i “/msg *status loadmod <moduł>”). Jak już załadujesz jakieś moduły WWW to menu się rozwinie." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "Użytkownik już istnieje" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL nie jest włączone" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Nie udało się odnaleźć pliku pem: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 nie jest włączone" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Nieprawidłowy port" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Nie udało się przypiąć: {1}" diff --git a/src/po/znc.pot b/src/po/znc.pot index 0c8c4017..a858ee5b 100644 --- a/src/po/znc.pot +++ b/src/po/znc.pot @@ -42,28 +42,28 @@ msgid "" "code>”). Once you have loaded some Web-enabled modules, the menu will expand." msgstr "" -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "" diff --git a/src/po/znc.pt_BR.po b/src/po/znc.pt_BR.po index 7e630e69..63db8a17 100644 --- a/src/po/znc.pt_BR.po +++ b/src/po/znc.pt_BR.po @@ -55,28 +55,28 @@ msgstr "" "module>”). Depois de carregar alguns módulos habilitados para a " "Web, o menu será expandido." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "O usuário já existe" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "O SSL não está habilitado" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Falha ao localizar o arquivo PEM: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "O IPv6 não está habilitado" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Porta inválida" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Não foi possível vincular: {1}" diff --git a/src/po/znc.pt_PT.po b/src/po/znc.pt_PT.po index 2f2ef2d4..5bb4d5be 100644 --- a/src/po/znc.pt_PT.po +++ b/src/po/znc.pt_PT.po @@ -55,28 +55,28 @@ msgstr "" "módulo>”). Após ter carregado algum módulo capaz de usar a Web, o " "menu irá expandir-se." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "O utilizador já existe" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "O SSL não está ativado" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Não foi possível localizar o ficheiro pen: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "O IPv6 não está ativado" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Porta inválida" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Não foi possível usar a porta: {1}" diff --git a/src/po/znc.ro_RO.po b/src/po/znc.ro_RO.po index 97f521aa..7ce11e86 100644 --- a/src/po/znc.ro_RO.po +++ b/src/po/znc.ro_RO.po @@ -52,28 +52,28 @@ msgid "" "code>”). Once you have loaded some Web-enabled modules, the menu will expand." msgstr "" -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "Utilizatorul există deja" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL nu este activat" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Imposibil de localizat fișierul pem: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 nu este activat" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Port invalid" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Imposibil de legat: {1}" diff --git a/src/po/znc.ru_RU.po b/src/po/znc.ru_RU.po index 2fc7fa3d..92c2de48 100644 --- a/src/po/znc.ru_RU.po +++ b/src/po/znc.ru_RU.po @@ -57,28 +57,28 @@ msgstr "" "модуль>»). Когда такие модули будут загружены, они будут доступны " "в меню сбоку." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "Такой пользователь уже есть" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL не включён" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Не могу найти файл pem: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 не включён" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Некорректный порт" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Не получилось слушать: {1}" diff --git a/src/po/znc.tr_TR.po b/src/po/znc.tr_TR.po index 8ab1b9dc..baf9b65a 100644 --- a/src/po/znc.tr_TR.po +++ b/src/po/znc.tr_TR.po @@ -54,28 +54,28 @@ msgstr "" "msg *status help” ve “/msg *status loadmod <module>”). Bazı Web özellikli modülleri yükledikten sonra menü genişleyecektir." -#: znc.cpp:1570 +#: znc.cpp:1577 msgid "User already exists" msgstr "Kullanıcı zaten var" -#: znc.cpp:1666 +#: znc.cpp:1673 msgid "SSL is not enabled" msgstr "SSL etkin değil" -#: znc.cpp:1674 +#: znc.cpp:1681 #, c++-format msgid "Unable to locate pem file: {1}" msgstr "Pem dosyası bulunamıyor: {1}" -#: znc.cpp:1719 +#: znc.cpp:1726 msgid "IPv6 is not enabled" msgstr "IPv6 etkin değil" -#: znc.cpp:1728 +#: znc.cpp:1735 msgid "Invalid port" msgstr "Geçersiz port" -#: znc.cpp:1869 ClientCommand.cpp:1754 +#: znc.cpp:1876 ClientCommand.cpp:1754 #, c++-format msgid "Unable to bind: {1}" msgstr "Bağlanamıyor: {1}" From 7eaa3048b383a1d2cfd28d13c31c1e3d91727e06 Mon Sep 17 00:00:00 2001 From: ZNC-Jenkins Date: Tue, 17 Jun 2025 00:26:07 +0000 Subject: [PATCH 2/5] Update translations from Crowdin for tr_TR --- modules/po/cert.tr_TR.po | 2 +- modules/po/clientnotify.tr_TR.po | 2 +- modules/po/controlpanel.tr_TR.po | 4 +- modules/po/log.tr_TR.po | 26 +++++------ modules/po/route_replies.tr_TR.po | 2 +- modules/po/saslplainauth.tr_TR.po | 2 + modules/po/webadmin.tr_TR.po | 73 ++++++++++++++++--------------- src/po/znc.tr_TR.po | 14 +++--- 8 files changed, 65 insertions(+), 60 deletions(-) diff --git a/modules/po/cert.tr_TR.po b/modules/po/cert.tr_TR.po index ba86508c..ad3bfeae 100644 --- a/modules/po/cert.tr_TR.po +++ b/modules/po/cert.tr_TR.po @@ -65,7 +65,7 @@ msgstr "Sertifikanız yok. Sertifika eklemek için lütfen web arayüzünü kull #: cert.cpp:44 #, c++-format msgid "Alternatively you can place one at {1}" -msgstr "" +msgstr "Alternatif olarak {1}'e de bir tane yerleştirebilirsiniz" #: cert.cpp:52 msgid "Delete the current certificate" diff --git a/modules/po/clientnotify.tr_TR.po b/modules/po/clientnotify.tr_TR.po index 9086c421..cbe1b285 100644 --- a/modules/po/clientnotify.tr_TR.po +++ b/modules/po/clientnotify.tr_TR.po @@ -70,7 +70,7 @@ msgstr "Kullanımı: Method " #: clientnotify.cpp:153 clientnotify.cpp:166 clientnotify.cpp:179 #: clientnotify.cpp:192 clientnotify.cpp:205 msgid "Saved." -msgstr "Kaydedildi" +msgstr "Kaydedildi." #: clientnotify.cpp:160 msgid "Usage: NewOnly " diff --git a/modules/po/controlpanel.tr_TR.po b/modules/po/controlpanel.tr_TR.po index 158eb732..ab58b2fd 100644 --- a/modules/po/controlpanel.tr_TR.po +++ b/modules/po/controlpanel.tr_TR.po @@ -394,11 +394,11 @@ msgstr "Kullanımı: AddServer [[+]port] [şif #: controlpanel.cpp:1254 msgid "Or: AddServer unix:[ssl:]/path/to/socket" -msgstr "" +msgstr "Ya da: AddServer unix:[ssl:]/path/to/socket" #: controlpanel.cpp:1256 msgid "+ means SSL" -msgstr "" +msgstr "+ SSL anlamına gelir" #: controlpanel.cpp:1280 #, c++-format diff --git a/modules/po/log.tr_TR.po b/modules/po/log.tr_TR.po index 1e19d56c..fdb60e3e 100644 --- a/modules/po/log.tr_TR.po +++ b/modules/po/log.tr_TR.po @@ -20,7 +20,7 @@ msgstr "" msgid "Set logging rules, use !#chan or !query to negate and * " msgstr "" "Günlük kurallarını belirleyin, terse çevirmek/reddetmek için !#kanal veya !" -"sorgu ve * kullanın" +"sorgu ve * kullanın " #: log.cpp:62 msgid "Clear all logging rules" @@ -82,27 +82,27 @@ msgstr "" #: log.cpp:197 msgid "Will log joins" -msgstr "joins (kanala girişler) günlüğe kaydedilecek" +msgstr "Kanala girişler (joins) günlüğe kaydedilecek" #: log.cpp:197 msgid "Will not log joins" -msgstr "joins (kanala girişler) günlüğe kaydedilmeyecek" +msgstr "Kanala girişler (joins) günlüğe kaydedilmeyecek" #: log.cpp:198 msgid "Will log quits" -msgstr "quits (IRC çıkışları) günlüğe kaydedilecek" +msgstr "IRC çıkışları (quits) günlüğe kaydedilecek" #: log.cpp:198 msgid "Will not log quits" -msgstr "quits (IRC çıkışları) günlüğe kaydedilmeyecek" +msgstr "IRC çıkışları (quits) günlüğe kaydedilmeyecek" #: log.cpp:200 msgid "Will log nick changes" -msgstr "nickchanges (nick değişiklikleri) günlüğe kaydedilecek" +msgstr "Rumuz değişiklikleri (nickchanges) günlüğe kaydedilecek" #: log.cpp:200 msgid "Will not log nick changes" -msgstr "nickchanges (nick değişiklikleri) günlüğe kaydedilmeyecek" +msgstr "Rumuz değişiklikleri (nickchanges) günlüğe kaydedilmeyecek" #: log.cpp:204 msgid "Unknown variable. Known variables: joins, quits, nickchanges" @@ -112,27 +112,27 @@ msgstr "" #: log.cpp:212 msgid "Logging joins" -msgstr "joins (kanala girişler) günlüğe kaydediliyor" +msgstr "Kanala girişler (joins) günlüğe kaydediliyor" #: log.cpp:212 msgid "Not logging joins" -msgstr "joins (kanala girişler) günlüğe kaydedilmiyor" +msgstr "Kanala girişler (joins) günlüğe kaydedilmiyor" #: log.cpp:213 msgid "Logging quits" -msgstr "quits (IRC çıkışları) günlüğe kaydediliyor" +msgstr "IRC çıkışları (quits) günlüğe kaydediliyor" #: log.cpp:213 msgid "Not logging quits" -msgstr "quits (IRC çıkışları) günlüğe kaydedilmiyor" +msgstr "IRC çıkışları (quits) günlüğe kaydedilmiyor" #: log.cpp:214 msgid "Logging nick changes" -msgstr "nickchanges (nick değişiklikleri) günlüğe kaydediliyor" +msgstr "Rumuz değişiklikleri (nickchanges) günlüğe kaydediliyor" #: log.cpp:215 msgid "Not logging nick changes" -msgstr "nickchanges (nick değişiklikleri) günlüğe kaydedilmiyor" +msgstr "Rumuz değişiklikleri (nickchanges) günlüğe kaydedilmiyor" #: log.cpp:352 #, c++-format diff --git a/modules/po/route_replies.tr_TR.po b/modules/po/route_replies.tr_TR.po index c036d86b..b2dc4188 100644 --- a/modules/po/route_replies.tr_TR.po +++ b/modules/po/route_replies.tr_TR.po @@ -31,7 +31,7 @@ msgid "" "a bug." msgstr "" "Ancak, bu sorunu yeniden oluşturmak için gerekli adımları sağlayabilirseniz, " -"lütfen bir hata raporlayın" +"lütfen bir hata raporlayın." #: route_replies.cpp:381 #, c++-format diff --git a/modules/po/saslplainauth.tr_TR.po b/modules/po/saslplainauth.tr_TR.po index f7a004f5..0db7fa04 100644 --- a/modules/po/saslplainauth.tr_TR.po +++ b/modules/po/saslplainauth.tr_TR.po @@ -15,3 +15,5 @@ msgstr "" #: saslplainauth.cpp:55 msgid "Allows users to authenticate via the PLAIN SASL mechanism." msgstr "" +"Kullanıcıların PLAIN SASL mekanizması aracılığıyla kimlik doğrulaması " +"yapmasına olanak tanır." diff --git a/modules/po/webadmin.tr_TR.po b/modules/po/webadmin.tr_TR.po index ac97e7a1..34f73b86 100644 --- a/modules/po/webadmin.tr_TR.po +++ b/modules/po/webadmin.tr_TR.po @@ -36,7 +36,7 @@ msgstr "Varsa kanalın şifresi." #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:258 #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:277 msgid "Buffer size:" -msgstr "" +msgstr "Arabellek boyutu:" #: modules/po/../data/webadmin/tmpl/add_edit_chan.tmpl:32 msgid "The buffer count." @@ -45,7 +45,7 @@ msgstr "Ara bellek sayısı." #: modules/po/../data/webadmin/tmpl/add_edit_chan.tmpl:36 #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:252 msgid "Default modes:" -msgstr "" +msgstr "Varsayılan modlar:" #: modules/po/../data/webadmin/tmpl/add_edit_chan.tmpl:38 msgid "The default modes of the channel." @@ -171,7 +171,7 @@ msgstr "Bind Host:" #: modules/po/../data/webadmin/tmpl/add_edit_network.tmpl:71 #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:117 msgid "Quit message:" -msgstr "" +msgstr "Çıkış mesajı:" #: modules/po/../data/webadmin/tmpl/add_edit_network.tmpl:73 #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:119 @@ -456,7 +456,7 @@ msgstr "Lütfen yukarıdaki şifreyi tekrar yazın." #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:48 #: modules/po/../data/webadmin/tmpl/settings.tmpl:173 msgid "Auth only via module:" -msgstr "" +msgstr "Yalnızca modül aracılığıyla kimlik doğrulama:" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:50 msgid "" @@ -497,7 +497,7 @@ msgstr "Ident, kullanıcı adı olarak sunucuya gönderilir." #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:90 #: modules/po/../data/webadmin/tmpl/settings.tmpl:124 msgid "Status prefix:" -msgstr "" +msgstr "Durum öneki:" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:92 #: modules/po/../data/webadmin/tmpl/settings.tmpl:126 @@ -581,7 +581,7 @@ msgstr "Sorgular" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:272 msgid "Max buffers:" -msgstr "" +msgstr "Maks arabellek:" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:274 msgid "Maximum number of query buffers. 0 is unlimited." @@ -609,7 +609,7 @@ msgstr "" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:307 msgid "Timestamp format:" -msgstr "" +msgstr "Zaman damgası formatı:" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:309 msgid "" @@ -640,7 +640,7 @@ msgstr "İstemci kodlaması:" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:329 msgid "Join tries:" -msgstr "" +msgstr "Giriş denemeleri:" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:331 msgid "" @@ -679,7 +679,7 @@ msgstr "" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:344 msgid "Max IRC networks number:" -msgstr "" +msgstr "Maksimum IRC ağ sayısı:" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:346 msgid "Maximum number of IRC networks allowed for this user." @@ -692,7 +692,7 @@ msgstr "Yedekler" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:351 #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:359 msgid "CTCP replies:" -msgstr "" +msgstr "CTCP yanıtları:" #: modules/po/../data/webadmin/tmpl/add_edit_user.tmpl:355 msgid "One reply per line. Example: TIME Buy a watch!" @@ -887,7 +887,7 @@ msgstr "Yalnızca yeni kullanıcılar için varsayılandır." #: modules/po/../data/webadmin/tmpl/settings.tmpl:132 msgid "Maximum buffer size:" -msgstr "" +msgstr "Maksimum arabellek boyutu:" #: modules/po/../data/webadmin/tmpl/settings.tmpl:134 msgid "Sets the global Max Buffer Size a user can have." @@ -896,7 +896,7 @@ msgstr "" #: modules/po/../data/webadmin/tmpl/settings.tmpl:139 msgid "Connect delay:" -msgstr "" +msgstr "Bağlantı gecikmesi:" #: modules/po/../data/webadmin/tmpl/settings.tmpl:141 msgid "" @@ -910,7 +910,7 @@ msgstr "" #: modules/po/../data/webadmin/tmpl/settings.tmpl:146 msgid "Server throttle:" -msgstr "" +msgstr "Sunucu kısıtı:" #: modules/po/../data/webadmin/tmpl/settings.tmpl:148 msgid "" @@ -923,7 +923,7 @@ msgstr "" #: modules/po/../data/webadmin/tmpl/settings.tmpl:153 msgid "Anonymous connection limit per IP:" -msgstr "" +msgstr "IP başına anonim bağlantı limiti:" #: modules/po/../data/webadmin/tmpl/settings.tmpl:155 msgid "Limits the number of unidentified connections per IP." @@ -931,15 +931,15 @@ msgstr "IP başına tanımlanamayan bağlantı sayısını sınırlar." #: modules/po/../data/webadmin/tmpl/settings.tmpl:160 msgid "Protect web sessions:" -msgstr "" +msgstr "Web oturumları koruması:" #: modules/po/../data/webadmin/tmpl/settings.tmpl:162 msgid "Disallow IP changing during each web session" -msgstr "Her web oturumu sırasında IP değişimine izin verme!" +msgstr "Her web oturumu sırasında IP değişimine izin verme" #: modules/po/../data/webadmin/tmpl/settings.tmpl:167 msgid "Hide ZNC version:" -msgstr "" +msgstr "ZNC sürümünügizle:" #: modules/po/../data/webadmin/tmpl/settings.tmpl:169 msgid "Hide version number from non-ZNC users" @@ -975,24 +975,24 @@ msgstr "Çalışma Süresi" #: modules/po/../data/webadmin/tmpl/traffic.tmpl:18 msgid "Total users" -msgstr "" +msgstr "Toplam kullanıcı" #: modules/po/../data/webadmin/tmpl/traffic.tmpl:22 msgid "Total networks" -msgstr "" +msgstr "Toplam ağ" #: modules/po/../data/webadmin/tmpl/traffic.tmpl:26 #: modules/po/../data/webadmin/tmpl/traffic.tmpl:43 msgid "Attached networks" -msgstr "" +msgstr "Ekli ağlar" #: modules/po/../data/webadmin/tmpl/traffic.tmpl:30 msgid "Total client connections" -msgstr "" +msgstr "Toplam istemci bağlantıları" #: modules/po/../data/webadmin/tmpl/traffic.tmpl:34 msgid "Total IRC connections" -msgstr "" +msgstr "Toplam IRC bağlantıları" #: modules/po/../data/webadmin/tmpl/traffic.tmpl:47 msgid "Client Connections" @@ -1128,11 +1128,11 @@ msgstr "Kanal Ekle" #: webadmin.cpp:719 webadmin.cpp:1564 msgid "Auto clear chan buffer" -msgstr "" +msgstr "Kanal arabelleğini otomatik temizle" #: webadmin.cpp:721 msgid "Automatically clear channel buffer after playback" -msgstr "" +msgstr "Kanal arabelleğini oynatmadan sonra otomatik olarak temizle" #: webadmin.cpp:729 msgid "Detached" @@ -1221,18 +1221,20 @@ msgid "" "Automatically clear channel buffer after playback (the default value for new " "channels)" msgstr "" +"Kanal arabelleğini oynatmadan sonra otomatik olarak temizle (yeni kanallar " +"için varsayılan değer)" #: webadmin.cpp:1576 msgid "Allow multiple clients" -msgstr "" +msgstr "Çoklu istemcilere izin ver" #: webadmin.cpp:1583 msgid "Append timestamps" -msgstr "" +msgstr "Zaman damgalarını ekle" #: webadmin.cpp:1590 msgid "Prepend timestamps" -msgstr "" +msgstr "Zaman damgalarını başına ekle" #: webadmin.cpp:1598 msgid "Deny LoadMod" @@ -1244,15 +1246,15 @@ msgstr "Yönetici (Tehlikeli! Shell erişimi sağlayabilir)" #: webadmin.cpp:1615 msgid "Deny setting BindHost" -msgstr "" +msgstr "BindHost ayarlamayı reddet" #: webadmin.cpp:1622 msgid "Deny setting Ident" -msgstr "" +msgstr "Ident ayarlamayı reddet" #: webadmin.cpp:1629 msgid "Deny editing networks/servers" -msgstr "" +msgstr "Ağları/sunucuları ayarlamayı reddet" #: webadmin.cpp:1631 msgid "" @@ -1264,27 +1266,28 @@ msgstr "" #: webadmin.cpp:1638 msgid "Deny setting RealName" -msgstr "" +msgstr "Gerçek adı ayarlamayı reddet" #: webadmin.cpp:1645 msgid "Deny setting quit message" -msgstr "" +msgstr "Çıkış mesajını ayarlamayı reddet" #: webadmin.cpp:1652 msgid "Deny setting CTCP replies" -msgstr "" +msgstr "CTCP yanıtlarını ayarlamayı reddet" #: webadmin.cpp:1654 msgid "Block customizing CTCP replies for non-admin users" msgstr "" +"Yönetici olmayan kullanıcıalar için CTCP yanıtlarını özelleştirmeyi engelle" #: webadmin.cpp:1662 msgid "Auto clear query buffer" -msgstr "" +msgstr "Sorgu arabelleğini otomatik temizleme" #: webadmin.cpp:1664 msgid "Automatically clear query buffer after playback" -msgstr "" +msgstr "Sorgu arabelleğini oynatmadan sonra otomatik olarak temizle" #: webadmin.cpp:1688 #, c++-format diff --git a/src/po/znc.tr_TR.po b/src/po/znc.tr_TR.po index baf9b65a..c975993a 100644 --- a/src/po/znc.tr_TR.po +++ b/src/po/znc.tr_TR.po @@ -161,7 +161,7 @@ msgstr "Çıktınız: {1}" #: IRCSock.cpp:1394 #, c++-format msgid "Warning: flood protection is delaying your messages by {1} seconds" -msgstr "" +msgstr "Uyarı: Flood koruması mesajlarınızı {1} saniye geciktiriyor" #: IRCSock.cpp:1452 msgid "Disconnected from IRC. Reconnecting..." @@ -175,7 +175,7 @@ msgstr "IRC'ye ({1}) bağlanılamıyor. Yeniden deneniyor..." #: IRCSock.cpp:1486 #, c++-format msgid "Disconnected from IRC ({1}). Reconnecting..." -msgstr "IRC'den bağlantı kesildi. Yeniden bağlanılıyor..." +msgstr "IRC ({1})'den bağlantı kesildi. Yeniden bağlanılıyor..." #: IRCSock.cpp:1522 #, c++-format @@ -989,11 +989,11 @@ msgstr "Kullanımı: AddServer [[+]port] [şifre]" #: ClientCommand.cpp:831 msgid "Or: AddServer unix:[ssl:]/path/to/socket" -msgstr "" +msgstr "Ya da: AddServer unix:[ssl:]/path/to/socket" #: ClientCommand.cpp:833 ClientCommand.cpp:1766 msgid "+ means SSL" -msgstr "" +msgstr "+ SSL anlamına gelir" #: ClientCommand.cpp:844 msgid "Server added" @@ -1068,7 +1068,7 @@ msgstr "Kanal" #: ClientCommand.cpp:969 ClientCommand.cpp:975 msgctxt "topicscmd" msgid "Set By" -msgstr "Ayarla:" +msgstr "Ayarlayan" #: ClientCommand.cpp:970 ClientCommand.cpp:976 msgctxt "topicscmd" @@ -1528,7 +1528,7 @@ msgstr "" #: ClientCommand.cpp:1768 msgid "Or: AddPort unix:[ssl:]/path/to/socket [uriprefix]" -msgstr "" +msgstr "Ya da: AddPort unix:[ssl:]/path/to/socket [uriprefix]" #: ClientCommand.cpp:1789 msgid "Deleted Port" @@ -1544,7 +1544,7 @@ msgstr "Kullanımı: DelPort [bindhost]" #: ClientCommand.cpp:1795 msgid "Or: DelPort unix:/path/to/socket" -msgstr "" +msgstr "Ya da: DelPort unix:/path/to/socket" #: ClientCommand.cpp:1802 ClientCommand.cpp:1817 msgctxt "helpcmd" From 7b7f6912131d02b032e3c5f01ea6fd4ba567f7e9 Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Mon, 23 Jun 2025 22:41:08 +0100 Subject: [PATCH 3/5] Don't store "this" in static variable Fix #1960 This could also cause use-after-free if the first connected socket disconnects --- src/IRCSock.cpp | 30 ++++++++++++++++++------------ test/integration/tests/core.cpp | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/IRCSock.cpp b/src/IRCSock.cpp index 37f3b9d5..b9ce227c 100644 --- a/src/IRCSock.cpp +++ b/src/IRCSock.cpp @@ -408,22 +408,28 @@ bool CIRCSock::OnCapabilityMessage(CMessage& Message) { sArgs = Message.GetParam(2); } - static std::map> mSupportedCaps = { - {"multi-prefix", [this](bool bVal) { m_bNamesx = bVal; }}, - {"userhost-in-names", [this](bool bVal) { m_bUHNames = bVal; }}, - {"cap-notify", [](bool bVal) {}}, - {"invite-notify", [](bool bVal) {}}, - {"server-time", [this](bool bVal) { m_bServerTime = bVal; }}, - {"znc.in/server-time-iso", [this](bool bVal) { m_bServerTime = bVal; }}, - {"chghost", [](bool) {}}, - {"message-tags", [this](bool bVal) { m_bMessageTagCap = bVal; }}, - }; + static std::map> + mSupportedCaps = { + {"multi-prefix", + [](CIRCSock* pSock, bool bVal) { pSock->m_bNamesx = bVal; }}, + {"userhost-in-names", + [](CIRCSock* pSock, bool bVal) { pSock->m_bUHNames = bVal; }}, + {"cap-notify", [](CIRCSock* pSock, bool bVal) {}}, + {"invite-notify", [](CIRCSock* pSock, bool bVal) {}}, + {"server-time", + [](CIRCSock* pSock, bool bVal) { pSock->m_bServerTime = bVal; }}, + {"znc.in/server-time-iso", + [](CIRCSock* pSock, bool bVal) { pSock->m_bServerTime = bVal; }}, + {"chghost", [](CIRCSock* pSock, bool) {}}, + {"message-tags", [](CIRCSock* pSock, + bool bVal) { pSock->m_bMessageTagCap = bVal; }}, + }; auto RemoveCap = [&](const CString& sCap) { IRCSOCKMODULECALL(OnServerCapResult(sCap, false), NOTHING); auto it = mSupportedCaps.find(sCap); if (it != mSupportedCaps.end()) { - it->second(false); + it->second(this, false); } m_ssAcceptedCaps.erase(sCap); m_ssPendingCaps.erase(sCap); @@ -457,7 +463,7 @@ bool CIRCSock::OnCapabilityMessage(CMessage& Message) { IRCSOCKMODULECALL(OnServerCapResult(sCap, true), NOTHING); auto it = mSupportedCaps.find(sCap); if (it != mSupportedCaps.end()) { - it->second(true); + it->second(this, true); } m_ssAcceptedCaps.insert(std::move(sCap)); } diff --git a/test/integration/tests/core.cpp b/test/integration/tests/core.cpp index 2bef8b67..9e1171d0 100644 --- a/test/integration/tests/core.cpp +++ b/test/integration/tests/core.cpp @@ -1191,5 +1191,24 @@ TEST_F(ZNCTest, JoinWhileRegistration) { ircd.ReadUntil("JOIN #foo"); } +TEST_F(ZNCTest, Issue1960) { + auto znc = Run(); + auto ircd1 = ConnectIRCd(); + auto client = LoginClient(); + ircd1.Write("CAP user ACK :message-tags"); + ircd1.Write(":server 001 nick :Hello"); + ircd1.Write(":server 005 nick blahblah"); + client.ReadUntil("blahblah"); + client.Write("znc addnetwork second"); + client.Write("znc jumpnetwork second"); + client.Write("znc addserver unix:" + m_dir.path().toUtf8() + "/inttest.ircd"); + auto ircd2 = ConnectIRCd(); + ircd2.Write("CAP user ACK :message-tags"); + ircd2.Write(":server 001 nick :Hello"); + client.ReadUntil("Connected"); + client.Write("@foo TAGMSG #bar"); + ircd2.ReadUntil("@foo TAGMSG #bar"); +} + } // namespace } // namespace znc_inttest From 4b12c0dc3c5ab5efb140ff478989daee47e1c7fa Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Mon, 23 Jun 2025 22:52:34 +0100 Subject: [PATCH 4/5] Fix nullptr dereference If client sends TAGMSG while server is not connected --- src/Client.cpp | 2 +- test/integration/tests/core.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Client.cpp b/src/Client.cpp index b3753e28..4da46f34 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -1657,7 +1657,7 @@ bool CClient::OnTagMessage(CTargetMessage& Message) { if (m_pNetwork) { AddBuffer(Message); EchoMessage(Message); - if (GetIRCSock()->HasMessageTagCap()) { + if (GetIRCSock() && GetIRCSock()->HasMessageTagCap()) { PutIRCStripping(Message); } } diff --git a/test/integration/tests/core.cpp b/test/integration/tests/core.cpp index 9e1171d0..0a56ba72 100644 --- a/test/integration/tests/core.cpp +++ b/test/integration/tests/core.cpp @@ -1210,5 +1210,16 @@ TEST_F(ZNCTest, Issue1960) { ircd2.ReadUntil("@foo TAGMSG #bar"); } +TEST_F(ZNCTest, DisconnectedTagmsgCrash) { + auto znc = Run(); + auto ircd = ConnectIRCd(); + auto client = LoginClient(); + client.Write("znc disconnect"); + client.ReadUntil("Disconnected"); + client.Write("@foo TAGMSG #foo"); + client.Write("znc help"); + client.ReadUntil("AddServer"); +} + } // namespace } // namespace znc_inttest From c46bd41037279255f553469fea3aa50700b38b51 Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Tue, 24 Jun 2025 09:04:29 +0100 Subject: [PATCH 5/5] Unix listener: chmod and change group Fix #1955 --- include/znc/Listener.h | 8 +- include/znc/znc.h | 5 +- modules/data/webadmin/tmpl/settings.tmpl | 64 +++++++++++--- modules/webadmin.cpp | 6 +- src/ClientCommand.cpp | 107 +++++++++++++++-------- src/Listener.cpp | 91 ++++++++++++++++++- src/znc.cpp | 16 +++- 7 files changed, 237 insertions(+), 60 deletions(-) diff --git a/include/znc/Listener.h b/include/znc/Listener.h index 383547a2..dcb0fc9d 100644 --- a/include/znc/Listener.h +++ b/include/znc/Listener.h @@ -97,9 +97,7 @@ class CTCPListener : public CListener { class CUnixListener : public CListener { public: CUnixListener(const CString& sPath, const CString& sURIPrefix, bool bSSL, - EAcceptType eAccept) - : CListener(sURIPrefix, bSSL, eAccept), - m_sPath(sPath) {} + EAcceptType eAccept, const CString& sGid, const CString& sMode); ~CUnixListener(); CUnixListener(const CUnixListener&) = delete; @@ -107,6 +105,8 @@ class CUnixListener : public CListener { // Getters const CString& GetPath() const { return m_sPath; } + const CString& GetGroup() const { return m_sGid; } + CString GetMode() const; // !Getters bool Listen() override; @@ -114,6 +114,8 @@ class CUnixListener : public CListener { protected: CString m_sPath; + CString m_sGid; + int m_iMode; }; class CRealListener : public CZNCSock { diff --git a/include/znc/znc.h b/include/znc/znc.h index 1365d518..6e7f0f95 100644 --- a/include/znc/znc.h +++ b/include/znc/znc.h @@ -209,8 +209,9 @@ class CZNC : private CCoreTranslationMixin { bool AddTCPListener(unsigned short uPort, const CString& sBindHost, const CString& sURIPrefix, bool bSSL, EAddrType eAddr, CListener::EAcceptType eAccept, CString& sError); - bool AddUnixListener(const CString& sPath, const CString& sURIPrefix, bool bSSL, - CListener::EAcceptType eAccept, CString& sError); + bool AddUnixListener(const CString& sPath, const CString& sURIPrefix, + bool bSSL, CListener::EAcceptType eAccept, + const CString& sGroup, const CString& sMode, CString& sError); bool DelListener(CListener*); // For backwards-compatibility TODO: Remove diff --git a/modules/data/webadmin/tmpl/settings.tmpl b/modules/data/webadmin/tmpl/settings.tmpl index 4822cd7d..1443dd96 100644 --- a/modules/data/webadmin/tmpl/settings.tmpl +++ b/modules/data/webadmin/tmpl/settings.tmpl @@ -21,10 +21,9 @@ - - + + - @@ -33,9 +32,6 @@
checked="checked"/>
- - unix: -
checked="checked"/>
@@ -51,14 +47,10 @@
- - - - "/>
@@ -66,7 +58,8 @@ - + +
@@ -82,11 +75,58 @@ "/>
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index feacc452..0b724138 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -1910,8 +1910,10 @@ class CWebAdminMod : public CModule { eAddr, eAccept, sMessage); } else { CString sPath = WebSock.GetParam("path"); + CString sMode = WebSock.GetParam("mode"); + CString sGroup = WebSock.GetParam("group"); bResult = CZNC::Get().AddUnixListener(sPath, sURIPrefix, bSSL, - eAccept, sMessage); + eAccept, sGroup, sMode, sMessage); } if (bResult) { @@ -2030,6 +2032,8 @@ class CWebAdminMod : public CModule { dynamic_cast(pListener)) { l["Type"] = "Unix"; l["Path"] = pUnixListener->GetPath(); + l["Mode"] = pUnixListener->GetMode(); + l["Group"] = pUnixListener->GetGroup(); // We can't determine whether it's the same port, as it's // always "localhost". Just assume the user knows what he's // doing. Unix sockets are advanced topic anyway. diff --git a/src/ClientCommand.cpp b/src/ClientCommand.cpp index 8ccbd963..b372d5db 100644 --- a/src/ClientCommand.cpp +++ b/src/ClientCommand.cpp @@ -1641,29 +1641,39 @@ void CClient::UserPortCommand(CString& sLine) { const CString sCommand = sLine.Token(0); if (sCommand.Equals("LISTPORTS")) { - CTable Table; - Table.AddColumn(t_s("Port", "listports")); - Table.AddColumn(t_s("BindHost", "listports")); - Table.AddColumn(t_s("SSL", "listports")); - Table.AddColumn(t_s("Protocol", "listports")); - Table.AddColumn(t_s("IRC", "listports")); - Table.AddColumn(t_s("Web", "listports")); + CTable TableT; + TableT.AddColumn(t_s("Port", "listports")); + TableT.AddColumn(t_s("BindHost", "listports")); + TableT.AddColumn(t_s("Protocol", "listports")); + TableT.AddColumn(t_s("SSL", "listports")); + TableT.AddColumn(t_s("IRC", "listports")); + TableT.AddColumn(t_s("Web", "listports")); + + CTable TableU; + TableU.AddColumn(t_s("Path", "listports")); + TableU.AddColumn(t_s("Mode", "listports")); + TableU.AddColumn(t_s("Group", "listports")); + TableU.AddColumn(t_s("SSL", "listports")); + TableU.AddColumn(t_s("IRC", "listports")); + TableU.AddColumn(t_s("Web", "listports")); const vector& vpListeners = CZNC::Get().GetListeners(); for (const CListener* pListener : vpListeners) { - Table.AddRow(); + CTable* pTable; if (const CTCPListener* pTCPListener = dynamic_cast(pListener)) { - Table.SetCell(t_s("Port", "listports"), - CString(pTCPListener->GetPort())); - Table.SetCell(t_s("BindHost", "listports"), - (pTCPListener->GetBindHost().empty() - ? CString("*") - : pTCPListener->GetBindHost())); + TableT.AddRow(); + pTable = &TableT; + TableT.SetCell(t_s("Port", "listports"), + CString(pTCPListener->GetPort())); + TableT.SetCell(t_s("BindHost", "listports"), + (pTCPListener->GetBindHost().empty() + ? CString("*") + : pTCPListener->GetBindHost())); EAddrType eAddr = pTCPListener->GetAddrType(); - Table.SetCell( + TableT.SetCell( t_s("Protocol", "listports"), eAddr == ADDR_ALL ? t_s("IPv4 and IPv6", "listports") @@ -1671,28 +1681,37 @@ void CClient::UserPortCommand(CString& sLine) { : t_s("IPv6", "listports"))); } else if (const CUnixListener* pUnixListener = dynamic_cast(pListener)) { - Table.SetCell(t_s("Port", "listports"), - pUnixListener->GetPath()); + TableU.AddRow(); + pTable = &TableU; + TableU.SetCell(t_s("Path", "listports"), + pUnixListener->GetPath()); + TableU.SetCell(t_s("Mode", "listports"), + pUnixListener->GetMode()); + TableU.SetCell(t_s("Group", "listports"), + pUnixListener->GetGroup()); + } else { + continue; } - Table.SetCell(t_s("SSL", "listports"), - pListener->IsSSL() ? t_s("yes", "listports|ssl") - : t_s("no", "listports|ssl")); + pTable->SetCell(t_s("SSL", "listports"), + pListener->IsSSL() ? t_s("yes", "listports|ssl") + : t_s("no", "listports|ssl")); CListener::EAcceptType eAccept = pListener->GetAcceptType(); - Table.SetCell(t_s("IRC", "listports"), - eAccept == CListener::ACCEPT_ALL || - eAccept == CListener::ACCEPT_IRC - ? t_s("yes", "listports|irc") - : t_s("no", "listports|irc")); - Table.SetCell(t_s("Web", "listports"), - eAccept == CListener::ACCEPT_ALL || - eAccept == CListener::ACCEPT_HTTP - ? t_f("yes, on {1}", "listports|irc")( - pListener->GetURIPrefix() + "/") - : t_s("no", "listports|web")); + pTable->SetCell(t_s("IRC", "listports"), + eAccept == CListener::ACCEPT_ALL || + eAccept == CListener::ACCEPT_IRC + ? t_s("yes", "listports|irc") + : t_s("no", "listports|irc")); + pTable->SetCell(t_s("Web", "listports"), + eAccept == CListener::ACCEPT_ALL || + eAccept == CListener::ACCEPT_HTTP + ? t_f("yes, on {1}", "listports|irc")( + pListener->GetURIPrefix() + "/") + : t_s("no", "listports|web")); } - PutStatus(Table); + PutStatus(TableT); + PutStatus(TableU); return; } @@ -1732,12 +1751,30 @@ void CClient::UserPortCommand(CString& sLine) { std::unique_ptr pListener; if (sPort.TrimPrefix("unix:")) { - bool bSSL = sPort.TrimPrefix("ssl:"); + bool bSSL = false; + CString sMode; + CString sGroup; + if (auto colon = sPort.find_first_of(':'); colon != std::string::npos) { + VCString vsOpts; + CString(sPort.substr(0, colon)).Split(",", vsOpts, false); + for (CString& sOpt : vsOpts) { + if (sOpt == "ssl") { + bSSL = true; + } else if (sOpt.TrimPrefix("mode=")) { + sMode = sOpt; + } else if (sOpt.TrimPrefix("group=")) { + sGroup = sOpt; + } else { + throw PortCommandUsage{}; + } + } + sPort = sPort.substr(colon + 1); + } const CString& sPath = sPort; CListener::EAcceptType eAccept = ParseEAccept(sLine.Token(2)); CString sURIPrefix = sLine.Token(3); - pListener.reset(new CUnixListener(sPath, sURIPrefix, bSSL, eAccept)); + pListener.reset(new CUnixListener(sPath, sURIPrefix, bSSL, eAccept, sGroup, sMode)); } else { bool bSSL = sPort.StartsWith("+"); EAddrType eAddr = ParseEAddr(sLine.Token(2)); @@ -1765,7 +1802,7 @@ void CClient::UserPortCommand(CString& sLine) { "[bindhost [uriprefix]]")); PutStatus(t_s("+ means SSL")); PutStatus( - t_s("Or: AddPort unix:[ssl:]/path/to/socket " + t_s("Or: AddPort unix:[ssl,mode=NNN,group=foo]:/path/to/socket " "[uriprefix]")); } } else if (sCommand.Equals("DELPORT")) { diff --git a/src/Listener.cpp b/src/Listener.cpp index bc763fbf..0b9dd187 100644 --- a/src/Listener.cpp +++ b/src/Listener.cpp @@ -14,6 +14,12 @@ * limitations under the License. */ +#include +#include +#include +#include +#include + #include #include #include @@ -85,9 +91,21 @@ CConfig CTCPListener::ToConfig() const { return listenerConfig; } -CUnixListener::~CUnixListener() { +CUnixListener::CUnixListener(const CString& sPath, const CString& sURIPrefix, + bool bSSL, EAcceptType eAccept, + const CString& sGid, const CString& sMode) + : CListener(sURIPrefix, bSSL, eAccept), + m_sPath(sPath), + m_sGid(sGid), + m_iMode(-1) { + if (!sMode.empty()) { + std::istringstream s(sMode); + s >> std::oct >> m_iMode; + } } +CUnixListener::~CUnixListener() {} + bool CUnixListener::Listen() { if (m_pListener) { errno = EINVAL; @@ -97,18 +115,85 @@ bool CUnixListener::Listen() { m_pListener = new CRealListener(*this); SetupSSL(); - return CZNC::Get().GetManager().ListenUnix("UNIX_LISTENER", m_sPath, - m_pListener); + if (!CZNC::Get().GetManager().ListenUnix("UNIX_LISTENER", m_sPath, + m_pListener)) + return false; + + if (!m_sGid.empty()) { + bool bSuccess = [&]() -> bool { + std::vector buffer(100); + group gr{}; + group* result; + retrysize: + int err = getgrnam_r(m_sGid.c_str(), &gr, buffer.data(), + buffer.size(), &result); + switch (err) { + case ERANGE: { + if (buffer.size() > 10000) { + DEBUG("Can't get gid due to memory size"); + return false; + } + buffer.resize(buffer.size() + 100); + goto retrysize; + } + case 0: { + if (!result) { + DEBUG("Group not found"); + return false; + } + if (chown(m_sPath.c_str(), -1, result->gr_gid)) { + char* e = strerror(errno); + DEBUG("Can't chmod: " << e); + return false; + } + break; + } + default: { + char* e = strerror(err); + DEBUG("Error while getting gid " << e); + return false; + } + } + return true; + }(); + if (!bSuccess) { + m_pListener->Close(); + return false; + } + } + + if (m_iMode != -1) { + if (chmod(m_sPath.c_str(), m_iMode)) { + char* e = strerror(errno); + DEBUG("Error while chmod " << e); + m_pListener->Close(); + return false; + } + } + + return true; } CConfig CUnixListener::ToConfig() const { CConfig listenerConfig = CListener::ToConfig(); listenerConfig.AddKeyValuePair("Path", GetPath()); + if (!m_sGid.empty()) listenerConfig.AddKeyValuePair("Group", m_sGid); + if (m_iMode != -1) { + listenerConfig.AddKeyValuePair("Mode", GetMode()); + } return listenerConfig; } +CString CUnixListener::GetMode() const { + std::ostringstream s; + if (m_iMode != -1) { + s << std::oct << m_iMode; + } + return s.str(); +} + void CListener::ResetRealListener() { m_pListener = nullptr; } CRealListener::~CRealListener() { m_Listener.ResetRealListener(); } diff --git a/src/znc.cpp b/src/znc.cpp index 2b2888a5..a0c9edc9 100644 --- a/src/znc.cpp +++ b/src/znc.cpp @@ -1744,13 +1744,16 @@ bool CZNC::AddTCPListener(unsigned short uPort, const CString& sBindHost, bool CZNC::AddUnixListener(const CString& sPath, const CString& sURIPrefix, bool bSSL, CListener::EAcceptType eAccept, - CString& sError) { - CUtils::PrintAction("Binding to path [" + sPath + "]" + (bSSL ? " with SSL" : "")); + const CString& sGroup, const CString& sMode, CString& sError) { + CUtils::PrintAction("Binding to path [" + sPath + "]" + + (bSSL ? " with SSL" : "") + + (sGroup.empty() ? CString() : " gid=" + sGroup) + + (sMode.empty() ? CString() : " mode=" + sMode)); if (!CheckSslAndPemFile(bSSL, sError)) return false; CListener* pListener = - new CUnixListener(sPath, sURIPrefix, bSSL, eAccept); + new CUnixListener(sPath, sURIPrefix, bSSL, eAccept, sGroup, sMode); return FinishAddingListener(pListener, sError); } @@ -1841,8 +1844,13 @@ bool CZNC::AddListener(CConfig* pConfig, CString& sError) { return AddTCPListener(uPort, sBindHost, sURIPrefix, bSSL, eAddr, eAccept, sError); + } else { + CString sGroup; + CString sMode; + pConfig->FindStringEntry("group", sGroup); + pConfig->FindStringEntry("mode", sMode); + return AddUnixListener(sPath, sURIPrefix, bSSL, eAccept, sGroup, sMode, sError); } - return AddUnixListener(sPath, sURIPrefix, bSSL, eAccept, sError); } bool CZNC::AddListener(CListener* pListener) {
unix: +
checked="checked"/>
+
+
checked="checked"/>
+
+
checked="checked"/>
+
+
+ + + + "/> +
+
unix:unix:"/>