diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE
index 8d1a5f259..d31eb5bb3 100644
--- a/.github/ISSUE_TEMPLATE
+++ b/.github/ISSUE_TEMPLATE
@@ -1,16 +1,15 @@
-Please answer these questions before submitting your issue. It may help !
-
-Thanks!
-
-1. What version of ejabberd are you using ?
+> What version of ejabberd are you using?
-2. What operating system are you using ?
+
+> What operating system (version) are you using?
-3. How did you install ejabberd (source, package, distribution) ?
+
+> How did you install ejabberd (source, package, distribution)?
-4. What did not work as expected ? What that error in the log ?
- What that unexpected behaviour ? What was the expected result ?
+
+> What did not work as expected? Are there error messages in the log? What
+> was the unexpected behavior? What was the expected result?
diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE
index 554cad4b6..643d025d0 100644
--- a/.github/PULL_REQUEST_TEMPLATE
+++ b/.github/PULL_REQUEST_TEMPLATE
@@ -1,23 +1,20 @@
-We are open to contribution for ejabberd, as Github pull requests (PR).
-Here is a few points to consider before submitting your pull request.
-(You can remove the whole text after reading).
+We are open to contributions for ejabberd, as GitHub pull requests (PR).
+Here are a few points to consider before submitting your PR. (You can
+remove the whole text after reading.)
-1. Does this PR address an issue ?
- Please reference it in PR description.
+1. Does this PR address an issue? Please reference it in the PR
+ description.
-2. Have you properly described the proposed changed ?
+2. Have you properly described the proposed change?
-3. Please, make sure the change is atomic and does only touch the
- needed modules.
- If you have other changes / fixes to provide, please make them as
- separate PR.
+3. Please make sure the change is atomic and does only touch the needed
+ modules. If you have other changes/fixes to provide, please submit
+ them as separate PRs.
-4. If you change or new feature involves backends,
- did you make sure you change is compliant with all backends or
- provide the feature for all backends ?
-
-5. Do you provides tests ?
- How can we check the behaviour of the code ?
+4. If your change or new feature involves storage backends, did you make
+ sure your change works with all backends?
-6. Did you consider documentation changes on project
- processone/docs.ejabberd.im ?
+5. Do you provide tests? How can we check the behavior of the code?
+
+6. Did you consider documentation changes in the
+ processone/docs.ejabberd.im repository?
diff --git a/.travis.yml b/.travis.yml
index 153631809..c5e0547e0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -44,7 +44,9 @@ script:
- make
- make install
- make xref
- - make test
+ - sed -i -e 's/ct:pal/ct:log/' test/suite.erl
+ - ln -sf ../sql priv/
+ - escript ./rebar skip_deps=true ct -v
- grep -q 'TEST COMPLETE, \([[:digit:]]*\) ok, .* of \1 ' logs/raw.log
after_script:
diff --git a/priv/msgs/gl.po b/priv/msgs/gl.po
index 7a8b27dcf..4d75d21da 100644
--- a/priv/msgs/gl.po
+++ b/priv/msgs/gl.po
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
-"Project-Id-Version: 2.1.0-alpha\n"
-"Last-Translator: Carlos E. Lopez - suso AT jabber-hispano.org\n"
+"Project-Id-Version: 16.02\n"
+"Last-Translator: Carlos E. Lopez - carlos AT suchat.org\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -9,7 +9,7 @@ msgstr ""
#: ejabberd_c2s.erl:505 ejabberd_c2s.erl:853
msgid "Use of STARTTLS required"
-msgstr "É obrigatorio usar STARTTLS"
+msgstr "Requírese o uso de STARTTLS"
#: ejabberd_c2s.erl:604
msgid "No resource provided"
@@ -26,11 +26,11 @@ msgstr "foi expulsado"
#: ejabberd_c2s.erl:2114
msgid "Your active privacy list has denied the routing of this stanza."
-msgstr ""
+msgstr "A súa lista de privacidade activa negou o encaminamiento desta estrofa."
#: ejabberd_c2s.erl:2429
msgid "Too many unacked stanzas"
-msgstr ""
+msgstr "Demasiadas mensaxes sen recoñecer recibilos"
#: ejabberd_captcha.erl:122 ejabberd_captcha.erl:245 ejabberd_captcha.erl:284
msgid "Enter the text you see"
@@ -43,11 +43,11 @@ msgstr ""
#: ejabberd_captcha.erl:192
msgid "If you don't see the CAPTCHA image here, visit the web page."
-msgstr ""
+msgstr "Si non ves a imaxe CAPTCHA aquí, visita a páxina web."
#: ejabberd_captcha.erl:227
msgid "CAPTCHA web page"
-msgstr ""
+msgstr "CAPTCHA páxina Web"
#: ejabberd_captcha.erl:381
msgid "The CAPTCHA is valid."
@@ -59,9 +59,8 @@ msgid "User"
msgstr "Usuario"
#: ejabberd_oauth.erl:256
-#, fuzzy
msgid "Server"
-msgstr "Servidor ~b"
+msgstr "Servidor"
#: ejabberd_oauth.erl:259 ejabberd_web_admin.erl:1408 mod_configure.erl:1398
#: mod_configure.erl:1485 mod_configure.erl:1889 mod_configure.erl:2123
@@ -71,7 +70,7 @@ msgstr "Contrasinal"
#: ejabberd_oauth.erl:267
msgid "Accept"
-msgstr ""
+msgstr "Aceptar"
#: ejabberd_web_admin.erl:202 ejabberd_web_admin.erl:214
#: ejabberd_web_admin.erl:234 ejabberd_web_admin.erl:246
@@ -238,7 +237,6 @@ msgid "Outgoing s2s Connections:"
msgstr "Conexións S2S saíntes:"
#: ejabberd_web_admin.erl:1559
-#, fuzzy
msgid "Incoming s2s Connections:"
msgstr "Conexións S2S saíntes:"
@@ -253,9 +251,8 @@ msgid "Change Password"
msgstr "Cambiar contrasinal"
#: ejabberd_web_admin.erl:1673
-#, fuzzy
msgid "User ~s"
-msgstr "Usuario "
+msgstr "Usuario ~s"
#: ejabberd_web_admin.erl:1684
msgid "Connected Resources:"
@@ -287,9 +284,8 @@ msgid "Stopped Nodes"
msgstr "Nodos detidos"
#: ejabberd_web_admin.erl:1833 ejabberd_web_admin.erl:1858
-#, fuzzy
msgid "Node ~p"
-msgstr "Nodo "
+msgstr "Nodo ~p"
#: ejabberd_web_admin.erl:1842 mod_configure.erl:150 mod_configure.erl:611
msgid "Database"
@@ -297,7 +293,7 @@ msgstr "Base de datos"
#: ejabberd_web_admin.erl:1843 mod_configure.erl:159 mod_configure.erl:648
msgid "Backup"
-msgstr "Gardar copia de seguridade"
+msgstr "Copia de seguridade"
#: ejabberd_web_admin.erl:1845
msgid "Listened Ports"
@@ -326,9 +322,8 @@ msgid "RPC Call Error"
msgstr "Erro na chamada RPC"
#: ejabberd_web_admin.erl:1917
-#, fuzzy
msgid "Database Tables at ~p"
-msgstr "Táboas da base de datos en "
+msgstr "Táboas da base de datos en ~p"
#: ejabberd_web_admin.erl:1927 mod_vcard.erl:490 mod_vcard.erl:616
msgid "Name"
@@ -336,7 +331,7 @@ msgstr "Nome"
#: ejabberd_web_admin.erl:1928
msgid "Storage Type"
-msgstr "Tipo de almacenamiento"
+msgstr "Tipo de almacenamento"
#: ejabberd_web_admin.erl:1929
msgid "Elements"
@@ -351,9 +346,8 @@ msgid "Error"
msgstr "Erro"
#: ejabberd_web_admin.erl:1955
-#, fuzzy
msgid "Backup of ~p"
-msgstr "Copia de seguridade de "
+msgstr "Copia de seguridade de ~p"
#: ejabberd_web_admin.erl:1959
msgid ""
@@ -387,7 +381,7 @@ msgid ""
"Restore binary backup after next ejabberd restart (requires less memory):"
msgstr ""
"Restaurar copia de seguridade binaria no seguinte reinicio de ejabberd "
-"(require menos memoria que se instantánea):"
+"(require menos memoria):"
#: ejabberd_web_admin.erl:1999
msgid "Store plain text backup:"
@@ -399,7 +393,7 @@ msgstr "Restaurar copias de seguridade de texto plano inmediatamente:"
#: ejabberd_web_admin.erl:2019
msgid "Import users data from a PIEFXIS file (XEP-0227):"
-msgstr "Importar usuarios desde un fichero PIEFXIS"
+msgstr "Importar usuarios en un fichero PIEFXIS (XEP-0227):"
#: ejabberd_web_admin.erl:2032
msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):"
@@ -409,17 +403,15 @@ msgstr ""
#: ejabberd_web_admin.erl:2044
msgid "Export data of users in a host to PIEFXIS files (XEP-0227):"
-msgstr ""
-"Exportar datos de todos os usuarios do servidor a ficheros PIEFXIS "
-"(XEP-0227):"
+msgstr "Exportar datos dos usuarios dun dominio a ficheiros PIEFXIS (XEP-0227):"
#: ejabberd_web_admin.erl:2060
msgid "Export all tables as SQL queries to a file:"
-msgstr ""
+msgstr "Exportar todas as táboas a un ficheiro SQL:"
#: ejabberd_web_admin.erl:2076
msgid "Import user data from jabberd14 spool file:"
-msgstr "Importar usuario de fichero spool de jabberd14:"
+msgstr "Importar usuario de ficheiro spool de jabberd14:"
#: ejabberd_web_admin.erl:2087
msgid "Import users data from jabberd14 spool directory:"
@@ -430,9 +422,8 @@ msgid "Listened Ports at "
msgstr "Portos de escoita en "
#: ejabberd_web_admin.erl:2144
-#, fuzzy
msgid "Modules at ~p"
-msgstr "Módulos en "
+msgstr "Módulos en ~p"
#: ejabberd_web_admin.erl:2175
msgid "Statistics of ~p"
@@ -463,9 +454,8 @@ msgid "Transactions Logged:"
msgstr "Transaccións rexistradas:"
#: ejabberd_web_admin.erl:2243
-#, fuzzy
msgid "Update ~p"
-msgstr "Actualizar"
+msgstr "Actualizar ~p"
#: ejabberd_web_admin.erl:2254
msgid "Update plan"
@@ -525,7 +515,7 @@ msgstr "Pong"
#: mod_announce.erl:523
msgid "Really delete message of the day?"
-msgstr "Está seguro de quere borrar a mensaxe do dia?"
+msgstr "¿Está seguro que quere borrar a mensaxe do dia?"
#: mod_announce.erl:536 mod_configure.erl:1238 mod_configure.erl:1298
msgid "Subject"
@@ -553,7 +543,7 @@ msgstr "Enviar anuncio a todos os usuarios en todos os dominios"
#: mod_announce.erl:668
msgid "Send announcement to all online users"
-msgstr "Enviar anuncio a todos los usuarios conectados"
+msgstr "Enviar anuncio a todos os usuarios conectados"
#: mod_announce.erl:670 mod_configure.erl:1231 mod_configure.erl:1291
msgid "Send announcement to all online users on all hosts"
@@ -595,7 +585,7 @@ msgstr "Iniciar módulos"
#: mod_configure.erl:156 mod_configure.erl:638
msgid "Stop Modules"
-msgstr "Detener módulos"
+msgstr "Deter módulos"
#: mod_configure.erl:162 mod_configure.erl:650
msgid "Restore"
@@ -844,18 +834,20 @@ msgid ""
"Too many (~p) failed authentications from this IP address (~s). The address "
"will be unblocked at ~s UTC"
msgstr ""
+"Demasiados (~p) fallou autenticaciones desde esta dirección IP (~s). A dirección "
+"será desbloqueada as ~s UTC"
#: mod_http_upload.erl:586
msgid "Please specify file size."
-msgstr ""
+msgstr "Por favor, especifica o tamaño do arquivo"
#: mod_http_upload.erl:590
msgid "Please specify file name."
-msgstr ""
+msgstr "Por favor, indique o nome do arquivo."
#: mod_ip_blacklist.erl:121
msgid "This IP address is blacklisted in ~s"
-msgstr ""
+msgstr "Esta dirección IP está na lista negra en ~s"
#: mod_irc.erl:220 mod_muc.erl:467
msgid "Access denied by service policy"
@@ -884,8 +876,8 @@ msgid ""
"Enter username, encodings, ports and passwords you wish to use for "
"connecting to IRC servers"
msgstr ""
-"Introduza o nome de usuario, codificaciones de carácter, portos e "
-"contrasinal que pretende utilizar a conectar a servidores de IRC"
+"Introduce o nome de usuario, codificaciones de carácteres, portos e "
+"contrasinai que queiras usar ao conectar nos servidores de IRC"
#: mod_irc.erl:667
msgid "IRC Username"
@@ -970,9 +962,8 @@ msgid "Server ~b"
msgstr "Servidor ~b"
#: mod_mam.erl:541
-#, fuzzy
msgid "Only members may query archives of this room"
-msgstr "Só os moderadores están autorizados a cambiar o tema nesta sala"
+msgstr "Só membros poden consultar o arquivo de mensaxes da sala"
#: mod_muc.erl:585
msgid "Only service administrators are allowed to send service messages"
@@ -994,10 +985,9 @@ msgstr "Salas de charla"
#: mod_muc.erl:781
msgid "Empty Rooms"
-msgstr ""
+msgstr "Salas baleiras"
#: mod_muc.erl:933
-#, fuzzy
msgid "You need a client that supports x:data to register the nickname"
msgstr ""
"Necesitas un cliente con soporte de x:data para poder rexistrar o alcume"
@@ -1030,34 +1020,31 @@ msgstr "Módulo de MUC para ejabberd"
#: mod_muc_admin.erl:231 mod_muc_admin.erl:234 mod_muc_admin.erl:246
#: mod_muc_admin.erl:320
msgid "Multi-User Chat"
-msgstr ""
+msgstr "Salas de Charla"
#: mod_muc_admin.erl:249
-#, fuzzy
msgid "Total rooms"
-msgstr "Salas de charla"
+msgstr "Salas totais"
#: mod_muc_admin.erl:250
-#, fuzzy
msgid "Permanent rooms"
-msgstr "sae da sala"
+msgstr "Salas permanentes"
#: mod_muc_admin.erl:251
-#, fuzzy
msgid "Registered nicknames"
-msgstr "Usuarios rexistrados"
+msgstr "Alcumes rexistrados"
#: mod_muc_admin.erl:254
msgid "List of rooms"
-msgstr ""
+msgstr "Lista de salas"
#: mod_muc_log.erl:398 mod_muc_log.erl:407
msgid "Chatroom configuration modified"
-msgstr "Configuración de la sala modificada"
+msgstr "Configuración da sala modificada"
#: mod_muc_log.erl:410
msgid "joins the room"
-msgstr "entra en la sala"
+msgstr "entra na sala"
#: mod_muc_log.erl:413 mod_muc_log.erl:416
msgid "leaves the room"
@@ -1077,7 +1064,7 @@ msgstr "foi expulsado, porque a sala cambiouse a só-membros"
#: mod_muc_log.erl:445
msgid "has been kicked because of a system shutdown"
-msgstr "foi expulsado por mor dun sistema de peche"
+msgstr "foi expulsado porque o sistema vaise a deter"
#: mod_muc_log.erl:450
msgid "is now known as"
@@ -1088,24 +1075,20 @@ msgid " has set the subject to: "
msgstr " puxo o asunto: "
#: mod_muc_log.erl:493
-#, fuzzy
msgid "Chatroom is created"
-msgstr "Salas de charla"
+msgstr "Creouse a sala"
#: mod_muc_log.erl:495
-#, fuzzy
msgid "Chatroom is destroyed"
-msgstr "Salas de charla"
+msgstr "Destruíuse a sala"
#: mod_muc_log.erl:497
-#, fuzzy
msgid "Chatroom is started"
-msgstr "Salas de charla"
+msgstr "Iniciouse a sala"
#: mod_muc_log.erl:499
-#, fuzzy
msgid "Chatroom is stopped"
-msgstr "Salas de charla"
+msgstr "Detívose a sala"
#: mod_muc_log.erl:503
msgid "Monday"
@@ -1200,6 +1183,8 @@ msgid ""
"It is not allowed to send error messages to the room. The participant (~s) "
"has sent an error message (~s) and got kicked from the room"
msgstr ""
+"Non está permitido enviar mensaxes de erro á sala. Este participante (~s) "
+"enviou unha mensaxe de erro (~s) e foi expulsado da sala"
#: mod_muc_room.erl:241
msgid "It is not allowed to send private messages to the conference"
@@ -1207,20 +1192,19 @@ msgstr "Impedir o envio de mensaxes privadas á sala"
#: mod_muc_room.erl:316
msgid "Please, wait for a while before sending new voice request"
-msgstr ""
+msgstr "Por favor, espera un pouco antes de enviar outra petición de voz"
#: mod_muc_room.erl:329
msgid "Voice requests are disabled in this conference"
-msgstr ""
+msgstr "As peticións de voz están desactivadas nesta sala"
#: mod_muc_room.erl:347
msgid "Failed to extract JID from your voice request approval"
-msgstr ""
+msgstr "Fallo ao extraer o Jabber ID da túa aprobación de petición de voz"
#: mod_muc_room.erl:377
-#, fuzzy
msgid "Only moderators can approve voice requests"
-msgstr "Permitir aos usuarios enviar invitacións"
+msgstr "Só os moderadores poden aprobar peticións de voz"
#: mod_muc_room.erl:389
msgid "Improper message type"
@@ -1269,11 +1253,11 @@ msgstr "Os visitantes non poden enviar mensaxes a todos os ocupantes"
#: mod_muc_room.erl:1080
msgid "Visitors are not allowed to change their nicknames in this room"
msgstr ""
-"Os visitantes non están autorizados a cambiar os seus That alcumes nesta sala"
+"Os visitantes non teñen permitido cambiar os seus alcumes nesta sala"
#: mod_muc_room.erl:1093 mod_muc_room.erl:1835
msgid "That nickname is already in use by another occupant"
-msgstr "Ese alcume que xa está en uso por outro ocupante"
+msgstr "Ese alcume xa está a ser usado por outro ocupante"
#: mod_muc_room.erl:1822
msgid "You have been banned from this room"
@@ -1289,12 +1273,11 @@ msgstr "Necesítase contrasinal para entrar nesta sala"
#: mod_muc_room.erl:1898 mod_register.erl:295
msgid "Too many CAPTCHA requests"
-msgstr ""
+msgstr "Demasiadas peticións de CAPTCHA"
#: mod_muc_room.erl:1908 mod_register.erl:301
-#, fuzzy
msgid "Unable to generate a CAPTCHA"
-msgstr "Non se pode xerar un CAPTCHA"
+msgstr "No se pudo generar un CAPTCHA"
#: mod_muc_room.erl:1919
msgid "Incorrect password"
@@ -1378,20 +1361,19 @@ msgstr "calquera"
#: mod_muc_room.erl:3471
msgid "Roles for which Presence is Broadcasted"
-msgstr ""
+msgstr "Roles para os que si se difunde a súa Presenza"
#: mod_muc_room.erl:3486
-#, fuzzy
msgid "Moderator"
-msgstr "só moderadores"
+msgstr "Moderator"
#: mod_muc_room.erl:3496
msgid "Participant"
-msgstr ""
+msgstr "Participante"
#: mod_muc_room.erl:3506
msgid "Visitor"
-msgstr ""
+msgstr "Visitante"
#: mod_muc_room.erl:3513
msgid "Make room members-only"
@@ -1414,13 +1396,12 @@ msgid "Allow users to send private messages"
msgstr "Permitir aos usuarios enviar mensaxes privadas"
#: mod_muc_room.erl:3533
-#, fuzzy
msgid "Allow visitors to send private messages to"
-msgstr "Permitir aos usuarios enviar mensaxes privadas"
+msgstr "Permitir aos visitantes enviar mensaxes privadas a"
#: mod_muc_room.erl:3551
msgid "nobody"
-msgstr ""
+msgstr "ninguén"
#: mod_muc_room.erl:3576
msgid "Allow users to query other users"
@@ -1440,13 +1421,12 @@ msgid "Allow visitors to change nickname"
msgstr "Permitir aos visitantes cambiarse o alcume"
#: mod_muc_room.erl:3589
-#, fuzzy
msgid "Allow visitors to send voice requests"
-msgstr "Permitir aos usuarios enviar invitacións"
+msgstr "Permitir aos visitantes enviar peticións de voz"
#: mod_muc_room.erl:3592
msgid "Minimum interval between voice requests (in seconds)"
-msgstr ""
+msgstr "Intervalo mínimo entre peticións de voz (en segundos)"
#: mod_muc_room.erl:3599
msgid "Make room CAPTCHA protected"
@@ -1454,11 +1434,11 @@ msgstr "Protexer a sala con CAPTCHA"
#: mod_muc_room.erl:3606
msgid "Enable message archiving"
-msgstr ""
+msgstr "Activar o almacenamento de mensaxes"
#: mod_muc_room.erl:3612
msgid "Exclude Jabber IDs from CAPTCHA challenge"
-msgstr ""
+msgstr "Excluír Jabber IDs das probas de CAPTCHA"
#: mod_muc_room.erl:3621
msgid "Enable logging"
@@ -1478,20 +1458,19 @@ msgstr "privado"
#: mod_muc_room.erl:4326
msgid "Voice request"
-msgstr ""
+msgstr "Petición de voz"
#: mod_muc_room.erl:4331
msgid "Either approve or decline the voice request."
-msgstr ""
+msgstr "Aproba ou rexeita a petición de voz."
#: mod_muc_room.erl:4351
-#, fuzzy
msgid "User JID"
-msgstr "Usuario "
+msgstr "Jabber ID do usuario"
#: mod_muc_room.erl:4355
msgid "Grant voice to this person?"
-msgstr ""
+msgstr "¿Conceder voz a esta persoa?"
#: mod_muc_room.erl:4498
msgid "~s invites you to the room ~s"
@@ -1503,11 +1482,11 @@ msgstr "a contrasinal é"
#: mod_multicast.erl:291
msgid "Multicast"
-msgstr ""
+msgstr "Multicast"
#: mod_multicast.erl:306
msgid "ejabberd Multicast service"
-msgstr ""
+msgstr "Servizo Multicast de ejabberd"
#: mod_offline.erl:647
msgid ""
@@ -1546,7 +1525,7 @@ msgstr "Borrar Todas as Mensaxes Sen conexión"
#: mod_proxy65_service.erl:248
msgid "ejabberd SOCKS5 Bytestreams module"
-msgstr "ejabberd SOCKS5 Bytestreams module"
+msgstr "Módulo SOCKS5 Bytestreams para ejabberd"
#: mod_pubsub.erl:1102
msgid "Publish-Subscribe"
@@ -1566,7 +1545,7 @@ msgstr "Decidir se aprobar a subscripción desta entidade."
#: mod_pubsub.erl:1559
msgid "Node ID"
-msgstr "Nodo IDE"
+msgstr "Nodo ID"
#: mod_pubsub.erl:1571
msgid "Subscriber Address"
@@ -1602,7 +1581,7 @@ msgstr "Persistir elementos ao almacenar"
#: mod_pubsub.erl:3757
msgid "A friendly name for the node"
-msgstr "Un nome para o nodo"
+msgstr "Un nome sinxelo para o nodo"
#: mod_pubsub.erl:3759
msgid "Max # of items to persist"
@@ -1626,12 +1605,11 @@ msgstr "Especificar o modelo do publicante"
#: mod_pubsub.erl:3769
msgid "Purge all items when the relevant publisher goes offline"
-msgstr ""
+msgstr "Purgar todos os elementos cando o editor correspondente desconéctase"
#: mod_pubsub.erl:3771
-#, fuzzy
msgid "Specify the event message type"
-msgstr "Especifica o modelo de acceso"
+msgstr "Especifica o tipo da mensaxe de evento"
#: mod_pubsub.erl:3773
msgid "Max payload size in bytes"
@@ -1650,15 +1628,13 @@ msgid "The collections with which a node is affiliated"
msgstr "As coleccións coas que un nodo está afiliado"
#: mod_register.erl:209
-#, fuzzy
msgid "The CAPTCHA verification has failed"
-msgstr "O CAPTCHA é válido."
+msgstr "A verificación de CAPTCHA fallou"
#: mod_register.erl:253
-#, fuzzy
msgid "You need a client that supports x:data and CAPTCHA to register"
msgstr ""
-"Necesitas un cliente con soporte de x:data para poder rexistrar o alcume"
+"Necesitas un cliente con soporte de x:data e CAPTCHA para rexistrarche"
#: mod_register.erl:259 mod_register.erl:320
msgid "Choose a username and password to register with this server"
@@ -1666,9 +1642,8 @@ msgstr ""
"Escolle un nome de usuario e contrasinal para rexistrarche neste servidor"
#: mod_register.erl:373 mod_register.erl:421
-#, fuzzy
msgid "The password is too weak"
-msgstr "a contrasinal é"
+msgstr "O contrasinal é demasiado débil"
#: mod_register.erl:426
msgid "Users are not allowed to register accounts so quickly"
@@ -1676,39 +1651,39 @@ msgstr "Os usuarios non están autorizados a rexistrar contas con tanta rapidez"
#: mod_register_web.erl:105
msgid "Your Jabber account was successfully created."
-msgstr ""
+msgstr "A súa conta Jabber creouse correctamente."
#: mod_register_web.erl:110
msgid "There was an error creating the account: "
-msgstr ""
+msgstr "Produciuse un erro ao crear a conta: "
#: mod_register_web.erl:119
msgid "Your Jabber account was successfully deleted."
-msgstr ""
+msgstr "A súa conta Jabber eliminouse correctamente."
#: mod_register_web.erl:124
msgid "There was an error deleting the account: "
-msgstr ""
+msgstr "Produciuse un erro ao eliminar a conta: "
#: mod_register_web.erl:135
msgid "The password of your Jabber account was successfully changed."
-msgstr ""
+msgstr "O contrasinal da súa conta Jabber cambiouse correctamente."
#: mod_register_web.erl:140
msgid "There was an error changing the password: "
-msgstr ""
+msgstr "Produciuse un erro ao cambiar o contrasinal: "
#: mod_register_web.erl:175 mod_register_web.erl:183
msgid "Jabber Account Registration"
-msgstr ""
+msgstr "Rexistro de conta Jabber"
#: mod_register_web.erl:186 mod_register_web.erl:204 mod_register_web.erl:212
msgid "Register a Jabber account"
-msgstr ""
+msgstr "Rexistrar unha conta Jabber"
#: mod_register_web.erl:191 mod_register_web.erl:453 mod_register_web.erl:461
msgid "Unregister a Jabber account"
-msgstr ""
+msgstr "Eliminar o rexistro dunha conta Jabber"
#: mod_register_web.erl:214
msgid ""
@@ -1716,40 +1691,45 @@ msgid ""
"(Jabber IDentifier) will be of the form: username@server. Please read "
"carefully the instructions to fill correctly the fields."
msgstr ""
+"Esta páxina permite crear unha conta Jabber neste servidor Jabber. o seu JID "
+"(Jabber IDentificador) será da forma: nomeusuario@servidor. Por favor le "
+"coidadosamente as instrucións para encher correctamente os campos."
#: mod_register_web.erl:224 mod_register_web.erl:360 mod_register_web.erl:469
-#, fuzzy
msgid "Username:"
-msgstr "Nome de usuario en IRC"
+msgstr "Nome de usuario:"
#: mod_register_web.erl:230
msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth."
-msgstr ""
+msgstr "Esta é insensible: Macbeth é o mesmo que MacBeth e Macbeth."
#: mod_register_web.erl:233
msgid "Characters not allowed:"
-msgstr ""
+msgstr "Caracteres non permitidos:"
#: mod_register_web.erl:236 mod_register_web.erl:364 mod_register_web.erl:473
-#, fuzzy
msgid "Server:"
-msgstr "Servidor ~b"
+msgstr "Servidor:"
#: mod_register_web.erl:245
msgid ""
"Don't tell your password to anybody, not even the administrators of the "
-"Jabber server."
+"Jabber Server."
msgstr ""
+"Non lle diga o seu contrasinal a ninguén, nin sequera os administradores do "
+"Servidor Jabber."
#: mod_register_web.erl:249
msgid "You can later change your password using a Jabber client."
-msgstr ""
+msgstr "Máis tarde, pode cambiar o seu contrasinal utilizando un cliente Jabber."
#: mod_register_web.erl:252
msgid ""
"Some Jabber clients can store your password in the computer, but you should "
"do this only in your personal computer for safety reasons."
msgstr ""
+"Algúns clientes Jabber pode almacenar o contrasinal no computador, pero debe "
+"facer isto só no seu computador persoal por razóns de seguridade."
#: mod_register_web.erl:256
msgid ""
@@ -1757,34 +1737,33 @@ msgid ""
"Jabber there isn't an automated way to recover your password if you forget "
"it."
msgstr ""
+"Memorice o seu contrasinal ou escribilo nun papel colocado nun lugar seguro. En "
+"Jabber non hai unha forma automatizada para recuperar o seu contrasinal si "
+"a esquece"
#: mod_register_web.erl:262 mod_register_web.erl:374
-#, fuzzy
msgid "Password Verification:"
msgstr "Verificación da contrasinal"
#: mod_register_web.erl:269
-#, fuzzy
msgid "Register"
-msgstr "Lista de contactos"
+msgstr "Rexistrar"
#: mod_register_web.erl:366
-#, fuzzy
msgid "Old Password:"
-msgstr "Contrasinal:"
+msgstr "Contrasinal anterior:"
#: mod_register_web.erl:370
-#, fuzzy
msgid "New Password:"
-msgstr "Contrasinal:"
+msgstr "Novo contrasinal:"
#: mod_register_web.erl:463
msgid "This page allows to unregister a Jabber account in this Jabber server."
-msgstr ""
+msgstr "Esta páxina permite anular o rexistro dunha conta Jabber neste servidor Jabber."
#: mod_register_web.erl:480
msgid "Unregister"
-msgstr ""
+msgstr "Eliminar rexistro"
#: mod_roster.erl:1436
msgid "Subscription"
@@ -1872,8 +1851,8 @@ msgid ""
"Fill in the form to search for any matching Jabber User (Add * to the end of "
"field to match substring)"
msgstr ""
-"Enche o formulario para buscar usuarios Jabber. Engade * ao final dun campo "
-"para buscar subcadenas."
+"Enche o formulario para buscar usuarios Jabber (Engade * ao final dun campo "
+"para buscar subcadenas)"
#: mod_vcard.erl:490 mod_vcard.erl:615
msgid "Full Name"
@@ -1901,7 +1880,7 @@ msgstr "Necesitas un cliente con soporte de x:data para poder buscar"
#: mod_vcard.erl:519 mod_vcard_ldap.erl:531
msgid "vCard User Search"
-msgstr "Procura de usuario en vCard"
+msgstr "vCard busqueda de usuario"
#: mod_vcard.erl:580 mod_vcard_ldap.erl:586
msgid "ejabberd vCard module"
@@ -1942,7 +1921,6 @@ msgstr "Rechea campos para buscar usuarios Jabber que concuerden"
#~ "Este participante é expulsado da sala, porque el enviou un erro de "
#~ "presenza"
-#, fuzzy
#~ msgid "CAPTCHA test failed"
#~ msgstr "O CAPTCHA é válido."
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index 292288a37..7c30f3b6c 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -178,6 +178,7 @@ bounce_resource_packet(From, To, Packet) ->
init([]) ->
lists:foreach(fun (Host) ->
ejabberd_router:register_route(Host,
+ Host,
{apply, ?MODULE,
route}),
ejabberd_hooks:add(local_send_to_resource_hook, Host,
diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl
index da1bd3e0f..e29d6acfb 100644
--- a/src/ejabberd_router.erl
+++ b/src/ejabberd_router.erl
@@ -36,7 +36,9 @@
route_error/4,
register_route/1,
register_route/2,
+ register_route/3,
register_routes/1,
+ host_of_route/1,
unregister_route/1,
unregister_routes/1,
dirty_get_all_routes/0,
@@ -55,7 +57,7 @@
-type local_hint() :: undefined | integer() | {apply, atom(), atom()}.
--record(route, {domain, pid, local_hint}).
+-record(route, {domain, server_host, pid, local_hint}).
-record(state, {}).
@@ -94,19 +96,29 @@ route_error(From, To, ErrPacket, OrigPacket) ->
-spec register_route(binary()) -> term().
register_route(Domain) ->
- register_route(Domain, undefined).
+ ?WARNING_MSG("~s:register_route/1 is deprected, "
+ "use ~s:register_route/2 instead",
+ [?MODULE, ?MODULE]),
+ register_route(Domain, ?MYNAME).
--spec register_route(binary(), local_hint()) -> term().
+-spec register_route(binary(), binary()) -> term().
-register_route(Domain, LocalHint) ->
- case jid:nameprep(Domain) of
- error -> erlang:error({invalid_domain, Domain});
- LDomain ->
+register_route(Domain, ServerHost) ->
+ register_route(Domain, ServerHost, undefined).
+
+-spec register_route(binary(), binary(), local_hint()) -> term().
+
+register_route(Domain, ServerHost, LocalHint) ->
+ case {jid:nameprep(Domain), jid:nameprep(ServerHost)} of
+ {error, _} -> erlang:error({invalid_domain, Domain});
+ {_, error} -> erlang:error({invalid_domain, ServerHost});
+ {LDomain, LServerHost} ->
Pid = self(),
case get_component_number(LDomain) of
undefined ->
F = fun () ->
mnesia:write(#route{domain = LDomain, pid = Pid,
+ server_host = LServerHost,
local_hint = LocalHint})
end,
mnesia:transaction(F);
@@ -115,46 +127,42 @@ register_route(Domain, LocalHint) ->
case mnesia:wread({route, LDomain}) of
[] ->
mnesia:write(#route{domain = LDomain,
+ server_host = LServerHost,
pid = Pid,
local_hint = 1}),
- lists:foreach(fun (I) ->
- mnesia:write(#route{domain
- =
- LDomain,
- pid
- =
- undefined,
- local_hint
- =
- I})
- end,
- lists:seq(2, N));
+ lists:foreach(
+ fun (I) ->
+ mnesia:write(
+ #route{domain = LDomain,
+ pid = undefined,
+ server_host = LServerHost,
+ local_hint = I})
+ end,
+ lists:seq(2, N));
Rs ->
- lists:any(fun (#route{pid = undefined,
- local_hint = I} =
- R) ->
- mnesia:write(#route{domain =
- LDomain,
- pid =
- Pid,
- local_hint
- =
- I}),
- mnesia:delete_object(R),
- true;
- (_) -> false
- end,
- Rs)
+ lists:any(
+ fun (#route{pid = undefined,
+ local_hint = I} = R) ->
+ mnesia:write(
+ #route{domain = LDomain,
+ pid = Pid,
+ server_host = LServerHost,
+ local_hint = I}),
+ mnesia:delete_object(R),
+ true;
+ (_) -> false
+ end,
+ Rs)
end
end,
mnesia:transaction(F)
end
end.
--spec register_routes([binary()]) -> ok.
+-spec register_routes([{binary(), binary()}]) -> ok.
register_routes(Domains) ->
- lists:foreach(fun (Domain) -> register_route(Domain)
+ lists:foreach(fun ({Domain, ServerHost}) -> register_route(Domain, ServerHost)
end,
Domains).
@@ -183,7 +191,9 @@ unregister_route(Domain) ->
of
[R] ->
I = R#route.local_hint,
+ ServerHost = R#route.server_host,
mnesia:write(#route{domain = LDomain,
+ server_host = ServerHost,
pid = undefined,
local_hint = I}),
mnesia:delete_object(R);
@@ -211,6 +221,20 @@ dirty_get_all_routes() ->
dirty_get_all_domains() ->
lists:usort(mnesia:dirty_all_keys(route)).
+-spec host_of_route(binary()) -> binary().
+
+host_of_route(Domain) ->
+ case jid:nameprep(Domain) of
+ error ->
+ erlang:error({invalid_domain, Domain});
+ LDomain ->
+ case mnesia:dirty_read(route, LDomain) of
+ [#route{server_host = ServerHost}|_] ->
+ ServerHost;
+ [] ->
+ erlang:error({unregistered_route, Domain})
+ end
+ end.
%%====================================================================
%% gen_server callbacks
@@ -283,8 +307,11 @@ handle_info({'DOWN', _Ref, _Type, Pid, _Info}, State) ->
if is_integer(E#route.local_hint) ->
LDomain = E#route.domain,
I = E#route.local_hint,
+ ServerHost = E#route.server_host,
mnesia:write(#route{domain =
LDomain,
+ server_host =
+ ServerHost,
pid =
undefined,
local_hint =
@@ -394,12 +421,10 @@ get_component_number(LDomain) ->
undefined).
update_tables() ->
- case catch mnesia:table_info(route, attributes) of
- [domain, node, pid] -> mnesia:delete_table(route);
- [domain, pid] -> mnesia:delete_table(route);
- [domain, pid, local_hint] -> ok;
- [domain, pid, local_hint|_] -> mnesia:delete_table(route);
- {'EXIT', _} -> ok
+ try
+ mnesia:transform_table(route, ignore, record_info(fields, route))
+ catch exit:{aborted, {no_exists, _}} ->
+ ok
end,
case lists:member(local_route,
mnesia:system_info(tables))
diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl
index e5508a190..5caae6102 100644
--- a/src/ejabberd_service.erl
+++ b/src/ejabberd_service.erl
@@ -222,7 +222,7 @@ wait_for_handshake({xmlstreamelement, El}, StateData) ->
send_text(StateData, <<"">>),
lists:foreach(
fun (H) ->
- ejabberd_router:register_route(H),
+ ejabberd_router:register_route(H, ?MYNAME),
?INFO_MSG("Route registered for service ~p~n",
[H])
end, dict:fetch_keys(StateData#state.host_opts)),
diff --git a/src/ejabberd_system_monitor.erl b/src/ejabberd_system_monitor.erl
index 3ea636033..3f6c05667 100644
--- a/src/ejabberd_system_monitor.erl
+++ b/src/ejabberd_system_monitor.erl
@@ -186,18 +186,24 @@ process_large_heap(Pid, Info) ->
"much memory:~n~p~n~s",
[node(), Pid, Info, DetailedInfo])),
From = jid:make(<<"">>, Host, <<"watchdog">>),
+ Hint = [#xmlel{name = <<"no-permanent-store">>,
+ attrs = [{<<"xmlns">>, ?NS_HINTS}]}],
lists:foreach(fun (JID) ->
- send_message(From, jid:make(JID), Body)
+ send_message(From, jid:make(JID), Body, Hint)
end, JIDs).
send_message(From, To, Body) ->
+ send_message(From, To, Body, []).
+
+send_message(From, To, Body, ExtraEls) ->
ejabberd_router:route(From, To,
#xmlel{name = <<"message">>,
attrs = [{<<"type">>, <<"chat">>}],
children =
[#xmlel{name = <<"body">>, attrs = [],
children =
- [{xmlcdata, Body}]}]}).
+ [{xmlcdata, Body}]}
+ | ExtraEls]}).
get_admin_jids() ->
ejabberd_config:get_option(
diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl
index 6180a16d1..ad3f10abb 100644
--- a/src/mod_admin_extra.erl
+++ b/src/mod_admin_extra.erl
@@ -861,7 +861,8 @@ connected_users_info() ->
PI when is_integer(PI) -> PI;
_ -> nil
end,
- {[U, $@, S, $/, R], atom_to_list(Conn), IPS, Port, PriorityI, NodeS, Uptime}
+ {binary_to_list(<>),
+ atom_to_list(Conn), IPS, Port, PriorityI, NodeS, Uptime}
end,
USRIs).
diff --git a/src/mod_echo.erl b/src/mod_echo.erl
index 8e7394cb4..7184ee4e7 100644
--- a/src/mod_echo.erl
+++ b/src/mod_echo.erl
@@ -86,7 +86,7 @@ stop(Host) ->
init([Host, Opts]) ->
MyHost = gen_mod:get_opt_host(Host, Opts,
<<"echo.@HOST@">>),
- ejabberd_router:register_route(MyHost),
+ ejabberd_router:register_route(MyHost, Host),
{ok, #state{host = MyHost}}.
%%--------------------------------------------------------------------
diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl
index 5635102b2..6c029c437 100644
--- a/src/mod_http_upload.erl
+++ b/src/mod_http_upload.erl
@@ -306,7 +306,7 @@ init({ServerHost, Opts}) ->
false ->
ok
end,
- ejabberd_router:register_route(Host),
+ ejabberd_router:register_route(Host, ServerHost),
{ok, #state{server_host = ServerHost, host = Host, name = Name,
access = Access, max_size = MaxSize,
secret_length = SecretLength, jid_in_url = JIDinURL,
diff --git a/src/mod_irc.erl b/src/mod_irc.erl
index b7300e28b..d5cd01353 100644
--- a/src/mod_irc.erl
+++ b/src/mod_irc.erl
@@ -133,7 +133,7 @@ init([Host, Opts]) ->
catch ets:new(irc_connection,
[named_table, public,
{keypos, #irc_connection.jid_server_host}]),
- ejabberd_router:register_route(MyHost),
+ ejabberd_router:register_route(MyHost, Host),
{ok,
#state{host = MyHost, server_host = Host,
access = Access}}.
diff --git a/src/mod_mix.erl b/src/mod_mix.erl
index 8224ec78a..d8cf94ac3 100644
--- a/src/mod_mix.erl
+++ b/src/mod_mix.erl
@@ -168,7 +168,7 @@ init([ServerHost, Opts]) ->
?NS_PUBSUB, mod_pubsub, iq_sm, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
?NS_MIX_0, ?MODULE, process_iq, IQDisc),
- ejabberd_router:register_route(Host),
+ ejabberd_router:register_route(Host, ServerHost),
{ok, #state{server_host = ServerHost, host = Host}}.
handle_call(_Request, _From, State) ->
diff --git a/src/mod_muc.erl b/src/mod_muc.erl
index de795fc0e..0d37a236e 100644
--- a/src/mod_muc.erl
+++ b/src/mod_muc.erl
@@ -373,7 +373,7 @@ init([Host, Opts]) ->
RoomShaper = gen_mod:get_opt(room_shaper, Opts,
fun(A) when is_atom(A) -> A end,
none),
- ejabberd_router:register_route(MyHost),
+ ejabberd_router:register_route(MyHost, Host),
load_permanent_rooms(MyHost, Host,
{Access, AccessCreate, AccessAdmin, AccessPersistent},
HistorySize, RoomShaper),
diff --git a/src/mod_multicast.erl b/src/mod_multicast.erl
index 5c662a868..83520c0be 100644
--- a/src/mod_multicast.erl
+++ b/src/mod_multicast.erl
@@ -151,7 +151,7 @@ init([LServerS, Opts]) ->
try_start_loop(),
create_pool(),
ejabberd_router_multicast:register_route(LServerS),
- ejabberd_router:register_route(LServiceS),
+ ejabberd_router:register_route(LServiceS, LServerS),
{ok,
#state{lservice = LServiceS, lserver = LServerS,
access = Access, service_limits = SLimits}}.
@@ -395,7 +395,7 @@ act_groups(FromJID, Packet_stripped, AAttrs, LServiceS,
perform(From, Packet, AAttrs, _,
{route_single, Group}) ->
[route_packet(From, ToUser, Packet, AAttrs,
- Group#group.addresses)
+ Group#group.others, Group#group.addresses)
|| ToUser <- Group#group.dests];
perform(From, Packet, AAttrs, _,
{{route_multicast, JID, RLimits}, Group}) ->
@@ -634,13 +634,13 @@ decide_action_group(Group) ->
%%% Route packet
%%%-------------------------
-route_packet(From, ToDest, Packet, AAttrs, Addresses) ->
+route_packet(From, ToDest, Packet, AAttrs, Others, Addresses) ->
Dests = case ToDest#dest.type of
<<"bcc">> -> [];
_ -> [ToDest]
end,
route_packet2(From, ToDest#dest.jid_string, Dests,
- Packet, AAttrs, Addresses).
+ Packet, AAttrs, {Others, Addresses}).
route_packet_multicast(From, ToS, Packet, AAttrs, Dests,
Addresses, Limits) ->
@@ -666,6 +666,8 @@ route_packet2(From, ToS, Dests, Packet, AAttrs,
ToJID = stj(ToS),
ejabberd_router:route(From, ToJID, Packet2).
+append_dests(_Dests, {Others, Addresses}) ->
+ Addresses++Others;
append_dests([], Addresses) -> Addresses;
append_dests([Dest | Dests], Addresses) ->
append_dests(Dests, [Dest#dest.full_xml | Addresses]).
@@ -912,8 +914,9 @@ received_awaiter(JID, Waiter, LServiceS) ->
From = Waiter#waiter.sender,
Packet = Waiter#waiter.packet,
AAttrs = Waiter#waiter.aattrs,
+ Others = Group#group.others,
Addresses = Waiter#waiter.addresses,
- [route_packet(From, ToUser, Packet, AAttrs, Addresses)
+ [route_packet(From, ToUser, Packet, AAttrs, Others, Addresses)
|| ToUser <- Group#group.dests];
true ->
send_query_info(RServer, LServiceS),
diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl
index 3fb86360a..8b4644ba8 100644
--- a/src/mod_proxy65_service.erl
+++ b/src/mod_proxy65_service.erl
@@ -63,7 +63,7 @@ start_link(Host, Opts) ->
init([Host, Opts]) ->
State = parse_options(Host, Opts),
- ejabberd_router:register_route(State#state.myhost),
+ ejabberd_router:register_route(State#state.myhost, Host),
{ok, State}.
terminate(_Reason, #state{myhost = MyHost}) ->
diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl
index 8017e3e5d..6531ed876 100644
--- a/src/mod_pubsub.erl
+++ b/src/mod_pubsub.erl
@@ -241,6 +241,7 @@ stop(Host) ->
init([ServerHost, Opts]) ->
?DEBUG("pubsub init ~p ~p", [ServerHost, Opts]),
Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>),
+ ejabberd_router:register_route(Host, ServerHost),
Access = gen_mod:get_opt(access_createnode, Opts,
fun(A) when is_atom(A) -> A end, all),
PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts,
@@ -256,22 +257,26 @@ init([ServerHost, Opts]) ->
DefaultNodeCfg = gen_mod:get_opt(default_node_config, Opts,
fun(A) when is_list(A) -> filter_node_options(A) end, []),
pubsub_index:init(Host, ServerHost, Opts),
- ets:new(gen_mod:get_module_proc(ServerHost, config), [set, named_table]),
{Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts),
mnesia:create_table(pubsub_last_item,
[{ram_copies, [node()]},
{attributes, record_info(fields, pubsub_last_item)}]),
mod_disco:register_feature(ServerHost, ?NS_PUBSUB),
- ets:insert(gen_mod:get_module_proc(ServerHost, config), {nodetree, NodeTree}),
- ets:insert(gen_mod:get_module_proc(ServerHost, config), {plugins, Plugins}),
- ets:insert(gen_mod:get_module_proc(ServerHost, config), {last_item_cache, LastItemCache}),
- ets:insert(gen_mod:get_module_proc(ServerHost, config), {max_items_node, MaxItemsNode}),
- ets:insert(gen_mod:get_module_proc(ServerHost, config), {max_subscriptions_node, MaxSubsNode}),
- ets:insert(gen_mod:get_module_proc(ServerHost, config), {default_node_config, DefaultNodeCfg}),
- ets:insert(gen_mod:get_module_proc(ServerHost, config), {pep_mapping, PepMapping}),
- ets:insert(gen_mod:get_module_proc(ServerHost, config), {ignore_pep_from_offline, PepOffline}),
- ets:insert(gen_mod:get_module_proc(ServerHost, config), {host, Host}),
- ets:insert(gen_mod:get_module_proc(ServerHost, config), {access, Access}),
+ lists:foreach(
+ fun(H) ->
+ T = gen_mod:get_module_proc(H, config),
+ ets:new(T, [set, named_table]),
+ ets:insert(T, {nodetree, NodeTree}),
+ ets:insert(T, {plugins, Plugins}),
+ ets:insert(T, {last_item_cache, LastItemCache}),
+ ets:insert(T, {max_items_node, MaxItemsNode}),
+ ets:insert(T, {max_subscriptions_node, MaxSubsNode}),
+ ets:insert(T, {default_node_config, DefaultNodeCfg}),
+ ets:insert(T, {pep_mapping, PepMapping}),
+ ets:insert(T, {ignore_pep_from_offline, PepOffline}),
+ ets:insert(T, {host, Host}),
+ ets:insert(T, {access, Access})
+ end, [Host, ServerHost]),
ejabberd_hooks:add(sm_remove_connection_hook, ServerHost,
?MODULE, on_user_offline, 75),
ejabberd_hooks:add(disco_local_identity, ServerHost,
@@ -309,7 +314,6 @@ init([ServerHost, Opts]) ->
false ->
ok
end,
- ejabberd_router:register_route(Host),
pubsub_migrate:update_node_database(Host, ServerHost),
pubsub_migrate:update_state_database(Host, ServerHost),
pubsub_migrate:update_lastitem_database(Host, ServerHost),
@@ -873,7 +877,6 @@ handle_info(_Info, State) ->
%% @private
terminate(_Reason,
#state{host = Host, server_host = ServerHost, nodetree = TreePlugin, plugins = Plugins}) ->
- ejabberd_router:unregister_route(Host),
case lists:member(?PEPNODE, Plugins) of
true ->
ejabberd_hooks:delete(caps_add, ServerHost,
@@ -918,7 +921,8 @@ terminate(_Reason,
Pid ->
Pid ! stop
end,
- terminate_plugins(Host, ServerHost, Plugins, TreePlugin).
+ terminate_plugins(Host, ServerHost, Plugins, TreePlugin),
+ ejabberd_router:unregister_route(Host).
%%--------------------------------------------------------------------
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
@@ -3641,7 +3645,7 @@ get_option(Options, Var, Def) ->
end.
node_options(Host, Type) ->
- case config(serverhost(Host), default_node_config) of
+ case config(Host, default_node_config) of
undefined -> node_plugin_options(Host, Type);
[] -> node_plugin_options(Host, Type);
Config -> Config
@@ -3954,15 +3958,15 @@ set_xoption(Host, [_ | Opts], NewOpts) ->
set_xoption(Host, Opts, NewOpts).
get_max_items_node(Host) ->
- config(serverhost(Host), max_items_node, undefined).
+ config(Host, max_items_node, undefined).
get_max_subscriptions_node(Host) ->
- config(serverhost(Host), max_subscriptions_node, undefined).
+ config(Host, max_subscriptions_node, undefined).
%%%% last item cache handling
is_last_item_cache_enabled(Host) ->
- config(serverhost(Host), last_item_cache, false).
+ config(Host, last_item_cache, false).
set_cached_item({_, ServerHost, _}, Nidx, ItemId, Publisher, Payload) ->
set_cached_item(ServerHost, Nidx, ItemId, Publisher, Payload);
@@ -4013,13 +4017,12 @@ host(ServerHost) ->
config(ServerHost, host, <<"pubsub.", ServerHost/binary>>).
serverhost({_U, ServerHost, _R})->
- ServerHost;
+ serverhost(ServerHost);
serverhost(Host) ->
- [_, ServerHost] = binary:split(Host, <<".">>),
- ServerHost.
+ ejabberd_router:host_of_route(Host).
tree(Host) ->
- case config(serverhost(Host), nodetree) of
+ case config(Host, nodetree) of
undefined -> tree(Host, ?STDTREE);
Tree -> Tree
end.
@@ -4041,7 +4044,7 @@ plugin(Host, Name) ->
end.
plugins(Host) ->
- case config(serverhost(Host), plugins) of
+ case config(Host, plugins) of
undefined -> [?STDNODE];
[] -> [?STDNODE];
Plugins -> Plugins
@@ -4056,6 +4059,9 @@ subscription_plugin(Host) ->
config(ServerHost, Key) ->
config(ServerHost, Key, undefined).
+
+config({_User, Host, _Resource}, Key, Default) ->
+ config(Host, Key, Default);
config(ServerHost, Key, Default) ->
case catch ets:lookup(gen_mod:get_module_proc(ServerHost, config), Key) of
[{Key, Value}] -> Value;
diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl
index f57957d1a..dd6a7f6d4 100644
--- a/src/mod_shared_roster_ldap.erl
+++ b/src/mod_shared_roster_ldap.erl
@@ -145,7 +145,7 @@ get_user_roster(Items, {U, S} = US) ->
%%case dict:find(US1, SRUsers1) of
{value, _, SRUsers2} -> {Item#roster{subscription = both, ask = none}, SRUsers2};
%%{ok, _GroupNames} -> {Item#roster{subscription = both, ask = none}, dict:erase(US1, SRUsers1)};
- error -> {Item, SRUsers1}
+ false -> {Item, SRUsers1}
end
end,
SRUsers, Items),
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index 3652fb2af..256dc5de7 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -105,7 +105,7 @@ init(Host, ServerHost, Search) ->
case Search of
false -> loop(Host, ServerHost);
_ ->
- ejabberd_router:register_route(Host),
+ ejabberd_router:register_route(Host, ServerHost),
loop(Host, ServerHost)
end.
diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl
index 25239133c..98aaf9362 100644
--- a/src/mod_vcard_ldap.erl
+++ b/src/mod_vcard_ldap.erl
@@ -173,7 +173,7 @@ init([Host, Opts]) ->
State#state.password, State#state.tls_options),
case State#state.search of
true ->
- ejabberd_router:register_route(State#state.myhost);
+ ejabberd_router:register_route(State#state.myhost, Host);
_ -> ok
end,
{ok, State}.
diff --git a/src/node_mix_odbc.erl b/src/node_mix_odbc.erl
new file mode 100644
index 000000000..e7cc6883a
--- /dev/null
+++ b/src/node_mix_odbc.erl
@@ -0,0 +1,170 @@
+%%%-------------------------------------------------------------------
+%%% @author Evgeny Khramtsov
+%%% @copyright (C) 2016, Evgeny Khramtsov
+%%% @doc
+%%%
+%%% @end
+%%% Created : 8 Mar 2016 by Evgeny Khramtsov
+%%%-------------------------------------------------------------------
+-module(node_mix_odbc).
+
+-behaviour(gen_pubsub_node).
+
+%% API
+-export([init/3, terminate/2, options/0, features/0,
+ create_node_permission/6, create_node/2, delete_node/1,
+ purge_node/2, subscribe_node/8, unsubscribe_node/4,
+ publish_item/6, delete_item/4, remove_extra_items/3,
+ get_entity_affiliations/2, get_node_affiliations/1,
+ get_affiliation/2, set_affiliation/3,
+ get_entity_subscriptions/2, get_node_subscriptions/1,
+ get_subscriptions/2, set_subscriptions/4,
+ get_pending_nodes/2, get_states/1, get_state/2,
+ set_state/1, get_items/7, get_items/3, get_item/7,
+ get_item/2, set_item/1, get_item_name/3, node_to_path/1,
+ path_to_node/1, get_entity_subscriptions_for_send_last/2]).
+
+-include("pubsub.hrl").
+
+%%%===================================================================
+%%% API
+%%%===================================================================
+init(Host, ServerHost, Opts) ->
+ node_flat_odbc:init(Host, ServerHost, Opts).
+
+terminate(Host, ServerHost) ->
+ node_flat_odbc:terminate(Host, ServerHost).
+
+options() ->
+ [{deliver_payloads, true},
+ {notify_config, false},
+ {notify_delete, false},
+ {notify_retract, true},
+ {purge_offline, false},
+ {persist_items, true},
+ {max_items, ?MAXITEMS},
+ {subscribe, true},
+ {access_model, open},
+ {roster_groups_allowed, []},
+ {publish_model, open},
+ {notification_type, headline},
+ {max_payload_size, ?MAX_PAYLOAD_SIZE},
+ {send_last_published_item, never},
+ {deliver_notifications, true},
+ {broadcast_all_resources, true},
+ {presence_based_delivery, false}].
+
+features() ->
+ [<<"create-nodes">>,
+ <<"delete-nodes">>,
+ <<"delete-items">>,
+ <<"instant-nodes">>,
+ <<"item-ids">>,
+ <<"outcast-affiliation">>,
+ <<"persistent-items">>,
+ <<"publish">>,
+ <<"purge-nodes">>,
+ <<"retract-items">>,
+ <<"retrieve-affiliations">>,
+ <<"retrieve-items">>,
+ <<"retrieve-subscriptions">>,
+ <<"subscribe">>,
+ <<"subscription-notifications">>].
+
+create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access) ->
+ node_flat_odbc:create_node_permission(Host, ServerHost, Node, ParentNode, Owner, Access).
+
+create_node(Nidx, Owner) ->
+ node_flat_odbc:create_node(Nidx, Owner).
+
+delete_node(Removed) ->
+ node_flat_odbc:delete_node(Removed).
+
+subscribe_node(Nidx, Sender, Subscriber, AccessModel,
+ SendLast, PresenceSubscription, RosterGroup, Options) ->
+ node_flat_odbc:subscribe_node(Nidx, Sender, Subscriber, AccessModel, SendLast,
+ PresenceSubscription, RosterGroup, Options).
+
+unsubscribe_node(Nidx, Sender, Subscriber, SubId) ->
+ node_flat_odbc:unsubscribe_node(Nidx, Sender, Subscriber, SubId).
+
+publish_item(Nidx, Publisher, Model, MaxItems, ItemId, Payload) ->
+ node_flat_odbc:publish_item(Nidx, Publisher, Model, MaxItems, ItemId, Payload).
+
+remove_extra_items(Nidx, MaxItems, ItemIds) ->
+ node_flat_odbc:remove_extra_items(Nidx, MaxItems, ItemIds).
+
+delete_item(Nidx, Publisher, PublishModel, ItemId) ->
+ node_flat_odbc:delete_item(Nidx, Publisher, PublishModel, ItemId).
+
+purge_node(Nidx, Owner) ->
+ node_flat_odbc:purge_node(Nidx, Owner).
+
+get_entity_affiliations(Host, Owner) ->
+ node_flat_odbc:get_entity_affiliations(Host, Owner).
+
+get_node_affiliations(Nidx) ->
+ node_flat_odbc:get_node_affiliations(Nidx).
+
+get_affiliation(Nidx, Owner) ->
+ node_flat_odbc:get_affiliation(Nidx, Owner).
+
+set_affiliation(Nidx, Owner, Affiliation) ->
+ node_flat_odbc:set_affiliation(Nidx, Owner, Affiliation).
+
+get_entity_subscriptions(Host, Owner) ->
+ node_flat_odbc:get_entity_subscriptions(Host, Owner).
+
+get_node_subscriptions(Nidx) ->
+ node_flat_odbc:get_node_subscriptions(Nidx).
+
+get_subscriptions(Nidx, Owner) ->
+ node_flat_odbc:get_subscriptions(Nidx, Owner).
+
+set_subscriptions(Nidx, Owner, Subscription, SubId) ->
+ node_flat_odbc:set_subscriptions(Nidx, Owner, Subscription, SubId).
+
+get_pending_nodes(Host, Owner) ->
+ node_flat_odbc:get_pending_nodes(Host, Owner).
+
+get_states(Nidx) ->
+ node_flat_odbc:get_states(Nidx).
+
+get_state(Nidx, JID) ->
+ node_flat_odbc:get_state(Nidx, JID).
+
+set_state(State) ->
+ node_flat_odbc:set_state(State).
+
+get_items(Nidx, From, RSM) ->
+ node_flat_odbc:get_items(Nidx, From, RSM).
+
+get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, SubId, RSM) ->
+ node_flat_odbc:get_items(Nidx, JID, AccessModel,
+ PresenceSubscription, RosterGroup, SubId, RSM).
+
+get_item(Nidx, ItemId) ->
+ node_flat_odbc:get_item(Nidx, ItemId).
+
+get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_flat_odbc:get_item(Nidx, ItemId, JID, AccessModel,
+ PresenceSubscription, RosterGroup, SubId).
+
+set_item(Item) ->
+ node_flat_odbc:set_item(Item).
+
+get_item_name(Host, Node, Id) ->
+ node_flat_odbc:get_item_name(Host, Node, Id).
+
+node_to_path(Node) ->
+ node_flat_odbc:node_to_path(Node).
+
+path_to_node(Path) ->
+ node_flat_odbc:path_to_node(Path).
+
+get_entity_subscriptions_for_send_last(Host, Owner) ->
+ node_flat_odbc:get_entity_subscriptions_for_send_last(Host, Owner).
+
+%%%===================================================================
+%%% Internal functions
+%%%===================================================================
diff --git a/test/ejabberd_SUITE.erl b/test/ejabberd_SUITE.erl
index f17bfeb4c..b239ddf0b 100644
--- a/test/ejabberd_SUITE.erl
+++ b/test/ejabberd_SUITE.erl
@@ -293,6 +293,8 @@ db_tests(_) ->
test_unregister]},
{test_muc_register, [sequence],
[muc_register_master, muc_register_slave]},
+ {test_mix, [parallel],
+ [mix_master, mix_slave]},
{test_roster_subscribe, [parallel],
[roster_subscribe_master,
roster_subscribe_slave]},
diff --git a/test/ejabberd_SUITE_data/ejabberd.yml b/test/ejabberd_SUITE_data/ejabberd.yml
index 96453f77b..923d69024 100644
--- a/test/ejabberd_SUITE_data/ejabberd.yml
+++ b/test/ejabberd_SUITE_data/ejabberd.yml
@@ -35,6 +35,7 @@ host_config:
- "flat"
- "hometree"
- "pep"
+ mod_mix: []
mod_roster:
versioning: true
store_current_id: true
@@ -88,6 +89,7 @@ Welcome to this XMPP server."
- "flat"
- "hometree"
- "pep"
+ mod_mix: []
mod_roster:
versioning: true
store_current_id: true
@@ -147,6 +149,7 @@ Welcome to this XMPP server."
- "flat"
- "hometree"
- "pep"
+ mod_mix: []
mod_roster:
versioning: true
store_current_id: true