Compare commits

..

225 Commits

Author SHA1 Message Date
Paweł Chmielowski c96de092fe Revert "Add workaround so rebar2 can use Elixir 1.12.0"
CI / Tests (ubuntu-18.04, 19.3, 2) (push) Has been cancelled
CI / Tests (ubuntu-20.04, 24.0, 3) (push) Has been cancelled
CI / Binaries (ubuntu-20.04, 21.3, 3) (push) Has been cancelled
This reverts commit 937e1c2e37.
2021-07-22 15:51:43 +02:00
Badlop cf72c5ee18 Remove leading zeros in ejabberd version number to satisfy Elixir SemVer 2021-07-21 21:29:04 +02:00
Badlop 69fa79b154 Add 21.07 changes to CHANGELOG 2021-07-21 17:58:35 +02:00
Badlop ea795e4bd7 Update man page 2021-07-21 17:58:32 +02:00
Badlop 537c8b966e In "make dev" don't create link ejabberdctl, seems buggy 2021-07-21 17:58:27 +02:00
Paweł Chmielowski 142e494d52 Update mix.lock 2021-07-21 14:50:18 +02:00
Badlop 50242cec78 Annotate the srg_create command as changed in 21.07 2021-07-21 13:11:09 +02:00
Badlop 33f821d4f7 Simplify the --with-rebar example in README 2021-07-21 13:11:06 +02:00
Badlop 9a823e5a16 Update Portuguese translation from Weblate (thanks to Ssantos) 2021-07-21 13:07:31 +02:00
Badlop 686ce01534 Update Italian translation from Weblate (thanks to Alessandro Mandelli) 2021-07-21 13:07:29 +02:00
Badlop 4225f14e8b Update Indonesian translation from Weblate (thanks to Reza Almanda) 2021-07-21 13:07:26 +02:00
Paweł Chmielowski a3478b7f0f Update pam 2021-07-21 11:37:32 +02:00
Paweł Chmielowski bab9543c1f Update dependences 2021-07-21 11:12:54 +02:00
Paweł Chmielowski c3169e9eea Typo 2021-07-20 17:07:40 +02:00
Badlop c04b6b2908 Update CHANGELOG.md with 21.04 and 21.01 (#3646) 2021-07-19 17:23:50 +02:00
Badlop 937e1c2e37 Add workaround so rebar2 can use Elixir 1.12.0
Notice that Elixir 1.12.0 requires Erlang/OTP 21 or higher
BTW, this workaround works only with rebar2... unfortunately
rebar3 doesn't compile the elixir files from lib/
2021-07-16 16:43:08 +02:00
Badlop 91763bbc61 As Mix config now must be evaluated at runtime, rename to runtime.exs 2021-07-16 13:57:25 +02:00
Badlop e0c9a6308d erlang:phash is deprecated in OTP 24, let's use phash2 2021-07-16 13:57:08 +02:00
Badlop e14cd5dd17 Mention in README.md the updated --with-rebar and "make dev" 2021-07-16 13:36:28 +02:00
Badlop e31919914b Add support to build release with back to old Elixir 1.10.3
However, to build a release with OTP 24 requires Elixir 1.11.4 or higher
2021-07-16 13:36:27 +02:00
Badlop fcbd72f2d7 Add rebar3 3.15.2
Reference: https://ferd.ca/you-ve-got-to-upgrade-rebar3.html
2021-07-16 13:36:25 +02:00
Badlop 4c5641a648 Add support for mix to: ./configure --enable-rebar=mix 2021-07-16 13:36:23 +02:00
Badlop 1fd452dca9 Update setup-dev.sh to work perfectly both with rebar3 and mix 2021-07-16 13:36:22 +02:00
Badlop f35d304582 Minor mix.exs definitions copied from the template file 2021-07-16 13:36:20 +02:00
Badlop 8ca12d4d23 Add support to build release with mix 2021-07-16 13:36:19 +02:00
Badlop 72e069d9ec Get ejabberd version from vars.config 2021-07-16 13:36:17 +02:00
Badlop df8b0cb1a5 Add sql to package files (#3251) 2021-07-16 13:36:15 +02:00
Badlop a00a11e38a Add vars.config to package files: version and cond_deps use it 2021-07-16 13:36:13 +02:00
Badlop 94949c9617 Sort package files 2021-07-16 13:36:10 +02:00
Badlop e2aaca7cdd Update mix applications list to fix error "p1_utils is listed as both..." 2021-07-16 13:36:04 +02:00
Badlop 3afaacab76 With the recent changes it seems mod_mix supports 0.14.1 (#3634) 2021-07-15 17:19:32 +02:00
badlop 57be0e38d8 Merge pull request #3634 from lnjX/mix-identity-conf-mix
mod_mix: Use disco identity conference/mix
2021-07-15 17:15:48 +02:00
Paweł Chmielowski 27c69f263c Allow multicast hook registering by host 2021-07-14 13:58:53 +02:00
Badlop e22ed8081a Provide proper error message when create_room fails with invalid_service 2021-07-13 20:43:52 +02:00
Badlop 5beaf50c67 Fix spec: xmpp:set_from_to/3 allows undefined as second argument 2021-07-13 20:43:44 +02:00
Paweł Chmielowski a07029dcad Fix previous commit to pass all tests 2021-07-13 17:56:16 +02:00
Paweł Chmielowski 0de6f1c538 Use multicast routing for more packets generated by muc 2021-07-13 16:01:25 +02:00
Badlop 2e2667bbd7 Update documentation: mod_muc ram_db_type supports SQL since 17.04 (#3632) 2021-07-08 12:29:16 +02:00
Badlop 271a9f097d After create_room, store in DB if it's persistent (#3632) 2021-07-08 12:29:13 +02:00
Badlop 7e3276f3a8 Ignore captcha scripts copied by relx after "make dev" 2021-07-08 12:29:03 +02:00
badlop 42fdac0b41 Merge pull request #3639 from McPo/xep0033-bcc-strip-fix
Correctly strip only third-party bcc addresses
2021-07-07 19:07:21 +02:00
Emmet McPoland 509331a563 Correctly strip only other bcc addresses i.e. bcc receiver should still be able to see their bcc address element and no other bcc address element 2021-07-07 16:44:58 +01:00
Badlop 08c2d0a83e Tell relx to include src, so that the tar will contain include/ (#3633)
That's the only way to ensure that tar.gz will contain include/
of ejabberd and its dependencies, which is required to compile
ejabberd-contrib modules with "ejabberdctl module_install ..."
2021-07-06 13:37:14 +02:00
Badlop bb0c6e1e02 Show messages with next configuration steps when installing a module 2021-07-06 13:37:04 +02:00
badlop 331a67f5f8 Merge pull request #3566 from Robbilie/feature/mqtt-shared-roster-groups-placeholder
allow shared roster group placeholder in mqtt topic
2021-07-06 13:36:41 +02:00
Paweł Chmielowski e3e4dae583 Yet another dialyzer warning fix 2021-06-28 12:53:30 +02:00
Paweł Chmielowski b669e4499c Fix dialyzer warning 2021-06-28 12:18:19 +02:00
Paweł Chmielowski 6e900d6a8f Add send_timeout option to listener 2021-06-28 11:31:45 +02:00
Paweł Chmielowski 795addca7d Try to limit serial access when checking api permissions 2021-06-28 11:31:43 +02:00
Badlop 774de2bdc5 Include odbc app in release only when required (#3633) 2021-06-27 17:32:09 +02:00
Badlop b5b2ad560a Copy captcha scripts in release (#3633) 2021-06-27 17:32:06 +02:00
Badlop b93fc4333c Let "make dev" always update SCRIPT_DIR in ejabberdctl, even if link exists 2021-06-27 17:32:04 +02:00
Linus Jahn d7c9809c59 mod_mix: Use disco identity conference/mix
Probably someone has forgotten to update it here.
https://xmpp.org/extensions/xep-0369.html#example-5

Fixes #2901.
2021-06-27 01:20:45 +02:00
Badlop ac06161f30 There are so many targets... add "make help" 2021-06-25 12:53:47 +02:00
Badlop 0fe2aea709 New "make dev" and "./ejabberdctl" (requires using rebar3) 2021-06-25 12:53:43 +02:00
Badlop 21b021d912 Set SCRIPT_DIR as done by the ejabberd script generated by "rebar3 release" 2021-06-25 12:53:30 +02:00
Badlop d5adcaea61 Add support for rebar3 to "make rel" 2021-06-25 12:53:22 +02:00
Holger Weiss 9d4c01d425 mod_push_keepalive: Fix 'resume_timeout' docs
The default 'resume_timeout' value is 72 hours, not 72 minutes.
2021-06-25 01:30:10 +02:00
Badlop ea97be9124 Don't cache rebar3 binaries... compiling is less than 2 minutes anyway 2021-06-21 11:46:10 +02:00
Paweł Chmielowski 2458f55837 Update stringprep in mix 2021-06-18 11:45:18 +02:00
badlop 1ef9f28f2d Merge pull request #3622 from pouriya/fix-ws-typos
ref: fix WS typos
2021-06-14 17:21:33 +02:00
Badlop 3ed41e39f6 CI: don't cache dialyzer output file: when there are several, ln fails 2021-06-14 17:20:57 +02:00
Badlop 4ee10c155d Fix reverse order of items when using <before/> in Pubsub with RSM (#3621) 2021-06-14 12:22:37 +02:00
Badlop c2d8bc7b2f Add mqtt_pub table definition for MSSQL (#3097) 2021-06-14 12:22:21 +02:00
Pouriya Jahanbakhsh b5bafca640 ref: fix WS typos 2021-06-12 20:27:30 +04:30
Badlop 9a93562b94 Revert luerl from v0.4 which has a compilation warning; v0.3 is enough
Revert "Update luerl dependency from v0.3 to v0.4"

This reverts commit 64f3f3287a.
2021-06-08 19:00:46 +02:00
Badlop bf8b4acf01 Return proper index when using after of before in PubSub with RSM (#3618)
This fixes Index attribute in examples from:
https://xmpp.org/extensions/xep-0059.html#forwards
https://xmpp.org/extensions/xep-0059.html#backwards
2021-06-08 19:00:44 +02:00
Badlop 41fd2afeb3 Fix index attribute when getting last page from PubSub with RSM (#3618)
This fixes Example 11 from "2.5 Requesting the Last Page in a Result Set":
https://xmpp.org/extensions/xep-0059.html#last
2021-06-08 19:00:41 +02:00
Badlop 4520d5f3c1 Support for simple limiting the number of items in PubSub with RSM (#3618)
This fixes crash in Example 1 from "2.1 Limiting the Number of Items":
https://xmpp.org/extensions/xep-0059.html#limit
2021-06-08 19:00:39 +02:00
Badlop ccadbf45a2 Get explicitely rebar3 3.15 binary that works with Erlang 21.3 2021-06-07 12:13:22 +02:00
Badlop 2b0d724aef Workaround so coveralls website shows git commit information
References:
https://github.com/markusn/coveralls-erl/pull/36
https://github.com/deadtrickster/prometheus.erl/pull/123
2021-06-06 16:56:29 +02:00
Badlop 9010c35193 CI: Get rebar3 compatible with previous OTP, the one in Ubuntu 20.04 is not 2021-05-28 16:56:05 +02:00
Badlop 2c20414453 Update eredis dependency from v1.0.8 to v1.2.0 2021-05-28 16:54:58 +02:00
Badlop 64f3f3287a Update luerl dependency from v0.3 to v0.4 2021-05-28 16:53:09 +02:00
Badlop 1befa8d8b7 Update lager dependency from 3.6.10 to 3.9.1 to make Dialyzer happy 2021-05-28 16:51:59 +02:00
Holger Weiß 3b5ddf0254 mod_muc_room: Don't leak owner JIDs (#3615)
Avoid publishing room owner JIDs (via the muc#roominfo form) without
their explicit consent.

Closes #3609.
2021-05-28 16:43:49 +02:00
Badlop 33fd45a960 Remove .travis.yml as it's superseded by ci.yml (#3613) 2021-05-25 19:16:06 +02:00
Badlop 77ef03e104 New ci.yml with all static and dynamic testing suites (#3613)
It supports all that was already in .travis.yml and tests.yml, plus:
- exclude paths that don't affect source code
- two very distinct scenarios, ancient a recent (OTP, Rebar, Ubuntu)
- cache binaries and dialyzer for small speedup and network usage
- separated results, to view comfortably where and what failed
- use coveralls example rebar3 code, instead of custom rebar2
- upload binaries.zip that can be used with Binary Installers
2021-05-25 18:45:31 +02:00
Badlop 70640e71f1 Remove tests.yml github workflow, a new reworked one is coming (#3613) 2021-05-25 18:40:28 +02:00
Badlop 1ee64091b3 Fix extauth.py failure in test suite with Python 3 (#3612) 2021-05-25 18:39:18 +02:00
Nikat 7b33499811 MySQL Backend Patch for scram-sha512 (#3582)
* Update mysql.new.sql

scram-sha512 does not work, because serverkey is longer, then that array. All passwords was unhashed.

* Update mysql.sql
2021-05-20 13:32:50 +02:00
Badlop d94bae241c Align numbers in WebAdmin tables to the right 2021-05-19 15:00:22 +02:00
Badlop 58a623778f Show uptime date in WebAdmin, it's easier to understand that uptime seconds 2021-05-19 15:00:19 +02:00
Badlop 494ba9a635 Show mnesia table memory in bytes, not in words 2021-05-19 15:00:16 +02:00
Paweł Chmielowski 95fa43aa96 Add missing indexes to sql sr_group tables 2021-05-18 18:29:32 +02:00
Badlop 16af8a4739 New simple webadmin pages to view mnesia tables information and content 2021-05-17 16:16:26 +02:00
Badlop 57202d958a Use G macro name for tag, as T overlapped T from translation 2021-05-17 16:14:39 +02:00
Badlop d741f6f5f2 Update documentation references for import_prosody and export2sql 2021-05-14 16:07:03 +02:00
Badlop 20b4deffe3 Apply improvement from 29462f005 to delete/2, and fix delete/3 (#3564) 2021-05-14 16:06:59 +02:00
Badlop ee3796b925 When exporting for SQLite, use its specific escape options (#2576) 2021-05-14 16:06:43 +02:00
Badlop 8e08703833 Tell io_lib:print to not care about line length, to avoid newlines in SQL export 2021-05-14 16:06:39 +02:00
Paweł Chmielowski 3b716d2cb0 Update econf:vcard() to generate correct vcard_temp record 2021-05-12 21:46:36 +02:00
Paweł Chmielowski 0f51a03d08 Update xmpp to bring updated vcard 2021-05-12 18:05:11 +02:00
Mickaël Rémond 20247af6f6 Use the new Github container registry 2021-05-12 11:51:40 +02:00
Mickaël Rémond 2698024b82 Use latest version of the container
This is the only image available for now
2021-05-12 11:22:45 +02:00
Mickaël Rémond a142dc4b11 Remove set up already set in prebuilt image 2021-05-12 11:17:26 +02:00
Mickaël Rémond 2844a2d73e Use a prebuilt image 2021-05-12 11:16:46 +02:00
Badlop 160cd11c83 Minor fixes for new_sql_schema support in SQLite (#3303) 2021-05-11 18:36:16 +02:00
Badlop 4fdebd296a Document that update_sql command only supports postgresql (#3439) 2021-05-11 18:36:14 +02:00
Badlop b18f622984 Use the deps versions defined in rebar.config, not the latest available 2021-05-11 18:36:11 +02:00
Badlop f61607df65 Don't add ejabberd version in API page either, following 3e4ebfae7 2021-05-11 18:36:08 +02:00
Mickaël Rémond 5d0c0eb03d Expose port label 2021-05-11 09:00:44 +00:00
Mickaël Rémond ef1d9a0723 Ignore basic Mnesia directory 2021-05-11 08:32:44 +00:00
Mickaël Rémond 5465e7ed2f Forward XMPP legacy SSL and MQTT ports 2021-05-11 08:29:38 +00:00
Mickaël Rémond 7edd9e3766 Install Erlang and Elixir VSCode extensions as default 2021-05-11 08:06:44 +00:00
Mickaël Rémond 7a6425544c Remove file syntax deprecation 2021-05-11 08:06:16 +00:00
Mickaël Rémond 97e7f25e6e Merge pull request #3595 from processone/codespaces
Codespaces
2021-05-11 09:50:46 +02:00
Badlop 916653e234 Cast as boolean when exporting privacy_list_data to PostgreSQL (#1773) 2021-05-10 12:04:52 +02:00
Badlop 6db228fcb3 Document that sql_ssl can be used with MySQL too 2021-05-05 11:57:08 +02:00
Badlop c2821be94c Use the new 'note' field to annotate changes in 20.01..21.03 2021-05-05 11:57:05 +02:00
Badlop 999d0af502 New 'note' field in commands and options documentation 2021-05-05 11:57:02 +02:00
Paweł Chmielowski 78c09789f7 Fix invalid_encoding error when using extended plane characters in vcard. 2021-04-29 14:21:37 +02:00
Paweł Chmielowski 5a8f1ca528 Display extender error message in ejabberdctl
This for example makes error from register explain what account
can't be registered

For reference https://github.com/processone/ejabberd/discussions/3584
2021-04-22 11:56:58 +02:00
badlop 2d38d48a55 Merge pull request #3578 from tappytaps/srg-cache-fix
Fixed srg_create params and shared roster groups cache issues
2021-04-20 21:22:25 +02:00
Jindrich Sarson dcc5d8704f delete cache after performing change to be sure that in cache will be up to date data 2021-04-17 19:07:21 +02:00
Jindrich Sarson c10e4fa275 update srg_create API to use label parameter instead of name 2021-04-17 18:49:26 +02:00
Paweł Chmielowski e462f0a584 Fix dialyzer warnings 2021-04-16 11:55:48 +02:00
Paweł Chmielowski 45bbbd0284 Fix syntax not recognized by older erlang 2021-04-16 10:46:28 +02:00
Paweł Chmielowski 5b0f0d8352 Improve database and caching in mod_shared_roster
This makes us keep cache of groups that use wildcards no matter
of cache settings, and tries to not same fetch data multiple times
in roster get operations.
2021-04-16 10:34:32 +02:00
Paweł Chmielowski 54916caf65 Use proper source for cache options in mod_shared_roster 2021-04-16 10:20:13 +02:00
Paweł Chmielowski c8afb5ceb6 Reconfigure cache in mod_shared_roster when options change 2021-04-16 10:19:09 +02:00
Badlop b3374e1f99 Remove SMP option from ejabberdctl.cfg, -smp was removed in OTP 21 (#3560) 2021-04-15 20:28:43 +02:00
Badlop 4914b33f8c Support the recent changes in the "ejabberdctl help" command (#3569) 2021-04-15 20:25:54 +02:00
Badlop 0ec69f0279 Major changes in ejabberdctl help output (#3569)
ejabberdctl: show list of commands
ejabberdctl some-command: if wrong number of arguments, shows command help
ejabberdctl help: show explanation of how to use "help"
ejabberdctl help tags: list tags with list of commands
ejabberdctl help commands: list tags with commands details
ejabberdctl help whatever*: filters commands and tags
2021-04-15 20:25:52 +02:00
Badlop 6f565147cb Change tag name because there's already a command called "stats" 2021-04-15 20:25:49 +02:00
Badlop f8a02f5d9d Get the arguments definition from the record (#3569)
This fixes "ejabberdctl help help"
2021-04-15 20:25:47 +02:00
Badlop 327dc31e62 Copy a change from include file available since OTP 17.0
See:
https://github.com/erlang/otp/commit/5e575f65629f6d99ed423bc646219c162f6bfa1a
2021-04-15 20:25:44 +02:00
Mickaël Rémond f77a163341 Update bug_report.md 2021-04-15 15:30:23 +02:00
Mickaël Rémond c280d172b1 Update feature_request.md 2021-04-15 15:30:06 +02:00
Badlop b860a25c82 When using OTP 24.0, use the new 'application' record definition (#3568)
This fixes "ejabberdctl update_list", "update", and the equivalent feature
on ejabberd's WebAdmin that got broken when using Erlang/OTP 24
2021-04-14 17:12:08 +02:00
Mickaël Rémond ab2b499869 Update devcontainer.json 2021-04-13 10:25:05 +02:00
Mickaël Rémond 0a55e07326 Use Dockerfile 2021-04-13 08:24:01 +00:00
Mickaël Rémond 22cc7cedff Use Dockerfile 2021-04-12 09:54:06 +00:00
Mickaël Rémond cdbfd91ec4 Update devcontainer.json
Disable docker compose for now
2021-04-12 11:45:59 +02:00
Mickaël Rémond 9359bab677 Create docker-compose.yml 2021-04-12 11:44:10 +02:00
Robert Schuh 0e93f70e38 allow shared roster group placeholder in mqtt topic 2021-04-08 23:21:15 +02:00
Holger Weiss 10905b0447 mod_push: Handle MUC/Sub events correctly
Unwrap MUC/Sub messages so that our check for a message body yields the
correct result.

Many thanks to Robert Schuh for pointing out the issue and suggesting a
fix.

Closes #3565.
2021-04-08 19:36:16 +02:00
Jérôme Sautret 4468c87115 Set version to 21.04
Tests / Dialyzer (19.3) (push) Has been cancelled
Tests / Dialyzer (latest) (push) Has been cancelled
2021-04-07 17:23:30 +02:00
Badlop 4b83ec1204 New Albanian translation (thanks to Besnik Bleta) 2021-04-07 16:01:28 +02:00
Paweł Chmielowski 03e62308e2 Update deps in mix 2021-04-07 12:14:58 +02:00
badlop c0dafc074d Merge pull request #3558 from fdie/fix_node_get_state_return_value
fix gen_pubsub_node:get_state return value
2021-03-29 15:52:04 +02:00
Badlop 3bb89010fe Recompile man page with "ejabberdctl man" 2021-03-26 11:05:49 +01:00
Badlop 3e4ebfae7e Revert "Add ejabberd version number to man pages"
That versioning just added noise to the git log in each release.
This reverts commit aa0ed37034.
2021-03-26 11:01:45 +01:00
Badlop c64df48978 Run "make translations", and *.msg get a warning to not edit them manually 2021-03-26 10:50:06 +01:00
Badlop 1c74bb7131 Update Japanese translation (thanks to Mako N) 2021-03-26 10:48:00 +01:00
Badlop f577715468 Update Greek translation (thanks to Michalis and Stratos Kostidis) 2021-03-26 10:47:13 +01:00
Badlop 1cd4f730b9 Update Esperanto translation (thanks to phlostically) 2021-03-26 10:46:48 +01:00
fdie edae3c9cc5 fix gen_pubsub_node:get_state return value 2021-03-25 14:32:24 +01:00
Badlop 815030a4f0 I think no need to be so strict in mix dependencies versions 2021-03-24 23:03:53 +01:00
Badlop 82bd7e5d5b Update rebar dependencies 2021-03-24 23:03:46 +01:00
Badlop 453d504fb7 No need to ignore ejabberd.app.src, it was recently removed, see 3c16f214 2021-03-19 15:13:20 +01:00
Badlop 627564983b No need to ignore XmppAddr*, it was removed in 2018, see 0bb14d16 2021-03-19 15:13:18 +01:00
Badlop 7e8b59a0aa No need to ignore extract_translations, it was removed in 2017, see cd098c5a 2021-03-19 15:13:15 +01:00
Badlop 9bf37d7fdf No need to ignore doc/, it was removed in 2015! See 1854b5e4 2021-03-19 15:13:04 +01:00
Badlop 02830a8b76 Tell git to ignore .deps-update/ used by tools/update-deps-releases.pl 2021-03-19 15:12:52 +01:00
Badlop d8f01080ce Cache rebar2 deps/ dir in Travis for a 10% speedup approx. 2021-03-19 15:12:50 +01:00
Badlop 1f88a26f60 When unregistering XMPP account close its MQTT sessions (#3426) 2021-03-19 15:12:48 +01:00
Badlop c6f2d0c3eb Improve wording of sql_pool_size option documentation (#2541) 2021-03-19 15:12:43 +01:00
Badlop 13e1307ab1 When occupant is banned, remove his subscriptions too (#2451) 2021-03-18 16:15:17 +01:00
Badlop f6c6ff561a Document that send_stanza_c2s requires an existing sender C2S session 2021-03-18 16:15:07 +01:00
Badlop c4d45ec08c Revert "Close pgsql ports on ejabberd_sql process termination (#2541)"
This reverts commit 404ae56e07.
2021-03-18 16:14:49 +01:00
Holger Weiss 7008ae231c Don't fail on PEP unsubscribe
Don't crash if a PEP node is explicitly unsubscribed.  This fixes a
regression introduced by 45eb49125b.

Thanks to Melvin Keskin for reporting the bug.
2021-03-16 17:26:47 +01:00
Badlop 14c8e1226f Generate enabled_backends in ejabberd.app instead of configure (#3549)
Passing a list of atoms in vars.config.in (introduced in 3c16f214)
breaks rebar2 in "make rel"
2021-03-15 10:11:05 +01:00
Badlop 8b78d27f30 Update Elixir logger, so logging should work now 2021-03-12 20:50:54 +01:00
Badlop 2fbd447f64 Update gitignore for Elixir, mnesiadb/ was renamed to database/ in ef6af11f1 2021-03-12 20:50:51 +01:00
Badlop 14d82fa600 Add mod_doc/0 to mod_presence_demo.ex so compiler stops complaining 2021-03-12 20:50:49 +01:00
Badlop 33fc320f1d Update jiffy and epam to fix compilation (#3413) 2021-03-12 20:50:46 +01:00
Badlop 9fbea40721 Sort dependencies alphabetically, it makes manual checking easier 2021-03-12 20:50:44 +01:00
Badlop 9525978f26 Fix INTRUDER and add padding to second text line
https://github.com/processone/ejabberd/commit/b41ce8828c579f06a33ca93a7af4fd5984997e16#r47461104
2021-03-12 20:50:41 +01:00
badlop 75a4e23996 Merge pull request #3458 from nosnilmot/sqlite3-macos
Remove external dependency on sqlite3 for macos
2021-03-09 01:18:00 +01:00
Badlop 404ae56e07 Close pgsql ports on ejabberd_sql process termination (#2541) 2021-03-09 00:58:36 +01:00
Badlop 2946df357c Update FORM_TYPE from captcha to register (#3045) 2021-03-09 00:58:31 +01:00
Badlop 5318bf3743 If stanza is type error, allow it passing (#3290) 2021-03-09 00:58:22 +01:00
Badlop 0f43c2c528 New command get_user_subscriptions (#3403) 2021-03-09 00:57:41 +01:00
Badlop b5da0ffd7e Show in WebAdmin the erlang node where the room resides
https://www.ejabberd.im/forum/29687/muc-mangement#comment-67685
2021-03-09 00:57:35 +01:00
Badlop 7ee018ad23 Obtain and provide photo type in vCard LDAP (#3541) 2021-03-08 16:33:30 +01:00
Badlop 31884f6c9d Fix remove_mam_for_user_with_peer when removing room archive (#3536) 2021-03-08 16:33:23 +01:00
Badlop c46bf7d56b Remove support for HiPE, it was experimental and Erlang/OTP 24 removes it 2021-03-08 16:33:16 +01:00
Badlop 1b155ed6e7 Add --enable-lua, and use that for luerl instead of --enable-tools (#3508)
--enable-tools is for development tools, but prosody2ejabberd is used at
runtime, so better move luerl to --enable-lua
2021-03-08 16:33:06 +01:00
Badlop e648cd7397 Sort libraries alphabetically, so they're easier to check manually 2021-03-08 16:33:03 +01:00
Badlop 3c248745e5 crypto:hmac is removed in Erlang/OTP 24, use our wrapper 2021-03-04 16:41:27 +01:00
Badlop c45b526ec3 Update sql_query record to handle the Erlang/OTP 24 compiler reports
As mentioned in the Erlang/OTP 24 announcement:
"Compiler warnings and errors now include column numbers
in addition to line numbers."
2021-03-04 16:41:24 +01:00
Badlop bf1600891b Get back description and simplify processing (#3507) 2021-03-04 16:41:22 +01:00
Badlop b139eb2fb3 Tell git to ignore rebar.lock used by rebar3 2021-03-04 16:41:19 +01:00
Badlop 9bd4f60c8a Added badges for github actions, coveralls.io and weblate 2021-03-04 16:41:15 +01:00
Paweł Chmielowski ca5d5f3b4c Use monitors to track muc rooms
This should prevent keeping rooms that were hard killed from in
online table.
2021-03-03 11:32:05 +01:00
badlop 7209486386 Merge pull request #3507 from slezakattack/master
Allow ejabberd to be compatible as a dependency for an Erlang project…
2021-03-02 19:01:33 +01:00
Badlop bb8bdf57b3 New Github Actions workflow to test Dialyzer, Xref, Options and Hooks 2021-02-23 19:45:53 +01:00
Badlop c8bec07c45 Clone to the dir specified in rebar.config... useful for erlang-sqlite3 2021-02-23 19:45:41 +01:00
Holger Weiß b41ce8828c Add question/answer-based CAPTCHA script (#3533)
* New captcha.sh question/answer based

* Keep original CAPTCHA script

Rather than replacing the original CAPTCHA script, keep it next to the
new one, for the moment.

* CAPTCHA-ng script cleanup

* remove various bashisms
* replace all echos with printf
+ add quotations to many variables

Co-authored-by: Adrien Bourmault <neox@os-k.eu>
Co-authored-by: nico wellpott <nico@magicbroccoli.de>
2021-02-22 09:34:02 +01:00
Badlop 3720b42b0f When using rebar3, "make dialyzer" needs just a single call 2021-02-19 17:00:39 +01:00
Badlop 69be0abdba Fix Dialyzer warning about function contract that changed in fad14ff31 2021-02-19 17:00:35 +01:00
Badlop 09f5e2aa03 Improve support for rebar3 in "make translations" 2021-02-19 17:00:32 +01:00
Paweł Chmielowski 7da033f733 Fix muc tests 2021-02-17 13:09:29 +01:00
Paweł Chmielowski 14871c54ac Take in account subscriber's affiliation when checking access to moderated room
This should fix issue #3525
2021-02-17 10:45:30 +01:00
Michael Slezak 3c16f21413 Allow ejabberd to be compatible as a dependency for an Erlang project using rebar3 2021-02-16 10:28:30 -07:00
Paweł Chmielowski 14d87cb5e9 Skip reading roster in one more case in mod_caps 2021-02-16 13:39:34 +01:00
Badlop 72ecf91f08 Return modules errors in set_vcard callback (#3502) 2021-02-16 13:09:33 +01:00
Badlop 4bc57f76eb make hooks and options work with rebar3 too 2021-02-16 13:09:30 +01:00
Badlop 18c9f5eedf Create annotated tags, meant for releases, instead of lightweight (#3512) 2021-02-16 13:09:27 +01:00
Badlop 4495f0f0b9 For OTP<22 define LAGER macro in ext_mod like in rebar.config (#3493) 2021-02-16 13:09:21 +01:00
Paweł Chmielowski fad14ff319 Make fetching roster in mod_privacy lazy 2021-02-16 10:57:55 +01:00
Paweł Chmielowski 8cb7ff7a88 Add fallback branch to last commit 2021-02-16 10:40:35 +01:00
Paweł Chmielowski 96929a5084 Don't request roster in mod_caps when not needed 2021-02-16 10:13:29 +01:00
Stu Tomlinson 1f194e417d fix eldap certificate verification (#3528)
Reported in #3527. Add hostname matching function, and specify SNI

Also, OTP 23 dropped backwards compatibility for 0, 1, 2 values for verify, so
replace with combination of verify_none/verify_peer and fail_if_no_peer_cert
as appropriate
2021-02-15 14:29:58 +01:00
Badlop e3fd120fd4 According to fast_tls, only atom and binary may accompany error tuple 2021-02-11 20:38:51 +01:00
Badlop 7b8bd960c6 Fix URL of CAPTCHA section 2021-02-11 20:38:45 +01:00
Paweł Chmielowski d147c733bb Update xmpp 2021-02-10 10:10:24 +01:00
Paweł Chmielowski 3d7fa15be7 Add argument guards to roster commands 2021-02-09 13:46:23 +01:00
Stu Tomlinson 6a0b01fe7f Move sql directory from extra_src_dirs to src_dirs (#3520)
rebar3 needs sql directory as a src dir so that tests can reference sql
files, so sql dir was added to extra_src_dirs in d9c1befb. It turns out
extra_src_dirs does unexpected unwanted extra things like copy all beam
files there too, so move sql dir to regular src_dirs
2021-02-08 13:02:50 +01:00
Frank 2d79a69719 Fix PONG responses (#3515)
Co-authored-by: Frank Diebolt <frank.diebolt@al-enterprise.com>
2021-02-04 19:57:20 +01:00
Badlop a51e777c56 Try to fix coveralls report in Travis, related to commit 2f3f6f8b7 2021-02-04 11:27:47 +01:00
Badlop 1c3a7b7c96 Use the mysql service available in Travis
Xenial in Travis nowadays includes mysql 5.7
Reverted "Let Travis grab MySQL 5.6 from repo.mysql.com"
Reverted "Use static key for mysql repo" and related ones
2021-02-02 19:03:14 +01:00
Badlop 26ee3141a9 Improve prepare-tr so *.msg files inform to not edit them (#3484) 2021-02-02 18:58:36 +01:00
Badlop 75c0443df2 Test against newest 23.1.2, and remove useless intermediate 22.3 2021-02-02 18:58:32 +01:00
Marek 5eab8450e7 New listener for encrypted ejabberd_c2s
Add a new listener on port 5223 for the TLS-enabled ejabberd_c2s, which combined with proper SRV records allows passing the XEP-0368 compliance test.
2021-02-02 15:25:19 +01:00
Divine 22d76bd1a4 Fix specified key was too long (#3513)
* Fix specified key was too long

This adds the correct engine and sets it to utf8mb4 collate. Prevents "Specified key was too long; max key length is 1000 bytes" from happening.

* Make two import SQL files consistent 

As suggested by @prefiks
2021-02-01 22:50:33 +01:00
Badlop bb397bb424 Fix bug handling jid:decode/1 return, introduced in cdb286d1d (#3461) 2021-02-01 00:10:33 +01:00
Badlop b3d9c0d1f7 Fix bug in send_message introduced in 7fc500dae (#3485) 2021-02-01 00:09:18 +01:00
Badlop d3aeed839d Fix MAM tests that now fail due to commit d6e9e0342 (#3506) 2021-02-01 00:09:10 +01:00
Badlop c0b364839c Fix typo in Weblate URL 2021-02-01 00:08:22 +01:00
Holger Weiss 6a6b771e0b mod_mam: Add missing semicolon 2021-01-29 20:27:07 +01:00
Holger Weiss 58e28e82bb Merge remote-tracking branch 'processone/pr/3506'
* processone/pr/3506:
  Remove queryid from MAM fin element
2021-01-29 19:25:40 +01:00
Paul Fariello d6e9e03422 Remove queryid from MAM fin element
According to xep, fin element is not supposed to have a queryid attribute.
2021-01-29 19:21:45 +01:00
Stu Tomlinson 1f60f5d8af Remove external dependency on sqlite3 for macos
On macos, erlang-sqlite3 is built using amalgamated sqlite3 library, there is
no external sqlite3 dependency required
2020-12-23 12:41:13 +00:00
132 changed files with 4028 additions and 1615 deletions
+2 -40
View File
@@ -1,42 +1,4 @@
# Update the VARIANT arg in docker-compose.yml to pick an Elixir version: 1.9, 1.10, 1.10.4
# Update the VARIANT arg to pick an Elixir version: latest, 1.11.4, etc.
ARG VARIANT=latest
FROM elixir:${VARIANT}
# This Dockerfile adds a non-root user with sudo access. Update the “remoteUser” property in
# devcontainer.json to use it. More info: https://aka.ms/vscode-remote/containers/non-root-user.
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID
# Options for common package install script
ARG INSTALL_ZSH="true"
ARG UPGRADE_PACKAGES="true"
ARG COMMON_SCRIPT_SOURCE="https://raw.githubusercontent.com/microsoft/vscode-dev-containers/master/script-library/common-debian.sh"
ARG COMMON_SCRIPT_SHA="dev-mode"
# Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies.
RUN apt-get update \
&& export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends curl ca-certificates 2>&1 \
&& curl -sSL ${COMMON_SCRIPT_SOURCE} -o /tmp/common-setup.sh \
&& ([ "${COMMON_SCRIPT_SHA}" = "dev-mode" ] || (echo "${COMMON_SCRIPT_SHA} */tmp/common-setup.sh" | sha256sum -c -)) \
&& /bin/bash /tmp/common-setup.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" \
#
# Install dependencies
&& apt-get install -y build-essential \
#
# Clean up
&& apt-get autoremove -y \
&& apt-get clean -y
#RUN su ${USERNAME} -c "mix local.hex --force \
# && mix local.rebar --force \
# && mix archive.install --force hex phx_new ${PHOENIX_VERSION}"
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update \
# && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment this line to install additional package.
# RUN mix ...
FROM ghcr.io/processone/elixir:${VARIANT}
+36 -4
View File
@@ -1,16 +1,48 @@
{
"name": "ejabberd",
"dockerComposeFile": "docker-compose.yml",
// "dockerComposeFile": "docker-compose.yml",
"build": {
"dockerfile": "Dockerfile",
"args": {
"VARIANT": "latest" // 1.11.4
}
},
"workspaceFolder": "/workspace",
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/bin/zsh",
"terminal.integrated.defaultProfile.linux": "/bin/zsh",
},
// Add the IDs of extensions you want installed when the container is created.
// "extensions": [],
"extensions": ["pgourlain.erlang", "jakebecker.elixir-ls"],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [5222, 5280, 5269],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "sh .devcontainer/post-create.sh",
// Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root.
"remoteUser": "vscode"
"remoteUser": "vscode",
"portsAttributes": {
"1883": {
"label": "MQTT"
},
"5222": {
"label": "XMPP C2S"
},
"5223": {
"label": "Legacy XMPP C2S"
},
"5269": {
"label": "XMPP S2S"
},
"5280": {
"label": "ejabberd HTTP"
},
"5443": {
"label": "ejabberd HTTPS"
}
}
}
+8
View File
@@ -0,0 +1,8 @@
ejabberd:
image: ejabberd/ecs
ports:
- 5222:5222
- 5223:5223
- 5269:5269
- 5280:5280
- 1883:1883
+3
View File
@@ -6,6 +6,9 @@ assignees: ''
---
Before creating a ticket, please consider if this should fit the discussion forum better:
https://github.com/processone/ejabberd/discussions
## Environment
- ejabberd version: 18.09
@@ -7,6 +7,9 @@ assignees: ''
---
Before creating a ticket, please consider if this should fit the discussion forum better:
https://github.com/processone/ejabberd/discussions
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+238
View File
@@ -0,0 +1,238 @@
name: CI
on:
push:
paths-ignore:
- '.devcontainer/**'
- 'examples/**'
- 'lib/**'
- 'man/**'
- 'priv/**'
- '**.md'
pull_request:
paths-ignore:
- '.devcontainer/**'
- 'examples/**'
- 'lib/**'
- 'man/**'
- 'priv/**'
- '**.md'
jobs:
tests:
name: Tests
strategy:
fail-fast: false
matrix:
otp: ['19.3', '24.0']
include:
- otp: '19.3'
rebar: 2
os: ubuntu-18.04
- otp: '24.0'
rebar: 3
os: ubuntu-20.04
runs-on: ${{ matrix.os }}
services:
redis:
image: redis
ports:
- 6379:6379
steps:
- uses: actions/checkout@v2
- name: Get previous Erlang/OTP
uses: ErlGang/setup-erlang@master
if: matrix.otp != 24.0
with:
otp-version: ${{ matrix.otp }}
- name: Prepare databases
run: |
sudo systemctl start mysql.service
sudo systemctl start postgresql.service
mysql -u root -proot -e "CREATE USER 'ejabberd_test'@'localhost'
IDENTIFIED BY 'ejabberd_test';"
mysql -u root -proot -e "CREATE DATABASE ejabberd_test;"
mysql -u root -proot -e "GRANT ALL ON ejabberd_test.*
TO 'ejabberd_test'@'localhost';"
mysql -u root -proot ejabberd_test < sql/mysql.sql
pg_isready
sudo -u postgres psql -c "CREATE USER ejabberd_test
WITH PASSWORD 'ejabberd_test';"
sudo -u postgres psql -c "CREATE DATABASE ejabberd_test;"
sudo -u postgres psql ejabberd_test -f sql/pg.sql
sudo -u postgres psql -c "GRANT ALL PRIVILEGES
ON DATABASE ejabberd_test TO ejabberd_test;"
sudo -u postgres psql ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL
TABLES IN SCHEMA public
TO ejabberd_test;"
sudo -u postgres psql ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL
SEQUENCES IN SCHEMA public
TO ejabberd_test;"
- name: Prepare libraries
run: |
sudo apt-get -qq update
sudo apt-get -qq install libexpat1-dev libgd-dev libpam0g-dev \
libsqlite3-dev libwebp-dev libyaml-dev
- name: Prepare rebar
id: rebar
run: |
echo '{xref_ignores, [{eldap_filter_yecc, return_error, 2}
]}.' >>rebar.config
echo '{xref_checks, [deprecated_function_calls, deprecated_functions,
locals_not_used, undefined_function_calls, undefined_functions]}.
% Disabled: exports_not_used,' >>rebar.config
echo '{dialyzer, [{get_warnings, true}, {plt_extra_apps, [cache_tab,
eimp, epam, esip, ezlib, fast_tls, fast_xml, fast_yaml,
mqtree, p1_acme, p1_mysql, p1_oauth2, p1_pgsql, p1_utils, pkix,
sqlite3, stringprep, stun, xmpp, yconf]} ]}.' >>rebar.config
echo '{ct_extra_params, "-verbosity 20"}.' >>rebar.config
- name: Cache rebar2
if: matrix.rebar == 2
uses: actions/cache@v2
with:
path: |
deps/
dialyzer/
ebin/
key: ${{matrix.otp}}-${{matrix.rebar}}-${{hashFiles('rebar.config')}}
- name: Cache rebar3
if: matrix.rebar == 3
uses: actions/cache@v2
with:
path: ~/.cache/rebar3/
key: ${{matrix.otp}}-${{matrix.rebar}}-${{hashFiles('rebar.config')}}
- name: Compile
run: |
./autogen.sh
[[ ${{ matrix.rebar }} = 2 ]] && REBAR=rebar || REBAR=`which rebar3`
./configure --with-rebar=$REBAR \
--prefix=/tmp/ejabberd \
--enable-all \
--disable-elixir \
--disable-odbc
make update
make
- run: make rel
- run: make install -s
- run: make hooks
- run: make options
- run: make xref
- run: make dialyzer
- run: make test
- name: Check results
if: always()
run: |
[[ -d _build ]] && ln -s _build/test/logs/ logs \
&& ln `find _build/ -name "*dialyzer_warnings"` \
logs/dialyzer.log \
|| ln dialyzer/error.log logs/dialyzer.log
ln `find logs/ -name suite.log` logs/suite.log
grep 'TEST COMPLETE' logs/suite.log
grep -q 'TEST COMPLETE,.* 0 failed' logs/suite.log
test $(find logs/ -empty -name error.log)
- name: View dialyzer report
run: cat logs/dialyzer.log
- name: View full suite.log
run: cat logs/suite.log
- name: View suite.log failures
if: failure()
run: cat logs/suite.log | awk
'BEGIN{RS="\n=case";FS="\n"} /=result\s*failed/ {print "=case" $0}'
- name: View full ejabberd.log
if: failure()
run: find logs/ -name ejabberd.log -exec cat '{}' ';'
- name: View exunit.log
if: failure()
run: find logs/ -name exunit.log -exec cat '{}' ';'
- name: Send to coveralls
if: matrix.otp == 24.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
rebar3 as test coveralls send
curl -v -k https://coveralls.io/webhook \
--header "Content-Type: application/json" \
--data '{"repo_name":"$GITHUB_REPOSITORY",
"repo_token":"$GITHUB_TOKEN",
"payload":{"build_num":$GITHUB_RUN_ID,
"status":"done"}}'
binaries:
name: Binaries
needs: [tests]
strategy:
fail-fast: false
matrix:
otp: ['21.3']
include:
- otp: '21.3'
rebar: 3
os: ubuntu-20.04
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 150
- name: Get last git tag
run: |
export TAGLAST=`git ls-remote --tags --refs origin 'refs/tags/2*' \
| tail -1 | awk '{print $2}'`
git fetch origin "$TAGLAST:$TAGLAST"
git describe
- name: Get previous Erlang/OTP
uses: ErlGang/setup-erlang@master
with:
otp-version: ${{ matrix.otp }}
- name: Get a compatible Rebar3
run: |
wget https://github.com/erlang/rebar3/releases/download/3.15.2/rebar3 \
&& chmod +x rebar3
- name: Cache Rebar3
uses: actions/cache@v2
with:
path: ~/.cache/rebar3/
key: ${{matrix.otp}}-${{matrix.rebar}}-${{hashFiles('rebar.config')}}
- name: Prepare libraries
run: |
sudo apt-get -qq update
sudo apt-get -qq install libexpat1-dev libgd-dev libpam0g-dev \
libsqlite3-dev libwebp-dev libyaml-dev
- name: Compile
run: |
./autogen.sh
./configure --with-rebar=./rebar3 \
--prefix=/tmp/ejabberd \
--disable-debug \
--enable-all \
--disable-elixir
make update
make
- run: make install -s
- name: Strip binaries
run: echo 'beam_lib:strip_files(filelib:wildcard(
"/tmp/ejabberd/lib/*/ebin/*beam")), init:stop().' \
| erl -boot start_clean
- name: Upload binaries
uses: actions/upload-artifact@v2
with:
name: ejabberd-binaries
path: /tmp/ejabberd/lib
retention-days: 7
+9 -19
View File
@@ -9,41 +9,31 @@
/Makefile
/config.log
/config.status
/config/releases.exs
/configure
/aclocal.m4
/contrib/extract_translations/extract_translations.beam
/*.cache
/deps/
/doc/*.aux
/doc/*.haux
/doc/*.html
/doc/*.htoc
/doc/*.idx
/doc/*.ilg
/doc/*.ind
/doc/*.log
/doc/*.out
/doc/*.pdf
/doc/*.toc
/doc/contributed_modules.tex
/doc/version.tex
/.deps-update/
/ebin/
/ejabberd.init
/ejabberd.service
/ejabberdctl
/ejabberdctl.example
XmppAddr.hrl
/rel/ejabberd/
/src/XmppAddr.asn1db
/src/XmppAddr.erl
/src/ejabberd.app.src
/rel/overlays/
/src/eldap_filter_yecc.erl
/vars.config
/dialyzer/
/test/*.beam
/test/*.ctc
/logs/
/priv/bin/captcha*sh
/priv/sql
/rel/ejabberd
/_build
/mnesiadb
/database/
/.rebar
/rebar.lock
/log/
Mnesia.nonode@nohost/
-77
View File
@@ -1,77 +0,0 @@
language: erlang
otp_release:
- 19.3
- 22.3
- 23.0
os: linux
dist: xenial
services:
- redis
- postgresql
before_install:
#
# We need MySQL 5.6 or newer in order to get support for FULLTEXT indexes
# with InnoDB. As soon as Travis ships that version, the following lines
# (except for the "apt-get update" call) can go away.
#
# See: https://github.com/travis-ci/travis-ci/issues/1986
#
- sudo sed -i -e s/table_cache/table_open_cache/ -e /log_slow_queries/d /etc/mysql/my.cnf
- sudo apt-key adv --import .travis/mysql_repo_key.asc
- sudo add-apt-repository 'deb http://repo.mysql.com/apt/ubuntu/ precise mysql-5.6'
- sudo apt-get -qq update
- sudo apt-get -qq -o Dpkg::Options::=--force-confold install mysql-server
- sudo service mysql start
- sudo mysql_upgrade
# /END MYSQL 5.6
- pip install --user coveralls-merge
install:
- sudo apt-get -qq install libexpat1-dev libyaml-dev libpam0g-dev libsqlite3-dev libgd-dev libwebp-dev
before_script:
# Ulimit: See Travis-CI issue report: https://github.com/travis-ci/travis-ci/issues/3328
- mysql -u root -e "CREATE USER 'ejabberd_test'@'localhost' IDENTIFIED BY 'ejabberd_test';"
- mysql -u root -e "CREATE DATABASE ejabberd_test;"
- mysql -u root -e "GRANT ALL ON ejabberd_test.* TO 'ejabberd_test'@'localhost';"
- mysql -u root ejabberd_test < sql/mysql.sql
- psql -U postgres -c "CREATE USER ejabberd_test WITH PASSWORD 'ejabberd_test';"
- psql -U postgres -c "CREATE DATABASE ejabberd_test;"
- psql -U postgres ejabberd_test -f sql/pg.sql
- psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE ejabberd_test TO ejabberd_test;"
- psql -U postgres ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO ejabberd_test;"
- psql -U postgres ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO ejabberd_test;"
script:
- ./autogen.sh
- ./configure --prefix=/tmp/ejabberd --enable-all --disable-odbc --disable-elixir
- make
- make install -s
- make xref
- ./tools/hook_deps.sh ebin
- sed -i -e 's/ct:pal/ct:log/' test/suite.erl
- ln -sf ../sql priv/
- echo "" >> rebar.config
- echo '{ct_extra_params, "-verbosity 20"}.' >> rebar.config
- escript ./rebar skip_deps=true ct -v
- grep -q 'TEST COMPLETE,.* 0 failed' logs/raw.log
- test $(find logs -empty -name error.log)
after_script:
- find logs -name suite.log -exec cat '{}' ';'
after_failure:
- find logs -name exunit.log -exec cat '{}' ';'
- find logs -name ejabberd.log -exec cat '{}' ';'
- find logs -name suite.log -exec cat '{}' ';' | awk 'BEGIN{RS="\n=case";FS="\n"} /=result\s*failed/ {print "=case" $0}'
after_success:
- coveralls-merge erlang.json
notifications:
email: false
-432
View File
@@ -1,432 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1
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
roUTAKClYAhZuX2nUNwH4vlEJQHDqYa5yQ==
=ghXk
-----END PGP PUBLIC KEY BLOCK-----
+122 -2
View File
@@ -1,8 +1,128 @@
# Version 21.07
Compilation
- Add rebar3 3.15.2 binary
- Add support for mix to: `./configure --enable-rebar=mix`
- Add workaround so rebar2 can use Elixir 1.12.0
- Improved `make rel` to work with rebar3 and mix
- Add `make dev` to build a development release with rebar3 or mix
- Hex: Add `sql/` and `vars.config` to Hex package files
- Hex: Update mix applications list to fix error `p1_utils is listed as both...`
- There are so many targets in Makefile... add `make help`
- Fix extauth.py failure in test suite with Python 3
- Added experimental support for GitHub Codespaces
- Switch test service from TravisCI to GitHub Actions
Commands:
- Display extended error message in ejabberdctl
- Remove SMP option from ejabberdctl.cfg, `-smp` was removed in OTP 21
- `create_room`: After creating room, store in DB if it's persistent
- `help`: Major changes in its usage and output
- `srg_create`: Update to use `label` parameter instead of `name`
Modules:
- ejabberd_listener: New `send_timeout` option
- mod_mix: Improvements to update to 0.14.1
- mod_muc_room: Don't leak owner JIDs
- mod_multicast: Routing for more MUC packets
- mod_multicast: Correctly strip only other bcc addresses
- mod_mqtt: Allow shared roster group placeholder in mqtt topic
- mod_pubsub: Several fixes when using PubSub with RSM
- mod_push: Handle MUC/Sub events correctly
- mod_shared_roster: Delete cache after performing change to be sure that in cache will be up to date data
- mod_shared_roster: Improve database and caching
- mod_shared_roster: Reconfigure cache when options change
- mod_vcard: Fix invalid_encoding error when using extended plane characters in vcard
- mod_vcard: Update econf:vcard() to generate correct vcard_temp record
- WebAdmin: New simple pages to view mnesia tables information and content
- WebSocket: Fix typos
SQL:
- MySQL Backend Patch for scram-sha512
- SQLite: When exporting for SQLite, use its specific escape options
- SQLite: Minor fixes for new_sql_schema support
- mod_privacy: Cast as boolean when exporting privacy_list_data to PostgreSQL
- mod_mqtt: Add mqtt_pub table definition for MSSQL
- mod_shared_roster: Add missing indexes to `sr_group` tables in all SQL databases
# Version 21.04
API Commands:
- `add_rosteritem/...`: Add argument guards to roster commands
- `get_user_subscriptions`: New command for MUC/Sub
- `remove_mam_for_user_with_peer`: Fix when removing room archive
- `send_message`: Fix bug introduced in ejabberd 21.01
- `set_vcard`: Return modules errors
Build and setup:
- Allow ejabberd to be compatible as a dependency for an Erlang project using rebar3
- CAPTCHA: New question/answer-based CAPTCHA script
- `--enable-lua`: new configure option for luerl instead of --enable-tools
- Remove support for HiPE, it was experimental and Erlang/OTP 24 removes it
- Update `sql_query` record to handle the Erlang/OTP 24 compiler reports
- Updated dependencies to fix Dialyzer warnings
Miscellaneous:
- CAPTCHA: Update `FORM_TYPE` from captcha to register
- LDAP: fix eldap certificate verification
- MySQL: Fix for "specified key was too long"
- Translations: updated the Esperanto, Greek, and Japanese translations
- Websocket: Fix PONG responses
Modules:
- `mod_block_strangers`: If stanza is type error, allow it passing
- `mod_caps`: Don't request roster when not needed
- `mod_caps`: Skip reading roster in one more case
- `mod_mam`: Remove `queryid` from MAM fin element
- `mod_mqtt`: When deregistering XMPP account, close its MQTT sessions
- `mod_muc`: Take in account subscriber's affiliation when checking access to moderated room
- `mod_muc`: Use monitors to track online and hard-killed rooms
- `mod_muc`: When occupant is banned, remove his subscriptions too
- `mod_privacy`: Make fetching roster lazy
- `mod_pubsub`: Don't fail on PEP unsubscribe
- `mod_pubsub`: Fix `gen_pubsub_node:get_state` return value
- `mod_vcard`: Obtain and provide photo type in vCard LDAP
# Version 21.01
Miscellaneous changes:
- `log_rotate_size` option: Fix handling of infinity value
- `mod_time`: Fix invalid timezone
- Auth JWT: New `check_decoded_jwt` hook runs the default JWT verifier
- MUC: Allow non-occupant non-subscribed service admin send private MUC message
- MUC: New `max_password` and `max_captcha_whitelist` options
- OAuth: New `oauth_cache_rest_failure_life_time` option
- PEP: Skip reading pep nodes that we know wont be requested due to caps
- SQL: Add sql script to migrate mysql from old schema to new
- SQL: Dont use REPLACE for upsert when there are “-” fields.
- Shared Rosters LDAP: Add multi-domain support (and flexibility)
- Sqlite3: Fix dependency version
- Stun: Block loopback addresses by default
- Several documentation fixes and clarifications
Commands:
- `decide_room`: Use better fallback value for room activity time when skipping room
- `delete_old_message`: Fix when using sqlite spool table
- `module_install`: Make ext_mod compile module with debug_info flags
- `room_unused_*`: Dont fetch subscribers list
- `send_message`: Dont include empty in messages
- `set_room_affiliation`: Validate affiliations
Running:
- Docker: New `Dockerfile` and `devcontainer.json`
- New `ejabberdctl foreground-quiet`
- Systemd: Allow for listening on privileged ports
- Systemd: Integrate nicely with systemd
Translations:
- Moved gettext PO files to a new `ejabberd-po` repository
- Improved several translations: Catalan, Chinese, German, Greek, Indonesian, Norwegian, Portuguese (Brazil), Spanish.
# Version 20.12
- Add support for `SCRAM-SHA-{256,512}-{PLUS}` authentication
- Don't use same value in cache for user don't exist and wrong password
- outgoing_s2s_ipv*_address: New options to set ipv4/ipv6 outbound s2s out interface
- `outgoing_s2s_ipv*_address`: New options to set ipv4/ipv6 outbound s2s out interface
- s2s_send_packet: this hook now filters outgoing s2s stanzas
- start_room: new hook runs when a room process is started
- check_decoded_jwt: new hook to check decoded JWT after success authentication
@@ -10,7 +130,7 @@
* Admin
- Docker: Fix DB initialization
- New sql_odbc_driver option: choose the mssql ODBC driver
- Rebar3: Fully supported. Enable with ./configure --with-rebar=/path/to/rebar3
- Rebar3: Fully supported. Enable with `./configure --with-rebar=/path/to/rebar3`
- systemd: start ejabberd in foreground
* Modules:
+2 -2
View File
@@ -96,10 +96,10 @@ Before you submit your pull request consider the following guidelines:
git push origin my-fix-branch
```
* In GitHub, send a pull request to `ejabberd:master`. This will trigger the Travis integration and run the test.
* In GitHub, send a pull request to `ejabberd:master`. This will trigger the automated testing.
We will also notify you if you have not yet signed the [contribution agreement][cla].
* If you find that the Travis integration has failed, look into the logs on Travis to find out
* If you find that the tests have failed, look into the logs to find out
if your changes caused test failures, the commit message was malformed etc. If you find that the
tests failed or times out for unrelated reasons, you can ping a team member so that the build can be
restarted.
+77 -10
View File
@@ -1,4 +1,5 @@
REBAR = @ESCRIPT@ @rebar@
MIX = @rebar@
INSTALL = @INSTALL@
SED = @SED@
ERL = @ERL@
@@ -97,16 +98,38 @@ ifneq ($(INSTALLGROUP),)
G_USER=-g $(INSTALLGROUP)
endif
IS_REBAR3:=$(shell expr `$(REBAR) --version | awk -F '[ .]' '/rebar / {print $$2}'` '>=' 3)
ifeq "$(MIX)" "mix"
IS_REBAR:=6
else
IS_REBAR:=$(shell expr `$(REBAR) --version | awk -F '[ .]' '/rebar / {print $$2}'`)
endif
ifeq "$(IS_REBAR3)" "1"
ifeq "$(IS_REBAR)" "6"
REBAR=$(MIX)
SKIPDEPS=
LISTDEPS=deps.tree
UPDATEDEPS=deps.update
DEPSPATTERN="s/.*─ \([a-z0-9_]*\) .*/\1/p;"
DEPSBASE=_build
DEPSDIR=$(DEPSBASE)/dev/lib
GET_DEPS= deps.get
CONFIGURE_DEPS=
EBINDIR=$(DEPSDIR)/ejabberd/ebin
REBARREL=MIX_ENV=prod $(REBAR) release --overwrite
REBARDEV=MIX_ENV=dev $(REBAR) release --overwrite
else
ifeq "$(IS_REBAR)" "3"
SKIPDEPS=
LISTDEPS=tree
UPDATEDEPS=upgrade
DEPSPATTERN="s/ (.*//; /^ / s/.* \([a-z0-9_]*\).*/\1/p;"
DEPSBASE=_build
DEPSDIR=$(DEPSBASE)/default/lib
GET_DEPS= get-deps
CONFIGURE_DEPS=$(REBAR) configure-deps
EBINDIR=$(DEPSDIR)/ejabberd/ebin
REBARREL=$(REBAR) as prod tar
REBARDEV=REBAR_PROFILE=dev $(REBAR) release
else
SKIPDEPS=skip_deps=true
LISTDEPS=-q list-deps
@@ -114,7 +137,12 @@ else
DEPSPATTERN="/ TAG / s/ .*// p; / REV / s/ .*// p; / BRANCH / s/ .*// p;"
DEPSBASE=deps
DEPSDIR=$(DEPSBASE)
GET_DEPS= get-deps
CONFIGURE_DEPS=$(REBAR) configure-deps
EBINDIR=ebin
REBARREL=$(REBAR) generate
REBARDEV=
endif
endif
all: deps src
@@ -125,10 +153,10 @@ $(DEPSDIR)/.got:
rm -rf $(DEPSDIR)/.got
rm -rf $(DEPSDIR)/.built
mkdir -p $(DEPSDIR)
$(REBAR) get-deps && :> $(DEPSDIR)/.got
$(REBAR) $(GET_DEPS) && :> $(DEPSDIR)/.got
$(DEPSDIR)/.built: $(DEPSDIR)/.got
$(REBAR) configure-deps
$(CONFIGURE_DEPS)
$(REBAR) compile && :> $(DEPSDIR)/.built
src: $(DEPSDIR)/.built
@@ -143,13 +171,13 @@ xref: all
$(REBAR) $(SKIPDEPS) xref
hooks: all
tools/hook_deps.sh ebin
tools/hook_deps.sh $(EBINDIR)
options: all
tools/opt_types.sh ejabberd_option ebin
tools/opt_types.sh ejabberd_option $(EBINDIR)
translations:
tools/prepare-tr.sh
tools/prepare-tr.sh $(DEPSDIR)
edoc:
$(ERL) -noinput +B -eval \
@@ -212,13 +240,16 @@ $(sort $(call TO_DEST,$(MAIN_DIRS) $(DEPS_DIRS))):
$(call TO_DEST,priv/sql/lite.sql): sql/lite.sql $(call TO_DEST,priv/sql)
$(INSTALL) -m 644 $< $@
$(call TO_DEST,priv/sql/lite.new.sql): sql/lite.new.sql $(call TO_DEST,priv/sql)
$(INSTALL) -m 644 $< $@
$(call TO_DEST,priv/bin/captcha.sh): tools/captcha.sh $(call TO_DEST,priv/bin)
$(INSTALL) -m 755 $(O_USER) $< $@
$(call TO_DEST,priv/lua/redis_sm.lua): priv/lua/redis_sm.lua $(call TO_DEST,priv/lua)
$(INSTALL) -m 644 $< $@
copy-files-sub2: $(call TO_DEST,$(DEPS_FILES) $(MAIN_FILES) priv/bin/captcha.sh priv/sql/lite.sql priv/lua/redis_sm.lua)
copy-files-sub2: $(call TO_DEST,$(DEPS_FILES) $(MAIN_FILES) priv/bin/captcha.sh priv/sql/lite.sql priv/sql/lite.new.sql priv/lua/redis_sm.lua)
.PHONY: $(call TO_DEST,$(DEPS_FILES) $(MAIN_DIRS) $(DEPS_DIRS))
@@ -354,14 +385,23 @@ distclean: clean clean-rel
rm -f ejabberdctl.example ejabberd.init ejabberd.service
[ ! -f ../ChangeLog ] || rm -f ../ChangeLog
rel: all
$(REBAR) generate
rel:
$(REBARREL)
DEV_CONFIG = _build/dev/rel/ejabberd/etc/ejabberd/ejabberd.yml
dev $(DEV_CONFIG):
$(REBARDEV)
TAGS:
etags *.erl
Makefile: Makefile.in
ifeq "$(IS_REBAR)" "3"
dialyzer:
$(REBAR) dialyzer
else
deps := $(wildcard $(DEPSDIR)/*/ebin)
dialyzer/erlang.plt:
@@ -400,6 +440,7 @@ dialyzer: erlang_plt deps_plt ejabberd_plt
@dialyzer --plts dialyzer/*.plt --no_check_plt \
--get_warnings -o dialyzer/error.log ebin; \
status=$$? ; if [ $$status -ne 2 ]; then exit $$status; else exit 0; fi
endif
test:
@echo "************************** NOTICE ***************************************"
@@ -411,3 +452,29 @@ test:
.PHONY: src edoc dialyzer Makefile TAGS clean clean-rel distclean rel \
install uninstall uninstall-binary uninstall-all translations deps test \
quicktest erlang_plt deps_plt ejabberd_plt xref hooks options
help:
@echo ""
@echo " [all] Compile dependencies and ejabberd"
@echo " src Compile ejabberd"
@echo " deps Get dependencies"
@echo " update Update dependencies' source code"
@echo " clean Clean binary files"
@echo " distclean Clean completely the development files"
@echo ""
@echo " install Install ejabberd to /usr/local"
@echo " uninstall Uninstall ejabberd (buggy)"
@echo " uninstall-all Uninstall also configuration, logs, mnesia... (buggy)"
@echo ""
@echo " rel Build a production release"
@echo " dev Build a development release"
@echo ""
@echo " edoc Generate edoc documentation (unused)"
@echo " options Generate ejabberd_option.erl"
@echo " translations Extract translation files (requires --enable-tools)"
@echo " tags Generate tags file for text editors"
@echo ""
@echo " dialyzer Run Dialyzer static analyzer"
@echo " hooks Run hooks validator"
@echo " test Run Common Tests suite"
@echo " xref Run cross reference analysis"
+25 -5
View File
@@ -1,7 +1,10 @@
ejabberd Community Edition
==========================
[![Build Status](https://travis-ci.org/processone/ejabberd.svg?branch=master)](https://travis-ci.org/processone/ejabberd) [![Hex version](https://img.shields.io/hexpm/v/ejabberd.svg "Hex version")](https://hex.pm/packages/ejabberd)
[![CI](https://github.com/processone/ejabberd/actions/workflows/ci.yml/badge.svg)](https://github.com/processone/ejabberd/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/github/processone/ejabberd/badge.svg?branch=master "Coverage in coveralls.io")](https://coveralls.io/github/processone/ejabberd?branch=master)
[![Translation status](https://hosted.weblate.org/widgets/ejabberd/-/ejabberd-po/svg-badge.svg "Translation status in Weblate")](https://hosted.weblate.org/projects/ejabberd/ejabberd-po/)
[![Hex version](https://img.shields.io/hexpm/v/ejabberd.svg "Hex version")](https://hex.pm/packages/ejabberd)
ejabberd is a distributed, fault-tolerant technology that allows the creation
of large-scale instant messaging applications. The server can reliably support
@@ -115,6 +118,7 @@ To compile ejabberd you need:
- PAM library. Optional. For Pluggable Authentication Modules (PAM).
- ImageMagick's Convert program and Ghostscript fonts. Optional. For CAPTCHA
challenges.
- Elixir ≥ 1.10.3. Optional. Alternative to build ejabberd
If your system splits packages in libraries and development headers, you must
install the development packages also.
@@ -152,9 +156,25 @@ start and stop ejabberd. For example:
ejabberdctl start
For detailed information please refer to the ejabberd Installation and
Operation Guide available online and in the `doc` directory of the source
tarball.
For detailed information please refer to the
[ejabberd Documentation](https://docs.ejabberd.im)
### 3. Use ejabberd locally
Alternatively, you can setup ejabberd without installing in your system:
./configure --with-rebar=rebar3
make dev
Or, if you have Elixir available and plan to develop Elixir code:
./configure --with-rebar=mix
make dev
Check the full list of targets:
make help
Development
@@ -177,7 +197,7 @@ Using any gettext editor, you can improve the translation files found in
`priv/msgs/*.po`, and then submit your changes.
Alternatively, a simple way to improve translations is using our Weblate project:
https://hosted.weblate.org/projects/ejabberd/ejabberd/
https://hosted.weblate.org/projects/ejabberd/ejabberd-po/
Links
-10
View File
@@ -1,10 +0,0 @@
use Mix.Config
# This is standard path in the context of ejabberd release
config :ejabberd,
file: "config/ejabberd.yml",
log_path: 'log/ejabberd.log'
# Customize Mnesia directory:
config :mnesia,
dir: 'database/'
+12
View File
@@ -0,0 +1,12 @@
import Config
rootpath = System.get_env("RELEASE_ROOT", "")
# This is standard path in the context of ejabberd release
config :ejabberd,
file: Path.join(rootpath, "etc/ejabberd/ejabberd.yml"),
log_path: Path.join(rootpath, 'var/log/ejabberd/ejabberd.log')
# Customize Mnesia directory:
config :mnesia,
dir: Path.join(rootpath, 'var/lib/ejabberd/')
+26 -32
View File
@@ -30,7 +30,7 @@ fi
AC_ARG_WITH(rebar,
AC_HELP_STRING([--with-rebar=bin],
[use rebar specified]),
[use the rebar/rebar3/mix binary specified]),
[if test "$withval" = "yes" -o "$withval" = "no" -o "X$with_rebar" = "X"; then
rebar="rebar"
else
@@ -67,14 +67,13 @@ fi
AC_PREFIX_DEFAULT(/usr/local)
AC_CONFIG_FILES([Makefile
vars.config
src/ejabberd.app.src])
vars.config])
AC_ARG_ENABLE(all,
[AC_HELP_STRING([--enable-all], [same as --enable-odbc --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-redis --enable-elixir --enable-stun --enable-sip --enable-debug --enable-tools (useful for Dialyzer checks, default: no)])],
[AC_HELP_STRING([--enable-all], [same as --enable-odbc --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-redis --enable-elixir --enable-stun --enable-sip --enable-debug --enable-lua --enable-tools (useful for Dialyzer checks, default: no)])],
[case "${enableval}" in
yes) odbc=true mysql=true pgsql=true sqlite=true pam=true zlib=true redis=true elixir=true stun=true sip=true debug=true tools=true ;;
no) odbc=false mysql=false pgsql=false sqlite=false pam=false zlib=false redis=false elixir=false stun=false sip=false debug=false tools=false ;;
yes) odbc=true mysql=true pgsql=true sqlite=true pam=true zlib=true redis=true elixir=true stun=true sip=true debug=true lua=true tools=true ;;
no) odbc=false mysql=false pgsql=false sqlite=false pam=false zlib=false redis=false elixir=false stun=false sip=false debug=false lua=false tools=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
esac],[])
@@ -128,14 +127,6 @@ if test "$ENABLEGROUP" != ""; then
AC_SUBST([INSTALLGROUP], [$ENABLEGROUP])
fi
AC_ARG_ENABLE(hipe,
[AC_HELP_STRING([--enable-hipe], [compile natively with HiPE, not recommended (default: no)])],
[case "${enableval}" in
yes) hipe=true ;;
no) hipe=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-hipe) ;;
esac],[hipe=false])
AC_ARG_ENABLE(latest_deps,
[AC_HELP_STRING([--enable-latest-deps], [makes rebar use latest commits for dependencies instead of tagged versions (default: no)])],
[case "${enableval}" in
@@ -144,6 +135,14 @@ AC_ARG_ENABLE(latest_deps,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-latest-deps) ;;
esac],[if test "x$latest_deps" = "x"; then latest_deps=false; fi])
AC_ARG_ENABLE(lua,
[AC_HELP_STRING([--enable-lua], [enable Lua support, to import from Prosody (default: no)])],
[case "${enableval}" in
yes) lua=true ;;
no) lua=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-lua) ;;
esac],[if test "x$lua" = "x"; then lua=false; fi])
AC_ARG_ENABLE(mssql,
[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
[case "${enableval}" in
@@ -270,25 +269,20 @@ AC_ARG_ENABLE(zlib,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-zlib) ;;
esac],[if test "x$zlib" = "x"; then zlib=true; fi])
if test "$sqlite" = "true"; then
AX_LIB_SQLITE3([3.6.19])
if test "x$SQLITE3_VERSION" = "x"; then
AC_MSG_ERROR(SQLite3 library >= 3.6.19 was not found)
fi
fi
enabled_backends=""
for backend in odbc mysql pgsql sqlite redis mssql; do
if eval test x\${$backend} = xtrue; then
if test "x$enabled_backends" = "x"; then
enabled_backends=$backend
else
enabled_backends="$enabled_backends, $backend"
fi
case "`uname`" in
"Darwin")
# Darwin (macos) erlang-sqlite is built using amalgamated lib, so no external dependency
;;
*)
if test "$sqlite" = "true"; then
AX_LIB_SQLITE3([3.6.19])
if test "x$SQLITE3_VERSION" = "x"; then
AC_MSG_ERROR(SQLite3 library >= 3.6.19 was not found)
fi
fi
done
;;
esac
AC_SUBST(hipe)
AC_SUBST(roster_gateway_workaround)
AC_SUBST(new_sql_schema)
AC_SUBST(full_xml)
@@ -305,12 +299,12 @@ AC_SUBST(elixir)
AC_SUBST(stun)
AC_SUBST(sip)
AC_SUBST(debug)
AC_SUBST(lua)
AC_SUBST(tools)
AC_SUBST(latest_deps)
AC_SUBST(system_deps)
AC_SUBST(CFLAGS)
AC_SUBST(CPPFLAGS)
AC_SUBST(LDFLAGS)
AC_SUBST(enabled_backends)
AC_OUTPUT
+9
View File
@@ -33,6 +33,15 @@ listen:
shaper: c2s_shaper
access: c2s
starttls_required: true
-
port: 5223
ip: "::"
tls: true
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
starttls_required: true
-
port: 5269
ip: "::"
-14
View File
@@ -12,20 +12,6 @@
#
#POLL=true
#.
#' SMP: SMP support ([enable|auto|disable])
#
# Explanation in Erlang/OTP documentation:
# enable: starts the Erlang runtime system with SMP support enabled.
# This may fail if no runtime system with SMP support is available.
# auto: starts the Erlang runtime system with SMP support enabled if it
# is available and more than one logical processor are detected.
# disable: starts a runtime system without SMP support.
#
# Default: auto
#
#SMP=auto
#.
#' ERL_MAX_PORTS: Maximum number of simultaneously open Erlang ports
#
+3 -3
View File
@@ -2,7 +2,6 @@
# define default configuration
POLL=true
SMP=auto
ERL_MAX_PORTS=32000
ERL_PROCESSES=250000
ERL_MAX_ETS_TABLES=1400
@@ -11,7 +10,8 @@ INET_DIST_INTERFACE=""
ERLANG_NODE=ejabberd@localhost
# define default environment variables
SCRIPT_DIR=$(cd "${0%/*}" && pwd)
[ -z "$SCRIPT" ] && SCRIPT=$0
SCRIPT_DIR="$(cd "$(dirname "$SCRIPT")" && pwd -P)"
ERL="{{erl}}"
IEX="{{bindir}}/iex"
EPMD="{{epmd}}"
@@ -69,7 +69,7 @@ done
: "${EJABBERD_LOG_PATH:="$LOGS_DIR/ejabberd.log"}"
# define erl parameters
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
ERLANG_OPTS="+K $POLL +P $ERL_PROCESSES $ERL_OPTIONS"
if [ -n "$FIREWALL_WINDOW" ] ; then
ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
fi
+1
View File
@@ -51,6 +51,7 @@
desc = "" :: string() | '_' | '$3',
longdesc = "" :: string() | '_',
version = 0 :: integer(),
note = "" :: string(),
weight = 1 :: integer(),
module :: atom() | '_',
function :: atom() | '_',
+8
View File
@@ -29,11 +29,19 @@
-define(SQL_INSERT_MARK, sql_insert__mark_).
-define(SQL_INSERT(Table, Fields), ?SQL_INSERT_MARK(Table, Fields)).
-ifdef(COMPILER_REPORTS_ONLY_LINES).
-record(sql_query, {hash :: binary(),
format_query :: fun(),
format_res :: fun(),
args :: fun(),
loc :: {module(), pos_integer()}}).
-else.
-record(sql_query, {hash :: binary(),
format_query :: fun(),
format_res :: fun(),
args :: fun(),
loc :: {module(), {pos_integer(), pos_integer()}}}).
-endif.
-record(sql_escape, {string :: fun((binary()) -> binary()),
integer :: fun((integer()) -> binary()),
+5 -5
View File
@@ -1,9 +1,9 @@
defmodule Ejabberd.Logger do
def critical(message, args \\ []), do: :lager.log(:critical, [], message, args)
def error(message, args \\ []), do: :lager.log(:error, [], message, args)
def warning(message, args \\ []), do: :lager.log(:warning, [], message, args)
def info(message, args \\ []), do: :lager.log(:info, [], message, args)
def debug(message, args \\ []), do: :lager.log(:debug, [], message, args)
def critical(message, args \\ []), do: :logger.critical(message, args)
def error(message, args \\ []), do: :logger.error(message, args)
def warning(message, args \\ []), do: :logger.warning(message, args)
def info(message, args \\ []), do: :logger.info(message, args)
def debug(message, args \\ []), do: :logger.debug( message, args)
end
+5 -1
View File
@@ -25,5 +25,9 @@ defmodule ModPresenceDemo do
def mod_options(_host) do
[]
end
def mod_doc() do
%{:desc => 'This is just a demonstration.'}
end
end
+36 -17
View File
@@ -2,12 +2,12 @@
.\" Title: ejabberd.yml
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
.\" Date: 01/27/2021
.\" Date: 07/21/2021
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
.TH "EJABBERD\&.YML" "5" "01/27/2021" "\ \&" "\ \&"
.TH "EJABBERD\&.YML" "5" "07/21/2021" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -82,12 +82,12 @@ All options can be changed in runtime by running \fIejabberdctl reload\-config\f
.sp
Some options can be specified for particular virtual host(s) only using \fIhost_config\fR or \fIappend_host_config\fR options\&. Such options are called \fIlocal\fR\&. Examples are \fImodules\fR, \fIauth_method\fR and \fIdefault_db\fR\&. The options that cannot be defined per virtual host are called \fIglobal\fR\&. Examples are \fIloglevel\fR, \fIcertfiles\fR and \fIlisten\fR\&. It is a configuration mistake to put \fIglobal\fR options under \fIhost_config\fR or \fIappend_host_config\fR section \- ejabberd will refuse to load such configuration\&.
.sp
It is not recommended to write ejabberd\&.yml from scratch\&. Instead it is better to start from "default" configuration file available at https://github\&.com/processone/ejabberd/blob/21\&.01/ejabberd\&.yml\&.example\&. Once you get ejabberd running you can start changing configuration options to meet your requirements\&.
It is not recommended to write ejabberd\&.yml from scratch\&. Instead it is better to start from "default" configuration file available at https://github\&.com/processone/ejabberd/blob/21\&.07/ejabberd\&.yml\&.example\&. Once you get ejabberd running you can start changing configuration options to meet your requirements\&.
.sp
Note that this document is intended to provide comprehensive description of all configuration options that can be consulted to understand the meaning of a particular option, its format and possible values\&. It will be quite hard to understand how to configure ejabberd by reading this document only \- for this purpose the reader is recommended to read online Configuration Guide available at https://docs\&.ejabberd\&.im/admin/configuration\&.
.SH "TOP LEVEL OPTIONS"
.sp
This section describes top level options of ejabberd 21\&.01
This section describes top level options of ejabberd\&.
.PP
\fBaccess_rules\fR: \fI{AccessName: {allow|deny: ACLRules|ACLName}}\fR
.RS 4
@@ -378,6 +378,8 @@ that can be installed from the
\fIejabberd\-contrib\fR
Git repository\&. Please refer to that module\(cqs README file for details\&.
.RE
.sp
\fINote\fR about the next option: improved in 20\&.01:
.PP
\fBauth_password_format\fR: \fIplain | scram\fR
.RS 4
@@ -996,7 +998,7 @@ minute\&.
Whether to use
\fInew\fR
SQL schema\&. All schemas are located at
https://github\&.com/processone/ejabberd/tree/21\&.01/sql\&. There are two schemas available\&. The default legacy schema allows to store one XMPP domain into one ejabberd database\&. The
https://github\&.com/processone/ejabberd/tree/21\&.07/sql\&. There are two schemas available\&. The default legacy schema allows to store one XMPP domain into one ejabberd database\&. The
\fInew\fR
schema allows to handle several XMPP domains in a single ejabberd database\&. Using this
\fInew\fR
@@ -1029,6 +1031,8 @@ Same as
\fIcache_missed\fR
will be used\&.
.RE
.sp
\fINote\fR about the next option: added in 21\&.01:
.PP
\fBoauth_cache_rest_failure_life_time\fR: \fItimeout()\fR
.RS 4
@@ -1110,12 +1114,16 @@ Specify which address families to try, in what order\&. The default is
\fI[ipv4, ipv6]\fR
which means it first tries connecting with IPv4, if that fails it tries using IPv6\&.
.RE
.sp
\fINote\fR about the next option: added in 20\&.12:
.PP
\fBoutgoing_s2s_ipv4_address\fR: \fIAddress\fR
.RS 4
Specify the IPv4 address that will be used when establishing an outgoing S2S IPv4 connection, for example "127\&.0\&.0\&.1"\&. The default value is
\fIundefined\fR\&.
.RE
.sp
\fINote\fR about the next option: added in 20\&.12:
.PP
\fBoutgoing_s2s_ipv6_address\fR: \fIAddress\fR
.RS 4
@@ -1542,6 +1550,8 @@ An SQL database name\&. For SQLite this must be a full path to a database file\&
.RS 4
An interval to make a dummy SQL request to keep alive the connections to the database\&. There is no default value, so no keepalive requests are made\&.
.RE
.sp
\fINote\fR about the next option: added in 20\&.12:
.PP
\fBsql_odbc_driver\fR: \fIPath\fR
.RS 4
@@ -1559,7 +1569,7 @@ The password for SQL authentication\&. The default is empty string\&.
.PP
\fBsql_pool_size\fR: \fISize\fR
.RS 4
A number of connections to the SQL server\&. By default ejabberd opens 10 connections to the database for each virtual host\&. WARNING: for SQLite this value is
Number of connections to the SQL server that ejabberd will open for each virtual host\&. The default value is 10\&. WARNING: for SQLite this value is
\fI1\fR
by default and it\(cqs not recommended to change it due to potential race conditions\&.
.RE
@@ -1574,6 +1584,8 @@ for PostgreSQL and
\fI1433\fR
for MS SQL\&. The option has no effect for SQLite\&.
.RE
.sp
\fINote\fR about the next option: added in 20\&.01:
.PP
\fBsql_prepared_statements\fR: \fItrue | false\fR
.RS 4
@@ -1605,10 +1617,12 @@ if the latter is not set\&.
A hostname or an IP address of the SQL server\&. The default value is
\fIlocalhost\fR\&.
.RE
.sp
\fINote\fR about the next option: improved in 20\&.03:
.PP
\fBsql_ssl\fR: \fItrue | false\fR
.RS 4
Whether to use SSL encrypted connections to the SQL server\&. The option is only available for PostgreSQL\&. The default value is
Whether to use SSL encrypted connections to the SQL server\&. The option is only available for MySQL and PostgreSQL\&. The default value is
\fIfalse\fR\&.
.RE
.PP
@@ -1722,7 +1736,7 @@ seconds\&.
.RE
.SH "MODULES"
.sp
This section describes options of all modules in ejabberd 21\&.01
This section describes options of all ejabberd modules\&.
.SS "mod_adhoc"
.sp
This module implements XEP\-0050: Ad\-Hoc Commands\&. It\(cqs an auxiliary module and is only needed by some of the other modules\&.
@@ -1870,7 +1884,7 @@ ejabberdctl srg\-create g1 example\&.org "\*(AqGroup number 1\*(Aq" this_is_g1 g
.RE
.SS "mod_admin_update_sql"
.sp
This module can be used to update existing SQL database from the default to the new schema\&. Check the section Default and New Schemas for details\&. When the module is loaded use \fIupdate_sql\fR ejabberdctl command\&.
This module can be used to update existing SQL database from the default to the new schema\&. Check the section Default and New Schemas for details\&. Please note that only PostgreSQL is supported\&. When the module is loaded use \fIupdate_sql\fR ejabberdctl command\&.
.sp
The module has no options\&.
.SS "mod_announce"
@@ -3749,12 +3763,16 @@ option is not specified, the only Jabber ID will be the hostname of the virtual
\fI@HOST@\fR
is replaced with the real virtual host name\&.
.RE
.sp
\fINote\fR about the next option: added in 21\&.01:
.PP
\fBmax_captcha_whitelist\fR: \fINumber\fR
.RS 4
This option defines the maximum number of characters that Captcha Whitelist can have when configuring the room\&. The default value is
\fIinfinity\fR\&.
.RE
.sp
\fINote\fR about the next option: added in 21\&.01:
.PP
\fBmax_password\fR: \fINumber\fR
.RS 4
@@ -3840,10 +3858,11 @@ Same as top\-level
option, but applied to this module only\&.
.RE
.PP
\fBram_db_type\fR: \fImnesia\fR
\fBram_db_type\fR: \fImnesia | sql\fR
.RS 4
Define the type of volatile (in\-memory) storage where the module will store room information\&. The only available value for this module is
\fImnesia\fR\&.
Define the type of volatile (in\-memory) storage where the module will store room information (\fImuc_online_room\fR
and
\fImuc_online_users\fR)\&.
.RE
.PP
\fBregexp_room_id\fR: \fIstring()\fR
@@ -5422,7 +5441,7 @@ This option specifies the period of time until the session of a disconnected pus
\fImod_stream_mgmt\fR
module is restored\&. The default value is
\fI72\fR
minutes\&.
hours\&.
.RE
.PP
\fBwake_on_start\fR: \fItrue | false\fR
@@ -6556,7 +6575,7 @@ minutes\&.
.RE
.SS "mod_stun_disco"
.sp
This module allows XMPP clients to discover STUN/TURN services and to obtain temporary credentials for using them as per XEP\-0215: External Service Discovery\&.
This module allows XMPP clients to discover STUN/TURN services and to obtain temporary credentials for using them as per XEP\-0215: External Service Discovery\&. This module is included in ejabberd since version 20\&.04\&.
.sp
.it 1 an-trap
.nr an-no-space-flag 1
@@ -7162,7 +7181,7 @@ Should the operating system be revealed or not\&. The default value is
.RE
.SH "LISTENERS"
.sp
This section describes options of all listeners in ejabberd 21\&.01
This section describes options of all ejabberd listeners\&.
.sp
TODO
.SH "AUTHOR"
@@ -7170,13 +7189,13 @@ TODO
ProcessOne\&.
.SH "VERSION"
.sp
This document describes the configuration file of ejabberd 21\&.01\&. Configuration options of other ejabberd versions may differ significantly\&.
This document describes the configuration file of ejabberd 21\&.04\&.131\&. Configuration options of other ejabberd versions may differ significantly\&.
.SH "REPORTING BUGS"
.sp
Report bugs to https://github\&.com/processone/ejabberd/issues
.SH "SEE ALSO"
.sp
Default configuration file: https://github\&.com/processone/ejabberd/blob/21\&.01/ejabberd\&.yml\&.example
Default configuration file: https://github\&.com/processone/ejabberd/blob/21\&.07/ejabberd\&.yml\&.example
.sp
Main site: https://ejabberd\&.im
.sp
+142 -35
View File
@@ -1,9 +1,9 @@
defmodule Ejabberd.Mixfile do
defmodule Ejabberd.MixProject do
use Mix.Project
def project do
[app: :ejabberd,
version: "21.1.0",
version: version(),
description: description(),
elixir: "~> 1.4",
elixirc_paths: ["lib"],
@@ -13,10 +13,21 @@ defmodule Ejabberd.Mixfile do
erlc_paths: ["asn1", "src"],
# Elixir tests are starting the part of ejabberd they need
aliases: [test: "test --no-start"],
start_permanent: Mix.env() == :prod,
language: :erlang,
releases: releases(),
package: package(),
deps: deps()]
end
def version do
case config(:vsn) do
:false -> "0.0.0" # ./configure wasn't run: vars.config not created
'0.0' -> "0.0.0" # the full git repository wasn't downloaded
vsn -> String.replace(:erlang.list_to_binary(vsn), ~r/0+([0-9])/, "\\1")
end
end
def description do
"""
Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP, MQTT, SIP Server)
@@ -25,12 +36,13 @@ defmodule Ejabberd.Mixfile do
def application do
[mod: {:ejabberd_app, []},
applications: [:kernel, :stdlib, :sasl, :ssl],
included_applications: [:lager, :mnesia, :inets, :p1_utils, :cache_tab,
:fast_tls, :stringprep, :fast_xml, :xmpp, :mqtree,
:stun, :fast_yaml, :esip, :jiffy, :p1_oauth2,
:eimp, :base64url, :jose, :pkix, :os_mon, :yconf,
:p1_acme, :idna]
extra_applications: [:mix],
applications: [:idna, :inets, :kernel, :sasl, :ssl, :stdlib,
:base64url, :fast_tls, :fast_xml, :fast_yaml, :jiffy, :jose,
:p1_utils, :stringprep, :stun, :yconf],
included_applications: [:lager, :mnesia, :os_mon,
:cache_tab, :eimp, :esip, :mqtree, :p1_acme,
:p1_oauth2, :pkix, :xmpp]
++ cond_apps()]
end
@@ -70,6 +82,8 @@ defmodule Ejabberd.Mixfile do
if_version_below('22', [{:d, :LAGER}]) ++
if_version_below('23', [{:d, :USE_OLD_CRYPTO_HMAC}]) ++
if_version_below('23', [{:d, :USE_OLD_PG2}]) ++
if_version_below('24', [{:d, :COMPILER_REPORTS_ONLY_LINES}]) ++
if_version_below('24', [{:d, :SYSTOOLS_APP_DEF_WITHOUT_OPTIONAL}]) ++
if_function_exported(:erl_error, :format_exception, 6, [{:d, :HAVE_ERL_ERROR}])
defines = for {:d, value} <- result, do: {:d, value}
result ++ [{:d, :ALL_DEFS, defines}]
@@ -85,30 +99,30 @@ defmodule Ejabberd.Mixfile do
end
defp deps do
[{:lager, "~> 3.6.0"},
{:p1_utils, "~> 1.0"},
{:fast_xml, "~> 1.1"},
{:xmpp, "~> 1.5.1"},
[{:base64url, "~> 0.0.1"},
{:cache_tab, "~> 1.0"},
{:stringprep, "~> 1.0"},
{:fast_yaml, "~> 1.0"},
{:fast_tls, "~> 1.1"},
{:stun, "~> 1.0.41"},
{:esip, "~> 1.0.32"},
{:p1_mysql, "~> 1.0"},
{:mqtree, "~> 1.0"},
{:p1_pgsql, "~> 1.1"},
{:jiffy, "~> 1.0.4"},
{:p1_oauth2, "~> 0.6.1"},
{:distillery, "~> 2.0"},
{:pkix, "~> 1.0"},
{:ex_doc, ">= 0.0.0", only: :dev},
{:eimp, "~> 1.0"},
{:base64url, "~> 0.0.1"},
{:yconf, "~> 1.0"},
{:jose, "~> 1.8"},
{:esip, "~> 1.0"},
{:ex_doc, ">= 0.0.0", only: :dev},
{:fast_tls, "~> 1.1"},
{:fast_xml, "~> 1.1"},
{:fast_yaml, "~> 1.0"},
{:idna, "~> 6.0"},
{:p1_acme, "~> 1.0"}]
{:jiffy, "~> 1.0.5"},
{:jose, "~> 1.8"},
{:lager, "~> 3.9.1"},
{:mqtree, "~> 1.0"},
{:p1_acme, "~> 1.0"},
{:p1_mysql, "~> 1.0"},
{:p1_oauth2, "~> 0.6"},
{:p1_pgsql, "~> 1.1"},
{:p1_utils, "~> 1.0"},
{:pkix, "~> 1.0"},
{:stringprep, ">= 1.0.26", override: true},
{:stun, "~> 1.0"},
{:xmpp, "~> 1.5"},
{:yconf, "~> 1.0"}]
++ cond_deps()
end
@@ -125,11 +139,11 @@ defmodule Ejabberd.Mixfile do
end
defp cond_deps do
for {:true, dep} <- [{config(:sqlite), {:sqlite3, "~> 1.1"}},
{config(:redis), {:eredis, "~> 1.0"}},
for {:true, dep} <- [{config(:pam), {:epam, "~> 1.0"}},
{config(:redis), {:eredis, "~> 1.2.0"}},
{config(:zlib), {:ezlib, "~> 1.0"}},
{config(:pam), {:epam, "~> 1.0"}},
{config(:tools), {:luerl, "~> 0.3.1"}}], do:
{config(:lua), {:luerl, "~> 0.3.1"}},
{config(:sqlite), {:sqlite3, "~> 1.1"}}], do:
dep
end
@@ -138,14 +152,15 @@ defmodule Ejabberd.Mixfile do
{config(:mysql), :p1_mysql},
{config(:odbc), :odbc},
{config(:pgsql), :p1_pgsql},
{config(:sqlite), :sqlite3},
{config(:zlib), :ezlib}], do:
{config(:sqlite), :sqlite3}], do:
app
end
defp package do
[# These are the default files included in the package
files: ["lib", "src", "priv", "mix.exs", "include", "README.md", "COPYING", "rebar.config", "rebar.config.script"],
files: ["include", "lib", "priv", "sql", "src",
"COPYING", "README.md",
"mix.exs", "rebar.config", "rebar.config.script", "vars.config"],
maintainers: ["ProcessOne"],
licenses: ["GPLv2"],
links: %{"Site" => "https://www.ejabberd.im",
@@ -168,6 +183,98 @@ defmodule Ejabberd.Mixfile do
end
end
defp releases do
maybe_tar = case Mix.env() do
:prod -> [:tar]
_ -> []
end
[
ejabberd: [
include_executables_for: [:unix],
# applications: [runtime_tools: :permanent]
steps: [&copy_extra_files/1, :assemble | maybe_tar]
]
]
end
defp copy_extra_files(release) do
assigns = [
version: version(),
rootdir: config(:rootdir),
installuser: config(:installuser),
libdir: config(:libdir),
sysconfdir: config(:sysconfdir),
localstatedir: config(:localstatedir),
docdir: config(:docdir),
erl: config(:erl),
epmd: config(:epmd),
bindir: Path.join([config(:release_dir), "releases", version()]),
release_dir: config(:release_dir),
erts_vsn: "erts-#{release.erts_version}"
]
ro = "rel/overlays"
File.rm_rf(ro)
# Elixir lower than 1.12.0 don't have System.shell
execute = fn(command) ->
case function_exported?(System, :shell, 1) do
true ->
System.shell(command)
false ->
:os.cmd(to_charlist(command))
end
end
# Mix/Elixir lower than 1.11.0 use config/releases.exs instead of runtime.exs
case Version.match?(System.version, ">= 1.11.0") do
true ->
:ok
false ->
execute.("cp config/runtime.exs config/releases.exs")
end
execute.("sed -e 's|{{\\(\[_a-z\]*\\)}}|<%= @\\1 %>|g' ejabberdctl.template > ejabberdctl.example1")
Mix.Generator.copy_template("ejabberdctl.example1", "ejabberdctl.example2", assigns)
execute.("sed -e 's|{{\\(\[_a-z\]*\\)}}|<%= @\\1 %>|g' ejabberdctl.example2 > ejabberdctl.example3")
execute.("sed -e 's|ERLANG_NODE=ejabberd@localhost|ERLANG_NODE=ejabberd|g' ejabberdctl.example3 > ejabberdctl.example4")
execute.("sed -e 's|INSTALLUSER=|ERL_OPTIONS=\"-setcookie \\$\\(cat \"\\${SCRIPT_DIR%/*}/releases/COOKIE\")\"\\nINSTALLUSER=|g' ejabberdctl.example4 > ejabberdctl.example5")
Mix.Generator.copy_template("ejabberdctl.example5", "#{ro}/bin/ejabberdctl", assigns)
File.chmod("#{ro}/bin/ejabberdctl", 0o755)
File.rm("ejabberdctl.example1")
File.rm("ejabberdctl.example2")
File.rm("ejabberdctl.example3")
File.rm("ejabberdctl.example4")
File.rm("ejabberdctl.example5")
suffix = case Mix.env() do
:dev ->
Mix.Generator.copy_file("test/ejabberd_SUITE_data/ca.pem", "#{ro}/etc/ejabberd/ca.pem")
Mix.Generator.copy_file("test/ejabberd_SUITE_data/cert.pem", "#{ro}/etc/ejabberd/cert.pem")
".example"
_ -> ""
end
Mix.Generator.copy_file("ejabberd.yml.example", "#{ro}/etc/ejabberd/ejabberd.yml#{suffix}")
Mix.Generator.copy_file("ejabberdctl.cfg.example", "#{ro}/etc/ejabberd/ejabberdctl.cfg#{suffix}")
Mix.Generator.copy_file("inetrc", "#{ro}/etc/ejabberd/inetrc")
Mix.Generator.copy_template("rel/vm.args.mix", "#{ro}/etc/ejabberd/vm.args", assigns)
Enum.each(File.ls!("sql"),
fn x ->
Mix.Generator.copy_file("sql/#{x}", "#{ro}/lib/ejabberd-#{release.version}/priv/sql/#{x}")
end)
Mix.Generator.create_directory("#{ro}/var/lib/ejabberd")
case Mix.env() do
:dev -> execute.("REL_DIR_TEMP=$PWD/rel/overlays/ rel/setup-dev.sh")
_ -> :ok
end
release
end
end
defmodule Mix.Tasks.Compile.Asn1 do
+25 -28
View File
@@ -1,39 +1,36 @@
%{
"artificery": {:hex, :artificery, "0.4.3", "0bc4260f988dcb9dda4b23f9fc3c6c8b99a6220a331534fdf5bf2fd0d4333b02", [:mix], [], "hexpm", "12e95333a30e20884e937abdbefa3e7f5e05609c2ba8cf37b33f000b9ffc0504"},
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm", "fab09b20e3f5db886725544cbcf875b8e73ec93363954eb8a1a9ed834aa8c1f9"},
"cache_tab": {:hex, :cache_tab, "1.0.27", "1e966fbae89800b91baeb3d2d81a50d29482ebaf1c75c64c820eeba1a2ed1278", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "1c6838afc7da3846774e9a661224524b361559302b8cc550e9db81fb819e9da3"},
"cache_tab": {:hex, :cache_tab, "1.0.29", "6c161988620b788d8df28c8f6af557571609c8e4b671dbadab295a4722cd501b", [:rebar3], [{:p1_utils, "1.0.23", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "a02a638021cce91ed1a8628dcbb4795bf5c01c9d11db8c613065923142824ce9"},
"distillery": {:hex, :distillery, "2.1.1", "f9332afc2eec8a1a2b86f22429e068ef35f84a93ea1718265e740d90dd367814", [:mix], [{:artificery, "~> 0.2", [hex: :artificery, repo: "hexpm", optional: false]}], "hexpm", "bbc7008b0161a6f130d8d903b5b3232351fccc9c31a991f8fcbf2a12ace22995"},
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
"earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"},
"eimp": {:hex, :eimp, "1.0.19", "f4cab7363dddb03b0c0c0c9a07aea2ed8266b059d2ffe01dd7318c910ef769d3", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "477cb4ff252aa239f54a247efec9391103c1d6535a99e394ac2c1102ef31fb83"},
"epam": {:hex, :epam, "1.0.7", "55889bbfdc5ab9f2e785a710229f34e550784c5ead1960d7839ea77514aef44d", [:rebar3], [], "hexpm", "6b029ebd2b244bc339cbf5cb5908d0f2d50e43f33a6e7f70818912ea5d3fd596"},
"eredis": {:hex, :eredis, "1.2.0", "0b8e9cfc2c00fa1374cd107ea63b49be08d933df2cf175e6a89b73dd9c380de4", [:rebar3], [], "hexpm"},
"esip": {:hex, :esip, "1.0.41", "3cb7e68f8aa0d3e2b7208461b2f0e7a5878db0084fc0e8d44f2d290146d60336", [:rebar3], [{:fast_tls, "1.1.11", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stun, "1.0.42", [hex: :stun, repo: "hexpm", optional: false]}], "hexpm", "8949368f1c45b61f52e57ffd5d15f23f582ef4ef2fc826b89ad874d3f896f7ac"},
"ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"},
"ezlib": {:hex, :ezlib, "1.0.9", "b17136b48bcf73962446b06d4427b0b6f2be4550bb5190a18a2979640271e244", [:rebar3], [], "hexpm", "fafc60a0de6e982be38f793da7b220b87a0da2969eba8a878351442b35cc2fde"},
"fast_tls": {:hex, :fast_tls, "1.1.11", "5ebc292e13e8947c065df6c73b46bcf8cb45acf952283c20145d243d7c93501d", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "410971e42a0af560b51d7db081c0943b2b0d1a84d0ae7cb486aeb940e83cbea9"},
"fast_xml": {:hex, :fast_xml, "1.1.45", "68eeec9a3c5e58de9164dd288523822226955d97013bd8a4d7657cf622eeb076", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "2d8eb7bb642920e63f69501b7bdb596bef135fc4919d9b6895875fa88d8a63e0"},
"fast_yaml": {:hex, :fast_yaml, "1.0.30", "9b971598dae53154150c65fdcedc5524da507469ddef627e0b12120359fbbf04", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "b1b9750c8f3b313f4bc01a87a8a0dc560ce2e01c066688210b75e92d111ea38b"},
"earmark_parser": {:hex, :earmark_parser, "1.4.13", "0c98163e7d04a15feb62000e1a891489feb29f3d10cb57d4f845c405852bbef8", [:mix], [], "hexpm", "d602c26af3a0af43d2f2645613f65841657ad6efc9f0e361c3b6c06b578214ba"},
"eimp": {:hex, :eimp, "1.0.21", "2e918a5dc9a1959ef8713a2360499e3baeee64cfd7881bd9d1f361ca9ddf07e8", [:rebar3], [{:p1_utils, "1.0.23", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "998f58538f58aa0cff103414994d7ce56dc253e6576cd6fb40c1ead64aa73a28"},
"epam": {:hex, :epam, "1.0.12", "2a5625d4133bca4b3943791a3f723ba764455a461ae9b6ba5debb262efcf4b40", [:rebar3], [], "hexpm", "54c166c4459cef72f2990a3d89a8f0be27180fe0ab0f24b28ddcc3b815f49f7f"},
"esip": {:hex, :esip, "1.0.43", "1cbdc073073f80b9b50e2759f66ca13a353eb4f874bcf92501bd4cd767e34d46", [:rebar3], [{:fast_tls, "1.1.13", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.23", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stun, "1.0.44", [hex: :stun, repo: "hexpm", optional: false]}], "hexpm", "b2c758ae52c4588e0399c0b4ce550bfa56551a5a2f828a28389f2614797e4f4b"},
"ex_doc": {:hex, :ex_doc, "0.25.0", "4070a254664ee5495c2f7cce87c2f43064a8752f7976f2de4937b65871b05223", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2d90883bd4f3d826af0bde7fea733a4c20adba1c79158e2330f7465821c8949b"},
"ezlib": {:hex, :ezlib, "1.0.10", "c1c24eb18944cfde55f0574e9922d5b0392fa864282f769f82b2ea15e54f6003", [:rebar3], [], "hexpm", "1d317f1d85373686199eb3b4164d3477e95033ac68e45a95ba18e7b7a8c23241"},
"fast_tls": {:hex, :fast_tls, "1.1.13", "828cdc75e1e8fce8158846d2b971d8b4fe2b2ddcc75b759e88d751079bf78afd", [:rebar3], [{:p1_utils, "1.0.23", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "d1f422af40c7777fe534496f508ee86515cb929ad10f7d1d56aa94ce899b44a0"},
"fast_xml": {:hex, :fast_xml, "1.1.47", "bd1d6c081b69c7bce0d2f22b013c1b864ed2588d48f34e2156d9428f8f772c66", [:rebar3], [{:p1_utils, "1.0.23", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "dd014c45247498effb9a28cf98cb716db79be635ad1e98c951240763119f24c7"},
"fast_yaml": {:hex, :fast_yaml, "1.0.32", "43f53a2c8572f2e4d66cd4e787fc6761b1c65b9132e42c511d8b9540b0989d65", [:rebar3], [{:p1_utils, "1.0.23", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "7258e322739ff0824237ebe44cd158e0bf52cd27a15fe731cf92f4b4c70b913e"},
"goldrush": {:hex, :goldrush, "0.1.9", "f06e5d5f1277da5c413e84d5a2924174182fb108dabb39d5ec548b27424cd106", [:rebar3], [], "hexpm", "99cb4128cffcb3227581e5d4d803d5413fa643f4eb96523f77d9e6937d994ceb"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"},
"jiffy": {:hex, :jiffy, "1.0.4", "72adeff75c52a2ff07de738f0813768abe7ce158026cc1115a170340259c0caa", [:rebar3], [], "hexpm", "113e5299ee4e6b9f40204256d7bbbd1caf646edeaef31ef0f7f5f842c0dad39e"},
"jiffy": {:hex, :jiffy, "1.0.5", "a69b58faf7123534c20e1b0b7ae97ac52079ca02ed4b6989b4b380179cd63a54", [:rebar3], [], "hexpm", "b617a53f46ae84f20d0c38951367dc947a2cf8cff922aa5c6ac6b64b8b052289"},
"jose": {:hex, :jose, "1.9.0", "4167c5f6d06ffaebffd15cdb8da61a108445ef5e85ab8f5a7ad926fdf3ada154", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm", "6429c4fee52b2dda7861ee19a4f09c8c1ffa213bee3a1ec187828fde95d447ed"},
"lager": {:hex, :lager, "3.6.10", "6172b43ab720ac33914ccd0aeb21fdbdf88213847707d4b91e6af57b2ae5c4d2", [:rebar3], [{:goldrush, "0.1.9", [hex: :goldrush, repo: "hexpm", optional: false]}], "hexpm", "5d10499461826b79c5abee18bb594b3949cbdf76d9d9fd7e66d0a558137c21c9"},
"luerl": {:hex, :luerl, "0.3.1", "5412807630aac1aaf59ffe5a1bc09259c447b4faeb1d3fe2d4ef41b87676cb04", [:rebar3], [], "hexpm", "1bc011c7297e43aec762e53b17ecb15b0ff29f9546cd153110b343cf5b043f5f"},
"lager": {:hex, :lager, "3.9.2", "4cab289120eb24964e3886bd22323cb5fefe4510c076992a23ad18cf85413d8c", [:rebar3], [{:goldrush, "0.1.9", [hex: :goldrush, repo: "hexpm", optional: false]}], "hexpm", "7f904d9e87a8cb7e66156ed31768d1c8e26eba1d54f4bc85b1aa4ac1f6340c28"},
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
"makeup_elixir": {:hex, :makeup_elixir, "0.15.0", "98312c9f0d3730fde4049985a1105da5155bfe5c11e47bdc7406d88e01e4219b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "75ffa34ab1056b7e24844c90bfc62aaf6f3a37a15faa76b07bc5eba27e4a8b4a"},
"mqtree": {:hex, :mqtree, "1.0.12", "1fbf05a87d19672d9074b40f4e63d9fc3a68c62a9dd9c1b18ddb5aefd079bd2b", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "de6e223cfbf1a69807fab23fb230f43715061f9ef780ffd06dca2d6ca76def3e"},
"makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"mqtree": {:hex, :mqtree, "1.0.14", "d201a79b51a9232b80e764b4b77a866f7c30a90c7ac6205d71f391eb3ea7eb31", [:rebar3], [{:p1_utils, "1.0.23", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "8626dac5e862b575eaf4836f0fc1be5a7c8435c378c5a309e34ee012d48b6f6e"},
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
"p1_acme": {:hex, :p1_acme, "1.0.6", "0b007b776331e3d6effe700fa85d63236a98dc4e6e8c3abbbf816d1bec70df3f", [:rebar3], [{:idna, "~>6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jiffy, "~>1.0.1", [hex: :jiffy, repo: "hexpm", optional: false]}, {:jose, "~>1.9.0", [hex: :jose, repo: "hexpm", optional: false]}, {:yconf, "~>1.0.5", [hex: :yconf, repo: "hexpm", optional: false]}], "hexpm", "7cc6528cbbe7a98929e954604ec670de56ca9f7a69a14d22166e8746fbe86f10"},
"p1_mysql": {:hex, :p1_mysql, "1.0.17", "1fd1eed07a0f1e79851e7a5dc17995ba42af1c1192dff978d5f17c9e096a6d8c", [:rebar3], [], "hexpm", "7da95ba3f36e50e80f6a7f89a0928c0bbe6c0a8c8a7a7432d1aa7349e5964a59"},
"p1_oauth2": {:hex, :p1_oauth2, "0.6.8", "22b859f3694da30c45722fae860922150f74cfb149ef6176a67c514093238917", [:rebar3], [], "hexpm", "12a476d809f3123098948ee95676198008e96afbc433070a1382e5aa3d2a7b93"},
"p1_pgsql": {:hex, :p1_pgsql, "1.1.10", "e4b19c9768ef4047f9c56090a91bfefc7337abb3809a28aa4a6538eef6ad76b0", [:rebar3], [], "hexpm", "5458c0db9e47425f8cc1f592356a29359267c624785b316b34a46ad7439e9367"},
"p1_utils": {:hex, :p1_utils, "1.0.21", "9d6244bbd4af881e85af71655e8be5720b5b965b1bdd51a35c7871fd4142af9a", [:rebar3], [], "hexpm", "4b9b90e5863f5fed17f06427ba99b2dc37b216e4dd1308891f0903745e2fccbd"},
"pkix": {:hex, :pkix, "1.0.7", "a0b8c9011edeba702d7cb73fecef1eabe3ae89b3dcf4b8f33775e4f17a7a1304", [:rebar3], [], "hexpm", "104a9e0ecd9cc0e579d148a028189a6efe6420b241f3d319d8a65d898a078295"},
"sqlite3": {:hex, :sqlite3, "1.1.9", "10090161893843c9839d884855cafbb33c8ee3a2d6597443d66e6f94144dfd79", [:rebar3], [], "hexpm", "148ef74ee796efc13ffc6bb0e7f5feeb050f425e7335ff02c7415ca86819c0d0"},
"stringprep": {:hex, :stringprep, "1.0.24", "5a2c29785cdc1eaddcba0564cd86020e5e686fe9e66fa47a80a97333f3dc75ea", [:rebar3], [{:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "aed7ac217493e5aa2f76066fb7bbfe0d4e94ca1ee72613dc954231422d911266"},
"stun": {:hex, :stun, "1.0.42", "9c5404342550137bd17853f57e51fd86c5a0f561d659136cffd483a9ba57edec", [:rebar3], [{:fast_tls, "1.1.11", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "b9a55e192cc140a85efff76594bff75bdef48f0049d19ac90f48b05529b53f15"},
"p1_acme": {:hex, :p1_acme, "1.0.13", "fec71df416004ce49e295f4846fe5ba3478b41fbe4f73a06b4a8fbc967d6e659", [:rebar3], [{:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jiffy, "1.0.5", [hex: :jiffy, repo: "hexpm", optional: false]}, {:jose, "1.9.0", [hex: :jose, repo: "hexpm", optional: false]}, {:yconf, "1.0.12", [hex: :yconf, repo: "hexpm", optional: false]}], "hexpm", "a2ce9d4904304df020c8e92e8577e0fc88f32623540656317c7e25440b4ac8d2"},
"p1_mysql": {:hex, :p1_mysql, "1.0.19", "22f1be58397780a7d580a954e7af66cde32a29dee1a24ab2aa196272fc654a4a", [:rebar3], [], "hexpm", "88f6cdb510e8959c14b6ae84ccda04967e3de239228f859d8341da67949622b1"},
"p1_oauth2": {:hex, :p1_oauth2, "0.6.10", "09ba1fbd447b1f480b223903e36d0415f21be592a1b00db964eea01285749028", [:rebar3], [], "hexpm", "c79cb61ababee4a8c85409b7f4932035797c093aeef1f9f53985e512b26f2a64"},
"p1_pgsql": {:hex, :p1_pgsql, "1.1.12", "10ae79eeb35ea98c0424a8b6420542fef9e4469eb12ccf41475d10840c291e68", [:rebar3], [], "hexpm", "32203f779e01cf0353270df24833a1d831ad7cb3e3e8e35a7556dfa1f40948d5"},
"p1_utils": {:hex, :p1_utils, "1.0.23", "7f94466ada69bd982ea7bb80fbca18e7053e7d0b82c9d9e37621fa508587069b", [:rebar3], [], "hexpm", "47f21618694eeee5006af1c88731ad86b757161e7823c29b6f73921b571c8502"},
"pkix": {:hex, :pkix, "1.0.8", "98ea05243847fd4504f7c7a0cd82cecd1010ac327a082e1c674c5384006eae75", [:rebar3], [], "hexpm", "399508819501fab9d2e586dfa601b5ee3ef22b5612d3db58204dd2d089ef45d7"},
"stringprep": {:hex, :stringprep, "1.0.27", "02808c7024bc6285ca6a8a67e7addfc16f35dda55551a582c5181d8ea960e890", [:rebar3], [{:p1_utils, "1.0.23", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "a5967b1144ca8002a58a03d16dd109fbd0bcdb82616cead2f983944314af6a00"},
"stun": {:hex, :stun, "1.0.44", "30b6b774864b24b05ba901291abe583bff19081e7c4efb3361df50b781ec9d3b", [:rebar3], [{:fast_tls, "1.1.13", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.23", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "e45bba816cbefff01d820e49e66814f450df25a7a468a70d68d1e64218d46520"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"},
"xmpp": {:hex, :xmpp, "1.5.2", "b55e5d910bbd7275a2419bd30289987e0c08d852b5f6dbfae4c558d3740d127f", [:rebar3], [{:ezlib, "1.0.9", [hex: :ezlib, repo: "hexpm", optional: false]}, {:fast_tls, "1.1.11", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:fast_xml, "1.1.45", [hex: :fast_xml, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.21", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stringprep, "1.0.24", [hex: :stringprep, repo: "hexpm", optional: false]}], "hexpm", "65710e8399b75a49ccef6ec04d42cd23c730466a644bc5df5827af5bdb696be7"},
"yconf": {:hex, :yconf, "1.0.10", "2850d28aa5eb23fc67c7df6a40e0596469593476eba25a494d29d82b97294198", [:rebar3], [{:fast_yaml, "1.0.30", [hex: :fast_yaml, repo: "hexpm", optional: false]}], "hexpm", "8ef0d5c86e27163a3da8545c1312d07449c02a23d05d2f053ca0d8be20b88c07"},
"xmpp": {:hex, :xmpp, "1.5.4", "6cd8144b3fe04745dc2cb3e746d6f2a963bb283db48a61f159b49cbe3fab8623", [:rebar3], [{:ezlib, "1.0.10", [hex: :ezlib, repo: "hexpm", optional: false]}, {:fast_tls, "1.1.13", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:fast_xml, "1.1.47", [hex: :fast_xml, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.23", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stringprep, "1.0.27", [hex: :stringprep, repo: "hexpm", optional: false]}], "hexpm", "3bc2b5cb24e52964fb11641422ce2b7ba7c261dd50080689a1cbe3d952a9db35"},
"yconf": {:hex, :yconf, "1.0.12", "78c119d39bb805207fcb7671cb884805d75ee89c9ec98632b678f90a597dee2c", [:rebar3], [{:fast_yaml, "1.0.32", [hex: :fast_yaml, repo: "hexpm", optional: false]}], "hexpm", "12faa51c281e95bcb6abf185fd034a242209621a7bb04b6cc411c867b192e207"},
}
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (Afegix * al final d'un camp per a buscar subcadenes)"}.
{" has set the subject to: "," ha posat el tema: "}.
{"# participants","# participants"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," změnil(a) téma na: "}.
{"A friendly name for the node","Přívětivé jméno pro uzel"}.
{"A password is required to enter this room","Pro vstup do místnosti musíte zadat heslo"}.
+6 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (Fügen Sie * am Ende des Feldes hinzu um nach Teilzeichenketten zu suchen)"}.
{" has set the subject to: "," hat das Thema geändert auf: "}.
{"# participants","# Teilnehmer"}.
@@ -320,6 +324,7 @@
{"Node index not found","Knotenindex nicht gefunden"}.
{"Node not found","Knoten nicht gefunden"}.
{"Node ~p","Knoten ~p"}.
{"Node","Knoten"}.
{"Nodeprep has failed","Nodeprep fehlgeschlagen"}.
{"Nodes","Knoten"}.
{"None","Keine"}.
+53 -35
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (Προσθέστε * στο τέλος του πεδίου για ταίριασμα με το substring)"}.
{" has set the subject to: "," έχει θέσει το θέμα σε: "}.
{"# participants","# συμμετέχοντες"}.
@@ -35,17 +39,17 @@
{"Allow visitors to send private messages to","Επιτρέψτε στους χρήστες να αποστέλλουν ιδιωτικά μηνύματα σε"}.
{"Allow visitors to send status text in presence updates","Επιτρέψτε στους επισκέπτες να αποστέλλουν κατάσταση στις ενημερώσεις παρουσίας"}.
{"Allow visitors to send voice requests","Επιτρέψτε στους επισκέπτες να στέλνουν αιτήματα φωνής"}.
{"An associated LDAP group that defines room membership; this should be an LDAP Distinguished Name according to an implementation-specific or deployment-specific definition of a group.","Μία σχετική LDAP ομάδα που καθορίζει τις συνδρομές στην αίθουσα: αυτό θα πρέπει να είναι ένα Διακεκριμένο Όνομα LDAP, σύμφωνα με τον προσδιορισμό κατεύθυνσης υλοποίησης ή ανάπτυξης της ομάδας."}.
{"An associated LDAP group that defines room membership; this should be an LDAP Distinguished Name according to an implementation-specific or deployment-specific definition of a group.","Μία σχετική LDAP ομάδα που καθορίζει τις συνδρομές στην αίθουσα: αυτό θα πρέπει να είναι ένα Διακεκριμένο Όνομα LDAP, σύμφωνα με τον προσδιορισμό κατεύθυνσης υλοποίησης ή ανάπτυξης της ομάδας."}.
{"Announcements","Ανακοινώσεις"}.
{"Answer associated with a picture","Η απάντηση σχετίστηκε με μια εικόνα"}.
{"Answer associated with a video","Η απάντηση σχετίστηκε με ένα βίντεο"}.
{"Answer associated with speech","Η απάντηση σχετίστηκε με ομιλία"}.
{"Answer to a question","Απάντηση σε ερώτηση"}.
{"Anyone in the specified roster group(s) may subscribe and retrieve items","Οποιοσδήποτε στις ορισθείσες Λίστες Ομάδων δύναται να εγγραφεί και να παραλάβει αντικείμενα"}.
{"Anyone may associate leaf nodes with the collection","Οποιοσδήποτε μπορεί να συσχετίσει leaf nodes με την συλλογή"}.
{"Anyone may associate leaf nodes with the collection","Οποιοσδήποτε μπορεί να συσχετίσει κόμβους φύλλων με τη συλλογή"}.
{"Anyone may publish","Οποιοσδήποτε δύναται να δημοσιέυει"}.
{"Anyone may subscribe and retrieve items","Οποιοσδήποτε δύναται να εγγραφεί και να παραλάβει αντικείμενα"}.
{"Anyone with a presence subscription of both or from may subscribe and retrieve items","Οποιοσδήποτε κατέχει Συνδρομή Παρουσίας και των δύο ή από, θα μπορούσε να εγγραφεί και να παραλάβει αντικείμενα"}.
{"Anyone with a presence subscription of both or from may subscribe and retrieve items","Όποιος έχει συνδρομή παρουσίας και των δύο ή από μπορεί να εγγραφεί και να ανακτήσει στοιχεία"}.
{"Anyone with Voice","Οποιοσδήποτε με Φωνή"}.
{"Anyone","Οποιοσδήποτε"}.
{"April","Απρίλιος"}.
@@ -68,8 +72,8 @@
{"Cannot remove default list","Δεν μπορείτε να καταργήσετε την προεπιλεγμένη λίστα"}.
{"CAPTCHA web page","Ιστοσελίδα CAPTCHA"}.
{"Challenge ID","Ταυτότητα Πρόκλησης"}.
{"Change Password","Αλλαγή κωδικού"}.
{"Change User Password","Αλλαγή Κωδικού Πρόσβασης Χρήστη"}.
{"Change Password","Αλλαγή κωδικού πρόσβασης"}.
{"Change User Password","Αλλαγή κωδικού πρόσβασης χρήστη"}.
{"Changing password is not allowed","Η αλλαγή του κωδικού πρόσβασης δεν επιτρέπεται"}.
{"Changing role/affiliation is not allowed","Η αλλαγή ρόλου/ομάδας δεν επιτρέπεται"}.
{"Channel already exists","Το κανάλι υπάρχει ήδη"}.
@@ -77,7 +81,7 @@
{"Channels","Κανάλια"}.
{"Characters not allowed:","Χαρακτήρες που δεν επιτρέπονται:"}.
{"Chatroom configuration modified","Η ρύθμιση παραμέτρων της αίθουσας σύνεδριασης τροποποιηθηκε"}.
{"Chatroom is created","Η αίθουσα σύνεδριασης δημιουργήθηκε"}.
{"Chatroom is created","Η αίθουσα συνομιλίας έχει δημιουργηθεί"}.
{"Chatroom is destroyed","Η αίθουσα σύνεδριασης διαγράφηκε"}.
{"Chatroom is started","Η αίθουσα σύνεδριασης έχει ξεκινήσει"}.
{"Chatroom is stopped","Η αίθουσα σύνεδριασης έχει σταματήσει"}.
@@ -89,7 +93,7 @@
{"Client acknowledged more stanzas than sent by server","Ο πελάτης γνωρίζει περισσότερα δωμάτια από αυτά που στάλθηκαν από τον εξυπηρετητή"}.
{"Commands","Εντολές"}.
{"Conference room does not exist","Η αίθουσα σύνεδριασης δεν υπάρχει"}.
{"Configuration of room ~s","Ρύθμιση παραμέτρων Αίθουσας ~s"}.
{"Configuration of room ~s","Διαμόρφωση δωματίου ~ s"}.
{"Configuration","Ρύθμιση παραμέτρων"}.
{"Connected Resources:","Συνδεδεμένοι Πόροι:"}.
{"Contact Addresses (normally, room owner or owners)","Διευθύνσεις της Επαφής (κανονικά, ιδιοκτήτης (-ες) αίθουσας)"}.
@@ -114,23 +118,24 @@
{"Disc only copy","Αντίγραφο μόνο σε δίσκο"}.
{"'Displayed groups' not added (they do not exist!): ","'Οι εμφανιζόμενες ομάδες' δεν προστέθηκαν (δεν υπάρχουν!): "}.
{"Displayed:","Απεικονίζεται:"}.
{"Don't tell your password to anybody, not even the administrators of the XMPP server.","Μη γνωστοποιείτε τον Κωδικό σας, ούτε στους Διαχειριστές του XMPP εξυπηρετητή."}.
{"Don't tell your password to anybody, not even the administrators of the XMPP server.","Μην πείτε τον κωδικό πρόσβασής σας σε κανέναν, ούτε στους διαχειριστές του διακομιστή XMPP."}.
{"Dump Backup to Text File at ","Αποθήκευση Αντιγράφου Ασφαλείας σε αρχείο κειμένου στο "}.
{"Dump to Text File","Αποθήκευση σε αρχείο κειμένου"}.
{"Duplicated groups are not allowed by RFC6121","Δεν επιτρέπονται διπλότυπες ομάδες από το RFC6121"}.
{"Dynamically specify a replyto of the item publisher","Δυναμικά προσδιορίστε το Απάντηση σε του εκδότη του αντικειμένου"}.
{"Edit Properties","Επεξεργασία ιδιοτήτων"}.
{"Either approve or decline the voice request.","Είτε εγκρίνετε ή απορρίψτε το αίτημα φωνής."}.
{"ejabberd HTTP Upload service","Υπηρεσία ανεβάσματος αρχείων του ejabberd"}.
{"ejabberd MUC module","ejabberd MUC module"}.
{"ejabberd MUC module","ενότητα ejabberd MUC"}.
{"ejabberd Multicast service","υπηρεσία ejabberd Multicast"}.
{"ejabberd Publish-Subscribe module","ejabberd module Δημοσίευσης-Εγγραφής"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}.
{"ejabberd SOCKS5 Bytestreams module","ενότητα ejabberd SOCKS5 Bytestreams"}.
{"ejabberd vCard module","ejabberd vCard module"}.
{"ejabberd Web Admin","ejabberd Web Admin"}.
{"ejabberd","ejabberd"}.
{"Elements","Στοιχεία"}.
{"Email Address","Ηλεκτρονική Διεύθυνση"}.
{"Email","Email"}.
{"Email","Ηλεκτρονικό ταχυδρομείο"}.
{"Enable logging","Ενεργοποίηση καταγραφής"}.
{"Enable message archiving","Ενεργοποιήστε την αρχειοθέτηση μηνυμάτων"}.
{"Enabling push without 'node' attribute is not supported","Η ενεργοποίηση της ώθησης χωρίς το χαρακτηριστικό 'κόμβος' δεν υποστηρίζεται"}.
@@ -141,7 +146,7 @@
{"Enter path to jabberd14 spool file","Εισάγετε τοποθεσία αρχείου σειράς jabberd14"}.
{"Enter path to text file","Εισάγετε Τοποθεσία Αρχείου Κειμένου"}.
{"Enter the text you see","Πληκτρολογήστε το κείμενο που βλέπετε"}.
{"Erlang XMPP Server","XMPP εξυπηρετητής Erlang"}.
{"Erlang XMPP Server","Διακομιστής Erlang XMPP"}.
{"Error","Σφάλμα"}.
{"Exclude Jabber IDs from CAPTCHA challenge","Εξαίρεσε αυτές τις ταυτότητες Jabber από την CAPTCHA πρόκληση"}.
{"Export all tables as SQL queries to a file:","Εξαγωγή όλων των πινάκων ως ερωτημάτων SQL σε ένα αρχείο:"}.
@@ -167,7 +172,7 @@
{"Full Name","Ονοματεπώνυμο"}.
{"Get Number of Online Users","Έκθεση αριθμού συνδεδεμένων χρηστών"}.
{"Get Number of Registered Users","Έκθεση αριθμού εγγεγραμμένων χρηστών"}.
{"Get Pending","Έκθεση των εκκρεμόντων"}.
{"Get Pending","Λήψη των εκκρεμοτήτων"}.
{"Get User Last Login Time","Έκθεση Τελευταίας Ώρας Σύνδεσης Χρήστη"}.
{"Get User Password","Έκθεση Κωδικού Πρόσβασης Χρήστη"}.
{"Get User Statistics","Έκθεση Στατιστικών Χρήστη"}.
@@ -181,8 +186,8 @@
{"has been kicked because of an affiliation change","έχει αποβληθεί λόγω αλλαγής υπαγωγής"}.
{"has been kicked because the room has been changed to members-only","αποβλήθηκε επειδή η αίθουσα αλλάξε γιά μέλη μόνο"}.
{"has been kicked","αποβλήθηκε"}.
{"Host unknown","Ο κεντρικός διακομιστής είναι άγνωστος"}.
{"Host","Κεντρικός Υπολογιστής"}.
{"Host unknown","Άγνωστος εξυπηρετητής"}.
{"Host","Εξυπηρετητής"}.
{"HTTP File Upload","Ανέβασμα αρχείου"}.
{"Idle connection","Αδρανής σύνδεση"}.
{"If you don't see the CAPTCHA image here, visit the web page.","Εάν δεν βλέπετε την εικόνα CAPTCHA εδώ, επισκεφθείτε την ιστοσελίδα."}.
@@ -254,11 +259,12 @@
{"Members not added (inexistent vhost!): ","Τα μέλη δεν προστέθηκαν (ανύπαρκτος vhost!): "}.
{"Membership is required to enter this room","Απαιτείται αίτηση συμετοχής για είσοδο σε αυτή την αίθουσα"}.
{"Members:","Μέλη:"}.
{"Memorize your password, or write it in a paper placed in a safe place. In XMPP there isn't an automated way to recover your password if you forget it.","Απομνημονεύστε τον κωδικό πρόσβασής σας ή γράψτε τον σε χαρτί που βρίσκεται σε ασφαλές μέρος. Στο XMPP δεν υπάρχει αυτοματοποιημένος τρόπος ανάκτησης του κωδικού πρόσβασής σας εάν τον ξεχάσετε."}.
{"Memory","Μνήμη"}.
{"Mere Availability in XMPP (No Show Value)","Διαθεσιμότητα στο XMPP (Χωρίς ένδειξη)"}.
{"Message body","Περιεχόμενο μηνύματος"}.
{"Message not found in forwarded payload","Δεν βρέθηκε μήνυμα στον προωθημένο φόρτο εργασίας"}.
{"Messages from strangers are rejected","Μηνύματα αγνώστων απορρίπτονται"}.
{"Messages from strangers are rejected","Τα μηνύματα από αγνώστους απορρίπτονται"}.
{"Messages of type headline","Μηνύματα του τύπου headline"}.
{"Messages of type normal","Μηνύματα του τύπου normal"}.
{"Middle Name","Πατρώνυμο"}.
@@ -269,7 +275,8 @@
{"Modified modules","Τροποποιημένα modules"}.
{"Module failed to handle the query","Το module απέτυχε να χειριστεί το ερώτημα"}.
{"Monday","Δευτέρα"}.
{"Multicast","Multicast"}.
{"Multicast","Πολλαπλή διανομή (Multicast)"}.
{"Multiple <item/> elements are not allowed by RFC6121","Πολλαπλά στοιχεία <item/> δεν επιτρέπονται από το RFC6121"}.
{"Multi-User Chat","Συνομιλία με πολλούς χρήστες"}.
{"Name in the rosters where this group will be displayed","Όνομα στις λίστες όπου αυτή η ομάδα θα εμφανίζεται"}.
{"Name","Όνομα"}.
@@ -310,7 +317,7 @@
{"No running node found","Δεν βρέθηκε ενεργός κόμβος"}.
{"No services available","Δεν υπάρχουν διαθέσιμες υπηρεσίες"}.
{"No statistics found for this item","Δεν βρέθηκαν στατιστικά στοιχεία για αυτό το στοιχείο"}.
{"No 'to' attribute found in the invitation","Δεν βρέθηκε το χαρακτηριστικό 'to' στην πρόσκληση"}.
{"No 'to' attribute found in the invitation","Δε βρέθηκε το χαρακτηριστικό 'to' στην πρόσκληση"}.
{"Nobody","Κανείς"}.
{"Node already exists","Ο κόμβος υπάρχει ήδη"}.
{"Node ID","Ταυτότητα Κόμβου"}.
@@ -321,9 +328,9 @@
{"Nodes","Κόμβοι"}.
{"None","Κανένα"}.
{"Not allowed","Δεν επιτρέπεται"}.
{"Not Found","Δεν βρέθηκε"}.
{"Not Found","Δε βρέθηκε"}.
{"Not subscribed","Δεν έχετε εγγραφεί"}.
{"Notify subscribers when items are removed from the node","Ειδοποίηση στους συνδρομητές όταν αφαίρούνται στοιχεία από τον κόμβο"}.
{"Notify subscribers when items are removed from the node","Ειδοποιήστε τους συνδρομητές όταν αφαιρούνται στοιχεία από τον κόμβο"}.
{"Notify subscribers when the node configuration changes","Ειδοποίηση στους συνδρομητές όταν αλλάζει η διαμόρφωση κόμβου"}.
{"Notify subscribers when the node is deleted","Ειδοποίηση στους συνδρομητές όταν ο κόμβος διαγράφεται"}.
{"November","Νοέμβριος"}.
@@ -333,12 +340,12 @@
{"Number of online users","Αριθμός συνδεδεμένων χρηστών"}.
{"Number of registered users","Αριθμός εγγεγραμμένων χρηστών"}.
{"Number of seconds after which to automatically purge items","Πλήθος δευτερολέπτων μετά τα οποία αυτομάτως εκκαθαρίζονται αντικείμενα"}.
{"Occupants are allowed to invite others","Οι συμμετέχοντες μπορούν να προσκαλέσουν και άλλους"}.
{"Occupants are allowed to invite others","Οι συμμετέχοντες μπορούν να προσκαλέσουν και άλλους"}.
{"Occupants May Change the Subject","Επιτρέψτε στους χρήστες να αλλάζουν το Θέμα"}.
{"October","Οκτώβριος"}.
{"Offline Messages","Χωρίς Σύνδεση Μηνύματα"}.
{"Offline Messages:","Χωρίς Σύνδεση Μηνύματα:"}.
{"OK","Όλα Καλά"}.
{"OK","Εντάξει"}.
{"Old Password:","Παλαιός κωδικός πρόσβασης:"}.
{"Online Users:","Online Χρήστες:"}.
{"Online Users","Συνδεμένοι χρήστες"}.
@@ -352,12 +359,12 @@
{"Only moderators and participants are allowed to change the subject in this room","Μόνο οι συντονιστές και οι συμμετέχοντες μπορούν να αλλάξουν το θέμα αυτής της αίθουσας"}.
{"Only moderators are allowed to change the subject in this room","Μόνο οι συντονιστές μπορούν να αλλάξουν το θέμα αυτής της αίθουσας"}.
{"Only moderators can approve voice requests","Μόνο οι συντονιστές μπορούν να εγκρίνουν τις αιτήσεις φωνής"}.
{"Only occupants are allowed to send messages to the conference","Μόνο οι συμμετέχωντες μπορούν να στέλνουν μηνύματα στο συνέδριο"}.
{"Only occupants are allowed to send queries to the conference","Μόνο οι συμετεχόντες μπορούν να στείλουν ερωτήματα στη διάσκεψη"}.
{"Only occupants are allowed to send messages to the conference","Μόνο οι συμμετέχοντες επιτρέπεται να στέλνουν μηνύματα στο συνέδριο"}.
{"Only occupants are allowed to send queries to the conference","Μόνο οι συμμετέχοντες επιτρέπεται να στείλουν ερωτήματα στη διάσκεψη"}.
{"Only publishers may publish","Μόνον εκδότες μπορούν να δημοσιεύσουν"}.
{"Only service administrators are allowed to send service messages","Μόνο οι διαχειριστές των υπηρεσιών επιτρέπεται να στείλουν υπηρεσιακά μηνύματα"}.
{"Only those on a whitelist may associate leaf nodes with the collection","Μόνον οι εξαιρεθέντες μπορούν να συσχετίσουν leaf nodes με τη συλλογή"}.
{"Only those on a whitelist may subscribe and retrieve items","Μόνον οι εξαιρεθέντες επιτρέπεται να εγγραφούν και να λάβουν αντικείμενα"}.
{"Only those on a whitelist may subscribe and retrieve items","Μόνο όσοι βρίσκονται στη λίστα επιτρεπόμενων μπορούν να εγγραφούν και να ανακτήσουν αντικείμενα"}.
{"Organization Name","Όνομα Οργανισμού"}.
{"Organization Unit","Μονάδα Οργανισμού"}.
{"Outgoing s2s Connections","Εξερχόμενες S2S Συνδέσεις"}.
@@ -368,8 +375,8 @@
{"Participant","Συμμετέχων"}.
{"Password Verification","Επαλήθευση κωδικού πρόσβασης"}.
{"Password Verification:","Επαλήθευση κωδικού πρόσβασης:"}.
{"Password","Κωδικός πρόσβασης"}.
{"Password:","Κωδικός πρόσβασης:"}.
{"Password","Κωδικός Πρόσβασης"}.
{"Path to Dir","Τοποθεσία κατάλογου αρχείων"}.
{"Path to File","Τοποθεσία Αρχείου"}.
{"Payload type","Τύπος φόρτου εργασιών"}.
@@ -381,7 +388,8 @@
{"Ping","Ping"}.
{"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Παρακαλώ σημειώστε ότι οι επιλογές αυτές θα αποθήκευσουν Αντιγράφο Ασφαλείας μόνο της ενσωματωμένης βάσης δεδομένων Mnesia. Εάν χρησιμοποιείτε το module ODBC, θα πρέπει επίσης να κάνετε χωριστά Αντιγράφο Ασφαλείας της SQL βάσης δεδομένων σας."}.
{"Please, wait for a while before sending new voice request","Παρακαλώ, περιμένετε για λίγο πριν την αποστολή νέου αιτήματος φωνής"}.
{"Pong","Pong"}.
{"Pong","Πονγκ"}.
{"Possessing 'ask' attribute is not allowed by RFC6121","Η κατοχή χαρακτηριστικού \"ask\" δεν επιτρέπεται από το RFC6121"}.
{"Present real Jabber IDs to","Παρούσιαση πραγματικών ταυτοτήτων Jabber σε"}.
{"Previous session not found","Η προηγούμενη περίοδος σύνδεσης χρήστη δεν βρέθηκε"}.
{"Previous session PID has been killed","Το προηγούμενο αναγνωριστικό περιόδου σύνδεσης PID αφαιρέθηκε"}.
@@ -410,9 +418,9 @@
{"Registered Users:","Εγγεγραμμένοι Χρήστες:"}.
{"Register","Καταχωρήστε"}.
{"Remote copy","Εξ αποστάσεως αντίγραφο"}.
{"Remove All Offline Messages","Αφαίρεση όλων των Χωρίς Σύνδεση Μηνύματων"}.
{"Remove All Offline Messages","Αφαίρεση όλων των μηνυμάτων χωρίς σύνδεση"}.
{"Remove User","Αφαίρεση χρήστη"}.
{"Remove","Αφαίρεστε"}.
{"Remove","Αφαίρεση"}.
{"Replaced by new connection","Αντικαταστάθηκε από μια νέα σύνδεση"}.
{"Request has timed out","Το αίτημα έληξε"}.
{"Request is ignored","Το αίτημα θα αγνοηθεί"}.
@@ -464,6 +472,7 @@
{"Show Ordinary Table","Δείτε Κοινό Πίνακα"}.
{"Shut Down Service","Τερματισμός Υπηρεσίας"}.
{"SOCKS5 Bytestreams","Bytestreams του SOCKS5"}.
{"Some XMPP clients can store your password in the computer, but you should do this only in your personal computer for safety reasons.","Ορισμένοι πελάτες XMPP μπορούν να αποθηκεύσουν τον κωδικό πρόσβασής σας στον υπολογιστή, αλλά θα πρέπει να το κάνετε μόνο στον προσωπικό σας υπολογιστή για λόγους ασφαλείας."}.
{"Specify the access model","Καθορίστε το μοντέλο πρόσβασης"}.
{"Specify the event message type","Καθορίστε τον τύπο μηνύματος συμβάντος"}.
{"Specify the publisher model","Καθορίστε το μοντέλο εκδότη"}.
@@ -498,14 +507,15 @@
{"The body text of the last received message","Ο κορμός του κειμένου του τελευταίου μηνύματος"}.
{"The CAPTCHA is valid.","Το CAPTCHA είναι έγκυρο."}.
{"The CAPTCHA verification has failed","Η επαλήθευση της εικόνας CAPTCHA απέτυχε"}.
{"The child nodes (leaf or collection) associated with a collection","Οι θυγατρικοί κόμβοι (leaf ή collection) που σχετίζονται με μια Συλλογή"}.
{"The captcha you entered is wrong","Το captcha που εισαγάγατε είναι λάθος"}.
{"The child nodes (leaf or collection) associated with a collection","Οι θυγατρικοί κόμβοι (leaf ή collection) που σχετίζονται με μια συλλογή"}.
{"The collections with which a node is affiliated","Οι συλλογές με τις οποίες ένας κόμβος σχετίζεται"}.
{"The DateTime at which a leased subscription will end or has ended","Ο Χρόνος στον οποίο μια μισθωμένη συνδρομή θα Εκπνεύσει ή Τελειώσει"}.
{"The datetime when the node was created","Η χρονοσφραγίδα δημιουργίας του κόμβου"}.
{"The default language of the node","Η προρυθμισμένη γλώσσα του κόμβου"}.
{"The feature requested is not supported by the conference","Η λειτουργία που ζητήθηκε δεν υποστηρίζεται από τη διάσκεψη"}.
{"The JID of the node creator","Το JID του δημιουγού του κόμβου"}.
{"The JIDs of those to contact with questions","Το JID αυτών με τους οποίους θα επικοινωνήσετε για ερωτήσεις"}.
{"The JIDs of those to contact with questions","Το JID αυτών με τους οποίους θα επικοινωνήσετε με ερωτήσεις"}.
{"The JIDs of those with an affiliation of owner","Το JID αυτών που σχετίζονται με τον ιδιοκτήτη"}.
{"The JIDs of those with an affiliation of publisher","Το JID αυτών που σχετίζονται με τον εκδότη"}.
{"The list of JIDs that may associate leaf nodes with a collection","Λίστα των JIDs που μπορούν να σχετίζουν leaf κόμβους με μια Συλλογή"}.
@@ -521,7 +531,7 @@
{"The password contains unacceptable characters","Ο κωδικός πρόσβασης περιέχει μη αποδεκτούς χαρακτήρες"}.
{"The password is too weak","Ο κωδικός πρόσβασης είναι πολύ αδύναμος"}.
{"the password is","ο κωδικός πρόσβασης είναι"}.
{"The password of your XMPP account was successfully changed.","Ο κωδικός πρόσβασης του XMPP λογαριασμού σας έχει αλλάξει επιτυχώς."}.
{"The password of your XMPP account was successfully changed.","Ο κωδικός πρόσβασης του XMPP λογαριασμού σας έχει αλλάξει επιτυχώς."}.
{"The password was not changed","Ο κωδικός πρόσβασης δεν άλλαξε"}.
{"The passwords are different","Οι κωδικοί πρόσβασης δεν ταιριάζουν"}.
{"The presence states for which an entity wants to receive notifications","Η παρουσία δηλώνει για ποιους θέλει κάποιος να λαμβάνει ειδοποιήσεις"}.
@@ -535,8 +545,12 @@
{"The URL of an XSL transformation which can be applied to payloads in order to generate an appropriate message body element.","Το URL ενός μετασχηματισμού XSL το οποίο μπορεί να εφαρμοστεί σε φόρτους εργασίας για να παραχθεί το κατάλληλο στοιχείο του σώματος του μηνύματος."}.
{"The URL of an XSL transformation which can be applied to the payload format in order to generate a valid Data Forms result that the client could display using a generic Data Forms rendering engine","Το URL ενός μετασχηματισμού XSL, το οποίο μπορεί να εφαρμοστεί στους τύπους φόρτου εργασίας για να παραχθεί έγκυρο αποτέλεσμα Data Forms, τέτοιο που ο πελάτης μπορεί να εμφανίσει, χρησιμοποιώντας μια ευρείας χρήσης μηχανή επεξεργασίας Data Forms"}.
{"The username is not valid","Το όνομα Χρήστη δεν είναι έγκυρο"}.
{"There was an error changing the password: ","Παρουσιάστηκε σφάλμα κατά την αλλαγή του κωδικού πρόσβασης: "}.
{"There was an error creating the account: ","Υπήρξε ένα σφάλμα κατά τη δημιουργία του λογαριασμού: "}.
{"There was an error deleting the account: ","Υπήρξε ένα σφάλμα κατά τη διαγραφή του λογαριασμού: "}.
{"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Αυτό σημαίνει ότι δεν έχει σημασία αν είναι κεφαλαία ή πεζά γράμματα: \"κατσαντώνης\" είναι το ίδιο με \"ΚατσΑντώνης\" , όπως και \"Κατσαντώνης\"."}.
{"This page allows to register an XMPP account in this XMPP server. Your JID (Jabber ID) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Αυτή η σελίδα επιτρέπει την εγγραφή ενός λογαριασμού XMPP σε αυτόν τον διακομιστή XMPP. Το JID (Jabber ID) θα έχει τη μορφή: όνομαχρήστη@διακομιστής. Διαβάστε προσεκτικά τις οδηγίες για να συμπληρώσετε σωστά τα πεδία."}.
{"This page allows to unregister an XMPP account in this XMPP server.","Αυτή η σελίδα επιτρέπει την κατάργηση εγγραφής ενός λογαριασμού XMPP σε αυτόν τον διακομιστή XMPP."}.
{"This room is not anonymous","Η αίθουσα αυτή δεν είναι ανώνυμη"}.
{"This service can not process the address: ~s","Αυτή η υπηρεσία δεν μπορεί να επεξεργαστεί την διεύθυνση: ~s"}.
{"Thursday","Πέμπτη"}.
@@ -545,7 +559,7 @@
{"Time","Χρόνος"}.
{"To register, visit ~s","Για να εγγραφείτε, επισκεφθείτε το ~s"}.
{"To ~ts","Προς ~ts"}.
{"Token TTL","Token TTL"}.
{"Token TTL","Διακριτικό TTL"}.
{"Too many active bytestreams","Πάρα πολλά ενεργά bytestreams"}.
{"Too many CAPTCHA requests","Πάρα πολλά αιτήματα CAPTCHA"}.
{"Too many child elements","Πάρα πολλά θυγατρικά στοιχεία"}.
@@ -584,6 +598,7 @@
{"URL for Archived Discussion Logs","URL αρχειοθετημένων καταγραφών συζητήσεων"}.
{"User already exists","Ο χρήστης υπάρχει ήδη"}.
{"User JID","JID Χρήστη"}.
{"User (jid)","Χρήστης (jid)"}.
{"User Management","Διαχείριση χρηστών"}.
{"User removed","Ο Χρήστης αφαιρέθηκε"}.
{"User session not found","Η περίοδος σύνδεσης χρήστη δεν βρέθηκε"}.
@@ -624,7 +639,7 @@
{"Who may associate leaf nodes with a collection","Ποιός μπορεί να συσχετίζει leaf nodes με μία συλλογή"}.
{"Wrong parameters in the web formulary","Εσφαλμένες παράμετροι στην διαμόρφωση τυπικότητας του δυκτίου"}.
{"Wrong xmlns","Εσφαλμένο xmlns"}.
{"XMPP Account Registration","Εγγραφή με Ψευδώνυμο στο "}.
{"XMPP Account Registration","Εγγραφή λογαριασμού XMPP"}.
{"XMPP Domains","Ονόματα χώρου XMPP"}.
{"XMPP Show Value of Away","Δείξε τιμή XMPP Απεμακρύνθην"}.
{"XMPP Show Value of Chat","Δείξε τιμή XMPP Αξία Συνομιλίας"}.
@@ -633,6 +648,7 @@
{"XMPP URI of Associated Publish-Subscribe Node","XMPP URI του συσχετισμένου κόμβου Δημοσίευσης-Εγγραφής"}.
{"You are being removed from the room because of a system shutdown","Απαιτείται η απομάκρυνσή σας από την αίθουσα, λόγω τερματισμού συστήματος"}.
{"You are not joined to the channel","Δεν λαμβάνετε μέρος στο κανάλι"}.
{"You can later change your password using an XMPP client.","Μπορείτε αργότερα να αλλάξετε τον κωδικό πρόσβασής σας χρησιμοποιώντας ένα πρόγραμμα-πελάτη XMPP."}.
{"You have been banned from this room","Σας έχει απαγορευθεί η είσοδος σε αυτή την αίθουσα"}.
{"You have joined too many conferences","Είσθε σε πάρα πολλά συνέδρια"}.
{"You must fill in field \"Nickname\" in the form","Απαιτείται να συμπληρώσετε το πεδίο \"Ψευδώνυμο\" στη φόρμα"}.
@@ -642,4 +658,6 @@
{"Your active privacy list has denied the routing of this stanza.","Ο ενεργός κατάλογος απορρήτου, έχει αρνηθεί τη δρομολόγηση αυτής της στροφής (stanza)."}.
{"Your contact offline message queue is full. The message has been discarded.","Η μνήμη μηνυμάτων χωρίς σύνδεση είναι πλήρης. Το μήνυμα έχει απορριφθεί."}.
{"Your subscription request and/or messages to ~s have been blocked. To unblock your subscription request, visit ~s","Τα μηνύματά σας προς ~s είναι αποκλεισμένα. Για αποδεσμεύση, επισκεφθείτε ~s"}.
{"Your XMPP account was successfully registered.","Ο λογαριασμός σας XMPP καταχωρήθηκε με επιτυχία."}.
{"Your XMPP account was successfully unregistered.","Ο XMPP λογαριασμός σας διαγράφηκε με επιτυχία."}.
{"You're not allowed to create nodes","Δεν σας επιτρέπεται η δημιουργία κόμβων"}.
+74 -9
View File
@@ -1,8 +1,22 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (Aldonu * al la fino de la kampo por kongruigi subĉenon)"}.
{" has set the subject to: "," ŝanĝis la temon al: "}.
{"A friendly name for the node","Kromnomo por ĉi tiu nodo"}.
{"# participants","Nombro de partoprenantoj"}.
{"A description of the node","Priskribo de la nodo"}.
{"A friendly name for the node","Kromnomo de la nodo"}.
{"A password is required to enter this room","Pasvorto estas bezonata por eniri ĉi tiun babilejon"}.
{"A Web Page","Retpaĝo"}.
{"Accept","Akcepti"}.
{"Access denied by service policy","Atingo rifuzita de serv-politiko"}.
{"Access model of open","Atingomodelo de malfermo"}.
{"Access model of presence","Atingomodelo de ĉeesto"}.
{"Access model of whitelist","Atingomodelo de permesolisto"}.
{"Access model","Atingomodelo"}.
{"Account doesn't exist","Konto ne ekzistas"}.
{"Action on user","Ago je uzanto"}.
{"Add Jabber ID","Aldonu Jabber ID"}.
{"Add New","Aldonu novan"}.
@@ -12,7 +26,8 @@
{"Administrator privileges required","Administrantaj rajtoj bezonata"}.
{"All activity","Ĉiu aktiveco"}.
{"All Users","Ĉiuj Uzantoj"}.
{"Allow this Jabber ID to subscribe to this pubsub node?","Ĉu permesi ĉi tiun Jabber ID aboni al la jena PubAbo-nodo"}.
{"Allow subscription","Permesi abonon"}.
{"Allow this Jabber ID to subscribe to this pubsub node?","Ĉu permesi ĉi tiun Jabber ID aboni al la jena PubAbo-nodo?"}.
{"Allow users to change the subject","Permesu uzantojn ŝanĝi la temon"}.
{"Allow users to query other users","Permesu uzantojn informpeti aliajn uzantojn"}.
{"Allow users to send invites","Permesu uzantojn sendi invitojn"}.
@@ -22,7 +37,18 @@
{"Allow visitors to send status text in presence updates","Permesu al vizitantoj sendi statmesaĝon en ĉeest-sciigoj"}.
{"Allow visitors to send voice requests","Permesu uzantojn sendi voĉ-petojn"}.
{"Announcements","Anoncoj"}.
{"Answer associated with a picture","Respondo asociita kun bildo"}.
{"Answer associated with a video","Respondo asociita kun filmeto"}.
{"Answer associated with speech","Respondo asociita kun parolo"}.
{"Answer to a question","Respondo al demando"}.
{"Anyone may publish","Ĉiu rajtas publici"}.
{"Anyone with Voice","Iu ajn kun Voĉo"}.
{"Anyone","Iu ajn"}.
{"April","Aprilo"}.
{"Attribute 'channel' is required for this request","Atributo 'channel' necesas por ĉi tiu peto"}.
{"Attribute 'id' is mandatory for MIX messages","Atributo 'id' estas deviga en MIX-mesaĝo"}.
{"Attribute 'jid' is not allowed here","Atributo 'jid' ne estas permesita ĉi tie"}.
{"Attribute 'node' is not allowed here","Atributo 'node' ne estas permesita ĉi tie"}.
{"August","Aŭgusto"}.
{"Backup Management","Mastrumado de sekurkopioj"}.
{"Backup of ~p","Sekurkopio de ~p"}.
@@ -30,9 +56,14 @@
{"Backup","Faru Sekurkopion"}.
{"Bad format","Malĝusta formo"}.
{"Birthday","Naskiĝtago"}.
{"Cannot remove active list","Ne povas forigi aktivan liston"}.
{"CAPTCHA web page","CAPTCHA teksaĵ-paĝo"}.
{"Challenge ID","Identigilo de Defio"}.
{"Change Password","Ŝanĝu pasvorton"}.
{"Change User Password","Ŝanĝu pasvorton de uzanto"}.
{"Channel already exists","Kanalo jam ekzistas"}.
{"Channel does not exist","Kanalo ne ekzistas"}.
{"Channels","Kanaloj"}.
{"Characters not allowed:","Karaktroj ne permesata:"}.
{"Chatroom configuration modified","Agordo de babilejo ŝanĝita"}.
{"Chatroom is created","Babilejo kreita"}.
@@ -42,7 +73,7 @@
{"Chatrooms","Babilejoj"}.
{"Choose a username and password to register with this server","Elektu uzantnomon kaj pasvorton por registri je ĉi tiu servilo"}.
{"Choose storage type of tables","Elektu konserv-tipon de tabeloj"}.
{"Choose whether to approve this entity's subscription.","Elektu ĉu permesi la abonon de ĉi tiu ento"}.
{"Choose whether to approve this entity's subscription.","Elektu ĉu permesi la abonon de ĉi tiu ento."}.
{"City","Urbo"}.
{"Commands","Ordonoj"}.
{"Conference room does not exist","Babilejo ne ekzistas"}.
@@ -51,6 +82,7 @@
{"Connected Resources:","Konektataj risurcoj:"}.
{"Country","Lando"}.
{"CPU Time:","CPU-tempo"}.
{"Current Discussion Topic","Aktuala Diskuta Temo"}.
{"Database Tables at ~p","Datumbaz-tabeloj je ~p"}.
{"Database Tables Configuration at ","Agordo de datumbaz-tabeloj je "}.
{"Database","Datumbazo"}.
@@ -66,6 +98,7 @@
{"Disc only copy","Nur disk-kopio"}.
{"Dump Backup to Text File at ","Skribu sekurkopion en plata teksto al "}.
{"Dump to Text File","Skribu en plata tekst-dosiero"}.
{"Duplicated groups are not allowed by RFC6121","RFC 6121 ne permesas duplikatajn grupojn"}.
{"Edit Properties","Redaktu atributojn"}.
{"Either approve or decline the voice request.","Ĉu aprobu, aŭ malaprobu la voĉ-peton."}.
{"ejabberd MUC module","ejabberd MUC-modulo"}.
@@ -74,7 +107,9 @@
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bajtfluo modulo"}.
{"ejabberd vCard module","ejabberd vCard-modulo"}.
{"ejabberd Web Admin","ejabberd Teksaĵa Administro"}.
{"ejabberd","ejabberd"}.
{"Elements","Eroj"}.
{"Email Address","Retpoŝta Adreso"}.
{"Email","Retpoŝto"}.
{"Enable logging","Ŝaltu protokoladon"}.
{"Enable message archiving","Ŝaltu mesaĝo-arkivo"}.
@@ -93,6 +128,7 @@
{"Failed to extract JID from your voice request approval","Malsukcesis ekstrakti JID-on de via voĉ-pet-aprobo"}.
{"Family Name","Lasta Nomo"}.
{"February","Februaro"}.
{"File larger than ~w bytes","Dosiero pli granda ol ~w bajtoj"}.
{"Friday","Vendredo"}.
{"From","De"}.
{"Full Name","Plena Nomo"}.
@@ -101,6 +137,7 @@
{"Get User Last Login Time","Montru tempon de lasta ensaluto"}.
{"Get User Password","Montru pasvorton de uzanto"}.
{"Get User Statistics","Montru statistikojn de uzanto"}.
{"Given Name","Persona Nomo"}.
{"Grant voice to this person?","Koncedu voĉon al ĉi-persono?"}.
{"Group","Grupo"}.
{"Groups","Grupoj"}.
@@ -120,6 +157,7 @@
{"Import Users from Dir at ","Importu uzantojn de dosierujo ĉe "}.
{"Import Users From jabberd14 Spool Files","Importu uzantojn de jabberd14-uzantdosieroj"}.
{"Improper message type","Malĝusta mesaĝo-tipo"}.
{"Incorrect CAPTCHA submit","Neĝusta CAPTCHA-submeto"}.
{"Incorrect password","Nekorekta pasvorto"}.
{"IP addresses","IP-adresoj"}.
{"is now known as","nun nomiĝas"}.
@@ -131,6 +169,8 @@
{"joins the room","eniras la babilejo"}.
{"July","Julio"}.
{"June","Junio"}.
{"Just created","Ĵus kreita"}.
{"Label:","Etikedo:"}.
{"Last Activity","Lasta aktiveco"}.
{"Last login","Lasta ensaluto"}.
{"Last month","Lasta monato"}.
@@ -139,7 +179,7 @@
{"List of rooms","Listo de babilejoj"}.
{"Low level update script","Bazanivela ĝisdatigo-skripto"}.
{"Make participants list public","Farigu partoprento-liston publika"}.
{"Make room CAPTCHA protected","Farigu babilejon protektata per CAPTCHA"}.
{"Make room CAPTCHA protected","Protektu babilejon per CAPTCHA"}.
{"Make room members-only","Farigu babilejon sole por membroj"}.
{"Make room moderated","Farigu babilejon moderigata"}.
{"Make room password protected","Farigu babilejon protektata per pasvorto"}.
@@ -148,6 +188,7 @@
{"March","Marĉo"}.
{"Max # of items to persist","Maksimuma kiomo de eroj en konservado"}.
{"Max payload size in bytes","Maksimuma aĵo-grando je bajtoj"}.
{"Maximum file size","Maksimuma grando de dosiero"}.
{"Maximum Number of Occupants","Limigo de nombro de partoprenantoj"}.
{"May","Majo"}.
{"Membership is required to enter this room","Membreco estas bezonata por eniri ĉi tiun babilejon"}.
@@ -158,19 +199,30 @@
{"Minimum interval between voice requests (in seconds)","Minimuma intervalo inter voĉ-petoj (je sekundoj)"}.
{"Moderator privileges required","Moderantaj rajtoj bezonata"}.
{"Modified modules","Ĝisdatigitaj moduloj"}.
{"Module failed to handle the query","Modulo malsukcesis trakti la informpeton"}.
{"Monday","Lundo"}.
{"Multicast","Multicast"}.
{"Multiple <item/> elements are not allowed by RFC6121","RFC 6121 ne permesas plurajn <item/>-elementojn"}.
{"Multi-User Chat","Grupbabilado"}.
{"Name","Nomo"}.
{"Name:","Nomo:"}.
{"Natural Language for Room Discussions","Homa Lingvo por Diskutoj en Babilejo"}.
{"Never","Neniam"}.
{"New Password:","Nova Pasvorto:"}.
{"Nickname Registration at ","Kaŝnomo-registrado je "}.
{"Nickname ~s does not exist in the room","Kaŝnomo ~s ne ekzistas en la babilejo"}.
{"Nickname","Kaŝnomo"}.
{"No address elements found","Adresa elemento ne trovita"}.
{"No addresses element found","Adresa elemento ne trovita"}.
{"No body provided for announce message","Neniu teksto donita por anonc-mesaĝo"}.
{"No child elements found","Ida elemento ne trovita"}.
{"No Data","Neniu datumo"}.
{"No <forwarded/> element found","Elemento <forwarded/> ne trovita"}.
{"No items found in this query","Neniu elemento <item/> trovita en ĉi tiu informpeto"}.
{"No limit","Neniu limigo"}.
{"No module is handling this query","Neniu modulo traktas ĉi tiun informpeton"}.
{"No 'password' found in this query","Neniu pasvorto trovita en ĉi tiu informpeto"}.
{"No private data found in this query","Neniu privata dateno trovita en ĉi tiu informpeto"}.
{"Node ID","Nodo ID"}.
{"Node not found","Nodo ne trovita"}.
{"Node ~p","Nodo ~p"}.
@@ -193,12 +245,16 @@
{"Online Users","Konektataj Uzantoj"}.
{"Online","Konektata"}.
{"Only deliver notifications to available users","Nur liveru sciigojn al konektataj uzantoj"}.
{"Only <list/> element is allowed in this query","Nur la elemento <list/> estas permesita en ĉi tiu informpeto"}.
{"Only moderators and participants are allowed to change the subject in this room","Nur moderigantoj kaj partoprenantoj rajtas ŝanĝi la temon en ĉi tiu babilejo"}.
{"Only moderators are allowed to change the subject in this room","Nur moderigantoj rajtas ŝanĝi la temon en ĉi tiu babilejo"}.
{"Only moderators can approve voice requests","Nur moderigantoj povas aprobi voĉ-petojn"}.
{"Only occupants are allowed to send messages to the conference","Nur partoprenantoj rajtas sendi mesaĝojn al la babilejo"}.
{"Only occupants are allowed to send queries to the conference","Nur partoprenantoj rajtas sendi informmendojn al la babilejoj"}.
{"Only publishers may publish","Nur publicantoj rajtas publici"}.
{"Only service administrators are allowed to send service messages","Nur servo-administrantoj rajtas sendi serv-mesaĝojn"}.
{"Only those on a whitelist may associate leaf nodes with the collection","Nur tiuj en permesolisto rajtas asocii foliajn nodojn kun la kolekto"}.
{"Only those on a whitelist may subscribe and retrieve items","Nur tiuj en permesolisto rajtas aboni kaj preni erojn"}.
{"Organization Name","Organiz-nomo"}.
{"Organization Unit","Organiz-parto"}.
{"Outgoing s2s Connections","Elirantaj s-al-s-konektoj"}.
@@ -220,14 +276,16 @@
{"Pong","Resondaĵo"}.
{"Present real Jabber IDs to","Montru verajn Jabber ID-ojn al"}.
{"private, ","privata, "}.
{"Publish-Subscribe","Public-Abonado"}.
{"Publish model","Publici modelon"}.
{"Publish-Subscribe","Publici-Aboni"}.
{"PubSub subscriber request","PubAbo abonpeto"}.
{"Purge all items when the relevant publisher goes offline","Forigu ĉiujn erojn kiam la rilata publikanto malkonektiĝas"}.
{"Purge all items when the relevant publisher goes offline","Forigu ĉiujn erojn kiam la rilata publicanto malkonektiĝas"}.
{"Queries to the conference members are not allowed in this room","Malpermesas informmendoj al partoprenantoj en ĉi tiu babilejo"}.
{"Query to another users is forbidden","Informpeto al aliaj uzantoj estas malpermesita"}.
{"RAM and disc copy","RAM- kaj disk-kopio"}.
{"RAM copy","RAM-kopio"}.
{"Really delete message of the day?","Ĉu vere forigi mesaĝon de la tago?"}.
{"Recipient is not in the conference room","Ricevanto ne ĉeestas en la babilejo "}.
{"Recipient is not in the conference room","Ricevanto ne ĉeestas en la babilejo"}.
{"Registered Users","Registritaj uzantoj"}.
{"Registered Users:","Registritaj uzantoj:"}.
{"Register","Registru"}.
@@ -283,15 +341,19 @@
{"Submit","Sendu"}.
{"Submitted","Sendita"}.
{"Subscriber Address","Abonanta adreso"}.
{"Subscribers may publish","Abonantoj rajtas publici"}.
{"Subscription","Abono"}.
{"Sunday","Dimanĉo"}.
{"That nickname is already in use by another occupant","Tiu kaŝnomo jam estas uzata de alia partoprenanto"}.
{"That nickname is registered by another person","Kaŝnomo estas registrita de alia persono"}.
{"The CAPTCHA is valid.","La CAPTCHA ĝustas"}.
{"The CAPTCHA is valid.","La CAPTCHA ĝustas."}.
{"The CAPTCHA verification has failed","La CAPTCHA-kontrolado malsukcesis"}.
{"The captcha you entered is wrong","La CAPTCHA enigita de vi malĝustas"}.
{"The collections with which a node is affiliated","Aro kun kiu nodo estas filigita"}.
{"The password is too weak","La pasvorto estas ne sufiĉe forta"}.
{"the password is","la pasvorto estas"}.
{"The query is only allowed from local users","La informpeto estas permesita nur de lokaj uzantoj"}.
{"The query must not contain <item/> elements","La informpeto devas ne enhavi elementojn <item/>"}.
{"There was an error creating the account: ","Estis eraro dum kreado de la konto:"}.
{"There was an error deleting the account: ","Estis eraro dum forigado de la konto:"}.
{"This room is not anonymous","Ĉi tiu babilejo ne estas anonima"}.
@@ -319,6 +381,7 @@
{"Update script","Ĝisdatigo-skripto"}.
{"Update","Ĝisdatigu"}.
{"Uptime:","Daŭro de funkciado"}.
{"URL for Archived Discussion Logs","Retpaĝa adreso de Enarkivigitaj Diskutprotokoloj"}.
{"User JID","Uzant-JID"}.
{"User Management","Uzanto-administrado"}.
{"Username:","Uzantnomo"}.
@@ -336,6 +399,8 @@
{"Wednesday","Merkredo"}.
{"When to send the last published item","Kiam sendi la laste publicitan eron"}.
{"Whether to allow subscriptions","Ĉu permesi aboni"}.
{"Wrong xmlns","Malĝusta XML-nomspaco (xmlns)"}.
{"XMPP Account Registration","Registrado de XMPP-Konto"}.
{"You have been banned from this room","Vi estas malpermesata en ĉi tiu babilejo"}.
{"You must fill in field \"Nickname\" in the form","Vi devas kompletigi la \"Kaŝnomo\" kampon"}.
{"You need a client that supports x:data and CAPTCHA to register","Vi bezonas klienton subtenante x:data-funkcio kaj CAPTCHA por registri kaŝnomon"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (Añade * al final del campo para buscar subcadenas)"}.
{" has set the subject to: "," ha puesto el asunto: "}.
{"# participants","# participantes"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (Ajouter * à la fin du champ pour correspondre à la sous-chaîne)"}.
{" has set the subject to: "," a défini le sujet sur : "}.
{"A description of the node","Une description du nœud"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," puxo o asunto: "}.
{"A friendly name for the node","Un nome sinxelo para o nodo"}.
{"A password is required to enter this room","Necesítase contrasinal para entrar nesta sala"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," הגדיר/ה את הנושא אל: "}.
{"A friendly name for the node","שם ידידותי עבור הצומת"}.
{"A password is required to enter this room","נדרשת סיסמה כדי להיכנס אל חדר זה"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (adjon * karaktert a mező végéhez a részkarakterláncra illesztéshez)"}.
{" has set the subject to: "," beállította a tárgyat erre: "}.
{"A password is required to enter this room","Jelszó szükséges a szobába történő belépéshez"}.
+95 -11
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," Isi formulir untuk pencarian pengguna Jabber yang cocok (Tambahkan * ke mengakhiri pengisian untuk menyamakan kata)"}.
{" has set the subject to: "," telah menetapkan topik yaitu: "}.
{"# participants","# pengguna"}.
@@ -9,8 +13,10 @@
{"Accept","Diterima"}.
{"Access denied by service policy","Akses ditolak oleh kebijakan layanan"}.
{"Access model of authorize","Model akses otorisasi"}.
{"Access model of open","Model akses terbuka"}.
{"Access model of presence","Model akses kehadiran"}.
{"Access model of roster","model akses daftar kontak"}.
{"Access model of whitelist","Model akses daftar putih"}.
{"Access model","Model akses"}.
{"Account doesn't exist","Akun tidak ada"}.
{"Action on user","Tindakan pada pengguna"}.
@@ -30,7 +36,9 @@
{"Allow users to send invites","Perbolehkan pengguna mengirimkan undangan"}.
{"Allow users to send private messages","perbolehkan pengguna mengirimkan pesan ke pengguna lain secara pribadi"}.
{"Allow visitors to change nickname","Perbolehkan visitor mengganti nama julukan"}.
{"Allow visitors to send private messages to","Izinkan pengunjung mengirimkan pesan privat ke"}.
{"Allow visitors to send status text in presence updates","Izinkan pengunjung untuk mengirim teks status terbaru"}.
{"Allow visitors to send voice requests","Izinkan pengunjung mengirim permintaan suara"}.
{"Announcements","Pengumuman"}.
{"Answer associated with a picture","Jawaban yang berhubungan dengan gambar"}.
{"Answer associated with a video","Jawaban yang berhubungan dengan video"}.
@@ -40,6 +48,7 @@
{"Anyone may publish","Siapapun dapat mempublikasi"}.
{"Anyone may subscribe and retrieve items","Siapapun dapat berlangganan dan mengambil item"}.
{"Anyone with Voice","Siapapun dengan fungsi suara"}.
{"Anyone","Siapapun"}.
{"April","April"}.
{"Attribute 'channel' is required for this request","Atribut 'channel' diperlukan untuk permintaan ini"}.
{"Attribute 'id' is mandatory for MIX messages","Atribut 'id' harus ada untuk pesan MIX"}.
@@ -108,8 +117,9 @@
{"Don't tell your password to anybody, not even the administrators of the XMPP server.","Jangan beritahukan kata sandi Anda ke siapapun, bahkan ke administrator layanan XMPP."}.
{"Dump Backup to Text File at ","Dump Backup menjadi File Teks di "}.
{"Dump to Text File","Dump menjadi File Teks"}.
{"Duplicated groups are not allowed by RFC6121","Grup duplikat tidak diperbolehkan oleh RFC6121"}.
{"Edit Properties","Ganti Properti"}.
{"Either approve or decline the voice request.","Antara terima atau tolak permintaan suara"}.
{"Either approve or decline the voice request.","Antara terima atau tolak permintaan suara."}.
{"ejabberd HTTP Upload service","Layanan HTTP Upload ejabberd"}.
{"ejabberd MUC module","Modul MUC ejabberd"}.
{"ejabberd Multicast service","Layanan Multicast ejabberd"}.
@@ -131,8 +141,10 @@
{"Enter path to jabberd14 spool file","Masukkan path ke file jabberd14 spool"}.
{"Enter path to text file","Masukkan path ke file teks"}.
{"Enter the text you see","Masukkan teks yang Anda lihat"}.
{"Erlang XMPP Server","Server Erlang XMPP"}.
{"Error","Kesalahan"}.
{"Exclude Jabber IDs from CAPTCHA challenge","Kecualikan Jabber IDs dari tantangan CAPTCHA"}.
{"Export all tables as SQL queries to a file:","Ekspor semua tabel sebagai kueri SQL ke file:"}.
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Ekspor data dari semua pengguna pada layanan ke berkas PIEFXIS (XEP-0227):"}.
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Ekspor data pengguna pada sebuah host ke berkas PIEFXIS (XEP-0227):"}.
{"External component failure","Kegagalan komponen eksternal"}.
@@ -145,6 +157,7 @@
{"FAQ Entry","Entri FAQ"}.
{"February","Februari"}.
{"File larger than ~w bytes","File lebih besar dari ~w bytes"}.
{"Fill in the form to search for any matching XMPP User","Isi kolom untuk mencari pengguna XMPP"}.
{"Friday","Jumat"}.
{"From ~ts","Dari ~ts"}.
{"From","Dari"}.
@@ -157,8 +170,11 @@
{"Get User Last Login Time","Lihat Waktu Login Terakhir Pengguna"}.
{"Get User Password","Dapatkan User Password"}.
{"Get User Statistics","Dapatkan Statistik Pengguna"}.
{"Given Name","Nama"}.
{"Grant voice to this person?","Ijinkan akses suara kepadanya?"}.
{"Group","Grup"}.
{"Groups that will be displayed to the members","Grup yang akan ditampilkan kepada anggota"}.
{"Groups","Grup"}.
{"has been banned","telah dibanned"}.
{"has been kicked because of a system shutdown","telah dikick karena sistem shutdown"}.
{"has been kicked because of an affiliation change","telah dikick karena perubahan afiliasi"}.
@@ -166,17 +182,27 @@
{"has been kicked","telah dikick"}.
{"Host unknown","Host tidak dikenal"}.
{"Host","Host"}.
{"HTTP File Upload","Unggah Berkas HTTP"}.
{"Idle connection","Koneksi menganggur"}.
{"If you don't see the CAPTCHA image here, visit the web page.","Jika Anda tidak melihat gambar CAPTCHA disini, silahkan kunjungi halaman web."}.
{"Import Directory","Impor Direktori"}.
{"Import File","Impor File"}.
{"Import user data from jabberd14 spool file:","Impor data pengguna dari sekumpulan berkas jabberd14:"}.
{"Import User from File at ","Impor Pengguna dari File pada"}.
{"Import User from File at ","Impor Pengguna dari File pada "}.
{"Import users data from a PIEFXIS file (XEP-0227):","impor data-data pengguna dari sebuah PIEFXIS (XEP-0227):"}.
{"Import users data from jabberd14 spool directory:","Импорт пользовательских данных из буферной директории jabberd14:"}.
{"Import Users from Dir at ","Impor Pengguna dari Dir di"}.
{"Import Users from Dir at ","Impor Pengguna dari Dir di "}.
{"Import Users From jabberd14 Spool Files","Impor Pengguna Dari jabberd14 Spool File"}.
{"Improper message type","Jenis pesan yang tidak benar"}.
{"Incoming s2s Connections:","Koneksi s2s masuk:"}.
{"Incorrect CAPTCHA submit","Isian CAPTCHA salah"}.
{"Incorrect data form","Formulir data salah"}.
{"Incorrect password","Kata sandi salah"}.
{"Incorrect value of 'action' attribute","Nilai atribut 'aksi' salah"}.
{"Incorrect value of 'action' in data form","Nilai 'tindakan' yang salah dalam formulir data"}.
{"Insufficient privilege","Hak tidak mencukupi"}.
{"Internal server error","Galat server internal"}.
{"Invalid node name","Nama node tidak valid"}.
{"IP addresses","Alamat IP"}.
{"is now known as","sekarang dikenal sebagai"}.
{"It is not allowed to send private messages of type \"groupchat\"","Hal ini tidak diperbolehkan untuk mengirim pesan pribadi jenis \"groupchat \""}.
@@ -213,15 +239,17 @@
{"Moderator privileges required","Hak istimewa moderator dibutuhkan"}.
{"Modified modules","Modifikasi modul-modul"}.
{"Monday","Senin"}.
{"Multiple <item/> elements are not allowed by RFC6121","Beberapa elemen <item/> tidak diizinkan oleh RFC6121"}.
{"Name","Nama"}.
{"Name:","Nama:"}.
{"Never","Tidak Pernah"}.
{"New Password:","Password Baru:"}.
{"Nickname Registration at ","Pendaftaran Julukan pada"}.
{"Nickname Registration at ","Pendaftaran Julukan pada "}.
{"Nickname ~s does not exist in the room","Nama Julukan ~s tidak berada di dalam ruangan"}.
{"Nickname","Nama Julukan"}.
{"No body provided for announce message","Tidak ada isi pesan yang disediakan untuk mengirimkan pesan"}.
{"No Data","Tidak Ada Data"}.
{"No <forwarded/> element found","Tidak ada elemen <forwarded/> yang ditemukan"}.
{"No limit","Tidak terbatas"}.
{"Node ID","ID Node"}.
{"Node not found","Node tidak ditemukan"}.
@@ -255,28 +283,45 @@
{"Outgoing s2s Connections:","Koneksi s2s yang keluar:"}.
{"Owner privileges required","Hak istimewa owner dibutuhkan"}.
{"Packet","Paket"}.
{"Participant","Partisipan"}.
{"Password Verification:","Verifikasi Kata Sandi:"}.
{"Password Verification","Verifikasi Sandi"}.
{"Password:","Kata Sandi:"}.
{"Password","Sandi"}.
{"Path to Dir","Jalur ke Dir"}.
{"Path to File","Jalur ke File"}.
{"Payload type","Tipe payload"}.
{"Pending","Tertunda"}.
{"Period: ","Periode:"}.
{"Period: ","Periode: "}.
{"Persist items to storage","Pertahankan item ke penyimpanan"}.
{"Persistent","Persisten"}.
{"Ping query is incorrect","Kueri ping salah"}.
{"Ping","Ping"}.
{"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Harap dicatat bahwa pilihan ini hanya akan membuat cadangan builtin Mnesia database. Jika Anda menggunakan modul ODBC, anda juga perlu untuk membuat cadangan database SQL Anda secara terpisah."}.
{"Pong","Pong"}.
{"Present real Jabber IDs to","Tampilkan Jabber ID secara lengkap"}.
{"Previous session not found","Sesi sebelumnya tidak ditemukan"}.
{"Previous session PID has been killed","Sesi PID sebelumnya telah dimatikan"}.
{"Previous session PID has exited","Sesi PID sebelumnya telah keluar"}.
{"Previous session PID is dead","Sesi PID sebelumnya mati"}.
{"Previous session timed out","Sesi sebelumnya habis waktu"}.
{"private, ","pribadi, "}.
{"Public","Publik"}.
{"Publish model","Model penerbitan"}.
{"Publish-Subscribe","Setujui-Pertemanan"}.
{"PubSub subscriber request","Permintaan pertemanan PubSub"}.
{"Purge all items when the relevant publisher goes offline","Bersihkan semua item ketika penerbit yang relevan telah offline"}.
{"Queries to the conference members are not allowed in this room","Permintaan untuk para anggota konferensi tidak diperbolehkan di ruangan ini"}.
{"Query to another users is forbidden","Kueri ke pengguna lain dilarang"}.
{"RAM and disc copy","RAM dan disc salinan"}.
{"RAM copy","Salinan RAM"}.
{"Really delete message of the day?","Benar-benar ingin menghapus pesan harian?"}.
{"Receive notification from all descendent nodes","Terima notifikasi dari semua node turunan"}.
{"Receive notification from direct child nodes only","Terima notifikasi dari child node saja"}.
{"Receive notification of new items only","Terima notifikasi dari item baru saja"}.
{"Receive notification of new nodes only","Terima notifikasi dari node baru saja"}.
{"Recipient is not in the conference room","Penerima tidak berada di ruangan konferensi"}.
{"Register an XMPP account","Daftarkan sebuah akun XMPP"}.
{"Registered Users","Pengguna Terdaftar"}.
{"Registered Users:","Pengguna Terdaftar:"}.
{"Register","Mendaftar"}.
@@ -285,28 +330,39 @@
{"Remove User","Hapus Pengguna"}.
{"Remove","Menghapus"}.
{"Replaced by new connection","Diganti dengan koneksi baru"}.
{"Request has timed out","Waktu permintaan telah habis"}.
{"Request is ignored","Permintaan diabaikan"}.
{"Requested role","Peran yang diminta"}.
{"Resources","Sumber daya"}.
{"Restart Service","Restart Layanan"}.
{"Restart","Jalankan Ulang"}.
{"Restore Backup from File at ","Kembalikan Backup dari File pada"}.
{"Restore Backup from File at ","Kembalikan Backup dari File pada "}.
{"Restore binary backup after next ejabberd restart (requires less memory):","Mengembalikan cadangan yang berpasanagn setelah ejabberd berikutnya dijalankan ulang (memerlukan memori lebih sedikit):"}.
{"Restore binary backup immediately:","Segera mengembalikan cadangan yang berpasangan:"}.
{"Restore plain text backup immediately:","Segera mengembalikan cadangan teks biasa:"}.
{"Restore","Mengembalikan"}.
{"Roles that May Send Private Messages","Peran yang Dapat Mengirim Pesan Pribadi"}.
{"Room Configuration","Konfigurasi Ruangan"}.
{"Room creation is denied by service policy","Pembuatan Ruangan ditolak oleh kebijakan layanan"}.
{"Room description","Keterangan ruangan"}.
{"Room Occupants","Penghuni Ruangan"}.
{"Room terminates","Ruang dihentikan"}.
{"Room title","Nama Ruangan"}.
{"Roster groups allowed to subscribe","Kelompok kontak yang diizinkan untuk berlangganan"}.
{"Roster of ~ts","Daftar ~ts"}.
{"Roster size","Ukuran Daftar Kontak"}.
{"Roster:","Daftar:"}.
{"RPC Call Error","Panggilan Kesalahan RPC"}.
{"Running Nodes","Menjalankan Node"}.
{"~s invites you to the room ~s","~s mengundang anda masuk kamar ~s"}.
{"Saturday","Sabtu"}.
{"Script check","Periksa naskah"}.
{"Search Results for ","Hasil Pencarian untuk"}.
{"Search users in ","Pencarian pengguna dalam"}.
{"Search from the date","Cari dari tanggal"}.
{"Search Results for ","Hasil Pencarian untuk "}.
{"Search the text","Cari teks"}.
{"Search until the date","Cari sampai tanggal"}.
{"Search users in ","Pencarian pengguna dalam "}.
{"Select All","Pilih Semua"}.
{"Send announcement to all online users on all hosts","Kirim pengumuman untuk semua pengguna yang online pada semua host"}.
{"Send announcement to all online users","Kirim pengumuman untuk semua pengguna yang online"}.
{"Send announcement to all users on all hosts","Kirim pengumuman untuk semua pengguna pada semua host"}.
@@ -319,9 +375,11 @@
{"Show Integral Table","Tampilkan Tabel Terpisah"}.
{"Show Ordinary Table","Tampilkan Tabel Normal"}.
{"Shut Down Service","Shut Down Layanan"}.
{"SOCKS5 Bytestreams","SOCKS5 Bytestreams"}.
{"Specify the access model","Tentukan model akses"}.
{"Specify the event message type","Tentukan jenis acara pesan"}.
{"Specify the publisher model","Tentukan model penerbitan"}.
{"Stanza ID","ID Stanza"}.
{"Statistics of ~p","statistik dari ~p"}.
{"Statistics","Statistik"}.
{"Stop","Hentikan"}.
@@ -329,18 +387,35 @@
{"Storage Type","Jenis Penyimpanan"}.
{"Store binary backup:","Penyimpanan cadangan yang berpasangan:"}.
{"Store plain text backup:","Simpan cadangan teks biasa:"}.
{"Stream management is already enabled","Manajemen stream sudah diaktifkan"}.
{"Stream management is not enabled","Manajemen stream tidak diaktifkan"}.
{"Subject","Subyek"}.
{"Submit","Serahkan"}.
{"Submitted","Ulangi masukan"}.
{"Subscriber Address","Alamat Pertemanan"}.
{"Subscribers may publish","Pelanggan dapat mempublikasikan"}.
{"Subscription","Berlangganan"}.
{"Subscriptions are not allowed","Langganan tidak diperbolehkan"}.
{"Sunday","Minggu"}.
{"Text associated with a picture","Teks yang terkait dengan gambar"}.
{"Text associated with a sound","Teks yang terkait dengan suara"}.
{"Text associated with a video","Teks yang terkait dengan video"}.
{"Text associated with speech","Teks yang terkait dengan ucapan"}.
{"That nickname is already in use by another occupant","Julukan itu sudah digunakan oleh penghuni lain"}.
{"That nickname is registered by another person","Julukan tersebut telah didaftarkan oleh orang lain"}.
{"The account was not unregistered","Akun tidak terdaftar"}.
{"The CAPTCHA is valid.","Captcha ini benar."}.
{"The CAPTCHA verification has failed","Verifikasi CAPTCHA telah gagal"}.
{"The captcha you entered is wrong","Isian captcha yang anda masukkan salah"}.
{"The collections with which a node is affiliated","Koleksi dengan yang berafiliasi dengan sebuah node"}.
{"The JID of the node creator","JID dari pembuat node"}.
{"The JIDs of those to contact with questions","JID dari mereka untuk dihubungi dengan pertanyaan"}.
{"The JIDs of those with an affiliation of owner","JID dari mereka yang memiliki afiliasi pemilik"}.
{"The JIDs of those with an affiliation of publisher","JID dari mereka yang memiliki afiliasi penerbit"}.
{"The name of the node","Nama node"}.
{"The node is a collection node","Node adalah node koleksi"}.
{"The node is a leaf node (default)","Node adalah leaf node (default)"}.
{"The NodeID of the relevant node","NodeID dari node yang relevan"}.
{"The number of subscribers to the node","Jumlah pendaftar di node"}.
{"The number of unread or undelivered messages","Jumlah pesan yang belum dibaca atau tidak terkirim"}.
{"The password contains unacceptable characters","Kata sandi mengandung karakter yang tidak dapat diterima"}.
@@ -348,10 +423,12 @@
{"the password is","kata sandinya"}.
{"The password was not changed","Kata sandi belum berubah"}.
{"The passwords are different","Kata sandi berbeda"}.
{"The username is not valid","Nama pengguna tidak valid"}.
{"There was an error changing the password: ","Ada kesalahan saat merubah kata kunci: "}.
{"There was an error creating the account: ","Ada kesalahan saat membuat akun: "}.
{"There was an error deleting the account: ","Ada kesalahan saat menghapus akun:"}.
{"There was an error deleting the account: ","Ada kesalahan saat menghapus akun: "}.
{"This room is not anonymous","Ruangan ini tidak dikenal"}.
{"This service can not process the address: ~s","Layanan ini tidak dapat memproses alamat: ~s"}.
{"Thursday","Kamis"}.
{"Time delay","Waktu tunda"}.
{"Time","Waktu"}.
@@ -359,10 +436,13 @@
{"To ~ts","Kepada ~ts"}.
{"Token TTL","TTL Token"}.
{"To","Kepada"}.
{"Too many active bytestreams","Terlalu banyak bytestream aktif"}.
{"Too many CAPTCHA requests","Terlalu banyak permintaan CAPTCHA"}.
{"Too many child elements","Terlalu banyak elemen turunan"}.
{"Too many <item/> elements","Terlalu banyak <item/> elemen"}.
{"Too many <list/> elements","Terlalu banyak <list/> elemen"}.
{"Too many (~p) failed authentications from this IP address (~s). The address will be unblocked at ~s UTC","Terlalu banyak (~p) percobaan otentifikasi yang gagal dari alamat IP (~s). Alamat akan di unblok pada ~s UTC"}.
{"Too many receiver fields were specified","Terlalu banyak bidang penerima yang ditentukan"}.
{"Too many users in this conference","Terlalu banyak pengguna di grup ini"}.
{"Total rooms","Total kamar"}.
{"Traffic rate limit is exceeded","Batas tingkat lalu lintas terlampaui"}.
@@ -373,6 +453,7 @@
{"~ts's Offline Messages Queue","~ts's antrian Pesan Offline"}.
{"Tuesday","Selasa"}.
{"Unable to generate a CAPTCHA","Tidak dapat menghasilkan CAPTCHA"}.
{"Unable to register route on existing local domain","Tidak dapat mendaftarkan rute di domain lokal yang ada"}.
{"Unauthorized","Ditolak"}.
{"Unexpected action","Aksi yang tidak diharapkan"}.
{"Unexpected error condition: ~p","Kondisi kerusakan yang tidak diduga: ~p"}.
@@ -410,7 +491,7 @@
{"vCard User Search","vCard Pencarian Pengguna"}.
{"View Queue","Lihat antrian"}.
{"View Roster","Lihat daftar kontak"}.
{"Virtual Hosts","Virtual Hosts"}.
{"Virtual Hosts","Host Virtual"}.
{"Visitors are not allowed to change their nicknames in this room","Tamu tidak diperbolehkan untuk mengubah nama panggilan di ruangan ini"}.
{"Visitors are not allowed to send messages to all occupants","Tamu tidak diperbolehkan untuk mengirim pesan ke semua penghuni"}.
{"Visitor","Tamu"}.
@@ -424,11 +505,14 @@
{"Whether an entity wants to receive digests (aggregations) of notifications or all notifications individually","Apakah entitas ingin menerima ringkasan(agregasi) pemberitahuan atau semua pemberitahuan satu per satu"}.
{"Whether an entity wants to receive or disable notifications","Apakah entitas ingin menerima atau menonaktifkan pemberitahuan"}.
{"Whether owners or publisher should receive replies to items","Apakah pemilik atau penerbit harus menerima balasan dari item"}.
{"Whether the node is a leaf (default) or a collection","Apakah node adalah leaf (default) atau koleksi"}.
{"Whether to allow subscriptions","Apakah diperbolehkan untuk berlangganan"}.
{"Whether to make all subscriptions temporary, based on subscriber presence","Apakah akan menjadikan semua langganan sementara, berdasarkan keberadaan pelanggan"}.
{"Whether to notify owners about new subscribers and unsubscribes","Apakah akan memberi tahu pemilik tentang pelanggan baru dan berhenti berlangganan"}.
{"Who may associate leaf nodes with a collection","Siapa yang dapat mengaitkan leaf node dengan koleksi"}.
{"Wrong parameters in the web formulary","Parameter yang salah di formula web"}.
{"Wrong xmlns","xmlns salah"}.
{"XMPP Account Registration","Pendaftaran Akun XMPP"}.
{"XMPP Domains","Domain XMPP"}.
{"XMPP Show Value of Away","XMPP menunjukkan status Away"}.
{"XMPP Show Value of Chat","XMPP menunjukkan status Chat"}.
+6 -1
View File
@@ -1,4 +1,9 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," Riempire il modulo per la ricerca di utenti Jabber corrispondenti ai criteri (Aggiungere * alla fine del campo per la ricerca di una sottostringa"}.
{" has set the subject to: "," ha modificato l'oggetto in: "}.
{"A friendly name for the node","Un nome comodo per il nodo"}.
{"A password is required to enter this room","Per entrare in questa stanza è prevista una password"}.
+93 -3
View File
@@ -1,9 +1,18 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (* を最後に付けると部分文字列にマッチします)"}.
{" has set the subject to: "," は件名を設定しました: "}.
{"A description of the node","ノードの説明"}.
{"A friendly name for the node","ノードのフレンドリネーム"}.
{"A password is required to enter this room","このチャットルームに入るにはパスワードが必要です"}.
{"A Web Page","ウェブページ"}.
{"Accept","許可"}.
{"Access denied by service policy","サービスポリシーによってアクセスが禁止されました"}.
{"Access model","アクセスモデル"}.
{"Account doesn't exist","アカウントは存在しません"}.
{"Action on user","ユーザー操作"}.
{"Add Jabber ID","Jabber ID を追加"}.
{"Add New","新規追加"}.
@@ -13,6 +22,7 @@
{"Administrator privileges required","管理者権限が必要です"}.
{"All activity","すべて"}.
{"All Users","全ユーザー"}.
{"Allow subscription","購読を認可"}.
{"Allow this Jabber ID to subscribe to this pubsub node?","この Jabber ID に、この pubsubノードの購読を許可しますか ?"}.
{"Allow users to change the subject","ユーザーによる件名の変更を許可"}.
{"Allow users to query other users","ユーザーによる他のユーザーへのクエリーを許可"}.
@@ -23,6 +33,7 @@
{"Allow visitors to send status text in presence updates","傍聴者によるプレゼンス更新のステータス文の送信を許可"}.
{"Allow visitors to send voice requests","傍聴者による発言権の要求を許可"}.
{"Announcements","アナウンス"}.
{"Anyone","誰にでも"}.
{"April","4月"}.
{"August","8月"}.
{"Backup Management","バックアップ管理"}.
@@ -31,9 +42,14 @@
{"Backup","バックアップ"}.
{"Bad format","不正なフォーマット"}.
{"Birthday","誕生日"}.
{"Both the username and the resource are required","ユーザー名とリソースの両方が必要"}.
{"CAPTCHA web page","CAPTCHA ウェブページ"}.
{"Change Password","パスワードを変更"}.
{"Change User Password","パスワードを変更"}.
{"Changing password is not allowed","パスワード変更の権限がありません"}.
{"Channel already exists","チャンネルは既に存在します"}.
{"Channel does not exist","チャンネルは存在しません"}.
{"Channels","チャンネル"}.
{"Characters not allowed:","使用できない文字:"}.
{"Chatroom configuration modified","チャットルームの設定が変更されました"}.
{"Chatroom is created","チャットルームを作りました"}.
@@ -50,33 +66,42 @@
{"Configuration of room ~s","チャットルーム ~s の設定"}.
{"Configuration","設定"}.
{"Connected Resources:","接続リソース:"}.
{"Contact Addresses (normally, room owner or owners)","連絡先 (通常は会議室の主宰者またはその複数)"}.
{"Country","国"}.
{"CPU Time:","CPU時間:"}.
{"Current Discussion Topic","現在の話題"}.
{"Database Tables at ~p","データーベーステーブル: ~p"}.
{"Database Tables Configuration at ","データーベーステーブル設定 "}.
{"Database","データーベース"}.
{"December","12月"}.
{"Default users as participants","デフォルトのユーザーは参加者"}.
{"Delete content","内容を削除"}.
{"Delete message of the day on all hosts","全ホストのお知らせメッセージを削除"}.
{"Delete message of the day","お知らせメッセージを削除"}.
{"Delete Selected","選択した項目を削除"}.
{"Delete table","テーブルを削除"}.
{"Delete User","ユーザーを削除"}.
{"Deliver event notifications","イベント通知を配送する"}.
{"Deliver payloads with event notifications","イベント通知と同時にペイロードを配送する"}.
{"Description:","説明:"}.
{"Disc only copy","ディスクだけのコピー"}.
{"Don't tell your password to anybody, not even the administrators of the XMPP server.","パスワードは誰にも(たとえ XMPP サーバーの管理者でも)教えないようにしてください。"}.
{"Dump Backup to Text File at ","テキストファイルにバックアップ: "}.
{"Dump to Text File","テキストファイルに出力"}.
{"Duplicated groups are not allowed by RFC6121","RFC6121 によりグループの重複は許されません"}.
{"Edit Properties","プロパティを編集"}.
{"Either approve or decline the voice request.","発言権の要求を承認または却下します。"}.
{"ejabberd HTTP Upload service","ejabberd HTTP ファイルアップロード"}.
{"ejabberd MUC module","ejabberd MUCモジュール"}.
{"ejabberd Multicast service","ejabberdマルチキャストサービス"}.
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe モジュール"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams モジュール"}.
{"ejabberd vCard module","ejabberd vCard モジュール"}.
{"ejabberd Web Admin","ejabberd ウェブ管理"}.
{"ejabberd","ejabberd"}.
{"Elements","要素"}.
{"Email","メールアドレス"}.
{"Email Address","メールアドレス"}.
{"Email","メール"}.
{"Enable logging","ロギングを有効"}.
{"Enable message archiving","メッセージアーカイブを有効化"}.
{"End User Session","エンドユーザーセッション"}.
@@ -86,29 +111,40 @@
{"Enter path to jabberd14 spool file","jabberd14 spool ファイルのパスを入力してください"}.
{"Enter path to text file","テキストファイルのパスを入力してください"}.
{"Enter the text you see","見えているテキストを入力してください"}.
{"Erlang XMPP Server","Erlang XMPP サーバー"}.
{"Error","エラー"}.
{"Exclude Jabber IDs from CAPTCHA challenge","CAPTCHA 入力を免除する Jabber ID"}.
{"Export all tables as SQL queries to a file:","すべてのテーブルをSQL形式でファイルにエクスポート: "}.
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","サーバーにあるすべてのユーザーデータを PIEFXIS ファイルにエクスポート (XEP-0227):"}.
{"Export data of users in a host to PIEFXIS files (XEP-0227):","ホストのユーザーデータを PIEFXIS ファイルにエクスポート (XEP-0227):"}.
{"Failed to extract JID from your voice request approval","発言権要求の承認から JID を取り出すことに失敗しました"}.
{"Failed to parse HTTP response","HTTP 応答のパースに失敗しました"}.
{"Family Name","姓"}.
{"February","2月"}.
{"Fill in the form to search for any matching XMPP User","XMPP ユーザーを検索するには欄に入力してください"}.
{"Friday","金曜日"}.
{"From ~ts","From ~ts"}.
{"From","差出人"}.
{"Full List of Room Admins","チャットルーム管理者の一覧"}.
{"Full List of Room Owners","チャットルーム主宰者の一覧"}.
{"Full Name","氏名"}.
{"Get Number of Online Users","オンラインユーザー数を取得"}.
{"Get Number of Registered Users","登録ユーザー数を取得"}.
{"Get User Last Login Time","最終ログイン時間を取得"}.
{"Get User Password","パスワードを取得"}.
{"Get User Statistics","ユーザー統計を取得"}.
{"Given Name","名"}.
{"Grant voice to this person?","この人に発言権を与えますか ?"}.
{"Groups","グループ"}.
{"Group","グループ"}.
{"has been banned","はバンされました"}.
{"has been kicked because of a system shutdown","はシステムシャットダウンのためキックされました"}.
{"has been kicked because of an affiliation change","は分掌が変更されたためキックされました"}.
{"has been kicked because the room has been changed to members-only","はチャットルームがメンバー制に変更されたためキックされました"}.
{"has been kicked","はキックされました"}.
{"Host unknown","不明なホスト"}.
{"Host","ホスト"}.
{"HTTP File Upload","HTTP ファイルアップロード"}.
{"If you don't see the CAPTCHA image here, visit the web page.","ここに CAPTCHA 画像が表示されない場合、ウェブページを参照してください。"}.
{"Import Directory","ディレクトリインポート"}.
{"Import File","ファイルからインポート"}.
@@ -120,7 +156,11 @@
{"Import Users From jabberd14 Spool Files","jabberd14 Spool ファイルからユーザーをインポート"}.
{"Improper message type","誤ったメッセージタイプです"}.
{"Incoming s2s Connections:","内向き s2s コネクション:"}.
{"Incorrect data form","データ形式が違います"}.
{"Incorrect password","パスワードが違います"}.
{"Internal server error","内部サーバーエラー"}.
{"Invalid node name","無効なノード名です"}.
{"Invitations are not allowed in this conference","この会議では、招待はできません"}.
{"IP addresses","IP アドレス"}.
{"is now known as","は名前を変更しました: "}.
{"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","このルームにエラーメッセージを送ることは許可されていません。参加者(~s)はエラーメッセージを(~s)を送信してルームからキックされました。"}.
@@ -132,8 +172,11 @@
{"joins the room","がチャットルームに参加しました"}.
{"July","7月"}.
{"June","6月"}.
{"Just created","作成しました"}.
{"Label:","ラベル:"}.
{"Last Activity","活動履歴"}.
{"Last login","最終ログイン"}.
{"Last message","最終メッセージ"}.
{"Last month","先月"}.
{"Last year","去年"}.
{"leaves the room","がチャットルームから退出しました"}.
@@ -146,13 +189,16 @@
{"Make room password protected","チャットルームをパスワードで保護"}.
{"Make room persistent","チャットルームを永続化"}.
{"Make room public searchable","チャットルームを検索可"}.
{"Malformed username","不正な形式のユーザー名"}.
{"March","3月"}.
{"Max # of items to persist","アイテムの最大保存数"}.
{"Max payload size in bytes","最大ぺイロードサイズ (byte)"}.
{"Maximum file size","最大ファイルサイズ"}.
{"Maximum Number of Occupants","最大在室者数"}.
{"May","5月"}.
{"Membership is required to enter this room","このチャットルームに入るにはメンバーでなければなりません"}.
{"Members:","メンバー:"}.
{"Memorize your password, or write it in a paper placed in a safe place. In XMPP there isn't an automated way to recover your password if you forget it.","パスワードは記憶するか、紙に書いて安全な場所に保管してください。もしあなたがパスワードを忘れてしまった場合、XMPP ではパスワードのリカバリを自動的に行うことはできません。"}.
{"Memory","メモリ"}.
{"Message body","本文"}.
{"Middle Name","ミドルネーム"}.
@@ -165,14 +211,17 @@
{"Multi-User Chat","マルチユーザーチャット"}.
{"Name","名"}.
{"Name:","名前:"}.
{"Natural-Language Room Name","自然言語での会議室名"}.
{"Never","なし"}.
{"New Password:","新しいパスワード:"}.
{"Nickname can't be empty","ニックネームは空にできません"}.
{"Nickname Registration at ","ニックネーム登録: "}.
{"Nickname ~s does not exist in the room","ニックネーム ~s はこのチャットルームにいません"}.
{"Nickname","ニックネーム"}.
{"No body provided for announce message","アナウンスメッセージはありませんでした"}.
{"No Data","データなし"}.
{"No limit","制限なし"}.
{"Node already exists","ノードは既に存在しています"}.
{"Node ID","ノードID"}.
{"Node not found","ノードが見つかりません"}.
{"Node ~p","ノード ~p"}.
@@ -184,8 +233,11 @@
{"Notify subscribers when the node is deleted","ノードが削除された時に購読者へ通知する"}.
{"November","11月"}.
{"Number of occupants","在室者の数"}.
{"Number of Offline Messages","オフラインメッセージ数"}.
{"Number of online users","オンラインユーザー数"}.
{"Number of registered users","登録ユーザー数"}.
{"Occupants are allowed to invite others","在室者は誰かを招待することができます"}.
{"Occupants May Change the Subject","ユーザーによる件名の変更を許可"}.
{"October","10月"}.
{"Offline Messages","オフラインメッセージ"}.
{"Offline Messages:","オフラインメッセージ:"}.
@@ -218,6 +270,7 @@
{"Pending","保留"}.
{"Period: ","期間: "}.
{"Persist items to storage","アイテムをストレージに保存する"}.
{"Persistent","チャットルームを永続化"}.
{"Ping","Ping"}.
{"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","これらのオプションは組み込みの Mnesia データーベースのバックアップのみを行うことに注意してください。もし ODBC モジュールを使用している場合は、SQL データーベースのバックアップを別に行う必要があります。"}.
{"Please, wait for a while before sending new voice request","新しい発言権の要求を送るまで少し間をおいてください"}.
@@ -232,6 +285,7 @@
{"RAM copy","RAM コピー"}.
{"Really delete message of the day?","本当にお知らせメッセージを削除しますか ?"}.
{"Recipient is not in the conference room","受信者はこの会議室にいません"}.
{"Register an XMPP account","XMPP アカウントを登録"}.
{"Registered Users","登録ユーザー"}.
{"Registered Users:","登録ユーザー:"}.
{"Register","登録"}.
@@ -255,13 +309,17 @@
{"Room Occupants","在室者"}.
{"Room title","チャットルームのタイトル"}.
{"Roster groups allowed to subscribe","名簿グループは購読を許可しました"}.
{"Roster of ~ts","~ts の名簿"}.
{"Roster size","名簿サイズ"}.
{"Roster:","名簿:"}.
{"RPC Call Error","RPC 呼び出しエラー"}.
{"Running Nodes","起動ノード"}.
{"~s invites you to the room ~s","~s はあなたをチャットルーム ~s に招待しています"}.
{"Saturday","土曜日"}.
{"Script check","スクリプトチェック"}.
{"Search Results for ","検索結果: "}.
{"Search users in ","ユーザーの検索: "}.
{"Select All","すべて選択"}.
{"Send announcement to all online users on all hosts","全ホストのオンラインユーザーにアナウンスを送信"}.
{"Send announcement to all online users","すべてのオンラインユーザーにアナウンスを送信"}.
{"Send announcement to all users on all hosts","全ホストのユーザーにアナウンスを送信"}.
@@ -274,9 +332,11 @@
{"Show Integral Table","累積の表を表示"}.
{"Show Ordinary Table","通常の表を表示"}.
{"Shut Down Service","サービスを停止"}.
{"Some XMPP clients can store your password in the computer, but you should do this only in your personal computer for safety reasons.","XMPP クライアントはコンピューターにパスワードを記憶できます。コンピューターが安全であると信頼できる場合にのみ、この機能を使用してください。"}.
{"Specify the access model","アクセスモデルを設定する"}.
{"Specify the event message type","イベントメッセージ種別を設定"}.
{"Specify the publisher model","公開モデルを指定する"}.
{"Stanza ID","スタンザ ID"}.
{"Statistics of ~p","~p の統計"}.
{"Statistics","統計"}.
{"Stopped Nodes","停止ノード"}.
@@ -292,13 +352,27 @@
{"Sunday","日曜日"}.
{"That nickname is already in use by another occupant","そのニックネームは既にほかの在室者によって使用されています"}.
{"That nickname is registered by another person","ニックネームはほかの人によって登録されています"}.
{"The account already exists","アカウントは既に存在しています"}.
{"The account was not unregistered","アカウントは削除されませんでした"}.
{"The CAPTCHA is valid.","CAPTCHA は有効です。"}.
{"The CAPTCHA verification has failed","CAPTCHA 検証は失敗しました"}.
{"The captcha you entered is wrong","入力した CAPTCHA は間違っています"}.
{"The collections with which a node is affiliated","提携されたノードの集合です"}.
{"The default language of the node","ノードのデフォルトの言語"}.
{"The JID of the node creator","ノード作成者の JID"}.
{"The name of the node","ノード名"}.
{"The password contains unacceptable characters","パスワードに使用できない文字が含まれています"}.
{"The password is too weak","このパスワードは単純過ぎます"}.
{"the password is","パスワードは"}.
{"The password of your XMPP account was successfully changed.","XMPP アカウントのパスワード変更に成功しました。"}.
{"The password was not changed","このパスワードは変更されませんでした"}.
{"The passwords are different","このパスワードが違います"}.
{"The username is not valid","ユーザー名が正しくありません"}.
{"There was an error creating the account: ","アカウントの作成中にエラーが発生しました: "}.
{"There was an error deleting the account: ","アカウントの削除中にエラーが発生しました: "}.
{"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","大文字と小文字は区別しません: macbeth は MacBeth や Macbeth と同じです。"}.
{"This page allows to register an XMPP account in this XMPP server. Your JID (Jabber ID) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","ここはこの XMPP サーバーにアカウントを作成するページです。あなたの JID (JabberID) は username@server のような形式になります。注意事項どおり、正しく項目を記入してください。"}.
{"This page allows to unregister an XMPP account in this XMPP server.","このページはサーバー上のXMPPアカウントを削除するページです。"}.
{"This room is not anonymous","このチャットルームは非匿名です"}.
{"Thursday","木曜日"}.
{"Time delay","遅延時間"}.
@@ -313,10 +387,13 @@
{"Transactions Committed:","トランザクションのコミット:"}.
{"Transactions Logged:","トランザクションのログ: "}.
{"Transactions Restarted:","トランザクションの再起動:"}.
{"~ts's Offline Messages Queue","~ts のオフラインメッセージキュー"}.
{"Tuesday","火曜日"}.
{"Unable to generate a CAPTCHA","CAPTCHA を生成できません"}.
{"Unauthorized","認証されていません"}.
{"Unregister an XMPP account","XMPP アカウントを削除"}.
{"Unregister","削除"}.
{"Unsupported version","対応していないバージョン"}.
{"Update message of the day (don't send)","お知らせメッセージを更新 (送信しない)"}.
{"Update message of the day on all hosts (don't send)","全ホストのお知らせメッセージを更新 (送信しない)"}.
{"Update plan","更新計画"}.
@@ -324,8 +401,12 @@
{"Update script","スクリプトの更新"}.
{"Update","更新"}.
{"Uptime:","起動時間:"}.
{"User already exists","ユーザーは既に存在しています"}.
{"User (jid)","ユーザー (JID)"}.
{"User JID","ユーザー JID"}.
{"User Management","ユーザー管理"}.
{"User removed","ユーザーを削除しました"}.
{"User ~ts","ユーザー ~ts"}.
{"Username:","ユーザー名:"}.
{"Users are not allowed to register accounts so quickly","それほど速くアカウントを登録することはできません"}.
{"Users Last Activity","ユーザーの活動履歴"}.
@@ -333,6 +414,8 @@
{"User","ユーザー"}.
{"Validate","検証"}.
{"vCard User Search","vCard検索"}.
{"View Queue","キューを表示"}.
{"View Roster","名簿を表示"}.
{"Virtual Hosts","バーチャルホスト"}.
{"Visitors are not allowed to change their nicknames in this room","傍聴者はこのチャットルームでニックネームを変更することはできません"}.
{"Visitors are not allowed to send messages to all occupants","傍聴者はすべての在室者にメッセージを送信することはできません"}.
@@ -342,7 +425,11 @@
{"Wednesday","水曜日"}.
{"When to send the last published item","最後の公開アイテムを送信するタイミングで"}.
{"Whether to allow subscriptions","購読を許可するかどうか"}.
{"You have been banned from this room","あなたはこのチャットルームからバンされています"}.
{"XMPP Account Registration","XMPP アカウント登録"}.
{"XMPP Domains","XMPP ドメイン"}.
{"You are being removed from the room because of a system shutdown","システムシャットダウンのためチャットルームから削除されました"}.
{"You can later change your password using an XMPP client.","あなたは後で XMPP クライアントを使用してパスワードを変更できます。"}.
{"You have been banned from this room","あなたはこのチャットルームから締め出されています"}.
{"You must fill in field \"Nickname\" in the form","フォームの\"ニックネーム\"欄を入力する必要があります"}.
{"You need a client that supports x:data and CAPTCHA to register","登録を行うには x:data と CAPTCHA をサポートするクライアントが必要です"}.
{"You need a client that supports x:data to register the nickname","ニックネームを登録するには x:data をサポートするクライアントが必要です"}.
@@ -350,3 +437,6 @@
{"Your active privacy list has denied the routing of this stanza.","あなたのプライバシーリストはこのスタンザのルーティングを拒否しました。"}.
{"Your contact offline message queue is full. The message has been discarded.","相手先のオフラインメッセージキューが一杯です。このメッセージは破棄されます。"}.
{"Your subscription request and/or messages to ~s have been blocked. To unblock your subscription request, visit ~s","~s 宛のメッセージはブロックされています。解除するにはこちらを見てください ~s"}.
{"Your XMPP account was successfully registered.","XMPP アカウントの登録に成功しました。"}.
{"Your XMPP account was successfully unregistered.","XMPP アカウントの削除に成功しました。"}.
{"You're not allowed to create nodes","ノードを作成する権限がありません"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," veranderde het onderwerp in: "}.
{"A friendly name for the node","Bijnaam voor deze knoop"}.
{"A password is required to enter this room","U hebt een wachtwoord nodig om deze chatruimte te kunnen betreden"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," har satt emnet til: "}.
{"A friendly name for the node","Et vennlig navn for noden"}.
{"A password is required to enter this room","Et passord kreves for tilgang til samtalerommet"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," zmienił temat na: "}.
{"A friendly name for the node","Przyjazna nazwa węzła"}.
{"A password is required to enter this room","Aby wejść do pokoju wymagane jest hasło"}.
+6 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (Adicione * no final do campo para combinar com a substring)"}.
{" has set the subject to: "," mudou o assunto para: "}.
{"# participants","# participantes"}.
@@ -320,6 +324,7 @@
{"Node index not found","O índice do nó não foi encontrado"}.
{"Node not found","Nó não encontrado"}.
{"Node ~p","Nó ~p"}.
{"Node","Nó"}.
{"Nodeprep has failed","Processo de identificação de nó falhou (nodeprep)"}.
{"Nodes","Nós"}.
{"None","Nenhum"}.
+565 -2
View File
@@ -1,101 +1,664 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (Adicione * no final do campo para combinar com a substring)"}.
{" has set the subject to: "," colocou o tópico: "}.
{"# participants","# participantes"}.
{"A description of the node","Uma descrição do nó"}.
{"A friendly name for the node","Um nome familiar para o nó"}.
{"A password is required to enter this room","Se necessita palavra-passe para entrar nesta sala"}.
{"A Web Page","Uma página da web"}.
{"Accept","Aceito"}.
{"Access denied by service policy","Acesso negado pela política de serviço"}.
{"Access model of authorize","Modelo de acesso da autorização"}.
{"Access model of open","Modelo para acesso aberto"}.
{"Access model of presence","Modelo para acesso presença"}.
{"Access model of roster","Modelo para acesso lista"}.
{"Access model of whitelist","Modelo de acesso da lista branca"}.
{"Access model","Modelo de acesso"}.
{"Account doesn't exist","A conta não existe"}.
{"Action on user","Acção no utilizador"}.
{"Add Jabber ID","Adicionar ID jabber"}.
{"Add New","Adicionar novo"}.
{"Add User","Adicionar utilizador"}.
{"Administration of ","Administração de "}.
{"Administration","Administração"}.
{"Administrator privileges required","São necessários privilégios de administrador"}.
{"All activity","Todas atividades"}.
{"All Users","Todos os utilizadores"}.
{"Allow subscription","Permitir a assinatura"}.
{"Allow this Jabber ID to subscribe to this pubsub node?","Autorizar este Jabber ID para a inscrição neste tópico pubsub?"}.
{"Allow this person to register with the room?","Permita que esta pessoa se registe na sala?"}.
{"Allow users to change the subject","Permitir a utilizadores modificar o assunto"}.
{"Allow users to query other users","Permitir a utilizadores pesquisar informações sobre os demais"}.
{"Allow users to send invites","Permitir a utilizadores envio de convites"}.
{"Allow users to send private messages","Permitir a utilizadores enviarem mensagens privadas"}.
{"Allow visitors to change nickname","Permitir mudança de apelido aos visitantes"}.
{"Allow visitors to send private messages to","Permitir visitantes enviar mensagem privada para"}.
{"Allow visitors to send status text in presence updates","Permitir atualizações de estado aos visitantes"}.
{"Allow visitors to send voice requests","Permitir aos visitantes o envio de requisições de voz"}.
{"An associated LDAP group that defines room membership; this should be an LDAP Distinguished Name according to an implementation-specific or deployment-specific definition of a group.","Um grupo LDAP associado que define a adesão à sala; este deve ser um Nome Distinto LDAP de acordo com uma definição específica da implementação ou da implantação específica de um grupo."}.
{"Announcements","Anúncios"}.
{"Answer associated with a picture","Resposta associada com uma foto"}.
{"Answer associated with a video","Resposta associada com um vídeo"}.
{"Answer associated with speech","Resposta associada com a fala"}.
{"Answer to a question","Resposta para uma pergunta"}.
{"Anyone in the specified roster group(s) may subscribe and retrieve items","Qualquer pessoa do(s) grupo(s) informado(s) podem se inscrever e recuperar itens"}.
{"Anyone may associate leaf nodes with the collection","Qualquer pessoa pode associar nós das páginas à coleção"}.
{"Anyone may publish","Qualquer pessoa pode publicar"}.
{"Anyone may subscribe and retrieve items","Qualquer pessoa pode se inscrever e recuperar os itens"}.
{"Anyone with a presence subscription of both or from may subscribe and retrieve items","Qualquer pessoa com uma assinatura presente dos dois ou de ambos pode se inscrever e recuperar os itens"}.
{"Anyone with Voice","Qualquer pessoa com voz"}.
{"Anyone","Qualquer pessoa"}.
{"April","Abril"}.
{"Attribute 'channel' is required for this request","O atributo 'canal' é necessário para esta solicitação"}.
{"Attribute 'id' is mandatory for MIX messages","O atributo 'id' é obrigatório para mensagens MIX"}.
{"Attribute 'jid' is not allowed here","O atributo 'jid' não é permitido aqui"}.
{"Attribute 'node' is not allowed here","O Atributo 'nó' não é permitido aqui"}.
{"Attribute 'to' of stanza that triggered challenge","O atributo 'para' da estrofe que desencadeou o desafio"}.
{"August","Agosto"}.
{"Automatic node creation is not enabled","Criação automatizada de nós está desativada"}.
{"Backup Management","Gestão de cópias de segurança"}.
{"Backup of ~p","Backup de ~p"}.
{"Backup to File at ","Guardar cópia de segurança para ficheiro em "}.
{"Backup","Guardar cópia de segurança"}.
{"Bad format","Formato incorreto"}.
{"Birthday","Data de nascimento"}.
{"Both the username and the resource are required","Nome de utilizador e recurso são necessários"}.
{"Bytestream already activated","Bytestream já foi ativado"}.
{"Cannot remove active list","Não é possível remover uma lista ativa"}.
{"Cannot remove default list","Não é possível remover uma lista padrão"}.
{"CAPTCHA web page","CAPTCHA web page"}.
{"Challenge ID","ID do desafio"}.
{"Change Password","Mudar palavra-chave"}.
{"Change User Password","Alterar Palavra-passe do Utilizador"}.
{"Changing password is not allowed","Não é permitida a alteração da palavra-passe"}.
{"Changing role/affiliation is not allowed","Não é permitida a alteração da função/afiliação"}.
{"Channel already exists","O canal já existe"}.
{"Channel does not exist","O canal não existe"}.
{"Channels","Canais"}.
{"Characters not allowed:","Caracteres não aceitos:"}.
{"Chatroom configuration modified","Configuração da sala de bate-papo modificada"}.
{"Chatroom is created","A sala de chat está criada"}.
{"Chatroom is destroyed","A sala de chat está destruída"}.
{"Chatroom is started","A sala de chat está iniciada"}.
{"Chatroom is stopped","A sala de chat está parada"}.
{"Chatrooms","Salas de Chat"}.
{"Choose a username and password to register with this server","Escolha um nome de utilizador e palavra-chave para se registar neste servidor"}.
{"Choose storage type of tables","Seleccione o tipo de armazenagem das tabelas"}.
{"Choose whether to approve this entity's subscription.","Aprovar esta assinatura."}.
{"City","Cidade"}.
{"Client acknowledged more stanzas than sent by server","O cliente reconheceu mais estrofes do que as enviadas pelo servidor"}.
{"Commands","Comandos"}.
{"Conference room does not exist","A sala não existe"}.
{"Configuration of room ~s","Configuração para ~s"}.
{"Configuration","Configuração"}.
{"Connected Resources:","Recursos conectados:"}.
{"Contact Addresses (normally, room owner or owners)","Endereços de contato (normalmente, o proprietário ou os proprietários da sala)"}.
{"Country","País"}.
{"CPU Time:","Tempo da CPU:"}.
{"Current Discussion Topic","Assunto em discussão"}.
{"Database failure","Falha no banco de dados"}.
{"Database Tables at ~p","Tabelas da Base de dados em ~p"}.
{"Database Tables Configuration at ","Configuração de Tabelas de Base de dados em "}.
{"Database","Base de dados"}.
{"December","Dezembro"}.
{"Default users as participants","Utilizadores padrões como participantes"}.
{"Delete content","Apagar o conteúdo"}.
{"Delete message of the day on all hosts","Apagar a mensagem do dia em todos os hosts"}.
{"Delete message of the day","Apagar mensagem do dia"}.
{"Delete Selected","Eliminar os seleccionados"}.
{"Delete table","Apagar a tabela"}.
{"Delete User","Deletar Utilizador"}.
{"Deliver event notifications","Entregar as notificações de evento"}.
{"Deliver payloads with event notifications","Enviar payloads junto com as notificações de eventos"}.
{"Description:","Descrição:"}.
{"Disc only copy","Cópia apenas em disco"}.
{"'Displayed groups' not added (they do not exist!): ","Os 'Grupos exibidos' não foi adicionado (eles não existem!): "}.
{"Displayed:","Exibido:"}.
{"Don't tell your password to anybody, not even the administrators of the XMPP server.","Não revele a sua palavra-passe a ninguém, nem mesmo para o administrador deste servidor XMPP."}.
{"Dump Backup to Text File at ","Exporta cópia de segurança para ficheiro de texto em "}.
{"Dump to Text File","Exportar para ficheiro de texto"}.
{"Duplicated groups are not allowed by RFC6121","Os grupos duplicados não são permitidos pela RFC6121"}.
{"Dynamically specify a replyto of the item publisher","Definir de forma dinâmica uma resposta da editora do item"}.
{"Edit Properties","Editar propriedades"}.
{"Either approve or decline the voice request.","Deve aprovar/desaprovar a requisição de voz."}.
{"ejabberd HTTP Upload service","serviço HTTP de upload ejabberd"}.
{"ejabberd MUC module","Módulo MUC de ejabberd"}.
{"ejabberd Multicast service","Serviço multicast ejabberd"}.
{"ejabberd Publish-Subscribe module","Módulo para Publicar Tópicos do ejabberd"}.
{"ejabberd SOCKS5 Bytestreams module","Modulo ejabberd SOCKS5 Bytestreams"}.
{"ejabberd vCard module","Módulo vCard de ejabberd"}.
{"ejabberd Web Admin","ejabberd Web Admin"}.
{"ejabberd","ejabberd"}.
{"Elements","Elementos"}.
{"Email Address","Endereço de e-mail"}.
{"Email","Email"}.
{"Enable logging","Permitir criação de logs"}.
{"Enable message archiving","Ativar arquivamento de mensagens"}.
{"Enabling push without 'node' attribute is not supported","Abilitar push sem o atributo 'node' não é suportado"}.
{"End User Session","Terminar Sessão do Utilizador"}.
{"Enter nickname you want to register","Introduza a alcunha que quer registar"}.
{"Enter path to backup file","Introduza o caminho do ficheiro de cópia de segurança"}.
{"Enter path to jabberd14 spool dir","Introduza o caminho para o directório de spools do jabberd14"}.
{"Enter path to jabberd14 spool file","Introduza o caminho para o ficheiro de spool do jabberd14"}.
{"Enter path to text file","Introduza caminho para o ficheiro de texto"}.
{"Enter the text you see","Insira o texto que vê"}.
{"Erlang XMPP Server","Servidor XMPP Erlang"}.
{"Error","Erro"}.
{"Exclude Jabber IDs from CAPTCHA challenge","Excluir IDs Jabber de serem submetidos ao CAPTCHA"}.
{"Export all tables as SQL queries to a file:","Exportar todas as tabelas como SQL para um ficheiro:"}.
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportar todos os dados de todos os utilizadores no servidor, para ficheiros de formato PIEFXIS (XEP-0227):"}.
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportar dados dos utilizadores num host, para ficheiros de PIEFXIS (XEP-0227):"}.
{"External component failure","Falha de componente externo"}.
{"External component timeout","Tempo esgotado à espera de componente externo"}.
{"Failed to activate bytestream","Falha ao ativar bytestream"}.
{"Failed to extract JID from your voice request approval","Não foi possível extrair o JID (Jabber ID) da requisição de voz"}.
{"Failed to map delegated namespace to external component","Falha ao mapear namespace delegado ao componente externo"}.
{"Failed to parse HTTP response","Falha ao analisar resposta HTTP"}.
{"Failed to process option '~s'","Falha ao processar opção '~s'"}.
{"Family Name","Apelido"}.
{"FAQ Entry","Registo das perguntas frequentes"}.
{"February","Fevereiro"}.
{"File larger than ~w bytes","Ficheiro é maior que ~w bytes"}.
{"Fill in the form to search for any matching XMPP User","Preencha campos para procurar por quaisquer utilizadores XMPP"}.
{"Friday","Sexta"}.
{"From ~ts","De ~s"}.
{"From","De"}.
{"Full List of Room Admins","Lista completa dos administradores das salas"}.
{"Full List of Room Owners","Lista completa dos proprietários das salas"}.
{"Full Name","Nome completo"}.
{"Get Number of Online Users","Obter quantidade de utilizadores online"}.
{"Get Number of Registered Users","Obter quantidade de utilizadores registados"}.
{"Get Pending","Obter os pendentes"}.
{"Get User Last Login Time","Obter a data do último login"}.
{"Get User Password","Obter palavra-passe do utilizador"}.
{"Get User Statistics","Obter estatísticas do utilizador"}.
{"Given Name","Sobrenome"}.
{"Grant voice to this person?","Dar voz a esta pessoa?"}.
{"Group","Grupo"}.
{"Groups that will be displayed to the members","Os grupos que serão exibidos para os membros"}.
{"Groups","Grupos"}.
{"has been banned","foi banido"}.
{"has been kicked because of a system shutdown","foi desconectado porque o sistema foi desligado"}.
{"has been kicked because of an affiliation change","foi desconectado porque por afiliação inválida"}.
{"has been kicked because the room has been changed to members-only","foi desconectado porque a política da sala mudou, só membros são permitidos"}.
{"has been kicked","foi removido"}.
{"Host unknown","Máquina desconhecida"}.
{"Host","Máquina"}.
{"HTTP File Upload","Upload de ficheiros por HTTP"}.
{"Idle connection","Conexão inativa"}.
{"If you don't see the CAPTCHA image here, visit the web page.","Se não conseguir ver o CAPTCHA aqui, visite a web page."}.
{"Import Directory","Importar directório"}.
{"Import File","Importar ficheiro"}.
{"Import user data from jabberd14 spool file:","Importar dados dos utilizadores de uma fila jabberd14:"}.
{"Import User from File at ","Importar utilizador a partir do ficheiro em "}.
{"Import users data from a PIEFXIS file (XEP-0227):","Importe os utilizadores de um ficheiro PIEFXIS (XEP-0227):"}.
{"Import users data from jabberd14 spool directory:","Importar dados dos utilizadores de um diretório-fila jabberd14:"}.
{"Import Users from Dir at ","Importar utilizadores a partir do directório em "}.
{"Import Users From jabberd14 Spool Files","Importar utilizadores de ficheiros de jabberd14 (spool files)"}.
{"Improper domain part of 'from' attribute","Atributo 'from' contém domínio incorreto"}.
{"Improper message type","Tipo de mensagem incorrecto"}.
{"Incoming s2s Connections:","Conexões s2s de Entrada:"}.
{"Incorrect CAPTCHA submit","CAPTCHA submetido incorretamente"}.
{"Incorrect data form","Formulário dos dados incorreto"}.
{"Incorrect password","Palavra-chave incorrecta"}.
{"Incorrect value of 'action' attribute","Valor incorreto do atributo 'action'"}.
{"Incorrect value of 'action' in data form","Valor incorreto de 'action' no formulário de dados"}.
{"Incorrect value of 'path' in data form","Valor incorreto de 'path' no formulário de dados"}.
{"Insufficient privilege","Privilégio insuficiente"}.
{"Internal server error","Erro interno do servidor"}.
{"Invalid 'from' attribute in forwarded message","Atributo 'from' inválido na mensagem reenviada"}.
{"Invalid node name","Nome do nó inválido"}.
{"Invalid 'previd' value","Valor 'previd' inválido"}.
{"Invitations are not allowed in this conference","Os convites não são permitidos nesta conferência"}.
{"IP addresses","Endereços IP"}.
{"is now known as","é agora conhecido como"}.
{"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","Não é permitido o envio de mensagens de erro para a sala. O membro (~s) enviou uma mensagem de erro (~s) e foi expulso da sala"}.
{"It is not allowed to send private messages of type \"groupchat\"","Não é permitido enviar mensagens privadas do tipo \"groupchat\""}.
{"It is not allowed to send private messages to the conference","Impedir o envio de mensagens privadas para a sala"}.
{"It is not allowed to send private messages","Não é permitido enviar mensagens privadas"}.
{"Jabber ID","ID Jabber"}.
{"January","Janeiro"}.
{"JID normalization denied by service policy","Normalização JID negada por causa da política de serviços"}.
{"JID normalization failed","A normalização JID falhou"}.
{"joins the room","Entrar na sala"}.
{"July","Julho"}.
{"June","Junho"}.
{"Just created","Acabou de ser criado"}.
{"Label:","Rótulo:"}.
{"Last Activity","Última actividade"}.
{"Last login","Último login"}.
{"Last message","Última mensagem"}.
{"Last month","Último mês"}.
{"Last year","Último ano"}.
{"Least significant bits of SHA-256 hash of text should equal hexadecimal label","Bits menos significativos do hash sha-256 do texto devem ser iguais ao rótulo hexadecimal"}.
{"leaves the room","Sair da sala"}.
{"List of rooms","Lista de salas"}.
{"Logging","Registando no log"}.
{"Low level update script","Script de atualização low level"}.
{"Make participants list public","Tornar pública a lista de participantes"}.
{"Make room CAPTCHA protected","Tornar protegida a palavra-passe da sala"}.
{"Make room members-only","Tornar sala apenas para membros"}.
{"Make room moderated","Tornar a sala moderada"}.
{"Make room password protected","Tornar sala protegida à palavra-passe"}.
{"Make room persistent","Tornar sala persistente"}.
{"Make room public searchable","Tornar sala pública possível de ser encontrada"}.
{"Malformed username","Nome de utilizador inválido"}.
{"MAM preference modification denied by service policy","Modificação de preferência MAM negada por causa da política de serviços"}.
{"March","Março"}.
{"Max # of items to persist","Máximo # de elementos que persistem"}.
{"Max payload size in bytes","Máximo tamanho do payload em bytes"}.
{"Maximum file size","Tamanho máximo do ficheiro"}.
{"Maximum Number of History Messages Returned by Room","Quantidade máxima das mensagens do histórico que foram devolvidas por sala"}.
{"Maximum number of items to persist","Quantidade máxima dos itens para manter"}.
{"Maximum Number of Occupants","Quantidate máxima de participantes"}.
{"May","Maio"}.
{"Members not added (inexistent vhost!): ","Membros que não foram adicionados (o vhost não existe!): "}.
{"Membership is required to enter this room","É necessário ser membro desta sala para poder entrar"}.
{"Members:","Membros:"}.
{"Memorize your password, or write it in a paper placed in a safe place. In XMPP there isn't an automated way to recover your password if you forget it.","Memorize a sua palavra-passe ou anote-a num papel guardado num local seguro. No XMPP, não há uma maneira automatizada de recuperar a sua palavra-passe caso a esqueça."}.
{"Memory","Memória"}.
{"Mere Availability in XMPP (No Show Value)","Mera disponibilidade no XMPP (Sem valor para ser exibido)"}.
{"Message body","Corpo da mensagem"}.
{"Message not found in forwarded payload","Mensagem não encontrada em conteúdo encaminhado"}.
{"Messages from strangers are rejected","As mensagens vindas de estranhos são rejeitadas"}.
{"Messages of type headline","Mensagens do tipo do título"}.
{"Messages of type normal","Mensagens do tipo normal"}.
{"Middle Name","Segundo nome"}.
{"Minimum interval between voice requests (in seconds)","O intervalo mínimo entre requisições de voz (em segundos)"}.
{"Moderator privileges required","São necessários privilégios de moderador"}.
{"Moderator","Moderador"}.
{"Moderators Only","Somente moderadores"}.
{"Modified modules","Módulos atualizados"}.
{"Module failed to handle the query","Módulo falhou ao processar a consulta"}.
{"Monday","Segunda"}.
{"Multicast","Multicast"}.
{"Multiple <item/> elements are not allowed by RFC6121","Vários elementos <item/> não são permitidos pela RFC6121"}.
{"Multi-User Chat","Chat multi-utilizador"}.
{"Name in the rosters where this group will be displayed","O nome nas listas onde este grupo será exibido"}.
{"Name","Nome"}.
{"Name:","Nome:"}.
{"Natural Language for Room Discussions","Idioma nativo para as discussões na sala"}.
{"Natural-Language Room Name","Nome da sala no idioma nativo"}.
{"Neither 'jid' nor 'nick' attribute found","Nem o atributo 'jid' nem 'nick' foram encontrados"}.
{"Neither 'role' nor 'affiliation' attribute found","Nem o atributo 'role' nem 'affiliation' foram encontrados"}.
{"Never","Nunca"}.
{"New Password:","Nova Palavra-passe:"}.
{"Nickname can't be empty","O apelido não pode ser vazio"}.
{"Nickname Registration at ","Registo da alcunha em "}.
{"Nickname ~s does not exist in the room","A alcunha ~s não existe na sala"}.
{"Nickname","Alcunha"}.
{"No address elements found","Nenhum elemento endereço foi encontrado"}.
{"No addresses element found","Nenhum elemento endereços foi encontrado"}.
{"No 'affiliation' attribute found","Atributo 'affiliation' não foi encontrado"}.
{"No available resource found","Nenhum recurso disponível foi encontrado"}.
{"No body provided for announce message","Nenhum corpo de texto fornecido para anunciar mensagem"}.
{"No child elements found","Nenhum elemento filho foi encontrado"}.
{"No data form found","Nenhum formulário de dados foi encontrado"}.
{"No Data","Nenhum dado"}.
{"No features available","Nenhuma funcionalidade disponível"}.
{"No <forwarded/> element found","Nenhum elemento <forwarded/> foi encontrado"}.
{"No hook has processed this command","Nenhum hook processou este comando"}.
{"No info about last activity found","Não foi encontrada informação sobre última atividade"}.
{"No 'item' element found","O elemento 'item' não foi encontrado"}.
{"No items found in this query","Nenhum item encontrado nesta consulta"}.
{"No limit","Ilimitado"}.
{"No module is handling this query","Nenhum módulo está processando esta consulta"}.
{"No node specified","Nenhum nó especificado"}.
{"No 'password' found in data form","'password' não foi encontrado em formulário de dados"}.
{"No 'password' found in this query","Nenhuma 'palavra-passe' foi encontrado nesta consulta"}.
{"No 'path' found in data form","'path' não foi encontrado em formulário de dados"}.
{"No pending subscriptions found","Não foram encontradas subscrições"}.
{"No privacy list with this name found","Nenhuma lista de privacidade encontrada com este nome"}.
{"No private data found in this query","Nenhum dado privado encontrado nesta consulta"}.
{"No running node found","Nenhum nó em execução foi encontrado"}.
{"No services available","Não há serviços disponíveis"}.
{"No statistics found for this item","Não foram encontradas estatísticas para este item"}.
{"No 'to' attribute found in the invitation","Atributo 'to' não foi encontrado no convite"}.
{"Nobody","Ninguém"}.
{"Node already exists","Nó já existe"}.
{"Node ID","ID do Tópico"}.
{"Node index not found","O índice do nó não foi encontrado"}.
{"Node not found","Nodo não encontrado"}.
{"Node ~p","Nó ~p"}.
{"Node","Nó"}.
{"Nodeprep has failed","Processo de identificação de nó falhou (nodeprep)"}.
{"Nodes","Nodos"}.
{"None","Nenhum"}.
{"Not allowed","Não é permitido"}.
{"Not Found","Não encontrado"}.
{"Not subscribed","Não subscrito"}.
{"Notify subscribers when items are removed from the node","Notificar assinantes quando itens forem eliminados do nó"}.
{"Notify subscribers when the node configuration changes","Notificar assinantes a configuração do nó mudar"}.
{"Notify subscribers when the node is deleted","Notificar assinantes quando o nó for eliminado se elimine"}.
{"November","Novembro"}.
{"Number of answers required","Quantidade de respostas necessárias"}.
{"Number of occupants","Quantidade de participantes"}.
{"Number of Offline Messages","Quantidade das mensagens offline"}.
{"Number of online users","Quantidade de utilizadores online"}.
{"Number of registered users","Quantidade de utilizadores registados"}.
{"Number of seconds after which to automatically purge items","Quantidade de segundos para excluir os itens automaticamente"}.
{"Occupants are allowed to invite others","As pessoas estão autorizadas a convidar outras pessoas"}.
{"Occupants May Change the Subject","As pessoas talvez possam alterar o assunto"}.
{"October","Outubro"}.
{"Offline Messages","Mensagens offline"}.
{"Offline Messages:","Mensagens offline:"}.
{"OK","OK"}.
{"Old Password:","Palavra-passe Antiga:"}.
{"Online Users","Utilizadores ligados"}.
{"Online Users:","Utilizadores online:"}.
{"Online","Ligado"}.
{"Only admins can see this","Apenas administradores podem ver isso"}.
{"Only collection node owners may associate leaf nodes with the collection","Apenas um grupo dos proprietários dos nós podem associar as páginas na coleção"}.
{"Only deliver notifications to available users","Somente enviar notificações aos utilizadores disponíveis"}.
{"Only <enable/> or <disable/> tags are allowed","Apenas tags <enable/> ou <disable/> são permitidas"}.
{"Only <list/> element is allowed in this query","Apenas elemento <list/> é permitido nesta consulta"}.
{"Only members may query archives of this room","Somente os membros podem procurar nos arquivos desta sala"}.
{"Only moderators and participants are allowed to change the subject in this room","Somente os moderadores e os participamentes podem alterar o assunto desta sala"}.
{"Only moderators are allowed to change the subject in this room","Somente os moderadores podem alterar o assunto desta sala"}.
{"Only moderators can approve voice requests","Somente moderadores podem aprovar requisições de voz"}.
{"Only occupants are allowed to send messages to the conference","Só os ocupantes podem enviar mensagens para a sala"}.
{"Only occupants are allowed to send queries to the conference","Só os ocupantes podem enviar consultas para a sala"}.
{"Only publishers may publish","Apenas os editores podem publicar"}.
{"Only service administrators are allowed to send service messages","Só os administradores do serviço têm permissão para enviar mensagens de serviço"}.
{"Only those on a whitelist may associate leaf nodes with the collection","Apenas aqueles presentes numa lista branca podem associar páginas na coleção"}.
{"Only those on a whitelist may subscribe and retrieve items","Apenas aqueles presentes numa lista branca podem se inscrever e recuperar os itens"}.
{"Organization Name","Nome da organização"}.
{"Organization Unit","Unidade da organização"}.
{"Outgoing s2s Connections","Conexões s2s de Saída"}.
{"Outgoing s2s Connections:","Saída das conexões s2s:"}.
{"Owner privileges required","São necessários privilégios de dono"}.
{"Packet relay is denied by service policy","A retransmissão de pacote é negada por causa da política de serviço"}.
{"Packet","Pacote"}.
{"Participant","Participante"}.
{"Password Verification:","Verificação da Palavra-passe:"}.
{"Password Verification","Verificação de Palavra-passe"}.
{"Password","Palavra-chave"}.
{"Password:","Palavra-chave:"}.
{"Path to Dir","Caminho para o directório"}.
{"Path to File","Caminho do ficheiro"}.
{"Payload type","Tipo da carga útil"}.
{"Pending","Pendente"}.
{"private, ","privado"}.
{"Period: ","Período: "}.
{"Persist items to storage","Persistir elementos ao armazenar"}.
{"Persistent","Persistente"}.
{"Ping query is incorrect","A consulta ping está incorreta"}.
{"Ping","Ping"}.
{"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Observe que tais opções farão backup apenas da base de dados Mnesia. Caso esteja a utilizar o modulo ODBC, precisará fazer backup da sua base de dados SQL separadamente."}.
{"Please, wait for a while before sending new voice request","Por favor, espere antes de enviar uma nova requisição de voz"}.
{"Pong","Pong"}.
{"Possessing 'ask' attribute is not allowed by RFC6121","Possuir o atributo 'ask' não é permitido pela RFC6121"}.
{"Present real Jabber IDs to","Tornar o Jabber ID real visível por"}.
{"Previous session not found","A sessão anterior não foi encontrada"}.
{"Previous session PID has been killed","O PID da sessão anterior foi excluído"}.
{"Previous session PID has exited","O PID da sessão anterior foi encerrado"}.
{"Previous session PID is dead","O PID da sessão anterior está morto"}.
{"Previous session timed out","A sessão anterior expirou"}.
{"private, ","privado, "}.
{"Public","Público"}.
{"Publish model","Publicar o modelo"}.
{"Publish-Subscribe","Publicação de Tópico"}.
{"PubSub subscriber request","PubSub requisição de assinante"}.
{"Purge all items when the relevant publisher goes offline","Descartar todos os itens quando o publicante principal estiver offline"}.
{"Push record not found","O registo push não foi encontrado"}.
{"Queries to the conference members are not allowed in this room","Nesta sala não são permitidas consultas aos seus membros"}.
{"Query to another users is forbidden","Consultar a outro utilizador é proibido"}.
{"RAM and disc copy","Cópia em RAM e em disco"}.
{"RAM copy","Cópia em RAM"}.
{"Really delete message of the day?","Deletar realmente a mensagem do dia?"}.
{"Receive notification from all descendent nodes","Receba a notificação de todos os nós descendentes"}.
{"Receive notification from direct child nodes only","Receba apenas as notificações dos nós relacionados"}.
{"Receive notification of new items only","Receba apenas as notificações dos itens novos"}.
{"Receive notification of new nodes only","Receba apenas as notificações dos nós novos"}.
{"Recipient is not in the conference room","O destinatário não está na sala"}.
{"Register an XMPP account","Registe uma conta XMPP"}.
{"Registered Users","Utilizadores registados"}.
{"Registered Users:","Utilizadores registados:"}.
{"Register","Registar"}.
{"Remote copy","Cópia remota"}.
{"Remove All Offline Messages","Remover Todas as Mensagens Offline"}.
{"Remove User","Eliminar utilizador"}.
{"Remove","Remover"}.
{"Replaced by new connection","Substituído por nova conexão"}.
{"Request has timed out","O pedido expirou"}.
{"Request is ignored","O pedido foi ignorado"}.
{"Requested role","Função solicitada"}.
{"Resources","Recursos"}.
{"Restart Service","Reiniciar Serviço"}.
{"Restart","Reiniciar"}.
{"Restore Backup from File at ","Restaura cópia de segurança a partir do ficheiro em "}.
{"Restore binary backup after next ejabberd restart (requires less memory):","Restaurar backup binário após reinicialização do ejabberd (requer menos memória):"}.
{"Restore binary backup immediately:","Restaurar imediatamente o backup binário:"}.
{"Restore plain text backup immediately:","Restaurar backup formato texto imediatamente:"}.
{"Restore","Restaurar"}.
{"Roles and Affiliations that May Retrieve Member List","As funções e as afiliações que podem recuperar a lista dos membros"}.
{"Roles for which Presence is Broadcasted","Para quem a presença será notificada"}.
{"Roles that May Send Private Messages","Atribuições que talvez possam enviar mensagens privadas"}.
{"Room Configuration","Configuração de salas"}.
{"Room creation is denied by service policy","Sala não pode ser criada devido à política do serviço"}.
{"Room description","Descrição da Sala"}.
{"Room Occupants","Quantidade de participantes"}.
{"Room terminates","Terminação da sala"}.
{"Room title","Título da sala"}.
{"Roster groups allowed to subscribe","Listar grupos autorizados"}.
{"Roster of ~ts","Lista de ~ts"}.
{"Roster size","Tamanho da Lista"}.
{"Roster:","Lista:"}.
{"RPC Call Error","Erro de chamada RPC"}.
{"Running Nodes","Nodos a correr"}.
{"~s invites you to the room ~s","~s convidaram-o à sala ~s"}.
{"Saturday","Sábado"}.
{"Script check","Verificação de Script"}.
{"Search from the date","Pesquise a partir da data"}.
{"Search Results for ","Resultados de pesquisa para "}.
{"Search the text","Pesquise o texto"}.
{"Search until the date","Pesquise até a data"}.
{"Search users in ","Procurar utilizadores em "}.
{"Select All","Selecione tudo"}.
{"Send announcement to all online users on all hosts","Enviar anúncio a todos utilizadores online em todas as máquinas"}.
{"Send announcement to all online users","Enviar anúncio a todos os utilizadorns online"}.
{"Send announcement to all users on all hosts","Enviar aviso para todos os utilizadores em todos os hosts"}.
{"Send announcement to all users","Enviar anúncio a todos os utilizadores"}.
{"September","Setembro"}.
{"Server:","Servidor:"}.
{"Service list retrieval timed out","A recuperação da lista dos serviços expirou"}.
{"Session state copying timed out","A cópia do estado da sessão expirou"}.
{"Set message of the day and send to online users","Definir mensagem do dia e enviar a todos utilizadores online"}.
{"Set message of the day on all hosts and send to online users","Definir mensagem do dia em todos os hosts e enviar para os utilizadores online"}.
{"Shared Roster Groups","Grupos Shared Roster"}.
{"Show Integral Table","Mostrar Tabela Integral"}.
{"Show Ordinary Table","Mostrar Tabela Ordinária"}.
{"Shut Down Service","Parar Serviço"}.
{"SOCKS5 Bytestreams","Bytestreams SOCKS5"}.
{"Some XMPP clients can store your password in the computer, but you should do this only in your personal computer for safety reasons.","Alguns clientes XMPP podem armazenar a sua palavra-passe no seu computador, só faça isso no seu computador particular por questões de segurança."}.
{"Specify the access model","Especificar os modelos de acesso"}.
{"Specify the event message type","Especificar o tipo de mensagem para o evento"}.
{"Specify the publisher model","Especificar o modelo do publicante"}.
{"Stanza ID","ID da estrofe"}.
{"Statically specify a replyto of the node owner(s)","Defina uma resposta fixa do(s) proprietário(s) do nó"}.
{"Statistics of ~p","Estatísticas de ~p"}.
{"Statistics","Estatísticas"}.
{"Stop","Parar"}.
{"Stopped Nodes","Nodos parados"}.
{"Storage Type","Tipo de armazenagem"}.
{"Store binary backup:","Armazenar backup binário:"}.
{"Store plain text backup:","Armazenar backup em texto:"}.
{"Stream management is already enabled","A gestão do fluxo já está ativada"}.
{"Stream management is not enabled","A gestão do fluxo não está ativada"}.
{"Subject","Assunto"}.
{"Submit","Enviar"}.
{"Submitted","Submetido"}.
{"Subscriber Address","Endereço dos Assinantes"}.
{"Subscribers may publish","Os assinantes podem publicar"}.
{"Subscription requests must be approved and only subscribers may retrieve items","Os pedidos de assinatura devem ser aprovados e apenas os assinantes podem recuperar os itens"}.
{"Subscriptions are not allowed","Subscrições não estão permitidas"}.
{"Subscription","Subscrição"}.
{"Sunday","Domingo"}.
{"Text associated with a picture","Um texto associado a uma imagem"}.
{"Text associated with a sound","Um texto associado a um som"}.
{"Text associated with a video","Um texto associado a um vídeo"}.
{"Text associated with speech","Um texto associado à fala"}.
{"That nickname is already in use by another occupant","O apelido (nick) já está a ser utilizado"}.
{"That nickname is registered by another person","O apelido já está registado por outra pessoa"}.
{"The account already exists","A conta já existe"}.
{"The account was not unregistered","A conta não estava não registada"}.
{"The body text of the last received message","O corpo do texto da última mensagem que foi recebida"}.
{"The CAPTCHA is valid.","O CAPTCHA é inválido."}.
{"The CAPTCHA verification has failed","A verificação do CAPTCHA falhou"}.
{"The captcha you entered is wrong","O captcha que digitou está errado"}.
{"The child nodes (leaf or collection) associated with a collection","Os nós relacionados (página ou coleção) associados com uma coleção"}.
{"The collections with which a node is affiliated","As coleções com as quais o nó está relacionado"}.
{"The DateTime at which a leased subscription will end or has ended","A data e a hora que uma assinatura alugada terminará ou terá terminado"}.
{"The datetime when the node was created","A data em que o nó foi criado"}.
{"The default language of the node","O idioma padrão do nó"}.
{"The feature requested is not supported by the conference","A funcionalidade solicitada não é suportada pela sala de conferência"}.
{"The JID of the node creator","O JID do criador do nó"}.
{"The JIDs of those to contact with questions","Os JIDs daqueles para entrar em contato com perguntas"}.
{"The JIDs of those with an affiliation of owner","Os JIDs daqueles com uma afiliação de proprietário"}.
{"The JIDs of those with an affiliation of publisher","Os JIDs daqueles com uma afiliação de editor"}.
{"The list of JIDs that may associate leaf nodes with a collection","A lista dos JIDs que podem associar as páginas dos nós numa coleção"}.
{"The maximum number of child nodes that can be associated with a collection","A quantidade máxima dos nós relacionados que podem ser associados com uma coleção"}.
{"The minimum number of milliseconds between sending any two notification digests","A quantidade mínima de milissegundos entre o envio do resumo das duas notificações"}.
{"The name of the node","O nome do nó"}.
{"The node is a collection node","O nó é um nó da coleção"}.
{"The node is a leaf node (default)","O nó é uma página do nó (padrão)"}.
{"The NodeID of the relevant node","O NodeID do nó relevante"}.
{"The number of pending incoming presence subscription requests","A quantidade pendente dos pedidos da presença da assinatura"}.
{"The number of subscribers to the node","A quantidade dos assinantes para o nó"}.
{"The number of unread or undelivered messages","A quantidade das mensagens que não foram lidas ou não foram entregues"}.
{"The password contains unacceptable characters","A palavra-passe contém caracteres proibidos"}.
{"The password is too weak","Palavra-passe considerada muito fraca"}.
{"the password is","a palavra-passe é"}.
{"The password of your XMPP account was successfully changed.","A palavra-passe da sua conta XMPP foi alterada com sucesso."}.
{"The password was not changed","A palavra-passe não foi alterada"}.
{"The passwords are different","As palavras-passe não batem"}.
{"The presence states for which an entity wants to receive notifications","As condições da presença para os quais uma entidade queira receber as notificações"}.
{"The query is only allowed from local users","Esta consulta só é permitida a partir de utilizadores locais"}.
{"The query must not contain <item/> elements","A consulta não pode conter elementos <item/>"}.
{"The room subject can be modified by participants","O tema da sala pode ser alterada pelos próprios participantes"}.
{"The sender of the last received message","O remetente da última mensagem que foi recebida"}.
{"The stanza MUST contain only one <active/> element, one <default/> element, or one <list/> element","A instância DEVE conter apenas um elemento <active/>, um elemento <default/>, ou um elemento <list/>"}.
{"The subscription identifier associated with the subscription request","O identificador da assinatura associado à solicitação da assinatura"}.
{"The type of node data, usually specified by the namespace of the payload (if any)","O tipo dos dados do nó, normalmente definido pelo espaço dos nomes da carga útil (caso haja)"}.
{"The URL of an XSL transformation which can be applied to payloads in order to generate an appropriate message body element.","O URL da transformação XSL que pode ser aplicada nas cargas úteis para gerar um elemento apropriado no corpo da mensagem."}.
{"The URL of an XSL transformation which can be applied to the payload format in order to generate a valid Data Forms result that the client could display using a generic Data Forms rendering engine","A URL de uma transformação XSL que pode ser aplicada ao formato de carga útil para gerar um Formulário de Dados válido onde o cliente possa exibir usando um mecanismo genérico de renderização do Formulários de Dados"}.
{"The username is not valid","O nome do utilizador não é válido"}.
{"There was an error changing the password: ","Houve um erro ao alterar a palavra-passe: "}.
{"There was an error creating the account: ","Houve um erro ao criar esta conta: "}.
{"There was an error deleting the account: ","Houve um erro ao deletar esta conta: "}.
{"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","O tamanho da caixa não importa: macbeth é o mesmo que MacBeth e Macbeth."}.
{"This page allows to register an XMPP account in this XMPP server. Your JID (Jabber ID) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Esta pagina permite a criação de novas contas XMPP neste servidor. O seu JID (Identificador Jabber) será da seguinte maneira: utilizador@servidor. Por favor, leia cuidadosamente as instruções para preencher todos os campos corretamente."}.
{"This page allows to unregister an XMPP account in this XMPP server.","Esta página permite a exclusão de uma conta XMPP neste servidor."}.
{"This room is not anonymous","Essa sala não é anônima"}.
{"This service can not process the address: ~s","Este serviço não pode processar o endereço: ~s"}.
{"Thursday","Quinta"}.
{"Time delay","Intervalo (Tempo)"}.
{"Timed out waiting for stream resumption","Tempo limite expirou durante à espera da retomada da transmissão"}.
{"Time","Data"}.
{"To register, visit ~s","Para registar, visite ~s"}.
{"To ~ts","Para ~s"}.
{"Token TTL","Token TTL"}.
{"Too many active bytestreams","Quantidade excessiva de bytestreams ativos"}.
{"Too many CAPTCHA requests","Quantidade excessiva de requisições para o CAPTCHA"}.
{"Too many child elements","Quantidade excessiva de elementos filho"}.
{"Too many <item/> elements","Quantidade excessiva de elementos <item/>"}.
{"Too many <list/> elements","Quantidade excessiva de elementos <list/>"}.
{"Too many (~p) failed authentications from this IP address (~s). The address will be unblocked at ~s UTC","Tentativas excessivas (~p) com falha de autenticação (~s). O endereço será desbloqueado às ~s UTC"}.
{"Too many receiver fields were specified","Foram definidos receptores demais nos campos"}.
{"Too many unacked stanzas","Quantidade excessiva de instâncias sem confirmação"}.
{"Too many users in this conference","Há uma quantidade excessiva de utilizadores nesta conferência"}.
{"To","Para"}.
{"Total rooms","Salas no total"}.
{"Traffic rate limit is exceeded","Limite de banda excedido"}.
{"Transactions Aborted:","Transações abortadas:"}.
{"Transactions Committed:","Transações salvas:"}.
{"Transactions Logged:","Transações de log:"}.
{"Transactions Restarted:","Transações reiniciadas:"}.
{"~ts's Offline Messages Queue","~s's Fila de Mensagens Offline"}.
{"Tuesday","Terça"}.
{"Unable to generate a CAPTCHA","Impossível gerar um CAPTCHA"}.
{"Unable to register route on existing local domain","Não foi possível registar rota no domínio local existente"}.
{"Unauthorized","Não Autorizado"}.
{"Unexpected action","Ação inesperada"}.
{"Unexpected error condition: ~p","Condição de erro inesperada: ~p"}.
{"Unregister an XMPP account","Excluir uma conta XMPP"}.
{"Unregister","Deletar registo"}.
{"Unselect All","Desmarcar todos"}.
{"Unsupported <index/> element","Elemento <index/> não suportado"}.
{"Unsupported version","Versão sem suporte"}.
{"Update message of the day (don't send)","Atualizar mensagem do dia (não enviar)"}.
{"Update message of the day on all hosts (don't send)","Atualizar a mensagem do dia em todos os host (não enviar)"}.
{"Update ~p","Atualizar ~p"}.
{"Update plan","Plano de atualização"}.
{"Update script","Script de atualização"}.
{"Update","Actualizar"}.
{"Uptime:","Tempo de atividade:"}.
{"URL for Archived Discussion Logs","A URL para o arquivamento dos registos da discussão"}.
{"User already exists","Utilizador já existe"}.
{"User (jid)","Utilizador (jid)"}.
{"User JID","Utilizador JID"}.
{"User Management","Gestão de utilizadores"}.
{"User removed","O utilizador foi removido"}.
{"User session not found","A sessão do utilizador não foi encontrada"}.
{"User session terminated","Sessão de utilizador terminada"}.
{"User ~ts","Utilizador ~s"}.
{"Username:","Utilizador:"}.
{"Users are not allowed to register accounts so quickly","Utilizadores não estão autorizados a registar contas imediatamente"}.
{"Users Last Activity","Últimas atividades dos utilizadores"}.
{"Users","Utilizadores"}.
{"User","Utilizador"}.
{"Validate","Validar"}.
{"Value 'get' of 'type' attribute is not allowed","Valor 'get' não permitido para atributo 'type'"}.
{"Value of '~s' should be boolean","Value de '~s' deveria ser um booleano"}.
{"Value of '~s' should be datetime string","Valor de '~s' deveria ser data e hora"}.
{"Value of '~s' should be integer","Valor de '~s' deveria ser um inteiro"}.
{"Value 'set' of 'type' attribute is not allowed","Valor 'set' não permitido para atributo 'type'"}.
{"vCard User Search","Busca de Utilizador vCard"}.
{"View Queue","Exibir a fila"}.
{"View Roster","Ver a lista"}.
{"Virtual Hosts","Hosts virtuais"}.
{"Visitors are not allowed to change their nicknames in this room","Nesta sala, os visitantes não podem mudar os apelidos deles"}.
{"Visitors are not allowed to send messages to all occupants","Os visitantes não podem enviar mensagens para todos os ocupantes"}.
{"Visitor","Visitante"}.
{"Voice request","Requisição de voz"}.
{"Voice requests are disabled in this conference","Requisições de voz estão desativadas nesta sala de conferência"}.
{"Wednesday","Quarta"}.
{"When a new subscription is processed and whenever a subscriber comes online","Quando uma nova assinatura é processada e sempre que um assinante fica online"}.
{"When a new subscription is processed","Quando uma nova assinatura é processada"}.
{"When to send the last published item","Quando enviar o último tópico publicado"}.
{"Whether an entity wants to receive an XMPP message body in addition to the payload format","Caso uma entidade queira receber o corpo de uma mensagem XMPP além do formato de carga útil"}.
{"Whether an entity wants to receive digests (aggregations) of notifications or all notifications individually","Caso uma entidade queira receber os resumos (as agregações) das notificações ou todas as notificações individualmente"}.
{"Whether an entity wants to receive or disable notifications","Caso uma entidade queira receber ou desativar as notificações"}.
{"Whether owners or publisher should receive replies to items","Caso os proprietários ou a editora devam receber as respostas nos itens"}.
{"Whether the node is a leaf (default) or a collection","Caso o nó seja uma folha (padrão) ou uma coleção"}.
{"Whether to allow subscriptions","Permitir subscrições"}.
{"Whether to make all subscriptions temporary, based on subscriber presence","Caso todas as assinaturas devam ser temporárias, com base na presença do assinante"}.
{"Whether to notify owners about new subscribers and unsubscribes","Caso deva notificar os proprietários sobre os novos assinantes e aqueles que cancelaram a assinatura"}.
{"Who may associate leaf nodes with a collection","Quem pode associar as folhas dos nós numa coleção"}.
{"Wrong parameters in the web formulary","O formulário web está com os parâmetros errados"}.
{"Wrong xmlns","Xmlns errado"}.
{"XMPP Account Registration","Registo da Conta XMPP"}.
{"XMPP Domains","Domínios XMPP"}.
{"XMPP Show Value of Away","XMPP Exiba o valor da ausência"}.
{"XMPP Show Value of Chat","XMPP Exiba o valor do chat"}.
{"XMPP Show Value of DND (Do Not Disturb)","XMPP Exiba o valor do DND (Não Perturbe)"}.
{"XMPP Show Value of XA (Extended Away)","XMPP Exiba o valor do XA (Ausência Estendida)"}.
{"XMPP URI of Associated Publish-Subscribe Node","XMPP URI da publicação do nó associado da assinatura"}.
{"You are being removed from the room because of a system shutdown","Está a ser removido da sala devido ao desligamento do sistema"}.
{"You are not joined to the channel","Não está inscrito no canal"}.
{"You can later change your password using an XMPP client.","Pode alterar a sua palavra-passe mais tarde usando um cliente XMPP."}.
{"You have been banned from this room","Foi banido desta sala"}.
{"You have joined too many conferences","Entrou em demais salas de conferência"}.
{"You must fill in field \"Nickname\" in the form","Deve completar o campo \"Apelido\" no formulário"}.
{"You need a client that supports x:data and CAPTCHA to register","Precisa de um cliente com suporte de x:data para poder registar o apelido"}.
{"You need a client that supports x:data to register the nickname","Precisa de um cliente com suporte a x:data para registar o seu apelido"}.
{"You need an x:data capable client to search","É necessário um cliente com suporte de x:data para poder procurar"}.
{"Your active privacy list has denied the routing of this stanza.","A sua lista de privacidade ativa negou o roteamento desta instância."}.
{"Your contact offline message queue is full. The message has been discarded.","A fila de contatos offline esta cheia. A sua mensagem foi descartada."}.
{"Your subscription request and/or messages to ~s have been blocked. To unblock your subscription request, visit ~s","As suas mensagens para ~s estão bloqueadas. Para desbloqueá-las, visite: ~s"}.
{"Your XMPP account was successfully registered.","A sua conta XMPP foi registada com sucesso."}.
{"Your XMPP account was successfully unregistered.","A sua conta XMPP foi excluída com sucesso."}.
{"You're not allowed to create nodes","Não tem autorização para criar nós"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (Добавьте * в конец поля для поиска подстроки)"}.
{" has set the subject to: "," установил(а) тему: "}.
{"A friendly name for the node","Легко запоминаемое имя для узла"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: ","zmenil(a) tému na: "}.
{"A friendly name for the node","Prístupný názov pre uzol"}.
{"A password is required to enter this room","Pre vstup do miestnosti je potrebné heslo"}.
+383
View File
@@ -0,0 +1,383 @@
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," ka caktuar si subjekt: "}.
{"# participants","# pjesëmarrës"}.
{"A description of the node","Përshkrim i nyjës"}.
{"A friendly name for the node","Emër miqësor për nyjën"}.
{"A password is required to enter this room","Lypset fjalëkalim për të hyrë në këtë dhomë"}.
{"A Web Page","Faqe Web"}.
{"Accept","Pranoje"}.
{"Account doesn't exist","Llogaria sekziston"}.
{"Add Jabber ID","Shtoni ID Jabber"}.
{"Add New","Shtoni të Ri"}.
{"Add User","Shtoni Përdorues"}.
{"Administration of ","Administrim i "}.
{"Administration","Administrim"}.
{"Administrator privileges required","Lyp privilegje përgjegjësi"}.
{"All activity","Krejt veprimtaria"}.
{"All Users","Krejt Përdoruesit"}.
{"Allow subscription","Lejo pajtim"}.
{"Allow users to query other users","Lejojuni përdoruesve të kërkojnë për përdorues të tjerë"}.
{"Allow users to send invites","Lejojuni përdoruesve të dërgojnë ftesa"}.
{"Allow users to send private messages","Lejojuni përdoruesve të dërgojnë mesazhe private"}.
{"Allow visitors to change nickname","Lejojuni përdoruesve të ndryshojnë nofkë"}.
{"Allow visitors to send private messages to","Lejojuni përdoruesve të dërgojnë mesazhe private te"}.
{"Announcements","Lajmërime"}.
{"Answer to a question","Përgjigjuni një pyetje"}.
{"Anyone may publish","Gjithkush mund të publikojë"}.
{"Anyone with Voice","Cilido me Zë"}.
{"Anyone","Cilido"}.
{"April","Prill"}.
{"Attribute 'channel' is required for this request","Atributi 'channel' është i domosdoshëm për këtë kërkesë"}.
{"Attribute 'jid' is not allowed here","Atributi 'jid' slejohet këtu"}.
{"Attribute 'node' is not allowed here","Atributi 'node' slejohet këtu"}.
{"August","Gusht"}.
{"Automatic node creation is not enabled","S’është aktivizuar krijimi automatik i nyjes"}.
{"Backup Management","Administrim Kopjeruajtjesh"}.
{"Backup of ~p","Kopjeruajtje e ~p"}.
{"Backup to File at ","Kopjeruaje te Kartelë në "}.
{"Backup","Kopjeruajtje"}.
{"Bad format","Format i gabuar"}.
{"Birthday","Datëlindje"}.
{"Both the username and the resource are required","Janë të domosdoshëm të dy, emri i përdoruesit dhe burimi"}.
{"Cannot remove active list","Shiqet dot lista aktive"}.
{"Cannot remove default list","Shiqet dot lista parazgjedhje"}.
{"CAPTCHA web page","Faqe web e CAPTCHA-s"}.
{"Change Password","Ndryshoni Fjalëkalimin"}.
{"Change User Password","Ndryshoni Fjalëkalim Përdoruesi"}.
{"Changing password is not allowed","Nuk lejohet ndryshimi i fjalëkalimit"}.
{"Changing role/affiliation is not allowed","Nuk lejohet ndryshim roli/përkatësie"}.
{"Channel already exists","Kanali ekziston tashmë"}.
{"Channel does not exist","Kanali sekziston"}.
{"Channels","Kanale"}.
{"Characters not allowed:","Shenja të palejuara:"}.
{"Chatroom configuration modified","Ndryshoi formësimi i dhomës së fjalosjeve"}.
{"Chatroom is created","Dhoma e fjalosjes u krijua"}.
{"Chatroom is destroyed","Dhoma e fjalosjes u asgjësua"}.
{"Chatroom is started","Dhoma e fjalosjes u nis"}.
{"Chatroom is stopped","Dhoma e fjalosjes u ndal"}.
{"Chatrooms","Dhoma fjalosjeje"}.
{"Choose a username and password to register with this server","Zgjidhni një emër përdoruesi dhe fjalëkalim për ta regjistruar me këtë shërbyes"}.
{"Choose storage type of tables","Zgjidhni lloj depozitimi tableash"}.
{"City","Qytet"}.
{"Commands","Urdhra"}.
{"Conference room does not exist","Dhoma e konferencës sekziston"}.
{"Configuration of room ~s","Formësim i dhomë ~s"}.
{"Configuration","Formësim"}.
{"Country","Vend"}.
{"CPU Time:","Kohë CPU-je:"}.
{"Current Discussion Topic","Tema e Tanishme e Diskutimit"}.
{"Database failure","Dështim baze të dhënash"}.
{"Database Tables at ~p","Tabela Baze të Dhënash te ~p"}.
{"Database Tables Configuration at ","Formësim Tabelash Baze të Dhënash te "}.
{"Database","Bazë të dhënash"}.
{"December","Dhjetor"}.
{"Delete content","Fshini lëndë"}.
{"Delete message of the day","Fshini mesazhin e ditës"}.
{"Delete Selected","Fshi të Përzgjedhurin"}.
{"Delete table","Fshini tabelën"}.
{"Delete User","Fshi Përdorues"}.
{"Deliver event notifications","Dërgo njoftime aktesh"}.
{"Description:","Përshkrim:"}.
{"Disc only copy","Kopje vetëm në disk"}.
{"Duplicated groups are not allowed by RFC6121","Grupe të përsëdytur slejohen nga RFC6121"}.
{"Edit Properties","Përpunoni Veti"}.
{"ejabberd","ejabberd"}.
{"Elements","Elementë"}.
{"Email Address","Adresë Email"}.
{"Email","Email"}.
{"Enable logging","Aktivizo regjistrim"}.
{"Enable message archiving","Aktivizoni arkivim mesazhesh"}.
{"Enter path to backup file","Jepni shteg për te kartelë kopjeruajtje"}.
{"Enter path to text file","Jepni shteg për te kartelë tekst"}.
{"Enter the text you see","Jepni tekstin që shihni"}.
{"Error","Gabim"}.
{"External component failure","Dështim përbërësi të jashtëm"}.
{"External component timeout","Mbarim kohe për përbërës të jashtëm"}.
{"Failed to parse HTTP response","Su arrit të përtypet përgjigje HTTP"}.
{"Failed to process option '~s'","Su arrit të përpunohej mundësia '~s'"}.
{"Family Name","Mbiemër"}.
{"FAQ Entry","Zë PBR-sh"}.
{"February","Shkurt"}.
{"File larger than ~w bytes","Kartelë më e madhe se ~w bajte"}.
{"Fill in the form to search for any matching XMPP User","Plotësoni formularin që të kërkohet për çfarëdo përdoruesi XMPP me përputhje"}.
{"Friday","E premte"}.
{"From ~ts","Nga ~ts"}.
{"From","Nga"}.
{"Full List of Room Admins","Listë e Plotë Përgjegjësish Dhome"}.
{"Full List of Room Owners","Listë e Plotë të Zotësh Dhome"}.
{"Full Name","Emër i Plotë"}.
{"Get Number of Online Users","Merr Numër Përdoruesish Në Linjë"}.
{"Get Number of Registered Users","Merr Numër Përdoruesish të Regjistruar"}.
{"Get User Password","Merr Fjalëkalim Përdoruesi"}.
{"Get User Statistics","Merr Statistika Përdoruesi"}.
{"Given Name","Emër"}.
{"Grant voice to this person?","Ti akordohet zë këtij personi?"}.
{"Group","Grup"}.
{"Groups that will be displayed to the members","Grupe që do tu shfaqen anëtarëve"}.
{"Groups","Grupe"}.
{"has been banned","është dëbuar"}.
{"has been kicked","është përzënë"}.
{"Host unknown","Strehë e panjohur"}.
{"Host","Strehë"}.
{"HTTP File Upload","Ngarkim Kartelash HTTP"}.
{"Idle connection","Lidhje e plogësht"}.
{"Import Directory","Importoni Drejtori"}.
{"Import File","Importoni Kartelë"}.
{"Import User from File at ","Importo Përdorues prej Kartele te "}.
{"Import Users from Dir at ","Importo Përdorues nga Drejtori te "}.
{"Improper message type","Lloj i pasaktë mesazhesh"}.
{"Incoming s2s Connections:","Lidhje s2s Ardhëse:"}.
{"Incorrect CAPTCHA submit","Parashtim Captcha-je të pasaktë"}.
{"Incorrect password","Fjalëkalim i pasaktë"}.
{"Incorrect value of 'action' attribute","Vlerë e pavlefshme atributi 'action'"}.
{"Insufficient privilege","Privilegj i pamjaftueshëm"}.
{"Internal server error","Gabim i brendshëm shërbyesi"}.
{"Invalid node name","Emër i pavlefshëm nyjeje"}.
{"Invalid 'previd' value","Vlerë e pavlefshme 'previd'"}.
{"Invitations are not allowed in this conference","Në këtë konferencë nuk lejohen ftesa"}.
{"IP addresses","Adresa IP"}.
{"is now known as","tani njihet si"}.
{"It is not allowed to send private messages to the conference","Nuk lejohet të dërgohen mesazhe private te konferenca"}.
{"It is not allowed to send private messages","Nuk lejohet të dërgohen mesazhe private"}.
{"Jabber ID","ID Jabber"}.
{"January","Janar"}.
{"JID normalization failed","Normalizimi JID dështoi"}.
{"joins the room","hyn te dhoma"}.
{"July","Korrik"}.
{"June","Qershor"}.
{"Just created","Të sapokrijuara"}.
{"Label:","Etiketë:"}.
{"Last Activity","Veprimtaria e Fundit"}.
{"Last login","Hyrja e fundit"}.
{"Last message","Mesazhi i fundit"}.
{"Last month","Muaji i fundit"}.
{"Last year","Viti i shkuar"}.
{"leaves the room","del nga dhoma"}.
{"List of rooms","Listë dhomash"}.
{"Logging","Regjistrim"}.
{"Make participants list public","Bëje publike listën e pjesëmarrësve"}.
{"Make room CAPTCHA protected","Bëje dhomën të mbrojtur me CAPTCHA"}.
{"Make room members-only","Bëje dhomën vetëm për anëtarët"}.
{"Make room moderated","Bëje dhomën të moderuar"}.
{"Make room password protected","Bëje dhomën të mbrojtur me fjalëkalim"}.
{"Make room persistent","Bëje dhomën të qëndrueshme"}.
{"Make room public searchable","Bëje dhomën të kërkueshme publikisht"}.
{"Malformed username","Faqerojtës i keqformuar"}.
{"March","Mars"}.
{"Max payload size in bytes","Madhësi maksimum ngarkese në bajte"}.
{"Maximum file size","Madhësi maksimum kartelash"}.
{"Maximum Number of Occupants","Numër Maksimum të Pranishmish"}.
{"May","Maj"}.
{"Members not added (inexistent vhost!): ","Su shtuan anëtarë (vhost joekzistuese!): "}.
{"Members:","Anëtarë:"}.
{"Membership is required to enter this room","Lypset anëtarësim për të hyrë në këtë dhomë"}.
{"Memory","Kujtesë"}.
{"Message body","Lëndë mesazhi"}.
{"Messages from strangers are rejected","Mesazhet prej të panjohurish hidhen tej"}.
{"Messages of type headline","Mesazhe të llojit titull"}.
{"Messages of type normal","Mesazhe të llojit normal"}.
{"Middle Name","Emër i Dytë"}.
{"Moderator privileges required","Lypset privilegj moderatori"}.
{"Moderator","Moderator"}.
{"Moderators Only","Vetëm Moderatorët"}.
{"Module failed to handle the query","Moduli sarrii të trajtonte kërkesën"}.
{"Monday","E hënë"}.
{"Multicast","Multikast"}.
{"Multi-User Chat","Fjalosje Me Shumë Përdorues Njëherësh"}.
{"Name","Emër"}.
{"Name:","Emër:"}.
{"Natural-Language Room Name","Emër Dhome Në Gjuhë Natyrale"}.
{"Never","Kurrë"}.
{"New Password:","Fjalëkalim i Ri:"}.
{"Nickname can't be empty","Nofka smund të jetë e zbrazët"}.
{"Nickname Registration at ","Regjistrim Nofke te "}.
{"Nickname ~s does not exist in the room","Në këtë dhomë sekziston nofka ~s"}.
{"Nickname","Nofkë"}.
{"No address elements found","Su gjetën elementë adrese"}.
{"No addresses element found","Su gjetën elementë adresash"}.
{"No child elements found","Su gjetën elementë pjella"}.
{"No Data","Ska të Dhëna"}.
{"No items found in this query","Su gjetën objekte në këtë kërkesë"}.
{"No limit","Pa kufi"}.
{"No node specified","Su përcaktua nyjë"}.
{"No pending subscriptions found","Su gjetën pajtime pezull"}.
{"No privacy list with this name found","Su gjet listë privatësie me atë emër"}.
{"No running node found","Su gjet nyjë në funksionim"}.
{"No services available","Ska shërbime të gatshme"}.
{"No statistics found for this item","Su gjetën statistika për këtë objekt"}.
{"Nobody","Askush"}.
{"Node already exists","Nyja ekziston tashmë"}.
{"Node ID","ID Nyjeje"}.
{"Node index not found","Su gjet tregues nyje"}.
{"Node not found","Su gjet nyjë"}.
{"Node ~p","Nyjë ~p"}.
{"Nodes","Nyja"}.
{"None","Asnjë"}.
{"Not allowed","E palejuar"}.
{"Not Found","Su Gjet"}.
{"Not subscribed","Jo i pajtuar"}.
{"November","Nëntor"}.
{"Number of answers required","Numër përgjigjesh të domosdoshme"}.
{"Number of occupants","Numër të pranishmish"}.
{"Number of Offline Messages","Numër Mesazhesh Jo Në Linjë"}.
{"Number of online users","Numër përdoruesish në linjë"}.
{"Number of registered users","Numër përdoruesish të regjistruar"}.
{"Occupants are allowed to invite others","Të pranishmëve u është lejuar të ftojnë të tjerë"}.
{"Occupants May Change the Subject","Të pranishmit Mund të Ndryshojnë Subjektin"}.
{"October","Tetor"}.
{"Offline Messages","Mesazhe Jo Në Linjë"}.
{"Offline Messages:","Mesazhe Jo Në Linjë:"}.
{"OK","OK"}.
{"Old Password:","Fjalëkalimi i Vjetër:"}.
{"Online Users","Përdorues Në Linjë"}.
{"Online Users:","Përdorues Në Linjë:"}.
{"Online","Në linjë"}.
{"Only admins can see this","Këtë mund ta shohin vetëm përgjegjësit"}.
{"Only deliver notifications to available users","Dorëzo njoftime vetëm te përdoruesit e pranishëm"}.
{"Only occupants are allowed to send messages to the conference","Vetëm të pranishmëve u lejohet të dërgojnë mesazhe te konferenca"}.
{"Only publishers may publish","Vetëm botuesit mund të botojnë"}.
{"Organization Name","Emër Enti"}.
{"Organization Unit","Njësi Organizative"}.
{"Outgoing s2s Connections","Lidhje s2s Ikëse"}.
{"Outgoing s2s Connections:","Lidhje s2s Ikëse:"}.
{"Owner privileges required","Lypset privilegje të zoti"}.
{"Packet","Paketë"}.
{"Participant","Pjesëmarrës"}.
{"Password Verification","Verifikim Fjalëkalimi"}.
{"Password Verification:","Verifikim Fjalëkalimi:"}.
{"Password","Fjalëkalim"}.
{"Password:","Fjalëkalim:"}.
{"Path to Dir","Shteg për te Drejtori"}.
{"Path to File","Shteg për te Kartelë"}.
{"Payload type","Lloj ngarkese"}.
{"Pending","Pezull"}.
{"Period: ","Periudhë: "}.
{"Ping","Ping"}.
{"Pong","Pong"}.
{"Previous session not found","Su gjet sesion i mëparshëm"}.
{"Previous session PID is dead","PID e sesionit të mëparshëm është e asgjësuar"}.
{"Previous session timed out","Sesionit të mëparshëm i mbaroi koha"}.
{"private, ","private, "}.
{"RAM and disc copy","RAM dhe kopje në disk"}.
{"RAM copy","Kopje në RAM"}.
{"Really delete message of the day?","Të fshihet vërtet mesazhi i ditës?"}.
{"Recipient is not in the conference room","Pjesëmarrësi s’është në dhomën e konferencës"}.
{"Register an XMPP account","Regjistroni një llogari XMPP"}.
{"Registered Users","Përdorues të Regjistruar"}.
{"Registered Users:","Përdorues të Regjistruar:"}.
{"Register","Regjistrohuni"}.
{"Remote copy","Kopje e largët"}.
{"Remove All Offline Messages","Hiq Krejt Mesazhet Jo Në Linjë"}.
{"Remove User","Hiqeni Përdoruesin"}.
{"Remove","Hiqe"}.
{"Replaced by new connection","Zëvendësuar nga lidhje e re"}.
{"Request has timed out","Kërkesës i mbaroi koha"}.
{"Request is ignored","Kërkesa u shpërfill"}.
{"Requested role","Rol i domosdoshëm"}.
{"Resources","Burime"}.
{"Restart Service","Rinise Shërbimin"}.
{"Restart","Rinise"}.
{"Restore","Riktheje"}.
{"Roles that May Send Private Messages","Role që Mund të Dërgojnë Mesazhe Private"}.
{"Room Configuration","Formësim Dhome"}.
{"Room description","Përshkrim i dhomës"}.
{"Room Occupants","Të pranishëm Në Dhomë"}.
{"Room title","Titull dhome"}.
{"RPC Call Error","Gabim Thirrjeje RPC"}.
{"Running Nodes","Nyje Në Punë"}.
{"Saturday","E shtunë"}.
{"Search from the date","Kërko nga data"}.
{"Search Results for ","Përfundime Kërkimi për "}.
{"Search the text","Kërkoni për tekst"}.
{"Search until the date","Kërko deri më datën"}.
{"Search users in ","Kërko përdorues te "}.
{"Select All","Përzgjidheni Krejt"}.
{"Send announcement to all users","Dërgo njoftim krejt përdoruesve"}.
{"September","Shtator"}.
{"Server:","Shërbyes:"}.
{"Show Integral Table","Shfaq Tabelë të Plotë"}.
{"Show Ordinary Table","Shfaq Tabelë të Rëndomtë"}.
{"Shut Down Service","Fike Shërbimin"}.
{"Specify the access model","Specifikoni model hyrjeje"}.
{"Specify the event message type","Përcaktoni llojin e mesazhit për aktin"}.
{"Specify the publisher model","Përcaktoni model botuesi"}.
{"Statistics of ~p","Statistika për ~p"}.
{"Statistics","Statistika"}.
{"Stop","Ndale"}.
{"Stopped Nodes","Nyja të Ndalura"}.
{"Storage Type","Lloj Depozitimi"}.
{"Subject","Subjekti"}.
{"Submit","Parashtrojeni"}.
{"Submitted","Parashtruar"}.
{"Subscriber Address","Adresë e Pajtimtarit"}.
{"Subscription","Pajtim"}.
{"Sunday","E diel"}.
{"The account already exists","Ka tashmë një llogari të tillë"}.
{"The account was not unregistered","Llogaria sqe çregjistruar"}.
{"The CAPTCHA is valid.","Kaptça është e vlefshme."}.
{"The default language of the node","Gjuha parazgjedhje e nyjës"}.
{"The feature requested is not supported by the conference","Veçoria e kërkuar nuk mbulohen nga konferenca"}.
{"The JID of the node creator","JID i krijjuesit të nyjës"}.
{"The name of the node","Emri i nyjës"}.
{"The number of subscribers to the node","Numri i pajtimtarëve te nyja"}.
{"The number of unread or undelivered messages","Numri i mesazheve të palexuar ose të padorëzuar"}.
{"The password is too weak","Fjalëkalimi është shumë i dobët"}.
{"the password is","fjalëkalimi është"}.
{"The password of your XMPP account was successfully changed.","Fjalëkalimi i llogarisë tuaj XMPP u ndryshua me sukses."}.
{"The password was not changed","Fjalëkalimi su ndryshua"}.
{"The passwords are different","Fjalëkalimet janë të ndryshëm"}.
{"The sender of the last received message","Dërguesi i mesazhit të fundit të marrë"}.
{"The username is not valid","Emri i përdoruesit s’është i vlefshëm"}.
{"There was an error changing the password: ","Pati një gabim në ndryshimin e fjalëkalimit: "}.
{"There was an error creating the account: ","Pati një gabim në krijimin e llogarisë: "}.
{"This room is not anonymous","Kjo dhomë s’është anonime"}.
{"Thursday","E enjte"}.
{"Time delay","Vonesë kohore"}.
{"Time","Kohë"}.
{"Too many CAPTCHA requests","Shumë kërkesa ndaj CAPTCHA-s"}.
{"Too many child elements","Shumë elementë pjella"}.
{"Too many <item/> elements","Shumë elementë <item/>"}.
{"Too many <list/> elements","Shumë elementë <list/>"}.
{"Too many users in this conference","Shumë përdorues në këtë konferencë"}.
{"Total rooms","Dhoma gjithsej"}.
{"Tuesday","E martë"}.
{"Unable to generate a CAPTCHA","Sarrihet të prodhohet një CAPTCHA"}.
{"Unauthorized","E paautorizuar"}.
{"Unexpected action","Veprim i papritur"}.
{"Unregister an XMPP account","Çregjistroni një llogari XMPP"}.
{"Unregister","Çregjistrohuni"}.
{"Unselect All","Shpërzgjidhi Krejt"}.
{"Unsupported version","Version i pambuluar"}.
{"Update","Përditësoje"}.
{"Uptime:","Kohëpunim:"}.
{"User already exists","Ka tashmë një përdorues të tillë"}.
{"User JID","JID përdoruesi"}.
{"User (jid)","Përdorues (jid)"}.
{"User Management","Administrim Përdoruesish"}.
{"User removed","Përdoruesi u hoq"}.
{"User session not found","Su gjet sesion përdoruesi"}.
{"User session terminated","Sesioni i përdoruesit përfundoi"}.
{"Username:","Emër përdoruesi:"}.
{"User","Përdorues"}.
{"Users Last Activity","Veprimtaria e Fundit Nga Përdorues"}.
{"Users","Përdorues"}.
{"Validate","Vleftësoje"}.
{"View Queue","Shihni Radhën"}.
{"Virtual Hosts","Streha Virtuale"}.
{"Visitor","Vizitor"}.
{"Wednesday","E mërkurë"}.
{"When a new subscription is processed","Kur përpunohet një pajtim i ri"}.
{"Whether to allow subscriptions","Nëse duhen lejuar apo jo pajtime"}.
{"Wrong parameters in the web formulary","Parametër i gabuar në formular web"}.
{"XMPP Account Registration","Regjistrim Llogarish XMPP"}.
{"XMPP Domains","Përkatësi XMPP"}.
{"You are not joined to the channel","Skeni hyrë te kanali"}.
{"You have been banned from this room","Jeni dëbuar prej kësaj dhome"}.
{"You have joined too many conferences","Keni hyrë në shumë konferenca"}.
{"Your XMPP account was successfully registered.","Llogaria juaj XMPP u regjistrua me sukses."}.
{"Your XMPP account was successfully unregistered.","Llogaria juaj XMPP u çregjistrua me sukses."}.
{"You're not allowed to create nodes","Skeni leje të krijoni nyja"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," har satt ämnet till: "}.
{"A friendly name for the node","Ett vänligt namn for noden"}.
{"Access denied by service policy","Åtkomst nekad enligt lokal policy"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," ตั้งหัวข้อว่า: "}.
{"Access denied by service policy","การเข้าถึงถูกปฏิเสธโดยนโยบายการบริการ"}.
{"Action on user","การดำเนินการกับผู้ใช้"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," konuyu değiştirdi: "}.
{"A friendly name for the node","Düğüm için dostane bir isim"}.
{"A password is required to enter this room","Bu odaya girmek için parola gerekiyor"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," встановив(ла) тему: "}.
{"A friendly name for the node","Псевдонім для вузла"}.
{"A password is required to enter this room","Щоб зайти в цю конференцію, необхідно ввести пароль"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," đã đặt chủ đề thành: "}.
{"Access denied by service policy","Sự truy cập bị chặn theo chính sách phục vụ"}.
{"Action on user","Hành động đối với người sử dụng"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" has set the subject to: "," a candjî l' tite a: "}.
{"A friendly name for the node","On no uzeu-ahessåve pol nuk"}.
{"A password is required to enter this room","I fåt dner on scret po poleur intrer dins cisse såle ci"}.
+5 -1
View File
@@ -1,4 +1,8 @@
%% -*- coding: utf-8 -*-
%% Generated automatically
%% DO NOT EDIT: run `make translations` instead
%% To improve translations please read:
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (在字段末添加*来匹配子串)"}.
{" has set the subject to: ","已将标题设置为: "}.
{"# participants","# 个参与人"}.
+64 -27
View File
@@ -19,48 +19,48 @@
%%%----------------------------------------------------------------------
{deps, [{base64url, ".*", {git, "https://github.com/dvv/base64url", {tag, "1.0.1"}}},
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.27"}}},
{eimp, ".*", {git, "https://github.com/processone/eimp", {tag, "1.0.19"}}},
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", {tag, "1.0.29"}}},
{eimp, ".*", {git, "https://github.com/processone/eimp", {tag, "1.0.21"}}},
{if_var_true, tools,
{ejabberd_po, ".*", {git, "https://github.com/processone/ejabberd-po", {branch, "main"}}}},
{if_var_true, elixir,
{elixir, ".*", {git, "https://github.com/elixir-lang/elixir", {tag, "v1.4.4"}}}},
{if_var_true, pam,
{epam, ".*", {git, "https://github.com/processone/epam", {tag, "1.0.10"}}}},
{epam, ".*", {git, "https://github.com/processone/epam", {tag, "1.0.12"}}}},
{if_var_true, redis,
{eredis, ".*", {git, "https://github.com/wooga/eredis", {tag, "v1.0.8"}}}},
{eredis, ".*", {git, "https://github.com/wooga/eredis", {tag, "v1.2.0"}}}},
{if_var_true, sip,
{esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.41"}}}},
{esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.43"}}}},
{if_var_true, zlib,
{ezlib, ".*", {git, "https://github.com/processone/ezlib", {tag, "1.0.9"}}}},
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.1.11"}}},
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.45"}}},
{fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.30"}}},
{ezlib, ".*", {git, "https://github.com/processone/ezlib", {tag, "1.0.10"}}}},
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.1.13"}}},
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.47"}}},
{fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.32"}}},
{idna, ".*", {git, "https://github.com/benoitc/erlang-idna", {tag, "6.0.0"}}},
{jiffy, ".*", {git, "https://github.com/davisp/jiffy", {tag, "1.0.5"}}},
{jose, ".*", {git, "https://github.com/potatosalad/erlang-jose", {tag, "1.9.0"}}},
{lager, ".*", {git, "https://github.com/erlang-lager/lager", {tag, "3.6.10"}}},
{if_var_true, tools,
{lager, ".*", {git, "https://github.com/erlang-lager/lager", {tag, "3.9.1"}}},
{if_var_true, lua,
{luerl, ".*", {git, "https://github.com/rvirding/luerl", {tag, "v0.3"}}}},
{mqtree, ".*", {git, "https://github.com/processone/mqtree", {tag, "1.0.12"}}},
{p1_acme, ".*", {git, "https://github.com/processone/p1_acme", {tag, "1.0.11"}}},
{mqtree, ".*", {git, "https://github.com/processone/mqtree", {tag, "1.0.14"}}},
{p1_acme, ".*", {git, "https://github.com/processone/p1_acme", {tag, "1.0.13"}}},
{if_var_true, mysql,
{p1_mysql, ".*", {git, "https://github.com/processone/p1_mysql", {tag, "1.0.17"}}}},
{p1_oauth2, ".*", {git, "https://github.com/processone/p1_oauth2", {tag, "0.6.8"}}},
{p1_mysql, ".*", {git, "https://github.com/processone/p1_mysql", {tag, "1.0.19"}}}},
{p1_oauth2, ".*", {git, "https://github.com/processone/p1_oauth2", {tag, "0.6.10"}}},
{if_var_true, pgsql,
{p1_pgsql, ".*", {git, "https://github.com/processone/p1_pgsql", {tag, "1.1.10"}}}},
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.21"}}},
{pkix, ".*", {git, "https://github.com/processone/pkix", {tag, "1.0.7"}}},
{p1_pgsql, ".*", {git, "https://github.com/processone/p1_pgsql", {tag, "1.1.12"}}}},
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.23"}}},
{pkix, ".*", {git, "https://github.com/processone/pkix", {tag, "1.0.8"}}},
{if_not_rebar3, %% Needed because modules are not fully migrated to new structure and mix
{if_var_true, elixir,
{rebar_elixir_plugin, ".*", {git, "https://github.com/processone/rebar_elixir_plugin", "0.1.0"}}}},
{if_var_true, sqlite,
{sqlite3, ".*", {git, "https://github.com/processone/erlang-sqlite3", {tag, "1.1.11"}}}},
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.24"}}},
{sqlite3, ".*", {git, "https://github.com/processone/erlang-sqlite3", {tag, "1.1.13"}}}},
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.27"}}},
{if_var_true, stun,
{stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.42"}}}},
{xmpp, ".*", {git, "https://github.com/processone/xmpp", {tag, "1.5.2"}}},
{yconf, ".*", {git, "https://github.com/processone/yconf", {tag, "1.0.10"}}}
{stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.44"}}}},
{xmpp, ".*", {git, "https://github.com/processone/xmpp", {tag, "1.5.4"}}},
{yconf, ".*", {git, "https://github.com/processone/yconf", {tag, "1.0.12"}}}
]}.
{gitonly_deps, [elixir, luerl]}.
@@ -96,25 +96,25 @@
{if_version_above, "20", {d, 'DEPRECATED_GET_STACKTRACE'}},
{if_version_below, "21", {d, 'USE_OLD_HTTP_URI'}},
{if_version_below, "22", {d, 'LAGER'}},
{if_version_below, "21", {d, 'NO_CUSTOMIZE_HOSTNAME_CHECK'}},
{if_version_below, "23", {d, 'USE_OLD_CRYPTO_HMAC'}},
{if_version_below, "23", {d, 'USE_OLD_PG2'}},
{if_version_below, "24", {d, 'COMPILER_REPORTS_ONLY_LINES'}},
{if_version_below, "24", {d, 'SYSTOOLS_APP_DEF_WITHOUT_OPTIONAL'}},
{if_var_match, db_type, mssql, {d, 'mssql'}},
{if_var_false, debug, no_debug_info},
{if_var_true, debug, debug_info},
{if_var_true, elixir, {d, 'ELIXIR_ENABLED'}},
{if_var_true, hipe, native},
{if_var_true, new_sql_schema, {d, 'NEW_SQL_SCHEMA'}},
{if_var_true, roster_gateway_workaround, {d, 'ROSTER_GATWAY_WORKAROUND'}},
{if_var_true, sip, {d, 'SIP'}},
{if_var_true, stun, {d, 'STUN'}},
{if_have_fun, {erl_error, format_exception, 6}, {d, 'HAVE_ERL_ERROR'}},
{if_rebar3, {extra_src_dirs, [sql]}},
{src_dirs, [src,
{if_rebar3, sql},
{if_var_true, tools, tools},
{if_var_true, elixir, include}]}]}.
{deps_erl_opts, [{if_var_true, hipe, native}]}.
{if_rebar3, {plugins, [rebar3_hex, {provider_asn1, "0.2.0"}]}}.
{if_rebar3, {project_plugins, [configure_deps]}}.
{if_not_rebar3, {plugins, [
@@ -156,6 +156,8 @@
{cover_enabled, true}.
{cover_export_enabled, true}.
{coveralls_coverdata, "_build/test/cover/ct.coverdata"}.
{coveralls_service_name, "github"}.
{recursive_cmds, ['configure-deps']}.
{overrides, [
@@ -170,6 +172,41 @@
{"fast_yaml", []},
{"stringprep", []}]}.
{relx, [{release, {ejabberd, {cmd, "grep {vsn, vars.config | sed 's|{vsn, \"||;s|\"}.||' | tr -d '\012'"}},
[ejabberd]},
{sys_config, "./rel/sys.config"},
{vm_args, "./rel/vm.args"},
{overlay_vars, "vars.config"},
{extended_start_script, true},
{overlay, [{mkdir, "var/log/ejabberd"},
{mkdir, "var/lock"},
{mkdir, "var/lib/ejabberd"},
{mkdir, "etc/ejabberd"},
{copy, "rel/files/erl", "\{\{erts_vsn\}\}/bin/erl"}, % in rebar2 this prepends erts-
{template, "ejabberdctl.template", "bin/ejabberdctl"},
{copy, "inetrc", "etc/ejabberd/inetrc"},
{copy, "tools/captcha*.sh", "lib/ejabberd-\{\{release_version\}\}/priv/bin/"},
{copy, "rel/files/install_upgrade.escript", "bin/install_upgrade.escript"}]}
]}.
{profiles, [{prod, [{relx, [{debug_info, strip},
{dev_mode, false},
{include_erts, true},
{include_src, true},
{overlay, [{copy, "sql/*", "lib/ejabberd-\{\{release_version\}\}/priv/sql/"},
{copy, "ejabberdctl.cfg.example", "etc/ejabberd/ejabberdctl.cfg"},
{copy, "ejabberd.yml.example", "etc/ejabberd/ejabberd.yml"}]}]}]},
{dev, [{post_hooks, [{release, "rel/setup-dev.sh"}]},
{relx, [{debug_info, keep},
{dev_mode, true},
{include_erts, true},
{include_src, false},
{overlay, [{copy, "ejabberdctl.cfg.example", "etc/ejabberd/ejabberdctl.cfg.example"},
{copy, "ejabberd.yml.example", "etc/ejabberd/ejabberd.yml.example"},
{copy, "test/ejabberd_SUITE_data/ca.pem", "etc/ejabberd/"},
{copy, "test/ejabberd_SUITE_data/cert.pem", "etc/ejabberd/"}]}]}]},
{test, [{erl_opts, [nowarn_export_all]}]}]}.
%% Local Variables:
%% mode: erlang
%% End:
+46 -16
View File
@@ -339,17 +339,44 @@ fun(Deps, FDeps) ->
end, Deps)
end,
TravisPostHooks =
fun(true) ->
[{eunit, "echo '\n%%! -pa .eunit/ deps/coveralls/ebin\n" ++
"main(_)->{ok,F}=file:open(\"erlang.json\",[write])," ++
"io:fwrite(F,\"~s\",[coveralls:convert_file(" ++
"\".eunit/cover.coverdata\", \"" ++
os:getenv("TRAVIS_JOB_ID") ++
"\", \"travis-ci\",\"\")]).' > getcover.erl"},
{eunit, "escript ./getcover.erl"}];
(_) ->
[]
VarsApps = case file:consult(filename:join([filename:dirname(SCRIPT),"vars.config"])) of
{ok, TermsV} ->
case proplists:get_bool(odbc, TermsV) of
true -> [odbc];
false -> []
end;
_->
[]
end,
ProcessRelx = fun(Relx, Deps) ->
{value, {release, NameVersion, DefaultApps}, RelxTail} = lists:keytake(release, 1, Relx),
ProfileApps = case os:getenv("REBAR_PROFILE") of
"dev" -> [observer, runtime_tools, wx, debugger];
_ -> []
end,
DepApps = lists:map(fun({DepName, _, _}) -> DepName;
({DepName, _}) -> DepName
end, Deps),
[{release, NameVersion, DefaultApps ++ VarsApps ++ ProfileApps ++ DepApps} | RelxTail]
end,
GithubConfig = case {os:getenv("GITHUB_ACTIONS"), os:getenv("GITHUB_TOKEN")} of
{"true", Token} when is_list(Token) ->
CONFIG1 = [{coveralls_repo_token, Token},
{coveralls_service_job_id, os:getenv("GITHUB_RUN_ID")},
{coveralls_commit_sha, os:getenv("GITHUB_SHA")},
{coveralls_service_number, os:getenv("GITHUB_RUN_NUMBER")}],
case os:getenv("GITHUB_EVENT_NAME") =:= "pull_request"
andalso string:tokens(os:getenv("GITHUB_REF"), "/") of
[_, "pull", PRNO, _] ->
[{coveralls_service_pull_request, PRNO} | CONFIG1];
_ ->
CONFIG1
end;
_ ->
[]
end,
Rules = [
@@ -358,10 +385,10 @@ Rules = [
{compile, {asn, compile}},
{clean, {asn, clean}}
]}]), []},
{[deps], os:getenv("TRAVIS") == "true",
AppendList([{coveralls, ".*", {git, "https://github.com/markusn/coveralls-erl", {tag, "v2.0.1"}}}]), []},
{[post_hooks], [cover_enabled], os:getenv("TRAVIS") == "true",
AppendList2(TravisPostHooks), [], false},
{[plugins], IsRebar3 and (os:getenv("GITHUB_ACTIONS") == "true"),
AppendList([{coveralls, {git,
"https://github.com/RoadRunnr/coveralls-erl.git",
{branch, "feature/git-info"}}} ]), []},
{[overrides], [post_hook_configure], SystemDeps == false,
AppendList2(GenDepsConfigure), [], []},
{[ct_extra_params], [eunit_compile_opts], true,
@@ -370,6 +397,8 @@ Rules = [
ProcessErlOpt, []},
{[xref_queries], [xref_exclusions], true,
AppendList2(ProcssXrefExclusions), [], []},
{[relx], [deps], IsRebar3,
ProcessRelx, [], []},
{[deps], [floating_deps], true,
ProcessFloatingDeps, [], []},
{[deps], [gitonly_deps], IsRebar3,
@@ -379,7 +408,8 @@ Rules = [
],
Config = [{plugin_dir, filename:join([filename:dirname(SCRIPT),"plugins"])}]++
FilterConfig(ProcessVars(CONFIG, []), Rules),
FilterConfig(ProcessVars(CONFIG, []), Rules)++
GithubConfig,
%io:format("ejabberd configuration:~n ~p~n", [Config]),
Executable
BIN
View File
Binary file not shown.
+28
View File
@@ -0,0 +1,28 @@
echo -n "===> Preparing dev configuration files: "
PWD_DIR=`pwd`
REL_DIR=$PWD_DIR/_build/dev/rel/ejabberd/
CON_DIR=$REL_DIR/etc/ejabberd/
[ -z "$REL_DIR_TEMP" ] && REL_DIR_TEMP=$REL_DIR
CON_DIR_TEMP=$REL_DIR_TEMP/etc/ejabberd/
BIN_DIR_TEMP=$REL_DIR_TEMP/bin/
cd $CON_DIR_TEMP
sed -i "s|# certfiles:|certfiles:\n - $CON_DIR/cert.pem|g" ejabberd.yml.example
sed -i "s|certfiles:|ca_file: $CON_DIR/ca.pem\ncertfiles:|g" ejabberd.yml.example
sed -i 's|^acl:$|acl:\n admin: [user: admin]|g' ejabberd.yml.example
[ ! -f "$CON_DIR/ejabberd.yml" ] \
&& echo -n "ejabberd.yml " \
&& mv ejabberd.yml.example ejabberd.yml
sed -i "s|#' POLL|EJABBERD_BYPASS_WARNINGS=true\n\n#' POLL|g" ejabberdctl.cfg.example
[ ! -f "$CON_DIR/ejabberdctl.cfg" ] \
&& echo -n "ejabberdctl.cfg " \
&& mv ejabberdctl.cfg.example ejabberdctl.cfg
echo ""
echo "===> Some example ways to start this ejabberd dev:"
echo " _build/dev/rel/ejabberd/bin/ejabberd console"
echo " _build/dev/rel/ejabberd/bin/ejabberdctl live"
+2
View File
@@ -0,0 +1,2 @@
[{ejabberd, [{config, "etc/ejabberd/ejabberd.yml"},
{log_path, "var/log/ejabberd/ejabberd.log"}]}].
+32
View File
@@ -0,0 +1,32 @@
## Name of the node
-sname ejabberd@localhost
## Cookie for distributed erlang
#-setcookie ejabberd
-mnesia dir \"var/lib/ejabberd\"
## Heartbeat management; auto-restarts VM if it dies or becomes unresponsive
## (Disabled by default..use with caution!)
##-heart
## Enable kernel poll and a few async threads
##+K true
##+A 5
## Increase number of concurrent ports/sockets
##-env ERL_MAX_PORTS 4096
## Tweak GC to run more often
##-env ERL_FULLSWEEP_AFTER 10
# +B [c | d | i]
# Option c makes Ctrl-C interrupt the current shell instead of invoking the emulator break
# handler. Option d (same as specifying +B without an extra option) disables the break handler. # Option i makes the emulator ignore any break signal.
# If option c is used with oldshell on Unix, Ctrl-C will restart the shell process rather than
# interrupt it.
# Disable the emulator break handler
# it easy to accidentally type ctrl-c when trying
# to reach for ctrl-d. ctrl-c on a live node can
# have very undesirable results
##+Bi
+14
View File
@@ -0,0 +1,14 @@
## Customize flags given to the VM: https://erlang.org/doc/man/erl.html
## -mode/-name/-sname/-setcookie are configured via env vars, do not set them here
-boot ../releases/<%= @version %>/start_clean
-boot_var RELEASE_LIB ../lib
## Number of dirty schedulers doing IO work (file, sockets, and others)
##+SDio 5
## Increase number of concurrent ports/sockets
##+Q 65536
## Tweak GC to run more often
##-env ERL_FULLSWEEP_AFTER 10
+3
View File
@@ -73,6 +73,8 @@ CREATE TABLE sr_group (
PRIMARY KEY (server_host, name)
);
CREATE UNIQUE INDEX i_sr_group_sh_name ON sr_group (server_host, name);
CREATE TABLE sr_user (
jid text NOT NULL,
server_host text NOT NULL,
@@ -81,6 +83,7 @@ CREATE TABLE sr_user (
PRIMARY KEY (server_host, jid, grp)
);
CREATE UNIQUE INDEX i_sr_user_sh_jid_grp ON sr_user (server_host, jid, grp);
CREATE INDEX i_sr_user_sh_jid ON sr_user (server_host, jid);
CREATE INDEX i_sr_user_sh_grp ON sr_user (server_host, grp);
+2
View File
@@ -65,6 +65,8 @@ CREATE TABLE sr_group (
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE UNIQUE INDEX i_sr_group_name ON sr_group (name);
CREATE TABLE sr_user (
jid text NOT NULL,
grp text NOT NULL,
+20
View File
@@ -544,3 +544,23 @@ WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW
CREATE UNIQUE INDEX [i_push_ut] ON [push_session] (username, timestamp)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);
CREATE TABLE [dbo].[mqtt_pub](
[username] [varchar](191) NOT NULL,
[server_host] [varchar](191) NOT NULL,
[resource] [varchar](191) NOT NULL,
[topic] [varchar](191) NOT NULL,
[qos] [tinyint] NOT NULL,
[payload] [varbinary](max) NOT NULL,
[payload_format] [tinyint] NOT NULL,
[content_type] [text] NOT NULL,
[response_topic] [text] NOT NULL,
[correlation_data] [varbinary](max) NOT NULL,
[user_properties] [varbinary](max) NOT NULL,
[expiry] [int] NOT NULL,
CONSTRAINT [i_mqtt_topic_server] PRIMARY KEY CLUSTERED
(
[topic] ASC,
[server_host] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY];
+7 -4
View File
@@ -20,8 +20,8 @@ CREATE TABLE users (
username varchar(191) NOT NULL,
server_host varchar(191) NOT NULL,
password text NOT NULL,
serverkey varchar(64) NOT NULL DEFAULT '',
salt varchar(64) NOT NULL DEFAULT '',
serverkey varchar(128) NOT NULL DEFAULT '',
salt varchar(128) NOT NULL DEFAULT '',
iterationcount integer NOT NULL DEFAULT 0,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (server_host(191), username)
@@ -76,6 +76,8 @@ CREATE TABLE sr_group (
PRIMARY KEY (server_host(191), name)
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE UNIQUE INDEX i_sr_group_sh_name ON sr_group(server_host(191), name);
CREATE TABLE sr_user (
jid varchar(191) NOT NULL,
server_host varchar(191) NOT NULL,
@@ -84,6 +86,7 @@ CREATE TABLE sr_user (
PRIMARY KEY (server_host(191), jid, grp)
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE UNIQUE INDEX i_sr_user_sh_jid_group ON sr_group(server_host(191), jid, grp);
CREATE INDEX i_sr_user_sh_jid ON sr_user(server_host(191), jid);
CREATE INDEX i_sr_user_sh_grp ON sr_user(server_host(191), grp);
@@ -430,7 +433,7 @@ CREATE TABLE push_session (
node text NOT NULL,
xml text NOT NULL,
PRIMARY KEY (server_host(191), username(191), timestamp)
);
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE UNIQUE INDEX i_push_session_susn ON push_session (server_host(191), username(191), service(191), node(191));
@@ -502,4 +505,4 @@ CREATE TABLE mqtt_pub (
user_properties blob NOT NULL,
expiry int unsigned NOT NULL,
UNIQUE KEY i_mqtt_topic_server (topic(191), server_host)
);
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+6 -4
View File
@@ -19,8 +19,8 @@
CREATE TABLE users (
username varchar(191) PRIMARY KEY,
password text NOT NULL,
serverkey varchar(64) NOT NULL DEFAULT '',
salt varchar(64) NOT NULL DEFAULT '',
serverkey varchar(128) NOT NULL DEFAULT '',
salt varchar(128) NOT NULL DEFAULT '',
iterationcount integer NOT NULL DEFAULT 0,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
@@ -68,6 +68,8 @@ CREATE TABLE sr_group (
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE UNIQUE INDEX i_sr_group_name ON sr_group(name);
CREATE TABLE sr_user (
jid varchar(191) NOT NULL,
grp varchar(191) NOT NULL,
@@ -398,7 +400,7 @@ CREATE TABLE push_session (
service text NOT NULL,
node text NOT NULL,
xml text NOT NULL
);
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE UNIQUE INDEX i_push_usn ON push_session (username(191), service(191), node(191));
CREATE UNIQUE INDEX i_push_ut ON push_session (username(191), timestamp);
@@ -469,4 +471,4 @@ CREATE TABLE mqtt_pub (
user_properties blob NOT NULL,
expiry int unsigned NOT NULL,
UNIQUE KEY i_mqtt_topic (topic(191))
);
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+3
View File
@@ -218,6 +218,8 @@ CREATE TABLE sr_group (
PRIMARY KEY (server_host, name)
);
CREATE UNIQUE INDEX i_sr_group_sh_name ON sr_group USING btree (server_host, name);
CREATE TABLE sr_user (
jid text NOT NULL,
server_host text NOT NULL,
@@ -226,6 +228,7 @@ CREATE TABLE sr_user (
PRIMARY KEY (server_host, jid, grp)
);
CREATE UNIQUE INDEX i_sr_user_sh_jid_grp ON sr_user USING btree (server_host, jid, grp);
CREATE INDEX i_sr_user_sh_jid ON sr_user USING btree (server_host, jid);
CREATE INDEX i_sr_user_sh_grp ON sr_user USING btree (server_host, grp);
+2
View File
@@ -69,6 +69,8 @@ CREATE TABLE sr_group (
created_at TIMESTAMP NOT NULL DEFAULT now()
);
CREATE UNIQUE INDEX i_sr_group_name ON sr_group USING btree (name);
CREATE TABLE sr_user (
jid text NOT NULL,
grp text NOT NULL,
+1
View File
@@ -25,6 +25,7 @@
-export([match_rules/4, match_acls/3]).
-export([access_rules_validator/0, access_validator/0]).
-export([validator/1, validators/0]).
-export([loaded_shared_roster_module/1]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
+36 -31
View File
@@ -553,37 +553,42 @@ hosts() ->
-spec vcard_temp() -> yconf:validator().
vcard_temp() ->
vcard_validator(
vcard_temp, undefined,
[{version, undefined, binary()},
{fn, undefined, binary()},
{n, undefined, vcard_name()},
{nickname, undefined, binary()},
{photo, undefined, vcard_photo()},
{bday, undefined, binary()},
{adr, [], list(vcard_adr())},
{label, [], list(vcard_label())},
{tel, [], list(vcard_tel())},
{email, [], list(vcard_email())},
{jabberid, undefined, binary()},
{mailer, undefined, binary()},
{tz, undefined, binary()},
{geo, undefined, vcard_geo()},
{title, undefined, binary()},
{role, undefined, binary()},
{logo, undefined, vcard_logo()},
{org, undefined, vcard_org()},
{categories, [], list(binary())},
{note, undefined, binary()},
{prodid, undefined, binary()},
{rev, undefined, binary()},
{sort_string, undefined, binary()},
{sound, undefined, vcard_sound()},
{uid, undefined, binary()},
{url, undefined, binary()},
{class, undefined, enum([confidential, private, public])},
{key, undefined, vcard_key()},
{desc, undefined, binary()}]).
and_then(
vcard_validator(
vcard_temp, undefined,
[{version, undefined, binary()},
{fn, undefined, binary()},
{n, undefined, vcard_name()},
{nickname, undefined, binary()},
{photo, undefined, vcard_photo()},
{bday, undefined, binary()},
{adr, [], list(vcard_adr())},
{label, [], list(vcard_label())},
{tel, [], list(vcard_tel())},
{email, [], list(vcard_email())},
{jabberid, undefined, binary()},
{mailer, undefined, binary()},
{tz, undefined, binary()},
{geo, undefined, vcard_geo()},
{title, undefined, binary()},
{role, undefined, binary()},
{logo, undefined, vcard_logo()},
{org, undefined, vcard_org()},
{categories, [], list(binary())},
{note, undefined, binary()},
{prodid, undefined, binary()},
{rev, undefined, binary()},
{sort_string, undefined, binary()},
{sound, undefined, vcard_sound()},
{uid, undefined, binary()},
{url, undefined, binary()},
{class, undefined, enum([confidential, private, public])},
{key, undefined, vcard_key()},
{desc, undefined, binary()}]),
fun(Tuple) ->
list_to_tuple(tuple_to_list(Tuple) ++ [[]])
end).
-spec vcard_name() -> yconf:validator().
vcard_name() ->
-17
View File
@@ -1,17 +0,0 @@
%% $Id$
{application, ejabberd,
[{description, "@PACKAGE_NAME@"},
{vsn, "@PACKAGE_VERSION@"},
{modules, []},
{registered, []},
{applications, [kernel, stdlib, sasl, ssl]},
{included_applications, [os_mon, lager, mnesia, inets, p1_utils, fast_yaml, fast_tls, pkix, xmpp, cache_tab, eimp]},
{env, [{enabled_backends, [@enabled_backends@]}]},
{mod, {ejabberd_app, []}}]}.
%% Local Variables:
%% mode: erlang
%% End:
%% vim: set filetype=erlang tabstop=8:
+37
View File
@@ -0,0 +1,37 @@
Vars = case file:consult(filename:join([filename:dirname(SCRIPT), "..", "vars.config"])) of
{ok, Terms} ->
Backends = [mssql, mysql, odbc, pgsql, redis, sqlite],
EBs = lists:filter(fun(Backend) -> lists:member({Backend, true}, Terms) end, Backends),
[lists:keyfind(description, 1, Terms),
lists:keyfind(vsn, 1, Terms),
{env, [{enabled_backends, EBs}]}
];
_Err ->
[]
end,
{application, ejabberd,
Vars ++
[{modules, []},
{registered, []},
{applications, [kernel, sasl, ssl, stdlib]},
{included_applications,
[inets, mnesia, os_mon,
cache_tab,
eimp,
fast_tls,
fast_xml,
fast_yaml,
lager,
p1_acme,
p1_utils,
pkix,
stringprep,
yconf,
xmpp]},
{mod, {ejabberd_app, []}}]}.
%% Local Variables:
%% mode: erlang
%% End:
%% vim: set filetype=erlang tabstop=8:
+35 -33
View File
@@ -46,6 +46,7 @@
code_change/3]).
-define(SERVER, ?MODULE).
-define(CACHE_TAB, access_permissions_cache).
-record(state,
{definitions = none :: none | [definition()]}).
@@ -71,17 +72,45 @@
%%%===================================================================
-spec can_access(atom(), caller_info()) -> allow | deny.
can_access(Cmd, CallerInfo) ->
gen_server:call(?MODULE, {can_access, Cmd, CallerInfo}).
Defs0 = show_current_definitions(),
CallerModule = maps:get(caller_module, CallerInfo, none),
Host = maps:get(caller_host, CallerInfo, global),
Tag = maps:get(tag, CallerInfo, none),
Defs = maps:get(extra_permissions, CallerInfo, []) ++ Defs0,
Res = lists:foldl(
fun({Name, _} = Def, none) ->
case matches_definition(Def, Cmd, CallerModule, Tag, Host, CallerInfo) of
true ->
?DEBUG("Command '~p' execution allowed by rule "
"'~ts' (CallerInfo=~p)", [Cmd, Name, CallerInfo]),
allow;
_ ->
none
end;
(_, Val) ->
Val
end, none, Defs),
case Res of
allow -> allow;
_ ->
?DEBUG("Command '~p' execution denied "
"(CallerInfo=~p)", [Cmd, CallerInfo]),
deny
end.
-spec invalidate() -> ok.
invalidate() ->
gen_server:cast(?MODULE, invalidate).
gen_server:cast(?MODULE, invalidate),
ets_cache:delete(?CACHE_TAB, definitions).
-spec show_current_definitions() -> [definition()].
show_current_definitions() ->
gen_server:call(?MODULE, show_current_definitions).
ets_cache:lookup(?CACHE_TAB, definitions,
fun() ->
{cache, gen_server:call(?MODULE, show_current_definitions)}
end).
start_link() ->
ets_cache:new(?CACHE_TAB, [{max_size, 2}]),
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
%%%===================================================================
@@ -90,38 +119,11 @@ start_link() ->
-spec init([]) -> {ok, state()}.
init([]) ->
ejabberd_hooks:add(config_reloaded, ?MODULE, invalidate, 90),
ets_cache:new(access_permissions),
{ok, #state{}}.
-spec handle_call({can_access, atom(), caller_info()} |
show_current_definitions | term(),
-spec handle_call(show_current_definitions | term(),
term(), state()) -> {reply, term(), state()}.
handle_call({can_access, Cmd, CallerInfo}, _From, State) ->
CallerModule = maps:get(caller_module, CallerInfo, none),
Host = maps:get(caller_host, CallerInfo, global),
Tag = maps:get(tag, CallerInfo, none),
{State2, Defs0} = get_definitions(State),
Defs = maps:get(extra_permissions, CallerInfo, []) ++ Defs0,
Res = lists:foldl(
fun({Name, _} = Def, none) ->
case matches_definition(Def, Cmd, CallerModule, Tag, Host, CallerInfo) of
true ->
?DEBUG("Command '~p' execution allowed by rule "
"'~ts' (CallerInfo=~p)", [Cmd, Name, CallerInfo]),
allow;
_ ->
none
end;
(_, Val) ->
Val
end, none, Defs),
Res2 = case Res of
allow -> allow;
_ ->
?DEBUG("Command '~p' execution denied "
"(CallerInfo=~p)", [Cmd, CallerInfo]),
deny
end,
{reply, Res2, State2};
handle_call(show_current_definitions, _From, State) ->
{State2, Defs} = get_definitions(State),
{reply, Defs, State2};
+8 -3
View File
@@ -282,8 +282,8 @@ get_commands_spec() ->
args = [{host, binary}], result = {res, rescode}},
#ejabberd_commands{name = import_prosody, tags = [mnesia, sql],
desc = "Import data from Prosody",
longdesc = "Note: this method requires ejabberd compiled with optional tools support "
"and package must provide optional luerl dependency.",
longdesc = "Note: this requires ejabberd compiled with --enable-lua "
"and include the optional 'luerl' library.",
module = prosody2ejabberd, function = from_dir,
args_desc = ["Full path to the Prosody data directory"],
args_example = ["/var/lib/prosody/datadump/"],
@@ -317,7 +317,10 @@ get_commands_spec() ->
#ejabberd_commands{name = export2sql, tags = [mnesia],
desc = "Export virtual host information from Mnesia tables to SQL file",
longdesc = "Configure the modules to use SQL, then call this command.",
longdesc = "Configure the modules to use SQL, then call this command. "
"After correctly exported the database of a vhost, "
"you may want to delete from mnesia with "
"the http://./#delete-mnesia[delete_mnesia] command.",
module = ejd2sql, function = export,
args_desc = ["Vhost", "Full path to the destination SQL file"],
args_example = ["example.com", "/var/lib/ejabberd/example.com.sql"],
@@ -393,10 +396,12 @@ get_commands_spec() ->
args = [], result = {res, rescode}},
#ejabberd_commands{name = gc, tags = [server],
desc = "Force full garbage collection",
note = "added in 20.01",
module = ?MODULE, function = gc,
args = [], result = {res, rescode}},
#ejabberd_commands{name = man, tags = [documentation],
desc = "Generate Unix manpage for current ejabberd version",
note = "added in 20.01",
module = ejabberd_doc, function = man,
args = [], result = {res, restuple}}
].
+1 -1
View File
@@ -880,7 +880,7 @@ get_priority_from_presence(#presence{priority = Prio}) ->
-spec route_multiple(state(), [jid()], stanza()) -> ok.
route_multiple(#{lserver := LServer}, JIDs, Pkt) ->
From = xmpp:get_from(Pkt),
ejabberd_router_multicast:route_multicast(From, LServer, JIDs, Pkt).
ejabberd_router_multicast:route_multicast(From, LServer, JIDs, Pkt, false).
get_subscription(#jid{luser = LUser, lserver = LServer}, JID) ->
{Subscription, _, _} = ejabberd_hooks:run_fold(
+10 -3
View File
@@ -83,6 +83,8 @@ md_tag(h2, V) ->
[<<"\n__">>, V, <<"__\n\n">>];
md_tag(strong, V) ->
[<<"*">>, V, <<"*">>];
md_tag('div', V) ->
[<<"<div class='note-down'>">>, V, <<"</div>">>];
md_tag(_, V) ->
V.
@@ -359,7 +361,7 @@ gen_param(Name, Type, Desc, HTMLOutput) ->
?TAG(dd, ?RAW(Desc))].
gen_doc(#ejabberd_commands{name=Name, tags=_Tags, desc=Desc, longdesc=LongDesc,
args=Args, args_desc=ArgsDesc,
args=Args, args_desc=ArgsDesc, note=Note,
result=Result, result_desc=ResultDesc}=Cmd, HTMLOutput, Langs) ->
try
ArgsText = case ArgsDesc of
@@ -387,8 +389,13 @@ gen_doc(#ejabberd_commands{name=Name, tags=_Tags, desc=Desc, longdesc=LongDesc,
[?TAG(dl, [gen_param(RName, Type, ResultDesc, HTMLOutput)])]
end
end,
NoteEl = case Note of
"" -> [];
_ -> ?TAG('div', "note-down", ?RAW(Note))
end,
[?TAG(h1, atom_to_list(Name)),
[NoteEl,
?TAG(h1, atom_to_list(Name)),
?TAG(p, ?RAW(Desc)),
case LongDesc of
"" -> [];
@@ -461,7 +468,7 @@ generate_md_output(File, RegExp, Languages) ->
Langs = binary:split(Languages, <<",">>, [global]),
Header = <<"---\ntitle: Administration API reference\ntoc: true\nmenu: Administration API\norder: 40\n"
"// Autogenerated with 'ejabberdctl gen_markdown_doc_for_commands'\n---\n\n"
"This section describes API of ejabberd version ", (ejabberd_option:version())/binary>>,
"This section describes API of ejabberd.">>,
Out = lists:map(fun(C) -> gen_doc(C, false, Langs) end, Cmds4),
{ok, Fh} = file:open(File, [write]),
io:format(Fh, "~ts~ts", [Header, Out]),
+156 -72
View File
@@ -174,27 +174,38 @@ process(["help" | Mode], Version) ->
{MaxC, ShCode} = get_shell_info(),
case Mode of
[] ->
print_usage(dual, MaxC, ShCode, Version),
?STATUS_USAGE;
print_usage_help(MaxC, ShCode),
?STATUS_SUCCESS;
["--dual"] ->
print_usage(dual, MaxC, ShCode, Version),
?STATUS_USAGE;
["--long"] ->
print_usage(long, MaxC, ShCode, Version),
?STATUS_USAGE;
["--tags"] ->
["tags"] ->
print_usage_tags(MaxC, ShCode, Version),
?STATUS_SUCCESS;
["--tags", Tag] ->
["--tags"] -> % deprecated in favor of "tags"
print_usage_tags(MaxC, ShCode, Version),
?STATUS_SUCCESS;
["commands"] ->
print_usage_tags_long(MaxC, ShCode, Version),
?STATUS_SUCCESS;
["--tags", Tag] -> % deprecated in favor of simply "Tag"
print_usage_tags(Tag, MaxC, ShCode, Version),
?STATUS_SUCCESS;
["help"] ->
print_usage_help(MaxC, ShCode),
?STATUS_SUCCESS;
[CmdString | _] ->
CmdStringU = ejabberd_regexp:greplace(
list_to_binary(CmdString), <<"-">>, <<"_">>),
print_usage_commands2(binary_to_list(CmdStringU), MaxC, ShCode, Version),
[String | _] ->
case determine_string_type(String, Version) of
no_idea ->
io:format("No tag or command matches '~ts'~n", [String]);
both ->
print_usage_tags(String, MaxC, ShCode, Version),
print_usage_commands2(String, MaxC, ShCode, Version);
tag ->
print_usage_tags(String, MaxC, ShCode, Version);
command ->
print_usage_commands2(String, MaxC, ShCode, Version)
end,
?STATUS_SUCCESS
end;
@@ -250,6 +261,21 @@ process2(Args, AccessCommands, Auth, Version) ->
{"Erroneous result: " ++ io_lib:format("~p", [Other]), ?STATUS_ERROR}
end.
determine_string_type(String, Version) ->
TagsCommands = ejabberd_commands:get_tags_commands(Version),
CommandsNames = case lists:keysearch(String, 1, TagsCommands) of
{value, {String, CNs}} -> CNs;
false -> []
end,
AllCommandsNames = [atom_to_list(Name) || {Name, _, _} <- ejabberd_commands:list_commands(Version)],
Cmds = filter_commands(AllCommandsNames, String),
case {CommandsNames, Cmds} of
{[], []} -> no_idea;
{[], _} -> command;
{_, []} -> tag;
{_, _} -> both
end.
%%-----------------------------
%% Command calling
%%-----------------------------
@@ -323,7 +349,8 @@ call_command([CmdString | Args], Auth, _AccessCommands, Version) ->
{L1, L2} when L1 < L2 -> {L2-L1, "less argument"};
{L1, L2} when L1 > L2 -> {L1-L2, "more argument"}
end,
{io_lib:format("Error: the command ~p requires ~p ~ts.",
process(["help" | [CmdString]]),
{io_lib:format("Error: the command '~ts' requires ~p ~ts.",
[CmdString, NumCompa, TextCompa]),
wrong_command_arguments}
end.
@@ -367,8 +394,8 @@ format_result({error, ErrorAtom}, _) ->
%% An error should always be allowed to return extended error to help with API.
%% Extended error is of the form:
%% {error, type :: atom(), code :: int(), Desc :: string()}
format_result({error, ErrorAtom, Code, _Msg}, _) ->
{io_lib:format("Error: ~p", [ErrorAtom]), make_status(Code)};
format_result({error, ErrorAtom, Code, Msg}, _) ->
{io_lib:format("Error: ~p: ~s", [ErrorAtom, Msg]), make_status(Code)};
format_result(Atom, {_Name, atom}) ->
io_lib:format("~p", [Atom]);
@@ -472,15 +499,25 @@ is_supported_args(Args) ->
%% Print help
%%-----------------------------
%% Bold
%% Commands are Bold
-define(B1, "\e[1m").
-define(B2, "\e[22m").
-define(B(S), case ShCode of true -> [?B1, S, ?B2]; false -> S end).
-define(B2, "\e[21m").
-define(C(S), case ShCode of true -> [?B1, S, ?B2]; false -> S end).
%% Underline
%% Arguments are Dim
-define(D1, "\e[2m").
-define(D2, "\e[22m").
-define(A(S), case ShCode of true -> [?D1, S, ?D2]; false -> S end).
%% Tags are Underline
-define(U1, "\e[4m").
-define(U2, "\e[24m").
-define(U(S), case ShCode of true -> [?U1, S, ?U2]; false -> S end).
-define(G(S), case ShCode of true -> [?U1, S, ?U2]; false -> S end).
%% B are Nothing
-define(N1, "\e[0m").
-define(N2, "\e[0m").
-define(B(S), case ShCode of true -> [?N1, S, ?N2]; false -> S end).
print_usage(Version) ->
{MaxC, ShCode} = get_shell_info(),
@@ -491,22 +528,15 @@ print_usage(HelpMode, MaxC, ShCode, Version) ->
{"status", [], "Get ejabberd status"},
{"stop", [], "Stop ejabberd"},
{"restart", [], "Restart ejabberd"},
{"help", ["[--tags [tag] | com?*]"], "Show help (try: ejabberdctl help help)"},
{"mnesia", ["[info]"], "show information of Mnesia system"}] ++
get_list_commands(Version),
print(
["Usage: ", ?B("ejabberdctl"), " [--no-timeout] [--node ", ?U("nodename"), "] [--version ", ?U("api_version"), "] ",
?U("command"), " [", ?U("options"), "]\n"
["Usage: ", "ejabberdctl", " [--no-timeout] [--node ", ?A("nodename"), "] [--version ", ?A("api_version"), "] ",
?C("command"), " [", ?A("arguments"), "]\n"
"\n"
"Available commands in this ejabberd node:\n"], []),
print_usage_commands(HelpMode, MaxC, ShCode, AllCommands),
print(
["\n"
"Examples:\n"
" ejabberdctl restart\n"
" ejabberdctl --node ejabberd@host restart\n"],
[]).
print_usage_commands(HelpMode, MaxC, ShCode, AllCommands).
print_usage_commands(HelpMode, MaxC, ShCode, Commands) ->
CmdDescsSorted = lists:keysort(1, Commands),
@@ -550,8 +580,24 @@ get_shell_info() ->
_:_ -> {78, false}
end.
%% Erlang/OTP 20.0 introduced string:find/2, but we must support old 19.3
string_find([], _SearchPattern) ->
nomatch;
string_find([A | String], [A]) ->
String;
string_find([_ | String], SearchPattern) ->
string_find(String, SearchPattern).
%% Split this command description in several lines of proper length
prepare_description(DescInit, MaxC, Desc) ->
case string_find(Desc, "\n") of
nomatch ->
prepare_description2(DescInit, MaxC, Desc);
_ ->
Desc
end.
prepare_description2(DescInit, MaxC, Desc) ->
Words = string:tokens(Desc, " "),
prepare_long_line(DescInit, MaxC, Words).
@@ -598,21 +644,27 @@ format_command_lines(CALD, MaxCmdLen, MaxC, ShCode, dual)
%% If the space available for descriptions is too narrow, enforce long help mode
format_command_lines(CALD, MaxCmdLen, MaxC, ShCode, long);
format_command_lines(CALD, _MaxCmdLen, _MaxC, ShCode, short) ->
lists:map(
fun({Cmd, Args, _CmdArgsL, _Desc}) ->
[" ", ?C(Cmd), [[" ", ?A(Arg)] || Arg <- Args], "\n"]
end, CALD);
format_command_lines(CALD, MaxCmdLen, MaxC, ShCode, dual) ->
lists:map(
fun({Cmd, Args, CmdArgsL, Desc}) ->
DescFmt = prepare_description(MaxCmdLen+4, MaxC, Desc),
[" ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args],
string:chars($\s, MaxCmdLen - CmdArgsL + 1),
[" ", ?C(Cmd), [[" ", ?A(Arg)] || Arg <- Args],
lists:duplicate(MaxCmdLen - CmdArgsL + 1, $\s),
DescFmt, "\n"]
end, CALD);
format_command_lines(CALD, _MaxCmdLen, MaxC, ShCode, long) ->
lists:map(
fun({Cmd, Args, _CmdArgsL, Desc}) ->
DescFmt = prepare_description(8, MaxC, Desc),
["\n ", ?B(Cmd), " ", [[?U(Arg), " "] || Arg <- Args], "\n", " ",
DescFmt, "\n"]
DescFmt = prepare_description(13, MaxC, Desc),
[" ", ?C(Cmd), [[" ", ?A(Arg)] || Arg <- Args], "\n",
" ", DescFmt, "\n"]
end, CALD).
@@ -621,20 +673,42 @@ format_command_lines(CALD, _MaxCmdLen, MaxC, ShCode, long) ->
%%-----------------------------
print_usage_tags(MaxC, ShCode, Version) ->
print("Available tags and commands:", []),
print("Available tags and list of commands:", []),
TagsCommands = ejabberd_commands:get_tags_commands(Version),
lists:foreach(
fun({Tag, Commands} = _TagCommands) ->
print(["\n\n ", ?B(Tag), "\n "], []),
print(["\n\n ", ?G(Tag), "\n "], []),
Words = lists:sort(Commands),
Desc = prepare_long_line(5, MaxC, Words),
print(Desc, [])
print(?C(Desc), [])
end,
TagsCommands),
print("\n\n", []).
print_usage_tags_long(MaxC, ShCode, Version) ->
print("Available tags and commands details:", []),
TagsCommands = ejabberd_commands:get_tags_commands(Version),
print("\n", []),
lists:foreach(
fun({Tag, CommandsNames} = _TagCommands) ->
print(["\n ", ?G(Tag), "\n"], []),
CommandsList = lists:map(
fun(NameString) ->
C = ejabberd_commands:get_command_definition(
list_to_atom(NameString), Version),
#ejabberd_commands{name = Name,
args = Args,
desc = Desc} = C,
tuple_command_help({Name, Args, Desc})
end,
CommandsNames),
print_usage_commands(short, MaxC, ShCode, CommandsList)
end,
TagsCommands),
print("\n", []).
print_usage_tags(Tag, MaxC, ShCode, Version) ->
print(["Available commands with tag ", ?B(Tag), ":", "\n"], []),
print(["Available commands with tag ", ?G(Tag), ":", "\n", "\n"], []),
HelpMode = long,
TagsCommands = ejabberd_commands:get_tags_commands(Version),
CommandsNames = case lists:keysearch(Tag, 1, TagsCommands) of
@@ -661,26 +735,29 @@ print_usage_tags(Tag, MaxC, ShCode, Version) ->
print_usage_help(MaxC, ShCode) ->
LongDesc =
["The special 'help' ejabberdctl command provides help of ejabberd commands.\n\n"
"The format is:\n ", ?B("ejabberdctl"), " ", ?B("help"), " [", ?B("--tags"), " ", ?U("[tag]"), " | ", ?U("com?*"), "]\n\n"
["This special ", ?C("help"), " command provides help of ejabberd commands.\n\n"
"The format is:\n ", ?B("ejabberdctl"), " ", ?C("help"),
" [", ?A("tags"), " | ", ?A("commands"), " | ", ?G("tag"), " | ", ?C("command"), " | ", ?C("com?*"), "]\n\n"
"The optional arguments:\n"
" ",?B("--tags")," Show all tags and the names of commands in each tag\n"
" ",?B("--tags"), " ", ?U("tag")," Show description of commands in this tag\n"
" ",?U("command")," Show detailed description of the command\n"
" ",?U("com?*")," Show detailed description of commands that match this glob.\n"
" You can use ? to match a simple character,\n"
" and * to match several characters.\n"
" ",?A("tags")," Show all tags and commands names in each tag\n"
" ",?A("commands")," Show all tags and commands details in each tag\n"
" ",?G("tag")," Show commands related to this tag\n"
" ",?C("command")," Show detailed description of this command\n"
" ",?C("com?*")," Show commands that match this glob.\n"
" (? will match a simple character, and\n"
" * will match several characters)\n"
"\n",
"Some example usages:\n",
" ejabberdctl help\n",
" ejabberdctl help --tags\n",
" ejabberdctl help --tags accounts\n",
" ejabberdctl help register\n",
" ejabberdctl help regist*\n",
" ejabberdctl ", ?C("help"), "\n",
" ejabberdctl ", ?C("help"), " ", ?A("tags"), "\n",
" ejabberdctl ", ?C("help"), " ", ?A("commands"), "\n",
" ejabberdctl ", ?C("help"), " ", ?G("accounts"), "\n",
" ejabberdctl ", ?C("help"), " ", ?C("register"), "\n",
" ejabberdctl ", ?C("help"), " ", ?C("regist*"), "\n",
"\n",
"Please note that 'ejabberdctl help' shows all ejabberd commands,\n",
"Please note that 'ejabberdctl' shows all ejabberd commands,\n",
"even those that cannot be used in the shell with ejabberdctl.\n",
"Those commands can be identified because the description starts with: *"],
"Those commands can be identified because their description starts with: *"],
ArgsDef = [],
C = #ejabberd_commands{
name = help,
@@ -701,23 +778,26 @@ print_usage_commands2(CmdSubString, MaxC, ShCode, Version) ->
AllCommandsNames = [atom_to_list(Name) || {Name, _, _} <- ejabberd_commands:list_commands(Version)],
Cmds = filter_commands(AllCommandsNames, CmdSubString),
case Cmds of
[] -> io:format("Error: no command found that match: ~p~n", [CmdSubString]);
[] -> io:format("Error: no command found that match '~ts'~n", [CmdSubString]);
_ -> print_usage_commands3(lists:sort(Cmds), MaxC, ShCode, Version)
end.
print_usage_commands3([Cmd], MaxC, ShCode, Version) ->
print_usage_command(Cmd, MaxC, ShCode, Version);
print_usage_commands3(Cmds, MaxC, ShCode, Version) ->
%% Then for each one print it
lists:mapfoldl(
fun(Cmd, Remaining) ->
print_usage_command(Cmd, MaxC, ShCode, Version),
case Remaining > 1 of
true -> print([" ", lists:duplicate(MaxC, 126), " \n"], []);
false -> ok
end,
{ok, Remaining-1}
end,
length(Cmds),
Cmds).
CommandsList = lists:map(
fun(NameString) ->
C = ejabberd_commands:get_command_definition(
list_to_atom(NameString), Version),
#ejabberd_commands{name = Name,
args = Args,
desc = Desc} = C,
tuple_command_help({Name, Args, Desc})
end,
Cmds),
print_usage_commands(long, MaxC, ShCode, CommandsList), %% que aqui solo muestre un par de lineas
ok.
filter_commands(All, SubString) ->
case lists:member(SubString, All) of
@@ -748,14 +828,13 @@ print_usage_command2(Cmd, C, MaxC, ShCode) ->
#ejabberd_commands{
tags = TagsAtoms,
desc = Desc,
args = ArgsDef,
longdesc = LongDesc,
result = ResultDef} = C,
NameFmt = [" ", ?B("Command Name"), ": ", Cmd, "\n"],
NameFmt = [" ", ?B("Command Name"), ": ", ?C(Cmd), "\n"],
%% Initial indentation of result is 13 = length(" Arguments: ")
{ArgsDef, _, _} = ejabberd_commands:get_command_format(
C#ejabberd_commands.name, admin),
Args = [format_usage_ctype(ArgDef, 13) || ArgDef <- ArgsDef],
ArgsMargin = lists:duplicate(13, $\s),
ArgsListFmt = case Args of
@@ -770,9 +849,9 @@ print_usage_command2(Cmd, C, MaxC, ShCode) ->
XmlrpcFmt = "", %%+++ [" ",?B("XML-RPC"),": ", format_usage_xmlrpc(ArgsDef, ResultDef), "\n\n"],
TagsFmt = [" ",?B("Tags"),": ", prepare_long_line(8, MaxC, [atom_to_list(TagA) || TagA <- TagsAtoms])],
TagsFmt = [" ",?B("Tags"),":", prepare_long_line(8, MaxC, [?G(atom_to_list(TagA)) || TagA <- TagsAtoms])],
DescFmt = [" ",?B("Description"),": ", prepare_description(15, MaxC, Desc)],
DescFmt = [" ",?B("Description"),":", prepare_description(15, MaxC, Desc)],
LongDescFmt = case LongDesc of
"" -> "";
@@ -784,7 +863,12 @@ print_usage_command2(Cmd, C, MaxC, ShCode) ->
false -> [" ", ?B("Note:"), " This command cannot be executed using ejabberdctl. Try ejabberd_xmlrpc.\n\n"]
end,
print(["\n", NameFmt, "\n", ArgsFmt, "\n", ReturnsFmt, "\n\n", XmlrpcFmt, TagsFmt, "\n\n", DescFmt, "\n\n", LongDescFmt, NoteEjabberdctl], []).
case Cmd of
"help" -> ok;
_ -> print([NameFmt, "\n", ArgsFmt, "\n", ReturnsFmt,
"\n\n", XmlrpcFmt, TagsFmt, "\n\n", DescFmt, "\n\n"], [])
end,
print([LongDescFmt, NoteEjabberdctl], []).
format_usage_ctype(Type, _Indentation)
when (Type==atom) or (Type==integer) or (Type==string) or (Type==binary) or (Type==rescode) or (Type==restuple)->
+7 -4
View File
@@ -69,11 +69,10 @@ man(Lang) ->
catch _:undef -> []
end
end, ejabberd_config:callback_modules(all)),
Version = binary_to_list(ejabberd_option:version()),
Options =
["TOP LEVEL OPTIONS",
"-----------------",
"This section describes top level options of ejabberd "++Version,
tr(Lang, ?T("This section describes top level options of ejabberd.")),
io_lib:nl()] ++
lists:flatmap(
fun(Opt) ->
@@ -93,7 +92,7 @@ man(Lang) ->
"MODULES",
"-------",
"[[modules]]",
"This section describes options of all modules in ejabberd "++Version,
tr(Lang, ?T("This section describes options of all ejabberd modules.")),
io_lib:nl()] ++
lists:flatmap(
fun({M, Descr, DocOpts, Backends, Example}) ->
@@ -112,7 +111,7 @@ man(Lang) ->
"LISTENERS",
"-------",
"[[listeners]]",
"This section describes options of all listeners in ejabberd "++Version,
tr(Lang, ?T("This section describes options of all ejabberd listeners.")),
io_lib:nl(),
"TODO"],
AsciiData =
@@ -160,6 +159,10 @@ opt_to_man(Lang, {Option, Options, Children}, Level) ->
lists:keysort(1, Children))]) ++
[io_lib:nl()|format_example(Level, Lang, Options)].
format_option(Lang, Option, #{note := Note, value := Val}) ->
"\n\n_Note_ about the next option: " ++ Note ++ ":\n\n"++
"*" ++ atom_to_list(Option) ++ "*: 'pass:[" ++
tr(Lang, Val) ++ "]'::";
format_option(Lang, Option, #{value := Val}) ->
"*" ++ atom_to_list(Option) ++ "*: 'pass:[" ++
tr(Lang, Val) ++ "]'::";
+8 -8
View File
@@ -51,7 +51,7 @@
active = false :: boolean(),
c2s_pid :: pid(),
ws :: {#ws{}, pid()},
rfc_compilant = undefined :: boolean() | undefined}).
rfc_compliant = undefined :: boolean() | undefined}).
%-define(DBGFSM, true).
@@ -166,7 +166,7 @@ handle_event({new_shaper, Shaper}, StateName, #state{ws = {_, WsPid}} = StateDat
{next_state, StateName, StateData}.
handle_sync_event({send_xml, Packet}, _From, StateName,
#state{ws = {_, WsPid}, rfc_compilant = R} = StateData) ->
#state{ws = {_, WsPid}, rfc_compliant = R} = StateData) ->
Packet2 = case {case R of undefined -> true; V -> V end, Packet} of
{true, {xmlstreamstart, _, Attrs}} ->
Attrs2 = [{<<"xmlns">>, <<"urn:ietf:params:xml:ns:xmpp-framing">>} |
@@ -215,7 +215,7 @@ handle_sync_event({send_xml, Packet}, _From, StateName,
StateName
end,
{reply, ok, SN2, StateData};
handle_sync_event(close, _From, StateName, #state{ws = {_, WsPid}, rfc_compilant = true} = StateData)
handle_sync_event(close, _From, StateName, #state{ws = {_, WsPid}, rfc_compliant = true} = StateData)
when StateName /= stream_end_sent ->
Close = #xmlel{name = <<"close">>,
attrs = [{<<"xmlns">>, <<"urn:ietf:params:xml:ns:xmpp-framing">>}]},
@@ -313,7 +313,7 @@ get_human_html_xmlel() ->
"client that supports it.">>}]}]}]}.
parse(#state{rfc_compilant = C} = State, Data) ->
parse(#state{rfc_compliant = C} = State, Data) ->
case C of
undefined ->
P = fxml_stream:new(self()),
@@ -321,13 +321,13 @@ parse(#state{rfc_compilant = C} = State, Data) ->
fxml_stream:close(P2),
case parsed_items([]) of
error ->
{State#state{rfc_compilant = true}, <<"parse error">>};
{State#state{rfc_compliant = true}, <<"parse error">>};
[] ->
{State#state{rfc_compilant = true}, <<"parse error">>};
{State#state{rfc_compliant = true}, <<"parse error">>};
[{xmlstreamstart, <<"open">>, _} | _] ->
parse(State#state{rfc_compilant = true}, Data);
parse(State#state{rfc_compliant = true}, Data);
_ ->
parse(State#state{rfc_compilant = false}, Data)
parse(State#state{rfc_compliant = false}, Data)
end;
true ->
El = fxml_stream:parse_element(Data),
+5 -2
View File
@@ -113,10 +113,11 @@ init({Port, _, udp} = EndPoint, Module, Opts, SockOpts) ->
_ ->
{Port, SockOpts}
end,
ExtraOpts2 = lists:keydelete(send_timeout, 1, ExtraOpts),
case gen_udp:open(Port2, [binary,
{active, false},
{reuseaddr, true} |
ExtraOpts]) of
ExtraOpts2]) of
{ok, Socket} ->
case inet:sockname(Socket) of
{ok, {Addr, Port1}} ->
@@ -195,7 +196,6 @@ listen_tcp(Port, SockOpts) ->
{active, false},
{reuseaddr, true},
{nodelay, true},
{send_timeout, ?TCP_SEND_TIMEOUT},
{send_timeout_close, true},
{keepalive, true} | ExtraOpts]),
case Res of
@@ -682,6 +682,8 @@ listen_opt_type(max_stanza_size) ->
econf:pos_int(infinity);
listen_opt_type(max_fsm_queue) ->
econf:pos_int();
listen_opt_type(send_timeout) ->
econf:timeout(second, infinity);
listen_opt_type(shaper) ->
econf:shaper();
listen_opt_type(access) ->
@@ -694,6 +696,7 @@ listen_options() ->
{transport, tcp},
{ip, {0,0,0,0}},
{accept_interval, 0},
{send_timeout, 15000},
{backlog, 5},
{use_proxy_protocol, false},
{supervisor, true}].
+10 -3
View File
@@ -363,6 +363,7 @@ doc() ->
"module's README file for details.")}},
{auth_password_format,
#{value => "plain | scram",
note => "improved in 20.01",
desc =>
?T("The option defines in what format the users passwords "
"are stored. 'plain': The password is stored as plain text "
@@ -869,6 +870,7 @@ doc() ->
"only. If not set, the value from 'cache_missed' will be used.")}},
{oauth_cache_rest_failure_life_time,
#{value => "timeout()",
note => "added in 21.01",
desc =>
?T("The time that a failure in OAuth ReST is cached. "
"The default value is 'infinity'.")}},
@@ -935,12 +937,14 @@ doc() ->
"connecting with IPv4, if that fails it tries using IPv6.")}},
{outgoing_s2s_ipv4_address,
#{value => "Address",
note => "added in 20.12",
desc =>
?T("Specify the IPv4 address that will be used when establishing "
"an outgoing S2S IPv4 connection, for example \"127.0.0.1\". "
"The default value is 'undefined'.")}},
{outgoing_s2s_ipv6_address,
#{value => "Address",
note => "added in 20.12",
desc =>
?T("Specify the IPv6 address that will be used when establishing "
"an outgoing S2S IPv6 connection, for example "
@@ -1246,6 +1250,7 @@ doc() ->
"keepalive requests are made.")}},
{sql_odbc_driver,
#{value => "Path",
note => "added in 20.12",
desc =>
?T("Path to the ODBC driver to use to connect to a Microsoft SQL "
"Server database. This option is only valid if the 'sql_type' "
@@ -1258,8 +1263,8 @@ doc() ->
{sql_pool_size,
#{value => ?T("Size"),
desc =>
?T("A number of connections to the SQL server. By default ejabberd opens "
"10 connections to the database for each virtual host. WARNING: "
?T("Number of connections to the SQL server that ejabberd will "
"open for each virtual host. The default value is 10. WARNING: "
"for SQLite this value is '1' by default and it's not recommended "
"to change it due to potential race conditions.")}},
{sql_port,
@@ -1270,6 +1275,7 @@ doc() ->
"'1433' for MS SQL. The option has no effect for SQLite.")}},
{sql_prepared_statements,
#{value => "true | false",
note => "added in 20.01",
desc =>
?T("This option is 'true' by default, and is useful to disable "
"prepared statements. The option is valid for PostgreSQL.")}},
@@ -1292,9 +1298,10 @@ doc() ->
"The default value is 'localhost'.")}},
{sql_ssl,
#{value => "true | false",
note => "improved in 20.03",
desc =>
?T("Whether to use SSL encrypted connections to the "
"SQL server. The option is only available for "
"SQL server. The option is only available for MySQL and "
"PostgreSQL. The default value is 'false'.")}},
{sql_ssl_cafile,
#{value => ?T("Path"),
+3 -3
View File
@@ -424,15 +424,15 @@ balancing_route(From, To, Packet, Rs) ->
Value = erlang:system_time(),
case [R || R <- Rs, node(R#route.pid) == node()] of
[] ->
R = lists:nth(erlang:phash(Value, length(Rs)), Rs),
R = lists:nth(erlang:phash2(Value, length(Rs))+1, Rs),
do_route(Packet, R);
LRs ->
R = lists:nth(erlang:phash(Value, length(LRs)), LRs),
R = lists:nth(erlang:phash2(Value, length(LRs))+1, LRs),
do_route(Packet, R)
end;
Value ->
SRs = lists:ukeysort(#route.local_hint, Rs),
R = lists:nth(erlang:phash(Value, length(SRs)), SRs),
R = lists:nth(erlang:phash2(Value, length(SRs))+1, SRs),
do_route(Packet, R)
end.
+42 -9
View File
@@ -30,7 +30,7 @@
-behaviour(gen_server).
%% API
-export([route_multicast/4,
-export([route_multicast/5,
register_route/1,
unregister_route/1
]).
@@ -39,7 +39,7 @@
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
terminate/2, code_change/3, update_to_in_wrapped/2]).
-include("logger.hrl").
-include_lib("xmpp/include/xmpp.hrl").
@@ -58,9 +58,11 @@
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-spec route_multicast(jid(), binary(), [jid()], stanza()) -> ok.
route_multicast(From, Domain, Destinations, Packet) ->
case catch do_route(Domain, Destinations, xmpp:set_from(Packet, From)) of
-spec route_multicast(jid(), binary(), [jid()], stanza(), boolean()) -> ok.
route_multicast(From0, Domain0, Destinations0, Packet0, Wrapped0) ->
{From, Domain, Destinations, Packet, Wrapped} =
ejabberd_hooks:run_fold(multicast_route, Domain0, {From0, Domain0, Destinations0, Packet0, Wrapped0}, []),
case catch do_route(Domain, Destinations, xmpp:set_from(Packet, From), Wrapped) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
[Reason, {From, Domain, Destinations, Packet}]);
@@ -157,7 +159,7 @@ handle_cast(Msg, State) ->
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info({route_multicast, Domain, Destinations, Packet}, State) ->
case catch do_route(Domain, Destinations, Packet) of
case catch do_route(Domain, Destinations, Packet, false) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
[Reason, {Domain, Destinations, Packet}]);
@@ -204,13 +206,41 @@ terminate(_Reason, _State) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
-spec update_to_in_wrapped(stanza(), jid()) -> stanza().
update_to_in_wrapped(Packet, To) ->
case Packet of
#message{sub_els = [#ps_event{
items = #ps_items{
items = [#ps_item{
sub_els = [Internal]
} = PSItem]
} = PSItems
} = PSEvent]} ->
Internal2 = xmpp:set_to(Internal, To),
PSItem2 = PSItem#ps_item{sub_els = [Internal2]},
PSItems2 = PSItems#ps_items{items = [PSItem2]},
PSEvent2 = PSEvent#ps_event{items = PSItems2},
xmpp:set_to(Packet#message{sub_els = [PSEvent2]}, To);
_ ->
xmpp:set_to(Packet, To)
end.
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
%% From = #jid
%% Destinations = [#jid]
-spec do_route(binary(), [jid()], stanza()) -> any().
do_route(Domain, Destinations, Packet) ->
-spec do_route(binary(), [jid()], stanza(), boolean()) -> any().
do_route(Domain, Destinations, Packet, true) ->
?DEBUG("Route multicast:~n~ts~nDomain: ~ts~nDestinations: ~ts~n",
[xmpp:pp(Packet), Domain,
str:join([jid:encode(To) || To <- Destinations], <<", ">>)]),
lists:foreach(
fun(To) ->
Packet2 = update_to_in_wrapped(Packet, To),
ejabberd_router:route(Packet2)
end, Destinations);
do_route(Domain, Destinations, Packet, false) ->
?DEBUG("Route multicast:~n~ts~nDomain: ~ts~nDestinations: ~ts~n",
[xmpp:pp(Packet), Domain,
str:join([jid:encode(To) || To <- Destinations], <<", ">>)]),
@@ -236,4 +266,7 @@ pick_multicast_pid(Rs) ->
-spec do_route_normal([jid()], stanza()) -> any().
do_route_normal(Destinations, Packet) ->
[ejabberd_router:route(xmpp:set_to(Packet, To)) || To <- Destinations].
lists:foreach(
fun(To) ->
ejabberd_router:route(xmpp:set_to(Packet, To))
end, Destinations).
+4 -4
View File
@@ -429,8 +429,8 @@ choose_pid(From, Pids) ->
Ps -> Ps
end,
Pid =
lists:nth(erlang:phash(jid:remove_resource(From),
length(Pids1)),
lists:nth(erlang:phash2(jid:remove_resource(From),
length(Pids1))+1,
Pids1),
?DEBUG("Using ejabberd_s2s_out ~p~n", [Pid]),
Pid.
@@ -513,13 +513,13 @@ needed_connections_number(Ls, MaxS2SConnectionsNumber,
get_commands_spec() ->
[#ejabberd_commands{
name = incoming_s2s_number, tags = [stats, s2s],
name = incoming_s2s_number, tags = [statistics, s2s],
desc = "Number of incoming s2s connections on the node",
policy = admin,
module = ?MODULE, function = incoming_s2s_number,
args = [], result = {s2s_incoming, integer}},
#ejabberd_commands{
name = outgoing_s2s_number, tags = [stats, s2s],
name = outgoing_s2s_number, tags = [statistics, s2s],
desc = "Number of outgoing s2s connections on the node",
policy = admin,
module = ?MODULE, function = outgoing_s2s_number,
+1 -1
View File
@@ -985,7 +985,7 @@ get_commands_spec() ->
result_desc = "List of users sessions",
result_example = [<<"user1@example.com">>, <<"user2@example.com">>],
result = {connected_users, {list, {sessions, string}}}},
#ejabberd_commands{name = connected_users_number, tags = [session, stats],
#ejabberd_commands{name = connected_users_number, tags = [session, statistics],
desc = "Get the number of established sessions",
policy = admin,
module = ?MODULE, function = connected_users_number,
+6
View File
@@ -39,6 +39,7 @@
restart/1,
use_new_schema/0,
sql_query_to_iolist/1,
sql_query_to_iolist/2,
escape/1,
standard_escape/1,
escape_like/1,
@@ -832,6 +833,11 @@ sql_query_format_res(Res, _SQLQuery) ->
sql_query_to_iolist(SQLQuery) ->
generic_sql_query_format(SQLQuery).
sql_query_to_iolist(sqlite, SQLQuery) ->
sqlite_sql_query_format(SQLQuery);
sql_query_to_iolist(_DbType, SQLQuery) ->
generic_sql_query_format(SQLQuery).
sql_begin() ->
sql_query_internal(
[{mssql, [<<"begin transaction;">>]},
+5 -1
View File
@@ -188,7 +188,11 @@ check_sqlite_db(Host) ->
create_sqlite_tables(DB) ->
SqlDir = misc:sql_dir(),
File = filename:join(SqlDir, "lite.sql"),
Filename = case ejabberd_sql:use_new_schema() of
true -> "lite.new.sql";
false -> "lite.sql"
end,
File = filename:join(SqlDir, Filename),
case file:open(File, [read, binary]) of
{ok, Fd} ->
Qs = read_lines(Fd, File, []),
+37 -1
View File
@@ -148,6 +148,7 @@ build_script(Dir, UpdatedBeams) ->
{Script, LowLevelScript, Check1}.
%% Copied from Erlang/OTP file: lib/sasl/src/systools.hrl
-ifdef(SYSTOOLS_APP_DEF_WITHOUT_OPTIONAL).
-record(application,
{name, %% Name of the application, atom().
type = permanent, %% Application start type, atom().
@@ -172,11 +173,46 @@ build_script(Dir, UpdatedBeams) ->
%% integer() | infinity.
mod = [], %% [] | {Mod, StartArgs}, Mod= atom(),
%% StartArgs = list().
start_phases = [], %% [] | {Phase, PhaseArgs}, Phase = atom(),
start_phases, %% [{Phase, PhaseArgs}] | undefined,
%% Phase = atom(),
%% PhaseArgs = list().
dir = "" %% The directory where the .app file was
%% found (internal use).
}).
-else.
-record(application,
{name, %% Name of the application, atom().
type = permanent, %% Application start type, atom().
vsn = "", %% Version of the application, string().
id = "", %% Id of the application, string().
description = "", %% Description of application, string().
modules = [], %% [Module | {Module,Vsn}] of modules
%% incorporated in the application,
%% Module = atom(), Vsn = string().
uses = [], %% [Application] list of applications required
%% by the application, Application = atom().
optional = [], %% [Application] list of applications in uses
%% that are optional, Application = atom().
includes = [], %% [Application] list of applications included
%% by the application, Application = atom().
regs = [], %% [RegNames] a list of registered process
%% names used by the application, RegNames =
%% atom().
env = [], %% [{Key,Value}] environment variable of
%% application, Key = Value = term().
maxT = infinity, %% Max time an application may exist,
%% integer() | infinity.
maxP = infinity, %% Max number of processes in an application,
%% integer() | infinity.
mod = [], %% [] | {Mod, StartArgs}, Mod= atom(),
%% StartArgs = list().
start_phases, %% [{Phase, PhaseArgs}] | undefined,
%% Phase = atom(),
%% PhaseArgs = list().
dir = "" %% The directory where the .app file was
%% found (internal use).
}).
-endif.
make_script(UpdatedBeams) ->
+159 -19
View File
@@ -585,8 +585,12 @@ list_vhosts2(Lang, Hosts) ->
[?XE(<<"thead">>,
[?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Host")),
?XCT(<<"td">>, ?T("Registered Users")),
?XCT(<<"td">>, ?T("Online Users"))])]),
?XACT(<<"td">>,
[{<<"class">>, <<"alignright">>}],
?T("Registered Users")),
?XACT(<<"td">>,
[{<<"class">>, <<"alignright">>}],
?T("Online Users"))])]),
?XE(<<"tbody">>,
(lists:map(fun (Host) ->
OnlineUsers =
@@ -598,9 +602,11 @@ list_vhosts2(Lang, Hosts) ->
[?AC(<<"../server/", Host/binary,
"/">>,
Host)]),
?XC(<<"td">>,
?XAC(<<"td">>,
[{<<"class">>, <<"alignright">>}],
(pretty_string_int(RegisteredUsers))),
?XC(<<"td">>,
?XAC(<<"td">>,
[{<<"class">>, <<"alignright">>}],
(pretty_string_int(OnlineUsers)))])
end,
SHosts)))])].
@@ -706,7 +712,9 @@ list_given_users(Host, Users, Prefix, Lang, URLFunc) ->
[?XE(<<"thead">>,
[?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("User")),
?XCT(<<"td">>, ?T("Offline Messages")),
?XACT(<<"td">>,
[{<<"class">>, <<"alignright">>}],
?T("Offline Messages")),
?XCT(<<"td">>, ?T("Last Activity"))])]),
?XE(<<"tbody">>,
(lists:map(fun (_SU = {Server, User}) ->
@@ -749,7 +757,9 @@ list_given_users(Host, Users, Prefix, Lang, URLFunc) ->
misc:url_encode(User),
Server})),
(us_to_list(US)))]),
?XE(<<"td">>, FQueueLen),
?XAE(<<"td">>,
[{<<"class">>, <<"alignright">>}],
FQueueLen),
?XC(<<"td">>, FLast)])
end,
Users)))]).
@@ -808,16 +818,24 @@ get_stats(global, Lang) ->
[?XE(<<"tbody">>,
[?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Registered Users:")),
?XC(<<"td">>, (pretty_string_int(RegisteredUsers)))]),
?XAC(<<"td">>,
[{<<"class">>, <<"alignright">>}],
(pretty_string_int(RegisteredUsers)))]),
?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Online Users:")),
?XC(<<"td">>, (pretty_string_int(OnlineUsers)))]),
?XAC(<<"td">>,
[{<<"class">>, <<"alignright">>}],
(pretty_string_int(OnlineUsers)))]),
?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Outgoing s2s Connections:")),
?XC(<<"td">>, (pretty_string_int(OutS2SNumber)))]),
?XAC(<<"td">>,
[{<<"class">>, <<"alignright">>}],
(pretty_string_int(OutS2SNumber)))]),
?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Incoming s2s Connections:")),
?XC(<<"td">>, (pretty_string_int(InS2SNumber)))])])])];
?XAC(<<"td">>,
[{<<"class">>, <<"alignright">>}],
(pretty_string_int(InS2SNumber)))])])])];
get_stats(Host, Lang) ->
OnlineUsers =
length(ejabberd_sm:get_vh_session_list(Host)),
@@ -827,10 +845,14 @@ get_stats(Host, Lang) ->
[?XE(<<"tbody">>,
[?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Registered Users:")),
?XC(<<"td">>, (pretty_string_int(RegisteredUsers)))]),
?XAC(<<"td">>,
[{<<"class">>, <<"alignright">>}],
(pretty_string_int(RegisteredUsers)))]),
?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Online Users:")),
?XC(<<"td">>, (pretty_string_int(OnlineUsers)))])])])].
?XAC(<<"td">>,
[{<<"class">>, <<"alignright">>}],
(pretty_string_int(OnlineUsers)))])])])].
list_online_users(Host, _Lang) ->
Users = [{S, U}
@@ -1151,17 +1173,23 @@ get_node(global, Node, [<<"db">>], Query, Lang) ->
{T, S, M};
_ -> {unknown, 0, 0}
end,
MemoryB = Memory*erlang:system_info(wordsize),
?XE(<<"tr">>,
[?XC(<<"td">>, STable),
[?XE(<<"td">>,
[?AC(<<"./", STable/binary,
"/">>,
STable)]),
?XE(<<"td">>,
[db_storage_select(STable, Type,
Lang)]),
?XAE(<<"td">>,
[{<<"class">>, <<"alignright">>}],
[?AC(<<"./", STable/binary,
"/1/">>,
(pretty_string_int(Size)))]),
?XAC(<<"td">>,
[{<<"class">>, <<"alignright">>}],
(pretty_string_int(Size))),
?XAC(<<"td">>,
[{<<"class">>, <<"alignright">>}],
(pretty_string_int(Memory)))])
(pretty_string_int(MemoryB)))])
end,
STables),
[?XC(<<"h1">>,
@@ -1177,8 +1205,12 @@ get_node(global, Node, [<<"db">>], Query, Lang) ->
[?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Name")),
?XCT(<<"td">>, ?T("Storage Type")),
?XCT(<<"td">>, ?T("Elements")),
?XCT(<<"td">>, ?T("Memory"))])]),
?XACT(<<"td">>,
[{<<"class">>, <<"alignright">>}],
?T("Elements")),
?XACT(<<"td">>,
[{<<"class">>, <<"alignright">>}],
?T("Memory"))])]),
?XE(<<"tbody">>,
(Rows ++
[?XE(<<"tr">>,
@@ -1189,6 +1221,10 @@ get_node(global, Node, [<<"db">>], Query, Lang) ->
<<"submit">>,
?T("Submit"))])])]))])])]
end;
get_node(global, Node, [<<"db">>, TableName], _Query, Lang) ->
make_table_view(Node, TableName, Lang);
get_node(global, Node, [<<"db">>, TableName, PageNumber], _Query, Lang) ->
make_table_elements_view(Node, TableName, Lang, binary_to_integer(PageNumber));
get_node(global, Node, [<<"backup">>], Query, Lang) ->
HomeDirRaw = case {os:getenv("HOME"), os:type()} of
{EnvHome, _} when is_list(EnvHome) -> list_to_binary(EnvHome);
@@ -1344,6 +1380,7 @@ get_node(global, Node, [<<"stats">>], _Query, Lang) ->
[wall_clock]),
UpTimeS = (str:format("~.3f",
[element(1, UpTime) / 1000])),
UpTimeDate = uptime_date(Node),
CPUTime = ejabberd_cluster:call(Node, erlang, statistics, [runtime]),
CPUTimeS = (str:format("~.3f",
[element(1, CPUTime) / 1000])),
@@ -1364,6 +1401,10 @@ get_node(global, Node, [<<"stats">>], _Query, Lang) ->
[?XCT(<<"td">>, ?T("Uptime:")),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
UpTimeS)]),
?XE(<<"tr">>,
[?X(<<"td">>),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
UpTimeDate)]),
?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("CPU Time:")),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
@@ -1458,6 +1499,16 @@ get_node(Host, Node, NPath, Query, Lang) ->
_ -> Res
end.
uptime_date(Node) ->
Localtime = ejabberd_cluster:call(Node, erlang, localtime, []),
Now = calendar:datetime_to_gregorian_seconds(Localtime),
{Wall, _} = ejabberd_cluster:call(Node, erlang, statistics, [wall_clock]),
LastRestart = Now - (Wall div 1000),
{{Year, Month, Day}, {Hour, Minute, Second}} =
calendar:gregorian_seconds_to_datetime(LastRestart),
str:format("~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
[Year, Month, Day, Hour, Minute, Second]).
%%%==================================
%%%% node parse
@@ -1732,6 +1783,95 @@ pretty_string_int(String) when is_binary(String) ->
{0, <<"">>}, lists:reverse(binary_to_list(String))),
Result.
%%%==================================
%%%% mnesia table view
make_table_view(Node, STable, Lang) ->
Table = misc:binary_to_atom(STable),
TInfo = ejabberd_cluster:call(Node, mnesia, table_info, [Table, all]),
{value, {storage_type, Type}} = lists:keysearch(storage_type, 1, TInfo),
{value, {size, Size}} = lists:keysearch(size, 1, TInfo),
{value, {memory, Memory}} = lists:keysearch(memory, 1, TInfo),
MemoryB = Memory*erlang:system_info(wordsize),
TableInfo = str:format("~p", [TInfo]),
[?XC(<<"h1">>, (str:translate_and_format(Lang, ?T("Database Tables at ~p"),
[Node]))),
?XAE(<<"table">>, [],
[?XE(<<"tbody">>,
[?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Name")),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
STable
)]),
?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Node")),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
misc:atom_to_binary(Node)
)]),
?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Storage Type")),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
misc:atom_to_binary(Type)
)]),
?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Elements")),
?XAE(<<"td">>,
[{<<"class">>, <<"alignright">>}],
[?AC(<<"1/">>,
(pretty_string_int(Size)))])
]),
?XE(<<"tr">>,
[?XCT(<<"td">>, ?T("Memory")),
?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}],
(pretty_string_int(MemoryB))
)])
])]),
?XC(<<"pre">>, TableInfo)].
make_table_elements_view(Node, STable, Lang, PageNumber) ->
Table = misc:binary_to_atom(STable),
TInfo = ejabberd_cluster:call(Node, mnesia, table_info, [Table, all]),
{value, {storage_type, Type}} = lists:keysearch(storage_type, 1, TInfo),
{value, {size, Size}} = lists:keysearch(size, 1, TInfo),
PageSize = 500,
TableContentErl = get_table_content(Node, Table, Type, PageNumber, PageSize),
TableContent = str:format("~p", [TableContentErl]),
PagesLinks = build_elements_pages_list(Size, PageNumber, PageSize),
[?XC(<<"h1">>, (str:translate_and_format(Lang, ?T("Database Tables at ~p"),
[Node]))),
?P, ?AC(<<"../">>, STable), ?P
] ++ PagesLinks ++ [?XC(<<"pre">>, TableContent)].
build_elements_pages_list(Size, PageNumber, PageSize) ->
PagesNumber = calculate_pages_number(Size, PageSize),
PagesSeq = lists:seq(1, PagesNumber),
PagesList = [?AC(<<"../", (integer_to_binary(N))/binary, "/">>,
<<(integer_to_binary(N))/binary, " ">>)
|| N <- PagesSeq],
lists:keyreplace(
[?C(<<(integer_to_binary(PageNumber))/binary, " ">>)],
4,
PagesList,
?C(<<" [", (integer_to_binary(PageNumber))/binary, "] ">>)).
calculate_pages_number(Size, PageSize) ->
Remainer = case Size rem PageSize of
0 -> 0;
_ -> 1
end,
case (Size div PageSize) + Remainer of
1 -> 0;
Res -> Res
end.
get_table_content(Node, Table, _Type, PageNumber, PageSize) ->
Keys1 = lists:sort(ejabberd_cluster:call(Node, mnesia, dirty_all_keys, [Table])),
FirstKeyPos = 1 - PageSize + PageNumber*PageSize,
Keys = lists:sublist(Keys1, FirstKeyPos, PageSize),
Res = [ejabberd_cluster:call(Node, mnesia, dirty_read, [Table, Key])
|| Key <- Keys],
lists:flatten(Res).
%%%==================================
%%%% navigation menu
+33 -33
View File
@@ -187,32 +187,32 @@ find_subprotocol(Headers) ->
end.
ws_loop(FrameInfo, Socket, WsHandleLoopPid, SocketMode, Shaper) ->
ws_loop(FrameInfo, Socket, WsHandleLoopPid, SockMod, Shaper) ->
receive
{DataType, _Socket, Data} when DataType =:= tcp orelse DataType =:= raw ->
case handle_data(DataType, FrameInfo, Data, Socket, WsHandleLoopPid, SocketMode, Shaper) of
case handle_data(DataType, FrameInfo, Data, Socket, WsHandleLoopPid, SockMod, Shaper) of
{error, Error} ->
?DEBUG("TLS decode error ~p", [Error]),
websocket_close(Socket, WsHandleLoopPid, SocketMode, 1002); % protocol error
websocket_close(Socket, WsHandleLoopPid, SockMod, 1002); % protocol error
{NewFrameInfo, ToSend, NewShaper} ->
lists:foreach(fun(Pkt) -> SocketMode:send(Socket, Pkt)
lists:foreach(fun(Pkt) -> SockMod:send(Socket, Pkt)
end, ToSend),
ws_loop(NewFrameInfo, Socket, WsHandleLoopPid, SocketMode, NewShaper)
ws_loop(NewFrameInfo, Socket, WsHandleLoopPid, SockMod, NewShaper)
end;
{new_shaper, NewShaper} ->
NewShaper = case NewShaper of
none when Shaper /= none ->
activate(Socket, SocketMode, true), none;
activate(Socket, SockMod, true), none;
_ ->
NewShaper
end,
ws_loop(FrameInfo, Socket, WsHandleLoopPid, SocketMode, NewShaper);
ws_loop(FrameInfo, Socket, WsHandleLoopPid, SockMod, NewShaper);
{tcp_closed, _Socket} ->
?DEBUG("TCP connection was closed, exit", []),
websocket_close(Socket, WsHandleLoopPid, SocketMode, 0);
websocket_close(Socket, WsHandleLoopPid, SockMod, 0);
{tcp_error, Socket, Reason} ->
?DEBUG("TCP connection error: ~ts", [inet:format_error(Reason)]),
websocket_close(Socket, WsHandleLoopPid, SocketMode, 0);
websocket_close(Socket, WsHandleLoopPid, SockMod, 0);
{'DOWN', Ref, process, WsHandleLoopPid, Reason} ->
Code = case Reason of
normal ->
@@ -224,39 +224,39 @@ ws_loop(FrameInfo, Socket, WsHandleLoopPid, SocketMode, Shaper) ->
1011 % internal error
end,
erlang:demonitor(Ref),
websocket_close(Socket, WsHandleLoopPid, SocketMode, Code);
websocket_close(Socket, WsHandleLoopPid, SockMod, Code);
{text_with_reply, Data, Sender} ->
SocketMode:send(Socket, encode_frame(Data, 1)),
SockMod:send(Socket, encode_frame(Data, 1)),
Sender ! {text_reply, self()},
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
SocketMode, Shaper);
SockMod, Shaper);
{data_with_reply, Data, Sender} ->
SocketMode:send(Socket, encode_frame(Data, 2)),
SockMod:send(Socket, encode_frame(Data, 2)),
Sender ! {data_reply, self()},
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
SocketMode, Shaper);
SockMod, Shaper);
{text, Data} ->
SocketMode:send(Socket, encode_frame(Data, 1)),
SockMod:send(Socket, encode_frame(Data, 1)),
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
SocketMode, Shaper);
SockMod, Shaper);
{data, Data} ->
SocketMode:send(Socket, encode_frame(Data, 2)),
SockMod:send(Socket, encode_frame(Data, 2)),
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
SocketMode, Shaper);
SockMod, Shaper);
{ping, Data} ->
SocketMode:send(Socket, encode_frame(Data, 9)),
SockMod:send(Socket, encode_frame(Data, 9)),
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
SocketMode, Shaper);
SockMod, Shaper);
shutdown ->
?DEBUG("Shutdown request received, closing websocket "
"with pid ~p",
[self()]),
websocket_close(Socket, WsHandleLoopPid, SocketMode, 1001); % going away
websocket_close(Socket, WsHandleLoopPid, SockMod, 1001); % going away
_Ignored ->
?WARNING_MSG("Received unexpected message, ignoring: ~p",
[_Ignored]),
ws_loop(FrameInfo, Socket, WsHandleLoopPid,
SocketMode, Shaper)
SockMod, Shaper)
end.
encode_frame(Data, Opcode) ->
@@ -358,7 +358,7 @@ process_frame(#frame_info{unprocessed = none,
| Recv],
Send};
9 -> % Ping
Frame = encode_frame(Unprocessed, 10),
Frame = encode_frame(Unmasked, 10),
{FrameInfo3#frame_info{unmasked_msg = UnmaskedMsg}, [ping | Recv],
[Frame | Send]};
10 -> % Pong
@@ -421,7 +421,7 @@ handle_data(tcp, FrameInfo, Data, Socket, WsHandleLoopPid, fast_tls, Shaper) ->
handle_data(_, FrameInfo, Data, Socket, WsHandleLoopPid, SockMod, Shaper) ->
handle_data_int(FrameInfo, Data, Socket, WsHandleLoopPid, SockMod, Shaper).
handle_data_int(FrameInfo, Data, Socket, WsHandleLoopPid, SocketMode, Shaper) ->
handle_data_int(FrameInfo, Data, Socket, WsHandleLoopPid, SockMod, Shaper) ->
{NewFrameInfo, Recv, Send} = process_frame(FrameInfo, Data),
lists:foreach(fun (El) ->
case El of
@@ -434,27 +434,27 @@ handle_data_int(FrameInfo, Data, Socket, WsHandleLoopPid, SocketMode, Shaper) ->
end
end,
Recv),
{NewFrameInfo, Send, handle_shaping(Data, Socket, SocketMode, Shaper)}.
{NewFrameInfo, Send, handle_shaping(Data, Socket, SockMod, Shaper)}.
websocket_close(Socket, WsHandleLoopPid,
SocketMode, CloseCode) when CloseCode > 0 ->
SockMod, CloseCode) when CloseCode > 0 ->
Frame = encode_frame(<<CloseCode:16/integer-big>>, 8),
SocketMode:send(Socket, Frame),
websocket_close(Socket, WsHandleLoopPid, SocketMode, 0);
websocket_close(Socket, WsHandleLoopPid, SocketMode, _CloseCode) ->
SockMod:send(Socket, Frame),
websocket_close(Socket, WsHandleLoopPid, SockMod, 0);
websocket_close(Socket, WsHandleLoopPid, SockMod, _CloseCode) ->
WsHandleLoopPid ! closed,
SocketMode:close(Socket).
SockMod:close(Socket).
get_origin() ->
ejabberd_option:websocket_origin().
handle_shaping(_Data, _Socket, _SocketMode, none) ->
handle_shaping(_Data, _Socket, _SockMod, none) ->
none;
handle_shaping(Data, Socket, SocketMode, Shaper) ->
handle_shaping(Data, Socket, SockMod, Shaper) ->
{NewShaper, Pause} = ejabberd_shaper:update(Shaper, byte_size(Data)),
if Pause > 0 ->
activate_after(Socket, self(), Pause);
true -> activate(Socket, SocketMode, once)
true -> activate(Socket, SockMod, once)
end,
NewShaper.
+13 -8
View File
@@ -104,12 +104,17 @@ delete(Server) ->
delete(Server, Module)
end, Modules).
delete(Server, Module) ->
delete(Server, Module1) ->
LServer = jid:nameprep(iolist_to_binary(Server)),
Module = case Module1 of
mod_pubsub -> pubsub_db;
_ -> Module1
end,
SQLMod = gen_mod:db_mod(sql, Module),
lists:foreach(
fun({Table, ConvertFun}) ->
delete(LServer, Table, ConvertFun)
end, Module:export(Server)).
end, SQLMod:export(Server)).
import(Server, Dir, ToType) ->
lists:foreach(
@@ -154,6 +159,7 @@ import_info(Mod) ->
%%% Internal functions
%%%----------------------------------------------------------------------
export(LServer, Table, IO, ConvertFun) ->
DbType = ejabberd_option:sql_type(LServer),
F = fun () ->
mnesia:read_lock_table(Table),
{_N, SQLs} =
@@ -163,7 +169,7 @@ export(LServer, Table, IO, ConvertFun) ->
[] ->
Acc;
SQL1 ->
SQL = format_queries(SQL1),
SQL = format_queries(DbType, SQL1),
if N < (?MAX_RECORDS_PER_TRANSACTION) - 1 ->
{N + 1, [SQL | SQLs]};
true ->
@@ -191,7 +197,7 @@ output(_LServer, Table, Fd, SQLs) ->
delete(LServer, Table, ConvertFun) ->
F = fun () ->
mnesia:write_lock_table(Table),
{_N, SQLs} =
{_N, _SQLs} =
mnesia:foldl(
fun(R, Acc) ->
case ConvertFun(LServer, R) of
@@ -202,8 +208,7 @@ delete(LServer, Table, ConvertFun) ->
Acc
end
end,
{0, []}, Table),
delete(LServer, Table, SQLs)
{0, []}, Table)
end,
mnesia:transaction(F).
@@ -368,10 +373,10 @@ format_error({error, eof}) ->
format_error({error, Posix}) ->
file:format_error(Posix).
format_queries(SQLs) ->
format_queries(DbType, SQLs) ->
lists:map(
fun(#sql_query{} = SQL) ->
ejabberd_sql:sql_query_to_iolist(SQL);
ejabberd_sql:sql_query_to_iolist(DbType, SQL);
(SQL) ->
SQL
end, SQLs).
+24 -5
View File
@@ -132,7 +132,8 @@
tls_options = [] :: [{certfile, string()} |
{cacertfile, string()} |
{depth, non_neg_integer()} |
{verify, non_neg_integer()}],
{verify, non_neg_integer()} |
{fail_if_no_peer_cert, boolean()}],
fd :: gen_tcp:socket() | undefined,
rootdn = <<"">> :: binary(),
passwd = <<"">> :: binary(),
@@ -604,9 +605,9 @@ init([Hosts, Port, Rootdn, Passwd, Opts]) ->
[]),
CertOpts;
Verify == soft ->
[{verify, 1}] ++ CertOpts ++ CacertOpts ++ DepthOpts;
[{verify, verify_peer}, {fail_if_no_peer_cert, false}] ++ CertOpts ++ CacertOpts ++ DepthOpts;
Verify == hard ->
[{verify, 2}] ++ CertOpts ++ CacertOpts ++ DepthOpts;
[{verify, verify_peer}, {fail_if_no_peer_cert, true}] ++ CertOpts ++ CacertOpts ++ DepthOpts;
true -> []
end,
{ok, connecting,
@@ -1035,22 +1036,40 @@ polish([H | T], Res,
polish(T, Res, [H | Ref]);
polish([], Res, Ref) -> {Res, Ref}.
-ifdef(NO_CUSTOMIZE_HOSTNAME_CHECK).
check_hostname_opt(TLSOpts) ->
TLSOpts.
-else.
check_hostname_opt(TLSOpts) ->
MatchFun = public_key:pkix_verify_hostname_match_fun(https),
[{customize_hostname_check, [{match_fun, MatchFun}]} | TLSOpts].
-endif.
host_tls_options(Host, TLSOpts) ->
case proplists:get_value(verify, TLSOpts) of
verify_peer ->
check_hostname_opt([{server_name_indication, Host} | TLSOpts]);
_ ->
TLSOpts
end.
%%-----------------------------------------------------------------------
%% Connect to next server in list and attempt to bind to it.
%%-----------------------------------------------------------------------
connect_bind(S) ->
Host = next_host(S#eldap.host, S#eldap.hosts),
HostS = binary_to_list(Host),
Opts = if S#eldap.tls == tls ->
[{packet, asn1}, {active, true}, {keepalive, true},
binary
| S#eldap.tls_options];
| host_tls_options(HostS, S#eldap.tls_options)];
true ->
[{packet, asn1}, {active, true}, {keepalive, true},
{send_timeout, ?SEND_TIMEOUT}, binary]
end,
?DEBUG("Connecting to LDAP server at ~ts:~p with options ~p",
[Host, S#eldap.port, Opts]),
HostS = binary_to_list(Host),
SockMod = case S#eldap.tls of
tls -> ssl;
_ -> gen_tcp
+26
View File
@@ -569,8 +569,15 @@ compile_result(Results) ->
[Error|_] -> Error
end.
maybe_define_lager_macro() ->
case list_to_integer(erlang:system_info(otp_release)) < 22 of
true -> [{d, 'LAGER'}];
false -> []
end.
compile_options() ->
[verbose, report_errors, report_warnings, debug_info, ?ALL_DEFS]
++ maybe_define_lager_macro()
++ [{i, filename:join(app_dir(App), "include")}
|| App <- [fast_xml, xmpp, p1_utils, ejabberd]]
++ [{i, filename:join(mod_dir(Mod), "include")}
@@ -631,6 +638,7 @@ install(Module, Spec, SrcDir, LibDir) ->
Errors = lists:dropwhile(fun({_, ok}) -> true;
(_) -> false
end, Files1++Files2),
inform_module_configuration(Module, LibDir, Files1),
Result = case Errors of
[{F, {error, E}}|_] ->
{error, {F, E}};
@@ -642,6 +650,24 @@ install(Module, Spec, SrcDir, LibDir) ->
file:set_cwd(CurDir),
Result.
inform_module_configuration(Module, LibDir, Files1) ->
Res = lists:filter(fun({[$c, $o, $n, $f |_], ok}) -> true;
(_) -> false
end, Files1),
case Res of
[{ConfigPath, ok}] ->
FullConfigPath = filename:join(LibDir, ConfigPath),
io:format("Module ~p has been installed and started.~n"
"It's configured in the file:~n ~s~n"
"Configure the module in that file, or remove it~n"
"and configure in your main ejabberd.yml~n",
[Module, FullConfigPath]);
[] ->
io:format("Module ~p has been installed.~n"
"Now you can configure it in your ejabberd.yml~n",
[Module])
end.
%% -- minimalist rebar spec parser, only support git
fetch_rebar_deps(SrcDir) ->
+1 -1
View File
@@ -262,7 +262,7 @@ expr_to_term(Expr) ->
Term.
term_to_expr(Term) ->
list_to_binary(io_lib:print(Term)).
list_to_binary(io_lib:print(Term, 1, 999999, -1)).
-spec now_to_usec(erlang:timestamp()) -> non_neg_integer().
now_to_usec({MSec, Sec, USec}) ->
+54 -26
View File
@@ -275,7 +275,7 @@ get_commands_spec() ->
result = {res, rescode},
result_example = ok,
result_desc = "Status code: 0 on success, 1 otherwise"},
#ejabberd_commands{name = status_num_host, tags = [session, stats],
#ejabberd_commands{name = status_num_host, tags = [session, statistics],
desc = "Number of logged users with this status in host",
policy = admin,
module = ?MODULE, function = status_num,
@@ -285,7 +285,7 @@ get_commands_spec() ->
result = {users, integer},
result_example = 23,
result_desc = "Number of connected sessions with given status type"},
#ejabberd_commands{name = status_num, tags = [session, stats],
#ejabberd_commands{name = status_num, tags = [session, statistics],
desc = "Number of logged users with this status",
policy = admin,
module = ?MODULE, function = status_num,
@@ -662,9 +662,11 @@ get_commands_spec() ->
"For example:\n"
" ejabberdctl srg_create group3 myserver.com "
"name desc \\\"group1\\\\ngroup2\\\"",
note = "changed in 21.07",
module = ?MODULE, function = srg_create,
args = [{group, binary}, {host, binary},
{name, binary}, {description, binary}, {display, binary}],
{label, binary}, {description, binary}, {display, binary}],
args_rename = [{name, label}],
args_example = [<<"group3">>, <<"myserver.com">>, <<"Group3">>,
<<"Third group">>, <<"group1\\\\ngroup2">>],
args_desc = ["Group identifier", "Group server name", "Group name",
@@ -744,7 +746,9 @@ get_commands_spec() ->
"Receiver JID", "Subject, or empty string", "Body"],
result = {res, rescode}},
#ejabberd_commands{name = send_stanza_c2s, tags = [stanza],
desc = "Send a stanza as if sent from a c2s session",
desc = "Send a stanza from an existing C2S session",
longdesc = "USER@HOST/RESOURCE must be an existing C2S session."
" As an alternative, use send_stanza instead.",
module = ?MODULE, function = send_stanza_c2s,
args = [{user, binary}, {host, binary}, {resource, binary}, {stanza, binary}],
args_example = [<<"admin">>, <<"myserver.com">>, <<"bot">>,
@@ -768,7 +772,7 @@ get_commands_spec() ->
args_desc = ["Username", "Server name", "Query XML element"],
result = {res, rescode}},
#ejabberd_commands{name = stats, tags = [stats],
#ejabberd_commands{name = stats, tags = [statistics],
desc = "Get statistical value: registeredusers onlineusers onlineusersnode uptimeseconds processes",
policy = admin,
module = ?MODULE, function = stats,
@@ -778,7 +782,7 @@ get_commands_spec() ->
result_example = 6,
result_desc = "Integer statistic value",
result = {stat, integer}},
#ejabberd_commands{name = stats_host, tags = [stats],
#ejabberd_commands{name = stats_host, tags = [statistics],
desc = "Get statistical value for this host: registeredusers onlineusers",
policy = admin,
module = ?MODULE, function = stats,
@@ -1243,23 +1247,42 @@ update_vcard_els(Data, ContentList, Els1) ->
%%%
add_rosteritem(LocalUser, LocalServer, User, Server, Nick, Group, Subs) ->
Jid = jid:make(LocalUser, LocalServer),
RosterItem = build_roster_item(User, Server, {add, Nick, Subs, Group}),
case mod_roster:set_item_and_notify_clients(Jid, RosterItem, true) of
ok -> ok;
_ -> error
case {jid:make(LocalUser, LocalServer), jid:make(User, Server)} of
{error, _} ->
throw({error, "Invalid 'localuser'/'localserver'"});
{_, error} ->
throw({error, "Invalid 'user'/'server'"});
{Jid, _Jid2} ->
RosterItem = build_roster_item(User, Server, {add, Nick, Subs, Group}),
case mod_roster:set_item_and_notify_clients(Jid, RosterItem, true) of
ok -> ok;
_ -> error
end
end.
subscribe(LU, LS, User, Server, Nick, Group, Subscription, _Xattrs) ->
ItemEl = build_roster_item(User, Server, {add, Nick, Subscription, Group}),
mod_roster:set_items(LU, LS, #roster_query{items = [ItemEl]}).
case {jid:make(LU, LS), jid:make(User, Server)} of
{error, _} ->
throw({error, "Invalid 'localuser'/'localserver'"});
{_, error} ->
throw({error, "Invalid 'user'/'server'"});
{_Jid, _Jid2} ->
ItemEl = build_roster_item(User, Server, {add, Nick, Subscription, Group}),
mod_roster:set_items(LU, LS, #roster_query{items = [ItemEl]})
end.
delete_rosteritem(LocalUser, LocalServer, User, Server) ->
Jid = jid:make(LocalUser, LocalServer),
RosterItem = build_roster_item(User, Server, remove),
case mod_roster:set_item_and_notify_clients(Jid, RosterItem, true) of
ok -> ok;
_ -> error
case {jid:make(LocalUser, LocalServer), jid:make(User, Server)} of
{error, _} ->
throw({error, "Invalid 'localuser'/'localserver'"});
{_, error} ->
throw({error, "Invalid 'user'/'server'"});
{Jid, _Jid2} ->
RosterItem = build_roster_item(User, Server, remove),
case mod_roster:set_item_and_notify_clients(Jid, RosterItem, true) of
ok -> ok;
_ -> error
end
end.
%% -----------------------------
@@ -1267,8 +1290,13 @@ delete_rosteritem(LocalUser, LocalServer, User, Server) ->
%% -----------------------------
get_roster(User, Server) ->
Items = ejabberd_hooks:run_fold(roster_get, Server, [], [{User, Server}]),
make_roster_xmlrpc(Items).
case jid:make(User, Server) of
error ->
throw({error, "Invalid 'user'/'server'"});
#jid{luser = U, lserver = S} ->
Items = ejabberd_hooks:run_fold(roster_get, S, [], [{U, S}]),
make_roster_xmlrpc(Items)
end.
%% Note: if a contact is in several groups, the contact is returned
%% several times, each one in a different group.
@@ -1430,12 +1458,12 @@ private_set2(Username, Host, Xml) ->
%%% Shared Roster Groups
%%%
srg_create(Group, Host, Name, Description, Display) ->
srg_create(Group, Host, Label, Description, Display) ->
DisplayList = case Display of
<<>> -> [];
_ -> ejabberd_regexp:split(Display, <<"\\\\n">>)
end,
Opts = [{name, Name},
Opts = [{label, Label},
{displayed_groups, DisplayList},
{description, Description}],
{atomic, _} = mod_shared_roster:create_group(Host, Group, Opts),
@@ -1494,10 +1522,10 @@ send_message(Type, From, To, Subject, Body) ->
#xmlel{name = <<"body">>,
children = [{xmlcdata, Body}]}]},
?NS_CLIENT, CodecOpts) of
#message{from = JID, subject = Subject, body = Body} = Msg ->
Msg2 = case {xmpp:get_text(Subject), xmpp:get_text(Body)} of
{_, <<>>} -> Msg;
{<<>>, _} -> Msg#message{subject = []};
#message{from = JID, subject = SubjectEl, body = BodyEl} = Msg ->
Msg2 = case {xmpp:get_text(SubjectEl), xmpp:get_text(BodyEl)} of
{Subject, <<>>} -> Msg;
{<<>>, Body} -> Msg#message{subject = []};
_ -> Msg
end,
State = #{jid => JID},
+2 -1
View File
@@ -63,7 +63,7 @@ depends(_Host, _Opts) ->
get_commands_spec() ->
[#ejabberd_commands{name = update_sql, tags = [sql],
desc = "Convert SQL DB to the new format",
desc = "Convert PostgreSQL DB to the new format",
module = ?MODULE, function = update_sql,
args = [],
args_example = [],
@@ -365,4 +365,5 @@ mod_doc() ->
?T("This module can be used to update existing SQL database "
"from the default to the new schema. Check the section "
"http://../database-ldap/#default-and-new-schemas[Default and New Schemas] for details. "
"Please note that only PostgreSQL is supported. "
"When the module is loaded use 'update_sql' ejabberdctl command.")}.
+2 -1
View File
@@ -208,9 +208,10 @@ need_check(Pkt) ->
_ ->
false
end,
IsError = (error == xmpp:get_type(Pkt)),
AllowLocalUsers = mod_block_strangers_opt:allow_local_users(LServer),
Access = mod_block_strangers_opt:access(LServer),
not (IsSelf orelse IsEmpty
not (IsSelf orelse IsEmpty orelse IsError
orelse acl:match_rule(LServer, Access, From) == allow
orelse ((AllowLocalUsers orelse From#jid.luser == <<"">>)
andalso ejabberd_router:is_my_host(From#jid.lserver))).
+45 -33
View File
@@ -226,40 +226,52 @@ disco_info(Acc, _, _, _Node, _Lang) ->
-spec c2s_presence_in(ejabberd_c2s:state(), presence()) -> ejabberd_c2s:state().
c2s_presence_in(C2SState,
#presence{from = From, to = To, type = Type} = Presence) ->
{Subscription, _, _} = ejabberd_hooks:run_fold(
roster_get_jid_info, To#jid.lserver,
{none, none, []},
[To#jid.luser, To#jid.lserver, From]),
ToSelf = (From#jid.luser == To#jid.luser)
and (From#jid.lserver == To#jid.lserver),
Insert = (Type == available)
and ((Subscription == both) or (Subscription == from) or ToSelf),
Delete = (Type == unavailable) or (Type == error),
if Insert or Delete ->
LFrom = jid:tolower(From),
Rs = maps:get(caps_resources, C2SState, gb_trees:empty()),
Caps = read_caps(Presence),
NewRs = case Caps of
nothing when Insert == true -> Rs;
_ when Insert == true ->
case gb_trees:lookup(LFrom, Rs) of
{value, Caps} -> Rs;
none ->
ejabberd_hooks:run(caps_add, To#jid.lserver,
[From, To,
get_features(To#jid.lserver, Caps)]),
gb_trees:insert(LFrom, Caps, Rs);
_ ->
ejabberd_hooks:run(caps_update, To#jid.lserver,
[From, To,
get_features(To#jid.lserver, Caps)]),
gb_trees:update(LFrom, Caps, Rs)
end;
_ -> gb_trees:delete_any(LFrom, Rs)
end,
C2SState#{caps_resources => NewRs};
true ->
C2SState
andalso (From#jid.lserver == To#jid.lserver),
Caps = read_caps(Presence),
Operation =
case {Type, ToSelf, Caps} of
{unavailable, _, _} -> delete;
{error, _, _} -> delete;
{available, _, nothing} -> skip;
{available, true, _} -> insert;
{available, _, _} ->
{Subscription, _, _} = ejabberd_hooks:run_fold(
roster_get_jid_info, To#jid.lserver,
{none, none, []},
[To#jid.luser, To#jid.lserver, From]),
case Subscription of
from -> insert;
both -> insert;
_ -> skip
end;
_ ->
skip
end,
case Operation of
skip ->
C2SState;
delete ->
LFrom = jid:tolower(From),
Rs = maps:get(caps_resources, C2SState, gb_trees:empty()),
C2SState#{caps_resources => gb_trees:delete_any(LFrom, Rs)};
insert ->
LFrom = jid:tolower(From),
Rs = maps:get(caps_resources, C2SState, gb_trees:empty()),
NewRs = case gb_trees:lookup(LFrom, Rs) of
{value, Caps} -> Rs;
none ->
ejabberd_hooks:run(caps_add, To#jid.lserver,
[From, To,
get_features(To#jid.lserver, Caps)]),
gb_trees:insert(LFrom, Caps, Rs);
_ ->
ejabberd_hooks:run(caps_update, To#jid.lserver,
[From, To,
get_features(To#jid.lserver, Caps)]),
gb_trees:update(LFrom, Caps, Rs)
end,
C2SState#{caps_resources => NewRs}
end.
-spec depends(binary(), gen_mod:opts()) -> [{module(), hard | soft}].
+11 -3
View File
@@ -326,7 +326,7 @@ remove_mam_for_user_with_peer(User, Server, Peer) ->
LServer = jid:nameprep(Server),
try jid:decode(Peer) of
Jid ->
Mod = gen_mod:db_mod(LServer, ?MODULE),
Mod = get_module_host(LServer),
case Mod:remove_from_archive(LUser, LServer, Jid) of
ok ->
{ok, <<"MAM archive removed">>};
@@ -339,6 +339,12 @@ remove_mam_for_user_with_peer(User, Server, Peer) ->
{error, <<"Invalid peer JID">>}
end.
get_module_host(LServer) ->
try gen_mod:db_mod(LServer, ?MODULE)
catch error:{module_not_loaded, ?MODULE, LServer} ->
gen_mod:db_mod(ejabberd_router:host_of_route(LServer), ?MODULE)
end.
-spec get_room_config([muc_roomconfig:property()], mod_muc_room:state(),
jid(), binary()) -> [muc_roomconfig:property()].
get_room_config(Fields, RoomState, _From, _Lang) ->
@@ -1286,9 +1292,11 @@ send(Msgs, Count, IsComplete,
RSMOut = make_rsm_out(Msgs, Count),
Result = if NS == ?NS_MAM_TMP ->
#mam_query{xmlns = NS, id = QID, rsm = RSMOut};
true ->
NS == ?NS_MAM_0 ->
#mam_fin{xmlns = NS, id = QID, rsm = RSMOut,
complete = IsComplete}
complete = IsComplete};
true ->
#mam_fin{xmlns = NS, rsm = RSMOut, complete = IsComplete}
end,
if NS /= ?NS_MAM_0 ->
lists:foreach(
+2 -2
View File
@@ -24,7 +24,7 @@
-module(mod_mix).
-behaviour(gen_mod).
-behaviour(gen_server).
-protocol({xep, 369, '0.13.0'}).
-protocol({xep, 369, '0.14.1'}).
%% API
-export([route/1]).
@@ -166,7 +166,7 @@ process_disco_info(#iq{type = get, to = #jid{luser = <<>>} = To,
[ServerHost, ?MODULE, <<"">>, Lang]),
Name = mod_mix_opt:name(ServerHost),
Identity = #identity{category = <<"conference">>,
type = <<"text">>,
type = <<"mix">>,
name = translate:translate(Lang, Name)},
Features = [?NS_DISCO_INFO, ?NS_DISCO_ITEMS,
?NS_MIX_CORE_0, ?NS_MIX_CORE_SEARCHABLE_0,

Some files were not shown because too many files have changed in this diff Show More