Compare commits
538 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e4ec23919d | |||
| 1c095b609a | |||
| a819514e43 | |||
| 16cd93d587 | |||
| a8e5984f5f | |||
| 1a45637860 | |||
| 8cb3f61f88 | |||
| 4bc4f54e43 | |||
| 08774b1b5a | |||
| 300e765e20 | |||
| 951599be21 | |||
| 8bea14837e | |||
| 09250d6121 | |||
| 5968b35320 | |||
| f364fcda56 | |||
| 170874e115 | |||
| bec499a4a1 | |||
| d6709bd53a | |||
| 1cd1dd9f23 | |||
| af198dbe92 | |||
| 80ff4ad3d3 | |||
| 6e1691e2fa | |||
| e52c324a5e | |||
| e7b1f21e1c | |||
| a2d2581199 | |||
| eedd9496e4 | |||
| 3d4775d555 | |||
| 7f11f4a1fb | |||
| 612f15ab17 | |||
| af9ff6f1a1 | |||
| 9664de5242 | |||
| b13c51c8cf | |||
| 8229ee8dd8 | |||
| 476acbfa44 | |||
| 23dd81d18c | |||
| f08595b0e5 | |||
| 50b8500bd5 | |||
| 1cacd48261 | |||
| cf11acc450 | |||
| 0c18dd7068 | |||
| 4e807d69e8 | |||
| a61b7b1d98 | |||
| a55c85252f | |||
| 0168e39bb3 | |||
| 8f8b6870a0 | |||
| dc7208ed1c | |||
| 60b0b918a6 | |||
| d9e2d4e6a9 | |||
| 8fc80178b6 | |||
| c801bd9411 | |||
| b9d5a3350d | |||
| 2bb0095a32 | |||
| eda360914e | |||
| 042172eae1 | |||
| 0eaab78f67 | |||
| 5ec65571f8 | |||
| 7bbc98b04c | |||
| eda6b80ece | |||
| 2ddb7be19a | |||
| 04f20a21fb | |||
| 40ae9b33ef | |||
| e2357ecd96 | |||
| 0116287405 | |||
| 6ee534b262 | |||
| 42f72a49b1 | |||
| 771acc3ac7 | |||
| 5706aaa89c | |||
| c17bbc8859 | |||
| 8f317c0059 | |||
| d1c654a7e1 | |||
| ae5c31b06d | |||
| b09cda5c17 | |||
| 7887392c1d | |||
| cc2b7d2832 | |||
| 0a69935b6b | |||
| 4b7c74415f | |||
| 418baf4fa6 | |||
| fcf647738d | |||
| 3c9ab9e53d | |||
| c339c9b2ad | |||
| 4ef32bb18f | |||
| 0f87034539 | |||
| acee58f6bb | |||
| ceeef24faa | |||
| 201b0b3725 | |||
| 5f8b41a357 | |||
| a003ef556b | |||
| cb91e10803 | |||
| 5190866a24 | |||
| 473a58e3c2 | |||
| 3e6b88cbc3 | |||
| 362d7f617d | |||
| d11df52abf | |||
| 906161b27f | |||
| 347e8b28ef | |||
| c85c2796f4 | |||
| df72de96ae | |||
| e1f8233d08 | |||
| 38d2a27c56 | |||
| 6a42119292 | |||
| 89787875d4 | |||
| d76ae701cd | |||
| c4db156ad2 | |||
| d95778ea16 | |||
| a9b452fba9 | |||
| afed9e919e | |||
| 5252dcbd2c | |||
| a5cfac76dd | |||
| 45aa32f6fe | |||
| 2372e30150 | |||
| f3b55596b2 | |||
| 84eee8d5a7 | |||
| a800a5d4df | |||
| dfa47556d1 | |||
| 77111aeec1 | |||
| c9ac75474f | |||
| 0fcaef0566 | |||
| 031c7412a8 | |||
| 594ff79514 | |||
| 8f3f74a6d7 | |||
| ff2050b301 | |||
| 89ea1dd1c4 | |||
| 66902b788b | |||
| ec8cb81c0d | |||
| 1a24ac62e5 | |||
| 78fb913a00 | |||
| e521c8368a | |||
| ac8c536b50 | |||
| 84d9ee07b4 | |||
| ab9ac62138 | |||
| beaf351ba4 | |||
| 37d3a4e1f5 | |||
| 566c046cd5 | |||
| df921fef40 | |||
| 56e7affdfd | |||
| bef66dba24 | |||
| e62af41fa8 | |||
| 472089a328 | |||
| c4d582ace4 | |||
| a4e320c263 | |||
| 7d3d008940 | |||
| 3be9c27509 | |||
| 3ef6e4c834 | |||
| a15e689386 | |||
| 7c8a452b00 | |||
| e5d202a0bf | |||
| 083dfe01ea | |||
| f0c745b916 | |||
| 9ff1a80db4 | |||
| 5480ee29fd | |||
| 0d4b0b4218 | |||
| cfe396e155 | |||
| 2163cbb22e | |||
| 6b3f228327 | |||
| e58e6a09dd | |||
| 2d05ddd466 | |||
| 975f4c56d4 | |||
| 8eef2f02bf | |||
| 2f7c69fd14 | |||
| 02eeebd41a | |||
| 99610c3357 | |||
| aad740f34c | |||
| a70c72e50e | |||
| a2fdc75730 | |||
| b82789f11d | |||
| 6b7d70adf6 | |||
| 10f10a2fd3 | |||
| 35c4e740ab | |||
| e3085a4d48 | |||
| e8d008c392 | |||
| 674ab27700 | |||
| 9442a583bc | |||
| 9787416e88 | |||
| fbe2995696 | |||
| 33251cd5a8 | |||
| f387934886 | |||
| fb39b163df | |||
| 011535f0de | |||
| 75d3152a0f | |||
| 6c94d040fa | |||
| e8921d79ba | |||
| db8bd0126b | |||
| 6719d9669b | |||
| 8b13226d00 | |||
| 545f9ce525 | |||
| 437f68a9f3 | |||
| 7f1e9d3972 | |||
| 453e249de3 | |||
| 8688030d7a | |||
| 6e2003c2e2 | |||
| 5ed8959eba | |||
| 7623ebd327 | |||
| 522eb0fe9d | |||
| 7dd171322d | |||
| 752652e56c | |||
| 2582a478ab | |||
| 52ff5de564 | |||
| ba793af8b7 | |||
| 3304ecd1f0 | |||
| 4e0394cab3 | |||
| eaa963a840 | |||
| 31c13cc1c8 | |||
| 310aa7a00d | |||
| fafd605d4d | |||
| 078f3583f0 | |||
| 0b337329ba | |||
| f5df63554f | |||
| 46c4f46451 | |||
| e034864c12 | |||
| 91f38cc849 | |||
| e616d2686f | |||
| 5a09d671ab | |||
| 58d49d2867 | |||
| 8bb58ba3c3 | |||
| 017ce4e092 | |||
| 49859683b0 | |||
| 169b83b36d | |||
| 86435ba9aa | |||
| 431c34709c | |||
| cf6d67ceed | |||
| e2d6bc95a4 | |||
| ef0cf5d3d7 | |||
| 06f570f4ff | |||
| 730dfe8fc7 | |||
| e99ecf6d06 | |||
| 83c7da3831 | |||
| 8dc4dd7f3b | |||
| 66b7caafe0 | |||
| 7c0b2f5425 | |||
| 4645885180 | |||
| 472d046426 | |||
| 613d175f37 | |||
| 5619d39bd3 | |||
| 959e0ff1c9 | |||
| 2c228e6414 | |||
| 82468bff00 | |||
| 5f82846732 | |||
| 09c75af15c | |||
| 91964b1aba | |||
| af2e9169e6 | |||
| 4637e2c66b | |||
| 1f1a98d7ae | |||
| cea23b055b | |||
| 41a0eae0bd | |||
| 5fab00011e | |||
| ca5f028016 | |||
| b43444f674 | |||
| 866085c918 | |||
| 585c5afd1a | |||
| 6ec5c7c4d8 | |||
| 6b3875814c | |||
| a63bbe8a23 | |||
| bc118986b7 | |||
| 3a51c801e1 | |||
| 983da9c887 | |||
| 8d8dee5acf | |||
| 92feebd0fa | |||
| 0b423eb287 | |||
| f7b6446c74 | |||
| deb87f2dfa | |||
| 7d7c739cb3 | |||
| b1e2538488 | |||
| 7b9e59d15d | |||
| 794d0bbe69 | |||
| 60d422eb8e | |||
| 52df4fa024 | |||
| f7ffdfa15d | |||
| 4900ac31a7 | |||
| 6ebebdd02d | |||
| 112a18f966 | |||
| 7d623d5eb4 | |||
| 4819738e8f | |||
| e30e7686e3 | |||
| 290432c0ee | |||
| 6563267055 | |||
| ecf7b0282e | |||
| ea6e85d926 | |||
| b4d107301d | |||
| 948318ca19 | |||
| 89aa7baa5b | |||
| fead37d1c5 | |||
| 95928a7cd4 | |||
| 1ecc9ac48c | |||
| eaecb9b65c | |||
| 288196c7e8 | |||
| 2948cddebf | |||
| 438dc57def | |||
| 4d64fbb0ac | |||
| 0283c6cdfe | |||
| d4e7b0cda0 | |||
| e0781d9217 | |||
| f04fe5f743 | |||
| 66a5aff323 | |||
| 5746c08f72 | |||
| 39acf823ef | |||
| 2ea9e6ed59 | |||
| 21c75ebce5 | |||
| 32e0a88edc | |||
| bd91e2da16 | |||
| f3d24b6a07 | |||
| d1377da151 | |||
| d471be26cf | |||
| 31f6a9e66e | |||
| d736c47649 | |||
| 0e4806820e | |||
| 3850b91571 | |||
| 7b0174a626 | |||
| 2270df86d9 | |||
| a04131c6d7 | |||
| e5830253b9 | |||
| b7a07087d1 | |||
| adf56dedf3 | |||
| 6bfd8b8e9a | |||
| 1babae067d | |||
| 3ae4797848 | |||
| 86f0a9790d | |||
| 54acf9bde4 | |||
| 8f27a697c0 | |||
| c9a712a16a | |||
| d6e81ac06b | |||
| b0b371d23a | |||
| dd772404c5 | |||
| bed5e80ef9 | |||
| 9ccdb5d78b | |||
| 5bef1a8f77 | |||
| 4f1637fa40 | |||
| 796cb6634b | |||
| bb5480756a | |||
| edb030f49a | |||
| 0ed4ceebea | |||
| 31f7eadfca | |||
| 1c72c45404 | |||
| f8fd9969e1 | |||
| 8d09655a89 | |||
| a06b627631 | |||
| cb41c8ef80 | |||
| d4cea0f78f | |||
| 4d20abd7b6 | |||
| 351ad528f9 | |||
| 006da5589e | |||
| 5f32dd3959 | |||
| a9269df2aa | |||
| a7d82d6ecb | |||
| 5b10b58c9f | |||
| ae24f7d787 | |||
| 1dfd9fd568 | |||
| f655ab2ffc | |||
| 302294faec | |||
| b6a637c121 | |||
| 60009ece44 | |||
| 41fad8956b | |||
| f0c32433dc | |||
| 78f50c58bf | |||
| 133b8d42a3 | |||
| 3785b3e951 | |||
| 70e1545d3a | |||
| 8aaf9bffa0 | |||
| d65b785f5d | |||
| 9aabd59a1f | |||
| 8806fdc1c2 | |||
| 1922bf21f0 | |||
| c98ddeb59f | |||
| 613214da18 | |||
| 38693a670b | |||
| a97a60a888 | |||
| 49365da481 | |||
| 70e84021f2 | |||
| 24e033ac79 | |||
| 658ab235ba | |||
| 2f16a160c0 | |||
| 4a2f62062e | |||
| 33d4126290 | |||
| 87315e92a8 | |||
| 494add4fd0 | |||
| 3b7458bbc2 | |||
| f05a4d1638 | |||
| 75d2cbcb14 | |||
| f9fa168d84 | |||
| 5ad1d08b89 | |||
| dcb068c7ad | |||
| 2d32d2f25e | |||
| 307e57a105 | |||
| 8e68e89816 | |||
| 1564060c6c | |||
| f39ccd73c5 | |||
| 01689bc6b9 | |||
| 024a80d41f | |||
| f485109c39 | |||
| bde46896d6 | |||
| 0c30b012f7 | |||
| 14b39a0ee4 | |||
| e380eee223 | |||
| 1959546ff9 | |||
| 92f5509b35 | |||
| 1a2e6b02ab | |||
| 56bf156b6f | |||
| 5632901820 | |||
| 92b6c12420 | |||
| 062d58026a | |||
| 7ef85dddea | |||
| 4a9e7f0a3a | |||
| cffe224d4a | |||
| 15c27c9ddd | |||
| 149f8e2b45 | |||
| 2ab31cb613 | |||
| 03870f962c | |||
| 405e9b24b0 | |||
| 3c51ca06d5 | |||
| 02cfb11a6d | |||
| 4e875c7fb7 | |||
| 21f2817f40 | |||
| 31e4ccf78b | |||
| bfedd21c98 | |||
| 9f3cdad3f7 | |||
| 931866ee33 | |||
| b3facf092a | |||
| 70c1e1d0b1 | |||
| aea394861d | |||
| 2e33904bb8 | |||
| 2d3bbd43d7 | |||
| 6c0e9ef575 | |||
| ca62271a89 | |||
| c96a1805e8 | |||
| babff870a8 | |||
| 5cd3de9cd7 | |||
| 437d8c6b7c | |||
| 440eef74e9 | |||
| c849552177 | |||
| 6134c67df4 | |||
| aa60140ba8 | |||
| 59135cac6f | |||
| 8d69d4aaba | |||
| 426b7ca769 | |||
| b61d16dd33 | |||
| 807af3c08a | |||
| d07424365d | |||
| 70fe2948b9 | |||
| a5166f3946 | |||
| 11b00b92e9 | |||
| c10e43f95f | |||
| eeffc77a1a | |||
| 254686ab46 | |||
| 4a6fc46713 | |||
| bde3bce1e7 | |||
| f76dcd0d48 | |||
| 7da8d9e4e3 | |||
| 3a7d02dbd3 | |||
| 350af319bf | |||
| f81473fc65 | |||
| b6dcd41225 | |||
| db2baa8f84 | |||
| a894d25b1f | |||
| a93991bef2 | |||
| 7127d067c8 | |||
| ba326eb976 | |||
| fd50b2169b | |||
| 00d8b2ac30 | |||
| cac23c39c9 | |||
| a5813b798f | |||
| 191cd2af3c | |||
| f2cfee11de | |||
| b0c79c57b0 | |||
| 8ea523889b | |||
| b44c462b0e | |||
| 0987700a27 | |||
| ff4f052bb1 | |||
| 100b821c1a | |||
| 893c47a2e0 | |||
| 694af69982 | |||
| c576f340f9 | |||
| 179a0cf255 | |||
| a45ecb70ff | |||
| df1ab9149f | |||
| cb54444f00 | |||
| c77e7fbb7d | |||
| 40625b29f2 | |||
| 2624f3ba51 | |||
| 44832e12b3 | |||
| caa8d0c411 | |||
| 7e72d18292 | |||
| b0a81778af | |||
| 652774a83c | |||
| 2aea503a2a | |||
| 0d8aacb3e7 | |||
| e6be70943f | |||
| c86e4faba3 | |||
| c3c06ccd1c | |||
| 18b569a356 | |||
| 261acfce54 | |||
| c8567f1de2 | |||
| 35a0e27d04 | |||
| 73f7b2ba38 | |||
| 8a693df6e6 | |||
| c41bdea1f1 | |||
| cccbf7de12 | |||
| 660a2735f0 | |||
| 77136bccdf | |||
| b8b6fc0da5 | |||
| 8ecf8d7e27 | |||
| 4134edf8de | |||
| a77d53d738 | |||
| 49a3424a26 | |||
| 92a60ff7fd | |||
| 33c7d36a95 | |||
| 6c7316cbdd | |||
| 09da9eeb95 | |||
| 76d4ba66b2 | |||
| f284fc3284 | |||
| 86a59fb469 | |||
| 31da259a75 | |||
| 363711a370 | |||
| bf98fa0c01 | |||
| cd923838c3 | |||
| a22ebd3c49 | |||
| 353d16b8ef | |||
| 6bb0dc12f1 | |||
| ad00ec1518 | |||
| c03140d4be | |||
| ea8aa1f25b | |||
| 8fe6ed011d | |||
| 35cde6787d | |||
| 23b28ec60f | |||
| 59ae9bea76 | |||
| 7be707f7bc | |||
| 200815dcdb | |||
| 2d1c416daf | |||
| 3aaebe98f4 | |||
| 2ee7642816 | |||
| bf63d09d80 | |||
| 28c4c87956 | |||
| d0b7cd599b | |||
| cc1839a250 | |||
| 7d37715f8b | |||
| 091b4568d5 | |||
| cc0503fd5e | |||
| 4862251f34 | |||
| 987d796439 | |||
| 628571f8cf |
-20
@@ -16,23 +16,3 @@
|
||||
/doc/*.toc
|
||||
/doc/contributed_modules.tex
|
||||
/doc/version.tex
|
||||
/src/*.beam
|
||||
/src/*.so
|
||||
/src/*.so.dSYM
|
||||
/src/*/*.beam
|
||||
/src/*/Makefile
|
||||
/src/Makefile
|
||||
/src/XmppAddr.asn1db
|
||||
/src/XmppAddr.erl
|
||||
/src/XmppAddr.hrl
|
||||
/src/aclocal.m4
|
||||
/src/autom4te.cache
|
||||
/src/config.log
|
||||
/src/config.status
|
||||
/src/ejabberd.init
|
||||
/src/ejabberdctl.example
|
||||
/src/eldap/ELDAPv3.asn1db
|
||||
/src/eldap/ELDAPv3.erl
|
||||
/src/eldap/ELDAPv3.hrl
|
||||
/src/eldap/eldap_filter_yecc.erl
|
||||
/src/epam
|
||||
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
REBAR = @REBAR@
|
||||
INSTALL = @INSTALL@
|
||||
SED = @SED@
|
||||
ERL = @ERL@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
DESTDIR =
|
||||
|
||||
# /etc/ejabberd/
|
||||
ETCDIR = $(DESTDIR)@sysconfdir@/ejabberd
|
||||
|
||||
# /sbin/
|
||||
SBINDIR = $(DESTDIR)@sbindir@
|
||||
|
||||
# /lib/ejabberd/
|
||||
EJABBERDDIR = $(DESTDIR)@libdir@/ejabberd
|
||||
|
||||
# /share/doc/ejabberd
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
datarootdir = @datarootdir@
|
||||
DOCDIR = $(DESTDIR)@docdir@
|
||||
|
||||
# /usr/lib/ejabberd/ebin/
|
||||
BEAMDIR = $(EJABBERDDIR)/ebin
|
||||
|
||||
# /usr/lib/ejabberd/include/
|
||||
INCLUDEDIR = $(EJABBERDDIR)/include
|
||||
|
||||
# /usr/lib/ejabberd/priv/
|
||||
PRIVDIR = $(EJABBERDDIR)/priv
|
||||
|
||||
# /usr/lib/ejabberd/priv/bin
|
||||
PBINDIR = $(PRIVDIR)/bin
|
||||
|
||||
# /usr/lib/ejabberd/priv/lib
|
||||
SODIR = $(PRIVDIR)/lib
|
||||
|
||||
# /usr/lib/ejabberd/priv/msgs
|
||||
MSGSDIR = $(PRIVDIR)/msgs
|
||||
|
||||
# /var/lib/ejabberd/
|
||||
SPOOLDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
|
||||
|
||||
# /var/lock/ejabberdctl
|
||||
CTLLOCKDIR = $(DESTDIR)@localstatedir@/lock/ejabberdctl
|
||||
|
||||
# /var/lib/ejabberd/.erlang.cookie
|
||||
COOKIEFILE = $(SPOOLDIR)/.erlang.cookie
|
||||
|
||||
# /var/log/ejabberd/
|
||||
LOGDIR = $(DESTDIR)@localstatedir@/log/ejabberd
|
||||
|
||||
INSTALLUSER=@INSTALLUSER@
|
||||
# if no user was enabled, don't set privileges or ownership
|
||||
ifeq ($(INSTALLUSER),)
|
||||
O_USER=
|
||||
G_USER=
|
||||
CHOWN_COMMAND=echo
|
||||
CHOWN_OUTPUT=/dev/null
|
||||
INIT_USER=root
|
||||
else
|
||||
O_USER=-o $(INSTALLUSER)
|
||||
G_USER=-g $(INSTALLUSER)
|
||||
CHOWN_COMMAND=chown
|
||||
CHOWN_OUTPUT=&1
|
||||
INIT_USER=$(INSTALLUSER)
|
||||
endif
|
||||
|
||||
all: deps src
|
||||
|
||||
deps:
|
||||
$(REBAR) get-deps
|
||||
|
||||
src:
|
||||
$(REBAR) compile
|
||||
|
||||
translations:
|
||||
contrib/extract_translations/prepare-translation.sh -updateall
|
||||
|
||||
doc:
|
||||
echo making $$target in doc; \
|
||||
(cd doc && $(MAKE) $$target) || exit 1
|
||||
|
||||
edoc:
|
||||
$(ERL) -noinput +B -eval \
|
||||
'case edoc:application(ejabberd, ".", []) of ok -> halt(0); error -> halt(1) end.'
|
||||
|
||||
install: all
|
||||
#
|
||||
# Configuration files
|
||||
$(INSTALL) -d -m 750 $(G_USER) $(ETCDIR)
|
||||
[ -f $(ETCDIR)/ejabberd.cfg ] \
|
||||
&& $(INSTALL) -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg-new \
|
||||
|| $(INSTALL) -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
|
||||
$(SED) -e "s*{{rootdir}}*@prefix@*" \
|
||||
-e "s*{{installuser}}*@INSTALLUSER@*" \
|
||||
-e "s*{{libdir}}*@libdir@*" \
|
||||
-e "s*{{sysconfdir}}*@sysconfdir@*" \
|
||||
-e "s*{{localstatedir}}*@localstatedir@*" \
|
||||
-e "s*{{docdir}}*@docdir@*" \
|
||||
-e "s*{{erl}}*@ERL@*" ejabberdctl.template \
|
||||
> ejabberdctl.example
|
||||
[ -f $(ETCDIR)/ejabberdctl.cfg ] \
|
||||
&& $(INSTALL) -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg-new \
|
||||
|| $(INSTALL) -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg
|
||||
$(INSTALL) -b -m 644 $(G_USER) inetrc $(ETCDIR)/inetrc
|
||||
#
|
||||
# Administration script
|
||||
[ -d $(SBINDIR) ] || $(INSTALL) -d -m 755 $(SBINDIR)
|
||||
$(INSTALL) -m 550 $(G_USER) ejabberdctl.example $(SBINDIR)/ejabberdctl
|
||||
#
|
||||
# Init script
|
||||
$(SED) -e "s*@ctlscriptpath@*$(SBINDIR)*" \
|
||||
-e "s*@installuser@*$(INIT_USER)*" ejabberd.init.template \
|
||||
> ejabberd.init
|
||||
chmod 755 ejabberd.init
|
||||
#
|
||||
# Binary Erlang files
|
||||
$(INSTALL) -d $(BEAMDIR)
|
||||
$(INSTALL) -m 644 ebin/*.app $(BEAMDIR)
|
||||
$(INSTALL) -m 644 ebin/*.beam $(BEAMDIR)
|
||||
$(INSTALL) -m 644 deps/*/ebin/*.app $(BEAMDIR)
|
||||
$(INSTALL) -m 644 deps/*/ebin/*.beam $(BEAMDIR)
|
||||
rm -f $(BEAMDIR)/configure.beam
|
||||
#
|
||||
# ejabberd header files
|
||||
$(INSTALL) -d $(INCLUDEDIR)
|
||||
$(INSTALL) -m 644 include/*.hrl $(INCLUDEDIR)
|
||||
$(INSTALL) -m 644 deps/*/include/*.hrl $(INCLUDEDIR)
|
||||
#
|
||||
# Binary C programs
|
||||
$(INSTALL) -d $(PBINDIR)
|
||||
$(INSTALL) -m 750 $(O_USER) tools/captcha.sh $(PBINDIR)
|
||||
#
|
||||
# Binary system libraries
|
||||
$(INSTALL) -d $(SODIR)
|
||||
#$(INSTALL) -m 644 priv/lib/*.so $(SODIR)
|
||||
$(INSTALL) -m 644 deps/*/priv/lib/*.so $(SODIR)
|
||||
#
|
||||
# Translated strings
|
||||
$(INSTALL) -d $(MSGSDIR)
|
||||
$(INSTALL) -m 644 priv/msgs/*.msg $(MSGSDIR)
|
||||
#
|
||||
# Spool directory
|
||||
$(INSTALL) -d -m 750 $(O_USER) $(SPOOLDIR)
|
||||
$(CHOWN_COMMAND) -R @INSTALLUSER@ $(SPOOLDIR) >$(CHOWN_OUTPUT)
|
||||
chmod -R 750 $(SPOOLDIR)
|
||||
[ ! -f $(COOKIEFILE) ] || { $(CHOWN_COMMAND) @INSTALLUSER@ $(COOKIEFILE) >$(CHOWN_OUTPUT) ; chmod 400 $(COOKIEFILE) ; }
|
||||
#
|
||||
# ejabberdctl lock directory
|
||||
$(INSTALL) -d -m 750 $(O_USER) $(CTLLOCKDIR)
|
||||
$(CHOWN_COMMAND) -R @INSTALLUSER@ $(CTLLOCKDIR) >$(CHOWN_OUTPUT)
|
||||
chmod -R 750 $(CTLLOCKDIR)
|
||||
#
|
||||
# Log directory
|
||||
$(INSTALL) -d -m 750 $(O_USER) $(LOGDIR)
|
||||
$(CHOWN_COMMAND) -R @INSTALLUSER@ $(LOGDIR) >$(CHOWN_OUTPUT)
|
||||
chmod -R 750 $(LOGDIR)
|
||||
#
|
||||
# Documentation
|
||||
$(INSTALL) -d $(DOCDIR)
|
||||
$(INSTALL) -m 644 doc/dev.html $(DOCDIR)
|
||||
$(INSTALL) -m 644 doc/guide.html $(DOCDIR)
|
||||
$(INSTALL) -m 644 doc/*.png $(DOCDIR)
|
||||
$(INSTALL) -m 644 doc/*.txt $(DOCDIR)
|
||||
[ -f doc/guide.pdf ] \
|
||||
&& $(INSTALL) -m 644 doc/guide.pdf $(DOCDIR) \
|
||||
|| echo "No doc/guide.pdf was built"
|
||||
$(INSTALL) -m 644 COPYING $(DOCDIR)
|
||||
|
||||
uninstall: uninstall-binary
|
||||
|
||||
uninstall-binary:
|
||||
rm -f $(SBINDIR)/ejabberdctl
|
||||
rm -fr $(DOCDIR)
|
||||
rm -f $(BEAMDIR)/*.beam
|
||||
rm -f $(BEAMDIR)/*.app
|
||||
rm -fr $(BEAMDIR)
|
||||
rm -f $(INCLUDEDIR)/*.hrl
|
||||
rm -fr $(INCLUDEDIR)
|
||||
rm -fr $(PBINDIR)
|
||||
rm -f $(SODIR)/*.so
|
||||
rm -fr $(SODIR)
|
||||
rm -f $(MSGSDIR)/*.msgs
|
||||
rm -fr $(MSGSDIR)
|
||||
rm -fr $(PRIVDIR)
|
||||
rm -fr $(EJABBERDDIR)
|
||||
|
||||
uninstall-all: uninstall-binary
|
||||
rm -rf $(ETCDIR)
|
||||
rm -rf $(EJABBERDDIR)
|
||||
rm -rf $(SPOOLDIR)
|
||||
rm -rf $(CTLLOCKDIR)
|
||||
rm -rf $(LOGDIR)
|
||||
|
||||
clean:
|
||||
$(REBAR) clean
|
||||
|
||||
clean-rel:
|
||||
rm -rf rel/ejabberd
|
||||
|
||||
distclean: clean clean-rel
|
||||
rm -f config.status
|
||||
rm -f config.log
|
||||
rm -rf autom4te.cache
|
||||
rm -rf deps
|
||||
rm -rf ebin
|
||||
rm -f Makefile
|
||||
rm -f vars.config
|
||||
rm -f src/ejabberd.app.src
|
||||
[ ! -f ../ChangeLog ] || rm -f ../ChangeLog
|
||||
|
||||
rel: all
|
||||
$(REBAR) generate
|
||||
|
||||
TAGS:
|
||||
etags *.erl
|
||||
|
||||
Makefile: Makefile.in
|
||||
|
||||
deps := $(filter-out deps/riak_pb/ebin, $(wildcard deps/*/ebin))
|
||||
|
||||
erlang.plt:
|
||||
-dialyzer --build_plt --output_plt erlang.plt \
|
||||
--apps kernel stdlib sasl crypto public_key ssl mnesia \
|
||||
inets odbc tools compiler erts webtool runtime_tools asn1 \
|
||||
observer xmerl et gs wx syntax_tools $(deps)
|
||||
|
||||
plt: erlang.plt
|
||||
|
||||
dialyzer: plt
|
||||
-dialyzer --plt erlang.plt --add_to_plt --output_plt ejabberd.plt \
|
||||
--get_warnings -o dialyzer.log ebin
|
||||
|
||||
.PHONY: src doc edoc dialyzer Makefile TAGS clean clean-rel distclean rel plt \
|
||||
install uninstall uninstall-binary uninstall-all translations
|
||||
@@ -59,6 +59,8 @@ release : build release_clean
|
||||
copy mod_muc\*.erl $(SRC_DIR)\mod_muc
|
||||
mkdir $(SRC_DIR)\mod_pubsub
|
||||
copy mod_pubsub\*.erl $(SRC_DIR)\mod_pubsub
|
||||
mkdir $(SRC_DIR)\mod_pubsub_ng
|
||||
copy mod_pubsub_ng\*.erl $(SRC_DIR)\mod_pubsub_ng
|
||||
mkdir $(SRC_DIR)\mod_proxy65
|
||||
copy mod_proxy65\*.erl $(SRC_DIR)\mod_proxy65
|
||||
copy mod_proxy65\*.hrl $(SRC_DIR)\mod_proxy65
|
||||
@@ -100,6 +102,8 @@ all-recursive :
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\mod_pubsub
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\mod_pubsub_ng
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\mod_proxy65
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\stringprep
|
||||
@@ -143,6 +147,8 @@ clean-recursive :
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\mod_pubsub
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\mod_pubsub_ng
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\mod_proxy65
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\stringprep
|
||||
@@ -170,7 +176,7 @@ LD=link.exe
|
||||
LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" "$(EXPAT_LIB)" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib
|
||||
|
||||
$(DLL) : $(OBJECT)
|
||||
$(LD) $(LD_FLAGS) -out:$(DLL) $(OBJECT)
|
||||
$(LD) $(LD_FLAGS) -out:$@ $<
|
||||
|
||||
$(OBJECT) : $(SOURCE)
|
||||
$(CC) $(CC_FLAGS) -c -Fo$(OBJECT) $(SOURCE)
|
||||
$(CC) $(CC_FLAGS) -c -Fo$@ $<
|
||||
@@ -9,13 +9,11 @@ To compile ejabberd you need:
|
||||
- GNU Make
|
||||
- GCC
|
||||
- Libexpat 1.95 or higher
|
||||
- Erlang/OTP R10B-9 or higher. Recommended: R12B-5 and R13B04.
|
||||
- Erlang/OTP R10B-9 or higher. Recommended: R13B04 and R14B04.
|
||||
Avoid R14A and R14B.
|
||||
- OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption.
|
||||
- Zlib 1.2.3 or higher, for Stream Compression support
|
||||
(XEP-0138). Optional.
|
||||
- Erlang mysql library. Optional. MySQL authentication/storage.
|
||||
- Erlang pgsql library. Optional. PostgreSQL authentication/storage.
|
||||
- PAM library. Optional. For Pluggable Authentication Modules (PAM).
|
||||
- GNU Iconv 1.8 or higher, for the IRC Transport
|
||||
(mod_irc). Optional. Not needed on systems with GNU Libc.
|
||||
@@ -25,7 +23,7 @@ To compile ejabberd you need:
|
||||
|
||||
1. Compile and install on *nix systems
|
||||
|
||||
To compile ejabberd, go to the directory src/ and execute the commands:
|
||||
To compile ejabberd execute the commands:
|
||||
./configure
|
||||
make
|
||||
|
||||
|
||||
Vendored
+1538
-3225
File diff suppressed because it is too large
Load Diff
+266
@@ -0,0 +1,266 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.53)
|
||||
AC_PACKAGE_VERSION(3.0.0)
|
||||
AC_INIT(ejabberd, 3.0.0, [ejabberd@process-one.net], [ejabberd])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_SED
|
||||
|
||||
if test "x$GCC" = "xyes"; then
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
fi
|
||||
|
||||
# Checks Erlang runtime and compiler
|
||||
AC_ERLANG_NEED_ERL
|
||||
AC_ERLANG_NEED_ERLC
|
||||
|
||||
# Checks and sets ERLANG_ROOT_DIR and ERLANG_LIB_DIR variable
|
||||
# AC_ERLANG_SUBST_ROOT_DIR
|
||||
# AC_ERLANG_SUBST_LIB_DIR
|
||||
|
||||
#locating escript
|
||||
AC_PATH_PROG([ESCRIPT], [escript], [])
|
||||
|
||||
#locating rebar
|
||||
AC_PATH_PROG([REBAR], [rebar], [./rebar])
|
||||
|
||||
#locating make
|
||||
AC_CHECK_PROG([MAKE], [make], [make], [])
|
||||
|
||||
if test "x$ESCRIPT" = "x"; then
|
||||
AC_MSG_ERROR(['escript' was not found])
|
||||
fi
|
||||
|
||||
if test "x$MAKE" = "x"; then
|
||||
AC_MSG_ERROR(['make' was not found])
|
||||
fi
|
||||
|
||||
# Change default prefix
|
||||
AC_PREFIX_DEFAULT(/)
|
||||
|
||||
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(roster_gateway_workaround,
|
||||
[AC_HELP_STRING([--enable-roster-gateway-workaround], [turn on workaround for processing gateway subscriptions (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) roster_gateway_workaround=true ;;
|
||||
no) roster_gateway_workaround=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-roster-gateway-workaround) ;;
|
||||
esac],[roster_gateway_workaround=false])
|
||||
|
||||
AC_ARG_ENABLE(flash_hack,
|
||||
[AC_HELP_STRING([--enable-flash-hack], [support Adobe Flash client XML (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) flash_hack=true ;;
|
||||
no) flash_hack=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-flash-hack) ;;
|
||||
esac],[flash_hack=false])
|
||||
|
||||
AC_ARG_ENABLE(transient_supervisors,
|
||||
[AC_HELP_STRING([--enable-transient_supervisors], [use Erlang supervision for transient process (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) transient_supervisors=true ;;
|
||||
no) transient_supervisors=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-transient_supervisors) ;;
|
||||
esac],[transient_supervisors=false])
|
||||
|
||||
AC_ARG_ENABLE(full_xml,
|
||||
[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
|
||||
[case "${enableval}" in
|
||||
yes) full_xml=true ;;
|
||||
no) full_xml=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-full-xml) ;;
|
||||
esac],[full_xml=false])
|
||||
|
||||
AC_ARG_ENABLE(mssql,
|
||||
[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
|
||||
[case "${enableval}" in
|
||||
yes) db_type=mssql ;;
|
||||
no) db_type=generic ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mssql) ;;
|
||||
esac],[db_type=generic])
|
||||
|
||||
AC_ARG_ENABLE(tools,
|
||||
[AC_HELP_STRING([--enable-tools], [build development tools (currently the ejabberd profiler only, default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) tools=true ;;
|
||||
no) tools=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-tools) ;;
|
||||
esac],[tools=false])
|
||||
|
||||
AC_ARG_ENABLE(all,
|
||||
[AC_HELP_STRING([--enable-all], [same as --enable-nif --enable-mysql --enable-pgsql --enable-pam --enable-zlib --enable-stun --enable-riak --enable-json --enable-iconv --enable-debug --enable-pubsub-ng --enable-http (useful for Dialyzer checks, default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) nif=true mysql=true pgsql=true pam=true zlib=true stun=true riak=true json=true iconv=true debug=true pubsub_ng=true http=true ;;
|
||||
no) nif=false mysql=false pgsql=false pam=false zlib=false stun=false riak=false json=false iconv=false debug=false pubsub_ng=false http=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
|
||||
esac],[])
|
||||
|
||||
AC_ARG_ENABLE(nif,
|
||||
[AC_HELP_STRING([--enable-nif], [replace some functions with C equivalents. Requires Erlang R13B04 or higher (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) nif=true ;;
|
||||
no) nif=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-nif) ;;
|
||||
esac],[if test "x$nif" = "x"; then nif=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(mysql,
|
||||
[AC_HELP_STRING([--enable-mysql], [enable MySQL support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) mysql=true ;;
|
||||
no) mysql=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mysql) ;;
|
||||
esac],[if test "x$mysql" = "x"; then mysql=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(pgsql,
|
||||
[AC_HELP_STRING([--enable-pgsql], [enable PostgreSQL support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) pgsql=true ;;
|
||||
no) pgsql=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-pgsql) ;;
|
||||
esac],[if test "x$pgsql" = "x"; then pgsql=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(pam,
|
||||
[AC_HELP_STRING([--enable-pam], [enable PAM support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) pam=true ;;
|
||||
no) pam=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-pam) ;;
|
||||
esac],[if test "x$pam" = "x"; then pam=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(zlib,
|
||||
[AC_HELP_STRING([--enable-zlib], [enable Stream Compression (XEP-0138) using zlib (default: yes)])],
|
||||
[case "${enableval}" in
|
||||
yes) zlib=true ;;
|
||||
no) zlib=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-zlib) ;;
|
||||
esac],[if test "x$zlib" = "x"; then zlib=true; fi])
|
||||
|
||||
AC_ARG_ENABLE(stun,
|
||||
[AC_HELP_STRING([--enable-stun], [enable STUN support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) stun=true ;;
|
||||
no) stun=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-stun) ;;
|
||||
esac],[if test "x$stun" = "x"; then stun=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(riak,
|
||||
[AC_HELP_STRING([--enable-riak], [enable Riak support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) riak=true ;;
|
||||
no) riak=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-riak) ;;
|
||||
esac],[if test "x$riak" = "x"; then riak=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(json,
|
||||
[AC_HELP_STRING([--enable-json], [enable JSON support for mod_bosh (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) json=true ;;
|
||||
no) json=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-json) ;;
|
||||
esac],[if test "x$json" = "x"; then json=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(iconv,
|
||||
[AC_HELP_STRING([--enable-iconv], [enable iconv support (default: yes)])],
|
||||
[case "${enableval}" in
|
||||
yes) iconv=true ;;
|
||||
no) iconv=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-iconv) ;;
|
||||
esac],[if test "x$iconv" = "x"; then iconv=true; fi])
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[AC_HELP_STRING([--enable-debug], [enable debug information (default: yes)])],
|
||||
[case "${enableval}" in
|
||||
yes) debug=true ;;
|
||||
no) debug=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
|
||||
esac],[if test "x$debug" = "x"; then debug=true; fi])
|
||||
|
||||
AC_ARG_ENABLE(pubsub_ng,
|
||||
[AC_HELP_STRING([--enable-pubsub-ng], [enable PubSub NG (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) pubsub_ng=true ;;
|
||||
no) pubsub_ng=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-pubsub-ng) ;;
|
||||
esac],[if test "x$pubsub_ng" = "x"; then pubsub_ng=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(http,
|
||||
[AC_HELP_STRING([--enable-http], [build external HTTP libraries ('ibrowse' and 'lhttpc', default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) http=true ;;
|
||||
no) http=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-http) ;;
|
||||
esac],[if test "x$http" = "x"; then http=false; fi])
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
vars.config
|
||||
src/ejabberd.app.src])
|
||||
|
||||
ENABLEUSER=""
|
||||
AC_ARG_ENABLE(user,
|
||||
[AS_HELP_STRING([--enable-user[[[[=USER]]]]], [allow this system user to start ejabberd (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) ENABLEUSER=`whoami` ;;
|
||||
no) ENABLEUSER="" ;;
|
||||
*) ENABLEUSER=$enableval
|
||||
esac],
|
||||
[])
|
||||
if test "$ENABLEUSER" != ""; then
|
||||
echo "allow this system user to start ejabberd: $ENABLEUSER"
|
||||
AC_SUBST([INSTALLUSER], [$ENABLEUSER])
|
||||
fi
|
||||
|
||||
AC_ERLANG_CHECK_LIB([sasl], [],
|
||||
[AC_MSG_ERROR([Erlang application 'sasl' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([crypto], [],
|
||||
[AC_MSG_ERROR([Erlang application 'crypto' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([public_key], [],
|
||||
[AC_MSG_ERROR([Erlang application 'public_key' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([ssl], [],
|
||||
[AC_MSG_ERROR([Erlang application 'ssl' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([mnesia], [],
|
||||
[AC_MSG_ERROR([Erlang application 'mnesia' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([inets], [],
|
||||
[AC_MSG_ERROR([Erlang application 'inets' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([odbc], [],
|
||||
[AC_MSG_ERROR([Erlang application 'odbc' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([compiler], [],
|
||||
[AC_MSG_ERROR([Erlang application 'compiler' was not found])])
|
||||
if test "x$tools" = "xtrue"; then
|
||||
AC_ERLANG_CHECK_LIB([tools], [],
|
||||
[AC_MSG_ERROR([Erlang application 'tools' was not found])])
|
||||
AC_ERLANG_CHECK_LIB([runtime_tools], [],
|
||||
[AC_MSG_ERROR([Erlang application 'runtime_tools' was not found])])
|
||||
fi
|
||||
|
||||
AC_SUBST(hipe)
|
||||
AC_SUBST(roster_gateway_workaround)
|
||||
AC_SUBST(flash_hack)
|
||||
AC_SUBST(transient_supervisors)
|
||||
AC_SUBST(full_xml)
|
||||
AC_SUBST(nif)
|
||||
AC_SUBST(db_type)
|
||||
AC_SUBST(mysql)
|
||||
AC_SUBST(pgsql)
|
||||
AC_SUBST(pam)
|
||||
AC_SUBST(zlib)
|
||||
AC_SUBST(stun)
|
||||
AC_SUBST(riak)
|
||||
AC_SUBST(json)
|
||||
AC_SUBST(iconv)
|
||||
AC_SUBST(debug)
|
||||
AC_SUBST(pubsub_ng)
|
||||
AC_SUBST(http)
|
||||
AC_SUBST(tools)
|
||||
|
||||
AC_OUTPUT
|
||||
@@ -1,5 +0,0 @@
|
||||
% List of ejabberd-modules to add for ejabberd packaging (source archive and installer)
|
||||
%
|
||||
% HTTP-binding:
|
||||
%https://svn.process-one.net/ejabberd-modules/http_bind/trunk
|
||||
%https://svn.process-one.net/ejabberd-modules/mod_http_fileserver/trunk
|
||||
@@ -281,14 +281,14 @@ build_additional_translators(List) ->
|
||||
List).
|
||||
|
||||
print_translation(File, Line, Str, StrT) ->
|
||||
{ok, StrQ, _} = regexp:gsub(Str, "\"", "\\\""),
|
||||
{ok, StrTQ, _} = regexp:gsub(StrT, "\"", "\\\""),
|
||||
StrQ = ejabberd_regexp:greplace(Str, "\\\"", "\\\\\""),
|
||||
StrTQ = ejabberd_regexp:greplace(StrT, "\\\"", "\\\\\""),
|
||||
io:format("#: ~s:~p~nmsgid \"~s\"~nmsgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
|
||||
|
||||
print_translation_obsolete(Str, StrT) ->
|
||||
File = "unknown.erl",
|
||||
Line = 1,
|
||||
{ok, StrQ, _} = regexp:gsub(Str, "\"", "\\\""),
|
||||
{ok, StrTQ, _} = regexp:gsub(StrT, "\"", "\\\""),
|
||||
StrQ = ejabberd_regexp:greplace(Str, "\\\"", "\\\\\""),
|
||||
StrTQ = ejabberd_regexp:greplace(StrT, "\\\"", "\\\\\""),
|
||||
io:format("#: ~s:~p~n#~~ msgid \"~s\"~n#~~ msgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@ prepare_dirs ()
|
||||
ERL=`which erl`
|
||||
|
||||
EJA_SRC_DIR=$EJA_DIR/src/
|
||||
EJA_MSGS_DIR=$EJA_SRC_DIR/msgs/
|
||||
EJA_MSGS_DIR=$EJA_DIR/priv/msgs/
|
||||
EXTRACT_DIR=$EJA_DIR/contrib/extract_translations/
|
||||
EXTRACT_ERL=$EXTRACT_DIR/extract_translations.erl
|
||||
EXTRACT_BEAM=$EXTRACT_DIR/extract_translations.beam
|
||||
|
||||
SRC_DIR=$RUN_DIR/src
|
||||
MSGS_DIR=$SRC_DIR/msgs
|
||||
MSGS_DIR=$EJA_DIR/priv/msgs
|
||||
|
||||
if !([[ -n $EJA_DIR ]])
|
||||
then
|
||||
@@ -288,8 +288,8 @@ translation_instructions ()
|
||||
echo " $MSGS_PATH"
|
||||
}
|
||||
|
||||
EJA_DIR=`pwd`/..
|
||||
RUN_DIR=`pwd`/..
|
||||
EJA_DIR=`pwd`
|
||||
RUN_DIR=`pwd`
|
||||
PROJECT=ejabberd
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
|
||||
+15
-2
@@ -21,10 +21,11 @@ release:
|
||||
@echo "\newcommand{\version}{"`sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../src/ejabberd.app`"}" >> version.tex
|
||||
@echo -n "% Contributed modules (automatically generated)." > contributed_modules.tex
|
||||
@echo -e "$(CONTRIBUTED_MODULES)" >> contributed_modules.tex
|
||||
@echo "% mod_admin_p1 commands list."
|
||||
|
||||
html: guide.html dev.html features.html
|
||||
html: guide.html dev.html features.html commercial.html
|
||||
|
||||
pdf: guide.pdf features.pdf
|
||||
pdf: guide.pdf features.pdf commercial.pdf
|
||||
|
||||
clean:
|
||||
rm -f *.aux
|
||||
@@ -60,3 +61,15 @@ guide.pdf: guide.tex
|
||||
|
||||
features.pdf: features.tex
|
||||
pdflatex features.tex
|
||||
|
||||
commercial.html: commercial.tex
|
||||
./mod_admin_p1_commands.sh
|
||||
hevea -fix -pedantic commercial.tex
|
||||
|
||||
commercial.pdf: commercial.tex
|
||||
./mod_admin_p1_commands.sh
|
||||
pdflatex commercial.tex
|
||||
pdflatex commercial.tex
|
||||
pdflatex commercial.tex
|
||||
makeindex commercial.idx
|
||||
pdflatex commercial.tex
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@author Mickael Remond <mickael.remond@process-one.net>
|
||||
[http://www.process-one.net/]
|
||||
@copyright 2007 ProcessOne
|
||||
@copyright 2012 ProcessOne
|
||||
@version {@vsn}, {@date} {@time}
|
||||
@title ejabberd Development API Documentation
|
||||
|
||||
|
||||
+6184
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -2,7 +2,7 @@
|
||||
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Ejabberd 2.1.10 Developers Guide
|
||||
<TITLE>Ejabberd 2.1.11 Developers Guide
|
||||
</TITLE>
|
||||
|
||||
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
@@ -49,7 +49,7 @@ TD P{margin:0px;}
|
||||
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic dev.tex -->
|
||||
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
|
||||
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.10 Developers Guide</H1><H3 CLASS="titlerest">Alexey Shchepin<BR>
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.11 Developers Guide</H1><H3 CLASS="titlerest">Alexey Shchepin<BR>
|
||||
<A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
|
||||
<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3></TD></TR>
|
||||
</TABLE><DIV CLASS="center">
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Ejabberd 2.1.10 Feature Sheet
|
||||
<TITLE>Ejabberd 2.1.11 Feature Sheet
|
||||
</TITLE>
|
||||
|
||||
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
@@ -50,7 +50,7 @@ SPAN{width:20%; float:right; text-align:left; margin-left:auto;}
|
||||
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic features.tex -->
|
||||
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
|
||||
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.10 Feature Sheet</H1><H3 CLASS="titlerest">Sander Devrieze<BR>
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.11 Feature Sheet</H1><H3 CLASS="titlerest">Sander Devrieze<BR>
|
||||
<A HREF="mailto:s.devrieze@pandora.be"><TT>mailto:s.devrieze@pandora.be</TT></A><BR>
|
||||
<A HREF="xmpp:sander@devrieze.dyndns.org"><TT>xmpp:sander@devrieze.dyndns.org</TT></A></H3></TD></TR>
|
||||
</TABLE><DIV CLASS="center">
|
||||
|
||||
+42
-18
@@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
|
||||
ejabberd 2.1.10
|
||||
ejabberd 2.1.11
|
||||
|
||||
Installation and Operation Guide
|
||||
|
||||
@@ -76,7 +76,7 @@ BLOCKQUOTE.figure DIV.center DIV.center HR{display:none;}
|
||||
<HR SIZE=2><BR>
|
||||
<BR>
|
||||
|
||||
<TABLE CELLSPACING=6 CELLPADDING=0><TR><TD ALIGN=right NOWRAP> <FONT SIZE=6><B>ejabberd 2.1.10 </B></FONT></TD></TR>
|
||||
<TABLE CELLSPACING=6 CELLPADDING=0><TR><TD ALIGN=right NOWRAP> <FONT SIZE=6><B>ejabberd 2.1.11 </B></FONT></TD></TR>
|
||||
<TR><TD ALIGN=right NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=right NOWRAP> <FONT SIZE=6>Installation and Operation Guide</FONT></TD></TR>
|
||||
</TABLE><BR>
|
||||
@@ -109,7 +109,7 @@ BLOCKQUOTE.figure DIV.center DIV.center HR{display:none;}
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc15">2.4.7  Specific Notes for Sun Solaris</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc16">2.4.8  Specific Notes for Microsoft Windows</A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc17">2.5  Create a XMPP Account for Administration</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc17">2.5  Create an XMPP Account for Administration</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc18">2.6  Upgrading <TT>ejabberd</TT></A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc19">Chapter 3  Configuring <TT>ejabberd</TT></A>
|
||||
@@ -348,7 +348,7 @@ as long as your system have all the dependencies.</P><P> <A NAME="installreq"></
|
||||
GNU Make
|
||||
</LI><LI CLASS="li-itemize">GCC
|
||||
</LI><LI CLASS="li-itemize">Libexpat 1.95 or higher
|
||||
</LI><LI CLASS="li-itemize">Erlang/OTP R10B-9 or higher. The recommended versions are R12B-5 and R13B04.
|
||||
</LI><LI CLASS="li-itemize">Erlang/OTP R10B-9 or higher. The recommended versions are R13B04 and R14B04.
|
||||
Don’t use R14A or R14B because <A HREF="http://www.erlang.org/cgi-bin/ezmlm-cgi/4/54598">they have a bug</A>.
|
||||
</LI><LI CLASS="li-itemize">OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption.
|
||||
</LI><LI CLASS="li-itemize">Zlib 1.2.3 or higher, for Stream Compression support (<A HREF="http://xmpp.org/extensions/xep-0138.html">XEP-0138</A>). Optional.
|
||||
@@ -513,16 +513,16 @@ variable.
|
||||
nmake -f Makefile.win32
|
||||
</PRE></LI><LI CLASS="li-enumerate">Edit the file <CODE>ejabberd\src\ejabberd.cfg</CODE> and run
|
||||
<PRE CLASS="verbatim">werl -s ejabberd -name ejabberd
|
||||
</PRE></LI></OL><P> <A NAME="initialadmin"></A> </P><!--TOC section Create a XMPP Account for Administration-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc17">2.5</A>  <A HREF="#initialadmin">Create a XMPP Account for Administration</A></H2><!--SEC END --><P> <A NAME="initialadmin"></A> </P><P>You need a XMPP account and grant him administrative privileges
|
||||
</PRE></LI></OL><P> <A NAME="initialadmin"></A> </P><!--TOC section Create an XMPP Account for Administration-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc17">2.5</A>  <A HREF="#initialadmin">Create an XMPP Account for Administration</A></H2><!--SEC END --><P> <A NAME="initialadmin"></A> </P><P>You need an XMPP account and grant him administrative privileges
|
||||
to enter the <TT>ejabberd</TT> Web Admin:
|
||||
</P><OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
|
||||
Register a XMPP account on your <TT>ejabberd</TT> server, for example <TT>admin1@example.org</TT>.
|
||||
There are two ways to register a XMPP account:
|
||||
Register an XMPP account on your <TT>ejabberd</TT> server, for example <TT>admin1@example.org</TT>.
|
||||
There are two ways to register an XMPP account:
|
||||
<OL CLASS="enumerate" type=a><LI CLASS="li-enumerate">
|
||||
Using <TT>ejabberdctl</TT> (see section <A HREF="#ejabberdctl">4.1</A>):
|
||||
<PRE CLASS="verbatim">ejabberdctl register admin1 example.org FgT5bk3
|
||||
</PRE></LI><LI CLASS="li-enumerate">Using a XMPP client and In-Band Registration (see section <A HREF="#modregister">3.3.19</A>).
|
||||
</PRE></LI><LI CLASS="li-enumerate">Using an XMPP client and In-Band Registration (see section <A HREF="#modregister">3.3.19</A>).
|
||||
</LI></OL>
|
||||
</LI><LI CLASS="li-enumerate">Edit the <TT>ejabberd</TT> configuration file to give administration rights to the XMPP account you created:
|
||||
<PRE CLASS="verbatim">{acl, admin, {user, "admin1", "example.org"}}.
|
||||
@@ -695,7 +695,7 @@ Handles STUN Binding requests as defined in
|
||||
Options: <TT>certfile</TT>
|
||||
</DD><DT CLASS="dt-description"><B><TT>ejabberd_http</TT></B></DT><DD CLASS="dd-description">
|
||||
Handles incoming HTTP connections.<BR>
|
||||
Options: <TT>captcha</TT>, <TT>certfile</TT>, <TT>http_bind</TT>, <TT>http_poll</TT>,
|
||||
Options: <TT>captcha</TT>, <TT>certfile</TT>, <TT>default_host</TT>, <TT>http_bind</TT>, <TT>http_poll</TT>,
|
||||
<TT>request_handlers</TT>, <TT>tls</TT>, <TT>trusted_proxies</TT>, <TT>web_admin</TT><BR>
|
||||
</DD></DL><P> <A NAME="listened-options"></A> </P><!--TOC subsubsection Options-->
|
||||
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#listened-options">Options</A></H4><!--SEC END --><P> <A NAME="listened-options"></A> </P><P>This is a detailed description of each option allowed by the listening modules:
|
||||
@@ -712,6 +712,11 @@ immediately). Default value is 5.
|
||||
Simple web page that allows a user to fill a CAPTCHA challenge (see section <A HREF="#captcha">3.1.8</A>).
|
||||
</DD><DT CLASS="dt-description"><B><TT>{certfile, Path}</TT></B></DT><DD CLASS="dd-description"> Full path to a file containing the default SSL certificate.
|
||||
To define a certificate file specific for a given domain, use the global option <TT>domain_certfile</TT>.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{default_host, undefined|HostName}</TT></B></DT><DD CLASS="dd-description">
|
||||
If the HTTP request received by ejabberd contains the HTTP header <TT>Host</TT>
|
||||
with an ambiguous virtual host that doesn’t match any one defined in ejabberd (see <A HREF="#hostnames">3.1.1</A>),
|
||||
then this configured HostName is set as the request Host.
|
||||
The default value of this option is: <TT>undefined</TT>.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{hosts, [Hostname, ...], [HostOption, ...]}</TT></B></DT><DD CLASS="dd-description">
|
||||
The external Jabber component that connects to this <TT>ejabberd_service</TT>
|
||||
can serve one or more hostnames.
|
||||
@@ -1059,7 +1064,11 @@ The possible values match exactly the three possibilities described in
|
||||
<A HREF="http://tools.ietf.org/html/rfc6120#section-7.7.2.2">XMPP Core: section 7.7.2.2</A>.
|
||||
The default value is <TT>closeold</TT>.
|
||||
If the client uses old Jabber Non-SASL authentication (<A HREF="http://xmpp.org/extensions/xep-0078.html">XEP-0078</A>),
|
||||
then this option is not respected, and the action performed is <TT>closeold</TT>.</P><P> <A NAME="internalauth"></A> </P><!--TOC subsubsection Internal-->
|
||||
then this option is not respected, and the action performed is <TT>closeold</TT>.</P><P>The option <TT>fqdn</TT> allows you to define the Fully Qualified Domain Name
|
||||
of the machine, in case it isn’t detected automatically.
|
||||
The FQDN is used to authenticate some clients that use the DIGEST-MD5 SASL mechanism.
|
||||
The option syntax is:
|
||||
</P><DL CLASS="description"><DT CLASS="dt-description"><B><TT>{fqdn, undefined|FqdnString}.</TT></B></DT></DL><P> <A NAME="internalauth"></A> </P><!--TOC subsubsection Internal-->
|
||||
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#internalauth">Internal</A></H4><!--SEC END --><P> <A NAME="internalauth"></A>
|
||||
</P><P><TT>ejabberd</TT> uses its internal Mnesia database as the default authentication method.
|
||||
The value <TT>internal</TT> will enable the internal authentication method.</P><P>The option <TT>{auth_password_format, plain|scram}</TT>
|
||||
@@ -1201,7 +1210,7 @@ attacks.
|
||||
</LI><LI CLASS="li-itemize">You may want to allow login access only for certain users. <TT>pam_listfile.so</TT>
|
||||
module provides such functionality.
|
||||
</LI><LI CLASS="li-itemize">If you use <TT>pam_winbind</TT> to authorise against a Windows Active Directory,
|
||||
then <TT>/etc/nssswitch.conf</TT> must be configured to use <TT>winbind</TT> as well.
|
||||
then <TT>/etc/nsswitch.conf</TT> must be configured to use <TT>winbind</TT> as well.
|
||||
</LI></UL><P> <A NAME="accessrules"></A> </P><!--TOC subsection Access Rules-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc25">3.1.5</A>  <A HREF="#accessrules">Access Rules</A></H3><!--SEC END --><P> <A NAME="accessrules"></A>
|
||||
</P><P> <A NAME="ACLDefinition"></A> </P><!--TOC subsubsection ACL Definition-->
|
||||
@@ -1340,7 +1349,7 @@ using ImageMagick’s Convert program.</P><P>The configurable options are:
|
||||
</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
<B><TT>{captcha_cmd, Path}</TT></B></DT><DD CLASS="dd-description">
|
||||
Full path to a script that generates the image.
|
||||
The default value is an empty string: <TT>""</TT>
|
||||
The default value disables the feature: <TT>undefined</TT>
|
||||
</DD><DT CLASS="dt-description"><B><TT>{captcha_host, ProtocolHostPort}</TT></B></DT><DD CLASS="dd-description">
|
||||
ProtocolHostPort is a string with the host, and optionally the Protocol and Port number.
|
||||
It must identify where ejabberd listens for CAPTCHA requests.
|
||||
@@ -1950,7 +1959,10 @@ all entries end with a comma:
|
||||
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1><TR><TD ALIGN=left NOWRAP><B>Module</B></TD><TD ALIGN=left NOWRAP><B>Feature</B></TD><TD ALIGN=left NOWRAP><B>Dependencies</B></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><TT>mod_adhoc</TT></TD><TD ALIGN=left NOWRAP>Ad-Hoc Commands (<A HREF="http://xmpp.org/extensions/xep-0050.html">XEP-0050</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modannounce"><TT>mod_announce</TT></A></TD><TD ALIGN=left NOWRAP>Manage announcements</TD><TD ALIGN=left NOWRAP>recommends <TT>mod_adhoc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modannounce"><TT>mod_announce_odbc</TT></A></TD><TD ALIGN=left NOWRAP>Manage announcements</TD><TD ALIGN=left NOWRAP>recommends <TT>mod_adhoc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP> </TD><TD ALIGN=left NOWRAP> </TD><TD ALIGN=left NOWRAP>supported DB (*)</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><TT>mod_blocking</TT></TD><TD ALIGN=left NOWRAP>Simple Communications Blocking (<A HREF="http://xmpp.org/extensions/xep-0191.html">XEP-0191</A>)</TD><TD ALIGN=left NOWRAP><TT>mod_privacy</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><TT>mod_blocking_odbc</TT></TD><TD ALIGN=left NOWRAP>Simple Communications Blocking (<A HREF="http://xmpp.org/extensions/xep-0191.html">XEP-0191</A>)</TD><TD ALIGN=left NOWRAP><TT>mod_privacy_odbc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><TT>mod_caps</TT></TD><TD ALIGN=left NOWRAP>Entity Capabilities (<A HREF="http://xmpp.org/extensions/xep-0115.html">XEP-0115</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><TT>mod_configure</TT></TD><TD ALIGN=left NOWRAP>Server configuration using Ad-Hoc</TD><TD ALIGN=left NOWRAP><TT>mod_adhoc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#moddisco"><TT>mod_disco</TT></A></TD><TD ALIGN=left NOWRAP>Service Discovery (<A HREF="http://xmpp.org/extensions/xep-0030.html">XEP-0030</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
@@ -1958,10 +1970,12 @@ all entries end with a comma:
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modhttpbind"><TT>mod_http_bind</TT></A></TD><TD ALIGN=left NOWRAP>XMPP over Bosh service (HTTP Binding)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modhttpfileserver"><TT>mod_http_fileserver</TT></A></TD><TD ALIGN=left NOWRAP>Small HTTP file server</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modirc"><TT>mod_irc</TT></A></TD><TD ALIGN=left NOWRAP>IRC transport</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modirc"><TT>mod_irc_odbc</TT></A></TD><TD ALIGN=left NOWRAP>IRC transport</TD><TD ALIGN=left NOWRAP>supported DB (*)</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modlast"><TT>mod_last</TT></A></TD><TD ALIGN=left NOWRAP>Last Activity (<A HREF="http://xmpp.org/extensions/xep-0012.html">XEP-0012</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modlast"><TT>mod_last_odbc</TT></A></TD><TD ALIGN=left NOWRAP>Last Activity (<A HREF="http://xmpp.org/extensions/xep-0012.html">XEP-0012</A>)</TD><TD ALIGN=left NOWRAP>supported DB (*)</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modmuc"><TT>mod_muc</TT></A></TD><TD ALIGN=left NOWRAP>Multi-User Chat (<A HREF="http://xmpp.org/extensions/xep-0045.html">XEP-0045</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modmuclog"><TT>mod_muc_log</TT></A></TD><TD ALIGN=left NOWRAP>Multi-User Chat room logging</TD><TD ALIGN=left NOWRAP><TT>mod_muc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modmuc"><TT>mod_muc_odbc</TT></A></TD><TD ALIGN=left NOWRAP>Multi-User Chat (<A HREF="http://xmpp.org/extensions/xep-0045.html">XEP-0045</A>)</TD><TD ALIGN=left NOWRAP>supported DB (*)</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modmuclog"><TT>mod_muc_log</TT></A></TD><TD ALIGN=left NOWRAP>Multi-User Chat room logging</TD><TD ALIGN=left NOWRAP><TT>mod_muc</TT> or <TT>mod_muc_odbc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modoffline"><TT>mod_offline</TT></A></TD><TD ALIGN=left NOWRAP>Offline message storage (<A HREF="http://xmpp.org/extensions/xep-0160.html">XEP-0160</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modoffline"><TT>mod_offline_odbc</TT></A></TD><TD ALIGN=left NOWRAP>Offline message storage (<A HREF="http://xmpp.org/extensions/xep-0160.html">XEP-0160</A>)</TD><TD ALIGN=left NOWRAP>supported DB (*)</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modping"><TT>mod_ping</TT></A></TD><TD ALIGN=left NOWRAP>XMPP Ping and periodic keepalives (<A HREF="http://xmpp.org/extensions/xep-0199.html">XEP-0199</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
@@ -1980,6 +1994,8 @@ all entries end with a comma:
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modservicelog"><TT>mod_service_log</TT></A></TD><TD ALIGN=left NOWRAP>Copy user messages to logger service</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modsharedroster"><TT>mod_shared_roster</TT></A></TD><TD ALIGN=left NOWRAP>Shared roster management</TD><TD ALIGN=left NOWRAP><TT>mod_roster</TT> or</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP> </TD><TD ALIGN=left NOWRAP> </TD><TD ALIGN=left NOWRAP><TT>mod_roster_odbc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modsharedroster"><TT>mod_shared_roster_odbc</TT></A></TD><TD ALIGN=left NOWRAP>Shared roster management</TD><TD ALIGN=left NOWRAP>supported DB (*) and</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP> </TD><TD ALIGN=left NOWRAP> </TD><TD ALIGN=left NOWRAP><TT>mod_roster</TT> or <TT>mod_roster_odbc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modsharedrosterldap"><TT>mod_shared_roster_ldap</TT></A></TD><TD ALIGN=left NOWRAP>LDAP Shared roster management</TD><TD ALIGN=left NOWRAP><TT>mod_roster</TT> or</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP> </TD><TD ALIGN=left NOWRAP> </TD><TD ALIGN=left NOWRAP><TT>mod_roster_odbc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modsic"><TT>mod_sic</TT></A></TD><TD ALIGN=left NOWRAP>Server IP Check (<A HREF="http://xmpp.org/extensions/xep-0279.html">XEP-0279</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
@@ -1989,6 +2005,7 @@ all entries end with a comma:
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modvcardldap"><TT>mod_vcard_ldap</TT></A></TD><TD ALIGN=left NOWRAP>vcard-temp (<A HREF="http://xmpp.org/extensions/xep-0054.html">XEP-0054</A>)</TD><TD ALIGN=left NOWRAP>LDAP server</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modvcard"><TT>mod_vcard_odbc</TT></A></TD><TD ALIGN=left NOWRAP>vcard-temp (<A HREF="http://xmpp.org/extensions/xep-0054.html">XEP-0054</A>)</TD><TD ALIGN=left NOWRAP>supported DB (*)</TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modvcardxupdate"><TT>mod_vcard_xupdate</TT></A></TD><TD ALIGN=left NOWRAP>vCard-Based Avatars (<A HREF="http://xmpp.org/extensions/xep-0153.html">XEP-0153</A>)</TD><TD ALIGN=left NOWRAP><TT>mod_vcard</TT> or <TT>mod_vcard_odbc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modvcardxupdate"><TT>mod_vcard_xupdate_odbc</TT></A></TD><TD ALIGN=left NOWRAP>vCard-Based Avatars (<A HREF="http://xmpp.org/extensions/xep-0153.html">XEP-0153</A>)</TD><TD ALIGN=left NOWRAP><TT>mod_vcard</TT> or <TT>mod_vcard_odbc</TT></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><A HREF="#modversion"><TT>mod_version</TT></A></TD><TD ALIGN=left NOWRAP>Software Version (<A HREF="http://xmpp.org/extensions/xep-0092.html">XEP-0092</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
</TABLE>
|
||||
<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
@@ -2010,10 +2027,16 @@ Last connection date and time: Use <TT>mod_last_odbc</TT> instead of
|
||||
</LI><LI CLASS="li-itemize">Offline messages: Use <TT>mod_offline_odbc</TT> instead of
|
||||
<TT>mod_offline</TT>.
|
||||
</LI><LI CLASS="li-itemize">Rosters: Use <TT>mod_roster_odbc</TT> instead of <TT>mod_roster</TT>.
|
||||
</LI><LI CLASS="li-itemize">Shared Rosters: Use <TT>mod_shared_roster_odbc</TT> instead of <TT>mod_shared_roster</TT>.
|
||||
</LI><LI CLASS="li-itemize">Users’ VCARD: Use <TT>mod_vcard_odbc</TT> instead of <TT>mod_vcard</TT>.
|
||||
</LI><LI CLASS="li-itemize">vCard-Based Avatars: Use <TT>mod_vcard_xupdate_odbc</TT> instead of <TT>mod_vcard_xupdate</TT>.
|
||||
</LI><LI CLASS="li-itemize">Private XML storage: Use <TT>mod_private_odbc</TT> instead of <TT>mod_private</TT>.
|
||||
</LI><LI CLASS="li-itemize">User rules for blocking communications: Use <TT>mod_privacy_odbc</TT> instead of <TT>mod_privacy</TT>.
|
||||
</LI><LI CLASS="li-itemize">Simple Communications Blocking: Use <TT>mod_blocking_odbc</TT> instead of <TT>mod_blocking</TT>.
|
||||
</LI><LI CLASS="li-itemize">Pub-Sub nodes, items and subscriptions: Use <TT>mod_pubsub_odbc</TT> instead of <TT>mod_pubsub</TT>.
|
||||
</LI><LI CLASS="li-itemize">Multi-user chats: Use <TT>mod_muc_odbc</TT> instead of <TT>mod_muc</TT>.
|
||||
</LI><LI CLASS="li-itemize">Manage announcements: Use <TT>mod_announce_odbc</TT> instead of <TT>mod_announce</TT>.
|
||||
</LI><LI CLASS="li-itemize">IRC transport: Use <TT>mod_irc_odbc</TT> instead of <TT>mod_irc</TT>.
|
||||
</LI></UL><P>You can find more
|
||||
<A HREF="http://www.ejabberd.im/contributions">contributed modules</A> on the
|
||||
<TT>ejabberd</TT> website. Please remember that these contributions might not work or
|
||||
@@ -2526,7 +2549,7 @@ discarded. A good value for this option is 4 seconds.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{default_room_options, [ {OptionName, OptionValue}, ...]}</TT></B></DT><DD CLASS="dd-description">
|
||||
This module option allows to define the desired default room options.
|
||||
Note that the creator of a room can modify the options of his room
|
||||
at any time using a XMPP client with MUC capability.
|
||||
at any time using an XMPP client with MUC capability.
|
||||
The available room options and the default values are:
|
||||
<DL CLASS="description"><DT CLASS="dt-description">
|
||||
<B><TT>{allow_change_subj, true|false}</TT></B></DT><DD CLASS="dd-description"> Allow occupants to change the subject.
|
||||
@@ -3189,7 +3212,7 @@ Enabling this option reduces the load for both ejabberd and the database.
|
||||
This option does not affect the client in any way.
|
||||
This option is only useful if Roster Versioning is enabled.
|
||||
This option is disabled by default.
|
||||
Important: if you use <TT>mod_shared_roster</TT> or <TT>mod_shared_roster_ldap</TT>,
|
||||
Important: if you use <TT>mod_shared_roster</TT>, <TT>mod_shared_roster_odbc</TT> or <TT>mod_shared_roster_ldap</TT>,
|
||||
you must disable this option.
|
||||
</DD></DL><P>This example configuration enables Roster Versioning with storage of current id:
|
||||
</P><PRE CLASS="verbatim">{modules,
|
||||
@@ -4146,7 +4169,7 @@ the environment variable <TT>EJABBERD_DOC_PATH</TT>.
|
||||
See section <A HREF="#erlangconfiguration">4.1.2</A>.</P><P> <A NAME="adhoccommands"></A> </P><!--TOC section Ad-hoc Commands-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc78">4.4</A>  <A HREF="#adhoccommands">Ad-hoc Commands</A></H2><!--SEC END --><P> <A NAME="adhoccommands"></A> </P><P>If you enable <TT>mod_configure</TT> and <TT>mod_adhoc</TT>,
|
||||
you can perform several administrative tasks in <TT>ejabberd</TT>
|
||||
with a XMPP client.
|
||||
with an XMPP client.
|
||||
The client must support Ad-Hoc Commands (<A HREF="http://xmpp.org/extensions/xep-0050.html">XEP-0050</A>),
|
||||
and you must login in the XMPP server with
|
||||
an account with proper privileges.</P><P> <A NAME="changeerlangnodename"></A> </P><!--TOC section Change Computer Hostname-->
|
||||
@@ -4467,6 +4490,7 @@ Alexey Shchepin (<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT
|
||||
</LI><LI CLASS="li-itemize">Badlop (<A HREF="xmpp:badlop@jabberes.org"><TT>xmpp:badlop@jabberes.org</TT></A>)
|
||||
</LI><LI CLASS="li-itemize">Evgeniy Khramtsov (<A HREF="xmpp:xram@jabber.ru"><TT>xmpp:xram@jabber.ru</TT></A>)
|
||||
</LI><LI CLASS="li-itemize">Florian Zumbiehl (<A HREF="xmpp:florz@florz.de"><TT>xmpp:florz@florz.de</TT></A>)
|
||||
</LI><LI CLASS="li-itemize">Ludovic Bocquet (<A HREF="xmpp:lbocquet@jabber.org"><TT>xmpp:lbocquet@jabber.org</TT></A>)
|
||||
</LI><LI CLASS="li-itemize">Marcin Owsiany (<A HREF="xmpp:marcin.owsiany@gmail.com"><TT>xmpp:marcin.owsiany@gmail.com</TT></A>)
|
||||
</LI><LI CLASS="li-itemize">Michael Grigutsch (<A HREF="xmpp:migri@jabber.i-pobox.net"><TT>xmpp:migri@jabber.i-pobox.net</TT></A>)
|
||||
</LI><LI CLASS="li-itemize">Mickael Remond (<A HREF="xmpp:mremond@process-one.net"><TT>xmpp:mremond@process-one.net</TT></A>)
|
||||
@@ -4475,7 +4499,7 @@ Alexey Shchepin (<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT
|
||||
</LI><LI CLASS="li-itemize">Vsevolod Pelipas (<A HREF="xmpp:vsevoload@jabber.ru"><TT>xmpp:vsevoload@jabber.ru</TT></A>)
|
||||
</LI></UL><P> <A NAME="copyright"></A> </P><!--TOC chapter Copyright Information-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc103">Appendix D</A>  <A HREF="#copyright">Copyright Information</A></H1><!--SEC END --><P> <A NAME="copyright"></A> </P><P>Ejabberd Installation and Operation Guide.<BR>
|
||||
Copyright © 2003 — 2010 ProcessOne</P><P>This document is free software; you can redistribute it and/or
|
||||
Copyright © 2003 — 2013 ProcessOne</P><P>This document is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.</P><P>This document is distributed in the hope that it will be useful,
|
||||
|
||||
+192
-97
@@ -66,7 +66,9 @@
|
||||
\newcommand{\module}[1]{\texttt{#1}}
|
||||
\newcommand{\modadhoc}{\module{mod\_adhoc}}
|
||||
\newcommand{\modannounce}{\module{mod\_announce}}
|
||||
\newcommand{\modannounceodbc}{\module{mod\_announce\_odbc}}
|
||||
\newcommand{\modblocking}{\module{mod\_blocking}}
|
||||
\newcommand{\modblockingodbc}{\module{mod\_blocking\_odbc}}
|
||||
\newcommand{\modcaps}{\module{mod\_caps}}
|
||||
\newcommand{\modconfigure}{\module{mod\_configure}}
|
||||
\newcommand{\moddisco}{\module{mod\_disco}}
|
||||
@@ -74,10 +76,13 @@
|
||||
\newcommand{\modhttpbind}{\module{mod\_http\_bind}}
|
||||
\newcommand{\modhttpfileserver}{\module{mod\_http\_fileserver}}
|
||||
\newcommand{\modirc}{\module{mod\_irc}}
|
||||
\newcommand{\modircodbc}{\module{mod\_irc\_odbc}}
|
||||
\newcommand{\modlast}{\module{mod\_last}}
|
||||
\newcommand{\modlastodbc}{\module{mod\_last\_odbc}}
|
||||
\newcommand{\modmuc}{\module{mod\_muc}}
|
||||
\newcommand{\modmucodbc}{\module{mod\_muc\_odbc}}
|
||||
\newcommand{\modmuclog}{\module{mod\_muc\_log}}
|
||||
\newcommand{\modmulticast}{\module{mod\_multicast}}
|
||||
\newcommand{\modoffline}{\module{mod\_offline}}
|
||||
\newcommand{\modofflineodbc}{\module{mod\_offline\_odbc}}
|
||||
\newcommand{\modping}{\module{mod\_ping}}
|
||||
@@ -95,6 +100,7 @@
|
||||
\newcommand{\modrosterodbc}{\module{mod\_roster\_odbc}}
|
||||
\newcommand{\modservicelog}{\module{mod\_service\_log}}
|
||||
\newcommand{\modsharedroster}{\module{mod\_shared\_roster}}
|
||||
\newcommand{\modsharedrosterodbc}{\module{mod\_shared\_roster\_odbc}}
|
||||
\newcommand{\modsharedrosterldap}{\module{mod\_shared\_roster\_ldap}}
|
||||
\newcommand{\modsic}{\module{mod\_sic}}
|
||||
\newcommand{\modstats}{\module{mod\_stats}}
|
||||
@@ -103,6 +109,7 @@
|
||||
\newcommand{\modvcardldap}{\module{mod\_vcard\_ldap}}
|
||||
\newcommand{\modvcardodbc}{\module{mod\_vcard\_odbc}}
|
||||
\newcommand{\modvcardxupdate}{\module{mod\_vcard\_xupdate}}
|
||||
\newcommand{\modvcardxupdateodbc}{\module{mod\_vcard\_xupdate\_odbc}}
|
||||
\newcommand{\modversion}{\module{mod\_version}}
|
||||
|
||||
%% Contributed modules
|
||||
@@ -247,6 +254,8 @@ go to the Windows service settings and set ejabberd to be automatically started.
|
||||
Note that the Windows service is a feature still in development,
|
||||
and for example it doesn't read the file ejabberdctl.cfg.
|
||||
|
||||
The OSX binary installer works on OSX 10.6 and newer.
|
||||
|
||||
On a *nix system, if you want ejabberd to be started as daemon at boot time,
|
||||
copy \term{ejabberd.init} from the 'bin' directory to something like \term{/etc/init.d/ejabberd}
|
||||
(depending on your distribution).
|
||||
@@ -315,7 +324,7 @@ To compile \ejabberd{} on a `Unix-like' operating system, you need:
|
||||
\item GNU Make
|
||||
\item GCC
|
||||
\item Libexpat 1.95 or higher
|
||||
\item Erlang/OTP R10B-9 or higher. The recommended versions are R12B-5 and R13B04.
|
||||
\item Erlang/OTP R10B-9 or higher. The recommended versions are R13B04 and R14B04.
|
||||
Don't use R14A or R14B because \footahref{http://www.erlang.org/cgi-bin/ezmlm-cgi/4/54598}{they have a bug}.
|
||||
\item OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption.
|
||||
\item Zlib 1.2.3 or higher, for Stream Compression support (\xepref{0138}). Optional.
|
||||
@@ -377,10 +386,34 @@ Some options that you may be interested in modifying:
|
||||
\titem{--enable-pam}
|
||||
Enable the PAM authentication method (see section \ref{pam}).
|
||||
|
||||
\titem{--enable-odbc or --enable-mssql}
|
||||
\titem{--enable-mssql}
|
||||
Required if you want to use an external database.
|
||||
See section~\ref{database} for more information.
|
||||
|
||||
\titem{--enable-tools}
|
||||
Enable the use of development tools.
|
||||
|
||||
\titem{--enable-mysql}
|
||||
Enable MySQL support (see section \ref{mysql}).
|
||||
|
||||
\titem{--enable-pgsql}
|
||||
Enable PostgreSQL support (see section \ref{pgsql}).
|
||||
|
||||
\titem{--enable-zlib}
|
||||
Enable Stream Compression (XEP-0138) using zlib.
|
||||
|
||||
\titem{--enable-stun}
|
||||
Enable STUN support (see section \ref{stun}).
|
||||
|
||||
\titem{--enable-riak}
|
||||
Enable Riak support.
|
||||
|
||||
\titem{--enable-iconv}
|
||||
Enable iconv support. This is needed for \term{mod\_irc} (see seciont \ref{modirc}).
|
||||
|
||||
\titem{--enable-debug}
|
||||
Compile with \term{+debug\_info} enabled.
|
||||
|
||||
\titem{--enable-full-xml}
|
||||
Enable the use of XML based optimisations.
|
||||
It will for example use CDATA to escape characters in the XMPP stream.
|
||||
@@ -392,6 +425,9 @@ Some options that you may be interested in modifying:
|
||||
\titem{--enable-nif}
|
||||
Replaces some critical Erlang functions with equivalents written in C to improve performance.
|
||||
This feature requires Erlang/OTP R13B04 or higher.
|
||||
|
||||
\titem{--enable-flash-hack}
|
||||
Enable support for non-standard XML socket clients of Adobe Flash 8 and lower.
|
||||
\end{description}
|
||||
|
||||
\makesubsection{install}{Install}
|
||||
@@ -569,19 +605,19 @@ werl -s ejabberd -name ejabberd
|
||||
%TODO: how to compile database support on windows?
|
||||
|
||||
|
||||
\makesection{initialadmin}{Create a XMPP Account for Administration}
|
||||
\makesection{initialadmin}{Create an XMPP Account for Administration}
|
||||
|
||||
You need a XMPP account and grant him administrative privileges
|
||||
You need an XMPP account and grant him administrative privileges
|
||||
to enter the \ejabberd{} Web Admin:
|
||||
\begin{enumerate}
|
||||
\item Register a XMPP account on your \ejabberd{} server, for example \term{admin1@example.org}.
|
||||
There are two ways to register a XMPP account:
|
||||
\item Register an XMPP account on your \ejabberd{} server, for example \term{admin1@example.org}.
|
||||
There are two ways to register an XMPP account:
|
||||
\begin{enumerate}
|
||||
\item Using \term{ejabberdctl}\ind{ejabberdctl} (see section~\ref{ejabberdctl}):
|
||||
\begin{verbatim}
|
||||
ejabberdctl register admin1 example.org FgT5bk3
|
||||
\end{verbatim}
|
||||
\item Using a XMPP client and In-Band Registration (see section~\ref{modregister}).
|
||||
\item Using an XMPP client and In-Band Registration (see section~\ref{modregister}).
|
||||
\end{enumerate}
|
||||
\item Edit the \ejabberd{} configuration file to give administration rights to the XMPP account you created:
|
||||
\begin{verbatim}
|
||||
@@ -826,8 +862,11 @@ The available modules, their purpose and the options allowed by each one are:
|
||||
Options: \texttt{certfile}
|
||||
\titem{\texttt{ejabberd\_http}}
|
||||
Handles incoming HTTP connections.\\
|
||||
Options: \texttt{captcha}, \texttt{certfile}, \texttt{http\_bind}, \texttt{http\_poll},
|
||||
Options: \texttt{captcha}, \texttt{certfile}, \texttt{default\_host}, \texttt{http\_bind}, \texttt{http\_poll},
|
||||
\texttt{request\_handlers}, \texttt{tls}, \texttt{trusted\_proxies}, \texttt{web\_admin}\\
|
||||
\titem{\texttt{ejabberd\_xmlrpc}}
|
||||
Handles incoming XML-RPC requests to execute ejabberd commands (see \ref{eja-commands}).\\
|
||||
Options: \texttt{access\_commands}, \texttt{timeout}\\
|
||||
\end{description}
|
||||
|
||||
|
||||
@@ -837,6 +876,19 @@ This is a detailed description of each option allowed by the listening modules:
|
||||
\begin{description}
|
||||
\titem{\{access, AccessName\}} \ind{options!access}This option defines
|
||||
access to the port. The default value is \term{all}.
|
||||
\titem{\{access\_commands, AccessCommands\}} \ind{options!accesscommands}
|
||||
This option allows to define a list of access restrictions (see \ref{accesscommands}).
|
||||
If this option is present, then XML-RPC calls must include as
|
||||
first argument a struct with a user, server and password of an
|
||||
account in ejabberd that has privileges in Access.
|
||||
If the option is not present, such struct must not be provided.
|
||||
The default value is to not define any restriction: \term{\[\]}
|
||||
When one or several access restrictions are defined and the
|
||||
XML-RPC call provides authentication for an account, each
|
||||
restriction is verified until one matches completely:
|
||||
the account matches the Access rule,
|
||||
the command name is listed in CommandNames,
|
||||
and the provided arguments do not contradict Arguments.
|
||||
\titem{\{backlog, Value\}} \ind{options!backlog}The backlog value
|
||||
defines the maximum length that the queue of pending connections may
|
||||
grow to. This should be increased if the server is going to handle
|
||||
@@ -847,6 +899,11 @@ This is a detailed description of each option allowed by the listening modules:
|
||||
Simple web page that allows a user to fill a CAPTCHA challenge (see section \ref{captcha}).
|
||||
\titem{\{certfile, Path\}} Full path to a file containing the default SSL certificate.
|
||||
To define a certificate file specific for a given domain, use the global option \term{domain\_certfile}.
|
||||
\titem{\{default\_host, undefined|HostName\}}
|
||||
If the HTTP request received by ejabberd contains the HTTP header \term{Host}
|
||||
with an ambiguous virtual host that doesn't match any one defined in ejabberd (see \ref{hostnames}),
|
||||
then this configured HostName is set as the request Host.
|
||||
The default value of this option is: \term{undefined}.
|
||||
\titem{\{hosts, [Hostname, ...], [HostOption, ...]\}} \ind{options!hosts}
|
||||
The external Jabber component that connects to this \term{ejabberd\_service}
|
||||
can serve one or more hostnames.
|
||||
@@ -939,6 +996,9 @@ This is a detailed description of each option allowed by the listening modules:
|
||||
No unencrypted connections will be allowed.
|
||||
You should also set the \option{certfile} option.
|
||||
You can define a certificate file for a specific domain using the global option \option{domain\_certfile}.
|
||||
\titem{\{timeout, Integer\}} \ind{options!timeout}
|
||||
Timeout of the connections, expressed in milliseconds.
|
||||
Default: 5000
|
||||
\titem{tls} \ind{options!tls}\ind{TLS}This option specifies that traffic on
|
||||
the port will be encrypted using SSL immediately after connecting.
|
||||
This was the traditional encryption method in the early Jabber software,
|
||||
@@ -1085,6 +1145,8 @@ In this example, the following configuration defines that:
|
||||
example in section~\ref{webadmin} shows how exactly this can be done.
|
||||
\item All users except for the administrators have a traffic of limit
|
||||
1,000\,Bytes/second
|
||||
\item The XML-RPC service listens in port 4560 and allows only
|
||||
a specific account, to request registrations and unregistrations in a specific host.
|
||||
\item \ind{transports!AIM}The
|
||||
\footahref{http://www.ejabberd.im/pyaimt}{AIM transport}
|
||||
\jid{aim.example.org} is connected to port 5233 on localhost IP addresses
|
||||
@@ -1115,6 +1177,8 @@ In this example, the following configuration defines that:
|
||||
{shaper, normal, {maxrate, 1000}}.
|
||||
{access, c2s_shaper, [{none, admin},
|
||||
{normal, all}]}.
|
||||
{acl, xmlrpc_bot, {user, "xmlrpc-robot", "example.org"}}.
|
||||
{access, xmlrpc_access, [{allow, xmlrpc_bot}]}.
|
||||
{listen,
|
||||
[{5222, ejabberd_c2s, [
|
||||
{access, c2s},
|
||||
@@ -1134,6 +1198,11 @@ In this example, the following configuration defines that:
|
||||
http_poll,
|
||||
web_admin
|
||||
]},
|
||||
{4560, ejabberd_xmlrpc, [
|
||||
{access_commands, [
|
||||
{xmlrpc_access, [register, unregister], [{host, "example.org"}]}
|
||||
]}
|
||||
]},
|
||||
{{5233, {127, 0, 0, 1}}, ejabberd_service, [
|
||||
{hosts, ["aim.example.org"],
|
||||
[{password, "aimsecret"}]}
|
||||
@@ -1212,6 +1281,7 @@ The following authentication methods are supported by \ejabberd{}:
|
||||
\ref{mssql} and \ref{odbc}.
|
||||
\item anonymous --- See section~\ref{saslanonymous}.
|
||||
\item pam --- See section~\ref{pam}.
|
||||
\item riak --- See section~\ref{riak}.
|
||||
\end{itemize}
|
||||
|
||||
Account creation is only supported by internal, external and odbc methods.
|
||||
@@ -1226,6 +1296,12 @@ The default value is \term{closeold}.
|
||||
If the client uses old Jabber Non-SASL authentication (\xepref{0078}),
|
||||
then this option is not respected, and the action performed is \term{closeold}.
|
||||
|
||||
The option \option{fqdn} allows you to define the Fully Qualified Domain Name
|
||||
of the machine, in case it isn't detected automatically.
|
||||
The FQDN is used to authenticate some clients that use the DIGEST-MD5 SASL mechanism.
|
||||
The option syntax is:
|
||||
\esyntax{\{fqdn, undefined|FqdnString|[FqdnString]\}.}
|
||||
|
||||
\makesubsubsection{internalauth}{Internal}
|
||||
\ind{internal authentication}\ind{Mnesia}
|
||||
|
||||
@@ -1434,7 +1510,7 @@ attacks.
|
||||
\item You may want to allow login access only for certain users. \term{pam\_listfile.so}
|
||||
module provides such functionality.
|
||||
\item If you use \term{pam\_winbind} to authorise against a Windows Active Directory,
|
||||
then \term{/etc/nssswitch.conf} must be configured to use \term{winbind} as well.
|
||||
then \term{/etc/nsswitch.conf} must be configured to use \term{winbind} as well.
|
||||
\end{itemize}
|
||||
|
||||
\makesubsection{accessrules}{Access Rules}
|
||||
@@ -1664,7 +1740,7 @@ The configurable options are:
|
||||
\begin{description}
|
||||
\titem{\{captcha\_cmd, Path\}}
|
||||
Full path to a script that generates the image.
|
||||
The default value is an empty string: \term{""}
|
||||
The default value disables the feature: \term{undefined}
|
||||
\titem{\{captcha\_host, ProtocolHostPort\}}
|
||||
ProtocolHostPort is a string with the host, and optionally the Protocol and Port number.
|
||||
It must identify where ejabberd listens for CAPTCHA requests.
|
||||
@@ -1921,14 +1997,8 @@ For example:
|
||||
\makesubsection{mysql}{MySQL}
|
||||
\ind{MySQL}\ind{MySQL!schema}
|
||||
|
||||
Although this section will describe \ejabberd{}'s configuration when you want to
|
||||
use the native MySQL driver, it does not describe MySQL's installation and
|
||||
database creation. Check the MySQL documentation and the tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} for information regarding these topics.
|
||||
Note that the tutorial contains information about \ejabberd{}'s configuration
|
||||
which is duplicate to this section.
|
||||
|
||||
Moreover, the file mysql.sql in the directory src/odbc might be interesting for
|
||||
you. This file contains the \ejabberd{} schema for MySQL. At the end of the file
|
||||
There is a file \term{mysql.sql} in the directory \term{odbc}.
|
||||
This file contains the \ejabberd{} schema for MySQL. At the end of the file
|
||||
you can find information to update your database schema.
|
||||
|
||||
|
||||
@@ -1936,19 +2006,13 @@ you can find information to update your database schema.
|
||||
\ind{MySQL!Driver Compilation}
|
||||
|
||||
You can skip this step if you installed \ejabberd{} using a binary installer or
|
||||
if the binary packages of \ejabberd{} you are using include support for MySQL.
|
||||
if the binary packages of \ejabberd{} you are using include support for ODBC.
|
||||
|
||||
\begin{enumerate}
|
||||
\item First, install the \footahref{http://support.process-one.net/doc/display/CONTRIBS/Yxa}{Erlang
|
||||
MySQL library}. Make sure the compiled files are in your Erlang path; you can
|
||||
put them for example in the same directory as your \ejabberd{} .beam files.
|
||||
\item Then, configure and install \ejabberd{} with ODBC support enabled (this is
|
||||
also needed for native MySQL support!). This can be done, by using next
|
||||
commands:
|
||||
Use \term{--enable-mysql} configure option in order to build \ejabberd{} with
|
||||
MySQL support:
|
||||
\begin{verbatim}
|
||||
./configure --enable-odbc && make install
|
||||
./configure --enable-mysql && make install
|
||||
\end{verbatim}
|
||||
\end{enumerate}
|
||||
|
||||
|
||||
\makesubsubsection{configuremysql}{Database Connection}
|
||||
@@ -2021,16 +2085,9 @@ that you cannot have several variants of the same module loaded!
|
||||
\makesubsection{mssql}{Microsoft SQL Server}
|
||||
\ind{Microsoft SQL Server}\ind{Microsoft SQL Server!schema}
|
||||
|
||||
Although this section will describe \ejabberd{}'s configuration when you want to
|
||||
use Microsoft SQL Server, it does not describe Microsoft SQL Server's
|
||||
installation and database creation. Check the MySQL documentation and the
|
||||
tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} for information regarding these topics.
|
||||
Note that the tutorial contains information about \ejabberd{}'s configuration
|
||||
which is duplicate to this section.
|
||||
|
||||
Moreover, the file mssql.sql in the directory src/odbc might be interesting for
|
||||
you. This file contains the \ejabberd{} schema for Microsoft SQL Server. At the end
|
||||
of the file you can find information to update your database schema.
|
||||
There is a file \term{mssql.sql} in the directory \term{odbc}.
|
||||
This file contains the \ejabberd{} schema for Microsoft SQL Server. At the end of the file
|
||||
you can find information to update your database schema.
|
||||
|
||||
|
||||
\makesubsubsection{compilemssql}{Driver Compilation}
|
||||
@@ -2039,20 +2096,29 @@ of the file you can find information to update your database schema.
|
||||
You can skip this step if you installed \ejabberd{} using a binary installer or
|
||||
if the binary packages of \ejabberd{} you are using include support for ODBC.
|
||||
|
||||
If you want to use Microsoft SQL Server with ODBC, you need to configure,
|
||||
compile and install \ejabberd{} with support for ODBC and Microsoft SQL Server
|
||||
enabled. This can be done, by using next commands:
|
||||
Use \term{--enable-mssql} configure option in order to build \ejabberd{} with
|
||||
Microsoft SQL Server support:
|
||||
\begin{verbatim}
|
||||
./configure --enable-odbc --enable-mssql && make install
|
||||
./configure --enable-mssql && make install
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\makesubsubsection{configuremssql}{Database Connection}
|
||||
\ind{Microsoft SQL Server!Database Connection}
|
||||
|
||||
The configuration of Database Connection for a Microsoft SQL Server
|
||||
is the same as the configuration for
|
||||
ODBC compatible servers (see section~\ref{configureodbc}).
|
||||
By default \ejabberd{} opens 10 connections to the database for each virtual host.
|
||||
Use this option to modify the value:
|
||||
\begin{verbatim}
|
||||
{odbc_pool_size, 10}.
|
||||
\end{verbatim}
|
||||
|
||||
You can configure an interval to make a dummy SQL request
|
||||
to keep alive the connections to the database.
|
||||
The default value is 'undefined', so no keepalive requests are made.
|
||||
Specify in seconds: for example 28800 means 8 hours.
|
||||
\begin{verbatim}
|
||||
{odbc_keepalive_interval, undefined}.
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\makesubsubsection{mssqlauth}{Authentication}
|
||||
@@ -2060,8 +2126,7 @@ ODBC compatible servers (see section~\ref{configureodbc}).
|
||||
|
||||
%TODO: not sure if this section is right!!!!!!
|
||||
|
||||
The configuration of Authentication for a Microsoft SQL Server
|
||||
is the same as the configuration for
|
||||
The configuration of Microsoft SQL Server is the same as the configuration of
|
||||
ODBC compatible servers (see section~\ref{odbcauth}).
|
||||
|
||||
\makesubsubsection{mssqlstorage}{Storage}
|
||||
@@ -2079,13 +2144,7 @@ module loaded!
|
||||
\makesubsection{pgsql}{PostgreSQL}
|
||||
\ind{PostgreSQL}\ind{PostgreSQL!schema}
|
||||
|
||||
Although this section will describe \ejabberd{}'s configuration when you want to
|
||||
use the native PostgreSQL driver, it does not describe PostgreSQL's installation
|
||||
and database creation. Check the PostgreSQL documentation and the tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} for information regarding these topics.
|
||||
Note that the tutorial contains information about \ejabberd{}'s configuration
|
||||
which is duplicate to this section.
|
||||
|
||||
Also the file pg.sql in the directory src/odbc might be interesting for you.
|
||||
There is a file \term{pg.sql} in the directory \term{odbc}.
|
||||
This file contains the \ejabberd{} schema for PostgreSQL. At the end of the file
|
||||
you can find information to update your database schema.
|
||||
|
||||
@@ -2097,19 +2156,11 @@ You can skip this step if you installed \ejabberd{} using a binary installer or
|
||||
if the binary packages of \ejabberd{} you are using include support for
|
||||
PostgreSQL.
|
||||
|
||||
\begin{enumerate}
|
||||
\item First, install the Erlang pgsql library from
|
||||
\footahref{http://www.ejabberd.im/ejabberd-modules/}{ejabberd-modules SVN repository}.
|
||||
Make sure the compiled
|
||||
files are in your Erlang path; you can put them for example in the same
|
||||
directory as your \ejabberd{} .beam files.
|
||||
\item Then, configure, compile and install \ejabberd{} with ODBC support enabled
|
||||
(this is also needed for native PostgreSQL support!). This can be done, by
|
||||
using next commands:
|
||||
Use \term{--enable-pgsql} configure option in order to build \ejabberd{} with
|
||||
PostgreSQL support:
|
||||
\begin{verbatim}
|
||||
./configure --enable-odbc && make install
|
||||
./configure --enable-pgsql && make install
|
||||
\end{verbatim}
|
||||
\end{enumerate}
|
||||
|
||||
|
||||
\makesubsubsection{configurepgsql}{Database Connection}
|
||||
@@ -2176,31 +2227,6 @@ Keep in mind that you cannot have several variants of the same module loaded!
|
||||
\makesubsection{odbc}{ODBC Compatible}
|
||||
\ind{databases!ODBC}
|
||||
|
||||
Although this section will describe \ejabberd{}'s configuration when you want to
|
||||
use the ODBC driver, it does not describe the installation and database creation
|
||||
of your database. Check the documentation of your database. The tutorial \footahref{http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver}{Using ejabberd with MySQL native driver} also can help you. Note that the tutorial
|
||||
contains information about \ejabberd{}'s configuration which is duplicate to
|
||||
this section.
|
||||
|
||||
|
||||
\makesubsubsection{compileodbc}{Driver Compilation}
|
||||
|
||||
You can skip this step if you installed \ejabberd{} using a binary installer or
|
||||
if the binary packages of \ejabberd{} you are using include support for
|
||||
ODBC.
|
||||
|
||||
\begin{enumerate}
|
||||
\item First, install the \footahref{http://support.process-one.net/doc/display/CONTRIBS/Yxa}{Erlang
|
||||
MySQL library}. Make sure the compiled files are in your Erlang path; you can
|
||||
put them for example in the same directory as your \ejabberd{} .beam files.
|
||||
\item Then, configure, compile and install \ejabberd{} with ODBC support
|
||||
enabled. This can be done, by using next commands:
|
||||
\begin{verbatim}
|
||||
./configure --enable-odbc && make install
|
||||
\end{verbatim}
|
||||
\end{enumerate}
|
||||
|
||||
|
||||
\makesubsubsection{configureodbc}{Database Connection}
|
||||
\ind{ODBC!Database Connection}
|
||||
|
||||
@@ -2567,7 +2593,10 @@ The following table lists all modules included in \ejabberd{}.
|
||||
\hline
|
||||
\hline \modadhoc{} & Ad-Hoc Commands (\xepref{0050}) & \\
|
||||
\hline \ahrefloc{modannounce}{\modannounce{}} & Manage announcements & recommends \modadhoc{} \\
|
||||
\hline \ahrefloc{modannounce}{\modannounceodbc{}} & Manage announcements & recommends \modadhoc{} \\
|
||||
& & supported DB (*) \\
|
||||
\hline \modblocking{} & Simple Communications Blocking (\xepref{0191}) & \modprivacy{} \\
|
||||
\hline \modblockingodbc{} & Simple Communications Blocking (\xepref{0191}) & \modprivacyodbc{} \\
|
||||
\hline \modcaps{} & Entity Capabilities (\xepref{0115}) & \\
|
||||
\hline \modconfigure{} & Server configuration using Ad-Hoc & \modadhoc{} \\
|
||||
\hline \ahrefloc{moddisco}{\moddisco{}} & Service Discovery (\xepref{0030}) & \\
|
||||
@@ -2575,10 +2604,13 @@ The following table lists all modules included in \ejabberd{}.
|
||||
\hline \ahrefloc{modhttpbind}{\modhttpbind{}} & XMPP over Bosh service (HTTP Binding) & \\
|
||||
\hline \ahrefloc{modhttpfileserver}{\modhttpfileserver{}} & Small HTTP file server & \\
|
||||
\hline \ahrefloc{modirc}{\modirc{}} & IRC transport & \\
|
||||
\hline \ahrefloc{modirc}{\modircodbc{}} & IRC transport & supported DB (*) \\
|
||||
\hline \ahrefloc{modlast}{\modlast{}} & Last Activity (\xepref{0012}) & \\
|
||||
\hline \ahrefloc{modlast}{\modlastodbc{}} & Last Activity (\xepref{0012}) & supported DB (*) \\
|
||||
\hline \ahrefloc{modmuc}{\modmuc{}} & Multi-User Chat (\xepref{0045}) & \\
|
||||
\hline \ahrefloc{modmuclog}{\modmuclog{}} & Multi-User Chat room logging & \modmuc{} \\
|
||||
\hline \ahrefloc{modmuc}{\modmucodbc{}} & Multi-User Chat (\xepref{0045}) & supported DB (*) \\
|
||||
\hline \ahrefloc{modmuclog}{\modmuclog{}} & Multi-User Chat room logging & \modmuc{} or \modmucodbc{} \\
|
||||
\hline \ahrefloc{modmulticast}{\modmulticast{}} & Multicast service (\xepref{0033}) & \\
|
||||
\hline \ahrefloc{modoffline}{\modoffline{}} & Offline message storage (\xepref{0160}) & \\
|
||||
\hline \ahrefloc{modoffline}{\modofflineodbc{}} & Offline message storage (\xepref{0160}) & supported DB (*) \\
|
||||
\hline \ahrefloc{modping}{\modping{}} & XMPP Ping and periodic keepalives (\xepref{0199}) & \\
|
||||
@@ -2597,6 +2629,8 @@ The following table lists all modules included in \ejabberd{}.
|
||||
\hline \ahrefloc{modservicelog}{\modservicelog{}} & Copy user messages to logger service & \\
|
||||
\hline \ahrefloc{modsharedroster}{\modsharedroster{}} & Shared roster management & \modroster{} or \\
|
||||
& & \modrosterodbc\\
|
||||
\hline \ahrefloc{modsharedroster}{\modsharedrosterodbc{}} & Shared roster management & supported DB (*) and\\
|
||||
& & \modroster{} or \modrosterodbc\\
|
||||
\hline \ahrefloc{modsharedrosterldap}{\modsharedrosterldap{}} & LDAP Shared roster management & \modroster{} or \\
|
||||
& & \modrosterodbc\\
|
||||
\hline \ahrefloc{modsic}{\modsic{}} & Server IP Check (\xepref{0279}) & \\
|
||||
@@ -2606,6 +2640,7 @@ The following table lists all modules included in \ejabberd{}.
|
||||
\hline \ahrefloc{modvcardldap}{\modvcardldap{}} & vcard-temp (\xepref{0054}) & LDAP server \\
|
||||
\hline \ahrefloc{modvcard}{\modvcardodbc{}} & vcard-temp (\xepref{0054}) & supported DB (*) \\
|
||||
\hline \ahrefloc{modvcardxupdate}{\modvcardxupdate{}} & vCard-Based Avatars (\xepref{0153}) & \modvcard{} or \modvcardodbc{} \\
|
||||
\hline \ahrefloc{modvcardxupdate}{\modvcardxupdateodbc{}} & vCard-Based Avatars (\xepref{0153}) & \modvcard{} or \modvcardodbc{} \\
|
||||
\hline \ahrefloc{modversion}{\modversion{}} & Software Version (\xepref{0092}) & \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
@@ -2636,10 +2671,16 @@ database for the following data:
|
||||
\item Offline messages: Use \term{mod\_offline\_odbc} instead of
|
||||
\term{mod\_offline}.
|
||||
\item Rosters: Use \term{mod\_roster\_odbc} instead of \term{mod\_roster}.
|
||||
\item Shared Rosters: Use \term{mod\_shared\_roster\_odbc} instead of \term{mod\_shared\_roster}.
|
||||
\item Users' VCARD: Use \term{mod\_vcard\_odbc} instead of \term{mod\_vcard}.
|
||||
\item vCard-Based Avatars: Use \term{mod\_vcard\_xupdate\_odbc} instead of \term{mod\_vcard\_xupdate}.
|
||||
\item Private XML storage: Use \term{mod\_private\_odbc} instead of \term{mod\_private}.
|
||||
\item User rules for blocking communications: Use \term{mod\_privacy\_odbc} instead of \term{mod\_privacy}.
|
||||
\item Simple Communications Blocking: Use \term{mod\_blocking\_odbc} instead of \term{mod\_blocking}.
|
||||
\item Pub-Sub nodes, items and subscriptions: Use \term{mod\_pubsub\_odbc} instead of \term{mod\_pubsub}.
|
||||
\item Multi-user chats: Use \term{mod\_muc\_odbc} instead of \term{mod\_muc}.
|
||||
\item Manage announcements: Use \term{mod\_announce\_odbc} instead of \term{mod\_announce}.
|
||||
\item IRC transport: Use \term{mod\_irc\_odbc} instead of \term{mod\_irc}.
|
||||
\end{itemize}
|
||||
|
||||
You can find more
|
||||
@@ -3260,7 +3301,7 @@ Module options:
|
||||
\titem{\{default\_room\_options, [ \{OptionName, OptionValue\}, ...]\}} \ind{options!default\_room\_options}
|
||||
This module option allows to define the desired default room options.
|
||||
Note that the creator of a room can modify the options of his room
|
||||
at any time using a XMPP client with MUC capability.
|
||||
at any time using an XMPP client with MUC capability.
|
||||
The available room options and the default values are:
|
||||
\begin{description}
|
||||
\titem{\{allow\_change\_subj, true|false\}} Allow occupants to change the subject.
|
||||
@@ -3531,6 +3572,56 @@ Examples:
|
||||
\end{verbatim}
|
||||
\end{itemize}
|
||||
|
||||
\makesubsection{modmulticast}{\modmulticast{}}
|
||||
\ind{modules!\modmulticast{}}
|
||||
|
||||
This module implements Extended Stanza Addressing (\xepref{0033}).
|
||||
|
||||
\begin{description}
|
||||
\hostitem{multicast}
|
||||
\titem{\{access, AccessName\}}\ind{options!access}
|
||||
This option specifies the access rule that defines who can send packets to the multicast service.
|
||||
The default value is \term{all}.
|
||||
\titem{\{limits, [\{SenderType, StanzaType, Number\}]\}}\ind{options!limits}
|
||||
Specify a list of custom limits which override the default ones defined
|
||||
in (\xepref{0033}).
|
||||
Where:
|
||||
\begin{itemize}
|
||||
\item SenderType can have values: local or remote.
|
||||
\item StanzaType can have values: message or presence.
|
||||
\item Number can be a positive integer or the key word infinite.
|
||||
\end{itemize}
|
||||
The default value is \term{[]}.
|
||||
\end{description}
|
||||
|
||||
Example configuration:
|
||||
\begin{verbatim}
|
||||
%% Only admins can send packets to multicast service
|
||||
{access, multicast, [{allow, admin}, {deny, all}]}.
|
||||
|
||||
%% If you want to allow all your users:
|
||||
%%{access, multicast, [{allow, all}]}.
|
||||
|
||||
%% This allows both admins and remote users to send packets,
|
||||
%% but does not allow local users
|
||||
%%{acl, allservers, {server_glob, "*"}}.
|
||||
%%{access, multicast, [{allow, admin}, {deny, local}, {allow, allservers}]}.
|
||||
|
||||
{modules, [
|
||||
...
|
||||
{mod_multicast, [
|
||||
%%{host, "multicast.@HOST@"},
|
||||
{access, multicast},
|
||||
{limits, [
|
||||
{local, message, 40},
|
||||
{local, presence, infinite},
|
||||
{remote, message, 150}
|
||||
]}
|
||||
]},
|
||||
...
|
||||
]}.
|
||||
\end{verbatim}
|
||||
|
||||
\makesubsection{modoffline}{\modoffline{}}
|
||||
\ind{modules!\modoffline{}}
|
||||
|
||||
@@ -4038,7 +4129,7 @@ Options:
|
||||
This option does not affect the client in any way.
|
||||
This option is only useful if Roster Versioning is enabled.
|
||||
This option is disabled by default.
|
||||
Important: if you use \modsharedroster{} or \modsharedrosterldap{},
|
||||
Important: if you use \modsharedroster{}, \modsharedrosterodbc{} or \modsharedrosterldap{},
|
||||
you must disable this option.
|
||||
\end{description}
|
||||
|
||||
@@ -5094,9 +5185,10 @@ with a defined number and type of calling arguments and type of result
|
||||
that is registered in the \term{ejabberd\_commands} service.
|
||||
Those commands can be defined in any Erlang module and executed using any valid frontend.
|
||||
|
||||
\ejabberd{} includes a frontend to execute \term{ejabberd commands}: the script \term{ejabberdctl}.
|
||||
\ejabberd{} includes two frontends to execute \term{ejabberd commands}:
|
||||
the \term{ejabberdctl} shell script (see \ref{ejabberdctl})
|
||||
and the \term{ejabberd\_xmlrpc} XML-RPC listener (see \ref{listened-module}).
|
||||
Other known frontends that can be installed to execute ejabberd commands in different ways are:
|
||||
\term{ejabberd\_xmlrpc} (XML-RPC service),
|
||||
\term{mod\_rest} (HTTP POST service),
|
||||
\term{mod\_shcommands} (ejabberd WebAdmin page).
|
||||
|
||||
@@ -5154,6 +5246,8 @@ The most interesting ones are:
|
||||
from other Jabber/XMPP servers
|
||||
There exist tutorials to
|
||||
\footahref{http://www.ejabberd.im/migrate-to-ejabberd}{migrate from other software to ejabberd}.
|
||||
\titem{export\_odbc virtualhost filename} \ind{export mnesia data to a SQL file}
|
||||
Export virtual host information from Mnesia tables to a SQL file.
|
||||
\titem{delete\_expired\_messages} This option can be used to delete old messages
|
||||
in offline storage. This might be useful when the number of offline messages
|
||||
is very high.
|
||||
@@ -5320,7 +5414,7 @@ See section \ref{erlangconfiguration}.
|
||||
|
||||
If you enable \modconfigure\ and \modadhoc,
|
||||
you can perform several administrative tasks in \ejabberd{}
|
||||
with a XMPP client.
|
||||
with an XMPP client.
|
||||
The client must support Ad-Hoc Commands (\xepref{0050}),
|
||||
and you must login in the XMPP server with
|
||||
an account with proper privileges.
|
||||
@@ -5873,6 +5967,7 @@ Thanks to all people who contributed to this guide:
|
||||
\item Badlop (\ahrefurl{xmpp:badlop@jabberes.org})
|
||||
\item Evgeniy Khramtsov (\ahrefurl{xmpp:xram@jabber.ru})
|
||||
\item Florian Zumbiehl (\ahrefurl{xmpp:florz@florz.de})
|
||||
\item Ludovic Bocquet (\ahrefurl{xmpp:lbocquet@jabber.org})
|
||||
\item Marcin Owsiany (\ahrefurl{xmpp:marcin.owsiany@gmail.com})
|
||||
\item Michael Grigutsch (\ahrefurl{xmpp:migri@jabber.i-pobox.net})
|
||||
\item Mickael Remond (\ahrefurl{xmpp:mremond@process-one.net})
|
||||
@@ -5885,7 +5980,7 @@ Thanks to all people who contributed to this guide:
|
||||
\makechapter{copyright}{Copyright Information}
|
||||
|
||||
Ejabberd Installation and Operation Guide.\\
|
||||
Copyright \copyright{} 2003 --- 2010 ProcessOne
|
||||
Copyright \copyright{} 2003 --- 2013 ProcessOne
|
||||
|
||||
This document is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
# Managing pubsub nodes through HTTP Atompub #
|
||||
|
||||
|
||||
## Configuration ##
|
||||
|
||||
These options will be used by the service to know how to build URLs. Using the previous configuration items the service should be accessed through `http://notify.push.bbc.co.uk:5280/pshb/<host>/<node>/`.
|
||||
|
||||
Also, in the ejabberd_http handler configuration, add the identified line.
|
||||
|
||||
{5280, ejabberd_http, [
|
||||
http_poll,
|
||||
web_admin,
|
||||
{request_handlers, [{["pshb"], pshb_http}]} % this should be added
|
||||
]}
|
||||
|
||||
It will automatically detect the version of mod_pubsub (odbc or mnesia) and call the appropriate module.
|
||||
|
||||
## Important notice ##
|
||||
|
||||
In the current version of the code, some security checks are not done :
|
||||
|
||||
* node creation uses the default `all` access_createnode acl, not checking for the actual configuration.
|
||||
|
||||
* most read operations are successfully executed without authentication. HOWEVER listing items can only be done when the node access_model is "open". In all other cases, the service returns 403. A finer grained authentication will be implemented.
|
||||
|
||||
|
||||
## Usage example with cURL ##
|
||||
|
||||
### Errors ###
|
||||
|
||||
HTTP status codes are used as intended. Additionally, the XMPP error stanza can also be set in the body :
|
||||
|
||||
$ curl -i -X POST -u cstar@localhost:encore -d @createnode.xml http://localhost:5280/pshb/localhost
|
||||
HTTP/1.1 409 Conflict
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Content-Length: 95
|
||||
Content-type: application/xml
|
||||
|
||||
<error code='409' type='cancel'><conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error>
|
||||
|
||||
or
|
||||
|
||||
$ curl -i -X DELETE -u cstar@localhost:encore http://localhost:5280/pshb/localhost/princely_musings
|
||||
HTTP/1.1 404 Not Found
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Content-Length: 101
|
||||
Content-type: application/xml
|
||||
|
||||
<error code='404' type='cancel'><item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error>
|
||||
|
||||
### Getting the service document ###
|
||||
|
||||
No authentication necessary. All nodes are listed.
|
||||
|
||||
$ curl -i http://host:port/pshb/domain/
|
||||
|
||||
### Getting items from a node ###
|
||||
|
||||
No authentication done, and all nodes are accessible.
|
||||
|
||||
$ curl -i http://host:port/pshb/domain/node/
|
||||
|
||||
|
||||
### Posting a new item ###
|
||||
|
||||
$ curl -u jid:password -i -X POST -d @entry.atom http://post:port/pshb/domain/node
|
||||
|
||||
User ability to post is based on node configuration.
|
||||
|
||||
### Editing a new item ###
|
||||
|
||||
$ curl -u jid:password -i -X POST -d @entry.atom http://post:port/pshb/domain/node/itemid
|
||||
|
||||
User ability to post is based on node configuration.
|
||||
|
||||
### Deleting an item ###
|
||||
|
||||
$ curl -u jid:password -i -X DELETE http://post:port/pshb/domain/node/itemid
|
||||
|
||||
User ability to post is based on node configuration.
|
||||
|
||||
|
||||
### Creating a new node ###
|
||||
|
||||
An instant node can be created if server configuration allows:
|
||||
|
||||
$ curl -X POST -u cstar@localhost:encore -d "" http://localhost:5280/pshb/localhost
|
||||
|
||||
or
|
||||
|
||||
$ curl -X POST -u cstar@localhost:encore -d "<pubsub><create node='princely_musings'/></pubsub>" http://localhost:5280/pshb/localhost
|
||||
|
||||
configure element (as per XEP-60) can be passed in the pubsub body.
|
||||
|
||||
$ cat createnode.xml
|
||||
<pubsub><create node='princely_musings' type='flat'/>
|
||||
<x xmlns='jabber:x:data' type='submit'>
|
||||
<field var='FORM_TYPE' type='hidden'>
|
||||
<value>http://jabber.org/protocol/pubsub#node_config</value>
|
||||
</field>
|
||||
<field var='pubsub#title'><value>Princely Musings (Atom)</value></field>
|
||||
<field var='pubsub#max_payload_size'><value>1028</value></field>
|
||||
<field var='pubsub#type'><value>Atom</value></field>
|
||||
</x>
|
||||
</pubsub>
|
||||
|
||||
$ curl -i -X POST -u cstar@localhost:encore -d @createnode.xml http://localhost:5280/pshb/localhost
|
||||
HTTP/1.1 200 OK
|
||||
Content-Length: 130
|
||||
Content-Type: application/xml
|
||||
|
||||
<?xml version="1.0" encoding="utf-8"?><pubsub xmlns='http://jabber.org/protocol/pubsub'><create node='princely_musings'/></pubsub>
|
||||
|
||||
### Editing a node configuration ###
|
||||
|
||||
$ cat editnode.xml
|
||||
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
|
||||
<configure node='princely_musings'>
|
||||
<x xmlns='jabber:x:data' type='submit'>
|
||||
<field var='FORM_TYPE' type='hidden'>
|
||||
<value>http://jabber.org/protocol/pubsub#node_config</value>
|
||||
</field>
|
||||
<field var='pubsub#title'><value>Princely Musings (Atom)</value></field>
|
||||
<field var='pubsub#deliver_notifications'><value>1</value></field>
|
||||
<field var='pubsub#deliver_payloads'><value>1</value></field>
|
||||
<field var='pubsub#persist_items'><value>1</value></field>
|
||||
<field var='pubsub#max_items'><value>10</value></field>
|
||||
<field var='pubsub#item_expire'><value>604800</value></field>
|
||||
<field var='pubsub#access_model'><value>roster</value></field>
|
||||
</x>
|
||||
</configure>
|
||||
</pubsub>
|
||||
|
||||
|
||||
$ curl -i -X PUT -u cstar@localhost:encore -d @createnode.xml http://localhost:5280/pshb/localhost/princely_musings
|
||||
|
||||
|
||||
|
||||
### Deleting a node ###
|
||||
|
||||
A node is deleted by:
|
||||
|
||||
$ curl -X DELETE -u cstar@localhost:encore http://localhost:5280/pshb/localhost/princely_musings
|
||||
|
||||
|
||||
|
||||
Executable
+99
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env escript
|
||||
%% -*- erlang -*-
|
||||
|
||||
-record(cmd, {name, desc, longdesc, args, result}).
|
||||
|
||||
main(_) ->
|
||||
Dir = filename:absname(filename:join(["..", "src"])),
|
||||
FileIn = filename:join([Dir, "mod_admin_p1.erl"]),
|
||||
{ok, Forms1} = epp_dodger:parse_file(FileIn, [no_fail]),
|
||||
Comments = erl_comment_scan:file(FileIn),
|
||||
Forms = erl_recomment:recomment_forms(Forms1, Comments),
|
||||
Tree = erl_syntax:flatten_form_list(Forms),
|
||||
AuxFile = "mod_admin.tex",
|
||||
case file:open(AuxFile, [write]) of
|
||||
{ok, Fd} ->
|
||||
io:format(Fd, "\\newcommand{\\modadminsection}{\\begin{description}~n", []),
|
||||
process(Fd, Tree),
|
||||
io:format(Fd, "\\end{description}}~n", []),
|
||||
file:close(Fd),
|
||||
halt(0);
|
||||
{error, Why} ->
|
||||
io:format("failed to open file ~s: ~s",
|
||||
[AuxFile, file:format_error(Why)]),
|
||||
halt(1)
|
||||
end.
|
||||
|
||||
process(Fd, Tree) ->
|
||||
case erl_syntax:type(Tree) of
|
||||
record_expr ->
|
||||
case erl_syntax_lib:analyze_record_expr(Tree) of
|
||||
{record_expr, {ejabberd_commands, _}} ->
|
||||
Fs = erl_syntax:record_expr_fields(Tree),
|
||||
Cmd = lists:foldl(
|
||||
fun(F, C) ->
|
||||
Name = erl_syntax:record_field_name(F),
|
||||
Value = erl_syntax:record_field_value(F),
|
||||
case {erl_syntax:concrete(Name),
|
||||
catch erl_syntax:concrete(Value)} of
|
||||
{_, {'EXIT', _}} ->
|
||||
C;
|
||||
{name, V} ->
|
||||
C#cmd{name = V};
|
||||
{desc, V} ->
|
||||
C#cmd{desc = V};
|
||||
{longdesc, V} ->
|
||||
C#cmd{longdesc = V};
|
||||
{args, V} ->
|
||||
C#cmd{args = V};
|
||||
{result, V} ->
|
||||
C#cmd{result = V};
|
||||
_ ->
|
||||
C
|
||||
end
|
||||
end, #cmd{}, Fs),
|
||||
format_command(Fd, Cmd);
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
case erl_syntax:subtrees(Tree) of
|
||||
[] ->
|
||||
ok;
|
||||
List ->
|
||||
lists:foreach(
|
||||
fun(Group) ->
|
||||
lists:foreach(
|
||||
fun(Subtree) ->
|
||||
process(Fd, Subtree)
|
||||
end, Group)
|
||||
end, List)
|
||||
end
|
||||
end.
|
||||
|
||||
-define(B(S), S).
|
||||
|
||||
format_command(Fd, #cmd{name = Cmd,
|
||||
desc = Desc,
|
||||
longdesc = _LongDesc,
|
||||
args = ArgsDef,
|
||||
result = _ResultDef}) ->
|
||||
io:format(Fd, "\\titem{~s ~s} ~s~n",
|
||||
[escape_underscores(atom_to_list(Cmd)),
|
||||
flatten_arguments(ArgsDef),
|
||||
escape_underscores(Desc)]).
|
||||
|
||||
flatten_arguments(Args) ->
|
||||
string:join(
|
||||
lists:map(
|
||||
fun({Name, _Type}) ->
|
||||
escape_underscores(io_lib:format("~s", [Name]))
|
||||
end, Args),
|
||||
" ").
|
||||
|
||||
escape_underscores(S) ->
|
||||
lists:flatten(
|
||||
[case C of
|
||||
$_ -> "\\_";
|
||||
_ -> C
|
||||
end || C <- S]).
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.11
|
||||
|
||||
ejabberd 2.1.11 includes a few bugfixes and improvements.
|
||||
|
||||
Read more details about the changes in:
|
||||
http://redir.process-one.net/ejabberd-2.1.11
|
||||
|
||||
Download the source code and installers from:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
The major changes are:
|
||||
|
||||
* HTTP service
|
||||
- Fix ejabberd_http:get_line
|
||||
- Don't use binary:match to extract lines from binaries
|
||||
- Parse and encode https header names like native http parser does
|
||||
- Parse correctly https request split into multiple packets
|
||||
- Properly handle HEAD request in mod_http_bind (EJAB-1538)
|
||||
- New option default_host for handling requests with ambiguous Host (EJAB-1261)
|
||||
|
||||
* ODBC
|
||||
- New ODBC support for mod_announce
|
||||
- New ODBC support for mod_blocking
|
||||
- New ODBC support for mod_irc
|
||||
- New ODBC support for mod_muc
|
||||
- New ODBC support for mod_shared_roster
|
||||
- New ODBC support for mod_vcard_xupdate
|
||||
- Add ODBC exporting function for privacy table
|
||||
- Work also with some unicode strings in PgSQL (EJAB-1490)
|
||||
- Replace a single quote with double quotes in an ODBC escape
|
||||
|
||||
* SSL
|
||||
- Make sure that res is initialized in all cases
|
||||
- Parse correctly https request split into multiple packets (EJAB-1537)
|
||||
- Added missed tls:recv_data/2
|
||||
- Don't ignore Length parameter in tls:recv
|
||||
- Avoid quadratic behavior in reading SSL data
|
||||
- Dix http_bind webserver TLS fail on Chrome (EJAB-1530)
|
||||
|
||||
* Miscelanea
|
||||
- Assume we have only one CPU when an auto-detection fails (EJAB-1516)
|
||||
- Auth: Relax digest-uri handling (EJAB-1529)
|
||||
- Caps: Cache caps timestamp before the IQ-request is done
|
||||
- IRC: Use of MUC password
|
||||
- Private: misc errors cases fixes
|
||||
- Pubsub: return user affiliation for a specified node (EJAB-1294)
|
||||
- Shared Roster: Foreign items were not pushed (EJAB-1509)
|
||||
- Shared Roster LDAP: user substitution in ldap_rfilter (EJAB-1555)
|
||||
- Windows: Fix makefile rules for building DLLs
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
% ejabberd version (automatically generated).
|
||||
\newcommand{\version}{2.1.10}
|
||||
\newcommand{\version}{3.0.0}
|
||||
|
||||
@@ -154,6 +154,13 @@
|
||||
%%
|
||||
%%{{3478, udp}, ejabberd_stun, []},
|
||||
|
||||
%%
|
||||
%% To handle XML-RPC requests that provide admin credentials:
|
||||
%%
|
||||
%%{4560, ejabberd_xmlrpc, [
|
||||
%% {access_commands, [{admin, all, []}]}
|
||||
%% ]},
|
||||
|
||||
{5280, ejabberd_http, [
|
||||
%%{request_handlers,
|
||||
%% [
|
||||
@@ -222,6 +229,9 @@
|
||||
%% Store the plain passwords or hashed for SCRAM:
|
||||
%%{auth_password_format, plain}.
|
||||
%%{auth_password_format, scram}.
|
||||
%%
|
||||
%% Define the FQDN if ejabberd doesn't detect it:
|
||||
%%{fqdn, "server3.example.com"}.
|
||||
|
||||
%%
|
||||
%% Authentication using external script
|
||||
Regular → Executable
+120
-81
@@ -7,12 +7,14 @@ ERL_MAX_PORTS=32000
|
||||
ERL_PROCESSES=250000
|
||||
ERL_MAX_ETS_TABLES=1400
|
||||
|
||||
SCRIPT_DIR=$(cd ${0%/*} && pwd)
|
||||
|
||||
# define default environment variables
|
||||
NODE=ejabberd
|
||||
HOST=localhost
|
||||
ERLANG_NODE=$NODE@$HOST
|
||||
ERL=@erl@
|
||||
INSTALLUSER=@installuser@
|
||||
ERL={{erl}}
|
||||
INSTALLUSER={{installuser}}
|
||||
|
||||
# parse command line parameters
|
||||
ARGS=
|
||||
@@ -33,7 +35,7 @@ done
|
||||
|
||||
# Define ejabberd variable if they have not been defined from the command line
|
||||
if [ "$ETCDIR" = "" ] ; then
|
||||
ETCDIR=@SYSCONFDIR@/ejabberd
|
||||
ETCDIR={{sysconfdir}}/ejabberd
|
||||
fi
|
||||
if [ "$EJABBERD_CONFIG_PATH" = "" ] ; then
|
||||
EJABBERD_CONFIG_PATH=$ETCDIR/ejabberd.cfg
|
||||
@@ -41,18 +43,21 @@ fi
|
||||
if [ "$EJABBERDCTL_CONFIG_PATH" = "" ] ; then
|
||||
EJABBERDCTL_CONFIG_PATH=$ETCDIR/ejabberdctl.cfg
|
||||
fi
|
||||
[ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
|
||||
if [ -f "$EJABBERDCTL_CONFIG_PATH" ] ; then
|
||||
. "$EJABBERDCTL_CONFIG_PATH"
|
||||
fi
|
||||
if [ "$LOGS_DIR" = "" ] ; then
|
||||
LOGS_DIR=@LOCALSTATEDIR@/log/ejabberd
|
||||
LOGS_DIR={{localstatedir}}/log/ejabberd
|
||||
fi
|
||||
if [ "$SPOOLDIR" = "" ] ; then
|
||||
SPOOLDIR=@LOCALSTATEDIR@/lib/ejabberd
|
||||
SPOOLDIR={{localstatedir}}/lib/ejabberd
|
||||
fi
|
||||
if [ "$EJABBERD_DOC_PATH" = "" ] ; then
|
||||
EJABBERD_DOC_PATH=@DOCDIR@
|
||||
EJABBERD_DOC_PATH={{docdir}}
|
||||
fi
|
||||
if [ "$ERLANG_NODE_ARG" != "" ] ; then
|
||||
ERLANG_NODE=$ERLANG_NODE_ARG
|
||||
NODE=${ERLANG_NODE%@*}
|
||||
fi
|
||||
|
||||
# check the proper system user is used
|
||||
@@ -62,19 +67,21 @@ EJID=`id -g $INSTALLUSER`
|
||||
EXEC_CMD="false"
|
||||
for GID in $GIDS; do
|
||||
if [ $GID -eq 0 ] ; then
|
||||
EXEC_CMD="su ${INSTALLUSER} -p -c"
|
||||
EXEC_CMD="su ${INSTALLUSER} -p -c"
|
||||
fi
|
||||
done
|
||||
if [ "$ID" -eq "$EJID" ] ; then
|
||||
EXEC_CMD="sh -c"
|
||||
EXEC_CMD="sh -c"
|
||||
fi
|
||||
if [ "$EXEC_CMD" = "false" ] ; then
|
||||
echo "This command can only be run by root or the user $INSTALLUSER" >&2
|
||||
exit 4
|
||||
echo "This command can only be run by root or the user $INSTALLUSER" >&2
|
||||
exit 4
|
||||
fi
|
||||
|
||||
NAME=-name
|
||||
[ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && NAME=-sname
|
||||
if [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] ; then
|
||||
NAME=-sname
|
||||
fi
|
||||
|
||||
KERNEL_OPTS=""
|
||||
if [ "$FIREWALL_WINDOW" != "" ] ; then
|
||||
@@ -87,23 +94,25 @@ fi
|
||||
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
|
||||
|
||||
# define additional environment variables
|
||||
if [ "$EJABBERDDIR" = "" ]; then
|
||||
EJABBERDDIR=@LIBDIR@/ejabberd
|
||||
fi
|
||||
if [ "$EJABBERD_EBIN_PATH" = "" ]; then
|
||||
EJABBERD_EBIN_PATH=$EJABBERDDIR/ebin
|
||||
fi
|
||||
if [ "$EJABBERD_PRIV_PATH" = "" ]; then
|
||||
EJABBERD_PRIV_PATH=$EJABBERDDIR/priv
|
||||
fi
|
||||
if [ "$EJABBERD_BIN_PATH" = "" ]; then
|
||||
EJABBERD_BIN_PATH=$EJABBERD_PRIV_PATH/bin
|
||||
fi
|
||||
if [ "$EJABBERD_SO_PATH" = "" ]; then
|
||||
EJABBERD_SO_PATH=$EJABBERD_PRIV_PATH/lib
|
||||
fi
|
||||
if [ "$EJABBERD_MSGS_PATH" = "" ]; then
|
||||
EJABBERD_MSGS_PATH=$EJABBERD_PRIV_PATH/msgs
|
||||
if [ "{{release}}" != "true" ] ; then
|
||||
if [ "$EJABBERDDIR" = "" ] ; then
|
||||
EJABBERDDIR={{libdir}}/ejabberd
|
||||
fi
|
||||
if [ "$EJABBERD_EBIN_PATH" = "" ] ; then
|
||||
EJABBERD_EBIN_PATH=$EJABBERDDIR/ebin
|
||||
fi
|
||||
if [ "$EJABBERD_PRIV_PATH" = "" ] ; then
|
||||
EJABBERD_PRIV_PATH=$EJABBERDDIR/priv
|
||||
fi
|
||||
if [ "$EJABBERD_BIN_PATH" = "" ] ; then
|
||||
EJABBERD_BIN_PATH=$EJABBERD_PRIV_PATH/bin
|
||||
fi
|
||||
if [ "$EJABBERD_SO_PATH" = "" ] ; then
|
||||
EJABBERD_SO_PATH=$EJABBERD_PRIV_PATH/lib
|
||||
fi
|
||||
if [ "$EJABBERD_MSGS_PATH" = "" ] ; then
|
||||
EJABBERD_MSGS_PATH=$EJABBERD_PRIV_PATH/msgs
|
||||
fi
|
||||
fi
|
||||
|
||||
EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
|
||||
@@ -143,6 +152,7 @@ export EXEC_CMD
|
||||
# start server
|
||||
start ()
|
||||
{
|
||||
check_start
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME $ERLANG_NODE \
|
||||
-noinput -detached \
|
||||
@@ -174,7 +184,7 @@ debug ()
|
||||
echo " EJABBERD_BYPASS_WARNINGS=true"
|
||||
echo "Press any key to continue"
|
||||
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
|
||||
read foo
|
||||
read foo
|
||||
fi
|
||||
echo ""
|
||||
TTY=`tty | sed -e 's/.*\///g'`
|
||||
@@ -189,6 +199,7 @@ debug ()
|
||||
# start interactive server
|
||||
live ()
|
||||
{
|
||||
check_start
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo ""
|
||||
echo "IMPORTANT: ejabberd is going to start in LIVE (interactive) mode."
|
||||
@@ -205,7 +216,7 @@ live ()
|
||||
echo " EJABBERD_BYPASS_WARNINGS=true"
|
||||
echo "Press any key to continue"
|
||||
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
|
||||
read foo
|
||||
read foo
|
||||
fi
|
||||
echo ""
|
||||
$EXEC_CMD "$ERL \
|
||||
@@ -217,6 +228,13 @@ live ()
|
||||
$ERLANG_OPTS $ARGS \"$@\""
|
||||
}
|
||||
|
||||
etop()
|
||||
{
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME debug-${TTY}-${ERLANG_NODE} \
|
||||
-hidden -s etop -s erlang halt -output text -node $ERLANG_NODE"
|
||||
}
|
||||
|
||||
help ()
|
||||
{
|
||||
echo ""
|
||||
@@ -244,69 +262,69 @@ ctl ()
|
||||
# using flock if available. Expects a linux-style
|
||||
# flock that can lock a file descriptor.
|
||||
MAXCONNID=100
|
||||
CONNLOCKDIR=@LOCALSTATEDIR@/lock/ejabberdctl
|
||||
CONNLOCKDIR={{localstatedir}}/lock/ejabberdctl
|
||||
FLOCK='/usr/bin/flock'
|
||||
if [ ! -x "$FLOCK" ] || [ ! -d "$CONNLOCKDIR" ] ; then
|
||||
JOT='/usr/bin/jot'
|
||||
if [ ! -x "$JOT" ] ; then
|
||||
# no flock or jot, simply invoke ctlexec()
|
||||
CTL_CONN="ctl-${ERLANG_NODE}"
|
||||
ctlexec $CTL_CONN $COMMAND
|
||||
result=$?
|
||||
else
|
||||
# no flock, but at least there is jot
|
||||
RAND=`jot -r 1 0 $MAXCONNID`
|
||||
CTL_CONN="ctl-${RAND}-${ERLANG_NODE}"
|
||||
ctlexec $CTL_CONN $COMMAND
|
||||
result=$?
|
||||
fi
|
||||
JOT='/usr/bin/jot'
|
||||
if [ ! -x "$JOT" ] ; then
|
||||
# no flock or jot, simply invoke ctlexec()
|
||||
CTL_CONN="ctl-${ERLANG_NODE}"
|
||||
ctlexec $CTL_CONN $COMMAND
|
||||
result=$?
|
||||
else
|
||||
# no flock, but at least there is jot
|
||||
RAND=`jot -r 1 0 $MAXCONNID`
|
||||
CTL_CONN="ctl-${RAND}-${ERLANG_NODE}"
|
||||
ctlexec $CTL_CONN $COMMAND
|
||||
result=$?
|
||||
fi
|
||||
else
|
||||
# we have flock so we get a lock
|
||||
# on one of a limited number of
|
||||
# conn names -- this allows
|
||||
# concurrent invocations using a bound
|
||||
# number of atoms
|
||||
for N in $(seq 1 $MAXCONNID); do
|
||||
CTL_CONN="ejabberdctl-$N"
|
||||
CTL_LOCKFILE="$CONNLOCKDIR/$CTL_CONN"
|
||||
(
|
||||
exec 8>"$CTL_LOCKFILE"
|
||||
if flock --nb 8; then
|
||||
ctlexec $CTL_CONN $COMMAND
|
||||
# we have flock so we get a lock
|
||||
# on one of a limited number of
|
||||
# conn names -- this allows
|
||||
# concurrent invocations using a bound
|
||||
# number of atoms
|
||||
for N in $(seq 1 $MAXCONNID); do
|
||||
CTL_CONN="ejabberdctl-$N"
|
||||
CTL_LOCKFILE="$CONNLOCKDIR/$CTL_CONN"
|
||||
(
|
||||
exec 8>"$CTL_LOCKFILE"
|
||||
if flock --nb 8; then
|
||||
ctlexec $CTL_CONN $COMMAND
|
||||
ssresult=$?
|
||||
# segregate from possible flock exit(1)
|
||||
ssresult=$(expr $ssresult \* 10)
|
||||
exit $ssresult
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
ssresult=$(expr $ssresult \* 10)
|
||||
exit $ssresult
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
result=$?
|
||||
if [ $result -eq 1 ]; then
|
||||
result=$?
|
||||
if [ $result -eq 1 ] ; then
|
||||
# means we errored out in flock
|
||||
# rather than in the exec - stay in the loop
|
||||
# trying other conn names...
|
||||
badlock=1
|
||||
else
|
||||
badlock=""
|
||||
break;
|
||||
fi
|
||||
done
|
||||
result=$(expr $result / 10)
|
||||
badlock=1
|
||||
else
|
||||
badlock=""
|
||||
break;
|
||||
fi
|
||||
done
|
||||
result=$(expr $result / 10)
|
||||
fi
|
||||
|
||||
if [ "$badlock" ];then
|
||||
echo "Ran out of connections to try. Your ejabberd processes" >&2
|
||||
echo "may be stuck or this is a very busy server. For very" >&2
|
||||
echo "busy servers, consider raising MAXCONNID in ejabberdctl">&2
|
||||
exit 1;
|
||||
if [ "$badlock" ] ;then
|
||||
echo "Ran out of connections to try. Your ejabberd processes" >&2
|
||||
echo "may be stuck or this is a very busy server. For very" >&2
|
||||
echo "busy servers, consider raising MAXCONNID in ejabberdctl">&2
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
case $result in
|
||||
0) :;;
|
||||
1) :;;
|
||||
2) help;;
|
||||
3) help;;
|
||||
0) :;;
|
||||
1) :;;
|
||||
2) help;;
|
||||
3) help;;
|
||||
esac
|
||||
return $result
|
||||
}
|
||||
@@ -337,6 +355,26 @@ stop_epmd()
|
||||
epmd -names | grep -q name || epmd -kill
|
||||
}
|
||||
|
||||
# make sure node not already running and node name unregistered
|
||||
check_start()
|
||||
{
|
||||
epmd -names | grep -q $NODE && {
|
||||
ps ux | grep -v grep | grep -q $ERLANG_NODE && {
|
||||
echo "ERROR: The ejabberd node '$ERLANG_NODE' is already running."
|
||||
exit 4
|
||||
} || {
|
||||
ps ux | grep beam | grep -v "grep beam" && {
|
||||
echo "ERROR: The ejabberd node '$ERLANG_NODE' is registered,"
|
||||
echo " but no ejabberd process has been found."
|
||||
echo "Shutdown other erlang nodes, and call 'epmd -kill'."
|
||||
exit 5
|
||||
} || {
|
||||
epmd -kill
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# allow sync calls
|
||||
wait_for_status()
|
||||
{
|
||||
@@ -344,7 +382,7 @@ wait_for_status()
|
||||
# return: 0 OK, 1 KO
|
||||
timeout=$2
|
||||
status=4
|
||||
while [ $status -ne $1 ]; do
|
||||
while [ $status -ne $1 ] ; do
|
||||
sleep $3
|
||||
timeout=$(($timeout - 1))
|
||||
[ $timeout -eq 0 ] && {
|
||||
@@ -366,6 +404,7 @@ case $ARGS in
|
||||
' start') start;;
|
||||
' debug') debug;;
|
||||
' live') live;;
|
||||
' etop') etop;;
|
||||
' started') wait_for_status 0 30 2;; # wait 30x2s before timeout
|
||||
' stopped') wait_for_status 3 15 2; stop_epmd;; # wait 15x2s before timeout
|
||||
*) ctl $ARGS;;
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -19,18 +19,27 @@
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(adhoc_request, {lang,
|
||||
node,
|
||||
sessionid,
|
||||
action,
|
||||
xdata,
|
||||
others}).
|
||||
-record(adhoc_request,
|
||||
{
|
||||
lang = <<"">> :: binary(),
|
||||
node = <<"">> :: binary(),
|
||||
sessionid = <<"">> :: binary(),
|
||||
action = <<"">> :: binary(),
|
||||
xdata = false :: false | xmlel(),
|
||||
others = [] :: [xmlel()]
|
||||
}).
|
||||
|
||||
-record(adhoc_response, {lang,
|
||||
node,
|
||||
sessionid,
|
||||
status,
|
||||
defaultaction = "",
|
||||
actions = [],
|
||||
notes = [],
|
||||
elements = []}).
|
||||
-record(adhoc_response,
|
||||
{
|
||||
lang = <<"">> :: binary(),
|
||||
node = <<"">> :: binary(),
|
||||
sessionid = <<"">> :: binary(),
|
||||
status :: atom(),
|
||||
defaultaction = <<"">> :: binary(),
|
||||
actions = [] :: [binary()],
|
||||
notes = [] :: [{binary(), binary()}],
|
||||
elements = [] :: [xmlel()]
|
||||
}).
|
||||
|
||||
-type adhoc_request() :: #adhoc_request{}.
|
||||
-type adhoc_response() :: #adhoc_response{}.
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -19,15 +19,34 @@
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(roster, {usj,
|
||||
us,
|
||||
jid,
|
||||
name = "",
|
||||
subscription = none,
|
||||
ask = none,
|
||||
groups = [],
|
||||
askmessage = [],
|
||||
xs = []}).
|
||||
-define(CT_XML,
|
||||
{<<"Content-Type">>, <<"text/xml; charset=utf-8">>}).
|
||||
|
||||
-record(roster_version, {us,
|
||||
version}).
|
||||
-define(CT_PLAIN,
|
||||
{<<"Content-Type">>, <<"text/plain">>}).
|
||||
|
||||
-define(CT_JSON,
|
||||
{<<"Content-Type">>, <<"application/json">>}).
|
||||
|
||||
-define(AC_ALLOW_ORIGIN,
|
||||
{<<"Access-Control-Allow-Origin">>, <<"*">>}).
|
||||
|
||||
-define(AC_ALLOW_METHODS,
|
||||
{<<"Access-Control-Allow-Methods">>,
|
||||
<<"GET, POST, OPTIONS">>}).
|
||||
|
||||
-define(AC_ALLOW_HEADERS,
|
||||
{<<"Access-Control-Allow-Headers">>,
|
||||
<<"Content-Type">>}).
|
||||
|
||||
-define(AC_MAX_AGE,
|
||||
{<<"Access-Control-Max-Age">>, <<"86400">>}).
|
||||
|
||||
-define(OPTIONS_HEADER,
|
||||
[?CT_PLAIN, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_METHODS,
|
||||
?AC_ALLOW_HEADERS, ?AC_MAX_AGE]).
|
||||
|
||||
-define(HEADER(CType),
|
||||
[CType, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_HEADERS]).
|
||||
|
||||
-define(PROCNAME, ejabberd_mod_bosh).
|
||||
@@ -0,0 +1,61 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(VERSION, ejabberd_config:get_version()).
|
||||
|
||||
-define(MYHOSTS, ejabberd_config:get_myhosts()).
|
||||
|
||||
-define(MYNAME, hd(ejabberd_config:get_myhosts())).
|
||||
|
||||
-define(MYLANG, ejabberd_config:get_mylang()).
|
||||
|
||||
-define(MSGS_DIR, filename:join(["priv", "msgs"])).
|
||||
|
||||
-define(CONFIG_PATH, <<"ejabberd.cfg">>).
|
||||
|
||||
-define(LOG_PATH, <<"ejabberd.log">>).
|
||||
|
||||
-ifdef(ENABLE_FLASH_HACK).
|
||||
|
||||
-define(FLASH_HACK, true).
|
||||
|
||||
-else.
|
||||
|
||||
-define(FLASH_HACK, false).
|
||||
|
||||
-endif.
|
||||
|
||||
-define(EJABBERD_URI,
|
||||
<<"http://www.process-one.net/en/ejabberd/">>).
|
||||
|
||||
-define(S2STIMEOUT, 600000).
|
||||
|
||||
%%-define(DBGFSM, true).
|
||||
|
||||
-record(scram,
|
||||
{storedkey = <<"">>,
|
||||
serverkey = <<"">>,
|
||||
salt = <<"">>,
|
||||
iterationcount = 0 :: integer()}).
|
||||
|
||||
-type scram() :: #scram{}.
|
||||
|
||||
-define(SCRAM_DEFAULT_ITERATION_COUNT, 4096).
|
||||
@@ -0,0 +1,93 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-ifndef(mod_privacy_hrl).
|
||||
|
||||
-include("mod_privacy.hrl").
|
||||
|
||||
-endif.
|
||||
|
||||
%-define(SETS, gb_sets).
|
||||
-define(SETS, ejabberd_sets).
|
||||
|
||||
-define(DICT, dict).
|
||||
|
||||
-record(state,
|
||||
{socket,
|
||||
sockmod = ejabberd_socket :: ejabberd_socket | ejabberd_frontend_socket,
|
||||
socket_monitor = make_ref() :: reference(),
|
||||
xml_socket = false :: boolean(),
|
||||
streamid = <<"">> :: binary(),
|
||||
sasl_state :: any(),
|
||||
access :: atom(),
|
||||
shaper = none :: shaper:shaper(),
|
||||
zlib = false :: boolean(),
|
||||
tls = false :: boolean(),
|
||||
tls_required = false :: boolean(),
|
||||
tls_enabled = false :: boolean(),
|
||||
tls_options = [] :: list(),
|
||||
authenticated = false :: boolean() | replaced | rebinded,
|
||||
jid = #jid{} :: jid(),
|
||||
user = <<"">> :: binary(),
|
||||
server = ?MYNAME :: binary(),
|
||||
resource = <<"">> :: binary(),
|
||||
sid = {now(), self()} :: ejabberd_sm:sid(),
|
||||
pres_t = (?SETS):new() :: ?SETS:ej_set() | {pres_t, non_neg_integer()},
|
||||
pres_f = (?SETS):new() :: ?SETS:ej_set() | {pres_f, non_neg_integer()},
|
||||
pres_a = (?SETS):new() :: ?SETS:ej_set() | {pres_a, non_neg_integer()},
|
||||
pres_last :: xmlel(),
|
||||
pres_timestamp :: calendar:datetime(),
|
||||
privacy_list = #userlist{} :: userlist(),
|
||||
conn = unknown :: atom(),
|
||||
auth_module = unknown :: atom(),
|
||||
ip :: {inet:ip_address(), inet:port_number()},
|
||||
redirect = false :: boolean(),
|
||||
aux_fields = [] :: [{atom(), any()}],
|
||||
fsm_limit_opts = [] :: [{atom(), any()}],
|
||||
lang = ?MYLANG :: binary(),
|
||||
debug = false :: boolean(),
|
||||
flash_hack = false :: boolean(),
|
||||
flash_connection = false :: boolean(),
|
||||
reception = true :: boolean(),
|
||||
standby = false :: boolean(),
|
||||
queue = queue:new() :: queue(),
|
||||
queue_len = 0 :: integer(),
|
||||
pres_queue = gb_trees:empty() :: gb_tree(),
|
||||
keepalive_timer :: reference(),
|
||||
keepalive_timeout :: timeout(),
|
||||
oor_timeout :: timeout(),
|
||||
oor_status = <<"">> :: binary(),
|
||||
oor_show = <<"">> :: binary(),
|
||||
oor_notification :: xmlel(),
|
||||
oor_send_body = all :: first_per_user | first | all | none,
|
||||
oor_send_groupchat = false :: boolean(),
|
||||
oor_send_from = jid :: jid | username | name | none,
|
||||
oor_appid = <<"">> :: binary(),
|
||||
oor_unread = 0 :: integer(),
|
||||
oor_unread_users = (?SETS):new() :: ?SETS:ej_set(),
|
||||
oor_unread_client = 0 :: integer(),
|
||||
oor_offline = false :: boolean(),
|
||||
ack_enabled = false :: boolean(),
|
||||
ack_counter = 0 :: integer(),
|
||||
ack_queue = queue:new() :: queue(),
|
||||
ack_timer :: reference()}).
|
||||
|
||||
-type c2s_state() :: #state{}.
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -19,10 +19,40 @@
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(ejabberd_commands, {name, tags = [],
|
||||
desc = "", longdesc = "",
|
||||
module, function,
|
||||
args = [], result = rescode}).
|
||||
-type aterm() :: {atom(), atype()}.
|
||||
-type atype() :: integer | string | binary |
|
||||
{tuple, [aterm()]} | {list, aterm()}.
|
||||
-type rterm() :: {atom(), rtype()}.
|
||||
-type rtype() :: integer | string | atom |
|
||||
{tuple, [rterm()]} | {list, rterm()} |
|
||||
rescode | restuple.
|
||||
|
||||
-record(ejabberd_commands,
|
||||
{name :: atom(),
|
||||
tags = [] :: [atom()] | '_' | '$2',
|
||||
desc = "" :: string() | '_' | '$3',
|
||||
longdesc = "" :: string() | '_',
|
||||
module :: atom(),
|
||||
function :: atom(),
|
||||
args = [] :: [aterm()] | '_' | '$1' | '$2',
|
||||
result = {res, rescode} :: rterm() | '_' | '$2',
|
||||
args_desc = none :: none | [string()],
|
||||
result_desc = none :: none | string(),
|
||||
args_example = none :: [any()],
|
||||
result_example = none :: any()}).
|
||||
|
||||
-type ejabberd_commands() :: #ejabberd_commands{name :: atom(),
|
||||
tags :: [atom()],
|
||||
desc :: string(),
|
||||
longdesc :: string(),
|
||||
module :: atom(),
|
||||
function :: atom(),
|
||||
args :: [aterm()],
|
||||
result :: rterm(),
|
||||
args_desc :: none | [string()],
|
||||
result_desc :: none | string(),
|
||||
args_example :: [any()],
|
||||
result_example :: any()}.
|
||||
|
||||
%% @type ejabberd_commands() = #ejabberd_commands{
|
||||
%% name = atom(),
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -19,21 +19,16 @@
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(LDAP_PORT, 389).
|
||||
-define(LDAPS_PORT, 636).
|
||||
-record(config, {key :: any(), value :: any()}).
|
||||
|
||||
-record(eldap_search, {scope = wholeSubtree,
|
||||
base = [],
|
||||
filter,
|
||||
limit = 0,
|
||||
attributes = [],
|
||||
types_only = false,
|
||||
deref_aliases = neverDerefAliases,
|
||||
timeout = 0}).
|
||||
-record(local_config, {key :: any(), value :: any()}).
|
||||
|
||||
-type config() :: #config{}.
|
||||
-type local_config() :: #local_config{}.
|
||||
|
||||
-record(eldap_search_result, {entries,
|
||||
referrals}).
|
||||
|
||||
-record(eldap_entry, {object_name,
|
||||
attributes}).
|
||||
-record(state,
|
||||
{opts = [] :: [acl:acl() | config() | local_config()],
|
||||
hosts = [] :: [binary()],
|
||||
override_local = false :: boolean(),
|
||||
override_global = false :: boolean(),
|
||||
override_acls = false :: boolean()}).
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -20,6 +20,9 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(STATUS_SUCCESS, 0).
|
||||
-define(STATUS_ERROR, 1).
|
||||
-define(STATUS_USAGE, 2).
|
||||
-define(STATUS_BADRPC, 3).
|
||||
|
||||
-define(STATUS_ERROR, 1).
|
||||
|
||||
-define(STATUS_USAGE, 2).
|
||||
|
||||
-define(STATUS_BADRPC, 3).
|
||||
@@ -0,0 +1,55 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(request,
|
||||
{method :: method(),
|
||||
path = [] :: [binary()],
|
||||
q = [] :: [{binary() | nokey, binary()}],
|
||||
us = {<<>>, <<>>} :: {binary(), binary()},
|
||||
auth :: {binary(), binary()} |
|
||||
{auth_jid, {binary(), binary()}, jlib:jid()},
|
||||
lang = <<"">> :: binary(),
|
||||
data = <<"">> :: binary(),
|
||||
ip :: {inet:ip_address(), inet:port_number()},
|
||||
host = <<"">> :: binary(),
|
||||
port = 5280 :: inet:port_number(),
|
||||
tp = http :: protocol(),
|
||||
headers = [] :: [{atom() | binary(), binary()}]}).
|
||||
|
||||
-record(ws,
|
||||
{socket :: inet:socket() | tls:tls_socket(),
|
||||
sockmod = gen_tcp :: gen_tcp | tls,
|
||||
ws_autoexit = false :: boolean(),
|
||||
ip :: {inet:ip_address(), inet:port_number()},
|
||||
vsn :: vsn(),
|
||||
origin = <<"">> :: binary(),
|
||||
host = <<"">> :: binary(),
|
||||
port = 5280 :: inet:port_number(),
|
||||
path = [] :: [binary()],
|
||||
headers = [] :: [{atom() | binary(), binary()}],
|
||||
local_path = [] :: [binary()],
|
||||
q = [] :: [{binary() | nokey, binary()}],
|
||||
buf :: binary()}).
|
||||
|
||||
-type method() :: 'GET' | 'HEAD' | 'DELETE' | 'OPTIONS' | 'PUT' | 'POST' | 'TRACE'.
|
||||
-type protocol() :: http | https.
|
||||
-type http_request() :: #request{}.
|
||||
-type vsn() :: {'draft-hybi' | 'draft-hixie', non_neg_integer()}.
|
||||
@@ -0,0 +1,102 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(X(Name),
|
||||
#xmlel{name = Name, attrs = [], children = []}).
|
||||
|
||||
-define(XA(Name, Attrs),
|
||||
#xmlel{name = Name, attrs = Attrs, children = []}).
|
||||
|
||||
-define(XE(Name, Els),
|
||||
#xmlel{name = Name, attrs = [], children = Els}).
|
||||
|
||||
-define(XAE(Name, Attrs, Els),
|
||||
#xmlel{name = Name, attrs = Attrs, children = Els}).
|
||||
|
||||
-define(C(Text), {xmlcdata, Text}).
|
||||
|
||||
-define(XC(Name, Text), ?XE(Name, [?C(Text)])).
|
||||
|
||||
-define(XAC(Name, Attrs, Text),
|
||||
?XAE(Name, Attrs, [?C(Text)])).
|
||||
|
||||
-define(T(Text), translate:translate(Lang, Text)).
|
||||
|
||||
-define(CT(Text), ?C((?T(Text)))).
|
||||
|
||||
-define(XCT(Name, Text), ?XC(Name, (?T(Text)))).
|
||||
|
||||
-define(XACT(Name, Attrs, Text),
|
||||
?XAC(Name, Attrs, (?T(Text)))).
|
||||
|
||||
-define(LI(Els), ?XE(<<"li">>, Els)).
|
||||
|
||||
-define(A(URL, Els),
|
||||
?XAE(<<"a">>, [{<<"href">>, URL}], Els)).
|
||||
|
||||
-define(AC(URL, Text), ?A(URL, [?C(Text)])).
|
||||
|
||||
-define(ACT(URL, Text), ?AC(URL, (?T(Text)))).
|
||||
|
||||
-define(P, ?X(<<"p">>)).
|
||||
|
||||
-define(BR, ?X(<<"br">>)).
|
||||
|
||||
-define(INPUT(Type, Name, Value),
|
||||
?XA(<<"input">>,
|
||||
[{<<"type">>, Type}, {<<"name">>, Name},
|
||||
{<<"value">>, Value}])).
|
||||
|
||||
-define(INPUTT(Type, Name, Value),
|
||||
?INPUT(Type, Name, (?T(Value)))).
|
||||
|
||||
-define(INPUTS(Type, Name, Value, Size),
|
||||
?XA(<<"input">>,
|
||||
[{<<"type">>, Type}, {<<"name">>, Name},
|
||||
{<<"value">>, Value}, {<<"size">>, Size}])).
|
||||
|
||||
-define(INPUTST(Type, Name, Value, Size),
|
||||
?INPUT(Type, Name, (?T(Value)), Size)).
|
||||
|
||||
-define(ACLINPUT(Text),
|
||||
?XE(<<"td">>,
|
||||
[?INPUT(<<"text">>, <<"value", ID/binary>>, Text)])).
|
||||
|
||||
-define(TEXTAREA(Name, Rows, Cols, Value),
|
||||
?XAC(<<"textarea">>,
|
||||
[{<<"name">>, Name}, {<<"rows">>, Rows},
|
||||
{<<"cols">>, Cols}],
|
||||
Value)).
|
||||
|
||||
-define(XRES(Text),
|
||||
?XAC(<<"p">>, [{<<"class">>, <<"result">>}], Text)).
|
||||
|
||||
-define(XREST(Text), ?XRES((?T(Text)))).
|
||||
|
||||
-define(GL(Ref, Title),
|
||||
?XAE(<<"div">>, [{<<"class">>, <<"guidelink">>}],
|
||||
[?XAE(<<"a">>,
|
||||
[{<<"href">>, <<"/admin/doc/guide.html#", Ref/binary>>},
|
||||
{<<"target">>, <<"_blank">>}],
|
||||
[?C(<<"[Guide: ", Title/binary, "]">>)])])).
|
||||
|
||||
-define(H1GL(Name, Ref, Title),
|
||||
[?XC(<<"h1">>, Name), ?GL(Ref, Title)]).
|
||||
@@ -0,0 +1,65 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(LDAP_PORT, 389).
|
||||
|
||||
-define(LDAPS_PORT, 636).
|
||||
|
||||
-type scope() :: baseObject | singleLevel | wholeSubtree.
|
||||
|
||||
-record(eldap_search,
|
||||
{scope = wholeSubtree :: scope(),
|
||||
base = <<"">> :: binary(),
|
||||
filter :: eldap:filter(),
|
||||
limit = 0 :: non_neg_integer(),
|
||||
attributes = [] :: [binary()],
|
||||
types_only = false :: boolean(),
|
||||
deref_aliases = neverDerefAliases :: neverDerefAliases |
|
||||
derefInSearching |
|
||||
derefFindingBaseObj |
|
||||
derefAlways,
|
||||
timeout = 0 :: non_neg_integer()}).
|
||||
|
||||
-record(eldap_search_result, {entries = [] :: [eldap_entry()],
|
||||
referrals = [] :: list()}).
|
||||
|
||||
-record(eldap_entry, {object_name = <<>> :: binary(),
|
||||
attributes = [] :: [{binary(), [binary()]}]}).
|
||||
|
||||
-type tlsopts() :: [{encrypt, tls | starttls | none} |
|
||||
{tls_cacertfile, binary() | undefined} |
|
||||
{tls_certfile, binary() | undefined} |
|
||||
{tls_depth, non_neg_integer() | undefined} |
|
||||
{tls_verify, hard | soft | false}].
|
||||
|
||||
-record(eldap_config, {servers = [] :: [binary()],
|
||||
backups = [] :: [binary()],
|
||||
tls_options = [] :: tlsopts(),
|
||||
port = ?LDAP_PORT :: inet:port_number(),
|
||||
dn = <<"">> :: binary(),
|
||||
password = <<"">> :: binary(),
|
||||
base = <<"">> :: binary(),
|
||||
deref_aliases = never :: never | searching |
|
||||
finding | always}).
|
||||
|
||||
-type eldap_config() :: #eldap_config{}.
|
||||
-type eldap_search() :: #eldap_search{}.
|
||||
-type eldap_entry() :: #eldap_entry{}.
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -19,14 +19,29 @@
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(CT_XML, {"Content-Type", "text/xml; charset=utf-8"}).
|
||||
-define(CT_PLAIN, {"Content-Type", "text/plain"}).
|
||||
-define(CT_XML,
|
||||
{<<"Content-Type">>, <<"text/xml; charset=utf-8">>}).
|
||||
|
||||
-define(AC_ALLOW_ORIGIN, {"Access-Control-Allow-Origin", "*"}).
|
||||
-define(AC_ALLOW_METHODS, {"Access-Control-Allow-Methods", "GET, POST, OPTIONS"}).
|
||||
-define(AC_ALLOW_HEADERS, {"Access-Control-Allow-Headers", "Content-Type"}).
|
||||
-define(AC_MAX_AGE, {"Access-Control-Max-Age", "86400"}).
|
||||
-define(CT_PLAIN,
|
||||
{<<"Content-Type">>, <<"text/plain">>}).
|
||||
|
||||
-define(OPTIONS_HEADER, [?CT_PLAIN, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_METHODS,
|
||||
?AC_ALLOW_HEADERS, ?AC_MAX_AGE]).
|
||||
-define(HEADER, [?CT_XML, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_HEADERS]).
|
||||
-define(AC_ALLOW_ORIGIN,
|
||||
{<<"Access-Control-Allow-Origin">>, <<"*">>}).
|
||||
|
||||
-define(AC_ALLOW_METHODS,
|
||||
{<<"Access-Control-Allow-Methods">>,
|
||||
<<"GET, POST, OPTIONS">>}).
|
||||
|
||||
-define(AC_ALLOW_HEADERS,
|
||||
{<<"Access-Control-Allow-Headers">>,
|
||||
<<"Content-Type">>}).
|
||||
|
||||
-define(AC_MAX_AGE,
|
||||
{<<"Access-Control-Max-Age">>, <<"86400">>}).
|
||||
|
||||
-define(OPTIONS_HEADER,
|
||||
[?CT_PLAIN, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_METHODS,
|
||||
?AC_ALLOW_HEADERS, ?AC_MAX_AGE]).
|
||||
|
||||
-define(HEADER,
|
||||
[?CT_XML, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_HEADERS]).
|
||||
@@ -0,0 +1,701 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
|
||||
-define(NS_DISCO_ITEMS,
|
||||
<<"http://jabber.org/protocol/disco#items">>).
|
||||
|
||||
-define(NS_DISCO_INFO,
|
||||
<<"http://jabber.org/protocol/disco#info">>).
|
||||
|
||||
-define(NS_VCARD, <<"vcard-temp">>).
|
||||
|
||||
-define(NS_VCARD_UPDATE, <<"vcard-temp:x:update">>).
|
||||
|
||||
-define(NS_AUTH, <<"jabber:iq:auth">>).
|
||||
|
||||
-define(NS_AUTH_ERROR, <<"jabber:iq:auth:error">>).
|
||||
|
||||
-define(NS_REGISTER, <<"jabber:iq:register">>).
|
||||
|
||||
-define(NS_SEARCH, <<"jabber:iq:search">>).
|
||||
|
||||
-define(NS_ROSTER, <<"jabber:iq:roster">>).
|
||||
|
||||
-define(NS_ROSTER_VER,
|
||||
<<"urn:xmpp:features:rosterver">>).
|
||||
|
||||
-define(NS_PRIVACY, <<"jabber:iq:privacy">>).
|
||||
|
||||
-define(NS_BLOCKING, <<"urn:xmpp:blocking">>).
|
||||
|
||||
-define(NS_PRIVATE, <<"jabber:iq:private">>).
|
||||
|
||||
-define(NS_VERSION, <<"jabber:iq:version">>).
|
||||
|
||||
-define(NS_TIME90, <<"jabber:iq:time">>).
|
||||
|
||||
-define(NS_TIME, <<"urn:xmpp:time">>).
|
||||
|
||||
-define(NS_LAST, <<"jabber:iq:last">>).
|
||||
|
||||
-define(NS_XDATA, <<"jabber:x:data">>).
|
||||
|
||||
-define(NS_IQDATA, <<"jabber:iq:data">>).
|
||||
|
||||
-define(NS_DELAY91, <<"jabber:x:delay">>).
|
||||
|
||||
-define(NS_DELAY, <<"urn:xmpp:delay">>).
|
||||
|
||||
-define(NS_EXPIRE, <<"jabber:x:expire">>).
|
||||
|
||||
-define(NS_EVENT, <<"jabber:x:event">>).
|
||||
|
||||
-define(NS_CHATSTATES,
|
||||
<<"http://jabber.org/protocol/chatstates">>).
|
||||
|
||||
-define(NS_XCONFERENCE, <<"jabber:x:conference">>).
|
||||
|
||||
-define(NS_STATS,
|
||||
<<"http://jabber.org/protocol/stats">>).
|
||||
|
||||
-define(NS_MUC, <<"http://jabber.org/protocol/muc">>).
|
||||
|
||||
-define(NS_MUC_USER,
|
||||
<<"http://jabber.org/protocol/muc#user">>).
|
||||
|
||||
-define(NS_MUC_ADMIN,
|
||||
<<"http://jabber.org/protocol/muc#admin">>).
|
||||
|
||||
-define(NS_MUC_OWNER,
|
||||
<<"http://jabber.org/protocol/muc#owner">>).
|
||||
|
||||
-define(NS_MUC_UNIQUE,
|
||||
<<"http://jabber.org/protocol/muc#unique">>).
|
||||
|
||||
-define(NS_PUBSUB,
|
||||
<<"http://jabber.org/protocol/pubsub">>).
|
||||
|
||||
-define(NS_PUBSUB_EVENT,
|
||||
<<"http://jabber.org/protocol/pubsub#event">>).
|
||||
|
||||
-define(NS_PUBSUB_META_DATA,
|
||||
<<"http://jabber.org/protocol/pubsub#meta-data">>).
|
||||
|
||||
-define(NS_PUBSUB_OWNER,
|
||||
<<"http://jabber.org/protocol/pubsub#owner">>).
|
||||
|
||||
-define(NS_PUBSUB_NMI,
|
||||
<<"http://jabber.org/protocol/pubsub#node-meta-info">>).
|
||||
|
||||
-define(NS_PUBSUB_ERRORS,
|
||||
<<"http://jabber.org/protocol/pubsub#errors">>).
|
||||
|
||||
-define(NS_PUBSUB_NODE_CONFIG,
|
||||
<<"http://jabber.org/protocol/pubsub#node_config">>).
|
||||
|
||||
-define(NS_PUBSUB_SUB_OPTIONS,
|
||||
<<"http://jabber.org/protocol/pubsub#subscribe_options">>).
|
||||
|
||||
-define(NS_PUBSUB_SUBSCRIBE_OPTIONS,
|
||||
<<"http://jabber.org/protocol/pubsub#subscribe_options">>).
|
||||
|
||||
-define(NS_PUBSUB_PUBLISH_OPTIONS,
|
||||
<<"http://jabber.org/protocol/pubsub#publish_options">>).
|
||||
|
||||
-define(NS_PUBSUB_SUB_AUTH,
|
||||
<<"http://jabber.org/protocol/pubsub#subscribe_authorization">>).
|
||||
|
||||
-define(NS_PUBSUB_GET_PENDING,
|
||||
<<"http://jabber.org/protocol/pubsub#get-pending">>).
|
||||
|
||||
-define(NS_COMMANDS,
|
||||
<<"http://jabber.org/protocol/commands">>).
|
||||
|
||||
-define(NS_BYTESTREAMS,
|
||||
<<"http://jabber.org/protocol/bytestreams">>).
|
||||
|
||||
-define(NS_ADMIN,
|
||||
<<"http://jabber.org/protocol/admin">>).
|
||||
-define(NS_ADMIN_ANNOUNCE,
|
||||
<<"http://jabber.org/protocol/admin#announce">>).
|
||||
-define(NS_ADMIN_ANNOUNCE_ALL,
|
||||
<<"http://jabber.org/protocol/admin#announce-all">>).
|
||||
-define(NS_ADMIN_SET_MOTD,
|
||||
<<"http://jabber.org/protocol/admin#set-motd">>).
|
||||
-define(NS_ADMIN_EDIT_MOTD,
|
||||
<<"http://jabber.org/protocol/admin#edit-motd">>).
|
||||
-define(NS_ADMIN_DELETE_MOTD,
|
||||
<<"http://jabber.org/protocol/admin#delete-motd">>).
|
||||
-define(NS_ADMIN_ANNOUNCE_ALLHOSTS,
|
||||
<<"http://jabber.org/protocol/admin#announce-allhosts">>).
|
||||
-define(NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS,
|
||||
<<"http://jabber.org/protocol/admin#announce-all-allhosts">>).
|
||||
-define(NS_ADMIN_SET_MOTD_ALLHOSTS,
|
||||
<<"http://jabber.org/protocol/admin#set-motd-allhosts">>).
|
||||
-define(NS_ADMIN_EDIT_MOTD_ALLHOSTS,
|
||||
<<"http://jabber.org/protocol/admin#edit-motd-allhosts">>).
|
||||
-define(NS_ADMIN_DELETE_MOTD_ALLHOSTS,
|
||||
<<"http://jabber.org/protocol/admin#delete-motd-allhosts">>).
|
||||
|
||||
-define(NS_SERVERINFO,
|
||||
<<"http://jabber.org/network/serverinfo">>).
|
||||
|
||||
-define(NS_RSM, <<"http://jabber.org/protocol/rsm">>).
|
||||
|
||||
-define(NS_EJABBERD_CONFIG, <<"ejabberd:config">>).
|
||||
|
||||
-define(NS_STREAM,
|
||||
<<"http://etherx.jabber.org/streams">>).
|
||||
|
||||
-define(NS_FLASH_STREAM,
|
||||
<<"http://www.jabber.com/streams/flash">>).
|
||||
|
||||
-define(NS_STANZAS,
|
||||
<<"urn:ietf:params:xml:ns:xmpp-stanzas">>).
|
||||
|
||||
-define(NS_STREAMS,
|
||||
<<"urn:ietf:params:xml:ns:xmpp-streams">>).
|
||||
|
||||
-define(NS_TLS, <<"urn:ietf:params:xml:ns:xmpp-tls">>).
|
||||
|
||||
-define(NS_SASL,
|
||||
<<"urn:ietf:params:xml:ns:xmpp-sasl">>).
|
||||
|
||||
-define(NS_SESSION,
|
||||
<<"urn:ietf:params:xml:ns:xmpp-session">>).
|
||||
|
||||
-define(NS_BIND,
|
||||
<<"urn:ietf:params:xml:ns:xmpp-bind">>).
|
||||
|
||||
-define(NS_FEATURE_IQAUTH,
|
||||
<<"http://jabber.org/features/iq-auth">>).
|
||||
|
||||
-define(NS_FEATURE_IQREGISTER,
|
||||
<<"http://jabber.org/features/iq-register">>).
|
||||
|
||||
-define(NS_FEATURE_COMPRESS,
|
||||
<<"http://jabber.org/features/compress">>).
|
||||
|
||||
-define(NS_FEATURE_MSGOFFLINE, <<"msgoffline">>).
|
||||
|
||||
-define(NS_COMPRESS,
|
||||
<<"http://jabber.org/protocol/compress">>).
|
||||
|
||||
-define(NS_CAPS, <<"http://jabber.org/protocol/caps">>).
|
||||
|
||||
-define(NS_SHIM, <<"http://jabber.org/protocol/shim">>).
|
||||
|
||||
-define(NS_ADDRESS,
|
||||
<<"http://jabber.org/protocol/address">>).
|
||||
|
||||
-define(NS_OOB, <<"jabber:x:oob">>).
|
||||
|
||||
-define(NS_CAPTCHA, <<"urn:xmpp:captcha">>).
|
||||
|
||||
-define(NS_MEDIA, <<"urn:xmpp:media-element">>).
|
||||
|
||||
-define(NS_BOB, <<"urn:xmpp:bob">>).
|
||||
|
||||
-include("xml.hrl").
|
||||
|
||||
-define(STANZA_ERROR(Code, Type, Condition),
|
||||
#xmlel{name = <<"error">>,
|
||||
attrs = [{<<"code">>, Code}, {<<"type">>, Type}],
|
||||
children =
|
||||
[#xmlel{name = Condition,
|
||||
attrs = [{<<"xmlns">>, ?NS_STANZAS}],
|
||||
children = []}]}).
|
||||
|
||||
-define(ERR_BAD_FORMAT,
|
||||
?STANZA_ERROR(<<"406">>, <<"modify">>,
|
||||
<<"bad-format">>)).
|
||||
|
||||
-define(ERR_BAD_REQUEST,
|
||||
?STANZA_ERROR(<<"400">>, <<"modify">>,
|
||||
<<"bad-request">>)).
|
||||
|
||||
-define(ERR_CONFLICT,
|
||||
?STANZA_ERROR(<<"409">>, <<"cancel">>, <<"conflict">>)).
|
||||
|
||||
-define(ERR_FEATURE_NOT_IMPLEMENTED,
|
||||
?STANZA_ERROR(<<"501">>, <<"cancel">>,
|
||||
<<"feature-not-implemented">>)).
|
||||
|
||||
-define(ERR_FORBIDDEN,
|
||||
?STANZA_ERROR(<<"403">>, <<"auth">>, <<"forbidden">>)).
|
||||
|
||||
-define(ERR_GONE,
|
||||
?STANZA_ERROR(<<"302">>, <<"modify">>, <<"gone">>)).
|
||||
|
||||
-define(ERR_INTERNAL_SERVER_ERROR,
|
||||
?STANZA_ERROR(<<"500">>, <<"wait">>,
|
||||
<<"internal-server-error">>)).
|
||||
|
||||
-define(ERR_ITEM_NOT_FOUND,
|
||||
?STANZA_ERROR(<<"404">>, <<"cancel">>,
|
||||
<<"item-not-found">>)).
|
||||
|
||||
-define(ERR_JID_MALFORMED,
|
||||
?STANZA_ERROR(<<"400">>, <<"modify">>,
|
||||
<<"jid-malformed">>)).
|
||||
|
||||
-define(ERR_NOT_ACCEPTABLE,
|
||||
?STANZA_ERROR(<<"406">>, <<"modify">>,
|
||||
<<"not-acceptable">>)).
|
||||
|
||||
-define(ERR_NOT_ALLOWED,
|
||||
?STANZA_ERROR(<<"405">>, <<"cancel">>,
|
||||
<<"not-allowed">>)).
|
||||
|
||||
-define(ERR_NOT_AUTHORIZED,
|
||||
?STANZA_ERROR(<<"401">>, <<"auth">>,
|
||||
<<"not-authorized">>)).
|
||||
|
||||
-define(ERR_PAYMENT_REQUIRED,
|
||||
?STANZA_ERROR(<<"402">>, <<"auth">>,
|
||||
<<"payment-required">>)).
|
||||
|
||||
-define(ERR_POLICY_VIOLATION,
|
||||
?STANZA_ERROR(<<"405">>, <<"cancel">>,
|
||||
<<"policy-violation">>)).
|
||||
|
||||
-define(ERR_RECIPIENT_UNAVAILABLE,
|
||||
?STANZA_ERROR(<<"404">>, <<"wait">>,
|
||||
<<"recipient-unavailable">>)).
|
||||
|
||||
-define(ERR_REDIRECT,
|
||||
?STANZA_ERROR(<<"302">>, <<"modify">>, <<"redirect">>)).
|
||||
|
||||
-define(ERR_REGISTRATION_REQUIRED,
|
||||
?STANZA_ERROR(<<"407">>, <<"auth">>,
|
||||
<<"registration-required">>)).
|
||||
|
||||
-define(ERR_REMOTE_SERVER_NOT_FOUND,
|
||||
?STANZA_ERROR(<<"404">>, <<"cancel">>,
|
||||
<<"remote-server-not-found">>)).
|
||||
|
||||
-define(ERR_REMOTE_SERVER_TIMEOUT,
|
||||
?STANZA_ERROR(<<"504">>, <<"wait">>,
|
||||
<<"remote-server-timeout">>)).
|
||||
|
||||
-define(ERR_RESOURCE_CONSTRAINT,
|
||||
?STANZA_ERROR(<<"500">>, <<"wait">>,
|
||||
<<"resource-constraint">>)).
|
||||
|
||||
-define(ERR_SERVICE_UNAVAILABLE,
|
||||
?STANZA_ERROR(<<"503">>, <<"cancel">>,
|
||||
<<"service-unavailable">>)).
|
||||
|
||||
-define(ERR_SUBSCRIPTION_REQUIRED,
|
||||
?STANZA_ERROR(<<"407">>, <<"auth">>,
|
||||
<<"subscription-required">>)).
|
||||
|
||||
-define(ERR_UNEXPECTED_REQUEST,
|
||||
?STANZA_ERROR(<<"400">>, <<"wait">>,
|
||||
<<"unexpected-request">>)).
|
||||
|
||||
-define(ERR_UNEXPECTED_REQUEST_CANCEL,
|
||||
?STANZA_ERROR(<<"401">>, <<"cancel">>,
|
||||
<<"unexpected-request">>)).
|
||||
|
||||
%-define(ERR_,
|
||||
% ?STANZA_ERROR("", "", "")).
|
||||
|
||||
-define(STANZA_ERRORT(Code, Type, Condition, Lang,
|
||||
Text),
|
||||
#xmlel{name = <<"error">>,
|
||||
attrs = [{<<"code">>, Code}, {<<"type">>, Type}],
|
||||
children =
|
||||
[#xmlel{name = Condition,
|
||||
attrs = [{<<"xmlns">>, ?NS_STANZAS}], children = []},
|
||||
#xmlel{name = <<"text">>,
|
||||
attrs = [{<<"xmlns">>, ?NS_STANZAS}],
|
||||
children =
|
||||
[{xmlcdata,
|
||||
translate:translate(Lang, Text)}]}]}).
|
||||
|
||||
-define(ERRT_BAD_FORMAT(Lang, Text),
|
||||
?STANZA_ERRORT(<<"406">>, <<"modify">>,
|
||||
<<"bad-format">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_BAD_REQUEST(Lang, Text),
|
||||
?STANZA_ERRORT(<<"400">>, <<"modify">>,
|
||||
<<"bad-request">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_CONFLICT(Lang, Text),
|
||||
?STANZA_ERRORT(<<"409">>, <<"cancel">>, <<"conflict">>,
|
||||
Lang, Text)).
|
||||
|
||||
-define(ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Text),
|
||||
?STANZA_ERRORT(<<"501">>, <<"cancel">>,
|
||||
<<"feature-not-implemented">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_FORBIDDEN(Lang, Text),
|
||||
?STANZA_ERRORT(<<"403">>, <<"auth">>, <<"forbidden">>,
|
||||
Lang, Text)).
|
||||
|
||||
-define(ERRT_GONE(Lang, Text),
|
||||
?STANZA_ERRORT(<<"302">>, <<"modify">>, <<"gone">>,
|
||||
Lang, Text)).
|
||||
|
||||
-define(ERRT_INTERNAL_SERVER_ERROR(Lang, Text),
|
||||
?STANZA_ERRORT(<<"500">>, <<"wait">>,
|
||||
<<"internal-server-error">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_ITEM_NOT_FOUND(Lang, Text),
|
||||
?STANZA_ERRORT(<<"404">>, <<"cancel">>,
|
||||
<<"item-not-found">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_JID_MALFORMED(Lang, Text),
|
||||
?STANZA_ERRORT(<<"400">>, <<"modify">>,
|
||||
<<"jid-malformed">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_NOT_ACCEPTABLE(Lang, Text),
|
||||
?STANZA_ERRORT(<<"406">>, <<"modify">>,
|
||||
<<"not-acceptable">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_NOT_ALLOWED(Lang, Text),
|
||||
?STANZA_ERRORT(<<"405">>, <<"cancel">>,
|
||||
<<"not-allowed">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_NOT_AUTHORIZED(Lang, Text),
|
||||
?STANZA_ERRORT(<<"401">>, <<"auth">>,
|
||||
<<"not-authorized">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_PAYMENT_REQUIRED(Lang, Text),
|
||||
?STANZA_ERRORT(<<"402">>, <<"auth">>,
|
||||
<<"payment-required">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_RECIPIENT_UNAVAILABLE(Lang, Text),
|
||||
?STANZA_ERRORT(<<"404">>, <<"wait">>,
|
||||
<<"recipient-unavailable">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_REDIRECT(Lang, Text),
|
||||
?STANZA_ERRORT(<<"302">>, <<"modify">>, <<"redirect">>,
|
||||
Lang, Text)).
|
||||
|
||||
-define(ERRT_REGISTRATION_REQUIRED(Lang, Text),
|
||||
?STANZA_ERRORT(<<"407">>, <<"auth">>,
|
||||
<<"registration-required">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_REMOTE_SERVER_NOT_FOUND(Lang, Text),
|
||||
?STANZA_ERRORT(<<"404">>, <<"cancel">>,
|
||||
<<"remote-server-not-found">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_REMOTE_SERVER_TIMEOUT(Lang, Text),
|
||||
?STANZA_ERRORT(<<"504">>, <<"wait">>,
|
||||
<<"remote-server-timeout">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_RESOURCE_CONSTRAINT(Lang, Text),
|
||||
?STANZA_ERRORT(<<"500">>, <<"wait">>,
|
||||
<<"resource-constraint">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_SERVICE_UNAVAILABLE(Lang, Text),
|
||||
?STANZA_ERRORT(<<"503">>, <<"cancel">>,
|
||||
<<"service-unavailable">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_SUBSCRIPTION_REQUIRED(Lang, Text),
|
||||
?STANZA_ERRORT(<<"407">>, <<"auth">>,
|
||||
<<"subscription-required">>, Lang, Text)).
|
||||
|
||||
-define(ERRT_UNEXPECTED_REQUEST(Lang, Text),
|
||||
?STANZA_ERRORT(<<"400">>, <<"wait">>,
|
||||
<<"unexpected-request">>, Lang, Text)).
|
||||
|
||||
-define(ERR_AUTH_NO_RESOURCE_PROVIDED(Lang),
|
||||
?ERRT_NOT_ACCEPTABLE(Lang, <<"No resource provided">>)).
|
||||
|
||||
-define(ERR_AUTH_BAD_RESOURCE_FORMAT(Lang),
|
||||
?ERRT_NOT_ACCEPTABLE(Lang,
|
||||
<<"Illegal resource format">>)).
|
||||
|
||||
-define(ERR_AUTH_RESOURCE_CONFLICT(Lang),
|
||||
?ERRT_CONFLICT(Lang, <<"Resource conflict">>)).
|
||||
|
||||
-define(STREAM_ERROR(Condition, Cdata),
|
||||
#xmlel{name = <<"stream:error">>, attrs = [],
|
||||
children =
|
||||
[#xmlel{name = Condition,
|
||||
attrs = [{<<"xmlns">>, ?NS_STREAMS}],
|
||||
children = [{xmlcdata, Cdata}]}]}).
|
||||
|
||||
-define(SERR_BAD_FORMAT,
|
||||
?STREAM_ERROR(<<"bad-format">>, <<"">>)).
|
||||
|
||||
-define(SERR_BAD_NAMESPACE_PREFIX,
|
||||
?STREAM_ERROR(<<"bad-namespace-prefix">>, <<"">>)).
|
||||
|
||||
-define(SERR_CONFLICT,
|
||||
?STREAM_ERROR(<<"conflict">>, <<"">>)).
|
||||
|
||||
-define(SERR_CONNECTION_TIMEOUT,
|
||||
?STREAM_ERROR(<<"connection-timeout">>, <<"">>)).
|
||||
|
||||
-define(SERR_HOST_GONE,
|
||||
?STREAM_ERROR(<<"host-gone">>, <<"">>)).
|
||||
|
||||
-define(SERR_HOST_UNKNOWN,
|
||||
?STREAM_ERROR(<<"host-unknown">>, <<"">>)).
|
||||
|
||||
-define(SERR_IMPROPER_ADDRESSING,
|
||||
?STREAM_ERROR(<<"improper-addressing">>, <<"">>)).
|
||||
|
||||
-define(SERR_INTERNAL_SERVER_ERROR,
|
||||
?STREAM_ERROR(<<"internal-server-error">>, <<"">>)).
|
||||
|
||||
-define(SERR_INVALID_FROM,
|
||||
?STREAM_ERROR(<<"invalid-from">>, <<"">>)).
|
||||
|
||||
-define(SERR_INVALID_ID,
|
||||
?STREAM_ERROR(<<"invalid-id">>, <<"">>)).
|
||||
|
||||
-define(SERR_INVALID_NAMESPACE,
|
||||
?STREAM_ERROR(<<"invalid-namespace">>, <<"">>)).
|
||||
|
||||
-define(SERR_INVALID_XML,
|
||||
?STREAM_ERROR(<<"invalid-xml">>, <<"">>)).
|
||||
|
||||
-define(SERR_NOT_AUTHORIZED,
|
||||
?STREAM_ERROR(<<"not-authorized">>, <<"">>)).
|
||||
|
||||
-define(SERR_POLICY_VIOLATION,
|
||||
?STREAM_ERROR(<<"policy-violation">>, <<"">>)).
|
||||
|
||||
-define(SERR_REMOTE_CONNECTION_FAILED,
|
||||
?STREAM_ERROR(<<"remote-connection-failed">>, <<"">>)).
|
||||
|
||||
-define(SERR_RESOURSE_CONSTRAINT,
|
||||
?STREAM_ERROR(<<"resource-constraint">>, <<"">>)).
|
||||
|
||||
-define(SERR_RESTRICTED_XML,
|
||||
?STREAM_ERROR(<<"restricted-xml">>, <<"">>)).
|
||||
|
||||
-define(SERR_SEE_OTHER_HOST(Host),
|
||||
?STREAM_ERROR(<<"see-other-host">>, Host)).
|
||||
|
||||
-define(SERR_SYSTEM_SHUTDOWN,
|
||||
?STREAM_ERROR(<<"system-shutdown">>, <<"">>)).
|
||||
|
||||
-define(SERR_UNSUPPORTED_ENCODING,
|
||||
?STREAM_ERROR(<<"unsupported-encoding">>, <<"">>)).
|
||||
|
||||
-define(SERR_UNSUPPORTED_STANZA_TYPE,
|
||||
?STREAM_ERROR(<<"unsupported-stanza-type">>, <<"">>)).
|
||||
|
||||
-define(SERR_UNSUPPORTED_VERSION,
|
||||
?STREAM_ERROR(<<"unsupported-version">>, <<"">>)).
|
||||
|
||||
-define(SERR_XML_NOT_WELL_FORMED,
|
||||
?STREAM_ERROR(<<"xml-not-well-formed">>, <<"">>)).
|
||||
|
||||
%-define(SERR_,
|
||||
% ?STREAM_ERROR("", "")).
|
||||
|
||||
-define(STREAM_ERRORT(Condition, Cdata, Lang, Text),
|
||||
#xmlel{name = <<"stream:error">>, attrs = [],
|
||||
children =
|
||||
[#xmlel{name = Condition,
|
||||
attrs = [{<<"xmlns">>, ?NS_STREAMS}],
|
||||
children = [{xmlcdata, Cdata}]},
|
||||
#xmlel{name = <<"text">>,
|
||||
attrs =
|
||||
[{<<"xml:lang">>, Lang},
|
||||
{<<"xmlns">>, ?NS_STREAMS}],
|
||||
children =
|
||||
[{xmlcdata,
|
||||
translate:translate(Lang, Text)}]}]}).
|
||||
|
||||
-define(SERRT_BAD_FORMAT(Lang, Text),
|
||||
?STREAM_ERRORT(<<"bad-format">>, <<"">>, Lang, Text)).
|
||||
|
||||
-define(SERRT_BAD_NAMESPACE_PREFIX(Lang, Text),
|
||||
?STREAM_ERRORT(<<"bad-namespace-prefix">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-define(SERRT_CONFLICT(Lang, Text),
|
||||
?STREAM_ERRORT(<<"conflict">>, <<"">>, Lang, Text)).
|
||||
|
||||
-define(SERRT_CONNECTION_TIMEOUT(Lang, Text),
|
||||
?STREAM_ERRORT(<<"connection-timeout">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-define(SERRT_HOST_GONE(Lang, Text),
|
||||
?STREAM_ERRORT(<<"host-gone">>, <<"">>, Lang, Text)).
|
||||
|
||||
-define(SERRT_HOST_UNKNOWN(Lang, Text),
|
||||
?STREAM_ERRORT(<<"host-unknown">>, <<"">>, Lang, Text)).
|
||||
|
||||
-define(SERRT_IMPROPER_ADDRESSING(Lang, Text),
|
||||
?STREAM_ERRORT(<<"improper-addressing">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-define(SERRT_INTERNAL_SERVER_ERROR(Lang, Text),
|
||||
?STREAM_ERRORT(<<"internal-server-error">>, <<"">>,
|
||||
Lang, Text)).
|
||||
|
||||
-define(SERRT_INVALID_FROM(Lang, Text),
|
||||
?STREAM_ERRORT(<<"invalid-from">>, <<"">>, Lang, Text)).
|
||||
|
||||
-define(SERRT_INVALID_ID(Lang, Text),
|
||||
?STREAM_ERRORT(<<"invalid-id">>, <<"">>, Lang, Text)).
|
||||
|
||||
-define(SERRT_INVALID_NAMESPACE(Lang, Text),
|
||||
?STREAM_ERRORT(<<"invalid-namespace">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-define(SERRT_INVALID_XML(Lang, Text),
|
||||
?STREAM_ERRORT(<<"invalid-xml">>, <<"">>, Lang, Text)).
|
||||
|
||||
-define(SERRT_NOT_AUTHORIZED(Lang, Text),
|
||||
?STREAM_ERRORT(<<"not-authorized">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-define(SERRT_POLICY_VIOLATION(Lang, Text),
|
||||
?STREAM_ERRORT(<<"policy-violation">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-define(SERRT_REMOTE_CONNECTION_FAILED(Lang, Text),
|
||||
?STREAM_ERRORT(<<"remote-connection-failed">>, <<"">>,
|
||||
Lang, Text)).
|
||||
|
||||
-define(SERRT_RESOURSE_CONSTRAINT(Lang, Text),
|
||||
?STREAM_ERRORT(<<"resource-constraint">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-define(SERRT_RESTRICTED_XML(Lang, Text),
|
||||
?STREAM_ERRORT(<<"restricted-xml">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-define(SERRT_SEE_OTHER_HOST(Host, Lang, Text),
|
||||
?STREAM_ERRORT(<<"see-other-host">>, Host, Lang, Text)).
|
||||
|
||||
-define(SERRT_SYSTEM_SHUTDOWN(Lang, Text),
|
||||
?STREAM_ERRORT(<<"system-shutdown">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-define(SERRT_UNSUPPORTED_ENCODING(Lang, Text),
|
||||
?STREAM_ERRORT(<<"unsupported-encoding">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-define(SERRT_UNSUPPORTED_STANZA_TYPE(Lang, Text),
|
||||
?STREAM_ERRORT(<<"unsupported-stanza-type">>, <<"">>,
|
||||
Lang, Text)).
|
||||
|
||||
-define(SERRT_UNSUPPORTED_VERSION(Lang, Text),
|
||||
?STREAM_ERRORT(<<"unsupported-version">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-define(SERRT_XML_NOT_WELL_FORMED(Lang, Text),
|
||||
?STREAM_ERRORT(<<"xml-not-well-formed">>, <<"">>, Lang,
|
||||
Text)).
|
||||
|
||||
-record(jid, {user = <<"">> :: binary(),
|
||||
server = <<"">> :: binary(),
|
||||
resource = <<"">> :: binary(),
|
||||
luser = <<"">> :: binary(),
|
||||
lserver = <<"">> :: binary(),
|
||||
lresource = <<"">> :: binary()}).
|
||||
|
||||
-type(jid() :: #jid{}).
|
||||
|
||||
-type(ljid() :: {binary(), binary(), binary()}).
|
||||
|
||||
-record(iq, {id = <<"">> :: binary(),
|
||||
type = get :: get | set | result | error,
|
||||
xmlns = <<"">> :: binary(),
|
||||
lang = <<"">> :: binary(),
|
||||
sub_el = #xmlel{} :: xmlel() | [xmlel()]}).
|
||||
|
||||
-type(iq_get()
|
||||
:: #iq{
|
||||
id :: binary(),
|
||||
type :: get,
|
||||
xmlns :: binary(),
|
||||
lang :: binary(),
|
||||
sub_el :: xmlel()
|
||||
}
|
||||
).
|
||||
|
||||
-type(iq_set()
|
||||
:: #iq{
|
||||
id :: binary(),
|
||||
type :: set,
|
||||
xmlns :: binary(),
|
||||
lang :: binary(),
|
||||
sub_el :: xmlel()
|
||||
}
|
||||
).
|
||||
|
||||
-type iq_request() :: iq_get() | iq_set().
|
||||
|
||||
-type(iq_result()
|
||||
:: #iq{
|
||||
id :: binary(),
|
||||
type :: result,
|
||||
xmlns :: binary(),
|
||||
lang :: binary(),
|
||||
sub_el :: [xmlel()]
|
||||
}
|
||||
).
|
||||
|
||||
-type(iq_error()
|
||||
:: #iq{
|
||||
id :: binary(),
|
||||
type :: error,
|
||||
xmlns :: binary(),
|
||||
lang :: binary(),
|
||||
sub_el :: [xmlel()]
|
||||
}
|
||||
).
|
||||
|
||||
-type iq_reply() :: iq_result() | iq_error() .
|
||||
|
||||
-type(iq() :: iq_request() | iq_reply()).
|
||||
|
||||
-record(rsm_in, {max :: integer(),
|
||||
direction :: before | aft,
|
||||
id :: binary(),
|
||||
index :: integer()}).
|
||||
|
||||
-record(rsm_out, {count :: integer(),
|
||||
index :: integer(),
|
||||
first :: binary(),
|
||||
last :: binary()}).
|
||||
|
||||
-type(rsm_in() :: #rsm_in{}).
|
||||
|
||||
-type(rsm_out() :: #rsm_out{}).
|
||||
|
||||
-type broadcast() :: {broadcast, broadcast_data()}.
|
||||
|
||||
-type broadcast_data() ::
|
||||
{rebind, pid(), binary()} | %% ejabberd_c2s
|
||||
{item, ljid(), mod_roster:subscription()} | %% mod_roster/mod_shared_roster
|
||||
{exit, binary()} | %% mod_roster/mod_shared_roster
|
||||
{privacy_list, mod_privacy:userlist(), binary()} | %% mod_privacy
|
||||
{blocking, unblock_all | {block | unblock, [ljid()]}}. %% mod_blocking
|
||||
|
||||
-record(xmlelement, {name = "" :: string(),
|
||||
attrs = [] :: [{string(), string()}],
|
||||
children = [] :: [{xmlcdata, iodata()} | xmlelement()]}).
|
||||
|
||||
-type xmlelement() :: #xmlelement{}.
|
||||
@@ -0,0 +1 @@
|
||||
-define(IS_VALID, true).
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -18,20 +18,19 @@
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
-define(PRINT(Format, Args), io:format(Format, Args)).
|
||||
|
||||
-record(privacy, {us,
|
||||
default = none,
|
||||
lists = []}).
|
||||
-define(DEBUG(Format, Args),
|
||||
ejabberd_logger:debug_msg(?MODULE, ?LINE, Format, Args)).
|
||||
|
||||
-record(listitem, {type = none,
|
||||
value = none,
|
||||
action,
|
||||
order,
|
||||
match_all = false,
|
||||
match_iq = false,
|
||||
match_message = false,
|
||||
match_presence_in = false,
|
||||
match_presence_out = false
|
||||
}).
|
||||
-define(INFO_MSG(Format, Args),
|
||||
ejabberd_logger:info_msg(?MODULE, ?LINE, Format, Args)).
|
||||
|
||||
-record(userlist, {name = none, list = [], needdb = false }).
|
||||
-define(WARNING_MSG(Format, Args),
|
||||
ejabberd_logger:warning_msg(?MODULE, ?LINE, Format, Args)).
|
||||
|
||||
-define(ERROR_MSG(Format, Args),
|
||||
ejabberd_logger:error_msg(?MODULE, ?LINE, Format, Args)).
|
||||
|
||||
-define(CRITICAL_MSG(Format, Args),
|
||||
ejabberd_logger:critical_msg(?MODULE, ?LINE, Format, Args)).
|
||||
@@ -0,0 +1,117 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(MAX_USERS_DEFAULT, 200).
|
||||
|
||||
-define(SETS, gb_sets).
|
||||
|
||||
-define(DICT, dict).
|
||||
|
||||
-record(lqueue,
|
||||
{
|
||||
queue :: queue(),
|
||||
len :: integer(),
|
||||
max :: integer()
|
||||
}).
|
||||
|
||||
-type lqueue() :: #lqueue{}.
|
||||
|
||||
-record(config,
|
||||
{
|
||||
title = <<"">> :: binary(),
|
||||
description = <<"">> :: binary(),
|
||||
allow_change_subj = true :: boolean(),
|
||||
allow_query_users = true :: boolean(),
|
||||
allow_private_messages = true :: boolean(),
|
||||
allow_private_messages_from_visitors = anyone :: anyone | moderators | nobody ,
|
||||
allow_visitor_status = true :: boolean(),
|
||||
allow_visitor_nickchange = true :: boolean(),
|
||||
public = true :: boolean(),
|
||||
public_list = true :: boolean(),
|
||||
persistent = false :: boolean(),
|
||||
moderated = true :: boolean(),
|
||||
captcha_protected = false :: boolean(),
|
||||
members_by_default = true :: boolean(),
|
||||
members_only = false :: boolean(),
|
||||
allow_user_invites = false :: boolean(),
|
||||
password_protected = false :: boolean(),
|
||||
password = <<"">> :: binary(),
|
||||
anonymous = true :: boolean(),
|
||||
allow_voice_requests = true :: boolean(),
|
||||
voice_request_min_interval = 1800 :: non_neg_integer(),
|
||||
max_users = ?MAX_USERS_DEFAULT :: non_neg_integer() | none,
|
||||
logging = false :: boolean(),
|
||||
captcha_whitelist = (?SETS):empty() :: gb_set()
|
||||
}).
|
||||
|
||||
-type config() :: #config{}.
|
||||
|
||||
-type role() :: moderator | participant | visitor | none.
|
||||
|
||||
-record(user,
|
||||
{
|
||||
jid :: jid(),
|
||||
nick :: binary(),
|
||||
role :: role(),
|
||||
last_presence :: xmlel()
|
||||
}).
|
||||
|
||||
-record(activity,
|
||||
{
|
||||
message_time = 0 :: integer(),
|
||||
presence_time = 0 :: integer(),
|
||||
message_shaper :: shaper:shaper(),
|
||||
presence_shaper :: shaper:shaper(),
|
||||
message :: xmlel(),
|
||||
presence :: {binary(), xmlel()}
|
||||
}).
|
||||
|
||||
-record(state,
|
||||
{
|
||||
room = <<"">> :: binary(),
|
||||
host = <<"">> :: binary(),
|
||||
server_host = <<"">> :: binary(),
|
||||
access = {none,none,none,none} :: {atom(), atom(), atom(), atom()},
|
||||
jid = #jid{} :: jid(),
|
||||
config = #config{} :: config(),
|
||||
users = (?DICT):new() :: dict(),
|
||||
last_voice_request_time = treap:empty() :: treap:treap(),
|
||||
robots = (?DICT):new() :: dict(),
|
||||
nicks = (?DICT):new() :: dict(),
|
||||
affiliations = (?DICT):new() :: dict(),
|
||||
history :: lqueue(),
|
||||
persist_history = false :: boolean(),
|
||||
subject = <<"">> :: binary(),
|
||||
subject_author = <<"">> :: binary(),
|
||||
just_created = false :: boolean(),
|
||||
activity = treap:empty() :: treap:treap(),
|
||||
room_shaper = none :: shaper:shaper(),
|
||||
room_queue = queue:new() :: queue()
|
||||
}).
|
||||
|
||||
-record(muc_online_users, {us = {<<>>, <<>>} :: {binary(), binary()},
|
||||
resource = <<>> :: binary() | '_',
|
||||
room = <<>> :: binary() | '_',
|
||||
host = <<>> :: binary() | '_'}).
|
||||
|
||||
-type muc_online_users() :: #muc_online_users{}.
|
||||
|
||||
-type muc_room_state() :: #state{}.
|
||||
@@ -0,0 +1,46 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(mod_privacy_hrl, true).
|
||||
|
||||
-record(privacy, {us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
default = none :: none | binary(),
|
||||
lists = [] :: [{binary(), [listitem()]}]}).
|
||||
|
||||
-record(listitem, {type = none :: none | jid | group | subscription,
|
||||
value = none :: none | both | from | to | ljid() | binary(),
|
||||
action = allow :: allow | deny,
|
||||
order = 0 :: integer(),
|
||||
match_all = false :: boolean(),
|
||||
match_iq = false :: boolean(),
|
||||
match_message = false :: boolean(),
|
||||
match_presence_in = false :: boolean(),
|
||||
match_presence_out = false :: boolean()}).
|
||||
|
||||
-type listitem() :: #listitem{}.
|
||||
|
||||
-record(userlist, {name = none :: none | binary(),
|
||||
list = [] :: [listitem()],
|
||||
needdb = false :: boolean()}).
|
||||
|
||||
-type userlist() :: #userlist{}.
|
||||
|
||||
-export_type([userlist/0]).
|
||||
@@ -2,7 +2,7 @@
|
||||
%%% RFC 1928 constants.
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -21,41 +21,48 @@
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
%% Version
|
||||
-define(VERSION_5, 5).
|
||||
|
||||
%% Authentication methods
|
||||
-define(AUTH_ANONYMOUS, 0).
|
||||
-define(AUTH_GSSAPI, 1).
|
||||
-define(AUTH_PLAIN, 2).
|
||||
-define(AUTH_NO_METHODS, 16#FF).
|
||||
|
||||
%% Address Type
|
||||
-define(AUTH_GSSAPI, 1).
|
||||
|
||||
-define(AUTH_PLAIN, 2).
|
||||
|
||||
-define(AUTH_NO_METHODS, 255).
|
||||
|
||||
-define(ATYP_IPV4, 1).
|
||||
|
||||
-define(ATYP_DOMAINNAME, 3).
|
||||
|
||||
-define(ATYP_IPV6, 4).
|
||||
|
||||
%% Commands
|
||||
-define(CMD_CONNECT, 1).
|
||||
|
||||
-define(CMD_BIND, 2).
|
||||
|
||||
-define(CMD_UDP, 3).
|
||||
|
||||
%% RFC 1928 replies
|
||||
-define(SUCCESS, 0).
|
||||
|
||||
-define(ERR_GENERAL_FAILURE, 1).
|
||||
|
||||
-define(ERR_NOT_ALLOWED, 2).
|
||||
|
||||
-define(ERR_NETWORK_UNREACHABLE, 3).
|
||||
|
||||
-define(ERR_HOST_UNREACHABLE, 4).
|
||||
|
||||
-define(ERR_CONNECTION_REFUSED, 5).
|
||||
|
||||
-define(ERR_TTL_EXPIRED, 6).
|
||||
|
||||
-define(ERR_COMMAND_NOT_SUPPORTED, 7).
|
||||
|
||||
-define(ERR_ADDRESS_TYPE_NOT_SUPPORTED, 8).
|
||||
|
||||
%% RFC 1928 defined timeout.
|
||||
-define(SOCKS5_REPLY_TIMEOUT, 10000).
|
||||
|
||||
-record(s5_request, {
|
||||
rsv = 0,
|
||||
cmd,
|
||||
sha1
|
||||
}).
|
||||
-record(s5_request, {rsv = 0 :: integer(),
|
||||
cmd = connect :: connect | udp,
|
||||
sha1 = <<"">> :: binary()}).
|
||||
@@ -0,0 +1,42 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(roster,
|
||||
{
|
||||
usj = {<<>>, <<>>, {<<>>, <<>>, <<>>}} :: {binary(), binary(), ljid()} | '_',
|
||||
us = {<<>>, <<>>} :: {binary(), binary()} | '_',
|
||||
jid = {<<>>, <<>>, <<>>} :: ljid(),
|
||||
name = <<>> :: binary() | '_',
|
||||
subscription = none :: subscription() | '_',
|
||||
ask = none :: ask() | '_',
|
||||
groups = [] :: [binary()] | '_',
|
||||
askmessage = <<"">> :: binary() | '_',
|
||||
xs = [] :: [xmlel()] | '_'
|
||||
}).
|
||||
|
||||
-record(roster_version,
|
||||
{
|
||||
us = {<<>>, <<>>} :: {binary(), binary()},
|
||||
version = <<>> :: binary()
|
||||
}).
|
||||
|
||||
-type ask() :: none | in | out | both | subscribe | unsubscribe.
|
||||
-type subscription() :: none | both | from | to | remove.
|
||||
@@ -0,0 +1,207 @@
|
||||
%%% ====================================================================
|
||||
%%% ``The contents of this file are subject to the Erlang Public License,
|
||||
%%% Version 1.1, (the "License"); you may not use this file except in
|
||||
%%% compliance with the License. You should have received a copy of the
|
||||
%%% Erlang Public License along with this software. If not, it can be
|
||||
%%% retrieved via the world wide web at http://www.erlang.org/.
|
||||
%%%
|
||||
%%% Software distributed under the License is distributed on an "AS IS"
|
||||
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%%% the License for the specific language governing rights and limitations
|
||||
%%% under the License.
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2013, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2013, ProcessOne.
|
||||
%%%
|
||||
%%%
|
||||
%%% copyright 2006-2013 ProcessOne
|
||||
%%%
|
||||
%%% This file contains pubsub types definition.
|
||||
%%% ====================================================================
|
||||
|
||||
-define(ERR_EXTENDED(E, C),
|
||||
mod_pubsub:extended_error(E, C)).
|
||||
|
||||
-define(MAXITEMS, 10).
|
||||
|
||||
-define(MAX_PAYLOAD_SIZE, 60000).
|
||||
|
||||
%% -------------------------------
|
||||
%% Pubsub types
|
||||
|
||||
-type(hostPubsub() :: binary()).
|
||||
%% <p><tt>hostPubsub</tt> is the name of the PubSub service. For example, it can be
|
||||
%% <tt>"pubsub.localhost"</tt>.</p>
|
||||
|
||||
-type(hostPEP() :: {binary(), binary(), <<>>}).
|
||||
%% @type hostPEP() = {User, Server, Resource}
|
||||
%% User = string()
|
||||
%% Server = string()
|
||||
%% Resource = [].
|
||||
%% <p>For example, it can be :
|
||||
%% ```{"bob", "example.org", []}'''.</p>
|
||||
|
||||
-type(host() :: hostPubsub() | hostPEP()).
|
||||
%% @type host() = hostPubsub() | hostPEP().
|
||||
|
||||
-type(nodeId() :: binary()).
|
||||
%% @type nodeId() = binary().
|
||||
%% <p>A node is defined by a list of its ancestors. The last element is the name
|
||||
%% of the current node. For example:
|
||||
%% ```<<"/home/localhost/user">>'''</p>
|
||||
|
||||
-type(nodeIdx() :: pos_integer()).
|
||||
%% @type nodeIdx() = integer().
|
||||
|
||||
-type(itemId() :: binary()).
|
||||
%% @type itemId() = string().
|
||||
|
||||
-type(subId() :: binary()).
|
||||
%% @type subId() = string().
|
||||
|
||||
|
||||
%% @type payload() = [#xmlelement{} | #xmlcdata{}].
|
||||
|
||||
%% @type stanzaError() = #xmlelement{}.
|
||||
%% Example:
|
||||
%% ```{xmlelement, "error",
|
||||
%% [{"code", Code}, {"type", Type}],
|
||||
%% [{xmlelement, Condition, [{"xmlns", ?NS_STANZAS}], []}]}'''
|
||||
%% @type pubsubIQResponse() = #xmlelement{}.
|
||||
%% Example:
|
||||
%% ```{xmlelement, "pubsub",
|
||||
%% [{"xmlns", ?NS_PUBSUB_EVENT}],
|
||||
%% [{xmlelement, "affiliations", [],
|
||||
%% []}]}'''
|
||||
|
||||
-type(nodeOption() ::
|
||||
{Option::atom(),
|
||||
Value::binary() | [binary()] | boolean() | non_neg_integer()
|
||||
}).
|
||||
|
||||
-type(nodeOptions() :: [NodeOption::mod_pubsub:nodeOption(),...]).
|
||||
|
||||
%% @type nodeOption() = {Option, Value}
|
||||
%% Option = atom()
|
||||
%% Value = term().
|
||||
%% Example:
|
||||
%% ```{deliver_payloads, true}'''
|
||||
|
||||
-type(subOption() ::
|
||||
{Option::atom(),
|
||||
Value::binary() | [binary()] | boolean()
|
||||
}).
|
||||
|
||||
-type(subOptions() :: [SubOption::mod_pubsub:subOption(),...]).
|
||||
|
||||
%% @type nodeType() = string().
|
||||
%% <p>The <tt>nodeType</tt> is a string containing the name of the PubSub
|
||||
%% plugin to use to manage a given node. For example, it can be
|
||||
%% <tt>"flat"</tt>, <tt>"hometree"</tt> or <tt>"blog"</tt>.</p>
|
||||
|
||||
%% @type jid() = {jid, User, Server, Resource, LUser, LServer, LResource}
|
||||
%% User = string()
|
||||
%% Server = string()
|
||||
%% Resource = string()
|
||||
%% LUser = string()
|
||||
%% LServer = string()
|
||||
%% LResource = string().
|
||||
|
||||
%-type(ljid() :: {binary(), binary(), binary()}).
|
||||
%% @type ljid() = {User, Server, Resource}
|
||||
%% User = string()
|
||||
%% Server = string()
|
||||
%% Resource = string().
|
||||
|
||||
-type(affiliation() :: 'none'
|
||||
| 'owner'
|
||||
| 'publisher'
|
||||
%| 'publish-only'
|
||||
| 'member'
|
||||
| 'outcast'
|
||||
).
|
||||
%% @type affiliation() = 'none' | 'owner' | 'publisher' | 'publish-only' | 'member' | 'outcast'.
|
||||
|
||||
-type(subscription() :: 'none'
|
||||
| 'pending'
|
||||
| 'unconfigured'
|
||||
| 'subscribed'
|
||||
).
|
||||
%% @type subscription() = 'none' | 'pending' | 'unconfigured' | 'subscribed'.
|
||||
|
||||
-type(accessModel() :: 'open'
|
||||
| 'presence'
|
||||
| 'roster'
|
||||
| 'authorize'
|
||||
| 'whitelist'
|
||||
).
|
||||
%% @type accessModel() = 'open' | 'presence' | 'roster' | 'authorize' | 'whitelist'.
|
||||
|
||||
-type(publishModel() :: 'publishers'
|
||||
| 'subscribers'
|
||||
| 'open'
|
||||
).
|
||||
|
||||
|
||||
-record(pubsub_index,
|
||||
{
|
||||
index :: atom(),
|
||||
last :: mod_pubsub:nodeIdx(),
|
||||
free :: [mod_pubsub:nodeIdx()]
|
||||
}).
|
||||
|
||||
-record(pubsub_node,
|
||||
{
|
||||
nodeid ,%:: {Host::mod_pubsub:host(), NodeId::mod_pubsub:nodeId()},
|
||||
id ,%:: mod_pubsub:nodeIdx(),
|
||||
parents = [] ,%:: [Parent_NodeId::mod_pubsub:nodeId()],
|
||||
type = <<"flat">> ,%:: binary(),
|
||||
owners = [] ,%:: [Owner::ljid(),...],
|
||||
options = [] %:: mod_pubsub:nodeOptions()
|
||||
}).
|
||||
|
||||
|
||||
%-record(pubsub_state,
|
||||
% {stateid, nodeidx, items = [], affiliation = none,
|
||||
% subscriptions = []}).
|
||||
-record(pubsub_state,
|
||||
{
|
||||
stateid ,%:: {Entity::ljid(), NodeIdx::mod_pubsub:nodeIdx()},
|
||||
nodeidx ,%:: mod_pubsub:nodeIdx(),
|
||||
items = [] ,%:: [ItemId::mod_pubsub:itemId()],
|
||||
affiliation = 'none' ,%:: mod_pubsub:affiliation(),
|
||||
subscriptions = [] %:: [{mod_pubsub:subscription(), mod_pubsub:subId()}]
|
||||
}).
|
||||
|
||||
%-record(pubsub_item,
|
||||
% {itemid, nodeidx, creation = {unknown, unknown},
|
||||
% modification = {unknown, unknown}, payload = []}).
|
||||
|
||||
-record(pubsub_item,
|
||||
{
|
||||
itemid ,%:: {mod_pubsub:itemId(), mod_pubsub:nodeIdx()},
|
||||
nodeidx ,%:: mod_pubsub_nodeIdx(),
|
||||
creation = {unknown, unknown} ,%:: {erlang:timestamp(), ljid()},
|
||||
modification = {unknown, unknown} ,%:: {erlang:timestamp(), ljid()},
|
||||
payload = [] %:: mod_pubsub:payload()
|
||||
}).
|
||||
|
||||
%-record(pubsub_subscription, {subid, options}).
|
||||
-record(pubsub_subscription,
|
||||
{
|
||||
subid ,%:: mod_pubsub:subId(),
|
||||
options %:: [] | mod_pubsub:subOptions()
|
||||
}).
|
||||
|
||||
%-record(pubsub_last_item,
|
||||
% {nodeid, itemid, creation, payload}).
|
||||
|
||||
-record(pubsub_last_item,
|
||||
{
|
||||
nodeid ,%:: mod_pubsub:nodeIdx(),
|
||||
itemid ,%:: mod_pubsub:itemId(),
|
||||
creation ,%:: {erlang:timestamp(), ljid()},
|
||||
payload %:: mod_pubsub:payload()
|
||||
}).
|
||||
@@ -0,0 +1,685 @@
|
||||
%%% ====================================================================
|
||||
%%% ``The contents of this file are subject to the Erlang Public License,
|
||||
%%% Version 1.1, (the "License"); you may not use this file except in
|
||||
%%% compliance with the License. You should have received a copy of the
|
||||
%%% Erlang Public License along with this software. If not, it can be
|
||||
%%% retrieved via the world wide web at http://www.erlang.org/.
|
||||
%%%
|
||||
%%% Software distributed under the License is distributed on an "AS IS"
|
||||
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%%% the License for the specific language governing rights and limitations
|
||||
%%% under the License.
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2013, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2013, ProcessOne.
|
||||
%%%
|
||||
%%% @copyright 2006-2013 ProcessOne
|
||||
%%% @author Karim Gemayel <karim.gemayel@process-one.net>
|
||||
%%% [http://www.process-one.net/]
|
||||
%%% @version {@vsn}, {@date} {@time}
|
||||
%%% @end
|
||||
%%% ====================================================================
|
||||
|
||||
%%% @headerfile "pubsub_dev.hrl"
|
||||
|
||||
-module(exmpp_pubsub).
|
||||
-author('karim.gemayel@process-one.net').
|
||||
|
||||
-compile(export_all).
|
||||
|
||||
-include("pubsub_dev.hrl").
|
||||
|
||||
|
||||
%% --------------------------------------------------------------------
|
||||
%% Documentation / type definitions.
|
||||
%% --------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
%-- Affiliations --%
|
||||
-export_type([
|
||||
affiliation/0,
|
||||
%%
|
||||
affiliation_owner/0,
|
||||
affiliation_publisher/0,
|
||||
affiliation_publish_only/0,
|
||||
affiliation_member/0,
|
||||
affiliation_none/0,
|
||||
affiliation_outcast/0
|
||||
]).
|
||||
|
||||
%% @type affiliation_owner() = 'owner'.
|
||||
-type(affiliation_owner() :: 'owner').
|
||||
|
||||
%% @type affiliation_publisher() = 'publisher'.
|
||||
-type(affiliation_publisher() :: 'publisher').
|
||||
|
||||
%% @type affiliation_publish_only() = 'publish-only'.
|
||||
-type(affiliation_publish_only() :: 'publish-only').
|
||||
|
||||
%% @type affiliation_member() = 'member'.
|
||||
-type(affiliation_member() :: 'member').
|
||||
|
||||
%% @type affiliation_none() = 'none'.
|
||||
-type(affiliation_none() :: 'none').
|
||||
|
||||
%% @type affiliation_outcast() = 'outcast'.
|
||||
-type(affiliation_outcast() :: 'outcast').
|
||||
|
||||
%% @type affiliation() = Owner | Publisher | Publish_Only | Member | None | Outcast
|
||||
%% Owner = exmpp_pubsub:affiliation_owner()
|
||||
%% Publisher = exmpp_pubsub:affiliation_publisher()
|
||||
%% Publish_Only = exmpp_pubsub:affiliation_publish_only()
|
||||
%% Member = exmpp_pubsub:affiliation_member()
|
||||
%% None = exmpp_pubsub:affiliation_none()
|
||||
%% Outcast = exmpp_pubsub:affiliation_outcast().
|
||||
-type(affiliation() :: exmpp_pubsub:affiliation_owner()
|
||||
| exmpp_pubsub:affiliation_publisher()
|
||||
| exmpp_pubsub:affiliation_publish_only()
|
||||
| exmpp_pubsub:affiliation_member()
|
||||
| exmpp_pubsub:affiliation_none()
|
||||
| exmpp_pubsub:affiliation_outcast()
|
||||
).
|
||||
|
||||
|
||||
%%
|
||||
|
||||
%-- Things identifiers --%
|
||||
-export_type([
|
||||
index/0,
|
||||
itemId/0,
|
||||
itemIds/0,
|
||||
level/0,
|
||||
nodeId/0,
|
||||
nodeIdx/0,
|
||||
subId/0,
|
||||
plugin/0
|
||||
]).
|
||||
|
||||
%% @type index() = 'node'.
|
||||
-type(index() :: 'node' ).
|
||||
|
||||
%% @type itemId() = binary().
|
||||
-type(itemId() :: binary()).
|
||||
|
||||
%% @type itemIds() = [ItemId::exmpp_pubsub:itemId(),...].
|
||||
-type(itemIds() :: [ItemId::exmpp_pubsub:itemId(),...]).
|
||||
|
||||
%% @type level() = non_neg_integer().
|
||||
-type(level() :: non_neg_integer()).
|
||||
|
||||
%% @type nodeId() = binary().
|
||||
-type(nodeId() :: binary()).
|
||||
|
||||
%% @type nodeIdx() = non_neg_integer().
|
||||
-type(nodeIdx() :: non_neg_integer()).
|
||||
|
||||
%% @type plugin() = module().
|
||||
-type(plugin() :: module()).
|
||||
|
||||
%% @type subId() = binary().
|
||||
-type(subId() :: binary()).
|
||||
|
||||
|
||||
-export_type([
|
||||
t_now/0
|
||||
]).
|
||||
|
||||
%% Temporary -type, until calendar.erl -type is exported
|
||||
-type(t_now()
|
||||
:: {MegaSec::non_neg_integer(),
|
||||
Sec::non_neg_integer(),
|
||||
MilliSec::non_neg_integer()}
|
||||
).
|
||||
|
||||
|
||||
%%
|
||||
-export_type([
|
||||
feature/0,
|
||||
features/0,
|
||||
pubsub_feature/0,
|
||||
pubsub_features/0
|
||||
]).
|
||||
|
||||
-type(feature() :: binary()).
|
||||
|
||||
-type(features() :: Features::[Feature::exmpp_pubsub:feature(),...]).
|
||||
|
||||
-type(pubsub_feature() :: exmpp_pubsub:feature()).
|
||||
|
||||
-type(pubsub_features() :: Pubsub_Features::[Pubsub_Feature::exmpp_pubsub:feature(),...]).
|
||||
|
||||
%%
|
||||
|
||||
%-- Payload types --%
|
||||
-export_type([
|
||||
payload/0,
|
||||
%%
|
||||
payload_empty/0,
|
||||
payload_full/0
|
||||
]).
|
||||
|
||||
%% @type payload_empty() = [].
|
||||
-type(payload_empty() :: []).
|
||||
|
||||
%% @type payload_full() = #xmlel{}.
|
||||
-type(payload_full() :: xmlel()).
|
||||
|
||||
%% @type payload() = Empty_Payload | Full_Payload
|
||||
%% Empty_Payload = exmpp_pubsub:payload_empty()
|
||||
%% Full_Payload = exmpp_pubsub:payload_full().
|
||||
-type(payload() :: exmpp_pubsub:payload_empty()
|
||||
| exmpp_pubsub:payload_full()
|
||||
).
|
||||
|
||||
|
||||
%%
|
||||
|
||||
%-- Pusbub Host --%
|
||||
-export_type([
|
||||
host/0,
|
||||
%%
|
||||
host_pubsub/0,
|
||||
host_pep/0
|
||||
]).
|
||||
|
||||
%% @type host_pubsub() = xmpp_jid:domain_jid().
|
||||
%% ```<<"pubsub.shakespeare.lit">>'''
|
||||
%% Identifier type of the Pubsub service
|
||||
-type(host_pubsub() :: binary()).
|
||||
|
||||
%% @type host_pep() = xmpp_jid:usr_contact_bare().
|
||||
%% ```{<<"juliet">>, <<"capulet.lit">>, undefined}'''
|
||||
%% Identifier type of the Pubsub-On-Jid service
|
||||
-type(host_pep() :: xmpp_jid:usr_contact_bare()).
|
||||
|
||||
%% @type host() = Pubsub_Host | Pubsub_On_Jid_Host
|
||||
%% Pubsub_Host = exmpp_pubsub:host_pubsub()
|
||||
%% Pubsub_On_Jid_Host = exmpp_pubsub:host_pep().
|
||||
%% Identifier types of the Pubsub and PEP (Pubsub-On-Jid) services
|
||||
%% ```* Pubsub_Host : <<"pubsub.shakespeare.lit">>
|
||||
%% * Pubsub_PEP : {<<"juliet">>, <<"capulet.lit">>, undefined}'''
|
||||
-type(host() :: exmpp_pubsub:host_pubsub()
|
||||
| exmpp_pubsub:host_pep()
|
||||
).
|
||||
|
||||
|
||||
%%
|
||||
|
||||
%-- Subscription States --%
|
||||
-export_type([
|
||||
subscription_state/0,
|
||||
%%
|
||||
subscription_state_none/0,
|
||||
subscription_state_pending/0,
|
||||
subscription_state_unconfigured/0,
|
||||
subscription_state_subscribed/0
|
||||
]).
|
||||
|
||||
%% @type subscription_state_none() = 'none'.
|
||||
-type(subscription_state_none() :: 'none').
|
||||
|
||||
%% @type subscription_state_pending() = 'pending'.
|
||||
-type(subscription_state_pending() :: 'pending').
|
||||
|
||||
%% @type subscription_state_unconfigured() = 'unconfigured'.
|
||||
-type(subscription_state_unconfigured() :: 'unconfigured').
|
||||
|
||||
%% @type subscription_state_subscribed() = 'subscribed'.
|
||||
-type(subscription_state_subscribed() :: 'subscribed').
|
||||
|
||||
%% @type subscription_state() = None | Pending | Unconfigured | Subscribed
|
||||
%% None = exmpp_pubsub:subscription_state_none()
|
||||
%% Pending = exmpp_pubsub:subscription_state_pending()
|
||||
%% Unconfigured = exmpp_pubsub:subscription_state_unconfigured()
|
||||
%% Subscribed = exmpp_pubsub:subscription_state_subscribed()
|
||||
-type(subscription_state() :: exmpp_pubsub:subscription_state_pending()
|
||||
| exmpp_pubsub:subscription_state_unconfigured()
|
||||
| exmpp_pubsub:subscription_state_subscribed()
|
||||
).
|
||||
|
||||
%%
|
||||
|
||||
%-- Subscription -- %%
|
||||
-export_type([
|
||||
subscriptions/0,
|
||||
subscription/0,
|
||||
%%
|
||||
subscription_subscribed/0,
|
||||
subscription_unconfigured/0,
|
||||
subscription_pending/0
|
||||
]).
|
||||
|
||||
-type(subscription_subscribed()
|
||||
:: {Subscription_State :: exmpp_pubsub:subscription_state_subscribed(),
|
||||
SubId :: exmpp_pubsub:subId(),
|
||||
Resource :: undefined | xmpp_jid:resource_jid() | {'caps', xmpp_jid:resource_jid()},
|
||||
Subscription_Options :: [] | pubsub_options:options_subscription()}
|
||||
).
|
||||
|
||||
-type(subscription_unconfigured()
|
||||
:: {Subscription_State :: exmpp_pubsub:subscription_state_unconfigured(),
|
||||
SubId :: exmpp_pubsub:subId(),
|
||||
Resource :: undefined | xmpp_jid:resource_jid() | {'caps', xmpp_jid:resource_jid()},
|
||||
Subscription_Options :: []}
|
||||
).
|
||||
|
||||
-type(subscription_pending()
|
||||
:: {Subscription_State :: exmpp_pubsub:subscription_state_pending(),
|
||||
SubId :: exmpp_pubsub:subId(),
|
||||
Resource :: undefined | xmpp_jid:resource_jid() | {'caps', xmpp_jid:resource_jid()},
|
||||
Subscription_Options :: []}
|
||||
).
|
||||
|
||||
%% -type(subscription()
|
||||
%% :: {Subscription_State :: exmpp_pubsub:subscription_state(),
|
||||
%% SubId :: exmpp_pubsub:subId(),
|
||||
%% Resource :: undefined | xmpp_jid:resource_jid() | {'caps', xmpp_jid:resource_jid()},
|
||||
%% Subscription_Options :: [] | pubsub_options:options_subscription()}
|
||||
%% %% :: exmpp_pubsub:subscription_subscribed()
|
||||
%% %% | exmpp_pubsub:subscription_pending()
|
||||
%% %% | exmpp_pubsub:subscription_unconfigured()
|
||||
%% ).
|
||||
|
||||
-type(subscriptions()
|
||||
:: [exmpp_pubsub:subscription(),...]
|
||||
%% :: [exmpp_pubsub:subscription_subscribed(),...]
|
||||
%% | [exmpp_pubsub:subscription_unconfigured(),...]
|
||||
%% | [exmpp_pubsub:subscription_pending(),...]
|
||||
).
|
||||
|
||||
%% TODO : commented -type unions return the following dialyzer error (bug ?) :
|
||||
%% ...
|
||||
%% Adding information from /home/meta/otp-exmpp.plt to ejabberd.plt...
|
||||
%%=ERROR REPORT==== 29-Jul-2011::15:14:42 ===
|
||||
%Error in process <0.2604.0> with exit value: {function_clause,[{erl_types,inf_tuples_in_sets,4},{erl_types,inf_tuple_sets,4},{erl_types,inf_tuple_sets,3},{erl_types,t_inf,3},{erl_types,t_inf_lists_strict,4},{erl_types,t_inf,3},{dialyzer_typesig,solve_one_c...
|
||||
%%
|
||||
%%
|
||||
%%dialyzer: Analysis failed with error: {function_clause,[{erl_types,inf_tuples_in_sets,4},
|
||||
%% {erl_types,inf_tuple_sets,4},
|
||||
%% {erl_types,inf_tuple_sets,3},
|
||||
%% {erl_types,t_inf,3},
|
||||
%% {erl_types,t_inf_lists_strict,4},
|
||||
%% {erl_types,t_inf,3},
|
||||
%% {dialyzer_typesig,solve_one_c,...},
|
||||
%% {dialyzer_typesig,...}]}
|
||||
%%Last messages in the log cache:
|
||||
%% Typesig analysis for SCC: [{ejabberd_web_admin,make_xhtml,5}]
|
||||
%% Typesig analysis for SCC: [{ejabberd_web_admin,make_xhtml,4}]
|
||||
%% Typesig analysis for SCC: [{ejabberd_web_admin,process_admin,2}]
|
||||
%% Typesig analysis for SCC: [{ejabberd_web_admin,process,2}]
|
||||
%% Typesig analysis for SCC: [{mod_stats,get_local_stat,3}]
|
||||
%% Typesig analysis for SCC: [{mod_stats,get_local_stats,3}]
|
||||
%% Typesig analysis for SCC: [{mod_stats,process_local_iq,3}]
|
||||
%% Typesig analysis for SCC: [{mod_register_web,send_registration_notifications,2}]
|
||||
%% Typesig analysis for SCC: [{mod_register_web,process,2}]
|
||||
%% Typesig analysis for SCC: [{pubsub_db,create_node,5}]
|
||||
|
||||
%%
|
||||
|
||||
|
||||
%% Pubsub #xmlel{} templates
|
||||
|
||||
|
||||
%% --------------------------------------------------------------------
|
||||
%% Functions.
|
||||
%% --------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
%% @spec nodeId() -> NodeId::exmpp_pubsub:nodeId()
|
||||
-spec(nodeId/0 :: () -> NodeId::exmpp_pubsub:nodeId()).
|
||||
|
||||
nodeId() ->
|
||||
randoms:get_string().
|
||||
|
||||
%% @spec subId() -> SubId::exmpp_pubsub:subId()
|
||||
-spec(subId/0 :: () -> SubId::exmpp_pubsub:subId()).
|
||||
|
||||
subId() ->
|
||||
{T1, T2, T3} = now(),
|
||||
list_to_binary(lists:flatten(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3]))).
|
||||
|
||||
%% @spec itemId() -> ItemId::exmpp_pubsub:itemId()
|
||||
-spec(itemId/0 :: () -> ItemId::exmpp_pubsub:itemId()).
|
||||
|
||||
itemId() ->
|
||||
{T1, T2, T3} = now(),
|
||||
list_to_binary(lists:flatten(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3]))).
|
||||
|
||||
id() ->
|
||||
{T1, T2, T3} = now(),
|
||||
list_to_binary(lists:flatten(io_lib:fwrite("~.16B~.16B~.16B", [T1, T2, T3]))).
|
||||
|
||||
|
||||
|
||||
%%
|
||||
-spec(subscription_subscribed/2 ::
|
||||
(
|
||||
Resource :: undefined
|
||||
| xmpp_jid:resource_jid()
|
||||
| {'caps', xmpp_jid:resource_jid()},
|
||||
Subscription_Options :: [] | pubsub_options:options_subscription())
|
||||
-> Subscription_Subscribed::exmpp_pubsub:subscription_subscribed()
|
||||
).
|
||||
|
||||
subscription_subscribed(Resource, Subscription_Options) ->
|
||||
{'subscribed', subId(), Resource, Subscription_Options}.
|
||||
|
||||
%%
|
||||
-spec(subscription_pending/2 ::
|
||||
(
|
||||
Resource :: undefined
|
||||
| xmpp_jid:resource_jid()
|
||||
| {'caps', xmpp_jid:resource_jid()},
|
||||
Subscription_Options :: [] | pubsub_options:options_subscription())
|
||||
-> Subscription_Pending::exmpp_pubsub:subscription_pending()
|
||||
).
|
||||
|
||||
subscription_pending(Resource, Subscription_Options) ->
|
||||
{'pending', subId(), Resource, Subscription_Options}.
|
||||
|
||||
|
||||
|
||||
%% Pubsub Xmlel templates
|
||||
|
||||
xmlcdata(CData) ->
|
||||
{xmlcdata, CData}.
|
||||
|
||||
xmlattr(Name, Value) ->
|
||||
{Name, Value}.
|
||||
|
||||
|
||||
xmlel('disco#info', Name, Attrs, Children) ->
|
||||
xmlel(?NS_DISCO_INFO, Name, Attrs, Children);
|
||||
xmlel('disco#items', Name, Attrs, Children) ->
|
||||
xmlel(?NS_DISCO_ITEMS, Name, Attrs, Children);
|
||||
xmlel('jabber:client', Name, Attrs, Children) ->
|
||||
xmlel(?NS_JABBER_CLIENT, Name, Attrs, Children);
|
||||
xmlel('pubsub', Name, Attrs, Children) ->
|
||||
xmlel(?NS_PUBSUB, Name, Attrs, Children);
|
||||
xmlel('pubsub#event', Name, Attrs, Children) ->
|
||||
xmlel(?NS_PUBSUB_EVENT, Name, Attrs, Children);
|
||||
xmlel('pubsub#owner', Name, Attrs, Children) ->
|
||||
xmlel(?NS_PUBSUB_OWNER, Name, Attrs, Children);
|
||||
xmlel('shim', Name, Attrs, Children) ->
|
||||
xmlel(?NS_SHIM, Name, Attrs, Children);
|
||||
xmlel(NS, Name, Attrs, Children) ->
|
||||
#xmlel{name = Name, attrs = [{<<"xmlns">>, NS} | Attrs], children = Children}.
|
||||
%%
|
||||
xmlattr_affiliation(Affiliation) ->
|
||||
xmlattr(<<"affiliation">>, list_to_binary(atom_to_list(Affiliation))).
|
||||
%%
|
||||
xmlattr_category(Category) ->
|
||||
xmlattr(<<"category">>, Category).
|
||||
%%
|
||||
xmlattr_id(ItemId) ->
|
||||
xmlattr(<<"id">>, ItemId).
|
||||
%%
|
||||
xmlattr_jid(Jid) ->
|
||||
xmlattr(<<"jid">>, Jid).
|
||||
%%
|
||||
xmlattr_name(Name) ->
|
||||
xmlattr(<<"name">>, Name).
|
||||
%%
|
||||
xmlattr_node(NodeId) ->
|
||||
xmlattr(<<"node">>, NodeId).
|
||||
%%
|
||||
xmlattr_publisher(Publisher) ->
|
||||
xmlattr(<<"publisher">>, Publisher).
|
||||
%%
|
||||
xmlattr_subid(SubId) ->
|
||||
xmlattr(<<"subid">>, SubId).
|
||||
%%
|
||||
xmlattr_subscription(Subscription_State) ->
|
||||
xmlattr(<<"subscription">>, list_to_binary(atom_to_list(Subscription_State))).
|
||||
%%
|
||||
xmlattr_type(Type) when is_atom(Type)->
|
||||
xmlattr(<<"type">>, list_to_binary(atom_to_list(Type)));
|
||||
%%
|
||||
xmlattr_type(Type) ->
|
||||
xmlattr(<<"type">>, Type).
|
||||
%%
|
||||
xmlattr_uri(URI) ->
|
||||
xmlattr(<<"uri">>, URI).
|
||||
%%
|
||||
xmlattr_var(Var) ->
|
||||
xmlattr(<<"var">>, Var).
|
||||
|
||||
%%
|
||||
xmlel_affiliation('pubsub', NodeId, Affiliation) ->
|
||||
xmlel('pubsub', <<"affiliation">>,
|
||||
[xmlattr_node(NodeId),
|
||||
xmlattr_affiliation(Affiliation)],
|
||||
[]);
|
||||
xmlel_affiliation('pubsub#owner', Jid, Affiliation) ->
|
||||
xmlel('pubsub#owner', <<"affiliation">>,
|
||||
[xmlattr_jid(Jid),
|
||||
xmlattr_affiliation(Affiliation)],
|
||||
[]).
|
||||
%%
|
||||
xmlel_affiliations('pubsub', Xmlels) ->
|
||||
xmlel('pubsub', <<"affiliations">>, [], Xmlels).
|
||||
|
||||
xmlel_affiliations('pubsub#owner', NodeId, Xmlels) ->
|
||||
xmlel('pubsub#owner', <<"affiliations">>, [xmlattr_node(NodeId)], Xmlels).
|
||||
%%
|
||||
xmlel_create(NodeId) ->
|
||||
xmlel('pubsub', <<"create">>, [xmlattr_node(NodeId)], []).
|
||||
|
||||
%%
|
||||
xmlel_configure('pubsub#owner', NodeId, Xmlels) ->
|
||||
xmlel('pubsub#owner', <<"configure">>, [xmlattr_node(NodeId)], Xmlels).
|
||||
|
||||
%%
|
||||
xmlel_default('pubsub', Xmlels) ->
|
||||
xmlel('pubsub', <<"default">>, [], Xmlels);
|
||||
%%
|
||||
xmlel_default('pubsub#owner', Xmlels) ->
|
||||
xmlel('pubsub#owner', <<"default">>, [], Xmlels).
|
||||
|
||||
%%
|
||||
xmlel_default('pubsub', NodeId, Xmlels) ->
|
||||
xmlel('pubsub', <<"default">>, [xmlattr_node(NodeId)], Xmlels).
|
||||
|
||||
%%
|
||||
xmlel_delete(NodeId, RedirectURI) ->
|
||||
xmlel('pubsub#event', <<"delete">>,
|
||||
[xmlattr_node(NodeId)],
|
||||
case RedirectURI of
|
||||
undefined -> [];
|
||||
_RedirectURI -> [xmlel_redirect(RedirectURI)]
|
||||
end).
|
||||
%%
|
||||
xmlel_event(Xmlels) ->
|
||||
xmlel('pubsub#event', <<"event">>, [], Xmlels).
|
||||
%%
|
||||
xmlel_feature('disco#info', Feature) ->
|
||||
xmlel('disco#info', <<"feature">>, [xmlattr_var(Feature)], []).
|
||||
%%
|
||||
xmlel_header(SubId) ->
|
||||
xmlel('shim', <<"header">>, [xmlattr_name(<<"SubID">>)], [xmlcdata(SubId)]).
|
||||
%%
|
||||
xmlel_headers(Xmlels_Header) ->
|
||||
xmlel('shim', <<"headers">>, [], Xmlels_Header).
|
||||
|
||||
|
||||
xmlel_identity('disco#info', Category, Type, Name) ->
|
||||
xmlel('disco#info', <<"identity">>,
|
||||
case Name of
|
||||
undefined ->
|
||||
[xmlattr_category(Category),
|
||||
xmlattr_type(Type)];
|
||||
_ ->
|
||||
[xmlattr_category(Category),
|
||||
xmlattr_name(Name),
|
||||
xmlattr_type(Type)]
|
||||
end,
|
||||
[]).
|
||||
|
||||
%%
|
||||
xmlel_item('pubsub', ItemId) ->
|
||||
xmlel('pubsub', <<"item">>, [xmlattr_id(ItemId)], []).
|
||||
|
||||
%%
|
||||
xmlel_item('disco#items', ItemId, Jid) ->
|
||||
xmlel('disco#items', <<"item">>,
|
||||
[xmlattr_name(ItemId),
|
||||
xmlattr_jid(Jid)],
|
||||
[]);
|
||||
xmlel_item('pubsub', ItemId, Payload) ->
|
||||
xmlel('pubsub', <<"item">>, [xmlattr_id(ItemId)],
|
||||
case Payload of
|
||||
[] -> [];
|
||||
_Payload -> [Payload]
|
||||
end).
|
||||
|
||||
xmlel_item('disco#items', NodeId, Jid, Name) ->
|
||||
xmlel('disco#items', <<"item">>,
|
||||
case Name of
|
||||
undefined ->
|
||||
[xmlattr_jid(Jid),
|
||||
xmlattr_node(NodeId)];
|
||||
_ ->
|
||||
[xmlattr_jid(Jid),
|
||||
xmlattr_node(NodeId),
|
||||
xmlattr_name(Name)]
|
||||
end,
|
||||
[]);
|
||||
%%
|
||||
xmlel_item('pubsub#event', ItemId, Publisher, Payload) ->
|
||||
xmlel('pubsub#event', <<"item">>,
|
||||
case Publisher of
|
||||
undefined ->
|
||||
[xmlattr_id(ItemId)];
|
||||
_Publisher ->
|
||||
[xmlattr_id(ItemId),
|
||||
xmlattr_publisher(Publisher)]
|
||||
end,
|
||||
case Payload of
|
||||
[] -> [];
|
||||
_Payload -> [Payload]
|
||||
end).
|
||||
%%
|
||||
xmlel_items('pubsub', NodeId, Xmlels) ->
|
||||
xmlel('pubsub', <<"items">>, [xmlattr_node(NodeId)], Xmlels);
|
||||
%%
|
||||
xmlel_items('pubsub#event', undefined = _NodeId, Xmlels) ->
|
||||
xmlel('pubsub#event', <<"items">>, [], Xmlels);
|
||||
%%
|
||||
xmlel_items('pubsub#event', NodeId, Xmlels) ->
|
||||
xmlel('pubsub#event', <<"items">>, [xmlattr_node(NodeId)], Xmlels).
|
||||
%%
|
||||
xmlel_items('pubsub#event', NodeId, undefined = _ItemId, _Publisher, _Payload) ->
|
||||
xmlel('pubsub#event', <<"items">>, [xmlattr_node(NodeId)], []);
|
||||
xmlel_items('pubsub#event', NodeId, ItemId, Publisher, Payload) ->
|
||||
xmlel('pubsub#event', <<"items">>,
|
||||
[xmlattr_node(NodeId)],
|
||||
[xmlel_item('pubsub#event', ItemId, Publisher, Payload)]).
|
||||
%%
|
||||
xmlel_message(undefined = _Type, Xmlels) ->
|
||||
xmlel_message('normal', Xmlels);
|
||||
xmlel_message(Type, Xmlels) ->
|
||||
xmlel('jabber:client', <<"message">>,
|
||||
[xmlattr_type(Type),
|
||||
xmlattr_id(_Id = id())],
|
||||
Xmlels).
|
||||
%%
|
||||
xmlel_options('pubsub', NodeId, Jid, SubId, Xmlels) ->
|
||||
xmlel('pubsub', <<"options">>,
|
||||
case SubId of
|
||||
undefined ->
|
||||
[xmlattr_node(NodeId),
|
||||
xmlattr_jid(Jid)];
|
||||
_ ->
|
||||
[xmlattr_node(NodeId),
|
||||
xmlattr_jid(Jid),
|
||||
xmlattr_subid(SubId)]
|
||||
end,
|
||||
Xmlels).
|
||||
%%
|
||||
xmlel_publish('pubsub', NodeId, Xmlels) ->
|
||||
xmlel('pubsub', <<"publish">>, [xmlattr_node(NodeId)], Xmlels).
|
||||
%%
|
||||
xmlel_purge(NodeId) ->
|
||||
xmlel('pubsub#event', <<"purge">>, [xmlattr_node(NodeId)], []).
|
||||
|
||||
%%
|
||||
xmlel_query('disco#info', Xmlels) ->
|
||||
xmlel('disco#info', <<"query">>, [], Xmlels);
|
||||
%%
|
||||
xmlel_query('disco#items', Xmlels) ->
|
||||
xmlel('disco#items', <<"query">>, [], Xmlels).
|
||||
|
||||
%%
|
||||
xmlel_query('disco#info', NodeId, Xmlels) ->
|
||||
xmlel('disco#info', <<"query">>, [xmlattr_node(NodeId)], Xmlels);
|
||||
xmlel_query('disco#items', NodeId, Xmlels) ->
|
||||
xmlel('disco#items', 'query', [xmlattr_node(NodeId)], Xmlels).
|
||||
|
||||
%%
|
||||
xmlel_redirect(RedirectURI) ->
|
||||
xmlel('pubsub#event', <<"redirect">>, [xmlattr_uri(RedirectURI)], []).
|
||||
%%
|
||||
xmlel_retract(undefined = _ItemId) ->
|
||||
xmlel('pubsub#event', <<"retract">>, [], []);
|
||||
xmlel_retract(ItemId) ->
|
||||
xmlel('pubsub#event', <<"retract">>, [xmlattr_id(ItemId)], []).
|
||||
%%
|
||||
xmlel_subscription('pubsub', NodeId, Jid, SubId, Subscription_State) ->
|
||||
xmlel('pubsub', <<"subscription">>,
|
||||
[xmlattr_node(NodeId),
|
||||
xmlattr_jid(Jid),
|
||||
xmlattr_subid(SubId),
|
||||
xmlattr_subscription(Subscription_State)],
|
||||
[]);
|
||||
xmlel_subscription('pubsub#event', NodeId, Jid, SubId, Subscription_State) ->
|
||||
xmlel('pubsub#event', <<"subscription">>,
|
||||
case SubId of
|
||||
undefined ->
|
||||
[xmlattr_node(NodeId),
|
||||
xmlattr_jid(Jid),
|
||||
xmlattr_subscription(Subscription_State)];
|
||||
_SubId ->
|
||||
[xmlattr_node(NodeId),
|
||||
xmlattr_jid(Jid),
|
||||
xmlattr_subid(SubId),
|
||||
xmlattr_subscription(Subscription_State)]
|
||||
end,
|
||||
[]).
|
||||
%%
|
||||
xmlel_subscription('pubsub#owner', Jid, SubId, Subscription_State) ->
|
||||
xmlel('pubsub#owner', <<"subscription">>,
|
||||
case SubId of
|
||||
undefined ->
|
||||
[xmlattr_jid(Jid),
|
||||
xmlattr_subscription(Subscription_State)];
|
||||
_SubId ->
|
||||
[xmlattr_jid(Jid),
|
||||
xmlattr_subid(SubId),
|
||||
xmlattr_subscription(Subscription_State)]
|
||||
end,
|
||||
[]).
|
||||
%%
|
||||
xmlel_subscriptions('pubsub', Xmlels) ->
|
||||
xmlel('pubsub', <<"subscriptions">>, [], Xmlels).
|
||||
|
||||
xmlel_subscriptions('pubsub#owner', NodeId, Xmlels) ->
|
||||
xmlel('pubsub#owner', <<"subscriptions">>, [xmlattr_node(NodeId)], Xmlels).
|
||||
%%
|
||||
xmlel_publish(NodeId, undefined = _ItemId) ->
|
||||
xmlel('pubsub', <<"publish">>, [xmlattr_node(NodeId)], []);
|
||||
xmlel_publish(NodeId, ItemId) ->
|
||||
xmlel('pubsub', <<"publish">>,
|
||||
[xmlattr_node(NodeId)],
|
||||
[xmlel_item('pubsub', ItemId)]).
|
||||
%%
|
||||
xmlel_pubsub('pubsub', Children) ->
|
||||
xmlel('pubsub', <<"pubsub">>, [], Children);
|
||||
%%
|
||||
xmlel_pubsub('pubsub#owner', Children) ->
|
||||
xmlel('pubsub#owner', <<"pubsub">>, [], Children).
|
||||
|
||||
@@ -0,0 +1,863 @@
|
||||
%%% ====================================================================
|
||||
%%% ``The contents of this file are subject to the Erlang Public License,
|
||||
%%% Version 1.1, (the "License"); you may not use this file except in
|
||||
%%% compliance with the License. You should have received a copy of the
|
||||
%%% Erlang Public License along with this software. If not, it can be
|
||||
%%% retrieved via the world wide web at http://www.erlang.org/.
|
||||
%%%
|
||||
%%% Software distributed under the License is distributed on an "AS IS"
|
||||
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%%% the License for the specific language governing rights and limitations
|
||||
%%% under the License.
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2013, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2013, ProcessOne.
|
||||
%%%
|
||||
%%% @copyright 2006-2013 ProcessOne
|
||||
%%% @author Christophe Romain <christophe.romain@process-one.net>
|
||||
%%% [http://www.process-one.net/]
|
||||
%%% @author Karim Gemayel <karim.gemayel@process-one.net>
|
||||
%%% [http://www.process-one.net/]
|
||||
%%% @version {@vsn}, {@date} {@time}
|
||||
%%% @end
|
||||
%%% ====================================================================
|
||||
|
||||
%%% @headerfile "pubsub_dev.hrl"
|
||||
|
||||
-module(mod_pubsub_dev).
|
||||
-author('christophe.romain@process-one.net').
|
||||
-author('karim.gemayel@process-one.net').
|
||||
-version('1.13-0').
|
||||
|
||||
-behaviour(gen_server).
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-include("pubsub_dev.hrl").
|
||||
-include("pubsub_api.hrl").
|
||||
|
||||
-compile(export_all).
|
||||
%%% Export Functions
|
||||
|
||||
%% API and gen_server callbacks
|
||||
-export([
|
||||
start_link/2,
|
||||
start/2,
|
||||
stop/1,
|
||||
init/1,
|
||||
handle_call/3,
|
||||
handle_cast/2,
|
||||
handle_info/2,
|
||||
terminate/2,
|
||||
code_change/3
|
||||
]).
|
||||
|
||||
%%
|
||||
-export_type([
|
||||
resource_show/0,
|
||||
presence_cache/0
|
||||
]).
|
||||
|
||||
-type(resource_show()
|
||||
:: {Resource :: xmpp_jid:resource_jid(),
|
||||
Show :: 'away' | 'chat' | 'dnd' | 'online' | 'xa' }
|
||||
).
|
||||
|
||||
-type(presence_cache() :: [Resource_Show::resource_show()]).
|
||||
|
||||
%%
|
||||
-export_type([
|
||||
resource_subids/0,
|
||||
resources_subids/0
|
||||
]).
|
||||
|
||||
-type(resource_subids()
|
||||
:: {Resource :: xmpp_jid:resource_jid(),
|
||||
SubIds :: [SubId::exmpp_pubsub:subId(),...]}
|
||||
).
|
||||
|
||||
-type(resources_subids() :: [Resource_SubIds::resource_subids(),...]).
|
||||
|
||||
%%%
|
||||
-export_type([
|
||||
entity/0,
|
||||
n0de/0,
|
||||
cache/0,
|
||||
subids/0,
|
||||
event/0
|
||||
]).
|
||||
|
||||
-type(entity() :: #entity{}).
|
||||
% id :: xmpp_jid:usr_bare(),
|
||||
% affiliation :: 'member' | 'owner' | 'publisher',
|
||||
% subscriptions :: []%[exmpp_pubsub:subscription(),...]
|
||||
%}).
|
||||
|
||||
%%%
|
||||
-type(n0de() :: #node{}).
|
||||
% id :: exmpp_pubsub:nodeId(),
|
||||
% owners :: [Node_Owner::xmpp_jid:usr_bare(),...],
|
||||
% access_model :: pubsub_options:access_model(),
|
||||
% itemreply :: 'owner' | 'publisher',
|
||||
% notification_type :: 'headline' | 'normal',
|
||||
% presence_based_delivery :: boolean(),
|
||||
% rosters_groups_allowed :: [] | pubsub_options:rosters_groups_allowed()
|
||||
%}).
|
||||
|
||||
%%%
|
||||
-type(cache() :: #cache{}).
|
||||
% presence :: undefined | mod_pubsub_dev:presence_cache(),
|
||||
% presence_subscriptions :: undefined | boolean(),
|
||||
% rosters_groups :: undefined | boolean()
|
||||
%}).
|
||||
|
||||
%%%
|
||||
-type(subids() :: #subids{}).
|
||||
% presence :: undefined | [] | mod_pubsub_dev:resources_subids(),
|
||||
% no_presence :: undefined | [] | mod_pubsub_dev:resources_subids()
|
||||
%}).
|
||||
|
||||
%%
|
||||
-type(event() :: #event{
|
||||
% host :: xmpp_jid:raw_jid_component_bare(),
|
||||
% component :: xmpp_jid:component_bare(),
|
||||
% entity :: mod_pubsub_dev:entity(),
|
||||
% node :: mod_pubsub_dev:n0de(),
|
||||
% cache :: mod_pubsub_dev:cache(),
|
||||
% subids :: mod_pubsub_dev:subids()
|
||||
}).
|
||||
|
||||
%%%
|
||||
-export_type([
|
||||
item/0,
|
||||
published_item/0,
|
||||
retracted_item/0
|
||||
]).
|
||||
|
||||
-type(published_item() :: #item{
|
||||
access_model :: undefined | pubsub_options:access_model(),
|
||||
presence_based_delivery :: undefined | boolean(),
|
||||
rosters_groups_allowed :: [] | pubsub_options:rosters_groups_allowed(),
|
||||
stanza :: xmlel()
|
||||
}).
|
||||
|
||||
-type(retracted_item() :: #item{
|
||||
access_model :: undefined | pubsub_options:access_model(),
|
||||
presence_based_delivery :: undefined | boolean(),
|
||||
rosters_groups_allowed :: [] | pubsub_options:rosters_groups_allowed(),
|
||||
stanza :: xmlel()
|
||||
}).
|
||||
|
||||
-type(item() :: published_item() | retracted_item()).
|
||||
|
||||
|
||||
%%
|
||||
|
||||
-export_type([
|
||||
pubsub_itemId/0,
|
||||
pubsub_nodeId/0,
|
||||
pubsub_stateId/0,
|
||||
item_owners/0,
|
||||
node_owners/0,
|
||||
item_creation/0,
|
||||
item_modification/0,
|
||||
node_creation/0
|
||||
]).
|
||||
|
||||
-type(pubsub_itemId()
|
||||
:: {ItemId::exmpp_pubsub:itemId(), NodeIdx::exmpp_pubsub:nodeIdx()}
|
||||
).
|
||||
|
||||
-type(pubsub_nodeId()
|
||||
:: {Pubsub_Host :: exmpp_pubsub:host(), NodeId :: exmpp_pubsub:nodeId()}
|
||||
).
|
||||
|
||||
-type(pubsub_stateId()
|
||||
:: {Entity::xmpp_jid:usr_bare(), NodeIdx::exmpp_pubsub:nodeIdx()}
|
||||
).
|
||||
|
||||
-type(item_owners() :: [Entity::xmpp_jid:usr_bare(),...]).
|
||||
-type(node_owners() :: [Entity::xmpp_jid:usr_bare(),...]).
|
||||
|
||||
-type(item_creation()
|
||||
:: {DateTime::erlang:timestamp(), Entity::xmpp_jid:usr_entity()}
|
||||
).
|
||||
|
||||
-type(item_modification()
|
||||
:: {DateTime::erlang:timestamp(), Entity::xmpp_jid:usr_entity()}
|
||||
).
|
||||
|
||||
-type(node_creation()
|
||||
:: {DateTime::erlang:timestamp(), Entity::xmpp_jid:usr_entity()}
|
||||
).
|
||||
|
||||
|
||||
|
||||
%%
|
||||
-export_type([
|
||||
pubsub_state/0,
|
||||
pubsub_states/0,
|
||||
%
|
||||
pubsub_state_owner/0,
|
||||
pubsub_state_publisher/0,
|
||||
pubsub_state_publish_only/0,
|
||||
pubsub_state_member/0,
|
||||
pubsub_state_none/0,
|
||||
pubsub_state_outcast/0
|
||||
]).
|
||||
|
||||
-type(pubsub_state_owner()
|
||||
:: #pubsub_state_dev{
|
||||
id :: mod_pubsub_dev:pubsub_stateId(),
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
affiliation :: 'owner',
|
||||
access :: undefined | 'presence' | 'roster',
|
||||
%subscriptions :: [exmpp_pubsub:subscription_subscribed() |
|
||||
% exmpp_pubsub:subscription_unconfigured()],
|
||||
subscriptions :: [exmpp_pubsub:subscription()],
|
||||
itemids :: [] | exmpp_pubsub:itemIds()
|
||||
}
|
||||
).
|
||||
|
||||
%%
|
||||
-type(pubsub_state_publisher()
|
||||
:: #pubsub_state_dev{
|
||||
id :: mod_pubsub_dev:pubsub_stateId(),
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
affiliation :: 'publisher',
|
||||
access :: undefined | 'presence' | 'roster',
|
||||
%subscriptions :: [exmpp_pubsub:subscription_subscribed() |
|
||||
% exmpp_pubsub:subscription_unconfigured()],
|
||||
subscriptions :: [exmpp_pubsub:subscription()],
|
||||
itemids :: [] | exmpp_pubsub:itemIds()
|
||||
}
|
||||
).
|
||||
|
||||
%%
|
||||
-type(pubsub_state_publish_only()
|
||||
:: #pubsub_state_dev{
|
||||
id :: mod_pubsub_dev:pubsub_stateId(),
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
affiliation :: 'publish-only',
|
||||
access :: undefined | 'presence' | 'roster',
|
||||
subscriptions :: [],
|
||||
itemids :: [] | exmpp_pubsub:itemIds()
|
||||
}
|
||||
).
|
||||
|
||||
%%
|
||||
-type(pubsub_state_member()
|
||||
:: #pubsub_state_dev{
|
||||
id :: mod_pubsub_dev:pubsub_stateId(),
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
affiliation :: 'member',
|
||||
access :: undefined | 'pending' | 'presence' | 'roster',
|
||||
subscriptions :: [],
|
||||
itemids :: [] | exmpp_pubsub:itemIds()
|
||||
}
|
||||
%%
|
||||
| #pubsub_state_dev{
|
||||
id :: mod_pubsub_dev:pubsub_stateId(),
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
affiliation :: 'member',
|
||||
access :: undefined | 'pending' | 'presence' | 'roster',
|
||||
%subscriptions :: [exmpp_pubsub:subscription_pending(),...],
|
||||
subscriptions :: [exmpp_pubsub:subscription()],
|
||||
itemids :: [] | exmpp_pubsub:itemIds()
|
||||
}
|
||||
%%
|
||||
| #pubsub_state_dev{
|
||||
id :: mod_pubsub_dev:pubsub_stateId(),
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
affiliation :: 'member',
|
||||
subscriptions :: [exmpp_pubsub:subscription()],
|
||||
%subscriptions :: [exmpp_pubsub:subscription_pending() |
|
||||
% exmpp_pubsub:subscription_subscribed() |
|
||||
% exmpp_pubsub:subscription_unconfigured()],
|
||||
itemids :: [] | exmpp_pubsub:itemIds()
|
||||
}
|
||||
).
|
||||
|
||||
%%
|
||||
-type(pubsub_state_none()
|
||||
:: #pubsub_state_dev{
|
||||
id :: mod_pubsub_dev:pubsub_stateId(),
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
affiliation :: 'none',
|
||||
access :: undefined | 'presence' | 'roster',
|
||||
subscriptions :: [],
|
||||
itemids :: []
|
||||
}
|
||||
%%
|
||||
| #pubsub_state_dev{
|
||||
id :: mod_pubsub_dev:pubsub_stateId(),
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
affiliation :: 'none',
|
||||
access :: undefined | 'presence' | 'roster',
|
||||
subscriptions :: [],
|
||||
itemids :: exmpp_pubsub:itemIds()
|
||||
}
|
||||
%%
|
||||
| #pubsub_state_dev{
|
||||
id :: mod_pubsub_dev:pubsub_stateId(),
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
affiliation :: 'none',
|
||||
access :: undefined | 'presence' | 'roster',
|
||||
subscriptions :: [],
|
||||
itemids :: exmpp_pubsub:itemIds()
|
||||
}
|
||||
).
|
||||
|
||||
%%
|
||||
-type(pubsub_state_outcast()
|
||||
:: #pubsub_state_dev{
|
||||
id :: mod_pubsub_dev:pubsub_stateId(),
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
affiliation :: 'outcast',
|
||||
access :: undefined | 'presence' | 'roster',
|
||||
subscriptions :: [exmpp_pubsub:subscription()],
|
||||
%subscriptions :: [exmpp_pubsub:subscription_pending() |
|
||||
% exmpp_pubsub:subscription_subscribed() |
|
||||
% exmpp_pubsub:subscription_unconfigured()],
|
||||
itemids :: [] | exmpp_pubsub:itemIds()
|
||||
}
|
||||
).
|
||||
|
||||
|
||||
%%
|
||||
-type(pubsub_state() :: mod_pubsub_dev:pubsub_state_owner()
|
||||
| mod_pubsub_dev:pubsub_state_publisher()
|
||||
| mod_pubsub_dev:pubsub_state_publish_only()
|
||||
| mod_pubsub_dev:pubsub_state_member()
|
||||
| mod_pubsub_dev:pubsub_state_none()
|
||||
| mod_pubsub_dev:pubsub_state_outcast()
|
||||
).
|
||||
|
||||
-type(pubsub_states() :: [Pubsub_State::mod_pubsub_dev:pubsub_state(),...]).
|
||||
|
||||
|
||||
%%
|
||||
-export_type([
|
||||
pubsub_node/0,
|
||||
pubsub_nodes/0
|
||||
]).
|
||||
|
||||
-type(pubsub_node()
|
||||
:: #pubsub_node_dev{
|
||||
id :: mod_pubsub_dev:pubsub_nodeId(),
|
||||
idx :: exmpp_pubsub:nodeIdx(),
|
||||
creation :: mod_pubsub_dev:node_creation(),
|
||||
level :: exmpp_pubsub:level(),
|
||||
owners :: mod_pubsub_dev:node_owners(),
|
||||
itemids :: [] | exmpp_pubsub:itemIds(),
|
||||
options :: pubsub_options:options_node()
|
||||
}
|
||||
).
|
||||
|
||||
-type(pubsub_nodes() :: [Pubsub_Node::mod_pubsub_dev:pubsub_node(),...]).
|
||||
|
||||
|
||||
%%
|
||||
-export_type([
|
||||
pubsub_item/0,
|
||||
pubsub_items/0
|
||||
]).
|
||||
|
||||
-type(pubsub_item()
|
||||
:: #pubsub_item_dev{
|
||||
id :: mod_pubsub_dev:pubsub_itemId(),
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
owners :: mod_pubsub_dev:item_owners(),
|
||||
creation :: mod_pubsub_dev:item_creation(),
|
||||
modification :: mod_pubsub_dev:item_modification(),
|
||||
payload :: exmpp_pubsub:payload(),
|
||||
options :: [] | pubsub_options:options_item()
|
||||
}
|
||||
).
|
||||
|
||||
-type(pubsub_items() :: [Pubsub_Item::mod_pubsub_dev:pubsub_item(),...]).
|
||||
|
||||
%%
|
||||
-export_type([
|
||||
pubsub_last_item/0
|
||||
]).
|
||||
|
||||
-type(pubsub_last_item()
|
||||
:: #pubsub_last_item_dev{
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
id :: exmpp_pubsub:itemId(),
|
||||
owners :: mod_pubsub_dev:item_owners(),
|
||||
creation :: mod_pubsub_dev:item_creation(),
|
||||
payload :: exmpp_pubsub:payload(),
|
||||
options :: [] | pubsub_options:options_item()
|
||||
}
|
||||
).
|
||||
|
||||
%%
|
||||
-export_type([
|
||||
pubsub_subscription_pending/0
|
||||
]).
|
||||
|
||||
-type(pubsub_subscription_pending()
|
||||
:: #pubsub_subscription_pending{
|
||||
id :: {Entity::xmpp_jid:usr_bare(), NodeIdx::exmpp_pubsub:nodeIdx()},
|
||||
nodeidx :: exmpp_pubsub:nodeIdx(),
|
||||
subids :: [SubId::exmpp_pubsub:subId(),...]
|
||||
}
|
||||
).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-define(PROCNAME, ejabberd_mod_pubsub_dev).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-record(state,
|
||||
{
|
||||
host :: xmpp_jid:raw_jid_component_bare(),
|
||||
pubsub_host :: xmpp_jid:raw_jid_component_bare(),
|
||||
pubsub :: #capabilities{},
|
||||
pubsub_on_jid :: #capabilities{}
|
||||
}).
|
||||
|
||||
-type(state()
|
||||
:: #state{
|
||||
host :: xmpp_jid:raw_jid_component_bare(),
|
||||
pubsub_host :: xmpp_jid:raw_jid_component_bare(),
|
||||
pubsub :: #capabilities{},
|
||||
pubsub_on_jid :: #capabilities{}
|
||||
}
|
||||
).
|
||||
|
||||
|
||||
%%====================================================================
|
||||
%% API
|
||||
%%====================================================================
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
|
||||
%% Description: Starts the server
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
%% @spec start_link(Host, Options) -> {'ok', pid()} | 'ignore' | {'error', atom()}
|
||||
%% Host = string()
|
||||
%% Options = {Option::atom(), Value::term()}
|
||||
-spec(start_link/2 ::
|
||||
(
|
||||
Host :: string(),
|
||||
Options :: [Option::{Key::atom(), Value::term()}])
|
||||
-> {'ok', pid()} | 'ignore' | {'error', _}
|
||||
).
|
||||
|
||||
start_link(Host, Options) ->
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
gen_server:start_link({local, Proc}, ?MODULE, [Host, Options], []).
|
||||
|
||||
%% @spec start(Host, Options) -> {'error',atom()} | {'ok','undefined' | pid()} | {'ok','undefined' | pid(),any()}
|
||||
%% Host = string()
|
||||
%% Options = {Option::atom(), Value::term()}
|
||||
-spec(start/2 ::
|
||||
(
|
||||
Host :: string(),
|
||||
Options :: [Option::{Key::atom(), Value::term()}])
|
||||
-> {'error',_} | {'ok','undefined' | pid()} | {'ok','undefined' | pid(),_}
|
||||
).
|
||||
|
||||
start(Host, Options) ->
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
ChildSpec = {Proc,
|
||||
{?MODULE, start_link, [Host, Options]},
|
||||
transient, 1000, worker, [?MODULE]},
|
||||
supervisor:start_child(ejabberd_sup, ChildSpec).
|
||||
|
||||
%% @spec stop(Host) -> 'ok' | {'error','not_found' | 'running' | 'simple_one_for_one'}
|
||||
%% Host = string()
|
||||
-spec(stop/1 ::
|
||||
(
|
||||
Host :: string())
|
||||
-> 'ok' | {'error','not_found' | 'running' | 'simple_one_for_one'}
|
||||
).
|
||||
|
||||
stop(Host) ->
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
gen_server:call(Proc, stop),
|
||||
supervisor:delete_child(ejabberd_sup, Proc).
|
||||
|
||||
|
||||
|
||||
|
||||
%%====================================================================
|
||||
%% gen_server callbacks
|
||||
%%====================================================================
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function: init(Args) -> {ok, State} |
|
||||
%% {ok, State, Timeout} |
|
||||
%% ignore |
|
||||
%% {stop, Reason}
|
||||
%% Description: Initiates the server
|
||||
%%--------------------------------------------------------------------
|
||||
-spec(init/1 ::
|
||||
(
|
||||
Args :: [binary() | [{Option::atom(), Value::term()}]])
|
||||
-> {'ok', State::state()}
|
||||
).
|
||||
|
||||
init([Host, Options] = _Args) ->
|
||||
?DEBUG("pubsub init ~p ~p",[Host, Options]),
|
||||
Pubsub_Host = gen_mod:expand_host_name(Host, Options, <<"pubsub">>),
|
||||
IQDisc = gen_mod:get_opt('iqdisc', Options, 'one_queue'),
|
||||
|
||||
% mod_disco:register_feature(Server_HostB, ?NS_PUBSUB_s),
|
||||
%%
|
||||
%% Pubsub Hooks
|
||||
%% - Service disco hooks
|
||||
%% * disco_local_identity
|
||||
%% * disco_local_features
|
||||
%% * disco_local_items
|
||||
%% * disco_local_forms
|
||||
%% - Connectivity hooks
|
||||
%% * presence_probe_hook
|
||||
%% * sm_remove_connection_hook
|
||||
%% - Roster hooks
|
||||
%% * roster_in_subscription
|
||||
%% * roster_out_subscription
|
||||
%% - User managment hooks
|
||||
%% * remove_user
|
||||
%% * anonymous_purge_hook
|
||||
%%
|
||||
%% Pubsub On Jid hooks
|
||||
%% - Service disco hooks
|
||||
%% * disco_sm_identity
|
||||
%% * disco_sm_features
|
||||
%% * disco_sm_items
|
||||
%% * disco_sm_forms
|
||||
%% - Connectitivy
|
||||
%% * caps_update
|
||||
|
||||
|
||||
Pubsub_Features = node_flat_dev:pubsub_features(),
|
||||
% mod_disco:register_feature(Server_HostB, ?NS_PUBSUB_s),
|
||||
pubsub_db:init('mnesia', 'dev'),
|
||||
%% Register hooks according to available Pubsub Features
|
||||
register_hooks(Host, Pubsub_Features, pubsub_hooks),
|
||||
%%
|
||||
ejabberd_router:register_route(Pubsub_Host),
|
||||
{ok,
|
||||
#state{
|
||||
host = Host,
|
||||
pubsub_host = Pubsub_Host,
|
||||
pubsub = node_flat_dev:capabilities()
|
||||
}
|
||||
}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function:
|
||||
%% handle_call(Request, From, State) -> {reply, Reply, State} |
|
||||
%% {reply, Reply, State, Timeout} |
|
||||
%% {noreply, State} |
|
||||
%% {noreply, State, Timeout} |
|
||||
%% {stop, Reason, Reply, State} |
|
||||
%% {stop, Reason, State}
|
||||
%% Description: Handling call messages
|
||||
%%--------------------------------------------------------------------
|
||||
%% @private
|
||||
|
||||
handle_call(stop, _From, State) ->
|
||||
{stop, normal, ok, State}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function: handle_cast(Msg, State) -> {noreply, State} |
|
||||
%% {noreply, State, Timeout} |
|
||||
%% {stop, Reason, State}
|
||||
%% Description: Handling cast messages
|
||||
%%--------------------------------------------------------------------
|
||||
%% @private
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function: handle_info(Info, State) -> {noreply, State} |
|
||||
%% {noreply, State, Timeout} |
|
||||
%% {stop, Reason, State}
|
||||
%% Description: Handling all non call/cast messages
|
||||
%%--------------------------------------------------------------------
|
||||
%% @private
|
||||
|
||||
handle_info({route, From, #jid{resource = undefined} = To, Stanza},
|
||||
#state{host = Host, pubsub = Capabilities} = State) ->
|
||||
do_route(Host, To, From, Stanza, Capabilities),
|
||||
{noreply, State};
|
||||
%%
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function: terminate(Reason, State) -> void()
|
||||
%% Description: This function is called by a gen_server when it is about to
|
||||
%% terminate. It should be the opposite of Module:init/1 and do any necessary
|
||||
%% cleaning up. When it returns, the gen_server terminates with Reason.
|
||||
%% The return value is ignored.
|
||||
%%--------------------------------------------------------------------
|
||||
%% @private
|
||||
%% @todo : -spec
|
||||
-spec(terminate/2 ::
|
||||
(
|
||||
Reason :: _,
|
||||
State :: state())
|
||||
-> 'ok'
|
||||
).
|
||||
|
||||
terminate(_Reason, #state{host = Host, pubsub_host = Pubsub_Host}) ->
|
||||
ejabberd_router:unregister_route(Pubsub_Host),
|
||||
ok.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
|
||||
%% Description: Convert process state when code is changed
|
||||
%%--------------------------------------------------------------------
|
||||
%% @private
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
|
||||
%%
|
||||
-define(Is_Stanza_IQ(Stanza),
|
||||
(
|
||||
Stanza#xmlel.name == <<"iq">>
|
||||
)).
|
||||
|
||||
-define(Is_Stanza_Message(Stanza),
|
||||
(
|
||||
Stanza#xmlel.name == <<"message">>
|
||||
)).
|
||||
|
||||
-define(Is_Stanza_Presence(Stanza),
|
||||
(
|
||||
Stanza#xmlel.name == <<"presence">>
|
||||
)).
|
||||
|
||||
-define(Is_IQ_Ignore(IQ),
|
||||
(
|
||||
IQ#iq.type == 'result'
|
||||
orelse
|
||||
IQ#iq.type == 'error'
|
||||
)).
|
||||
|
||||
-define(Is_IQ_Pubsub(IQ),
|
||||
(
|
||||
(IQ#iq.type == 'set'
|
||||
orelse
|
||||
IQ#iq.type == 'get')
|
||||
andalso
|
||||
(IQ#iq.xmlns == ?NS_PUBSUB
|
||||
orelse
|
||||
IQ#iq.xmlns == ?NS_PUBSUB_OWNER)
|
||||
andalso
|
||||
IQ#iq.sub_el#xmlel.name == <<"pubsub">>
|
||||
)).
|
||||
|
||||
-define(Is_IQ_Get_Disco_Info(IQ),
|
||||
(
|
||||
IQ#iq.type == 'get'
|
||||
andalso
|
||||
IQ#iq.xmlns == ?NS_DISCO_INFO
|
||||
andalso
|
||||
IQ#iq.sub_el#xmlel.name == <<"query">>
|
||||
% andalso
|
||||
% IQ#iq.payload#xmlel.children == []
|
||||
)).
|
||||
|
||||
-define(Is_IQ_Get_Disco_Items(IQ),
|
||||
(
|
||||
IQ#iq.type == 'get'
|
||||
andalso
|
||||
IQ#iq.xmlns == ?NS_DISCO_ITEMS
|
||||
andalso
|
||||
IQ#iq.sub_el#xmlel.name == <<"query">>
|
||||
% andalso
|
||||
% IQ#iq.payload#xmlel.children == []
|
||||
)).
|
||||
|
||||
%%
|
||||
do_route(Host,
|
||||
#jid{lserver = Pubsub_Host} = Pubsub_Component,
|
||||
#jid{luser = U, lserver = S, lresource = R} = Entity, Stanza_IQ,
|
||||
#capabilities{privacy = Privacy, plugin = Plugin} = Capabilities)
|
||||
when ?Is_Stanza_IQ(Stanza_IQ) ->
|
||||
case IQ = jlib:iq_query_or_response_info(Stanza_IQ) of
|
||||
IQ when ?Is_IQ_Ignore(IQ) ->
|
||||
ok;
|
||||
IQ when ?Is_IQ_Get_Disco_Info(IQ) ->
|
||||
case
|
||||
pubsub_disco:iq_disco_info('dev', Host, Pubsub_Host,
|
||||
Privacy, {U,S,undefined},
|
||||
case S of
|
||||
Host -> 'local';
|
||||
_ -> 'remote'
|
||||
end,
|
||||
Plugin,
|
||||
case xml:get_tag_attr_s(<<"node">>, IQ#iq.sub_el) of
|
||||
<<>> -> undefined;
|
||||
NodeId -> NodeId
|
||||
end,
|
||||
xml:remove_cdata(IQ#iq.sub_el#xmlel.children))
|
||||
of
|
||||
{result, Xmlel_Query} ->
|
||||
ejabberd_router:route(Pubsub_Component, Entity,
|
||||
jlib:iq_to_xml(IQ#iq{
|
||||
type = result,
|
||||
sub_el = [Xmlel_Query]
|
||||
}));
|
||||
{error, Error} ->
|
||||
ejabberd_router:route(Pubsub_Component, Entity,
|
||||
jlib:make_error_reply(Stanza_IQ, Error))
|
||||
end;
|
||||
IQ when ?Is_IQ_Get_Disco_Items(IQ) ->
|
||||
case
|
||||
pubsub_disco:iq_disco_items('dev', Host, Pubsub_Host,
|
||||
Privacy, {U,S,undefined},
|
||||
case S of
|
||||
Host -> 'local';
|
||||
_ -> 'remote'
|
||||
end,
|
||||
Plugin,
|
||||
case xml:get_tag_attr_s(<<"node">>, IQ#iq.sub_el) of
|
||||
<<>> -> undefined;
|
||||
NodeId -> NodeId
|
||||
end,
|
||||
xml:remove_cdata(IQ#iq.sub_el#xmlel.children))
|
||||
of
|
||||
{result, Xmlel_Query} ->
|
||||
ejabberd_router:route(Pubsub_Component, Entity,
|
||||
jlib:iq_to_xml(IQ#iq{
|
||||
type = result,
|
||||
sub_el = [Xmlel_Query]
|
||||
}));
|
||||
{error, Error} ->
|
||||
ejabberd_router:route(Pubsub_Component, Entity,
|
||||
jlib:make_error_reply(Stanza_IQ, Error))
|
||||
end;
|
||||
IQ when ?Is_IQ_Pubsub(IQ) ->
|
||||
case
|
||||
iq_pubsub(Host, Pubsub_Host, {U,S,R}, IQ#iq.type,
|
||||
_Rsm = lists:member(?NS_RSM, Plugin:features()),
|
||||
xml:remove_cdata(IQ#iq.sub_el#xmlel.children),
|
||||
IQ#iq.lang, Capabilities)
|
||||
of
|
||||
{result, []} ->
|
||||
ejabberd_router:route(Pubsub_Component, Entity,
|
||||
jlib:iq_to_xml(IQ#iq{
|
||||
type = result,
|
||||
sub_el = []
|
||||
}));
|
||||
{result, Xmlels} ->
|
||||
ejabberd_router:route(Pubsub_Component, Entity,
|
||||
jlib:iq_to_xml(IQ#iq{
|
||||
type = result,
|
||||
sub_el = Xmlels
|
||||
}));
|
||||
{error, Error} ->
|
||||
ejabberd_router:route(Pubsub_Component, Entity,
|
||||
jlib:make_error_reply(Stanza_IQ, Error))
|
||||
end
|
||||
end;
|
||||
do_route(Host,
|
||||
#jid{lserver = Pubsub_Host} = Pubsub_Component,
|
||||
#jid{luser = U, lserver = S, lresource = R} = Entity, Stanza_Message,
|
||||
Capabilities)
|
||||
when ?Is_Stanza_Message(Stanza_Message) ->
|
||||
ok;
|
||||
do_route(Host,
|
||||
#jid{lserver = Pubsub_Host} = Pubsub_Component,
|
||||
#jid{luser = U, lserver = S, lresource = R} = Entity, Stanza_Presence,
|
||||
Capabilities)
|
||||
when ?Is_Stanza_Presence(Stanza_Presence) ->
|
||||
ok.
|
||||
|
||||
|
||||
iq_pubsub(Host, Pubsub_Host, Entity, IQ_Type, Rsm, Xmlels, _Lang,
|
||||
#capabilities{api = #api{parser = Parser, core = API_Core}} = Capabilities) ->
|
||||
case Parser:parse(IQ_Type, Xmlels, Rsm, API_Core) of
|
||||
{result, Module, Function, Parameters} ->
|
||||
Module:Function(Host, Pubsub_Host, Entity, Parameters, Capabilities);
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
|
||||
|
||||
register_hooks(Host, Pubsub_Features, Module) ->
|
||||
register_hooks('roster', Host, Pubsub_Features, Module),
|
||||
register_hooks('presence', Host, Pubsub_Features, Module).
|
||||
|
||||
%ejabberd_hooks:add(roster_in_subscription, Host, pubsub_hooks, roster_in_subscription, 50),
|
||||
%ejabberd_hooks:add(roster_out_subscription, Host, ?MODULE, roster_out_subscription, 50),
|
||||
%ejabberd_hooks:add(roster_get, Host, ?MODULE, roster_get, 50),
|
||||
%ejabberd_hooks:add(roster_get_jid_info, Host, ?MODULE, roster_get_jid_info, 50),
|
||||
%ejabberd_hooks:add(roster_get_subscription_lists, Host, ?MODULE, roster_get_subscription_lists, 50),
|
||||
%%ejabberd_hooks:add(roster_process_item, Host, pubsub_hooks, roster_process_item, 50).
|
||||
|
||||
|
||||
register_hooks('roster', Host, Pubsub_Features, Module) ->
|
||||
case lists:member("access-roster", Pubsub_Features) of
|
||||
true ->
|
||||
ejabberd_hooks:add(roster_process_item, Host, Module,
|
||||
roster_process_item, 50),
|
||||
ok;
|
||||
false ->
|
||||
ok
|
||||
end;
|
||||
%%
|
||||
register_hooks('presence', Host, Pubsub_Features, Module) ->
|
||||
case
|
||||
lists:member(<<"access-presence">>, Pubsub_Features)
|
||||
orelse
|
||||
lists:member(<<"last-published">>, Pubsub_Features)
|
||||
orelse
|
||||
lists:member(<<"leased-subscription">>, Pubsub_Features)
|
||||
orelse
|
||||
lists:member(<<"presence-notifications">>, Pubsub_Features)
|
||||
of
|
||||
true ->
|
||||
ejabberd_hooks:add(presence_probe_hook, Host, Module,
|
||||
presence_online, 80),
|
||||
ejabberd_hooks:add(sm_remove_connection_hook, Host, Module,
|
||||
presence_offline, 80),
|
||||
ok;
|
||||
false ->
|
||||
ok
|
||||
end.
|
||||
|
||||
|
||||
roster_get(Acc, {User, Server}) ->
|
||||
?INFO_MSG("ROSTER_GET Acc ~p ~nUser ~p ~nServer ~p ~n",
|
||||
[Acc, User, Server]).
|
||||
|
||||
roster_get_jid_info(Acc, User, Server, JID) ->
|
||||
?INFO_MSG("ROSTER_GET_JID_INFO Acc ~p ~nUser ~p ~nServer ~p ~nJID ~p ~n",
|
||||
[Acc, User, Server, JID]).
|
||||
|
||||
roster_get_subscription_lists(Acc, User, Server) ->
|
||||
?INFO_MSG("ROSTER_GET_SUBSCRIPTION_LISTS Acc ~p ~nUser ~p ~nServer ~p ~n",
|
||||
[Acc, User, Server]).
|
||||
|
||||
roster_in_subscription(User, Server, JID, SubscriptionType, Reason, A) ->
|
||||
?INFO_MSG("ROSTER_IN_SUBSCRITION User ~p ~n Server ~p ~n JID ~p ~n SubscriptionType ~p ~n, Reason ~p ~nA ~p ~n",
|
||||
[User, Server, JID, SubscriptionType, Reason, A]).
|
||||
|
||||
roster_out_subscription(User, Server, JID, SubscriptionType) ->
|
||||
?INFO_MSG("ROSTER_OUT_SUBSCRITION User ~p ~n Server ~p ~n JID ~p ~n SubscriptionType ~p ~n",
|
||||
[User, Server, JID, SubscriptionType]).
|
||||
|
||||
roster_process_item(RosterItem, Server) ->
|
||||
?INFO_MSG("ROSTER_PROCESS_ITEM RosterItem ~p ~nServer ~p ~n",
|
||||
[RosterItem, Server]),
|
||||
RosterItem.
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
%%% ====================================================================
|
||||
%%% ``The contents of this file are subject to the Erlang Public License,
|
||||
%%% Version 1.1, (the "License"); you may not use this file except in
|
||||
%%% compliance with the License. You should have received a copy of the
|
||||
%%% Erlang Public License along with this software. If not, it can be
|
||||
%%% retrieved via the world wide web at http://www.erlang.org/.
|
||||
%%%
|
||||
%%% Software distributed under the License is distributed on an "AS IS"
|
||||
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%%% the License for the specific language governing rights and limitations
|
||||
%%% under the License.
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2013, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2013, ProcessOne.
|
||||
%%%
|
||||
%%% @copyright 2006-2013 ProcessOne
|
||||
%%% @author Karim Gemayel <karim.gemayel@process-one.net>
|
||||
%%% [http://www.process-one.net/]
|
||||
%%% @version {@vsn}, {@date} {@time}
|
||||
%%% @end
|
||||
%%% ====================================================================
|
||||
|
||||
%%% @headerfile "pubsub_dev.hrl"
|
||||
|
||||
-module(node_flat_dev).
|
||||
-author('karim.gemayel@process-one.net').
|
||||
|
||||
-include("pubsub_dev.hrl").
|
||||
-include("pubsub_api.hrl").
|
||||
|
||||
-compile(export_all).
|
||||
|
||||
|
||||
|
||||
%%
|
||||
-spec(capabilities/0 :: () -> #capabilities{}).
|
||||
|
||||
capabilities() ->
|
||||
#capabilities{plugin = ?MODULE}.
|
||||
|
||||
|
||||
%%
|
||||
-spec(pubsub_features/0 :: () -> Pubsub_Features::exmpp_pubsub:pubsub_features()).
|
||||
|
||||
pubsub_features() ->
|
||||
[<<"access-authorize">>,
|
||||
<<"access-open">>,
|
||||
<<"access-presence">>,
|
||||
<<"access-roster">>,
|
||||
<<"access-whitelist">>,
|
||||
<<"auto-create">>,
|
||||
<<"auto-subscribe">>,
|
||||
%<<"collections">>,
|
||||
<<"config-node">>,
|
||||
<<"create-and-configure">>,
|
||||
<<"create-nodes">>,
|
||||
<<"delete-items">>,
|
||||
<<"delete-nodes">>,
|
||||
%<<"filtered-notifications">>,
|
||||
<<"get-pending">>,
|
||||
<<"instant-nodes">>,
|
||||
<<"item-ids">>,
|
||||
<<"last-published">>,
|
||||
<<"leased-subscription">>,
|
||||
<<"manage-subscriptions">>,
|
||||
<<"member-affiliation">>,
|
||||
<<"meta-data">>,
|
||||
<<"modify-affiliations">>,
|
||||
%<<"multi-collections">>,
|
||||
<<"multi-subscribe">>,
|
||||
<<"outcast-affiliation">>,
|
||||
<<"persistent-items">>,
|
||||
<<"presence-notifications">>,
|
||||
%"presence-subscribe">>,
|
||||
<<"publish">>,
|
||||
<<"publish-only-affiliation">>,
|
||||
<<"publish-options">>,
|
||||
<<"publisher-affiliation">>,
|
||||
<<"purge-nodes">>,
|
||||
<<"retract-items">>,
|
||||
<<"retrieve-affiliations">>,
|
||||
<<"retrieve-default">>,
|
||||
<<"retrieve-default-sub">>,
|
||||
<<"retrieve-items">>,
|
||||
<<"retrieve-subscriptions">>,
|
||||
<<"subscribe">>,
|
||||
<<"subscription-notifications">>,
|
||||
<<"subscription-options">>].
|
||||
|
||||
%%
|
||||
-spec(pubsub_features/1 ::
|
||||
(
|
||||
Entity_Type :: 'local' | 'remote')
|
||||
-> Pubsub_Features::exmpp_pubsub:pubsub_features()
|
||||
).
|
||||
|
||||
pubsub_features('local') ->
|
||||
[<<"access-authorize">>,
|
||||
<<"access-open">>,
|
||||
<<"access-presence">>,
|
||||
<<"access-roster">>,
|
||||
<<"access-whitelist">>,
|
||||
<<"auto-create">>,
|
||||
<<"auto-subscribe">>,
|
||||
%<<"collections">>,
|
||||
<<"config-node">>,
|
||||
<<"create-and-configure">>,
|
||||
<<"create-nodes">>,
|
||||
<<"delete-items">>,
|
||||
<<"delete-nodes">>,
|
||||
%<<"filtered-notifications">>,
|
||||
<<"get-pending">>,
|
||||
<<"instant-nodes">>,
|
||||
<<"item-ids">>,
|
||||
<<"last-published">>,
|
||||
<<"leased-subscription">>,
|
||||
<<"manage-subscriptions">>,
|
||||
<<"member-affiliation">>,
|
||||
<<"meta-data">>,
|
||||
<<"modify-affiliations">>,
|
||||
%<<"multi-collections">>,
|
||||
<<"multi-subscribe">>,
|
||||
<<"outcast-affiliation">>,
|
||||
<<"persistent-items">>,
|
||||
<<"presence-notifications">>,
|
||||
%<<"presence-subscribe">>,
|
||||
<<"publish">>,
|
||||
<<"publish-only-affiliation">>,
|
||||
<<"publish-options">>,
|
||||
<<"publisher-affiliation">>,
|
||||
<<"purge-nodes">>,
|
||||
<<"retract-items">>,
|
||||
<<"retrieve-affiliations">>,
|
||||
<<"retrieve-default">>,
|
||||
<<"retrieve-default-sub">>,
|
||||
<<"retrieve-items">>,
|
||||
<<"retrieve-subscriptions">>,
|
||||
<<"subscribe">>,
|
||||
<<"subscription-notifications">>,
|
||||
<<"subscription-options">>];
|
||||
%%
|
||||
pubsub_features('remote') ->
|
||||
[<<"access-authorize">>,
|
||||
<<"access-open">>,
|
||||
<<"access-presence">>,
|
||||
<<"access-roster">>,
|
||||
<<"access-whitelist">>,
|
||||
<<"auto-create">>,
|
||||
<<"auto-subscribe">>,
|
||||
%<<"collections">>,
|
||||
<<"config-node">>,
|
||||
<<"create-and-configure">>,
|
||||
<<"create-nodes">>,
|
||||
<<"delete-items">>,
|
||||
<<"delete-nodes">>,
|
||||
%<<"filtered-notifications">>,
|
||||
<<"get-pending">>,
|
||||
<<"instant-nodes">>,
|
||||
<<"item-ids">>,
|
||||
<<"last-published">>,
|
||||
%<<"leased-subscription">>,
|
||||
<<"manage-subscriptions">>,
|
||||
<<"member-affiliation">>,
|
||||
<<"meta-data">>,
|
||||
<<"modify-affiliations">>,
|
||||
%<<"multi-collections">>,
|
||||
<<"multi-subscribe">>,
|
||||
<<"outcast-affiliation">>,
|
||||
<<"persistent-items">>,
|
||||
<<"publish">>,
|
||||
<<"publish-only-affiliation">>,
|
||||
<<"publish-options">>,
|
||||
<<"publisher-affiliation">>,
|
||||
<<"purge-nodes">>,
|
||||
<<"retract-items">>,
|
||||
<<"retrieve-affiliations">>,
|
||||
<<"retrieve-default">>,
|
||||
<<"retrieve-default-sub">>,
|
||||
<<"retrieve-items">>,
|
||||
<<"retrieve-subscriptions">>,
|
||||
<<"subscribe">>,
|
||||
<<"subscription-notifications">>,
|
||||
<<"subscription-options">>].
|
||||
|
||||
%%
|
||||
%%
|
||||
-spec(node_options/1 ::
|
||||
(
|
||||
Node_Type :: 'leaf' | 'collection')
|
||||
-> Node_Options :: pubsub_options:options_node_leaf()
|
||||
| pubsub_options:options_node_collection()
|
||||
).
|
||||
|
||||
node_options('leaf') ->
|
||||
[{'access_model', open},
|
||||
{'contact', []},
|
||||
%{'collection', []},
|
||||
{'deliver_notifications', true},
|
||||
{'deliver_payloads', true},
|
||||
{'description', undefined},
|
||||
{'item_expire', undefined},
|
||||
{'itemreply', publisher},
|
||||
{'language', <<"en">>},
|
||||
{'max_items', 2},
|
||||
{'max_payload_size', undefined},
|
||||
{'node_type', leaf},
|
||||
{'notification_type', normal},
|
||||
{'notify_config', true},
|
||||
{'notify_delete', true},
|
||||
{'notify_retract', true},
|
||||
{'notify_sub', true},
|
||||
{'persist_items', true},
|
||||
{'presence_based_delivery', true},
|
||||
{'publish_model', open},
|
||||
{'purge_offline', false},
|
||||
{'roster_groups_allowed', []},
|
||||
{'send_last_published_item', on_sub_and_presence},
|
||||
{'subscribe', true},
|
||||
{'tempsub', false},
|
||||
{'title', undefined},
|
||||
{'type', undefined}];
|
||||
%%
|
||||
node_options('collection') ->
|
||||
[].
|
||||
|
||||
item_options() ->
|
||||
[{'access_model', open},
|
||||
{'deliver_notifications', true},
|
||||
{'deliver_payloads', true},
|
||||
{'item_expire', undefined},
|
||||
{'itemreply', publisher},
|
||||
% {'max_payload_size', undefined},
|
||||
{'notification_type', normal},
|
||||
{'notify_config', true},
|
||||
{'notify_retract', true},
|
||||
{'persist_items', true},
|
||||
{'presence_based_delivery', true},
|
||||
% {'publish_model', open},
|
||||
{'purge_offline', false},
|
||||
{'roster_groups_allowed', []},
|
||||
{'send_last_published_item', on_sub_and_presence},
|
||||
{'type', undefined}].
|
||||
|
||||
%%
|
||||
-spec(subscription_options/2 ::
|
||||
(
|
||||
Entity_Type :: 'local' | 'remote',
|
||||
Node_Type :: 'leaf' | 'collection')
|
||||
-> Subscription_Options :: [] | pubsub_options:options_subscription()
|
||||
).
|
||||
|
||||
subscription_options('local', 'leaf') ->
|
||||
[];
|
||||
subscription_options('remote', 'leaf') ->
|
||||
[];
|
||||
subscription_options('local', 'collection') ->
|
||||
[];
|
||||
subscription_options('remote', 'collection') ->
|
||||
[].
|
||||
|
||||
%%
|
||||
-spec(default_subscription_options/2 ::
|
||||
(
|
||||
Entity_Type :: 'local' | 'remote',
|
||||
Node_Type :: 'leaf')%| 'collection')
|
||||
-> Subscription_Options :: pubsub_options:options_subscription_leaf()
|
||||
).
|
||||
|
||||
default_subscription_options('local', 'leaf') ->
|
||||
[{'deliver', true},
|
||||
{'expire', undefined},
|
||||
%{'include_body', undefined},
|
||||
{'show-values', ['away', 'chat', 'dnd', 'online', 'xa']}];
|
||||
%%
|
||||
default_subscription_options('remote', 'leaf') ->
|
||||
[{'deliver', true}
|
||||
%{'include_body', undefined}
|
||||
].
|
||||
%%
|
||||
%%default_subscription_options('local', 'collection') ->
|
||||
%% [{'deliver', true},
|
||||
%% %{'expire', undefined},
|
||||
%% %{'include_body', undefined},
|
||||
%% {'show-values', ['away', 'chat', 'dnd', 'online', 'xa']},
|
||||
%% {'subscription_type', 'all'},
|
||||
%% {'subscription_depth', 1}];
|
||||
%%
|
||||
%%default_subscription_options('remote', 'collection') ->
|
||||
%% [{'deliver', true},
|
||||
%% %{'include_body', undefined},
|
||||
%% {'show-values', ['away', 'chat', 'dnd', 'online', 'xa']},
|
||||
%% {'subscription_type', 'all'},
|
||||
%% {'subscription_depth', 1}].
|
||||
|
||||
%%
|
||||
-spec(features/0 :: () -> Features::exmpp_pubsub:features()).
|
||||
|
||||
features() ->
|
||||
[%?NS_ADDRESS,
|
||||
?NS_DISCO_INFO,
|
||||
?NS_DISCO_ITEMS,
|
||||
%?NS_RSM,
|
||||
?NS_VCARD].
|
||||
|
||||
%%
|
||||
identity() ->
|
||||
[{<<"pubsub">>, <<"Publish-Subscribe">>, <<"service">>},
|
||||
{<<"pubsub">>, <<"ejabberd/mod_pubsub/flat">>, <<"service">>}].
|
||||
@@ -0,0 +1,101 @@
|
||||
%% API function definition
|
||||
|
||||
-record(api_core,
|
||||
{
|
||||
create_node = 'pubsub_core' :: module(),
|
||||
delete_node = 'pubsub_core' :: module(),
|
||||
purge_node = 'pubsub_core' :: module(),
|
||||
get_configure_node = 'pubsub_core' :: module(),
|
||||
get_configure_node_default = 'pubsub_core' :: module(),
|
||||
%%
|
||||
publish_item = 'pubsub_core' :: module(),
|
||||
retract_item = 'pubsub_core' :: module(),
|
||||
%%
|
||||
subscribe_node = 'pubsub_core' :: module(),
|
||||
unsubscribe_node = 'pubsub_core' :: module(),
|
||||
set_configure_subscription = 'pubsub_core' :: module(),
|
||||
get_configure_subscription = 'pubsub_core' :: module(),
|
||||
get_configure_subscription_default = 'pubsub_core' :: module(),
|
||||
get_items = 'pubsub_core' :: module(),
|
||||
%%
|
||||
get_entity_affiliations = 'pubsub_core' :: module(),
|
||||
get_entity_subscriptions = 'pubsub_core' :: module(),
|
||||
%%
|
||||
get_node_affiliations = 'pubsub_core' :: module(),
|
||||
get_node_subscriptions = 'pubsub_core' :: module()
|
||||
}).
|
||||
|
||||
-record(api_db,
|
||||
{
|
||||
create_node = 'pubsub_db' :: module(),
|
||||
delete_node = 'pubsub_db' :: module(),
|
||||
purge_node = 'pubsub_db' :: module(),
|
||||
get_configure_node = 'pubsub_db' :: module(),
|
||||
%get_configure_node_default = 'pubsub_db' :: module(),
|
||||
%%
|
||||
publish_item = 'pubsub_db' :: module(),
|
||||
retract_item = 'pubsub_db' :: module(),
|
||||
%%
|
||||
subscribe_node = 'pubsub_db' :: module(),
|
||||
unsubscribe_node = 'pubsub_db' :: module(),
|
||||
set_configure_subscription = 'pubsub_db' :: module(),
|
||||
get_configure_subscription = 'pubsub_db' :: module(),
|
||||
get_configure_subscription_default = 'pubsub_db' :: module(),
|
||||
get_items = 'pubsub_db' :: module(),
|
||||
%%
|
||||
get_entity_affiliations = 'pubsub_db' :: module(),
|
||||
get_entity_subscriptions = 'pubsub_db' :: module(),
|
||||
%%
|
||||
get_node_affiliations = 'pubsub_db' :: module(),
|
||||
get_node_subscriptions = 'pubsub_db' :: module()
|
||||
}).
|
||||
|
||||
-record(api_broadcast,
|
||||
{
|
||||
broadcast_publish = 'pubsub_broadcast' :: module(),
|
||||
broadcast_publish_last = 'pubsub_broadcast' :: module(),
|
||||
notify_create = 'pubsub_broadcast' :: module(),
|
||||
notify_delete = 'pubsub_broadcast' :: module(),
|
||||
notify_publish = 'pubsub_broadcast' :: module(),
|
||||
notify_purge = 'pubsub_broadcast' :: module(),
|
||||
notify_retract = 'pubsub_broadcast' :: module(),
|
||||
notify_subscription = 'pubsub_broadcast' :: module(),
|
||||
notify_subscriptions = 'pubsub_broadcast' :: module()
|
||||
}).
|
||||
|
||||
-record(api,
|
||||
{
|
||||
core = #api_core{} :: #api_core{},
|
||||
db = #api_db{} :: #api_db{},
|
||||
broadcast = #api_broadcast{} :: #api_broadcast{},
|
||||
parser = 'pubsub_parser' :: module(),
|
||||
options = 'pubsub_options' :: module()
|
||||
}).
|
||||
|
||||
-record(capabilities,
|
||||
{
|
||||
plugin :: exmpp_pubsub:plugin(),
|
||||
privacy = false :: boolean(),
|
||||
api = #api{} :: #api{}
|
||||
}).
|
||||
|
||||
-record(api2,
|
||||
{
|
||||
func,
|
||||
core :: 'core',
|
||||
db :: 'db',
|
||||
bkd :: 'mnesia',
|
||||
rtr :: 'router'
|
||||
}).
|
||||
|
||||
-record(mod_pubsub,
|
||||
{
|
||||
server,
|
||||
component,
|
||||
plugin,
|
||||
entity,
|
||||
parameters,
|
||||
features,
|
||||
parser,
|
||||
options
|
||||
}).
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,147 @@
|
||||
|
||||
|
||||
%-include_lib("exmpp/include/exmpp.hrl").
|
||||
%-include_lib("exmpp/include/exmpp_jid.hrl").
|
||||
-include("logger.hrl").
|
||||
-include("ejabberd.hrl").
|
||||
-include("mod_roster.hrl").
|
||||
-include("jlib.hrl").
|
||||
%-include("pubsub_api.hrl").
|
||||
|
||||
-define(NS_JABBER_CLIENT, <<"jabber:client">>).
|
||||
|
||||
%%
|
||||
%% Pubsub Node
|
||||
-record(pubsub_node_dev,
|
||||
{
|
||||
id ,%:: {Pubsub_Host :: exmpp_pubsub:host(),
|
||||
% NodeId :: undefined | exmpp_pubsub:nodeId()},
|
||||
idx ,%:: exmpp_pubsub:nodeIdx(),
|
||||
creation ,%:: {DateTime::erlang:timestamp(), Entity::xmpp_jid:usr_entity()},
|
||||
level = 0 ,%:: exmpp_pubsub:level(),
|
||||
owners = [] ,%:: [Owner::xmpp_jid:usr_bare(),...],
|
||||
itemids = [] ,%:: [ItemId::exmpp_pubsub:itemId()],
|
||||
options = [] %:: pubsub_options:options_node()
|
||||
}).
|
||||
|
||||
%%
|
||||
%% Pubsub State
|
||||
-record(pubsub_state_dev,
|
||||
{
|
||||
id ,%:: {Entity :: xmpp_jid:usr_bare(),
|
||||
% NodeIdx :: exmpp_pubsub:nodeIdx()},
|
||||
nodeidx ,%:: exmpp_pubsub:nodeIdx(),
|
||||
affiliation = 'none' ,%:: exmpp_pubsub:affiliation(),
|
||||
access ,%:: pubsub_options:access_model(),
|
||||
subscriptions = [] ,%:: [] | exmpp_pubsub:subscriptions(),
|
||||
%groups = [] ,%:: [Roster_Group::binary()],
|
||||
itemids = [] %:: [ItemId::exmpp_pubsub:itemId()]
|
||||
}).
|
||||
|
||||
%%
|
||||
%% Pubsub Item
|
||||
-record(pubsub_item_dev,
|
||||
{
|
||||
id ,%:: {ItemId::exmpp_pubsub:itemId(), NodeIdx::exmpp_pubsub:nodeIdx()},
|
||||
nodeidx ,%:: exmpp_pubsub:nodeIdx(),
|
||||
owners = [] ,%:: [Owner::xmpp_jid:usr_bare(),...],
|
||||
creation ,%:: {DateTime::erlang:timestamp(), Entity::xmpp_jid:usr_entity()},
|
||||
modification ,%:: {DateTime::erlang:timestamp(), Entity::xmpp_jid:usr_entity()},
|
||||
payload ,%:: exmpp_pubsub:payload(),
|
||||
options = [] %:: [] | pubsub_options:options_item()
|
||||
}).
|
||||
|
||||
%%
|
||||
%% Pubsub Last Item
|
||||
-record(pubsub_last_item_dev,
|
||||
{
|
||||
nodeidx ,%:: exmpp_pubsub:nodeIdx(),
|
||||
id ,%:: exmpp_pubsub:itemId(),
|
||||
owners = [] ,%:: [Owner::xmpp_jid:usr_bare(),...],
|
||||
creation ,%:: {DateTime::erlang:timestamp(), Entity::xmpp_jid:usr_entity()},
|
||||
payload ,%:: exmpp_pubsub:payload(),
|
||||
options = [] %:: [] | pubsub_options:options_item()
|
||||
}).
|
||||
|
||||
%%
|
||||
%% Pubsub Index
|
||||
-record(pubsub_index_dev,
|
||||
{
|
||||
index :: exmpp_pubsub:index(),
|
||||
last :: exmpp_pubsub:nodeIdx(),
|
||||
free :: [exmpp_pubsub:nodeIdx()]
|
||||
}).
|
||||
|
||||
%%
|
||||
%% Pubsub_Subscription_Pending
|
||||
-record(pubsub_subscription_pending,
|
||||
{
|
||||
id ,%:: {Entity::xmpp_jid:usr_bare(), NodeIdx::exmpp_pubsub:nodeIdx()}
|
||||
nodeidx ,%:: exmpp_pubsub:nodeIdx()
|
||||
subids %:: [SubId::exmpp_pubsub:subId(),...]
|
||||
}).
|
||||
|
||||
|
||||
|
||||
%%
|
||||
%% Internal data structures
|
||||
%%
|
||||
-record(entity,
|
||||
{
|
||||
id :: xmpp_jid:usr_bare(),
|
||||
local :: boolean(),
|
||||
affiliation :: 'member' | 'owner' | 'publisher',
|
||||
subscriptions :: []%[exmpp_pubsub:subscription(),...]
|
||||
}).
|
||||
|
||||
%%
|
||||
-record(node,
|
||||
{
|
||||
id :: exmpp_pubsub:nodeId(),
|
||||
owners :: [Node_Owner::xmpp_jid:usr_bare(),...],
|
||||
access_model :: pubsub_options:access_model(),
|
||||
% itemreply :: 'owner' | 'publisher',
|
||||
% notification_type :: 'headline' | 'normal',
|
||||
% presence_based_delivery :: boolean(),
|
||||
rosters_groups_allowed = [] :: [] | pubsub_options:rosters_groups_allowed()
|
||||
}).
|
||||
|
||||
%%
|
||||
-record(item,
|
||||
{
|
||||
access_model ,%:: undefined | pubsub_options:access_model(),
|
||||
presence_based_delivery ,%:: undefined | boolean(),
|
||||
rosters_groups_allowed = [],%:: [] | pubsub_options:rosters_groups_allowed()
|
||||
stanza %::#xmlel{}
|
||||
}).
|
||||
|
||||
%%
|
||||
-record(cache,
|
||||
{
|
||||
%% Entity is online
|
||||
presence :: undefined | mod_pubsub_dev:presence_cache(),
|
||||
%% Entity has presence subscriptions with at least one node owner
|
||||
presence_subscriptions :: undefined | boolean(),
|
||||
%% Entity has presence subscriptions with at least one node owner
|
||||
%% and is contained in at least one roster group from the node owner
|
||||
rosters_groups :: undefined | boolean() %% TODO : use a list
|
||||
}).
|
||||
|
||||
%%
|
||||
-record(subids,
|
||||
{
|
||||
presence = undefined :: undefined | [] | mod_pubsub_dev:resources_subids(),
|
||||
no_presence = undefined :: undefined | [] | mod_pubsub_dev:resources_subids()
|
||||
}).
|
||||
|
||||
%%
|
||||
-record(event,
|
||||
{
|
||||
host :: xmpp_jid:raw_jid_component_bare(),
|
||||
component :: xmpp_jid:component_bare(),
|
||||
entity :: mod_pubsub_dev:entity(),
|
||||
node :: mod_pubsub_dev:n0de(),
|
||||
cache :: mod_pubsub_dev:cache(),
|
||||
subids :: mod_pubsub_dev:subids()
|
||||
}).
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,904 @@
|
||||
%%% ====================================================================
|
||||
%%% ``The contents of this file are subject to the Erlang Public License,
|
||||
%%% Version 1.1, (the "License"); you may not use this file except in
|
||||
%%% compliance with the License. You should have received a copy of the
|
||||
%%% Erlang Public License along with this software. If not, it can be
|
||||
%%% retrieved via the world wide web at http://www.erlang.org/.
|
||||
%%%
|
||||
%%% Software distributed under the License is distributed on an "AS IS"
|
||||
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%%% the License for the specific language governing rights and limitations
|
||||
%%% under the License.
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2013, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2013, ProcessOne.
|
||||
%%%
|
||||
%%% @copyright 2006-2013 ProcessOne
|
||||
%%% @author Karim Gemayel <karim.gemayel@process-one.net>
|
||||
%%% [http://www.process-one.net/]
|
||||
%%% @version {@vsn}, {@date} {@time}
|
||||
%%% @end
|
||||
%%% ====================================================================
|
||||
|
||||
%%% @headerfile "pubsub_dev.hrl"
|
||||
|
||||
-module(pubsub_groups).
|
||||
-author('karim.gemayel@process-one.net').
|
||||
|
||||
-compile(export_all).
|
||||
|
||||
-include("pubsub_dev.hrl").
|
||||
|
||||
-import(pubsub_tools,
|
||||
[
|
||||
get_option/2,
|
||||
get_option/3,
|
||||
get_value/2,
|
||||
get_value/3,
|
||||
set_value/3,
|
||||
%%
|
||||
check_acces_model/3,
|
||||
check_acces_model/7,
|
||||
check_publish_model/3,
|
||||
get_entity_roster/1,
|
||||
is_contact_subscribed_to_node_owners/3,
|
||||
is_contact_in_allowed_roster_groups/2,
|
||||
has_subscriptions/1,
|
||||
get_resources/2,
|
||||
get_resources_show/2,
|
||||
rosters_groups_allowed_cache/2
|
||||
]).
|
||||
|
||||
-import(pubsub_db_mnesia,
|
||||
[
|
||||
table/2
|
||||
]).
|
||||
|
||||
|
||||
-type(group() :: binary()).
|
||||
|
||||
-type(node_group() :: group()).
|
||||
|
||||
-type(roster_group() :: group()).
|
||||
|
||||
-type(node_groups() :: [Node_Group::node_group(),...]).
|
||||
|
||||
-type(roster_groups() :: [Roster_Group::roster_group(),...]).
|
||||
|
||||
-type(nodeIdxs() :: [NodeIdx::exmpp_pubsub:nodeIdx(),...]).
|
||||
|
||||
-type(n0de()
|
||||
:: {NodeIdx :: exmpp_pubsub:nodeIdx(),
|
||||
Groups :: node_groups()}
|
||||
).
|
||||
|
||||
-type(n0des() :: [Node::n0de(),...]).
|
||||
|
||||
%% -type(subscription()
|
||||
%% :: {NodeIdx :: exmpp_pubsub:nodeIdx(),
|
||||
%% Groups :: roster_groups()}
|
||||
%% ).
|
||||
|
||||
-type(subscriptions() :: [Subscription::subscription(),...]).
|
||||
|
||||
-type(contact()
|
||||
:: {Entity :: xmpp_jid:usr_bare(),
|
||||
Subscriptions :: subscriptions()}
|
||||
).
|
||||
|
||||
-type(contacts() :: [Contact::contact(),...]).
|
||||
|
||||
|
||||
-record(pubsub_groups,
|
||||
{
|
||||
owner :: xmpp_jid:usr_bare(),
|
||||
nodes = [] :: n0des(),
|
||||
contacts = [] :: [] | contacts()
|
||||
}).
|
||||
|
||||
|
||||
create_table_pubsub_groups(Suffix) ->
|
||||
mnesia:create_table(table('pubsub_groups', Suffix),
|
||||
[{type, set},
|
||||
{disc_copies, [node()]},
|
||||
{record_name, pubsub_groups},
|
||||
{attributes, record_info(fields, pubsub_groups)}]).
|
||||
|
||||
|
||||
|
||||
%%
|
||||
-spec(register_groups/4 ::
|
||||
(
|
||||
Suffix :: atom(),
|
||||
NodeIdx :: exmpp_pubsub:nodeIdx(),
|
||||
Owner :: xmpp_jid:usr_bare(),
|
||||
Groups :: [] | node_groups())
|
||||
-> undefined
|
||||
%
|
||||
| {Subscribers :: [Entity::xmpp_jid:usr_bare()],
|
||||
Unsubscribers :: [Entity::xmpp_jid:usr_bare()]}
|
||||
).
|
||||
|
||||
register_groups(Suffix, NodeIdx, Owner, [] = _Groups) ->
|
||||
case
|
||||
mnesia:read(Table_Pubsub_Groups = table('pubsub_groups', 'dev'),
|
||||
Owner, write)
|
||||
of
|
||||
%%
|
||||
[] ->
|
||||
undefined;
|
||||
%%
|
||||
[#pubsub_groups{nodes = [{NodeIdx, _Node_Groups}]} = Pubsub_Groups] ->
|
||||
mnesia:delete_object(Table_Pubsub_Groups, Pubsub_Groups, write),
|
||||
%
|
||||
{_Subscribers = [],
|
||||
_Unsubscribers = lists:foldl(fun
|
||||
({Entity, Subscriptions}, Unsubscribers) ->
|
||||
case lists:keymember(NodeIdx, 1, Subscriptions) of
|
||||
true -> [Entity | Unsubscribers];
|
||||
false -> Unsubscribers
|
||||
end
|
||||
%
|
||||
end, [], Pubsub_Groups#pubsub_groups.contacts)};
|
||||
%%
|
||||
[Pubsub_Groups] ->
|
||||
case lists:keyfind(NodeIdx, 1, Pubsub_Groups#pubsub_groups.nodes) of
|
||||
{_NodeIdx, Node_Groups} ->
|
||||
{Contacts, Unsubscribers} = subscriptions1(NodeIdx,
|
||||
Pubsub_Groups#pubsub_groups.contacts),
|
||||
%
|
||||
mnesia:write(Table_Pubsub_Groups,
|
||||
Pubsub_Groups#pubsub_groups{
|
||||
contacts = Contacts
|
||||
},
|
||||
write),
|
||||
%
|
||||
{_Subscribers = [],
|
||||
_Unsubscribers = Unsubscribers};
|
||||
false ->
|
||||
undefined
|
||||
end
|
||||
end;
|
||||
%%
|
||||
register_groups(Suffix, NodeIdx, Owner, Groups) ->
|
||||
case
|
||||
mnesia:read(Table_Pubsub_Groups = table('pubsub_groups', 'dev'), Owner,
|
||||
write)
|
||||
of
|
||||
[] ->
|
||||
{Contacts, Subscribers} = subscriptions2(NodeIdx, Owner, Groups),
|
||||
%
|
||||
mnesia:write(Table_Pubsub_Groups,
|
||||
#pubsub_groups{
|
||||
owner = Owner,
|
||||
nodes = [{NodeIdx, Groups}],
|
||||
contacts = Contacts
|
||||
},
|
||||
write),
|
||||
%
|
||||
{_Subscribers = Subscribers,
|
||||
_Unsubscribers = []};
|
||||
[Pubsub_Groups] ->
|
||||
case lists:keyfind(NodeIdx, 1, Pubsub_Groups#pubsub_groups.nodes) of
|
||||
{_NodeIdx, Node_Groups} ->
|
||||
case diff_groups(Groups, Node_Groups) of
|
||||
%%
|
||||
{[] = _New_Groups, [] = _Old_Groups} ->
|
||||
{_Subscribers = [],
|
||||
_Unsubscribers = []};
|
||||
%%
|
||||
{[] = _New_Groups, Old_Groups} ->
|
||||
{Contacts, Unsubscribers}
|
||||
= subscriptions3(NodeIdx, Old_Groups,
|
||||
Pubsub_Groups#pubsub_groups.contacts),
|
||||
%
|
||||
mnesia:write(Table_Pubsub_Groups,
|
||||
Pubsub_Groups#pubsub_groups{
|
||||
nodes = lists:keyreplace(NodeIdx, 1,
|
||||
Pubsub_Groups#pubsub_groups.nodes,
|
||||
{NodeIdx, Groups}),
|
||||
contacts = Contacts
|
||||
},
|
||||
write),
|
||||
%
|
||||
{_Subscribers = [],
|
||||
_Unsubscribers = Unsubscribers};
|
||||
%%
|
||||
{_New_Groups, _Old_Groups} ->
|
||||
{Contacts, Subscribers, Unsubscribers}
|
||||
= subscriptions4(NodeIdx, Owner, Node_Groups,
|
||||
Pubsub_Groups#pubsub_groups.contacts),
|
||||
%
|
||||
mnesia:write(Table_Pubsub_Groups,
|
||||
Pubsub_Groups#pubsub_groups{
|
||||
nodes = lists:keyreplace(NodeIdx, 1,
|
||||
Pubsub_Groups#pubsub_groups.nodes,
|
||||
{NodeIdx, Node_Groups}),
|
||||
contacts = Contacts
|
||||
},
|
||||
write),
|
||||
%
|
||||
{Subscribers = Subscribers,
|
||||
_Unsubscribers = Unsubscribers}
|
||||
end;
|
||||
false ->
|
||||
{Contacts, Subscribers}
|
||||
= subscriptions5(NodeIdx, Owner, Groups,
|
||||
_Contacts = Pubsub_Groups#pubsub_groups.contacts),
|
||||
%
|
||||
mnesia:write(Table_Pubsub_Groups,
|
||||
Pubsub_Groups#pubsub_groups{
|
||||
nodes = [{NodeIdx, Groups}
|
||||
| Pubsub_Groups#pubsub_groups.nodes],
|
||||
contacts = Contacts
|
||||
},
|
||||
write),
|
||||
%
|
||||
{_Subscribers = Subscribers,
|
||||
_Unsubscribers = []}
|
||||
end
|
||||
end.
|
||||
|
||||
|
||||
%% TODO : fix this hook managment
|
||||
-spec(monitor_contacts/3 ::
|
||||
(
|
||||
_ :: 'subscribed',
|
||||
Entity :: xmpp_jid:usr_bare(),
|
||||
Jid_Contacts :: xmpp_jid:entity_bare())
|
||||
-> undefined
|
||||
%
|
||||
| {Server :: xmpp_jid:raw_jid_component_bare(),
|
||||
Entity :: xmpp_jid:usr_bare(),
|
||||
Contact :: xmpp_jid:usr_bare(),
|
||||
_ :: {'subscribed', NodeIdxs :: nodeIdxs()}}
|
||||
).
|
||||
|
||||
monitor_contacts('subscribed', {_, Server, _} = Entity, Jid_Contact) ->
|
||||
case roster_groups(Entity, Contact = jlid:jid_to_lower(Jid_Contact)) of
|
||||
[] ->
|
||||
undefined;
|
||||
Roster_Groups ->
|
||||
case
|
||||
mnesia:read(Table_Pubsub_Groups = table('pubsub_groups', dev),
|
||||
_Owner = Entity, write)
|
||||
of
|
||||
[] ->
|
||||
undefined;
|
||||
[Pubsub_Groups] ->
|
||||
case
|
||||
filter_subscriptions(Pubsub_Groups#pubsub_groups.nodes,
|
||||
Roster_Groups)
|
||||
of
|
||||
[] ->
|
||||
undefined;
|
||||
Subscriptions ->
|
||||
mnesia:write(Table_Pubsub_Groups,
|
||||
Pubsub_Groups#pubsub_groups{
|
||||
contacts = case
|
||||
lists:keyreplace(Contact, 1,
|
||||
Pubsub_Groups#pubsub_groups.contacts,
|
||||
{Contact, Subscriptions})
|
||||
of
|
||||
_Contacts
|
||||
when _Contacts ==
|
||||
Pubsub_Groups#pubsub_groups.contacts ->
|
||||
[{Contact, Subscriptions}
|
||||
| Pubsub_Groups#pubsub_groups.contacts];
|
||||
Contacts ->
|
||||
Contacts
|
||||
end
|
||||
},
|
||||
write),
|
||||
{Server, Entity, Contact,
|
||||
{'subscribed',
|
||||
_NodeIdx = lists:map(fun
|
||||
({NodeIdx, _Groups}) ->
|
||||
NodeIdx
|
||||
end, Subscriptions)}}
|
||||
end
|
||||
end
|
||||
end.
|
||||
|
||||
|
||||
%%
|
||||
-spec(monitor_groups/2 ::
|
||||
(
|
||||
Server :: xmpp_jid:raw_jid_component_bare(),
|
||||
Roster :: #roster{groups :: [] | roster_groups()})
|
||||
-> undefined
|
||||
%
|
||||
| {Server :: xmpp_jid:raw_jid_component_bare(),
|
||||
Entity :: xmpp_jid:usr_bare(),
|
||||
Diff_NodeIdxs :: {NodeIdxs_Subscriptions :: [] | nodeIdxs(),
|
||||
NodeIdxs_Unsubscriptions :: [] | nodeIdxs()}}
|
||||
).
|
||||
|
||||
monitor_groups(Server, #roster{us = {U,S}} = _Roster) ->
|
||||
case
|
||||
mnesia:read(Table_Pubsub_Groups = table('pubsub_groups', dev),
|
||||
_Owner = {U,S,undefined}, write)
|
||||
of
|
||||
[] ->
|
||||
undefined;
|
||||
[Pubsub_Groups] ->
|
||||
case
|
||||
lists:keyfind(_Roster#roster.jid, 1,
|
||||
Pubsub_Groups#pubsub_groups.contacts)
|
||||
of %%
|
||||
{_Entity, Old_Subscriptions}
|
||||
when _Roster#roster.subscription == 'delete'
|
||||
orelse _Roster#roster.subscription == 'none' ->
|
||||
mnesia:write(Table_Pubsub_Groups,
|
||||
Pubsub_Groups#pubsub_groups{
|
||||
contacts = lists:keydelete(_Roster#roster.jid, 1,
|
||||
Pubsub_Groups#pubsub_groups.contacts)
|
||||
},
|
||||
write),
|
||||
{Server,
|
||||
_Entity = _Roster#roster.jid,
|
||||
_Diff_NodeIdxs = diff_nodeidxs(_New_Subscriptions = [],
|
||||
Old_Subscriptions)};
|
||||
%%
|
||||
{_Entity, Old_Subscriptions}
|
||||
when (_Roster#roster.subscription == 'both'
|
||||
orelse
|
||||
_Roster#roster.subscription == 'from')
|
||||
andalso _Roster#roster.groups == [] ->
|
||||
mnesia:write(Table_Pubsub_Groups,
|
||||
Pubsub_Groups#pubsub_groups{
|
||||
contacts = lists:keydelete(_Roster#roster.jid, 1,
|
||||
Pubsub_Groups#pubsub_groups.contacts)
|
||||
},
|
||||
write),
|
||||
{Server,
|
||||
_Roster#roster.jid,
|
||||
_Diff_NodeIdxs = diff_nodeidxs(_New_Subscriptions = [],
|
||||
Old_Subscriptions)};
|
||||
%%
|
||||
{_Entity, Old_Subscriptions}
|
||||
when _Roster#roster.subscription == 'both'
|
||||
orelse _Roster#roster.subscription == 'from' ->
|
||||
case
|
||||
filter_subscriptions(Pubsub_Groups#pubsub_groups.nodes,
|
||||
_Roster#roster.groups)
|
||||
of
|
||||
[] ->
|
||||
mnesia:write(Table_Pubsub_Groups,
|
||||
Pubsub_Groups#pubsub_groups{
|
||||
contacts = lists:keydelete(_Roster#roster.jid,
|
||||
1, Pubsub_Groups#pubsub_groups.contacts)
|
||||
},
|
||||
write),
|
||||
{Server, _Roster#roster.jid,
|
||||
diff_nodeidxs(_New_Subscriptions = [],
|
||||
Old_Subscriptions)};
|
||||
New_Subscriptions ->
|
||||
mnesia:write(Table_Pubsub_Groups,
|
||||
Pubsub_Groups#pubsub_groups{
|
||||
contacts = lists:keyreplace(_Roster#roster.jid,
|
||||
1, Pubsub_Groups#pubsub_groups.contacts,
|
||||
{_Roster#roster.jid, New_Subscriptions})
|
||||
},
|
||||
write),
|
||||
{Server,
|
||||
_Entity = _Roster#roster.jid,
|
||||
_Diff_NodeIdxs = diff_nodeidxs(New_Subscriptions,
|
||||
Old_Subscriptions)}
|
||||
end;
|
||||
%%
|
||||
false
|
||||
when (_Roster#roster.subscription == 'both'
|
||||
orelse
|
||||
_Roster#roster.subscription == 'from')
|
||||
andalso _Roster#roster.groups =/= [] ->
|
||||
case
|
||||
filter_subscriptions(Pubsub_Groups#pubsub_groups.nodes,
|
||||
_Roster#roster.groups)
|
||||
of
|
||||
[] ->
|
||||
undefined;
|
||||
New_Subscriptions ->
|
||||
mnesia:write(Table_Pubsub_Groups,
|
||||
Pubsub_Groups#pubsub_groups{
|
||||
contacts = [{_Roster#roster.jid, New_Subscriptions}
|
||||
| Pubsub_Groups#pubsub_groups.contacts]
|
||||
},
|
||||
write),
|
||||
{Server,
|
||||
_Entity = _Roster#roster.jid,
|
||||
_Diff_NodeIdxs = diff_nodeidxs(New_Subscriptions,
|
||||
_Old_Subscriptions = [])}
|
||||
end;
|
||||
%%
|
||||
_ ->
|
||||
undefined
|
||||
end
|
||||
end.
|
||||
|
||||
|
||||
|
||||
%%
|
||||
%%
|
||||
-spec(subscriptions1/2 ::
|
||||
(
|
||||
NodeIdx :: exmpp_pubsub:nodeIdx(),
|
||||
Old_Contacts :: [] | contacts())
|
||||
-> Diff_Contacts :: {New_Contacts :: [] | contacts(),
|
||||
Unsubscribers :: [Entity::xmpp_jid:usr_bare()]}
|
||||
).
|
||||
|
||||
subscriptions1(NodeIdx, Contacts) ->
|
||||
_Diff_Contacts = subscriptions1(NodeIdx, _Old_Contacts = Contacts,
|
||||
{_New_Contacts = [], _Unsubscribers = []}).
|
||||
|
||||
|
||||
%%
|
||||
-spec(subscriptions1/3 ::
|
||||
(
|
||||
NodeIdx :: exmpp_pubsub:nodeIdx(),
|
||||
Old_Contacts :: [] | contacts(),
|
||||
Diff_Contacts :: {Contacts :: [] | contacts(),
|
||||
Unsubscribers :: [Entity::xmpp_jid:usr_bare()]})
|
||||
-> Diff_Contacts :: {New_Contacts :: [] | contacts(),
|
||||
Unsubscribers :: [Entity::xmpp_jid:usr_bare()]}
|
||||
).
|
||||
|
||||
subscriptions1(_NodeIdx, [] = _Old_Contacts, Diff_Contacts) ->
|
||||
Diff_Contacts;
|
||||
%%
|
||||
subscriptions1(NodeIdx, [{Entity, Subscriptions} | Old_Contacts],
|
||||
{Contacts, Unsubscribers}) ->
|
||||
subscriptions1(NodeIdx, Old_Contacts,
|
||||
_Diff_Contacts = case lists:keydelete(NodeIdx, 1, Subscriptions) of
|
||||
[] ->
|
||||
{_Contacts = Contacts,
|
||||
_Unsubscribers = [Entity | Unsubscribers]};
|
||||
Subscriptions ->
|
||||
{_Contacts = [{Entity, Subscriptions} | Contacts],
|
||||
_Unsubscribers = Unsubscribers};
|
||||
New_Subscriptions ->
|
||||
{_Contacts = [{Entity, New_Subscriptions} | Contacts],
|
||||
_Unsubscribers = [Entity | Unsubscribers]}
|
||||
end).
|
||||
|
||||
|
||||
%%
|
||||
-spec(subscriptions2/3 ::
|
||||
(
|
||||
NodeIdx :: exmpp_pubsub:nodeIdx(),
|
||||
Owner :: xmpp_jid:usr_bare(),
|
||||
Node_Groups :: node_groups())
|
||||
-> Diff_Contacts :: {Contacts :: [] | contacts(),
|
||||
Subscribers :: [Entity::xmpp_jid:usr_bare()]}
|
||||
).
|
||||
|
||||
subscriptions2(NodeIdx, Owner, Node_Groups) ->
|
||||
subscriptions2(NodeIdx, _Rosters = get_entity_roster(Owner), Node_Groups,
|
||||
{_New_Contacts = [], _Subscribers = []}).
|
||||
|
||||
%%
|
||||
-spec(subscriptions2/4 ::
|
||||
(
|
||||
NodeIdx :: exmpp_pubsub:nodeIdx(),
|
||||
Rosters :: [Roster::#roster{groups :: [] | roster_groups()}],
|
||||
Node_Groups :: node_groups(),
|
||||
Diff_Contacts :: {Contacts :: [] | contacts(),
|
||||
Subscribers :: [Entity::xmpp_jid:usr_bare()]})
|
||||
-> Diff_Contacts :: {Contacts :: [] | contacts(),
|
||||
Subscribers :: [Entity::xmpp_jid:usr_bare()]}
|
||||
).
|
||||
|
||||
subscriptions2(_NodeIdx, [] = _Rosters, _Node_Groups, Diff_Contacts) ->
|
||||
Diff_Contacts;
|
||||
%%
|
||||
subscriptions2(NodeIdx, [_Roster | Rosters], Node_Groups, {Contacts, Subscribers})
|
||||
when _Roster#roster.groups =/= [] ->
|
||||
subscriptions2(NodeIdx, Rosters, Node_Groups,
|
||||
_Diff_Contacts = case
|
||||
filter_groups(_Roster#roster.groups, Node_Groups, [])
|
||||
of
|
||||
[] ->
|
||||
{_Contacts = Contacts,
|
||||
_Subscribers = Subscribers};
|
||||
Roster_Groups ->
|
||||
{_Contacts = [{_Roster#roster.jid, [{NodeIdx, Roster_Groups}]}
|
||||
| Contacts],
|
||||
_Subscribers = [_Roster#roster.jid | Subscribers]}
|
||||
end);
|
||||
%%
|
||||
subscriptions2(NodeIdx, [_Roster | Rosters], Node_Groups, Diff_Contacts) ->
|
||||
subscriptions2(NodeIdx, Rosters, Node_Groups, Diff_Contacts).
|
||||
|
||||
|
||||
%%
|
||||
-spec(subscriptions3/3 ::
|
||||
(
|
||||
NodeIdx :: exmpp_pubsub:nodeIdx(),
|
||||
Old_Groups :: roster_groups(),
|
||||
Contacts :: contacts() | [])
|
||||
-> Diff_Contacts :: {Contacts :: [] | contacts(),
|
||||
Unsubscribers :: [Entity::xmpp_jid:usr_bare()]}
|
||||
).
|
||||
subscriptions3(NodeIdx, Old_Groups, Contacts) ->
|
||||
subscriptions3(NodeIdx, Contacts, Old_Groups, {[],[]}).
|
||||
|
||||
%%
|
||||
-spec(subscriptions3/4 ::
|
||||
(
|
||||
NodeIdx :: exmpp_pubsub:nodeIdx(),
|
||||
Old_Contacts :: contacts() | [],
|
||||
Old_Groups :: roster_groups(),
|
||||
Diff_Contacts :: {Contacts :: [] | contacts(),
|
||||
Unsubscribers :: [Entity::xmpp_jid:usr_bare()]})
|
||||
-> Diff_Contacts :: {Contacts :: [] | contacts(),
|
||||
Unsubscribers :: [Entity::xmpp_jid:usr_bare()]}
|
||||
).
|
||||
|
||||
subscriptions3(_NodeIdx, [] = _Contacts, _Old_Groups, Diff_Contacts) ->
|
||||
Diff_Contacts;
|
||||
%%
|
||||
subscriptions3(NodeIdx, [{Entity, Subscriptions} | Old_Contacts], Old_Groups,
|
||||
{Contacts, Unsubscribers}) ->
|
||||
subscriptions3(NodeIdx, Old_Contacts, Old_Groups,
|
||||
_Diff_Contacts = case lists:keyfind(NodeIdx, 1, Subscriptions) of
|
||||
{_NodeIdx, Roster_Groups} ->
|
||||
case delete_groups(Old_Groups, Roster_Groups) of
|
||||
[] ->
|
||||
{_Contacts = Contacts,
|
||||
_Unsubscribers = [Entity | Unsubscribers]};
|
||||
Groups ->
|
||||
{_Contacts = [{Entity,
|
||||
lists:keyreplace(NodeIdx, 1,
|
||||
Subscriptions, {NodeIdx, Groups})}
|
||||
| Contacts],
|
||||
_Unsubscribers = Unsubscribers}
|
||||
end;
|
||||
false ->
|
||||
{_Contacts = [{Entity, Subscriptions} | Contacts],
|
||||
_Unsubscribers = Unsubscribers}
|
||||
end).
|
||||
|
||||
|
||||
%%
|
||||
-spec(subscriptions4/4 ::
|
||||
(
|
||||
NodeIdx :: exmpp_pubsub:nodeIdx(),
|
||||
_ :: xmpp_jid:usr_bare()
|
||||
| [Roster::#roster{groups :: [] | roster_groups()}],
|
||||
Node_Groups :: node_groups(),
|
||||
_ :: [] | contacts()
|
||||
| {Contacts :: [] | contacts(),
|
||||
Subscribers :: [Entity::xmpp_jid:usr_bare()],
|
||||
Unsubscribers :: [Entity::xmpp_jid:usr_bare()]})
|
||||
-> Diff_Contacts :: {Contacts :: [] | contacts(),
|
||||
Subscribers :: [Entity::xmpp_jid:usr_bare()],
|
||||
Unsubscribers :: [Entity::xmpp_jid:usr_bare()]}
|
||||
).
|
||||
|
||||
subscriptions4(_NodeIdx, [] = _Rosters, _Node_Groups, Diff_Contacts) ->
|
||||
Diff_Contacts;
|
||||
%%
|
||||
subscriptions4(NodeIdx, [_Roster | Rosters], Node_Groups,
|
||||
{Contacts, Subscribers, Unsubscribers})
|
||||
when _Roster#roster.groups =/= [] ->
|
||||
subscriptions4(NodeIdx, Rosters, Node_Groups,
|
||||
_Diff_Contacts = case
|
||||
{lists:keyfind(Entity = _Roster#roster.jid, 1, Contacts),
|
||||
filter_groups(_Roster#roster.groups, Node_Groups, [])}
|
||||
of
|
||||
%%
|
||||
{false, [] = _Groups} ->
|
||||
{_Contacts = Contacts,
|
||||
_Subscribers = Subscribers,
|
||||
_Unsubscribers = Unsubscribers};
|
||||
%%
|
||||
{false, Groups} ->
|
||||
{_Contacts = [{Entity, [{NodeIdx, Groups}]} | Contacts],
|
||||
_Subscribers = [Entity | Subscribers],
|
||||
_Unsubscribers = Unsubscribers};
|
||||
%%
|
||||
{{_Entity, [{NodeIdx, _Roster_Groups}] = _Subscriptions}, [] = _Groups} ->
|
||||
{_Contacts = lists:keydelete(Entity, 1, Contacts),
|
||||
_Subscribers = Subscribers,
|
||||
_Unsubscribers = [Entity | Unsubscribers]};
|
||||
%%
|
||||
{{_Entity, Subscriptions}, [] = _Groups} ->
|
||||
case lists:keydelete(NodeIdx, 1, Subscriptions) of
|
||||
Subscriptions ->
|
||||
{_Contacts = Contacts,
|
||||
_Subscribers = Subscribers,
|
||||
_Unsubscribers = Unsubscribers};
|
||||
New_Subscriptions ->
|
||||
{_Contacts = lists:keyreplace(Entity, 1, Contacts,
|
||||
{Entity, New_Subscriptions}),
|
||||
_Subscribers = Subscribers,
|
||||
_Unsubscribers = [Entity | Unsubscribers]}
|
||||
end;
|
||||
{{_Entity, Subscriptions}, Groups} ->
|
||||
case lists:keyreplace(NodeIdx, 1, Subscriptions, {NodeIdx, Groups}) of
|
||||
Subscriptions ->
|
||||
{_Contacts = lists:keyreplace(Entity, 1, Contacts,
|
||||
{Entity,
|
||||
[{NodeIdx, Groups} | Subscriptions]}),
|
||||
_Subscribers = [Entity | Subscribers],
|
||||
_Unsubscribers = Unsubscribers};
|
||||
New_Subscriptions ->
|
||||
{_Contacts = lists:keyreplace(Entity, 1, Contacts,
|
||||
{Entity, New_Subscriptions}),
|
||||
_Subscribers = Subscribers,
|
||||
_Unsubscribers = Unsubscribers}
|
||||
end
|
||||
end);
|
||||
%%
|
||||
subscriptions4(NodeIdx, [_Roster | Rosters], Node_Groups, Diff_Contacts) ->
|
||||
subscriptions4(NodeIdx, Rosters, Node_Groups, Diff_Contacts);
|
||||
%%
|
||||
subscriptions4(NodeIdx, Owner, Node_Groups, Contacts) ->
|
||||
subscriptions4(NodeIdx, _Rosters = get_entity_roster(Owner), Node_Groups,
|
||||
_Diff_Contacts = {Contacts, _Subscribers = [], _Unsubscribers = []}).
|
||||
|
||||
|
||||
|
||||
-spec(subscriptions5/4 ::
|
||||
(
|
||||
NodeIdx :: exmpp_pubsub:nodeIdx(),
|
||||
_ :: xmpp_jid:usr_bare()
|
||||
| [Roster::#roster{groups :: [] | roster_groups()}],
|
||||
Node_Groups :: node_groups(),
|
||||
_ :: [] | contacts()
|
||||
| {Contacts :: [] | contacts(),
|
||||
Subscribers :: [Entity::xmpp_jid:usr_bare()]})
|
||||
-> Diff_Contacts :: {Contacts :: [] | contacts(),
|
||||
Subscribers :: [Entity::xmpp_jid:usr_bare()]}
|
||||
).
|
||||
|
||||
subscriptions5(NodeIdx, [_Roster | Rosters], Node_Groups, {Contacts, Subscribers})
|
||||
when _Roster#roster.groups =/= [] ->
|
||||
subscriptions5(NodeIdx, Rosters, Node_Groups,
|
||||
_Diff_Contacts = case
|
||||
filter_groups(_Roster#roster.groups, Node_Groups, [])
|
||||
of
|
||||
[] ->
|
||||
{_Contacts = Contacts,
|
||||
_Subscribers = Subscribers};
|
||||
Groups ->
|
||||
{_Contacts = case
|
||||
lists:keyfind(_Roster#roster.jid, 1, Contacts)
|
||||
of
|
||||
false ->
|
||||
[{_Roster#roster.jid, [{NodeIdx, Groups}]} | Contacts];
|
||||
{Entity, Subscriptions} ->
|
||||
lists:keyreplace(Entity, 1, Contacts,
|
||||
{Entity, [{NodeIdx, Groups} | Subscriptions]})
|
||||
end,
|
||||
_Subscribers = [_Roster#roster.jid | Subscribers]}
|
||||
end);
|
||||
%%
|
||||
subscriptions5(NodeIdx, [_Roster | Rosters], Node_Groups, Diff_Contacts) ->
|
||||
subscriptions5(NodeIdx, Rosters, Node_Groups, Diff_Contacts);
|
||||
%%
|
||||
subscriptions5(NodeIdx, Owner, Node_Groups, Contacts) ->
|
||||
subscriptions5(NodeIdx, _Rosters = get_entity_roster(Owner), Node_Groups,
|
||||
_Diff_Contacts = {Contacts, _Subscribers = []}).
|
||||
|
||||
|
||||
%%
|
||||
-spec(delete_groups/2 ::
|
||||
(
|
||||
Old_Groups :: roster_groups(),
|
||||
Groups :: [] | roster_groups())
|
||||
-> Groups :: [] | roster_groups()
|
||||
).
|
||||
|
||||
delete_groups(_Old_Groups, [] = _Groups) ->
|
||||
_Groups = [];
|
||||
%%
|
||||
delete_groups([] = _Old_Groups, Groups) ->
|
||||
Groups;
|
||||
%%
|
||||
delete_groups([Old_Group | Old_Groups], Groups) ->
|
||||
_Groups = delete_groups(Old_Groups, lists:delete(Old_Group, Groups)).
|
||||
|
||||
|
||||
%%
|
||||
-spec(diff_groups/2 ::
|
||||
(
|
||||
Groups :: node_groups() | [],
|
||||
_ :: node_groups()
|
||||
| {New_Groups :: [] | node_groups(),
|
||||
Old_Groups :: [] | node_groups()})
|
||||
-> Diff_Groups :: {New_Groups :: [] | node_groups(),
|
||||
Old_Groups :: [] | node_groups()}
|
||||
).
|
||||
|
||||
diff_groups([] = _Groups, Diff_Groups) -> %% when is_tuple(Diff_Groups)
|
||||
Diff_Groups;
|
||||
%%
|
||||
diff_groups([Group | Groups], {New_Groups, Old_Groups}) ->
|
||||
diff_groups(Groups,
|
||||
_Diff_Groups = case lists:delete(Group, Old_Groups) of
|
||||
Old_Groups -> {[Group | New_Groups], Old_Groups};
|
||||
Old_Groups2 -> {New_Groups, Old_Groups2}
|
||||
end);
|
||||
%%
|
||||
diff_groups(New_Groups, Old_Groups) ->
|
||||
diff_groups(New_Groups, {[], Old_Groups}).
|
||||
|
||||
|
||||
%%
|
||||
-spec(filter_groups/3 ::
|
||||
(
|
||||
Roster_Groups :: roster_groups() | [],
|
||||
Node_Groups :: node_groups(),
|
||||
Groups :: [] | roster_groups())
|
||||
-> Groups :: [] | roster_groups()
|
||||
).
|
||||
|
||||
filter_groups([] = _Roster_Groups, _Node_Groups, Groups) ->
|
||||
Groups;
|
||||
%%
|
||||
filter_groups([Roster_Group | Roster_Groups], Node_Groups, Groups) ->
|
||||
filter_groups(Roster_Groups, Node_Groups,
|
||||
_Groups = case lists:member(Roster_Group, Node_Groups) of
|
||||
true -> [Roster_Group | Groups];
|
||||
false -> Groups
|
||||
end).
|
||||
|
||||
|
||||
%%
|
||||
-spec(filter_subscriptions/2 ::
|
||||
(
|
||||
Nodes :: n0des(),
|
||||
Roster_Groups :: roster_groups())
|
||||
-> Subscriptions :: [] | subscriptions()
|
||||
).
|
||||
|
||||
filter_subscriptions(Nodes, Roster_Groups) ->
|
||||
_Subscriptions = filter_subscriptions(Nodes, Roster_Groups, []).
|
||||
|
||||
%%
|
||||
-spec(filter_subscriptions/3 ::
|
||||
(
|
||||
Nodes :: n0des(),
|
||||
Roster_Groups :: roster_groups(),
|
||||
Subscriptions :: [] | subscriptions())
|
||||
-> Subscriptions :: [] | subscriptions()
|
||||
).
|
||||
|
||||
filter_subscriptions([] = _Nodes, _Roster_Groups, Subscriptions) ->
|
||||
Subscriptions;
|
||||
%%
|
||||
filter_subscriptions([{NodeIdx, Node_Groups} | Nodes], Roster_Groups,
|
||||
Subscriptions) ->
|
||||
filter_subscriptions(Nodes, Roster_Groups,
|
||||
_Subscriptions = case filter_groups(Roster_Groups, Node_Groups, []) of
|
||||
[] -> Subscriptions;
|
||||
Groups -> [{NodeIdx, Groups} | Subscriptions]
|
||||
end).
|
||||
|
||||
|
||||
%%
|
||||
-spec(diff_nodeidxs/2 ::
|
||||
(
|
||||
New_Subscriptions :: [] | subscriptions(),
|
||||
Old_Subscriptions :: [] | subscriptions())
|
||||
-> Diff_NodeIdxs :: {NodeIdxs_Subscriptions :: [] | nodeIdxs(),
|
||||
NodeIdxs_Unsubscriptions :: [] | nodeIdxs()}
|
||||
).
|
||||
|
||||
diff_nodeidxs(New_Subscriptions, Old_Subscriptions) ->
|
||||
_Diff_NodeIdxs = diff_nodeidxs(New_Subscriptions, Old_Subscriptions, []).
|
||||
|
||||
%%
|
||||
-spec(diff_nodeidxs/3 ::
|
||||
(
|
||||
New_Subscriptions :: [] | subscriptions(),
|
||||
Old_Subscriptions :: [] | subscriptions(),
|
||||
NodeIdxs_Subscriptions :: [] | nodeIdxs())
|
||||
-> Diff_NodeIdxs :: {NodeIdxs_Subscriptions :: [] | nodeIdxs(),
|
||||
NodeIdxs_Unsubscriptions :: [] | nodeIdxs()}
|
||||
).
|
||||
|
||||
diff_nodeidxs([] = _New_Subscriptions, Old_Subscriptions,
|
||||
NodeIdxs_Subscriptions) ->
|
||||
_Diff_NodeIdxs = {
|
||||
_NodeIdxs_Subscriptions = NodeIdxs_Subscriptions,
|
||||
_NodeIdxs_Unsubscriptions = lists:map(fun
|
||||
({NodeIdx, _Roster_Groups}) ->
|
||||
NodeIdx
|
||||
end, Old_Subscriptions)};
|
||||
%%
|
||||
diff_nodeidxs([{NodeIdx, _Groups} | New_Subscriptions], [] = Old_Subscriptions,
|
||||
NodeIdxs_Subscriptions) ->
|
||||
diff_nodeidxs(New_Subscriptions, Old_Subscriptions,
|
||||
[NodeIdx | NodeIdxs_Subscriptions]);
|
||||
%%
|
||||
diff_nodeidxs([{NodeIdx, _Groups} | New_Subscriptions], Old_Subscriptions,
|
||||
NodeIdxs_Subscriptions) ->
|
||||
case lists:keydelete(NodeIdx, 1, Old_Subscriptions) of
|
||||
Old_Subscriptions ->
|
||||
diff_nodeidxs(New_Subscriptions, Old_Subscriptions,
|
||||
[NodeIdx | NodeIdxs_Subscriptions]);
|
||||
Subscriptions ->
|
||||
diff_nodeidxs(New_Subscriptions, _Old_Subscriptions = Subscriptions,
|
||||
NodeIdxs_Subscriptions)
|
||||
end.
|
||||
|
||||
|
||||
%% TODO : use a new mod_roster_api for this call
|
||||
-spec(roster_groups/2 ::
|
||||
(
|
||||
Entity :: xmpp_jid:usr_bare(),
|
||||
Contact :: xmpp_jid:usr_bare())
|
||||
-> Roster_Groups :: [] | roster_groups()
|
||||
).
|
||||
|
||||
roster_groups({User, Server, _} = _Entity, Contact) ->
|
||||
_Roster_Groups = case
|
||||
gen_storage:transaction(Server, rosteritem,
|
||||
fun() ->
|
||||
gen_storage:select(Server, rostergroup,
|
||||
[{'=', user_host_jid, {User, Server, Contact}}])
|
||||
end)
|
||||
of
|
||||
{atomic, _RosterGroups} ->
|
||||
lists:map(fun
|
||||
(_RosterGroup) ->
|
||||
_RosterGroup#roster.groups
|
||||
end, _RosterGroups);
|
||||
_Error
|
||||
-> {error, 'internal-server-error'}
|
||||
end.
|
||||
|
||||
|
||||
%%
|
||||
-spec(select_roster_groups/1 ::
|
||||
(
|
||||
Entity :: xmpp_jid:usr_entity())
|
||||
-> Roster_Groups :: [] | roster_groups()
|
||||
).
|
||||
|
||||
select_roster_groups({User, Server, _} = Entity) ->
|
||||
_Roster_Groups = case
|
||||
gen_storage:transaction(Server, rosteritem,
|
||||
fun() ->
|
||||
gen_storage:select(Server, rostergroup,
|
||||
[{'=', user_host_jid, {User, Server, '_'}}])
|
||||
end)
|
||||
of
|
||||
{atomic, _RosterGroups} ->
|
||||
lists:map(fun
|
||||
(_RosterGroup) ->
|
||||
_RosterGroup#roster.groups
|
||||
end, _RosterGroups);
|
||||
_Error
|
||||
-> {error, 'internal-server-error'}
|
||||
end.
|
||||
|
||||
|
||||
%% TESTS
|
||||
|
||||
%%
|
||||
monitor_roster_groups(Server, Roster) ->
|
||||
?INFO_MSG("SERVER ~p ROSTER ~p", [Server, Roster]),
|
||||
Result = pubsub_db:transaction('mnesia', ?MODULE, monitor_groups,
|
||||
[Server, Roster]),
|
||||
?INFO_MSG("MONITOR ROSTER GROUPS ~p", [Result]).
|
||||
|
||||
|
||||
monitor_contacts2('subscribed', Entity, Jid_Contact) ->
|
||||
Result = pubsub_db:transaction('mnesia', ?MODULE, monitor_contacts,
|
||||
['subscribed', Entity, Jid_Contact]),
|
||||
?INFO_MSG("MONITOR CONTACTS2 ~p", [Result]).
|
||||
|
||||
register1(NodeIdx, User, Groups) ->
|
||||
Server = <<"localhost">>,
|
||||
Owner = {list_to_binary(atom_to_list(User)), Server, undefined},
|
||||
Groups_B = lists:map(fun(Group) -> list_to_binary(atom_to_list(Group)) end, Groups),
|
||||
register_groups(dev, NodeIdx, Owner, Groups_B).
|
||||
|
||||
register(NodeIdx, User, Groups) ->
|
||||
pubsub_db:transaction('mnesia', ?MODULE, register1, [NodeIdx, User, Groups]).
|
||||
@@ -0,0 +1,570 @@
|
||||
%%% ====================================================================
|
||||
%%% ``The contents of this file are subject to the Erlang Public License,
|
||||
%%% Version 1.1, (the "License"); you may not use this file except in
|
||||
%%% compliance with the License. You should have received a copy of the
|
||||
%%% Erlang Public License along with this software. If not, it can be
|
||||
%%% retrieved via the world wide web at http://www.erlang.org/.
|
||||
%%%
|
||||
%%% Software distributed under the License is distributed on an "AS IS"
|
||||
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%%% the License for the specific language governing rights and limitations
|
||||
%%% under the License.
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2013, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2013, ProcessOne.
|
||||
%%%
|
||||
%%% @copyright 2006-2013 ProcessOne
|
||||
%%% @author Karim Gemayel <karim.gemayel@process-one.net>
|
||||
%%% [http://www.process-one.net/]
|
||||
%%% @version {@vsn}, {@date} {@time}
|
||||
%%% @end
|
||||
%%% ====================================================================
|
||||
|
||||
%%% @headerfile "pubsub_dev.hrl"
|
||||
|
||||
-module(pubsub_hooks).
|
||||
-author('karim.gemayel@process-one.net').
|
||||
|
||||
-compile(export_all).
|
||||
|
||||
-include("pubsub_dev.hrl").
|
||||
|
||||
-import(pubsub_tools,
|
||||
[
|
||||
get_option/2,
|
||||
get_option/3,
|
||||
get_value/2,
|
||||
get_value/3,
|
||||
set_value/3,
|
||||
%%
|
||||
check_access_model/3,
|
||||
check_access_model/7,
|
||||
check_publish_model/3,
|
||||
is_contact_subscribed_to_node_owners/3,
|
||||
is_contact_in_allowed_roster_groups/2,
|
||||
has_subscriptions/1
|
||||
]).
|
||||
|
||||
-import(pubsub_db_mnesia,
|
||||
[
|
||||
table/2
|
||||
]).
|
||||
|
||||
%% 'node_config#send_last_published_item'
|
||||
-spec(presence_online/3 ::
|
||||
(
|
||||
From :: xmpp_jid:entity_full(),
|
||||
To :: xmpp_jid:entity_full(),
|
||||
C2SPid :: pid())
|
||||
-> 'ok'
|
||||
).
|
||||
|
||||
presence_online(#jid{luser = U, lserver = S, lresource = R} = Jid, Jid, C2SPid) ->
|
||||
?INFO_MSG("PRESENCE ONLINE From ~p ~n, To ~p ~n, C2SPid ~p ~n",
|
||||
[Jid, Jid, C2SPid]),
|
||||
Pubsub_Features = node_flat_dev:pubsub_features(),
|
||||
case lists:member(<<"last-published">>, Pubsub_Features) of
|
||||
true ->
|
||||
spawn(?MODULE, last_published_items,
|
||||
[_Host = <<"localhost">>, {U,S,R}]);
|
||||
false ->
|
||||
ok
|
||||
end;
|
||||
%%
|
||||
presence_online(_, _, _) ->
|
||||
ok.
|
||||
|
||||
|
||||
%%
|
||||
-spec(last_published_items/2 ::
|
||||
(
|
||||
Host :: xmpp_jid:raw_jid_component_bare(),
|
||||
Entity :: xmpp_jid:usr_full())
|
||||
-> 'ok'
|
||||
).
|
||||
|
||||
last_published_items(Host, {U,S,_R} = Entity) ->
|
||||
Table_Pubsub_State = table('pubsub_state', 'dev'),
|
||||
Table_Pubsub_Node = table('pubsub_node', 'dev'),
|
||||
Table_Pubsub_Last_Item = table('pubsub_last_item', 'dev'),
|
||||
lists:foreach(fun
|
||||
(State) ->
|
||||
last_published_items(Host, Entity, Table_Pubsub_Node,
|
||||
Table_Pubsub_Last_Item, State)
|
||||
end,
|
||||
mnesia:dirty_select(Table_Pubsub_State,
|
||||
[{#pubsub_state_dev{
|
||||
id = {{U,S,undefined}, '$1'},
|
||||
affiliation = '$2',
|
||||
access = '$3',
|
||||
subscriptions = '$4',
|
||||
_ = '_'
|
||||
},
|
||||
[{'=/=', '$2', 'outcast'},
|
||||
{'=/=', '$3', 'pending'},
|
||||
{'=/=', '$4', []}],
|
||||
['$$']}])).
|
||||
|
||||
%%
|
||||
-spec(last_published_items/5 ::
|
||||
(
|
||||
Host :: xmpp_jid:raw_jid_component_bare(),
|
||||
Entity :: xmpp_jid:usr_full(),
|
||||
Table_Pubsub_Node :: atom(),
|
||||
Table_Pubsub_Last_Item :: atom(),
|
||||
State :: [exmpp_pubsub:nodeIdx() |
|
||||
'member' | 'owner' | 'publisher' |
|
||||
_ |
|
||||
exmpp_pubsub:subscriptions(),... ])
|
||||
-> 'ok'
|
||||
).
|
||||
|
||||
last_published_items(Host, {_, _, Online_Resource} = Entity,
|
||||
Table_Pubsub_Node, Table_Pubsub_Last_Item,
|
||||
[NodeIdx, Affiliation, _Access, Subscriptions]) ->
|
||||
case mnesia:dirty_index_read(Table_Pubsub_Node, NodeIdx, idx) of
|
||||
[#pubsub_node_dev{
|
||||
id = {Pubsub_Host, NodeId},
|
||||
owners = Node_Owners,
|
||||
options = Node_Options
|
||||
}] ->
|
||||
case get_value(Node_Options, 'send_last_published_item') of
|
||||
'on_sub_and_presence' ->
|
||||
case mnesia:dirty_read(Table_Pubsub_Last_Item, NodeIdx) of
|
||||
[#pubsub_last_item_dev{
|
||||
id = ItemId,
|
||||
creation = {DateTime, Publisher},
|
||||
payload = Payload,
|
||||
options = Item_Options
|
||||
}] ->
|
||||
spawn(pubsub_broadcast, broadcast_publish_last2,
|
||||
[Host, Pubsub_Host, NodeId, Node_Options,
|
||||
Node_Owners,
|
||||
[{ItemId, Item_Options, Payload, Publisher, DateTime}],
|
||||
Entity, Affiliation,
|
||||
lists:foldl(fun
|
||||
({Subscription_State, SubId, Resource, Subscription_Options},
|
||||
Acc)
|
||||
when Subscription_State =/= 'pending'
|
||||
andalso (Resource == undefined
|
||||
orelse
|
||||
Resource == Online_Resource) ->
|
||||
[{Subscription_State, SubId,
|
||||
Online_Resource, Subscription_Options}
|
||||
| Acc];
|
||||
(_Subscription, Acc) ->
|
||||
Acc
|
||||
end, [], Subscriptions)]);
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%% 'node_config#purge_offline'
|
||||
%% 'node_config#tempsub'
|
||||
%% 'subscribe_options#expire'
|
||||
|
||||
-spec(presence_offline/3 ::
|
||||
(
|
||||
_ :: _,
|
||||
Jid :: xmpp_jid:entity_full(),
|
||||
_ :: _)
|
||||
-> 'ok'
|
||||
).
|
||||
|
||||
presence_offline({_DateTime, _Pid},
|
||||
#jid{luser = U, lserver = S, lresource = Offline_Resource} = _Jid, _) ->
|
||||
Host = <<"localhost">>,
|
||||
Pubsub_Features = node_flat_dev:pubsub_features(),
|
||||
Subscribe = lists:member(<<"subscribe">>, Pubsub_Features),
|
||||
Leased_Subscription = lists:member(<<"leased-subscription">>, Pubsub_Features),
|
||||
Purge_Nodes = lists:member(<<"purge-nodes">>, Pubsub_Features),
|
||||
Persistent_Items = lists:member(<<"persistent-items">>, Pubsub_Features),
|
||||
Subscription_Notifications = lists:member(<<"subscription-notifications">>,
|
||||
Pubsub_Features),
|
||||
Table_Pubsub_State = table('pubsub_state', 'dev'),
|
||||
Table_Pubsub_Node = table('pubsub_node', 'dev'),
|
||||
Online_Resources = case ejabberd_sm:get_user_resources(U, S) of
|
||||
[] -> false;
|
||||
_ -> true
|
||||
end,
|
||||
lists:foreach(fun
|
||||
(Pubsub_State) ->
|
||||
presence_offline(Host,
|
||||
_Entity = {U,S,undefined},
|
||||
Table_Pubsub_State,
|
||||
Pubsub_State,
|
||||
Table_Pubsub_Node,
|
||||
Offline_Resource,
|
||||
Online_Resources,
|
||||
{Subscribe,
|
||||
Leased_Subscription,
|
||||
Purge_Nodes,
|
||||
Persistent_Items,
|
||||
Subscription_Notifications})
|
||||
end,
|
||||
mnesia:dirty_match_object(Table_Pubsub_State,
|
||||
#pubsub_state_dev{
|
||||
id = {{U,S,undefined}, '_'},
|
||||
_ = '_'
|
||||
})).
|
||||
|
||||
%%
|
||||
-spec(presence_offline/8 ::
|
||||
(
|
||||
Host :: xmpp_jid:raw_jid_component_bare(),
|
||||
Entity :: xmpp_jid:usr_bare(),
|
||||
Table_Pubsub_State :: atom(),
|
||||
Pubsub_State :: mod_pubsub_dev:pubsub_state(),
|
||||
Table_Pubsub_Node :: atom(),
|
||||
Offline_Resource :: xmpp_jid:resource_jid(),
|
||||
Online_Resources :: boolean(),
|
||||
Pubsub_Features :: {Subscribe :: boolean(),
|
||||
Leased_Subscription :: boolean(),
|
||||
Purge_Nodes :: boolean(),
|
||||
Persistent_Items :: boolean(),
|
||||
Subscription_Notifications :: boolean()})
|
||||
-> 'ok'
|
||||
).
|
||||
|
||||
presence_offline(Host, Entity, Table_Pubsub_State, Pubsub_State,
|
||||
Table_Pubsub_Node, Offline_Resource, Online_Resources,
|
||||
{Subscribe, Leased_Subscription, Purge_Nodes, Persistent_Items,
|
||||
Subscription_Notifications}) ->
|
||||
case
|
||||
mnesia:dirty_index_read(Table_Pubsub_Node,
|
||||
Pubsub_State#pubsub_state_dev.nodeidx, idx)
|
||||
of
|
||||
[#pubsub_node_dev{id = {Pubsub_Host, NodeId}} = Pubsub_Node] ->
|
||||
Node_Options = Pubsub_Node#pubsub_node_dev.options,
|
||||
|
||||
case
|
||||
Subscribe == true
|
||||
andalso
|
||||
get_value(Node_Options, 'tempsub') == true
|
||||
of
|
||||
true ->
|
||||
case
|
||||
filter_tempsub_subscriptions(
|
||||
get_value(Node_Options, 'notify_sub'),
|
||||
Pubsub_State#pubsub_state_dev.subscriptions,
|
||||
Offline_Resource, Online_Resources, {[], []})
|
||||
of
|
||||
%%
|
||||
{_Unexpired_Subscriptions, [] = _Expired_Subscriptions} ->
|
||||
ok;
|
||||
%%
|
||||
{[] = _Unexpired_Subscriptions, Expired_Subscriptions}
|
||||
when Pubsub_State#pubsub_state_dev.affiliation == 'member'
|
||||
andalso Pubsub_State#pubsub_state_dev.itemids == [] ->
|
||||
mnesia:dirty_delete_object(Table_Pubsub_State,
|
||||
Pubsub_State),
|
||||
Notification_Type = get_value(Node_Options,
|
||||
'notification_type', 'headline'),
|
||||
notify_subscriptions(Host, Pubsub_Host,
|
||||
Entity, NodeId, Notification_Type,
|
||||
_Recipients = case Subscription_Notifications of
|
||||
true ->
|
||||
case
|
||||
lists:member(Entity,
|
||||
Pubsub_Node#pubsub_node_dev.owners)
|
||||
of
|
||||
true ->
|
||||
Pubsub_Node#pubsub_node_dev.owners;
|
||||
false ->
|
||||
[Entity
|
||||
| Pubsub_Node#pubsub_node_dev.owners]
|
||||
end;
|
||||
false ->
|
||||
Pubsub_Node#pubsub_node_dev.owners
|
||||
end,
|
||||
Expired_Subscriptions),
|
||||
ok;
|
||||
%%
|
||||
{Unexpired_Subscriptions, Expired_Subscriptions} ->
|
||||
mnesia:dirty_write(Table_Pubsub_State,
|
||||
Pubsub_State#pubsub_state_dev{
|
||||
subscriptions = Unexpired_Subscriptions
|
||||
}),
|
||||
Notification_Type = get_value(Node_Options,
|
||||
'notification_type', 'headline'),
|
||||
notify_subscriptions(Host, Pubsub_Host,
|
||||
Entity, NodeId, Notification_Type,
|
||||
_Recipients = case Subscription_Notifications of
|
||||
true ->
|
||||
case
|
||||
lists:member(Entity,
|
||||
Pubsub_Node#pubsub_node_dev.owners)
|
||||
of
|
||||
true ->
|
||||
Pubsub_Node#pubsub_node_dev.owners;
|
||||
false ->
|
||||
[Entity
|
||||
| Pubsub_Node#pubsub_node_dev.owners]
|
||||
end;
|
||||
false ->
|
||||
Pubsub_Node#pubsub_node_dev.owners
|
||||
end,
|
||||
Expired_Subscriptions),
|
||||
ok
|
||||
end;
|
||||
_ ->
|
||||
case Subscribe == true andalso Leased_Subscription == true of
|
||||
true ->
|
||||
case
|
||||
filter_expired_subscriptions(
|
||||
get_value(Node_Options, 'notify_sub'),
|
||||
Pubsub_State#pubsub_state_dev.subscriptions,
|
||||
Offline_Resource, Online_Resources, {[], []})
|
||||
of
|
||||
%%
|
||||
{_Unexpired_Subscriptions, [] = _Expired_Subscriptions} ->
|
||||
ok;
|
||||
%%
|
||||
{[] = _Unexpired_Subscriptions, Expired_Subscriptions}
|
||||
when Pubsub_State#pubsub_state_dev.affiliation == 'member' ->
|
||||
mnesia:dirty_delete_object(Table_Pubsub_State,
|
||||
Pubsub_State),
|
||||
Notification_Type = get_value(Node_Options,
|
||||
'notification_type', 'headline'),
|
||||
notify_subscriptions(Host, Pubsub_Host,
|
||||
Entity, NodeId, Notification_Type,
|
||||
_Recipients = case
|
||||
Subscription_Notifications
|
||||
of
|
||||
true ->
|
||||
case
|
||||
lists:member(Entity,
|
||||
Pubsub_Node#pubsub_node_dev.owners)
|
||||
of
|
||||
true ->
|
||||
Pubsub_Node#pubsub_node_dev.owners;
|
||||
false ->
|
||||
[Entity
|
||||
|Pubsub_Node#pubsub_node_dev.owners]
|
||||
end;
|
||||
false ->
|
||||
Pubsub_Node#pubsub_node_dev.owners
|
||||
end,
|
||||
Expired_Subscriptions),
|
||||
ok;
|
||||
%%
|
||||
{Unexpired_Subscriptions, Expired_Subscriptions} ->
|
||||
mnesia:dirty_write(Table_Pubsub_State,
|
||||
Pubsub_State#pubsub_state_dev{
|
||||
subscriptions = Unexpired_Subscriptions
|
||||
}),
|
||||
Notification_Type = get_value(Node_Options,
|
||||
'notification_type', 'headline'),
|
||||
notify_subscriptions(Host, Pubsub_Host,
|
||||
Entity, NodeId, Notification_Type,
|
||||
_Recipients = case
|
||||
Subscription_Notifications
|
||||
of
|
||||
true ->
|
||||
case
|
||||
lists:member(Entity,
|
||||
Pubsub_Node#pubsub_node_dev.owners)
|
||||
of
|
||||
true ->
|
||||
Pubsub_Node#pubsub_node_dev.owners;
|
||||
false ->
|
||||
[Entity
|
||||
| Pubsub_Node#pubsub_node_dev.owners]
|
||||
end;
|
||||
false ->
|
||||
Pubsub_Node#pubsub_node_dev.owners
|
||||
end,
|
||||
Expired_Subscriptions),
|
||||
ok
|
||||
end;
|
||||
false ->
|
||||
ok
|
||||
end
|
||||
end;
|
||||
[] ->
|
||||
ok
|
||||
end.
|
||||
|
||||
%%
|
||||
-spec(notify_subscriptions/7 ::
|
||||
(
|
||||
Host :: xmpp_jid:raw_jid_component_bare(),
|
||||
Pubsub_Host :: exmpp_pubsub:host(),
|
||||
Entity :: xmpp_jid:usr_bare(),
|
||||
NodeId :: exmpp_pubsub:nodeId(),
|
||||
Notification_Type :: 'message' | 'headline',
|
||||
Recipients :: [Entity::xmpp_jid:usr_bare(),...],
|
||||
Subscriptions :: [Subscription::exmpp_pubsub:subscription(),...])
|
||||
-> 'ok'
|
||||
).
|
||||
|
||||
notify_subscriptions(Host, Pubsub_Host, {U,S,_} = _Entity, NodeId,
|
||||
Notification_Type, Recipients, Subscriptions) ->
|
||||
Pubsub_Component_Jid = jlib:make_jid(<<>>, Pubsub_Host, <<>>),
|
||||
Jids = [pubsub_tools:make_jid(Recipient) || Recipient <- Recipients],
|
||||
lists:foreach(fun
|
||||
({_, SubId, Resource, _}) ->
|
||||
Subscriber = jlib:jid_to_string({U,S,Resource}),
|
||||
lists:foreach(fun
|
||||
(Recipient) ->
|
||||
spawn(pubsub_broadcast, notify_subscription,
|
||||
[Host, NodeId, Pubsub_Component_Jid, Recipient,
|
||||
Notification_Type, {Subscriber, 'none', SubId}])
|
||||
end, Jids)
|
||||
end, Subscriptions).
|
||||
|
||||
%%
|
||||
filter_purged_offline_itemids([Publisher_ItemId | Publisher_ItemIds],
|
||||
Table_Pubsub_Item, NodeIdx, {U,S,R} = _Entity,
|
||||
{Node_ItemIds, Unpurged_ItemIds, Purged_ItemIds}) ->
|
||||
filter_purged_offline_itemids(Publisher_ItemIds, Table_Pubsub_Item, NodeIdx,
|
||||
{U,S,R},
|
||||
case
|
||||
mnesia:dirty_index_match_object(Table_Pubsub_Item,
|
||||
#pubsub_item_dev{
|
||||
id = {Publisher_ItemId, NodeIdx},
|
||||
nodeidx = NodeIdx,
|
||||
_ = '_'
|
||||
},
|
||||
nodeidx)
|
||||
of
|
||||
[#pubsub_item_dev{creation = {_DateTime, {U,S,_}}} = Pubsub_Item] ->
|
||||
mnesia:dirty_delete_object(Table_Pubsub_Item, Pubsub_Item);
|
||||
_ ->
|
||||
{Node_ItemIds,
|
||||
[Publisher_ItemId | Unpurged_ItemIds],
|
||||
Purged_ItemIds}
|
||||
end).
|
||||
|
||||
|
||||
%%
|
||||
-spec(filter_tempsub_subscriptions/5 ::
|
||||
(
|
||||
Notify_Sub :: boolean() | 'none',
|
||||
Subscriptions :: [] | exmpp_pubsub:subscriptions(),
|
||||
Offline_Resource :: xmpp_jid:resource_jid(),
|
||||
Online_Resources :: boolean(),
|
||||
Filtered_TempSub_Subscriptions :: {
|
||||
Unexpired_Subscriptions :: [] | exmpp_pubsub:subscriptions(),
|
||||
Expired_Subscriptions :: [] | exmpp_pubsub:subscriptions()
|
||||
})
|
||||
-> Filtered_TempSub_Subscriptions :: {
|
||||
Unexpired_Subscriptions :: [] | exmpp_pubsub:subscriptions(),
|
||||
Expired_Subscriptions :: [] | exmpp_pubsub:subscriptions()
|
||||
}
|
||||
).
|
||||
|
||||
filter_tempsub_subscriptions(_Notify_Sub, [] = _Subscriptions,
|
||||
_Offline_Resource, _Online_Resources, Filtered_TempSub_Subscriptions) ->
|
||||
Filtered_TempSub_Subscriptions;
|
||||
%%
|
||||
filter_tempsub_subscriptions(Notify_Sub,
|
||||
[{Subscription_State, SubId, Resource, Subscription_Options} | Subscriptions],
|
||||
Offline_Resource, Online_Resources,
|
||||
{Unexpired_Subscriptions, Expired_Subscriptions})
|
||||
when ((Online_Resources == false
|
||||
andalso
|
||||
(Resource == undefined orelse Resource == Offline_Resource))
|
||||
orelse
|
||||
(Online_Resources == true
|
||||
andalso
|
||||
Resource == Offline_Resource)) ->
|
||||
filter_tempsub_subscriptions(Notify_Sub, Subscriptions, Offline_Resource,
|
||||
Online_Resources,
|
||||
{Unexpired_Subscriptions,
|
||||
_Expired_Subscriptions = case Notify_Sub of
|
||||
true ->
|
||||
[{Subscription_State, SubId, Resource, Subscription_Options}
|
||||
| Expired_Subscriptions];
|
||||
_ ->
|
||||
Expired_Subscriptions
|
||||
end});
|
||||
%%
|
||||
filter_tempsub_subscriptions(Notify_Sub, [Subscription | Subscriptions],
|
||||
Offline_Resource, Online_Resources,
|
||||
{Unexpired_Subscriptions, Expired_Subscriptions}) ->
|
||||
filter_tempsub_subscriptions(Notify_Sub, Subscriptions, Offline_Resource,
|
||||
Online_Resources,
|
||||
{[Subscription | Unexpired_Subscriptions], Expired_Subscriptions}).
|
||||
|
||||
%%
|
||||
-spec(filter_expired_subscriptions/5 ::
|
||||
(
|
||||
Notify_Sub :: boolean() | 'none',
|
||||
Subscriptions :: [] | exmpp_pubsub:subscriptions(),
|
||||
Offline_Resource :: xmpp_jid:resource_jid(),
|
||||
Online_Resources :: boolean(),
|
||||
Filtered_Expired_Subscriptions :: {
|
||||
Unexpired_Subscriptions :: [] | exmpp_pubsub:subscriptions(),
|
||||
Expired_Subscriptions :: [] | exmpp_pubsub:subscriptions()
|
||||
})
|
||||
-> Filtered_Expired_Subscriptions :: {
|
||||
Unexpired_Subscriptions :: [] | exmpp_pubsub:subscriptions(),
|
||||
Expired_Subscriptions :: [] | exmpp_pubsub:subscriptions()
|
||||
}
|
||||
).
|
||||
|
||||
filter_expired_subscriptions(_Notify_Sub, [] = _Subscriptions, _Offline_Resource,
|
||||
_Online_Resources, Filtered_Expired_Subscriptions) ->
|
||||
Filtered_Expired_Subscriptions;
|
||||
%%
|
||||
filter_expired_subscriptions(Notify_Sub,
|
||||
[{Subscription_State, SubId, Resource, Subscription_Options} | Subscriptions],
|
||||
Offline_Resource, Online_Resources,
|
||||
{Unexpired_Subscriptions, Expired_Subscriptions})
|
||||
when Subscription_Options =/= []
|
||||
andalso ((Online_Resources == false
|
||||
andalso
|
||||
(Resource == undefined orelse Resource == Offline_Resource))
|
||||
orelse
|
||||
(Online_Resources == true
|
||||
andalso
|
||||
Resource == Offline_Resource)) ->
|
||||
filter_expired_subscriptions(Notify_Sub, Subscriptions, Offline_Resource,
|
||||
Online_Resources,
|
||||
case get_value(Subscription_Options, 'expire') of
|
||||
'presence' ->
|
||||
{Unexpired_Subscriptions,
|
||||
_Expired_Subscriptions = case Notify_Sub of
|
||||
true ->
|
||||
[{Subscription_State, SubId, Resource, Subscription_Options}
|
||||
| Expired_Subscriptions];
|
||||
false ->
|
||||
Expired_Subscriptions
|
||||
end};
|
||||
_ ->
|
||||
{[{Subscription_State, SubId, Resource, Subscription_Options}
|
||||
| Unexpired_Subscriptions],
|
||||
Expired_Subscriptions}
|
||||
end);
|
||||
%%
|
||||
filter_expired_subscriptions(Notify_Sub, [Subscription | Subscriptions],
|
||||
Offline_Resource, Online_Resources,
|
||||
{Unexpired_Subscriptions, Expired_Subscriptions}) ->
|
||||
filter_expired_subscriptions(Notify_Sub, Subscriptions, Offline_Resource,
|
||||
Online_Resources,
|
||||
{[Subscription | Unexpired_Subscriptions], Expired_Subscriptions}).
|
||||
|
||||
|
||||
%%
|
||||
roster_process_item(Roster_Item, Server) ->
|
||||
spawn(pubsub_groups, monitor_roster_groups, [Server, Roster_Item]),
|
||||
Roster_Item.
|
||||
|
||||
|
||||
|
||||
roster_in_subscription(Boolean, User, Server, Jid_Contact,
|
||||
'subscribed' = _Subscription_Type) ->
|
||||
spawn(pubsub_groups, monitor_contacts2,
|
||||
['subscribed', {User, Server, undefined}, Jid_Contact]),
|
||||
Boolean;
|
||||
roster_in_subscription(Boolean, _User, _Server, _JID, _SubscriptionType) ->
|
||||
Boolean.
|
||||
@@ -0,0 +1,113 @@
|
||||
%%% ====================================================================
|
||||
%%% ``The contents of this file are subject to the Erlang Public License,
|
||||
%%% Version 1.1, (the "License"); you may not use this file except in
|
||||
%%% compliance with the License. You should have received a copy of the
|
||||
%%% Erlang Public License along with this software. If not, it can be
|
||||
%%% retrieved via the world wide web at http://www.erlang.org/.
|
||||
%%%
|
||||
%%% Software distributed under the License is distributed on an "AS IS"
|
||||
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%%% the License for the specific language governing rights and limitations
|
||||
%%% under the License.
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2013, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2013, ProcessOne.
|
||||
%%%
|
||||
%%%
|
||||
%%% @copyright 2006-2013 ProcessOne
|
||||
%%% @author Christophe Romain <christophe.romain@process-one.net>
|
||||
%%% [http://www.process-one.net/]
|
||||
%%% @version {@vsn}, {@date} {@time}
|
||||
%%% @end
|
||||
%%% ====================================================================
|
||||
|
||||
%% important note:
|
||||
%% new/1 and free/2 MUST be called inside a transaction bloc
|
||||
|
||||
-module(pubsub_index_dev).
|
||||
-author('christophe.romain@process-one.net').
|
||||
|
||||
-include("pubsub_dev.hrl").
|
||||
|
||||
-export([
|
||||
init/1,
|
||||
new/2,
|
||||
free/3
|
||||
]).
|
||||
|
||||
-import(pubsub_db_mnesia,
|
||||
[
|
||||
table/2
|
||||
]).
|
||||
|
||||
|
||||
%%
|
||||
-spec(init/1 ::
|
||||
(
|
||||
Suffix::atom()) -> 'ok'
|
||||
).
|
||||
|
||||
init(Suffix) ->
|
||||
mnesia:create_table(table('pubsub_index_dev', Suffix),
|
||||
[{disc_copies, [node()]},
|
||||
{record_name, pubsub_index_dev},
|
||||
{attributes, record_info(fields, pubsub_index_dev)}]).
|
||||
|
||||
%%
|
||||
-spec(new/2 ::
|
||||
(
|
||||
Suffix :: atom(),
|
||||
Index :: exmpp_pubsub:index())
|
||||
-> Idx::exmpp_pubsub:nodeIdx()
|
||||
).
|
||||
|
||||
new(Suffix, Index) ->
|
||||
case
|
||||
mnesia:read(Table_Pubsub_Index = table('pubsub_index_dev', Suffix),
|
||||
Index, write)
|
||||
of
|
||||
[#pubsub_index_dev{free = []} = Pubsub_Index] ->
|
||||
mnesia:write(Table_Pubsub_Index,
|
||||
Pubsub_Index#pubsub_index_dev{
|
||||
last = Idx = Pubsub_Index#pubsub_index_dev.last + 1
|
||||
},
|
||||
write),
|
||||
Idx;
|
||||
[#pubsub_index_dev{free = [Idx|Free]} = Pubsub_Index] ->
|
||||
mnesia:write(Table_Pubsub_Index,
|
||||
Pubsub_Index#pubsub_index_dev{
|
||||
free = Free
|
||||
},
|
||||
write),
|
||||
Idx;
|
||||
_ ->
|
||||
mnesia:write(Table_Pubsub_Index,
|
||||
#pubsub_index_dev{index = Index, last = 1, free = []}, write),
|
||||
1
|
||||
end.
|
||||
|
||||
%%
|
||||
-spec(free/3 ::
|
||||
(
|
||||
Suffix :: atom(),
|
||||
Index :: exmpp_pubsub:index(),
|
||||
Idx :: exmpp_pubsub:nodeIdx())
|
||||
-> 'ok'
|
||||
).
|
||||
|
||||
free(Suffix, Index, Idx) ->
|
||||
case
|
||||
mnesia:read(Table_Pubsub_Index = table('pubsub_index_dev', Suffix),
|
||||
Index, write)
|
||||
of
|
||||
[Pubsub_Index] ->
|
||||
mnesia:write(Table_Pubsub_Index,
|
||||
Pubsub_Index#pubsub_index_dev{
|
||||
free = [Idx | Pubsub_Index#pubsub_index_dev.free]
|
||||
},
|
||||
write);
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,685 @@
|
||||
%%% ====================================================================
|
||||
%%% ``The contents of this file are subject to the Erlang Public License,
|
||||
%%% Version 1.1, (the "License"); you may not use this file except in
|
||||
%%% compliance with the License. You should have received a copy of the
|
||||
%%% Erlang Public License along with this software. If not, it can be
|
||||
%%% retrieved via the world wide web at http://www.erlang.org/.
|
||||
%%%
|
||||
%%% Software distributed under the License is distributed on an "AS IS"
|
||||
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%%% the License for the specific language governing rights and limitations
|
||||
%%% under the License.
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2013, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2013, ProcessOne.
|
||||
%%%
|
||||
%%% @copyright 2006-2013 ProcessOne
|
||||
%%% @author Karim Gemayel <karim.gemayel@process-one.net>
|
||||
%%% [http://www.process-one.net/]
|
||||
%%% @version {@vsn}, {@date} {@time}
|
||||
%%% @end
|
||||
%%% ====================================================================
|
||||
|
||||
%%% @headerfile "pubsub_dev.hrl"
|
||||
|
||||
-module(pubsub_tools).
|
||||
-author('karim.gemayel@process-one.net').
|
||||
|
||||
-compile(export_all).
|
||||
|
||||
-include("pubsub_dev.hrl").
|
||||
|
||||
jid_to_string({undefined, S, undefined}) ->
|
||||
jlib:jid_to_string({<<>>, S, <<>>});
|
||||
jid_to_string({undefined, S, R}) ->
|
||||
jlib:jid_to_string({<<>>, S, R});
|
||||
jid_to_string({U, S, undefined}) ->
|
||||
jlib:jid_to_string({U, S, <<>>});
|
||||
jid_to_string(USR) ->
|
||||
jlib:jid_to_string(USR).
|
||||
|
||||
make_jid({undefined, S, undefined}) ->
|
||||
jlib:make_jid(<<>>, S, <<>>);
|
||||
make_jid({U, S, undefined}) ->
|
||||
jlib:make_jid({U, S, <<>>});
|
||||
make_jid(Entity) ->
|
||||
jlib:make_jid(Entity).
|
||||
|
||||
%% @doc Determine if data is a JID
|
||||
-spec(is_jid/1 ::
|
||||
(
|
||||
Data :: binary() | undefined)
|
||||
-> xmpp_jid:entity() | {error, 'jid-malformed'}
|
||||
).
|
||||
|
||||
is_jid(Data) ->
|
||||
try jlib:string_to_jid(Data) of
|
||||
#jid{} = Jid -> Jid
|
||||
catch
|
||||
_Error -> {error, 'jid-malformed'}
|
||||
end.
|
||||
|
||||
%%%
|
||||
%-spec(get_value/2 ::
|
||||
%(
|
||||
% Options :: {Node_Options :: pubsub_options:options_node(),
|
||||
% Item_Options :: [] | pubsub_options:options_item()}
|
||||
% | pubsub_options:options_item()
|
||||
% | pubsub_options:options_node()
|
||||
% | pubsub_options:options_subscription()
|
||||
% | [],
|
||||
% Key :: atom())
|
||||
% -> Value :: atom()
|
||||
% | binary()
|
||||
% | boolean()
|
||||
% | non_neg_integer()
|
||||
% | undefined
|
||||
% | []
|
||||
% | 'none'
|
||||
% | [atom(),...]
|
||||
% | [binary(),...]
|
||||
% | [boolean(),...]
|
||||
% | [non_neg_integer(),...]
|
||||
%).
|
||||
|
||||
get_value({Node_Options, [] = _Item_Options}, Key) ->
|
||||
get_value(Node_Options, Key, 0);
|
||||
%%
|
||||
get_value({Node_Options, Item_Options}, Key) ->
|
||||
case get_value(Item_Options, Key, 'none') of
|
||||
'none' -> get_value(Node_Options, Key, false);
|
||||
Value -> Value
|
||||
end;
|
||||
%%
|
||||
get_value([], _Key) -> 'none';
|
||||
%%
|
||||
get_value(Options, Key) ->
|
||||
get_value(Options, Key, 'none').
|
||||
|
||||
%%%
|
||||
%-spec(get_value/3 ::
|
||||
%(
|
||||
% Options :: {Node_Options :: pubsub_options:options_node(),
|
||||
% Item_Options :: [] | pubsub_options:options_item()}
|
||||
% | pubsub_options:options_item()
|
||||
% | pubsub_options:options_node()
|
||||
% | pubsub_options:options_subscription(),
|
||||
% Key :: atom(),
|
||||
% Default :: term())
|
||||
% -> Value :: atom()
|
||||
% | binary()
|
||||
% | boolean()
|
||||
% | non_neg_integer()
|
||||
% | undefined
|
||||
% | []
|
||||
% | [atom(),...]
|
||||
% | [binary(),...]
|
||||
% | [boolean(),...]
|
||||
% | [non_neg_integer(),...]
|
||||
%).
|
||||
get_value({Node_Options, [] = _Item_Options}, Key, Default) ->
|
||||
get_value(Node_Options, Key, Default);
|
||||
%%
|
||||
get_value({Node_Options, Item_Options}, Key, Default) ->
|
||||
case get_value(Item_Options, Key, 'none') of
|
||||
'none' -> get_value(Node_Options, Key, Default);
|
||||
Value -> Value
|
||||
end;
|
||||
%%
|
||||
get_value(Options, Key, Default) ->
|
||||
case lists:keyfind(Key, 1, Options) of
|
||||
{_Key, Value} -> Value;
|
||||
false -> Default
|
||||
end.
|
||||
|
||||
%%%
|
||||
%-spec(set_value/3 ::
|
||||
%(
|
||||
% Options :: pubsub_options:options_item()
|
||||
% | pubsub_options:options_node()
|
||||
% | pubsub_options:options_subscription(),
|
||||
% Key :: atom(),
|
||||
% Value :: atom()
|
||||
% | binary()
|
||||
% | boolean()
|
||||
% | non_neg_integer()
|
||||
% | undefined
|
||||
% | []
|
||||
% | [atom(),...]
|
||||
% | [binary(),...]
|
||||
% | [boolean(),...]
|
||||
% | [non_neg_integer(),...])
|
||||
% -> Options :: pubsub_options:options_item()
|
||||
% | pubsub_options:options_node()
|
||||
% | pubsub_options:options_subscription()
|
||||
%).
|
||||
|
||||
set_value(Options, Key, Value) ->
|
||||
lists:keyreplace(Key, 1, Options, {Key, Value}).
|
||||
|
||||
%%
|
||||
|
||||
%-spec(get_option/2 ::
|
||||
%(
|
||||
% Options :: {Node_Options :: pubsub_options:options_node(),
|
||||
% Item_Options :: [] | pubsub_options:options_item()}
|
||||
% | pubsub_options:options_item()
|
||||
% | pubsub_options:options_node()
|
||||
% | pubsub_options:options_subscription()
|
||||
% | [],
|
||||
% Key :: atom())
|
||||
% -> Option :: pubsub_options:option_item()
|
||||
% | pubsub_options:option_node()
|
||||
% | pubsub_options:option_subscription()
|
||||
% | 'none'
|
||||
%).
|
||||
|
||||
get_option({Node_Options, [] = _Item_Options}, Key) ->
|
||||
get_option(Node_Options, Key, 'none');
|
||||
%%
|
||||
get_option({Node_Options, Item_Options}, Key) ->
|
||||
case get_option(Item_Options, Key, 'none') of
|
||||
'none' -> get_option(Node_Options, Key, 'none');
|
||||
Option -> Option
|
||||
end;
|
||||
%%
|
||||
get_option([], _Key) -> 'none';
|
||||
%%
|
||||
get_option(Options, Key) ->
|
||||
get_option(Options, Key, 'none').
|
||||
|
||||
%%%
|
||||
%-spec(get_option/3 ::
|
||||
%(
|
||||
% Options :: {Node_Options :: pubsub_options:options_node(),
|
||||
% Item_Options :: [] | pubsub_options:options_item()}
|
||||
% | pubsub_options:options_item()
|
||||
% | pubsub_options:options_node()
|
||||
% | pubsub_options:options_subscription(),
|
||||
% Key :: atom(),
|
||||
% Default :: term())
|
||||
% -> Option :: pubsub_options:option_item()
|
||||
% | pubsub_options:option_node()
|
||||
% | pubsub_options:option_subscription()
|
||||
% | term()
|
||||
%).
|
||||
|
||||
get_option({Node_Options, [] = _Item_Options}, Key, Default) ->
|
||||
get_option(Node_Options, Key, Default);
|
||||
%%
|
||||
get_option({Node_Options, Item_Options}, Key, Default) ->
|
||||
case get_option(Item_Options, Key, 'none') of
|
||||
'none' -> get_option(Node_Options, Key, Default);
|
||||
Option -> Option
|
||||
end;
|
||||
%%
|
||||
get_option(Options, Key, Default) ->
|
||||
case lists:keyfind(Key, 1, Options) of
|
||||
{_Key, Value} -> _Option = {Key, Value};
|
||||
false -> Default
|
||||
end.
|
||||
|
||||
%%
|
||||
-spec(get_entity_roster/1 ::
|
||||
(
|
||||
Entity :: xmpp_jid:usr_entity()
|
||||
| xmpp_jid:entity())
|
||||
-> Roster::[Roster_Item::#roster{}]
|
||||
).
|
||||
|
||||
get_entity_roster({U,S, _R} = _USR_Entity) ->
|
||||
_Roster = ejabberd_hooks:run_fold(roster_get, S, [], [{U,S}]);
|
||||
get_entity_roster(#jid{luser = U, lserver = S} = _Jid_Entity) ->
|
||||
_Roster = get_entity_roster({U,S, undefined}).
|
||||
|
||||
%%
|
||||
-spec(check_access_model/3 ::
|
||||
(
|
||||
Host :: xmpp_jid:raw_jid_component_bare(),
|
||||
Entity :: xmpp_jid:usr_entity(),
|
||||
Criteria :: {Access_Model :: pubsub_options:access_model(),
|
||||
Affiliation :: exmpp_pubsub:affiliation(),
|
||||
Subscriptions :: exmpp_pubsub:subscriptions(),
|
||||
Node_Owners :: [Node_Owner::xmpp_jid:usr_bare(),...],
|
||||
Rosters_Groups_Allowed :: pubsub_options:rosters_groups_allowed()})
|
||||
-> ok
|
||||
%%%
|
||||
| {error, 'forbidden'}
|
||||
).
|
||||
|
||||
check_access_model(_Host, _Entity,
|
||||
{_Access_Model, 'outcast' = _Affiliation, _Subscriptions, _Node_Owners,
|
||||
_Rosters_Groups_Allowed}) ->
|
||||
{error, 'forbidden'};
|
||||
%%
|
||||
check_access_model(_Host, _Entity,
|
||||
{'open' = _Access_Model, _Affiliation, _Subscriptions, _Node_Owners,
|
||||
_Rosters_Groups_Allowed}) ->
|
||||
ok;
|
||||
%%
|
||||
check_access_model(Host, Entity,
|
||||
{'presence' = _Access_Model, _Affiliation, _Subscriptions, Node_Owners,
|
||||
_Rosters_Groups_Allowed}) ->
|
||||
case is_contact_subscribed_to_node_owners(Host, Entity, Node_Owners) of
|
||||
false ->
|
||||
{error, 'forbidden'};
|
||||
_Node_Owner ->
|
||||
ok
|
||||
end;
|
||||
%%
|
||||
check_access_model(_Host, Entity,
|
||||
{'roster' = _Access_Model, _Affiliation, _Subscriptions, _Node_Owners,
|
||||
Rosters_Groups_Allowed}) ->
|
||||
case is_contact_in_allowed_roster_groups(Entity, Rosters_Groups_Allowed) of
|
||||
false ->
|
||||
{error, 'forbidden'};
|
||||
{_Node_Owner, _Roster_Group_Allowed} ->
|
||||
ok
|
||||
end;
|
||||
%%
|
||||
check_access_model(_Host, _Entity,
|
||||
{'whitelist' = _Access_Model, Affiliation, _Subscriptions, _Node_Owners,
|
||||
_Roster_Groups_Allowed})
|
||||
when Affiliation == 'member'
|
||||
%%orelse Affiliation == 'owner'
|
||||
orelse Affiliation == 'publish-only'
|
||||
orelse Affiliation == 'publisher' ->
|
||||
ok;
|
||||
check_access_model(_Host, _Entity,
|
||||
{'whitelist' = _Access_Model, _Affiliation, _Subscriptions, _Node_Owners,
|
||||
_Roster_Groups_Allowed}) ->
|
||||
{error, 'forbidden'};
|
||||
%%
|
||||
check_access_model(_Host, _Entity,
|
||||
{'authorize' = _Access_Model, _Affiliation, Subscriptions, _Node_Owners,
|
||||
_Roster_Groups_Allowed}) ->
|
||||
case has_subscriptions(Subscriptions) of
|
||||
true -> ok;
|
||||
false -> {error, 'forbidden'}
|
||||
end.
|
||||
|
||||
|
||||
|
||||
%%
|
||||
-spec(check_access_model/7 ::
|
||||
(
|
||||
Host :: xmpp_jid:raw_jid_component_bare(),
|
||||
Entity :: xmpp_jid:usr_entity(),
|
||||
Access_Model :: pubsub_options:access_model(),
|
||||
Affiliation :: exmpp_pubsub:affiliation(),
|
||||
Subscriptions :: exmpp_pubsub:subscriptions(),
|
||||
Node_Owners :: [Node_Owner::xmpp_jid:usr_bare(),...],
|
||||
Rosters_Groups_Allowed :: pubsub_options:rosters_groups_allowed())
|
||||
-> ok
|
||||
%%%
|
||||
| {error, 'forbidden'}
|
||||
| {error, 'item-not-found'}
|
||||
).
|
||||
|
||||
check_access_model(_Host, _Entity, _Access_Model, 'owner' = _Affiliation,
|
||||
_Subscriptions, _Node_Owners, _Rosters_Groups_Allowed) ->
|
||||
ok;
|
||||
%%
|
||||
check_access_model(Host, Entity, Access_Model, 'outcast' = _Affiliation,
|
||||
_Subscriptions, Node_Owners, Rosters_Groups_Allowed) ->
|
||||
case Access_Model of
|
||||
%%
|
||||
'open'->
|
||||
{error, 'forbidden'};
|
||||
%%
|
||||
'presence' ->
|
||||
case
|
||||
is_contact_subscribed_to_node_owners(Host, Entity, Node_Owners)
|
||||
of
|
||||
false ->
|
||||
{error, 'item-not-found'};
|
||||
_Node_Owner ->
|
||||
{error, 'forbidden'}
|
||||
end;
|
||||
%%
|
||||
'roster' ->
|
||||
case
|
||||
is_contact_in_allowed_roster_groups(Entity,
|
||||
Rosters_Groups_Allowed)
|
||||
of
|
||||
false ->
|
||||
{error, 'item-not-found'};
|
||||
{_Node_Owner, _Roster_Group_Allowed} ->
|
||||
{error, 'forbidden'}
|
||||
end;
|
||||
%%
|
||||
'authorize' ->
|
||||
{error, 'forbidden'};
|
||||
%%
|
||||
'whitelist' ->
|
||||
{error, 'item-not-found'}
|
||||
end;
|
||||
%%
|
||||
check_access_model(_Host, _Entity, 'open' = _Access_Model, _Affiliation,
|
||||
_Subscriptions, _Node_Owners, _Rosters_Groups_Allowed) ->
|
||||
ok;
|
||||
%%
|
||||
check_access_model(Host, Entity, 'presence' = _Access_Model, _Affiliation,
|
||||
_Subscriptions, Node_Owners, _Rosters_Groups_Allowed) ->
|
||||
case is_contact_subscribed_to_node_owners(Host, Entity, Node_Owners) of
|
||||
false ->
|
||||
{error, 'item-not-found'};
|
||||
_Node_Owner ->
|
||||
ok
|
||||
end;
|
||||
%%
|
||||
check_access_model(_Host, Entity, 'roster' = _Access_Model, _Affiliation,
|
||||
_Subscriptions, _Node_Owners, Rosters_Groups_Allowed) ->
|
||||
case is_contact_in_allowed_roster_groups(Entity, Rosters_Groups_Allowed) of
|
||||
false ->
|
||||
{error, 'item-not-found'};
|
||||
{_Node_Owner, _Roster_Group_Allowed} ->
|
||||
ok
|
||||
end;
|
||||
%%
|
||||
check_access_model(_Host, _Entity, 'whitelist' = _Access_Model, Affiliation,
|
||||
_Subscriptions, _Node_Owners, _Roster_Groups_Allowed) ->
|
||||
case Affiliation of
|
||||
Affiliation
|
||||
when Affiliation == 'member'
|
||||
orelse Affiliation == 'publish-only'
|
||||
orelse Affiliation == 'publisher' ->
|
||||
ok;
|
||||
_Affiliation ->
|
||||
{error, 'item-not-found'}
|
||||
end;
|
||||
%%
|
||||
check_access_model(_Host, _Entity, 'authorize' = _Access_Model, _Affiliation,
|
||||
Subscriptions, _Node_Owners, _Roster_Groups_Allowed) ->
|
||||
case has_subscriptions(Subscriptions) of
|
||||
true ->
|
||||
ok;
|
||||
false ->
|
||||
{error, 'item-not-found'}
|
||||
end.
|
||||
|
||||
|
||||
-spec(check_publish_model/3 ::
|
||||
(
|
||||
Publish_Model :: pubsub_options:publish_model(),
|
||||
Affiliation :: exmpp_pubsub:affiliation(),
|
||||
Subscriptions :: exmpp_pubsub:subscriptions())
|
||||
-> ok
|
||||
%%%
|
||||
| {error, 'forbidden'}
|
||||
).
|
||||
|
||||
check_publish_model('open' = _Publish_Model, _Affiliation, _Subscriptions) ->
|
||||
ok;
|
||||
%%
|
||||
check_publish_model('publishers' = _Publish_Model, Affiliation, _Subscriptions) ->
|
||||
case Affiliation of
|
||||
Affiliation
|
||||
when Affiliation == 'owner'
|
||||
orelse Affiliation == 'publish-only'
|
||||
orelse Affiliation == 'publisher' ->
|
||||
ok;
|
||||
_Affiliation ->
|
||||
{error, 'forbidden'}
|
||||
end;
|
||||
%%
|
||||
check_publish_model('subscribers' = _Publish_Model, Affiliation, Subscriptions) ->
|
||||
case Affiliation of
|
||||
'owner' ->
|
||||
ok;
|
||||
_Affiliation ->
|
||||
case has_subscriptions(Subscriptions) of
|
||||
true ->
|
||||
ok;
|
||||
false ->
|
||||
{error, 'forbidden'}
|
||||
end
|
||||
end.
|
||||
|
||||
%%
|
||||
-spec(has_subscriptions/1 ::
|
||||
(
|
||||
Subscriptions :: exmpp_pubsub:subscriptions())
|
||||
-> Has_Subscriptions::boolean()
|
||||
).
|
||||
|
||||
has_subscriptions([] = _Subscriptions) ->
|
||||
false;
|
||||
has_subscriptions(
|
||||
[{'pending' = _Subscription_State, _SubId, _Resource, _Subscription_Options}]) ->
|
||||
false;
|
||||
has_subscriptions(_Subscriptions) ->
|
||||
true.
|
||||
|
||||
%%
|
||||
%% @doc Check if a contact is subscribed to at least one local node owner
|
||||
%% amongst a list of (remote and local) node owners
|
||||
-spec(is_contact_subscribed_to_node_owners/3 ::
|
||||
(
|
||||
Host :: xmpp_jid:raw_jid_component_bare(),
|
||||
Contact :: xmpp_jid:usr_entity(),
|
||||
Node_Owners :: [] | [Node_Owner::xmpp_jid:usr_bare(),...])
|
||||
-> Is_Contact_Subscribed_To_Node_Owners :: false | xmpp_jid:usr_bare()
|
||||
).
|
||||
|
||||
is_contact_subscribed_to_node_owners(_Host, _Contact, [] = _Node_Owners) ->
|
||||
false;
|
||||
%% The node owner is a local entity, check if the contact is subscribed to it
|
||||
is_contact_subscribed_to_node_owners(Host, Contact,
|
||||
[{_U, Host, _R} = Local_Node_Owner | Node_Owners] = _Node_Owners) ->
|
||||
_Is_Contact_Subscribed_To_Node_Owners = case
|
||||
is_contact_subscribed_to_entity(Contact,
|
||||
_Local_Node_Owner_Roster = get_entity_roster(Local_Node_Owner))
|
||||
of
|
||||
true ->
|
||||
Local_Node_Owner;
|
||||
false ->
|
||||
is_contact_subscribed_to_node_owners(Host, Contact, Node_Owners)
|
||||
end;
|
||||
%% The node owner is a remote entity, don't check if the contact is subscribed to it
|
||||
is_contact_subscribed_to_node_owners(Host, Contact,
|
||||
[_Remote_Node_Owner | Node_Owners] = _Node_Owners) ->
|
||||
is_contact_subscribed_to_node_owners(Host, Contact, Node_Owners).
|
||||
|
||||
%%
|
||||
%% @doc Check if an entity is in a #roster{}
|
||||
%% with #roster.subscription == 'from' or
|
||||
%% with #roster.subscription == 'both'
|
||||
-spec(is_contact_subscribed_to_entity/2 ::
|
||||
(
|
||||
Contact :: xmpp_jid:usr_entity(),
|
||||
Entity_Roster :: [] | [Roster_Item::#roster{},...])
|
||||
-> Is_Contact_Subscribed::boolean()
|
||||
).
|
||||
|
||||
is_contact_subscribed_to_entity(_Contact, [] = _Entity_Roster) ->
|
||||
_Is_Contact_Subscribed = false;
|
||||
%% Contact is included in a #roster{} item with
|
||||
%% a subscription of type 'from' and 'both' (i.e. is subscribed to it)
|
||||
is_contact_subscribed_to_entity({U, S, _R} = _Contact,
|
||||
[#roster{jid = {U, S, _}, subscription = Subscription} = _Roster_Item
|
||||
| _Roster_Items] = _Entity_Roster)
|
||||
when Subscription == 'from' orelse Subscription == 'both' ->
|
||||
_Is_Contact_Subscribed = true;
|
||||
%% Contact is not included in a #roster{} item
|
||||
%% or has a subscription of type different than 'from' and 'both'
|
||||
%% ( i.e. is not subscribed to it),
|
||||
%% check next roster items
|
||||
is_contact_subscribed_to_entity(Contact,
|
||||
[_Roster_Item | Roster_Items] = _Entity_Roster) ->
|
||||
_Is_Contact_Subscribed = is_contact_subscribed_to_entity(Contact,
|
||||
Roster_Items).
|
||||
|
||||
%%
|
||||
-spec(is_contact_in_allowed_roster_groups/2 ::
|
||||
(
|
||||
Contact :: xmpp_jid:usr_entity(),
|
||||
Rosters_Groups_Allowed :: pubsub_options:rosters_groups_allowed())
|
||||
-> Roster_Group_Allowed :: false
|
||||
| {Entity :: xmpp_jid:usr_bare(),
|
||||
Roster_Group :: pubsub_options:roster_group()}
|
||||
).
|
||||
|
||||
is_contact_in_allowed_roster_groups(_Contact, [] = _Rosters_Groups_Allowed) ->
|
||||
false;
|
||||
%%
|
||||
is_contact_in_allowed_roster_groups(Contact,
|
||||
[{Entity, Entity_Roster_Groups_Allowed} | Rosters_Groups_Allowed]
|
||||
= _Rosters_Groups_Allowed) ->
|
||||
case
|
||||
is_contact_in_allowed_roster_group(Contact,
|
||||
_Entity_Roster = get_entity_roster(Entity),
|
||||
Entity_Roster_Groups_Allowed)
|
||||
of
|
||||
false ->
|
||||
is_contact_in_allowed_roster_groups(Contact, Rosters_Groups_Allowed);
|
||||
Roster_Group ->
|
||||
{Entity, Roster_Group}
|
||||
end.
|
||||
|
||||
%%
|
||||
-spec(is_contact_in_allowed_roster_group/3 ::
|
||||
(
|
||||
Contact :: xmpp_jid:usr_entity(),
|
||||
Entity_Roster :: [] | [Roster_Item::#roster{groups::pubsub_options:roster_groups()}],
|
||||
Roster_Groups_Allowed :: [Roster_Group_Allowed::pubsub_options:roster_group(),...])
|
||||
-> Roster_Group :: false | pubsub_options:roster_group()
|
||||
).
|
||||
|
||||
is_contact_in_allowed_roster_group(_Contact, [] = _Entity_Roster,
|
||||
_Roster_Groups_Allowed) ->
|
||||
false;
|
||||
%%
|
||||
is_contact_in_allowed_roster_group({U, S, _R} = _Contact,
|
||||
[#roster{jid = {U, S, _}, subscription = Subscription, groups = Roster_Groups}
|
||||
| _Other_Roster_Items] = _Entity_Roster, Roster_Groups_Allowed)
|
||||
when Subscription == 'from' orelse Subscription == 'both' ->
|
||||
is_contact_in_allowed_roster_group(Roster_Groups, Roster_Groups_Allowed);
|
||||
%%
|
||||
is_contact_in_allowed_roster_group(Contact,
|
||||
[_Roster_Item | Roster_Items] = _Entity_Roster, Roster_Groups_Allowed) ->
|
||||
is_contact_in_allowed_roster_group(Contact, Roster_Items,
|
||||
Roster_Groups_Allowed).
|
||||
|
||||
%%
|
||||
-spec(is_contact_in_allowed_roster_group/2 ::
|
||||
(
|
||||
Roster_Groups :: [] | [Roster_Group::pubsub_options:roster_group()],
|
||||
Roster_Groups_Allowed :: [Roster_Group_Allowed::pubsub_options:roster_group(),...])
|
||||
-> Roster_Group :: false | pubsub_options:roster_group()
|
||||
).
|
||||
|
||||
is_contact_in_allowed_roster_group([] = _Roster_Groups, _Roster_Groups_Allowed) ->
|
||||
false;
|
||||
%%
|
||||
is_contact_in_allowed_roster_group([Roster_Group | Roster_Groups]
|
||||
= _Roster_Groups, Roster_Groups_Allowed) ->
|
||||
case lists:member(Roster_Group, Roster_Groups_Allowed) of
|
||||
true ->
|
||||
Roster_Group;
|
||||
false ->
|
||||
is_contact_in_allowed_roster_group(Roster_Groups,
|
||||
Roster_Groups_Allowed)
|
||||
end.
|
||||
|
||||
%%
|
||||
-spec(get_user_resources/2 ::
|
||||
(
|
||||
User :: binary(),
|
||||
Server :: binary())
|
||||
-> Resources::[Resource::xmpp_jid:resource_jid()]
|
||||
).
|
||||
|
||||
get_user_resources(User, Server) ->
|
||||
ejabberd_sm:get_user_resources(User, Server).
|
||||
|
||||
%%
|
||||
-spec(get_resources_show/2 ::
|
||||
(
|
||||
User :: binary(),
|
||||
Server :: binary())
|
||||
-> Resources_Show :: [{Resource :: xmpp_jid:resource_jid(),
|
||||
Show :: 'away' | 'chat' | 'dnd' | 'online' | 'xa' }]
|
||||
).
|
||||
|
||||
get_resources_show(User, Server) ->
|
||||
_Resources_Show = lists:foldl(fun
|
||||
(Resource, Resources_Show) ->
|
||||
case ejabberd_sm:get_session_pid(User, Server, Resource) of
|
||||
C2SPid when is_pid(C2SPid) ->
|
||||
case ejabberd_c2s:get_presence(C2SPid) of
|
||||
{_User, _Resource, Show, _} ->
|
||||
[{Resource, list_to_atom(Show)} | Resources_Show];
|
||||
_ ->
|
||||
Resources_Show
|
||||
end;
|
||||
_ ->
|
||||
Resources_Show
|
||||
end
|
||||
end, [], _Resources = ejabberd_sm:get_user_resources(User, Server)).
|
||||
|
||||
|
||||
%%
|
||||
-spec(rosters_groups_allowed_cache/2 ::
|
||||
(
|
||||
Rosters_Groups_Allowed :: pubsub_options:rosters_groups_allowed(),
|
||||
Rosters_Groups_Allowed_Cache :: pubsub_options:rosters_groups_allowed())
|
||||
-> Is_Roster_Groups_Cached::boolean()
|
||||
).
|
||||
|
||||
rosters_groups_allowed_cache(_Rosters_Groups_Allowed,
|
||||
[] = _Rosters_Groups_Allowed_Cache) ->
|
||||
false;
|
||||
%%
|
||||
rosters_groups_allowed_cache([] = _Rosters_Groups_Allowed,
|
||||
_Rosters_Groups_Allowed_Cache) ->
|
||||
false;
|
||||
%%
|
||||
rosters_groups_allowed_cache(
|
||||
[{Entity, Roster_Groups_Allowed} | Rosters_Groups_Allowed],
|
||||
Rosters_Groups_Allowed_Cache) ->
|
||||
case lists:keyfind(Entity, 1, Rosters_Groups_Allowed_Cache) of
|
||||
{_Entity, Roster_Groups_Allowed_Cache} ->
|
||||
case
|
||||
roster_groups_allowed_cache(Roster_Groups_Allowed,
|
||||
Roster_Groups_Allowed_Cache)
|
||||
of
|
||||
true ->
|
||||
true;
|
||||
false ->
|
||||
rosters_groups_allowed_cache(Rosters_Groups_Allowed,
|
||||
Rosters_Groups_Allowed_Cache)
|
||||
end;
|
||||
false ->
|
||||
rosters_groups_allowed_cache(Rosters_Groups_Allowed,
|
||||
Rosters_Groups_Allowed_Cache)
|
||||
end.
|
||||
|
||||
%%
|
||||
-spec(roster_groups_allowed_cache/2 ::
|
||||
(
|
||||
Roster_Groups_Allowed :: [Roster_Group_Allowed::pubsub_options:roster_group()],
|
||||
Roster_Groups_Allowed_Cache :: [Roster_Group_Allowed_Cache::pubsub_options:roster_group()])
|
||||
-> Is_Roster_Groups_Cached :: boolean()
|
||||
).
|
||||
|
||||
roster_groups_allowed_cache(_Roster_Groups_Allowed,
|
||||
[] = _Roster_Groups_Allowed_Cache) ->
|
||||
false;
|
||||
%%
|
||||
roster_groups_allowed_cache([] = _Roster_Groups_Allowed,
|
||||
_Roster_Groups_Allowed_Cache) ->
|
||||
false;
|
||||
%%
|
||||
roster_groups_allowed_cache([Roster_Group_Allowed | Roster_Groups_Allowed],
|
||||
Roster_Groups_Allowed_Cache) ->
|
||||
case lists:member(Roster_Group_Allowed, Roster_Groups_Allowed_Cache) of
|
||||
true ->
|
||||
true;
|
||||
false ->
|
||||
roster_groups_allowed_cache(Roster_Groups_Allowed,
|
||||
Roster_Groups_Allowed_Cache)
|
||||
end.
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
-module(xmpp_xdata).
|
||||
|
||||
|
||||
-include("jlib.hrl").
|
||||
-include("ejabberd.hrl").
|
||||
-compile(export_all).
|
||||
|
||||
xmlcdata(CData) ->
|
||||
{xmlcdata, CData}.
|
||||
|
||||
xmlattr(Name, Value) ->
|
||||
% #xmlattr{name = Name, value = Value}.
|
||||
{Name, Value}.
|
||||
|
||||
xmlattr_label(Label) ->
|
||||
xmlattr(<<"label">>, Label).
|
||||
|
||||
xmlattr_type(Type) ->
|
||||
xmlattr(<<"type">>, Type).
|
||||
|
||||
xmlattr_var(Var) ->
|
||||
xmlattr(<<"var">>, Var).
|
||||
|
||||
|
||||
xmlel(NS, Name, Attrs, Children) ->
|
||||
#xmlel{name = Name, attrs = [{<<"xmlns">>, NS} | Attrs], children = Children}.
|
||||
|
||||
xmlel(Name, Attrs, Children) ->
|
||||
xmlel(?NS_XDATA, Name, Attrs, Children).
|
||||
|
||||
xmlel_desc(CData) ->
|
||||
xmlel(<<"desc">>, [], [xmlcdata(CData)]).
|
||||
|
||||
xmlel_value(Value) ->
|
||||
xmlel(<<"value">>, [], [xmlcdata(Value)]).
|
||||
|
||||
xmlel_option({Value, Label}) ->
|
||||
xmlel(<<"option">>, [xmlattr_label(Label)], [xmlel_value(Value)]);
|
||||
xmlel_option(Value) ->
|
||||
xmlel(<<"option">>, [], [xmlel_value(Value)]).
|
||||
|
||||
xmlel_field(Var, Type, Values) ->
|
||||
xmlel(<<"field">>,
|
||||
[xmlattr_var(Var),
|
||||
xmlattr_type(Type)],
|
||||
[xmlel_value(Value) || Value <- Values]).
|
||||
|
||||
xmlel_field(Var, Type, Label, Values, Options) ->
|
||||
xmlel(<<"field">>,
|
||||
[xmlattr_var(Var),
|
||||
xmlattr_label(Label),
|
||||
xmlattr_type(Type)],
|
||||
[xmlel_option(Option) || Option <- Options]
|
||||
++
|
||||
[xmlel_value(Value) || Value <- Values]).
|
||||
|
||||
xmlel_field_boolean(Var, Label, Value) ->
|
||||
xmlel_field(Var, <<"boolean">>, Label, [Value], []).
|
||||
|
||||
%%
|
||||
xmlel_field_fixed(Var, Label, Value) ->
|
||||
xmlel_field(Var, <<"fixed">>, Label, [Value], []).
|
||||
|
||||
%%
|
||||
xmlel_field_hidden(Var, Value) ->
|
||||
xmlel_field(Var, <<"hidden">>, [Value]).
|
||||
|
||||
%%
|
||||
xmlel_field_list_single(Var, Label, Value, Options) ->
|
||||
xmlel_field(Var, <<"list-single">>, Label, [Value], Options).
|
||||
|
||||
%%
|
||||
xmlel_field_list_multi(Var, Label, Values, Options) ->
|
||||
xmlel_field(Var, <<"list-multi">>, Label, Values, Options).
|
||||
|
||||
%%
|
||||
xmlel_field_text_single(Var, Label, undefined = _Text) ->
|
||||
xmlel_field(Var, <<"text-single">>, Label, [], []);
|
||||
%%
|
||||
xmlel_field_text_single(Var, Label, Text) ->
|
||||
xmlel_field(Var, <<"text-single">>, Label, [Text], []).
|
||||
|
||||
%%
|
||||
xmlel_field_text_multi(Var, Label, Values) ->
|
||||
xmlel_field(Var, <<"text-multi">>, Label, Values, []).
|
||||
|
||||
%%
|
||||
xmlel_field_jid_multi(Var, Label, Jids) ->
|
||||
xmlel_field(Var, <<"jid-multi">>, Label, Jids, []).
|
||||
|
||||
%%
|
||||
xmlel_field_jid_single(Var, Label, Jid) ->
|
||||
xmlel_field(Var, <<"jid-single">>, Label, [Jid], []).
|
||||
|
||||
%%
|
||||
xmlel_x(Type, Fields) ->
|
||||
xmlel(<<"x">>, [xmlattr_type(Type)], Fields).
|
||||
|
||||
%%
|
||||
xmlel_title(Title) ->
|
||||
xmlel(<<"title">>, [], [xmlcdata(Title)]).
|
||||
|
||||
%%
|
||||
xmlel_instructions(Instructions) when is_list(Instructions) ->
|
||||
lists:map(fun xmlel_instructions/1, Instructions);
|
||||
%%
|
||||
xmlel_instructions(Instruction) when is_binary(Instruction) ->
|
||||
xmlel(<<"instructions">>, [], [xmlcdata(Instruction)]).
|
||||
@@ -20,11 +20,13 @@
|
||||
{"Allow users to send invites","Permetre que els usuaris envien invitacions"}.
|
||||
{"Allow users to send private messages","Permetre que els usuaris envien missatges privats"}.
|
||||
{"Allow visitors to change nickname","Permetre als visitants canviar el Nickname"}.
|
||||
{"Allow visitors to send private messages to","Permetre als visitants enviar missatges privats a"}.
|
||||
{"Allow visitors to send status text in presence updates","Permetre als visitants enviar text d'estat en les actualitzacions de presència"}.
|
||||
{"Allow visitors to send voice requests","Permetre als visitants enviar peticions de veu"}.
|
||||
{"All Users","Tots els usuaris"}.
|
||||
{"Announcements","Anuncis"}.
|
||||
{"anyone","qualsevol"}.
|
||||
{"A password is required to enter this room","Es necessita password per a entrar en aquesta sala"}.
|
||||
{"A password is required to enter this room","Es necessita contrasenya per a entrar en aquesta sala"}.
|
||||
{"April","Abril"}.
|
||||
{"August","Agost"}.
|
||||
{"Backup","Guardar còpia de seguretat"}.
|
||||
@@ -33,15 +35,17 @@
|
||||
{"Backup to File at ","Desar còpia de seguretat a fitxer en "}.
|
||||
{"Bad format","Format erroni"}.
|
||||
{"Birthday","Aniversari"}.
|
||||
{"Change Password","Canviar password"}.
|
||||
{"Change User Password","Canviar Password d'Usuari"}.
|
||||
{"CAPTCHA web page","Pàgina web del CAPTCHA"}.
|
||||
{"Change Password","Canviar Contrasenya"}.
|
||||
{"Change User Password","Canviar Contrasenya d'Usuari"}.
|
||||
{"Characters not allowed:","Caràcters no permesos:"}.
|
||||
{"Chatroom configuration modified","Configuració de la sala de xat modificada"}.
|
||||
{"Chatroom is created","La sala s'ha creat"}.
|
||||
{"Chatroom is destroyed","La sala s'ha destruït"}.
|
||||
{"Chatroom is started","La sala s'ha iniciat"}.
|
||||
{"Chatroom is stopped","La sala s'ha aturat"}.
|
||||
{"Chatrooms","Sales de xat"}.
|
||||
{"Choose a username and password to register with this server","Tria nom d'usuari i password per a registrar-te en aquest servidor"}.
|
||||
{"Choose a username and password to register with this server","Tria nom d'usuari i contrasenya per a registrar-te en aquest servidor"}.
|
||||
{"Choose modules to stop","Selecciona mòduls a detindre"}.
|
||||
{"Choose storage type of tables","Selecciona el tipus d'almacenament de les taules"}.
|
||||
{"Choose whether to approve this entity's subscription.","Tria si aprova aquesta entitat de subscripció"}.
|
||||
@@ -69,12 +73,14 @@
|
||||
{"Description:","Descripció:"}.
|
||||
{"Disc only copy","Còpia sols en disc"}.
|
||||
{"Displayed Groups:","Mostrar grups:"}.
|
||||
{"Don't tell your password to anybody, not even the administrators of the Jabber server.","No li donis la teva contrasenya a ningú, ni tan sols als administradors del servidor Jabber."}.
|
||||
{"Dump Backup to Text File at ","Exporta còpia de seguretat a fitxer de text en "}.
|
||||
{"Dump to Text File","Exportar a fitxer de text"}.
|
||||
{"Edit Properties","Editar propietats"}.
|
||||
{"Either approve or decline the voice request.","Aprova o denega la petició de veu"}.
|
||||
{"ejabberd IRC module","mòdul ejabberd IRC"}.
|
||||
{"ejabberd MUC module","mòdul ejabberd MUC"}.
|
||||
{"ejabberd Publish-Subscribe module","Mòdul ejannerd Publicar-Subscriure"}.
|
||||
{"ejabberd Publish-Subscribe module","Mòdul ejabberd Publicar-Subscriure"}.
|
||||
{"ejabberd SOCKS5 Bytestreams module","mòdul ejabberd SOCKS5 Bytestreams"}.
|
||||
{"ejabberd vCard module","Mòdul ejabberd vCard"}.
|
||||
{"ejabberd Web Admin","Web d'administració del ejabberd"}.
|
||||
@@ -89,14 +95,16 @@
|
||||
{"Enter path to jabberd14 spool dir","Introdueix la ruta al directori de jabberd14 spools"}.
|
||||
{"Enter path to jabberd14 spool file","Introdueix ruta al fitxer jabberd14 spool"}.
|
||||
{"Enter path to text file","Introdueix ruta al fitxer de text"}.
|
||||
{"Enter the text you see","Introdueix el textque veus"}.
|
||||
{"Enter the text you see","Introdueix el text que veus"}.
|
||||
{"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Introdueix el nom d'usuari i les codificacions de caràcters per a utilitzar als servidors de IRC. Apreta \"Seguent\" per veure més caps per omplir. Apreta \"Completar\" per guardar la configuració. "}.
|
||||
{"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Introdueix el nom d'usuari, les codificacions de caràcters, els ports i contrassenyes per a utilitzar al connectar als servidors de IRC "}.
|
||||
{"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Introdueix el nom d'usuari, les codificacions de caràcters, els ports i contrasenyes per a utilitzar al connectar als servidors de IRC"}.
|
||||
{"Erlang Jabber Server","Servidor Erlang Jabber"}.
|
||||
{"Error","Error"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Exemple: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Excloure Jabber IDs de la comprovació CAPTCHA"}.
|
||||
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportar dades de tots els usuaris del servidor a arxius PIEFXIS (XEP-0227):"}.
|
||||
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportar dades d'usuaris d'un host a arxius PIEFXIS (XEP-0227):"}.
|
||||
{"Failed to extract JID from your voice request approval","No s'ha pogut extraure el JID de la teva aprovació de petició de veu"}.
|
||||
{"Family Name","Cognom"}.
|
||||
{"February","Febrer"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Emplena camps per a buscar usuaris Jabber que concorden"}.
|
||||
@@ -108,8 +116,9 @@
|
||||
{"Get Number of Online Users","Obtenir Número d'Usuaris Connectats"}.
|
||||
{"Get Number of Registered Users","Obtenir Número d'Usuaris Registrats"}.
|
||||
{"Get User Last Login Time","Obtenir la última connexió d'Usuari"}.
|
||||
{"Get User Password","Obtenir Password d'usuari"}.
|
||||
{"Get User Password","Obtenir Contrasenya d'usuari"}.
|
||||
{"Get User Statistics","Obtenir Estadístiques d'Usuari"}.
|
||||
{"Grant voice to this person?","Concedir veu a aquesta persona?"}.
|
||||
{"Group ","Grup "}.
|
||||
{"Groups","Grups"}.
|
||||
{"has been banned","Has sigut banejat"}.
|
||||
@@ -119,7 +128,8 @@
|
||||
{"has been kicked","Has sigut expulsat"}.
|
||||
{" has set the subject to: "," ha posat l'assumpte: "}.
|
||||
{"Host","Host"}.
|
||||
{"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Si vols especificar codificacions de caràcters diferents per a cada servidor IRC emplena aquesta llista amb els valors amb el format '{\"servidor irc\", \"codificació\", port, \"contrassenya\"}'. Aquest servei utilitza per defecte la codificació \"~s\", port ~p, no contrassenya."}.
|
||||
{"If you don't see the CAPTCHA image here, visit the web page.","Si no veus la imatge CAPTCHA açí, visita la pàgina web."}.
|
||||
{"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Si vols especificar codificacions de caràcters diferents per a cada servidor IRC emplena aquesta llista amb els valors amb el format '{\"servidor irc\", \"codificació\", port, \"contrasenya\"}'. Aquest servei utilitza per defecte la codificació \"~s\", port ~p, no contrasenya."}.
|
||||
{"Import Directory","Importar directori"}.
|
||||
{"Import File","Importar fitxer"}.
|
||||
{"Import user data from jabberd14 spool file:","Importar dades d'usuaris de l'arxiu de spool de jabberd14"}.
|
||||
@@ -129,7 +139,7 @@
|
||||
{"Import Users from Dir at ","Importar usuaris des del directori en "}.
|
||||
{"Import Users From jabberd14 Spool Files","Importar usuaris de jabberd14"}.
|
||||
{"Improper message type","Tipus de missatge incorrecte"}.
|
||||
{"Incorrect password","Password incorrecte"}.
|
||||
{"Incorrect password","Contrasenya incorrecta"}.
|
||||
{"Invalid affiliation: ~s","Afiliació invàlida: ~s"}.
|
||||
{"Invalid role: ~s","Rol invàlid: ~s"}.
|
||||
{"IP addresses","Adreça IP"}.
|
||||
@@ -143,7 +153,8 @@
|
||||
{"is now known as","ara es conegut com"}.
|
||||
{"It is not allowed to send private messages","No està permés enviar missatges privats"}.
|
||||
{"It is not allowed to send private messages of type \"groupchat\"","No està permés enviar missatges del tipus \"groupchat\""}.
|
||||
{"It is not allowed to send private messages to the conference","No està permés l'enviament de missatges privats a la sala"}.
|
||||
{"It is not allowed to send private messages to the conference","No està permès l'enviament de missatges privats a la sala"}.
|
||||
{"Jabber Account Registration","Registre de compte Jabber"}.
|
||||
{"Jabber ID","ID Jabber"}.
|
||||
{"Jabber ID ~s is invalid","El Jabber ID ~s no és vàlid"}.
|
||||
{"January","Gener"}.
|
||||
@@ -163,10 +174,10 @@
|
||||
{"List of modules to start","Llista de mòduls a iniciar"}.
|
||||
{"Low level update script","Script d'actualització de baix nivell"}.
|
||||
{"Make participants list public","Crear una llista de participants pública"}.
|
||||
{"Make room captcha protected","Crear una sala protegida per captcha"}.
|
||||
{"Make room CAPTCHA protected","Crear una sala protegida per CAPTCHA"}.
|
||||
{"Make room members-only","Crear una sala de \"només membres\""}.
|
||||
{"Make room moderated","Crear una sala moderada"}.
|
||||
{"Make room password protected","Crear una sala amb password"}.
|
||||
{"Make room password protected","Crear una sala amb contrasenya"}.
|
||||
{"Make room persistent","Crear una sala persistent"}.
|
||||
{"Make room public searchable","Crear una sala pública"}.
|
||||
{"March","Març"}.
|
||||
@@ -176,9 +187,11 @@
|
||||
{"May","Maig"}.
|
||||
{"Membership is required to enter this room","Necessites ser membre d'aquesta sala per a poder entrar"}.
|
||||
{"Members:","Membre:"}.
|
||||
{"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Memoritza la teva contrasenya, o escriu-la en un paper guardat a un lloc segur.A Jabber no hi ha una forma automatitzada de recuperar la teva contrasenya si la oblides."}.
|
||||
{"Memory","Memòria"}.
|
||||
{"Message body","Missatge"}.
|
||||
{"Middle Name","Segon nom"}.
|
||||
{"Minimum interval between voice requests (in seconds)","Interval mínim entre peticions de veu (en segons)"}.
|
||||
{"Moderator privileges required","Es necessita tenir privilegis de moderador"}.
|
||||
{"moderators only","només moderadors"}.
|
||||
{"Modified modules","Mòduls modificats"}.
|
||||
@@ -189,9 +202,11 @@
|
||||
{"Name:","Nom:"}.
|
||||
{"Name","Nom"}.
|
||||
{"Never","Mai"}.
|
||||
{"New Password:","Nova Contrasenya:"}.
|
||||
{"Nickname","Nickname"}.
|
||||
{"Nickname Registration at ","Registre del Nickname en "}.
|
||||
{"Nickname ~s does not exist in the room","El Nickname ~s no existeix a la sala"}.
|
||||
{"nobody","ningú"}.
|
||||
{"No body provided for announce message","No hi ha proveedor per al missatge anunci"}.
|
||||
{"No Data","No hi ha dades"}.
|
||||
{"Node ID","ID del Node"}.
|
||||
@@ -213,14 +228,16 @@
|
||||
{"Offline Messages:","Missatges fora de línia:"}.
|
||||
{"Offline Messages","Missatges offline"}.
|
||||
{"OK","Acceptar"}.
|
||||
{"Old Password:","Antiga contrasenya:"}.
|
||||
{"Online","Connectat"}.
|
||||
{"Online Users","Usuaris conectats"}.
|
||||
{"Online Users:","Usuaris en línia:"}.
|
||||
{"Only deliver notifications to available users","Sols enviar notificacions als usuaris disponibles"}.
|
||||
{"Only moderators and participants are allowed to change the subject in this room","Només els moderadors i participants poden canviar l'assumpte d'aquesta sala"}.
|
||||
{"Only moderators are allowed to change the subject in this room","Només els moderadors poden canviar l'assumpte d'aquesta sala"}.
|
||||
{"Only moderators can approve voice requests","Només els moderadors poden aprovar les peticions de veu"}.
|
||||
{"Only occupants are allowed to send messages to the conference","Sols els ocupants poden enviar missatges a la sala"}.
|
||||
{"Only occupants are allowed to send queries to the conference","Sols els ocupants poden enviar solicituts a la sala"}.
|
||||
{"Only occupants are allowed to send queries to the conference","Sols els ocupants poden enviar sol·licituds a la sala"}.
|
||||
{"Only service administrators are allowed to send service messages","Sols els administradors del servei tenen permís per a enviar missatges de servei"}.
|
||||
{"Options","Opcions"}.
|
||||
{"Organization Name","Nom de la organizació"}.
|
||||
@@ -230,10 +247,11 @@
|
||||
{"Outgoing s2s Servers:","Servidors d'eixida de s2s"}.
|
||||
{"Owner privileges required","Es requerixen privilegis de propietari de la sala"}.
|
||||
{"Packet","Paquet"}.
|
||||
{"Password ~b","Password ~b"}.
|
||||
{"Password:","Password:"}.
|
||||
{"Password","Password"}.
|
||||
{"Password Verification","Verificació del Password"}.
|
||||
{"Password ~b","Contrasenya ~b"}.
|
||||
{"Password:","Contrasenya:"}.
|
||||
{"Password","Contrasenya"}.
|
||||
{"Password Verification:","Verificació de la Contrasenya:"}.
|
||||
{"Password Verification","Verificació de la Contrasenya"}.
|
||||
{"Path to Dir","Ruta al directori"}.
|
||||
{"Path to File","Ruta al fitxer"}.
|
||||
{"Pending","Pendent"}.
|
||||
@@ -241,6 +259,7 @@
|
||||
{"Persist items to storage","Persistir elements al guardar"}.
|
||||
{"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.","Recorda que aquestes opcions només fan còpia de seguretat de la base de dades Mnesia. Si estàs utilitzant el mòdul d'ODBC també deus de fer una còpia de seguretat de la base de dades de SQL a part."}.
|
||||
{"Please, wait for a while before sending new voice request","Si us plau, espera una mica abans d'enviar una nova petició de veu"}.
|
||||
{"Pong","Pong"}.
|
||||
{"Port ~b","Port ~b"}.
|
||||
{"Port","Port"}.
|
||||
@@ -250,14 +269,16 @@
|
||||
{"Publish-Subscribe","Publicar-subscriure't"}.
|
||||
{"PubSub subscriber request","Petició de subscriptor PubSub"}.
|
||||
{"Purge all items when the relevant publisher goes offline","Eliminar tots els elements quan el publicant relevant es desconnecti"}.
|
||||
{"Queries to the conference members are not allowed in this room"," En aquesta sala no es permeten solicituts als membres de la sala"}.
|
||||
{"Queries to the conference members are not allowed in this room"," En aquesta sala no es permeten sol·licituds als membres de la conferència"}.
|
||||
{"RAM and disc copy","Còpia en RAM i disc"}.
|
||||
{"RAM copy","Còpia en RAM"}.
|
||||
{"Raw","en format text"}.
|
||||
{"Really delete message of the day?","Segur que vols eliminar el missatge del dia?"}.
|
||||
{"Recipient is not in the conference room","El receptor no està en la sala de conferència"}.
|
||||
{"Register a Jabber account","Registrar un compte Jabber"}.
|
||||
{"Registered Users:","Usuaris registrats:"}.
|
||||
{"Registered Users","Usuaris registrats"}.
|
||||
{"Register","Registrar"}.
|
||||
{"Registration in mod_irc for ","Registre en mod_irc per a"}.
|
||||
{"Remote copy","Còpia remota"}.
|
||||
{"Remove All Offline Messages","Eliminar tots els missatges offline"}.
|
||||
@@ -294,6 +315,7 @@
|
||||
{"Send announcement to all users on all hosts","Enviar anunci a tots els usuaris de tots els hosts"}.
|
||||
{"September","Setembre"}.
|
||||
{"Server ~b","Servidor ~b"}.
|
||||
{"Server:","Servidor:"}.
|
||||
{"Set message of the day and send to online users","Configurar el missatge del dia i enviar a tots els usuaris"}.
|
||||
{"Set message of the day on all hosts and send to online users","Escriure missatge del dia en tots els hosts i enviar-ho als usuaris connectats"}.
|
||||
{"Shared Roster Groups","Grups de contactes compartits"}.
|
||||
@@ -301,6 +323,7 @@
|
||||
{"Show Ordinary Table","Mostrar Taula Ordinaria"}.
|
||||
{"Shut Down Service","Apager el Servei"}.
|
||||
{"~s invites you to the room ~s","~s et convida a la sala ~s"}.
|
||||
{"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Alguns clients Jabber poden emmagatzemar la teva contrasenya al teu ordinador. Fes servir aquesta característica només si saps que el teu ordinador és segur."}.
|
||||
{"Specify the access model","Especificar el model d'accés"}.
|
||||
{"Specify the event message type","Especifica el tipus de missatge d'event"}.
|
||||
{"Specify the publisher model","Especificar el model del publicant"}.
|
||||
@@ -325,9 +348,18 @@
|
||||
{"Sunday","Diumenge"}.
|
||||
{"That nickname is already in use by another occupant","El Nickname està siguent utilitzat per una altra persona"}.
|
||||
{"That nickname is registered by another person","El nickname ja està registrat per una altra persona"}.
|
||||
{"The captcha is valid.","El captcha es vàlid."}.
|
||||
{"The CAPTCHA is valid.","El CAPTCHA es vàlid."}.
|
||||
{"The CAPTCHA verification has failed","La verificació CAPTCHA ha fallat"}.
|
||||
{"The collections with which a node is affiliated","Les col.leccions amb les que un node està afiliat"}.
|
||||
{"the password is","el password és"}.
|
||||
{"the password is","la contrasenya és"}.
|
||||
{"The password is too weak","La contrasenya és massa simple"}.
|
||||
{"The password of your Jabber account was successfully changed.","La contrasenya del teu compte Jabber s'ha canviat correctament."}.
|
||||
{"There was an error changing the password: ","Hi ha hagut un error canviant la contrasenya: "}.
|
||||
{"There was an error creating the account: ","Hi ha hagut un error creant el compte: "}.
|
||||
{"There was an error deleting the account: ","Hi ha hagut un error esborrant el compte: "}.
|
||||
{"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Això no distingeix majúscules de minúscules: macbeth es el mateix que MacBeth i Macbeth."}.
|
||||
{"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Aquesta pàgina permet crear un compte Jabber en aquest servidor Jabber. El teu JID (Jabber IDentifier; Identificador Jabber) tindrà aquesta forma: usuari@servidor. Si us plau, llegeix amb cura les instruccions per emplenar correctament els camps."}.
|
||||
{"This page allows to unregister a Jabber account in this Jabber server.","Aquesta pàgina permet anul·lar el registre d'un compte Jabber en aquest servidor Jabber."}.
|
||||
{"This participant is kicked from the room because he sent an error message","Aquest participant ha sigut expulsat de la sala perque ha enviat un missatge d'error"}.
|
||||
{"This participant is kicked from the room because he sent an error message to another participant","Aquest participant ha sigut expulsat de la sala perque ha enviat un missatge erroni a un altre participant"}.
|
||||
{"This participant is kicked from the room because he sent an error presence","Aquest participant ha sigut expulsat de la sala perque ha enviat un error de presencia"}.
|
||||
@@ -335,6 +367,7 @@
|
||||
{"Thursday","Dijous"}.
|
||||
{"Time","Data"}.
|
||||
{"Time delay","Temps de retard"}.
|
||||
{"Too many CAPTCHA requests","Massa peticions de CAPTCHA"}.
|
||||
{"To","Per a"}.
|
||||
{"To ~s","A ~s"}.
|
||||
{"Traffic rate limit is exceeded","El llímit de tràfic ha sigut sobrepassat"}.
|
||||
@@ -343,8 +376,10 @@
|
||||
{"Transactions Logged:","Transaccions registrades"}.
|
||||
{"Transactions Restarted:","Transaccions reiniciades"}.
|
||||
{"Tuesday","Dimarts"}.
|
||||
{"Unable to generate a captcha","No s'ha pogut generar un captcha"}.
|
||||
{"Unable to generate a CAPTCHA","No s'ha pogut generar un CAPTCHA"}.
|
||||
{"Unauthorized","No autoritzat"}.
|
||||
{"Unregister a Jabber account","Anul·lar el registre d'un compte Jabber"}.
|
||||
{"Unregister","Anul·lar el registre"}.
|
||||
{"Update ","Actualitzar"}.
|
||||
{"Update","Actualitzar"}.
|
||||
{"Update message of the day (don't send)","Actualitzar el missatge del dia (no enviar)"}.
|
||||
@@ -353,7 +388,9 @@
|
||||
{"Update script","Script d'actualització"}.
|
||||
{"Uptime:","Temps en marxa"}.
|
||||
{"Use of STARTTLS required","És obligatori utilitzar STARTTLS"}.
|
||||
{"User JID","JID del usuari "}.
|
||||
{"User Management","Gestió d'Usuaris"}.
|
||||
{"Username:","Nom d'usuari:"}.
|
||||
{"Users are not allowed to register accounts so quickly","Els usuaris no tenen permís per a crear comptes tan depresa"}.
|
||||
{"Users Last Activity","Última activitat d'usuari"}.
|
||||
{"Users","Usuaris"}.
|
||||
@@ -364,13 +401,21 @@
|
||||
{"Virtual Hosts","Hosts virtuals"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Els visitants no tenen permés canviar el seus Nicknames en esta sala"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Els visitants no poden enviar missatges a tots els ocupants"}.
|
||||
{"Voice request","Petició de veu"}.
|
||||
{"Voice requests are disabled in this conference","Les peticions de veu es troben desactivades en aquesta conferència"}.
|
||||
{"Wednesday","Dimecres"}.
|
||||
{"When to send the last published item","Quan s'ha enviat l'última publicació"}.
|
||||
{"Whether to allow subscriptions","Permetre subscripcions"}.
|
||||
{"You can later change your password using a Jabber client.","Podràs canviar la teva contrasenya més endavant utilitzant un client Jabber."}.
|
||||
{"You have been banned from this room","Has sigut bloquejat en aquesta sala"}.
|
||||
{"You must fill in field \"Nickname\" in the form","Deus d'omplir el camp \"Nickname\" al formulari"}.
|
||||
{"You need a client that supports x:data and CAPTCHA to register","Necessites un client amb suport x:data i de CAPTCHA para poder registrar-te"}.
|
||||
{"You need a client that supports x:data to register the nickname","Necessites un client amb suport x:data per a poder registrar el Nickname"}.
|
||||
{"You need an x:data capable client to configure mod_irc settings","Necessites un client amb suport x:data per a configurar les opcions de mod_irc"}.
|
||||
{"You need an x:data capable client to configure room","Necessites un client amb suport x:data per a configurar la sala"}.
|
||||
{"You need an x:data capable client to search","Necesites un client amb suport x:data per a poder buscar"}.
|
||||
{"You need an x:data capable client to search","Necessites un client amb suport x:data per a poder buscar"}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","La teva llista de privacitat activa ha denegat l'encaminament d'aquesta stanza."}.
|
||||
{"Your contact offline message queue is full. The message has been discarded.","La cua de missatges offline és plena. El missatge ha sigut descartat"}.
|
||||
{"Your Jabber account was successfully created.","El teu compte Jabber ha sigut creat correctament."}.
|
||||
{"Your Jabber account was successfully deleted.","El teu compte Jabber ha sigut esborrat correctament."}.
|
||||
{"Your messages to ~s are being blocked. To unblock them, visit ~s","Els teus missatges per ~s s'estan bloquejant. Per desbloquejar-los, visita ~s"}.
|
||||
+443
-371
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,9 @@
|
||||
{"Allow users to send invites","Povolit uživatelům posílání pozvánek"}.
|
||||
{"Allow users to send private messages","Povolit uživatelům odesílat soukromé zprávy"}.
|
||||
{"Allow visitors to change nickname","Povolit návštěvníkům měnit přezdívku"}.
|
||||
{"Allow visitors to send private messages to","Povolit návštěvníkům odesílat soukromé zprávy"}.
|
||||
{"Allow visitors to send status text in presence updates","Povolit návštěvníkům posílat stavové zprávy ve statusu"}.
|
||||
{"Allow visitors to send voice requests","Povolit uživatelům posílat žádosti o voice práva"}.
|
||||
{"All Users","Všichni uživatelé"}.
|
||||
{"Announcements","Oznámení"}.
|
||||
{"anyone","každému"}.
|
||||
@@ -75,6 +77,7 @@
|
||||
{"Dump Backup to Text File at ","Uložit zálohu do textového souboru na "}.
|
||||
{"Dump to Text File","Uložit do textového souboru"}.
|
||||
{"Edit Properties","Upravit vlastnosti"}.
|
||||
{"Either approve or decline the voice request.","Povolit nebo odmítnout voice žádost."}.
|
||||
{"ejabberd IRC module","ejabberd IRC modul"}.
|
||||
{"ejabberd MUC module","ejabberd MUC modul"}.
|
||||
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe modul"}.
|
||||
@@ -98,8 +101,10 @@
|
||||
{"Erlang Jabber Server","Erlang Jabber Server"}.
|
||||
{"Error","Chyba"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Příklad: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].2\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Vyloučit Jabber ID z procesu CAPTCHA ověřování"}.
|
||||
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportovat všechny uživatele do souboru ve formátu PIEFXIS (XEP-0227):"}.
|
||||
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportovat uživatele na hostiteli do souboru ve formátu PIEFXIS (XEP-0227):"}.
|
||||
{"Failed to extract JID from your voice request approval","Došlo k chybě při získávání Jabber ID z vaší žádosti o voice práva"}.
|
||||
{"Family Name","Příjmení"}.
|
||||
{"February",". února"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Vyplňte políčka pro vyhledání uživatele Jabberu"}.
|
||||
@@ -113,6 +118,7 @@
|
||||
{"Get User Last Login Time","Získat čas podleního přihlášení uživatele"}.
|
||||
{"Get User Password","Získat heslo uživatele"}.
|
||||
{"Get User Statistics","Získat statistiky uživatele"}.
|
||||
{"Grant voice to this person?","Udělit voice práva této osobě?"}.
|
||||
{"Group ","Skupina "}.
|
||||
{"Groups","Skupiny"}.
|
||||
{"has been banned","byl(a) zablokován(a)"}.
|
||||
@@ -122,7 +128,7 @@
|
||||
{"has been kicked","byl(a) vyhozen(a) z místnosti"}.
|
||||
{" has set the subject to: "," změnil(a) téma na: "}.
|
||||
{"Host","Hostitel"}.
|
||||
{"If you don't see the CAPTCHA image here, visit the web page.","Pokud zde nevidíte obrázek CAPTCHE, přejděte na webovou stránku."}.
|
||||
{"If you don't see the CAPTCHA image here, visit the web page.","Pokud zde nevidíte obrázek CAPTCHA, přejděte na webovou stránku."}.
|
||||
{"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Pokud chcete zadat jiné kódování pro IRC servery, vyplňte seznam s hodnotami ve formátu '{\"irc server\",\"encoding\", port, \"password\"}'. Výchozí kódování pro tuto službu je \"~s\", port ~p, empty password."}.
|
||||
{"Import Directory","Import adresáře"}.
|
||||
{"Import File","Import souboru"}.
|
||||
@@ -168,7 +174,7 @@
|
||||
{"List of modules to start","Seznam modulů, které mají být spuštěné"}.
|
||||
{"Low level update script","Nízkoúrovňový aktualizační skript"}.
|
||||
{"Make participants list public","Nastavit seznam účastníků jako veřejný"}.
|
||||
{"Make room captcha protected","Chránit místnost pomocí CAPTCHA"}.
|
||||
{"Make room CAPTCHA protected","Chránit místnost pomocí CAPTCHA"}.
|
||||
{"Make room members-only","Zpřístupnit místnost jen členům"}.
|
||||
{"Make room moderated","Nastavit místnost jako moderovanou"}.
|
||||
{"Make room password protected","Chránit místnost heslem"}.
|
||||
@@ -185,6 +191,7 @@
|
||||
{"Memory","Paměť"}.
|
||||
{"Message body","Tělo zprávy"}.
|
||||
{"Middle Name","Druhé jméno"}.
|
||||
{"Minimum interval between voice requests (in seconds)","Minimální interval mezi žádostmi o voice práva (v sekundách)"}.
|
||||
{"Moderator privileges required","Potřebujete práva moderátora"}.
|
||||
{"moderators only","moderátorům"}.
|
||||
{"Modified modules","Aktualizované moduly"}.
|
||||
@@ -199,6 +206,7 @@
|
||||
{"Nickname","Přezdívka"}.
|
||||
{"Nickname Registration at ","Registrace přezdívky na "}.
|
||||
{"Nickname ~s does not exist in the room","Přezdívka ~s v místnosti neexistuje"}.
|
||||
{"nobody","nikdo"}.
|
||||
{"No body provided for announce message","Zpráva neobsahuje text"}.
|
||||
{"No Data","Žádná data"}.
|
||||
{"Node ID","ID uzlu"}.
|
||||
@@ -227,6 +235,7 @@
|
||||
{"Only deliver notifications to available users","Doručovat upozornění jen právě přihlášeným uživatelům"}.
|
||||
{"Only moderators and participants are allowed to change the subject in this room","Jen moderátoři a účastníci mají povoleno měnit téma této místnosti"}.
|
||||
{"Only moderators are allowed to change the subject in this room","Jen moderátoři mají povoleno měnit téma místnosti"}.
|
||||
{"Only moderators can approve voice requests","Pouze moderátoři mohou schválit žádosti o voice práva"}.
|
||||
{"Only occupants are allowed to send messages to the conference","Jen členové mají povolené zasílat zprávy do konference"}.
|
||||
{"Only occupants are allowed to send queries to the conference","Jen členové mohou odesílat požadavky (query) do konference"}.
|
||||
{"Only service administrators are allowed to send service messages","Pouze správci služby smí odesílat servisní zprávy"}.
|
||||
@@ -250,6 +259,7 @@
|
||||
{"Persist items to storage","Uložit položky natrvalo do úložiště"}.
|
||||
{"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.","Podotýkáme, že tato nastavení budou zálohována do zabudované databáze Mnesia. Pokud používáte ODBC modul, musíte zálohovat svoji SQL databázi samostatně."}.
|
||||
{"Please, wait for a while before sending new voice request","Prosím, počkejte chvíli před posláním nové žádosti o voice práva"}.
|
||||
{"Pong","Pong"}.
|
||||
{"Port ~b","Port ~b"}.
|
||||
{"Port","Port"}.
|
||||
@@ -338,7 +348,7 @@
|
||||
{"Sunday","Neděle"}.
|
||||
{"That nickname is already in use by another occupant","Přezdívka je již používána jiným členem"}.
|
||||
{"That nickname is registered by another person","Přezdívka je zaregistrována jinou osobou"}.
|
||||
{"The captcha is valid.","CAPTCHA souhlasí."}.
|
||||
{"The CAPTCHA is valid.","CAPTCHA souhlasí."}.
|
||||
{"The CAPTCHA verification has failed","Ověření CAPTCHA se nezdařilo"}.
|
||||
{"The collections with which a node is affiliated","Kolekce, se kterými je uzel spřízněn"}.
|
||||
{"the password is","heslo je"}.
|
||||
@@ -357,6 +367,7 @@
|
||||
{"Thursday","Čtvrtek"}.
|
||||
{"Time","Čas"}.
|
||||
{"Time delay","Časový posun"}.
|
||||
{"Too many CAPTCHA requests","Přiliš mnoho CAPTCHA žádostí"}.
|
||||
{"To","Pro"}.
|
||||
{"To ~s","Pro ~s"}.
|
||||
{"Traffic rate limit is exceeded","Byl překročen limit"}.
|
||||
@@ -365,7 +376,6 @@
|
||||
{"Transactions Logged:","Transakce zaznamenána"}.
|
||||
{"Transactions Restarted:","Transakce restartována"}.
|
||||
{"Tuesday","Úterý"}.
|
||||
{"Unable to generate a captcha","Nebylo možné vygenerovat CAPTCHA"}.
|
||||
{"Unable to generate a CAPTCHA","Nebylo možné vygenerovat CAPTCHA"}.
|
||||
{"Unauthorized","Nemáte oprávnění"}.
|
||||
{"Unregister a Jabber account","Zrušte registraci účtu Jabberu"}.
|
||||
@@ -377,7 +387,8 @@
|
||||
{"Update plan","Aktualizovat plán"}.
|
||||
{"Update script","Aktualizované skripty"}.
|
||||
{"Uptime:","Čas běhu:"}.
|
||||
{"Use of STARTTLS required","Je vyžadováno STARTTLS."}.
|
||||
{"Use of STARTTLS required","Je vyžadováno STARTTLS"}.
|
||||
{"User JID","Jabber ID uživatele"}.
|
||||
{"User Management","Správa uživatelů"}.
|
||||
{"Username:","Uživatelské jméno:"}.
|
||||
{"Users are not allowed to register accounts so quickly","Je zakázáno registrovat účty v tak rychlém sledu"}.
|
||||
@@ -390,6 +401,8 @@
|
||||
{"Virtual Hosts","Virtuální hostitelé"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Návštěvníkům této místnosti je zakázáno měnit přezdívku"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Návštevníci nemají povoleno zasílat zprávy všem účastníkům konference"}.
|
||||
{"Voice requests are disabled in this conference","Voice žádosti jsou v této konferenci zakázány"}.
|
||||
{"Voice request","Žádost o voice práva"}.
|
||||
{"Wednesday","Středa"}.
|
||||
{"When to send the last published item","Kdy odeslat poslední publikovanou položku"}.
|
||||
{"Whether to allow subscriptions","Povolit odebírání"}.
|
||||
+370
-315
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
||||
{"Access Rules","Zugangsregeln"}.
|
||||
{"Action on user","Aktion auf Benutzer"}.
|
||||
{"Add Jabber ID","Jabber-ID hinzufügen"}.
|
||||
{"Add New","Neuen hinzufügen"}.
|
||||
{"Add New","Neue hinzufügen"}.
|
||||
{"Add User","Benutzer hinzufügen"}.
|
||||
{"Administration of ","Administration von "}.
|
||||
{"Administration","Verwaltung"}.
|
||||
@@ -16,14 +16,16 @@
|
||||
{"All activity","Alle Aktivitäten"}.
|
||||
{"Allow this Jabber ID to subscribe to this pubsub node?","Dieser Jabber-ID das Abonnement dieses pubsub-Knotens erlauben?"}.
|
||||
{"Allow users to change the subject","Erlaube Benutzern das Thema zu ändern"}.
|
||||
{"Allow users to query other users","Erlaube Benutzern andere Benutzer abzufragen"}.
|
||||
{"Allow users to query other users","Erlaube Benutzern Informationen über andere Benutzer abzufragen"}.
|
||||
{"Allow users to send invites","Erlaube Benutzern Einladungen zu senden"}.
|
||||
{"Allow users to send private messages","Erlaube Benutzern private Nachrichten zu senden"}.
|
||||
{"Allow visitors to change nickname","Erlaube Besuchern ihren Spitznamen zu ändern"}.
|
||||
{"Allow visitors to send status text in presence updates","Erlaube Besuchern einen Text bei Statusänderung zu setzen"}.
|
||||
{"Allow visitors to send private messages to","Erlaube Besuchern das Senden von privaten Nachrichten an"}.
|
||||
{"Allow visitors to send status text in presence updates","Erlaube Besuchern einen Text bei Statusänderung zu senden"}.
|
||||
{"Allow visitors to send voice requests","Anfragen von Sprachrechten für Benutzer erlauben"}.
|
||||
{"All Users","Alle Benutzer"}.
|
||||
{"Announcements","Ankündigungen"}.
|
||||
{"anyone","jeder"}.
|
||||
{"anyone","jeden"}.
|
||||
{"A password is required to enter this room","Sie brauchen ein Passwort um diesen Raum zu betreten"}.
|
||||
{"April","April"}.
|
||||
{"August","August"}.
|
||||
@@ -67,7 +69,7 @@
|
||||
{"Delete Selected","Markierte löschen"}.
|
||||
{"Delete User","Benutzer löschen"}.
|
||||
{"Deliver event notifications","Ereignisbenachrichtigung zustellen"}.
|
||||
{"Deliver payloads with event notifications","Nachrichten mit mit Ereignis-Benachrichtigungen zustellen"}.
|
||||
{"Deliver payloads with event notifications","Nachrichten mit Ereignis-Benachrichtigungen zustellen"}.
|
||||
{"Description:","Beschreibung:"}.
|
||||
{"Disc only copy","Nur auf Festplatte"}.
|
||||
{"Displayed Groups:","Angezeigte Gruppen:"}.
|
||||
@@ -75,6 +77,7 @@
|
||||
{"Dump Backup to Text File at ","Ausgabe der Sicherung in diese Textdatei "}.
|
||||
{"Dump to Text File","Ausgabe in Textdatei"}.
|
||||
{"Edit Properties","Einstellungen ändern"}.
|
||||
{"Either approve or decline the voice request.","Diese Anfrage für Sprachrechte bestätigen oder ablehnen."}.
|
||||
{"ejabberd IRC module","ejabberd IRC-Modul"}.
|
||||
{"ejabberd MUC module","ejabberd MUC-Modul"}.
|
||||
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe-Modul"}.
|
||||
@@ -98,8 +101,10 @@
|
||||
{"Erlang Jabber Server","Erlang Jabber Server"}.
|
||||
{"Error","Fehler"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Beispiel: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Von CAPTCHA Überprüfung ausgeschlossene Jabber IDs"}.
|
||||
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Alle Benutzerdaten des Servers in PIEFXIS Dateien (XEP-0227) exportieren:"}.
|
||||
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Alle Benutzerdaten des Hosts in PIEFXIS Dateien (XEP-0227) exportieren:"}.
|
||||
{"Failed to extract JID from your voice request approval","Fehler beim Auslesen der JID aus der Anfragenbestätigung für Sprachrechte"}.
|
||||
{"Family Name","Nachname"}.
|
||||
{"February","Februar"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Füllen Sie die Felder aus, um nach passenden Jabber-Benutzern zu suchen"}.
|
||||
@@ -113,6 +118,7 @@
|
||||
{"Get User Last Login Time","letzte Anmeldezeit abrufen"}.
|
||||
{"Get User Password","Benutzer-Passwort abrufen"}.
|
||||
{"Get User Statistics","Benutzer-Statistiken abrufen"}.
|
||||
{"Grant voice to this person?","Sprachrechte dieser Person erteilen?"}.
|
||||
{"Group ","Gruppe "}.
|
||||
{"Groups","Gruppen"}.
|
||||
{"has been banned","wurde gebannt"}.
|
||||
@@ -136,7 +142,7 @@
|
||||
{"Incorrect password","Falsches Passwort"}.
|
||||
{"Invalid affiliation: ~s","Ungültige Mitgliedschaft: ~s"}.
|
||||
{"Invalid role: ~s","Ungültige Rolle: ~s"}.
|
||||
{"IP addresses","IP Addresse"}.
|
||||
{"IP addresses","IP Adressen"}.
|
||||
{"IP","IP"}.
|
||||
{"IRC channel (don't put the first #)","IRC Channel (ohne dem ersten #)"}.
|
||||
{"IRC server","IRC Server"}.
|
||||
@@ -153,7 +159,7 @@
|
||||
{"Jabber ID ~s is invalid","Die Jabber-ID ~s ist ungültig"}.
|
||||
{"January","Januar"}.
|
||||
{"Join IRC channel","IRC Channel beitreten"}.
|
||||
{"joins the room","kommt in den Raum"}.
|
||||
{"joins the room","betretet den Raum"}.
|
||||
{"Join the IRC channel here.","Hier den IRC Channel beitreten."}.
|
||||
{"Join the IRC channel in this Jabber ID: ~s","Den IRC Channel mit dieser Jabber ID beitreten: ~s"}.
|
||||
{"July","Juli"}.
|
||||
@@ -168,7 +174,7 @@
|
||||
{"List of modules to start","Liste der zu startenden Module"}.
|
||||
{"Low level update script","Low level Aktualisierungsscript"}.
|
||||
{"Make participants list public","Teilnehmerliste öffentlich machen"}.
|
||||
{"Make room captcha protected","Raum mit Verifizierung (Captcha) versehen"}.
|
||||
{"Make room CAPTCHA protected","Raum mit Verifizierung (Captcha) versehen"}.
|
||||
{"Make room members-only","Raum nur für Mitglieder zugänglich machen"}.
|
||||
{"Make room moderated","Raum moderiert machen"}.
|
||||
{"Make room password protected","Raum mit Passwort schützen"}.
|
||||
@@ -185,6 +191,7 @@
|
||||
{"Memory","Speicher"}.
|
||||
{"Message body","Nachrichtentext"}.
|
||||
{"Middle Name","Zweiter Vorname"}.
|
||||
{"Minimum interval between voice requests (in seconds)","Mindestdauer zwischen Anfragen für Sprachrechte (in Sekunden)"}.
|
||||
{"Moderator privileges required","Moderatorrechte benötigt"}.
|
||||
{"moderators only","ausschliesslich Moderatoren"}.
|
||||
{"Modified modules","Geänderte Module"}.
|
||||
@@ -199,6 +206,7 @@
|
||||
{"Nickname","Benutzername"}.
|
||||
{"Nickname Registration at ","Registrieren des Benutzernames auf"}.
|
||||
{"Nickname ~s does not exist in the room","Der Benutzername ~s existiert im Raum nicht"}.
|
||||
{"nobody","niemanden"}.
|
||||
{"No body provided for announce message","Kein Text für die Ankündigung angegeben"}.
|
||||
{"No Data","Keine Daten"}.
|
||||
{"Node ID","Knoten-ID"}.
|
||||
@@ -227,6 +235,7 @@
|
||||
{"Only deliver notifications to available users","Benachrichtigungen nur an verfügbare Benutzer schicken"}.
|
||||
{"Only moderators and participants are allowed to change the subject in this room","Nur Moderatoren und Mitglieder dürfen das Thema in diesem Raum ändern"}.
|
||||
{"Only moderators are allowed to change the subject in this room","Nur Moderatoren dürfen das Thema in diesem Raum ändern"}.
|
||||
{"Only moderators can approve voice requests","Nur Moderatoren können Anfragen für Sprachrechte bestätigen"}.
|
||||
{"Only occupants are allowed to send messages to the conference","Nur Teilnehmer dürfen Nachrichten an den Raum schicken"}.
|
||||
{"Only occupants are allowed to send queries to the conference","Nur Teilnehmer sind berechtigt Anfragen an die Konferenz zu senden"}.
|
||||
{"Only service administrators are allowed to send service messages","Nur Service-Administratoren sind berechtigt, Servicenachrichten zu versenden"}.
|
||||
@@ -250,6 +259,7 @@
|
||||
{"Persist items to storage","Einträge dauerhaft speichern"}.
|
||||
{"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.","Beachten sie, das diese Optionen nur die eingebaute Mnesia-Datenbank sichern. Wenn sie das ODBC-Modul verwenden, müssen sie die SQL-Datenbank manuell sichern."}.
|
||||
{"Please, wait for a while before sending new voice request","Bitte warten sie ein wenig, bevor sie eine weitere Anfrage für Sprachrechte senden"}.
|
||||
{"Pong","Pong"}.
|
||||
{"Port ~b","Port ~b"}.
|
||||
{"Port","Port"}.
|
||||
@@ -338,7 +348,7 @@
|
||||
{"Sunday","Sonntag"}.
|
||||
{"That nickname is already in use by another occupant","Dieser Benutzername wird bereits von einem Teilnehmer genutzt"}.
|
||||
{"That nickname is registered by another person","Dieser Benutzername wurde bereits von jemand anderem registriert"}.
|
||||
{"The captcha is valid.","Die Verifizierung ist gültig."}.
|
||||
{"The CAPTCHA is valid.","Die Verifizierung ist gültig."}.
|
||||
{"The CAPTCHA verification has failed","Die CAPTCHA Verifizierung schlug fehl"}.
|
||||
{"The collections with which a node is affiliated","Sammlungen, mit denen ein Knoten verknüpft ist"}.
|
||||
{"the password is","das Passwort lautet"}.
|
||||
@@ -350,14 +360,15 @@
|
||||
{"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Groß/Klein-Schreibung spielt hierbei keine Rolle: macbeth ist gleich MacBeth und Macbeth."}.
|
||||
{"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Diese Seite erlaubt das anlegen eines Jabber Kontos auf diesem Jabber Server. Ihre JID (Jabber IDentifier) setzt sich folgend zusammen: benutzername@server. Bitte lesen sie die Hinweise genau durch, um die Felder korrekt auszufüllen."}.
|
||||
{"This page allows to unregister a Jabber account in this Jabber server.","Diese Seite erlaubt es, ein Jabber Konto von diesem Server zu entfernen."}.
|
||||
{"This participant is kicked from the room because he sent an error message","Dieser Teilnehmer wurde aus dem Raum geworfen, da er eine Fehlernachricht gesendet hat"}.
|
||||
{"This participant is kicked from the room because he sent an error message to another participant","Dieser Teilnehmer wurde aus dem Raum geworfen, da er eine Fehlernachricht an einen anderen Teilnehmer gesendet hat"}.
|
||||
{"This participant is kicked from the room because he sent an error message","Dieser Teilnehmer wurde aus dem Raum geworfen, da er eine fehlerhafte Nachricht gesendet hat"}.
|
||||
{"This participant is kicked from the room because he sent an error message to another participant","Dieser Teilnehmer wurde aus dem Raum geworfen, da er eine fehlerhafte Nachricht an einen anderen Teilnehmer gesendet hat"}.
|
||||
{"This participant is kicked from the room because he sent an error presence","Dieser Teilnehmer wurde aus dem Raum gekickt, da er einen fehlerhaften Status gesendet hat"}.
|
||||
{"This room is not anonymous","Dieser Raum ist nicht anonym"}.
|
||||
{"Thursday","Donnerstag"}.
|
||||
{"Time delay","Zeitverzögerung"}.
|
||||
{"Time","Zeit"}.
|
||||
{"To","An"}.
|
||||
{"Too many CAPTCHA requests","Zu viele CAPTCHA Anfragen"}.
|
||||
{"To ~s","An ~s"}.
|
||||
{"Traffic rate limit is exceeded","Datenratenlimit wurde überschritten"}.
|
||||
{"Transactions Aborted:","Abgebrochene Transaktionen:"}.
|
||||
@@ -365,7 +376,6 @@
|
||||
{"Transactions Logged:","Protokollierte Transaktionen:"}.
|
||||
{"Transactions Restarted:","Neu gestartete Transaktionen:"}.
|
||||
{"Tuesday","Dienstag"}.
|
||||
{"Unable to generate a captcha","Konnte Captcha nicht erstellen"}.
|
||||
{"Unable to generate a CAPTCHA","Konnte CAPTCHA nicht erstellen"}.
|
||||
{"Unauthorized","Nicht berechtigt"}.
|
||||
{"Unregister","Abmelden"}.
|
||||
@@ -380,6 +390,7 @@
|
||||
{"Use of STARTTLS required","Verwendung von STARTTLS erforderlich"}.
|
||||
{"User ","Benutzer "}.
|
||||
{"User","Benutzer"}.
|
||||
{"User JID","Benutzer JID"}.
|
||||
{"User Management","Benutzerverwaltung"}.
|
||||
{"Username:","Benutzername:"}.
|
||||
{"Users are not allowed to register accounts so quickly","Benutzer dürfen Konten nicht so schnell registrieren"}.
|
||||
@@ -390,6 +401,8 @@
|
||||
{"Virtual Hosts","Virtuelle Hosts"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Besucher dürfen in diesem Raum ihren Benutzernamen nicht ändern"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Besucher dürfen nicht an alle Teilnehmer Nachrichten verschicken"}.
|
||||
{"Voice request","Anfrage für Sprachrechte"}.
|
||||
{"Voice requests are disabled in this conference","Anfragen für Sprachrechte sind in diesem Raum deaktiviert"}.
|
||||
{"Wednesday","Mittwoch"}.
|
||||
{"When to send the last published item","Wann soll das letzte veröffentlichte Objekt gesendet werden"}.
|
||||
{"Whether to allow subscriptions","Ob Abonnements erlaubt sind"}.
|
||||
+384
-326
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,9 @@
|
||||
{"Allow users to send invites","Επιτρέψετε στους χρήστες να αποστέλλουν προσκλήσεις"}.
|
||||
{"Allow users to send private messages","Επιτρέψετε στους χρήστες να αποστέλλουν ιδιωτικά μηνύματα"}.
|
||||
{"Allow visitors to change nickname","Επιτρέψετε στους επισκέπτες να αλλάζου ψευδώνυμο"}.
|
||||
{"Allow visitors to send private messages to","Επιτρέψετε στους χρήστες να αποστέλλουν ιδιωτικά μηνύματα σε"}.
|
||||
{"Allow visitors to send status text in presence updates","Επιτρέψτε στους επισκέπτες να αποστέλλουν κατάσταση στις ενημερώσεις παρουσίας"}.
|
||||
{"Allow visitors to send voice requests","Επιτρέψτε στους επισκέπτες να στέλνουν αιτήματα φωνής"}.
|
||||
{"All Users","Όλοι οι χρήστες"}.
|
||||
{"Announcements","Ανακοινώσεις"}.
|
||||
{"anyone","οποιοσδήποτε"}.
|
||||
@@ -75,6 +77,7 @@
|
||||
{"Dump Backup to Text File at ","Αποθήκευση Αντιγράφου Ασφαλείας σε αρχείο κειμένου στο "}.
|
||||
{"Dump to Text File","Αποθήκευση σε αρχείο κειμένου"}.
|
||||
{"Edit Properties","Επεξεργασία ιδιοτήτων"}.
|
||||
{"Either approve or decline the voice request.","Είτε εγκρίνετε ή απορρίψτε το αίτημα φωνής."}.
|
||||
{"ejabberd IRC module","ejabberd IRC module"}.
|
||||
{"ejabberd MUC module","ejabberd MUC module"}.
|
||||
{"ejabberd Publish-Subscribe module","ejabberd module Δημοσίευσης-Εγγραφής"}.
|
||||
@@ -98,8 +101,10 @@
|
||||
{"Erlang Jabber Server","Erlang Jabber Διακομιστής"}.
|
||||
{"Error","Σφάλμα"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Παράδειγμα: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Εξαίρεση από τις ταυτότητες Jabber, ή CAPTCHA πρόκληση"}.
|
||||
{"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 από την έγκριση του αιτήματος φωνής σας"}.
|
||||
{"Family Name","Επώνυμο"}.
|
||||
{"February","Φεβρουάριος"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Συμπληρώστε τα πεδία για να αναζητήσετε οποιαδήποτε ταιριάζοντα Jabber χρήστη"}.
|
||||
@@ -113,6 +118,7 @@
|
||||
{"Get User Last Login Time","Έκθεση Τελευταίας Ώρας Σύνδεσης Χρήστη"}.
|
||||
{"Get User Password","Έκθεση Κωδικού Πρόσβασης Χρήστη"}.
|
||||
{"Get User Statistics","Έκθεση Στατιστικών Χρήστη"}.
|
||||
{"Grant voice to this person?","Παραχώρηση φωνής σε αυτό το άτομο;"}.
|
||||
{"Groups","Ομάδες"}.
|
||||
{"Group ","Ομάδα"}.
|
||||
{"has been banned","έχει απαγορευθεί"}.
|
||||
@@ -168,7 +174,7 @@
|
||||
{"List of modules to start","Λίστα των Module για Εκκίνηση"}.
|
||||
{"Low level update script","Προγράμα ενημέρωσης χαμηλού επίπεδου "}.
|
||||
{"Make participants list public","Κάντε κοινό τον κατάλογο συμμετεχόντων"}.
|
||||
{"Make room captcha protected","Κάντε την αίθουσα CAPTCHA προστατεύονομενη"}.
|
||||
{"Make room CAPTCHA protected","Κάντε την αίθουσα CAPTCHA προστατεύονομενη"}.
|
||||
{"Make room members-only","Κάντε την αίθουσα μόνο για μέλη"}.
|
||||
{"Make room moderated","Κάντε την αίθουσα εποπτεύονομενη"}.
|
||||
{"Make room password protected","Κάντε την αίθουσα προστατεύομενη με κωδικό πρόσβασης"}.
|
||||
@@ -185,6 +191,7 @@
|
||||
{"Memory","Μνήμη"}.
|
||||
{"Message body","Περιεχόμενο μηνυμάτως"}.
|
||||
{"Middle Name","Πατρώνυμο"}.
|
||||
{"Minimum interval between voice requests (in seconds)","Ελάχιστο χρονικό διάστημα μεταξύ αιτημάτων φωνής (σε δευτερόλεπτα)"}.
|
||||
{"Moderator privileges required","Aπαιτούνται προνόμια συντονιστή"}.
|
||||
{"moderators only","συντονιστές μόνο"}.
|
||||
{"Modified modules","Τροποποιημένα modules"}.
|
||||
@@ -200,6 +207,7 @@
|
||||
{"Nickname ~s does not exist in the room","Ψευδώνυμο ~s δεν υπάρχει σε αυτή την αίθουσα"}.
|
||||
{"Nickname","Ψευδώνυμο"}.
|
||||
{"No body provided for announce message","Δεν προμηθεύτικε περιεχόμενο ανακοινώσης"}.
|
||||
{"nobody","κανείς"}.
|
||||
{"No Data","Κανένα στοιχείο"}.
|
||||
{"Node ID","Ταυτότητα Κόμβου"}.
|
||||
{"Node not found","Κόμβος δεν βρέθηκε"}.
|
||||
@@ -227,6 +235,7 @@
|
||||
{"Only deliver notifications to available users","Παράδωση κοινοποιήσεων μόνο σε διαθέσιμους χρήστες"}.
|
||||
{"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 service administrators are allowed to send service messages","Μόνο οι διαχειριστές των υπηρεσιών επιτρέπεται να στείλουν υπηρεσιακά μηνύματα"}.
|
||||
@@ -250,6 +259,7 @@
|
||||
{"Persist items to storage","Μονιμη αποθήκευση στοιχείων"}.
|
||||
{"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","Πονγκ"}.
|
||||
{"Port ~b","Θύρα ~b"}.
|
||||
{"Port","Θύρα"}.
|
||||
@@ -338,7 +348,7 @@
|
||||
{"Sunday","Κυριακή"}.
|
||||
{"That nickname is already in use by another occupant","Αυτό το ψευδώνυμο είναι ήδη σε χρήση από άλλον συμμετέχων"}.
|
||||
{"That nickname is registered by another person","Αυτό το ψευδώνυμο είναι καταχωρημένο από άλλο πρόσωπο"}.
|
||||
{"The captcha is valid.","Το captcha είναι έγκυρο."}.
|
||||
{"The CAPTCHA is valid.","Το CAPTCHA είναι έγκυρο."}.
|
||||
{"The CAPTCHA verification has failed","Η επαλήθευση της εικόνας CAPTCHA απέτυχε"}.
|
||||
{"The collections with which a node is affiliated","Οι συλλογές με την οποία είναι ένας κόμβος συνδέεται"}.
|
||||
{"The password is too weak","Ο κωδικός πρόσβασης είναι πολύ ασθενές"}.
|
||||
@@ -357,6 +367,7 @@
|
||||
{"Thursday","Πέμπτη"}.
|
||||
{"Time delay","Χρόνος καθυστέρησης"}.
|
||||
{"Time","Χρόνος"}.
|
||||
{"Too many CAPTCHA requests","Πάρα πολλά αιτήματα CAPTCHA"}.
|
||||
{"To ~s","Πρώς ~s"}.
|
||||
{"To","Πρώς"}.
|
||||
{"Traffic rate limit is exceeded","Υπέρφορτωση"}.
|
||||
@@ -365,8 +376,7 @@
|
||||
{"Transactions Logged:","Καταγραμμένες συναλλαγές:"}.
|
||||
{"Transactions Restarted:","Επανειλημμένες συναλλαγές:"}.
|
||||
{"Tuesday","Τρίτη"}.
|
||||
{"Unable to generate a captcha","Αδήνατο να δημιουργηθεί CAPTCHA"}.
|
||||
{"Unable to generate a CAPTCHA","Αδήνατο να δημιουργηθεί εικόνα CAPTCHA"}.
|
||||
{"Unable to generate a CAPTCHA","Αδήνατο να δημιουργηθεί CAPTCHA"}.
|
||||
{"Unauthorized","Χορίς Εξουσιοδότηση"}.
|
||||
{"Unregister a Jabber account","Καταργήστε την εγγραφή ενός λογαριασμού Jabber"}.
|
||||
{"Unregister","Καταργήση εγγραφής"}.
|
||||
@@ -378,6 +388,7 @@
|
||||
{"Update","Ενημέρωση"}.
|
||||
{"Uptime:","Uptime:"}.
|
||||
{"Use of STARTTLS required","Απαιτείται χρήση STARTTLS "}.
|
||||
{"User JID","JID Χρήστη"}.
|
||||
{"User Management","Διαχείριση χρηστών"}.
|
||||
{"Username:","Όνομα χρήστη"}.
|
||||
{"Users are not allowed to register accounts so quickly","Οι χρήστες δεν επιτρέπεται να εγγραφούν λογαριασμούς τόσο γρήγορα"}.
|
||||
@@ -390,6 +401,8 @@
|
||||
{"Virtual Hosts","εικονικοί κεντρικοί υπολογιστές"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Οι επισκέπτες δεν επιτρέπεται να αλλάξουν τα ψευδώνυμα τους σε αυτή την αίθουσα"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Οι επισκέπτες δεν επιτρέπεται να στείλουν μηνύματα σε όλους τους συμμετέχωντες"}.
|
||||
{"Voice requests are disabled in this conference","Τα αιτήματα φωνής είναι απενεργοποιημένα, σε αυτό το συνέδριο"}.
|
||||
{"Voice request","Αίτημα φωνής"}.
|
||||
{"Wednesday","Τετάρτη"}.
|
||||
{"When to send the last published item","Πότε να αποσταλθεί το τελευταίο στοιχείο που δημοσιεύθηκε"}.
|
||||
{"Whether to allow subscriptions","Εάν επιτρέποντε συνδρομές"}.
|
||||
+371
-316
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,9 @@
|
||||
{"Allow users to send invites","Permesu uzantojn sendi invitojn"}.
|
||||
{"Allow users to send private messages","Permesu uzantojn sendi privatajn mesaĝojn"}.
|
||||
{"Allow visitors to change nickname","Permesu al vizitantoj ŝanĝi siajn kaŝnomojn"}.
|
||||
{"Allow visitors to send private messages to","Permesu uzantojn sendi privatajn mesaĝojn al"}.
|
||||
{"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"}.
|
||||
{"All Users","Ĉiuj Uzantoj"}.
|
||||
{"Announcements","Anoncoj"}.
|
||||
{"anyone","iu ajn"}.
|
||||
@@ -33,8 +35,10 @@
|
||||
{"Backup to File at ","Faru sekurkopion je "}.
|
||||
{"Bad format","Malĝusta formo"}.
|
||||
{"Birthday","Naskiĝtago"}.
|
||||
{"CAPTCHA web page","CAPTCHA teksaĵ-paĝo"}.
|
||||
{"Change Password","Ŝanĝu pasvorton"}.
|
||||
{"Change User Password","Ŝanĝu pasvorton de uzanto"}.
|
||||
{"Characters not allowed:","Karaktroj ne permesata:"}.
|
||||
{"Chatroom configuration modified","Agordo de babilejo ŝanĝita"}.
|
||||
{"Chatroom is created","Babilejo kreita"}.
|
||||
{"Chatroom is destroyed","Babilejo neniigita"}.
|
||||
@@ -69,9 +73,11 @@
|
||||
{"Description:","Priskribo:"}.
|
||||
{"Disc only copy","Nur disk-kopio"}.
|
||||
{"Displayed Groups:","Montrataj grupoj:"}.
|
||||
{"Don't tell your password to anybody, not even the administrators of the Jabber server.","Ne donu vian pasvorton al iun ajn, eĉ ne al la administrantoj de la Ĵabber-servilo."}.
|
||||
{"Dump Backup to Text File at ","Skribu sekurkopion en plata teksto al "}.
|
||||
{"Dump to Text File","Skribu en plata tekst-dosiero"}.
|
||||
{"Edit Properties","Redaktu atributojn"}.
|
||||
{"Either approve or decline the voice request.","Ĉu aprobu, aŭ malaprobu la voĉ-peton."}.
|
||||
{"ejabberd IRC module","ejabberd IRC-modulo"}.
|
||||
{"ejabberd MUC module","ejabberd MUC-modulo"}.
|
||||
{"ejabberd Publish-Subscribe module","ejabberd Public-Abonada modulo"}.
|
||||
@@ -90,13 +96,14 @@
|
||||
{"Enter path to jabberd14 spool file","Enmetu vojon al jabberd14-uzantdosiero"}.
|
||||
{"Enter path to text file","Enmetu vojon al plata teksto"}.
|
||||
{"Enter the text you see","Enmetu montrita teksto"}.
|
||||
{"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Enmetu uzantnomon kaj enkodigoj kiujn vi volas uzi por konektoj al IRC-serviloj. Elektu \"Sekvonto\" por ekhavi pliajn kampojn. Elektu \"Kompletigu\" por savi agordojn."}.
|
||||
{"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Enmetu uzantnomon,j enkodigojn, pordojn kaj pasvortojn kiujn vi volas uzi por konektoj al IRC-serviloj"}.
|
||||
{"Erlang Jabber Server","Erlang-a Jabber-Servilo"}.
|
||||
{"Error","Eraro"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Ekzemplo: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"sekreto\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.iutestservilo.net\", \"utf-8\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Esceptu Ĵabber-identigilojn je CAPTCHA-defio"}.
|
||||
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Eksportu datumojn de ĉiuj uzantoj en servilo al PIEFXIS dosieroj (XEP-0227):"}.
|
||||
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Eksportu datumoj de uzantoj en gastigo al PIEFXIS dosieroj (XEP-0227):"}.
|
||||
{"Failed to extract JID from your voice request approval","Malsukcesis ekstrakti JID-on de via voĉ-pet-aprobo"}.
|
||||
{"Family Name","Lasta Nomo"}.
|
||||
{"February","Februaro"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Kompletigu la formon por serĉi rekonata Jabber-uzanto"}.
|
||||
@@ -110,6 +117,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"}.
|
||||
{"Grant voice to this person?","Koncedu voĉon al ĉi-persono?"}.
|
||||
{"Group ","Grupo "}.
|
||||
{"Groups","Grupoj"}.
|
||||
{"has been banned","estas forbarita"}.
|
||||
@@ -119,6 +127,7 @@
|
||||
{"has been kicked","estas forpelita"}.
|
||||
{" has set the subject to: "," ŝanĝis la temon al: "}.
|
||||
{"Host","Gastigo"}.
|
||||
{"If you don't see the CAPTCHA image here, visit the web page.","Se vi ne vidas la CAPTCHA-imagon jene, vizitu la teksaĵ-paĝon."}.
|
||||
{"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Se vi volas specifi diversajn pordojn, pasvortojn, enkodigojn por IRC-serviloj, kompletigu la jenan liston kun la formo '{\"irc-servilo\", \"enkodigo\", porto, \"pasvorto\"}'. Se ne specifita, ĉi tiu servilo uzas la enkodigo \"~s\", porto ~p, malplena pasvorto."}.
|
||||
{"Import Directory","Importu dosierujo"}.
|
||||
{"Import File","Importu dosieron"}.
|
||||
@@ -144,6 +153,7 @@
|
||||
{"It is not allowed to send private messages","Ne estas permesata sendi privatajn mesaĝojn"}.
|
||||
{"It is not allowed to send private messages of type \"groupchat\"","Malpermesas sendi mesaĝojn de tipo \"groupchat\""}.
|
||||
{"It is not allowed to send private messages to the conference","Nur partoprenantoj rajtas sendi privatajn mesaĝojn al la babilejo"}.
|
||||
{"Jabber Account Registration","Ĵabber-konto registrado"}.
|
||||
{"Jabber ID","Jabber ID"}.
|
||||
{"Jabber ID ~s is invalid","Jabber ID ~s estas nevalida"}.
|
||||
{"January","Januaro"}.
|
||||
@@ -163,7 +173,7 @@
|
||||
{"List of modules to start","Listo de moduloj por starti"}.
|
||||
{"Low level update script","Bazanivela ĝisdatigo-skripto"}.
|
||||
{"Make participants list public","Farigu partoprento-liston publika"}.
|
||||
{"Make room captcha protected","Farigu babilejon protektata per aŭtomata Turingtesto"}.
|
||||
{"Make room CAPTCHA protected","Farigu babilejon protektata 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"}.
|
||||
@@ -176,9 +186,11 @@
|
||||
{"May","Majo"}.
|
||||
{"Membership is required to enter this room","Membreco estas bezonata por eniri ĉi tiun babilejon"}.
|
||||
{"Members:","Membroj:"}.
|
||||
{"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Memoru vian pasvorton, aŭ skribu ĝin sur papero formetata je sekura loko. Je Ĵabber ne ekzistas aŭtomata metodo por reakiri vian pasvorton se vi forgesas ĝin."}.
|
||||
{"Memory","Memoro"}.
|
||||
{"Message body","Teksto de mesaĝo"}.
|
||||
{"Middle Name","Meza Nomo"}.
|
||||
{"Minimum interval between voice requests (in seconds)","Minimuma intervalo inter voĉ-petoj (je sekundoj)"}.
|
||||
{"Moderator privileges required","Moderantaj rajtoj bezonata"}.
|
||||
{"moderators only","moderantoj sole"}.
|
||||
{"Modified modules","Ĝisdatigitaj moduloj"}.
|
||||
@@ -189,9 +201,11 @@
|
||||
{"Name:","Nomo:"}.
|
||||
{"Name","Nomo"}.
|
||||
{"Never","Neniam"}.
|
||||
{"New Password:","Nova Pasvorto:"}.
|
||||
{"Nickname","Kaŝnomo"}.
|
||||
{"Nickname Registration at ","Kaŝnomo-registrado je "}.
|
||||
{"Nickname ~s does not exist in the room","Kaŝnomo ~s ne ekzistas en la babilejo"}.
|
||||
{"nobody","neniu"}.
|
||||
{"No body provided for announce message","Neniu teksto donita por anonc-mesaĝo"}.
|
||||
{"No Data","Neniu datumo"}.
|
||||
{"Node ID","Nodo ID"}.
|
||||
@@ -213,12 +227,14 @@
|
||||
{"Offline Messages:","Liverontaj mesaĝoj"}.
|
||||
{"Offline Messages","Liverontaj mesaĝoj"}.
|
||||
{"OK","Bone"}.
|
||||
{"Old Password:","Malnova Pasvorto:"}.
|
||||
{"Online","Konektata"}.
|
||||
{"Online Users:","Konektataj uzantoj:"}.
|
||||
{"Online Users","Konektataj Uzantoj"}.
|
||||
{"Only deliver notifications to available users","Nur liveru sciigojn al konektataj uzantoj"}.
|
||||
{"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 service administrators are allowed to send service messages","Nur servo-administrantoj rajtas sendi serv-mesaĝojn"}.
|
||||
@@ -233,6 +249,7 @@
|
||||
{"Password ~b","Pasvorto ~b"}.
|
||||
{"Password:","Pasvorto:"}.
|
||||
{"Password","Pasvorto"}.
|
||||
{"Password Verification:","Pasvortkontrolo:"}.
|
||||
{"Password Verification","Pasvortkontrolo"}.
|
||||
{"Path to Dir","Vojo al dosierujo"}.
|
||||
{"Path to File","Voje de dosiero"}.
|
||||
@@ -241,6 +258,7 @@
|
||||
{"Persist items to storage","Savu erojn en konservado"}.
|
||||
{"Ping","Sondaĵo"}.
|
||||
{"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.","Rimarku ke ĉi tiuj elektebloj nur sekurkopias la propran Mnesia-datumbazon. Se vi uzas la ODBC-modulon, vi ankaŭ devas sekurkopii tiujn SQL-datumbazoj aparte."}.
|
||||
{"Please, wait for a while before sending new voice request","Bonvolu atendi iomete antaŭ ol sendi plian voĉ-peton"}.
|
||||
{"Pong","Resondaĵo"}.
|
||||
{"Port ~b","Pordo ~b"}.
|
||||
{"Port","Pordo"}.
|
||||
@@ -256,8 +274,10 @@
|
||||
{"Raw","Kruda"}.
|
||||
{"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 "}.
|
||||
{"Register a Jabber account","Registru Ĵabber-konton"}.
|
||||
{"Registered Users:","Registritaj uzantoj:"}.
|
||||
{"Registered Users","Registritaj uzantoj"}.
|
||||
{"Register","Registru"}.
|
||||
{"Registration in mod_irc for ","Registraĵo en mod_irc de "}.
|
||||
{"Remote copy","Fora kopio"}.
|
||||
{"Remove All Offline Messages","Forigu ĉiujn liverontajn mesaĝojn"}.
|
||||
@@ -294,6 +314,7 @@
|
||||
{"Send announcement to all users","Sendu anoncon al ĉiu uzanto"}.
|
||||
{"September","Septembro"}.
|
||||
{"Server ~b","Servilo ~b"}.
|
||||
{"Server:","Servilo:"}.
|
||||
{"Set message of the day and send to online users","Enmetu mesaĝon de la tago kaj sendu al konektataj uzantoj"}.
|
||||
{"Set message of the day on all hosts and send to online users","Enmetu mesaĝon de la tago je ĉiu gastigo kaj sendu al konektataj uzantoj"}.
|
||||
{"Shared Roster Groups","Komuna Kontaktlist-grupo"}.
|
||||
@@ -301,6 +322,7 @@
|
||||
{"Show Ordinary Table","Montru ordinaran tabelon"}.
|
||||
{"Shut Down Service","Haltigu Servon"}.
|
||||
{"~s invites you to the room ~s","~s invitas vin al la babilejo ~s"}.
|
||||
{"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Kelkaj Ĵabber-klientoj povas memori vian pasvorton je via komputilo. Nur uzu tiun eblon se vi fidas ke via komputilo estas sekura."}.
|
||||
{"Specify the access model","Specifu atingo-modelon"}.
|
||||
{"Specify the event message type","Specifu tipo de event-mesaĝo"}.
|
||||
{"Specify the publisher model","Enmetu publikadan modelon"}.
|
||||
@@ -325,9 +347,18 @@
|
||||
{"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 aŭtomata Turingtesto estas ĝusta"}.
|
||||
{"The CAPTCHA is valid.","La CAPTCHA ĝustas"}.
|
||||
{"The CAPTCHA verification has failed","La CAPTCHA-kontrolado malsukcesis"}.
|
||||
{"The collections with which a node is affiliated","Aro kun kiu nodo estas filigita"}.
|
||||
{"the password is","la pasvorto estas"}.
|
||||
{"The password is too weak","La pasvorto estas ne sufiĉe forta"}.
|
||||
{"The password of your Jabber account was successfully changed.","La pasvorto de via Ĵabber-konto estas sukcese ŝanĝata."}.
|
||||
{"There was an error changing the password: ","Estis eraro dum ŝanĝi de la pasvortro:"}.
|
||||
{"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 is case insensitive: macbeth is the same that MacBeth and Macbeth.","Uskleco ne signifas: macbeth estas la sama ol MacBeth kaj Macbeth."}.
|
||||
{"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Jena paĝo ebligas kreadon de Ĵabber-konto je ĉi-Ĵabber-servilo. Via JID (Ĵabber-IDentigilo) estos ĉi-tiel: uzantnomo@servilo. Bonvolu legu bone la instrukciojn por korekta enmetigo de la kampoj. "}.
|
||||
{"This page allows to unregister a Jabber account in this Jabber server.","Jena pagxo ebligas malregistri Jxabber-konton je ĉi-servilo."}.
|
||||
{"This participant is kicked from the room because he sent an error message","Ĉi tiu partoprenanta estas forpelata de la babilejo pro sendado de erar-mesaĝo"}.
|
||||
{"This participant is kicked from the room because he sent an error message to another participant","Ĉi tiu partoprenanto estas forpelata de la babilejo pro sendo de erar-mesaĝo al alia partoprenanto"}.
|
||||
{"This participant is kicked from the room because he sent an error presence","Ĉi tiu partoprenanto estas forpelata de la babilejo pro sendo de erar-ĉeesto"}.
|
||||
@@ -336,6 +367,7 @@
|
||||
{"Time delay","Prokrasto"}.
|
||||
{"Time","Tempo"}.
|
||||
{"To","Ĝis"}.
|
||||
{"Too many CAPTCHA requests","Tro multaj CAPTCHA-petoj"}.
|
||||
{"To ~s","Al ~s"}.
|
||||
{"Traffic rate limit is exceeded","Trafikrapida limigo superita"}.
|
||||
{"Transactions Aborted:","Transakcioj nuligitaj"}.
|
||||
@@ -343,8 +375,10 @@
|
||||
{"Transactions Logged:","Transakcioj protokolitaj"}.
|
||||
{"Transactions Restarted:","Transakcioj restartitaj"}.
|
||||
{"Tuesday","Mardo"}.
|
||||
{"Unable to generate a captcha","Ne eblis krei aŭtomatas turingteston"}.
|
||||
{"Unable to generate a CAPTCHA","Ne eblis krei CAPTCHA"}.
|
||||
{"Unauthorized","Nepermesita"}.
|
||||
{"Unregister a Jabber account","Malregistru Ĵabber-konton"}.
|
||||
{"Unregister","Malregistru"}.
|
||||
{"Update ","Ĝisdatigu "}.
|
||||
{"Update","Ĝisdatigu"}.
|
||||
{"Update message of the day (don't send)","Ŝanĝu mesaĝon de la tago (ne sendu)"}.
|
||||
@@ -353,7 +387,9 @@
|
||||
{"Update script","Ĝisdatigo-skripto"}.
|
||||
{"Uptime:","Daŭro de funkciado"}.
|
||||
{"Use of STARTTLS required","Uzo de STARTTLS bezonata"}.
|
||||
{"User JID","Uzant-JID"}.
|
||||
{"User Management","Uzanto-administrado"}.
|
||||
{"Username:","Uzantnomo"}.
|
||||
{"Users are not allowed to register accounts so quickly","Ne estas permesata al uzantoj registri tiel rapide"}.
|
||||
{"Users Last Activity","Lasta aktiveco de uzanto"}.
|
||||
{"Users","Uzantoj"}.
|
||||
@@ -364,13 +400,21 @@
|
||||
{"Virtual Hosts","Virtual-gastigoj"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Ne estas permesata al vizitantoj ŝanĝi siajn kaŝnomojn en ĉi tiu ĉambro"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Vizitantoj ne rajtas sendi mesaĝojn al ĉiuj partoprenantoj"}.
|
||||
{"Voice requests are disabled in this conference","Voĉ-petoj estas malebligita en jena babilejo"}.
|
||||
{"Voice request","Voĉ-peto"}.
|
||||
{"Wednesday","Merkredo"}.
|
||||
{"When to send the last published item","Kiam sendi la laste publicitan eron"}.
|
||||
{"Whether to allow subscriptions","Ĉu permesi aboni"}.
|
||||
{"You can later change your password using a Jabber client.","Poste vi povas ŝanĝi vian pasvorton per Ĵabber-kliento."}.
|
||||
{"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"}.
|
||||
{"You need a client that supports x:data to register the nickname","Vi bezonas klienton subtenante x:data-funkcio por registri kaŝnomon"}.
|
||||
{"You need an x:data capable client to configure mod_irc settings","Vi bezonas klienton kun x:data-funkcio por agordi mod_irc"}.
|
||||
{"You need an x:data capable client to configure room","Vi bezonas klienton kun x:data-funkcio por agordi la babilejon"}.
|
||||
{"You need an x:data capable client to search","Vi bezonas klienton kun x:data-funkcio por serĉado"}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","Via aktiva privatec-listo malpermesas enkursigi ĉi-tiun pakaĵon"}.
|
||||
{"Your contact offline message queue is full. The message has been discarded.","Mesaĝo-atendovico de la senkonekta kontakto estas plena. La mesaĝo estas forĵetita"}.
|
||||
{"Your Jabber account was successfully created.","Via Ĵabber-konto estis sukcese kreata."}.
|
||||
{"Your Jabber account was successfully deleted.","Via Ĵabber-konto estas sukcese forigita."}.
|
||||
{"Your messages to ~s are being blocked. To unblock them, visit ~s","Viaj mesaĝoj al ~s estas blokata. Por malbloki ilin, iru al ~s"}.
|
||||
+411
-353
File diff suppressed because it is too large
Load Diff
@@ -14,13 +14,15 @@
|
||||
{"Administrator privileges required","Se necesita privilegios de administrador"}.
|
||||
{"A friendly name for the node","Un nombre sencillo para el nodo"}.
|
||||
{"All activity","Toda la actividad"}.
|
||||
{"Allow this Jabber ID to subscribe to this pubsub node?","¿Deseas permitir a este JabberID que se subscriba a este nodo PubSub?"}.
|
||||
{"Allow this Jabber ID to subscribe to this pubsub node?","¿Deseas permitir a este Jabber ID que se subscriba a este nodo PubSub?"}.
|
||||
{"Allow users to change the subject","Permitir a los usuarios cambiar el asunto"}.
|
||||
{"Allow users to query other users","Permitir a los usuarios consultar a otros usuarios"}.
|
||||
{"Allow users to send invites","Permitir a los usuarios enviar invitaciones"}.
|
||||
{"Allow users to send private messages","Permitir a los usuarios enviar mensajes privados"}.
|
||||
{"Allow visitors to change nickname","Permitir a los visitantes cambiarse el apodo"}.
|
||||
{"Allow visitors to send private messages to","Permitir a los visitantes enviar mensajes privados a"}.
|
||||
{"Allow visitors to send status text in presence updates","Permitir a los visitantes enviar texto de estado en las actualizaciones de presencia"}.
|
||||
{"Allow visitors to send voice requests","Permitir a los visitantes enviar peticiones de voz"}.
|
||||
{"All Users","Todos los usuarios"}.
|
||||
{"Announcements","Anuncios"}.
|
||||
{"anyone","cualquiera"}.
|
||||
@@ -75,6 +77,7 @@
|
||||
{"Dump Backup to Text File at ","Exporta copia de seguridad a fichero de texto en "}.
|
||||
{"Dump to Text File","Exportar a fichero de texto"}.
|
||||
{"Edit Properties","Editar propiedades"}.
|
||||
{"Either approve or decline the voice request.","Aprueba o rechaza la petición de voz."}.
|
||||
{"ejabberd IRC module","Módulo de IRC para ejabberd"}.
|
||||
{"ejabberd MUC module","Módulo de MUC para ejabberd"}.
|
||||
{"ejabberd Publish-Subscribe module","Módulo de Publicar-Subscribir de ejabberd"}.
|
||||
@@ -98,8 +101,10 @@
|
||||
{"Erlang Jabber Server","Servidor Jabber en Erlang"}.
|
||||
{"Error","Error"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Ejemplo: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Excluir Jabber IDs de las pruebas de CAPTCHA"}.
|
||||
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportar datos de todos los usuarios del servidor a ficheros PIEFXIS (XEP-0227):"}.
|
||||
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportar datos de los usuarios de un dominio a ficheros PIEFXIS (XEP-0227):"}.
|
||||
{"Failed to extract JID from your voice request approval","Fallo al extraer el Jabber ID de tu aprobación de petición de voz"}.
|
||||
{"Family Name","Apellido"}.
|
||||
{"February","febrero"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Rellena campos para buscar usuarios Jabber que concuerden"}.
|
||||
@@ -113,6 +118,7 @@
|
||||
{"Get User Last Login Time","Ver fecha de la última conexión de usuario"}.
|
||||
{"Get User Password","Ver contraseña de usuario"}.
|
||||
{"Get User Statistics","Ver estadísticas de usuario"}.
|
||||
{"Grant voice to this person?","¿Conceder voz a esta persona?"}.
|
||||
{"Group ","Grupo "}.
|
||||
{"Groups","Grupos"}.
|
||||
{"has been banned","ha sido bloqueado"}.
|
||||
@@ -168,7 +174,7 @@
|
||||
{"List of modules to start","Lista de módulos a iniciar"}.
|
||||
{"Low level update script","Script de actualización a bajo nivel"}.
|
||||
{"Make participants list public","La lista de participantes es pública"}.
|
||||
{"Make room captcha protected","Proteger la sala con captcha"}.
|
||||
{"Make room CAPTCHA protected","Proteger la sala con CAPTCHA"}.
|
||||
{"Make room members-only","Sala sólo para miembros"}.
|
||||
{"Make room moderated","Sala moderada"}.
|
||||
{"Make room password protected","Proteger la sala con contraseña"}.
|
||||
@@ -185,6 +191,7 @@
|
||||
{"Memory","Memoria"}.
|
||||
{"Message body","Cuerpo del mensaje"}.
|
||||
{"Middle Name","Segundo nombre"}.
|
||||
{"Minimum interval between voice requests (in seconds)","Intervalo mínimo entre peticiones de voz (en segundos)"}.
|
||||
{"Moderator privileges required","Se necesita privilegios de moderador"}.
|
||||
{"moderators only","solo moderadores"}.
|
||||
{"Modified modules","Módulos modificados"}.
|
||||
@@ -199,6 +206,7 @@
|
||||
{"Nickname","Apodo"}.
|
||||
{"Nickname Registration at ","Registro del apodo en "}.
|
||||
{"Nickname ~s does not exist in the room","El apodo ~s no existe en la sala"}.
|
||||
{"nobody","nadie"}.
|
||||
{"No body provided for announce message","No se ha proporcionado cuerpo de mensaje para el anuncio"}.
|
||||
{"No Data","Sin datos"}.
|
||||
{"Node ID","Nodo ID"}.
|
||||
@@ -227,6 +235,7 @@
|
||||
{"Only deliver notifications to available users","Solo enviar notificaciones a los usuarios disponibles"}.
|
||||
{"Only moderators and participants are allowed to change the subject in this room","Solo los moderadores y participantes pueden cambiar el asunto de esta sala"}.
|
||||
{"Only moderators are allowed to change the subject in this room","Solo los moderadores pueden cambiar el asunto de esta sala"}.
|
||||
{"Only moderators can approve voice requests","Solo los moderadores pueden aprobar peticiones de voz"}.
|
||||
{"Only occupants are allowed to send messages to the conference","Solo los ocupantes pueden enviar mensajes a la sala"}.
|
||||
{"Only occupants are allowed to send queries to the conference","Solo los ocupantes pueden enviar solicitudes a la sala"}.
|
||||
{"Only service administrators are allowed to send service messages","Solo los administradores del servicio tienen permiso para enviar mensajes de servicio"}.
|
||||
@@ -250,6 +259,7 @@
|
||||
{"Persist items to storage","Persistir elementos al almacenar"}.
|
||||
{"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.","Ten en cuenta que estas opciones solo harán copia de seguridad de la base de datos Mnesia embebida. Si estás usando ODBC tendrás que hacer también copia de seguridad de tu base de datos SQL."}.
|
||||
{"Please, wait for a while before sending new voice request","Por favor, espera un poco antes de enviar otra petición de voz"}.
|
||||
{"Pong","Pong"}.
|
||||
{"Port ~b","Puerto ~b"}.
|
||||
{"Port","Puerto"}.
|
||||
@@ -338,7 +348,7 @@
|
||||
{"Sunday","domingo"}.
|
||||
{"That nickname is already in use by another occupant","Ese apodo ya está siendo usado por otro ocupante"}.
|
||||
{"That nickname is registered by another person","El apodo ya está registrado por otra persona"}.
|
||||
{"The captcha is valid.","El captcha es válido."}.
|
||||
{"The CAPTCHA is valid.","El CAPTCHA es válido."}.
|
||||
{"The CAPTCHA verification has failed","La verificación de CAPTCHA ha fallado"}.
|
||||
{"The collections with which a node is affiliated","Las colecciones a las que un nodo está afiliado"}.
|
||||
{"the password is","la contraseña es"}.
|
||||
@@ -357,6 +367,7 @@
|
||||
{"Thursday","jueves"}.
|
||||
{"Time delay","Retraso temporal"}.
|
||||
{"Time","Fecha"}.
|
||||
{"Too many CAPTCHA requests","Demasiadas peticiones de CAPTCHA"}.
|
||||
{"To","Para"}.
|
||||
{"To ~s","A ~s"}.
|
||||
{"Traffic rate limit is exceeded","Se ha exedido el límite de tráfico"}.
|
||||
@@ -365,7 +376,6 @@
|
||||
{"Transactions Logged:","Transacciones registradas:"}.
|
||||
{"Transactions Restarted:","Transacciones reiniciadas:"}.
|
||||
{"Tuesday","martes"}.
|
||||
{"Unable to generate a captcha","No se pudo generar un captcha."}.
|
||||
{"Unable to generate a CAPTCHA","No se pudo generar un CAPTCHA"}.
|
||||
{"Unauthorized","No autorizado"}.
|
||||
{"Unregister a Jabber account","Borrar una cuenta Jabber"}.
|
||||
@@ -378,6 +388,7 @@
|
||||
{"Update script","Script de actualización"}.
|
||||
{"Uptime:","Tiempo desde el inicio:"}.
|
||||
{"Use of STARTTLS required","Es obligatorio usar STARTTLS"}.
|
||||
{"User JID","Jabber ID del usuario"}.
|
||||
{"User Management","Administración de usuarios"}.
|
||||
{"Username:","Nombre de usuario:"}.
|
||||
{"Users are not allowed to register accounts so quickly","Los usuarios no tienen permitido crear cuentas con tanta rapidez"}.
|
||||
@@ -390,6 +401,8 @@
|
||||
{"Virtual Hosts","Dominios Virtuales"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Los visitantes no tienen permitido cambiar sus apodos en esta sala"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Los visitantes no pueden enviar mensajes a todos los ocupantes"}.
|
||||
{"Voice request","Petición de voz"}.
|
||||
{"Voice requests are disabled in this conference","Las peticiones de voz están desactivadas en esta sala"}.
|
||||
{"Wednesday","miércoles"}.
|
||||
{"When to send the last published item","Cuando enviar el último elemento publicado"}.
|
||||
{"Whether to allow subscriptions","Permitir subscripciones"}.
|
||||
+374
-318
File diff suppressed because it is too large
Load Diff
@@ -168,7 +168,7 @@
|
||||
{"List of modules to start","Liste des modules à démarrer"}.
|
||||
{"Low level update script","Script de mise à jour de bas-niveau"}.
|
||||
{"Make participants list public","Rendre la liste des participants publique"}.
|
||||
{"Make room captcha protected","Protéger le salon par un captcha"}.
|
||||
{"Make room CAPTCHA protected","Protéger le salon par un CAPTCHA"}.
|
||||
{"Make room members-only","Réserver le salon aux membres uniquement"}.
|
||||
{"Make room moderated","Rendre le salon modéré"}.
|
||||
{"Make room password protected","Protéger le salon par mot de passe"}.
|
||||
@@ -338,7 +338,7 @@
|
||||
{"Sunday","Dimanche"}.
|
||||
{"That nickname is already in use by another occupant","Le pseudo est déjà utilisé par un autre occupant"}.
|
||||
{"That nickname is registered by another person","Le pseudo est enregistré par une autre personne"}.
|
||||
{"The captcha is valid.","Le captcha est valide"}.
|
||||
{"The CAPTCHA is valid.","Le CAPTCHA est valide"}.
|
||||
{"The CAPTCHA verification has failed","La vérification du CAPTCHA a échoué"}.
|
||||
{"The collections with which a node is affiliated","Les collections avec lesquelle un nœud est affilié"}.
|
||||
{"the password is","le mot de passe est"}.
|
||||
@@ -365,7 +365,6 @@
|
||||
{"Transactions Logged:","Transactions journalisées :"}.
|
||||
{"Transactions Restarted:","Transactions redémarrées :"}.
|
||||
{"Tuesday","Mardi"}.
|
||||
{"Unable to generate a captcha","Impossible de générer le captcha"}.
|
||||
{"Unable to generate a CAPTCHA","Impossible de générer le CAPTCHA"}.
|
||||
{"Unauthorized","Non autorisé"}.
|
||||
{"Unregister a Jabber account","Effacer un compte Jabber"}.
|
||||
+373
-315
File diff suppressed because it is too large
Load Diff
@@ -159,7 +159,7 @@
|
||||
{"List of modules to start","Lista de módulos a iniciar"}.
|
||||
{"Low level update script","Script de actualización a baixo nivel"}.
|
||||
{"Make participants list public","A lista de participantes é pública"}.
|
||||
{"Make room captcha protected","Protexer a sala con captcha"}.
|
||||
{"Make room CAPTCHA protected","Protexer a sala con CAPTCHA"}.
|
||||
{"Make room members-only","Sala só para membros"}.
|
||||
{"Make room moderated","Facer sala moderada"}.
|
||||
{"Make room password protected","Protexer a sala con contrasinal"}.
|
||||
@@ -319,7 +319,7 @@
|
||||
{"Sunday","Domingo"}.
|
||||
{"That nickname is already in use by another occupant","Ese alcume que xa está en uso por outro ocupante"}.
|
||||
{"That nickname is registered by another person","O alcume xa está rexistrado por outra persoa"}.
|
||||
{"The captcha is valid.","O Captcha é válido."}.
|
||||
{"The CAPTCHA is valid.","O CAPTCHA é válido."}.
|
||||
{"The collections with which a node is affiliated","As coleccións coas que un nodo está afiliado"}.
|
||||
{"the password is","a contrasinal é"}.
|
||||
{"This participant is kicked from the room because he sent an error message","Este participante é expulsado da sala, xa que enviou unha mensaxe de erro"}.
|
||||
@@ -337,7 +337,6 @@
|
||||
{"Transactions Logged:","Transaccións rexistradas:"}.
|
||||
{"Transactions Restarted:","Transaccións reiniciadas:"}.
|
||||
{"Tuesday","Martes"}.
|
||||
{"Unable to generate a captcha","Non se pode xerar un Captcha"}.
|
||||
{"Unauthorized","Non autorizado"}.
|
||||
{"Update ","Actualizar"}.
|
||||
{"Update","Actualizar"}.
|
||||
+375
-317
File diff suppressed because it is too large
Load Diff
@@ -168,7 +168,7 @@
|
||||
{"List of modules to start","Daftar modul untuk memulai"}.
|
||||
{"Low level update script","Perbaruan naskah tingkat rendah"}.
|
||||
{"Make participants list public","Buat daftar participant diketahui oleh public"}.
|
||||
{"Make room captcha protected","Buat ruangan dilindungi dengan chapta"}.
|
||||
{"Make room CAPTCHA protected","Buat ruangan dilindungi dengan CAPTCHA"}.
|
||||
{"Make room members-only","Buat ruangan hanya untuk member saja"}.
|
||||
{"Make room moderated","Buat ruangan hanya untuk moderator saja"}.
|
||||
{"Make room password protected","Buat ruangan yang dilindungi dengan kata sandi"}.
|
||||
@@ -338,7 +338,7 @@
|
||||
{"Sunday","Minggu"}.
|
||||
{"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 captcha is valid.","Captcha ini benar."}.
|
||||
{"The CAPTCHA is valid.","Captcha ini benar."}.
|
||||
{"The CAPTCHA verification has failed","Verifikasi CAPTCHA telah gagal"}.
|
||||
{"The collections with which a node is affiliated","Koleksi dengan yang berafiliasi dengan sebuah node"}.
|
||||
{"the password is","kata sandi yaitu:"}.
|
||||
@@ -365,7 +365,6 @@
|
||||
{"Transactions Logged:","Transaksi yang ditempuh:"}.
|
||||
{"Transactions Restarted:","Transaksi yang dijalankan ulang:"}.
|
||||
{"Tuesday","Selasa"}.
|
||||
{"Unable to generate a captcha","Tidak dapat menghasilkan captcha"}.
|
||||
{"Unable to generate a CAPTCHA","Tidak dapat menghasilkan CAPTCHA"}.
|
||||
{"Unauthorized","Ditolak"}.
|
||||
{"Unregister a Jabber account","Nonaktifkan akun jabber"}.
|
||||
+371
-313
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,9 @@
|
||||
{"Allow users to send invites","Consentire agli utenti l'invio di inviti"}.
|
||||
{"Allow users to send private messages","Consentire agli utenti l'invio di messaggi privati"}.
|
||||
{"Allow visitors to change nickname","Consentire ai visitatori di cambiare il nickname"}.
|
||||
{"Allow visitors to send private messages to","Consentire agli ospiti l'invio di messaggi privati a"}.
|
||||
{"Allow visitors to send status text in presence updates","Consentire ai visitatori l'invio di testo sullo stato in aggiornamenti sulla presenza"}.
|
||||
{"Allow visitors to send voice requests","Consentire agli ospiti l'invio di richieste di parola"}.
|
||||
{"All Users","Tutti gli utenti"}.
|
||||
{"Announcements","Annunci"}.
|
||||
{"anyone","tutti"}.
|
||||
@@ -33,8 +35,10 @@
|
||||
{"Backup to File at ","Salvataggio sul file "}.
|
||||
{"Bad format","Formato non valido"}.
|
||||
{"Birthday","Compleanno"}.
|
||||
{"CAPTCHA web page","Pagina web CAPTCHA"}.
|
||||
{"Change Password","Modificare la password"}.
|
||||
{"Change User Password","Cambiare la password dell'utente"}.
|
||||
{"Characters not allowed:","Caratteri non consentiti:"}.
|
||||
{"Chatroom configuration modified","Configurazione della stanza modificata"}.
|
||||
{"Chatroom is created","La stanza è creata"}.
|
||||
{"Chatroom is destroyed","La stanza è eliminata"}.
|
||||
@@ -69,9 +73,11 @@
|
||||
{"Description:","Descrizione:"}.
|
||||
{"Disc only copy","Copia su disco soltanto"}.
|
||||
{"Displayed Groups:","Gruppi visualizzati:"}.
|
||||
{"Don't tell your password to anybody, not even the administrators of the Jabber server.","Non comunicare la tua password a nessuno, neppure agli amministratori del server Jabber."}.
|
||||
{"Dump Backup to Text File at ","Trascrivere il salvataggio sul file di testo "}.
|
||||
{"Dump to Text File","Trascrivere su file di testo"}.
|
||||
{"Edit Properties","Modificare le proprietà"}.
|
||||
{"Either approve or decline the voice request.","Approva oppure respingi la richiesta di parola."}.
|
||||
{"ejabberd IRC module","Modulo IRC per ejabberd"}.
|
||||
{"ejabberd MUC module","Modulo MUC per ejabberd"}.
|
||||
{"ejabberd Publish-Subscribe module","Modulo Pubblicazione/Iscrizione (PubSub) per ejabberd"}.
|
||||
@@ -95,8 +101,10 @@
|
||||
{"Erlang Jabber Server","Erlang Jabber Server"}.
|
||||
{"Error","Errore"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Esempio: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"segreto\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.serverdiprova.net\", \"utf-8\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Escludi degli ID Jabber dal passaggio CAPTCHA"}.
|
||||
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Esportare i dati di tutti gli utenti nel server in file PIEFXIS (XEP-0227):"}.
|
||||
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Esportare i dati degli utenti di un host in file PIEFXIS (XEP-0227):"}.
|
||||
{"Failed to extract JID from your voice request approval","Impossibile estrarre il JID dall'approvazione della richiesta di parola"}.
|
||||
{"Family Name","Cognome"}.
|
||||
{"February","Febbraio"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Riempire i campi per la ricerca di utenti Jabber corrispondenti ai criteri"}.
|
||||
@@ -110,6 +118,7 @@
|
||||
{"Get User Last Login Time","Ottenere la data di ultimo accesso dell'utente"}.
|
||||
{"Get User Password","Ottenere la password dell'utente"}.
|
||||
{"Get User Statistics","Ottenere le statistiche dell'utente"}.
|
||||
{"Grant voice to this person?","Dare parola a questa persona?"}.
|
||||
{"Group ","Gruppo "}.
|
||||
{"Groups","Gruppi"}.
|
||||
{"has been banned","è stata/o bandita/o"}.
|
||||
@@ -119,6 +128,7 @@
|
||||
{"has been kicked","è stata/o espulsa/o"}.
|
||||
{" has set the subject to: "," ha modificato l'oggetto in: "}.
|
||||
{"Host","Host"}.
|
||||
{"If you don't see the CAPTCHA image here, visit the web page.","Se qui non vedi l'immagine CAPTCHA, visita la pagina web."}.
|
||||
{"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Se si vogliono specificare differenti porte, password, codifiche per i server IRC, si riempia questo elenco con valori nel formato '{\"server IRC\", \"codifica\", porta, \"password\"}'. Per default questo servizio utilizza la codifica \"~s\", la porta ~p, la password vuota."}.
|
||||
{"Import Directory","Importare una directory"}.
|
||||
{"Import File","Importare un file"}.
|
||||
@@ -144,6 +154,7 @@
|
||||
{"It is not allowed to send private messages","Non è consentito l'invio di messaggi privati"}.
|
||||
{"It is not allowed to send private messages of type \"groupchat\"","Non è consentito l'invio di messaggi privati di tipo \"groupchat\""}.
|
||||
{"It is not allowed to send private messages to the conference","Non è consentito l'invio di messaggi privati alla conferenza"}.
|
||||
{"Jabber Account Registration","Registrazione account Jabber"}.
|
||||
{"Jabber ID","Jabber ID (Jabber ID)"}.
|
||||
{"Jabber ID ~s is invalid","Il Jabber ID ~s non è valido"}.
|
||||
{"January","Gennaio"}.
|
||||
@@ -163,7 +174,7 @@
|
||||
{"List of modules to start","Elenco dei moduli da avviare"}.
|
||||
{"Low level update script","Script di aggiornamento di basso livello"}.
|
||||
{"Make participants list public","Rendere pubblica la lista dei partecipanti"}.
|
||||
{"Make room captcha protected","Rendere la stanza protetta da captcha"}.
|
||||
{"Make room CAPTCHA protected","Rendere la stanza protetta da CAPTCHA"}.
|
||||
{"Make room members-only","Rendere la stanza riservata ai membri"}.
|
||||
{"Make room moderated","Rendere la stanza moderata"}.
|
||||
{"Make room password protected","Rendere la stanza protetta da password"}.
|
||||
@@ -176,9 +187,11 @@
|
||||
{"May","Maggio"}.
|
||||
{"Membership is required to enter this room","Per entrare in questa stanza è necessario essere membro"}.
|
||||
{"Members:","Membri:"}.
|
||||
{"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Memorizza la password, o scrivila su un foglio di carta da conservare in un luogo sicuro. Jabber non prevede una modalità automatica per il recupero di una password dimenticata."}.
|
||||
{"Memory","Memoria"}.
|
||||
{"Message body","Corpo del messaggio"}.
|
||||
{"Middle Name","Altro nome"}.
|
||||
{"Minimum interval between voice requests (in seconds)","Intervallo minimo fra due richieste di parola (in secondi)"}.
|
||||
{"Moderator privileges required","Necessari i privilegi di moderatore"}.
|
||||
{"moderators only","moderatori soltanto"}.
|
||||
{"Modified modules","Moduli modificati"}.
|
||||
@@ -189,9 +202,11 @@
|
||||
{"Name:","Nome:"}.
|
||||
{"Name","Nome"}.
|
||||
{"Never","Mai"}.
|
||||
{"New Password:","Nuova password:"}.
|
||||
{"Nickname","Nickname"}.
|
||||
{"Nickname Registration at ","Registrazione di un nickname su "}.
|
||||
{"Nickname ~s does not exist in the room","Il nickname ~s non esiste nella stanza"}.
|
||||
{"nobody","nessuno"}.
|
||||
{"No body provided for announce message","Nessun corpo fornito per il messaggio di annuncio"}.
|
||||
{"No Data","Nessuna informazione"}.
|
||||
{"Node ID","ID del nodo"}.
|
||||
@@ -213,12 +228,14 @@
|
||||
{"Offline Messages:","Messaggi offline:"}.
|
||||
{"Offline Messages","Messaggi offline"}.
|
||||
{"OK","OK"}.
|
||||
{"Old Password:","Vecchia password:"}.
|
||||
{"Online","Online"}.
|
||||
{"Online Users:","Utenti connessi:"}.
|
||||
{"Online Users","Utenti online"}.
|
||||
{"Only deliver notifications to available users","Inviare le notifiche solamente agli utenti disponibili"}.
|
||||
{"Only moderators and participants are allowed to change the subject in this room","La modifica dell'oggetto di questa stanza è consentita soltanto ai moderatori e ai partecipanti"}.
|
||||
{"Only moderators are allowed to change the subject in this room","La modifica dell'oggetto di questa stanza è consentita soltanto ai moderatori"}.
|
||||
{"Only moderators can approve voice requests","Soltanto i moderatori possono approvare richieste di parola"}.
|
||||
{"Only occupants are allowed to send messages to the conference","L'invio di messaggi alla conferenza è consentito soltanto ai presenti"}.
|
||||
{"Only occupants are allowed to send queries to the conference","L'invio di query alla conferenza è consentito ai soli presenti"}.
|
||||
{"Only service administrators are allowed to send service messages","L'invio di messaggi di servizio è consentito solamente agli amministratori del servizio"}.
|
||||
@@ -233,6 +250,7 @@
|
||||
{"Password ~b","Password ~b"}.
|
||||
{"Password:","Password:"}.
|
||||
{"Password","Password"}.
|
||||
{"Password Verification:","Verifica della password:"}.
|
||||
{"Password Verification","Verifica della password"}.
|
||||
{"Path to Dir","Percorso della directory"}.
|
||||
{"Path to File","Percorso del file"}.
|
||||
@@ -241,6 +259,7 @@
|
||||
{"Persist items to storage","Conservazione persistente degli elementi"}.
|
||||
{"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.","N.B.: Queste opzioni comportano il salvataggio solamente del database interno Mnesia. Se si sta utilizzando il modulo ODBC, è necessario salvare anche il proprio database SQL separatamente."}.
|
||||
{"Please, wait for a while before sending new voice request","Attendi qualche istante prima di inviare una nuova richiesta di parola"}.
|
||||
{"Pong","Pong"}.
|
||||
{"Port ~b","Porta ~b"}.
|
||||
{"Port","Porta"}.
|
||||
@@ -256,8 +275,10 @@
|
||||
{"Raw","Grezzo"}.
|
||||
{"Really delete message of the day?","Si conferma l'eliminazione del messaggio del giorno (MOTD)?"}.
|
||||
{"Recipient is not in the conference room","Il destinatario non è nella stanza per conferenze"}.
|
||||
{"Register a Jabber account","Registra un account Jabber"}.
|
||||
{"Registered Users:","Utenti registrati:"}.
|
||||
{"Registered Users","Utenti registrati"}.
|
||||
{"Register","Registra"}.
|
||||
{"Registration in mod_irc for ","Registrazione in mod_irc per "}.
|
||||
{"Remote copy","Copia remota"}.
|
||||
{"Remove All Offline Messages","Eliminare tutti i messaggi offline"}.
|
||||
@@ -294,6 +315,7 @@
|
||||
{"Send announcement to all users on all hosts","Inviare l'annuncio a tutti gli utenti su tutti gli host"}.
|
||||
{"September","Settembre"}.
|
||||
{"Server ~b","Server ~b"}.
|
||||
{"Server:","Server:"}.
|
||||
{"Set message of the day and send to online users","Impostare il messaggio del giorno (MOTD) ed inviarlo agli utenti online"}.
|
||||
{"Set message of the day on all hosts and send to online users","Impostare il messaggio del giorno (MOTD) su tutti gli host e inviarlo agli utenti online"}.
|
||||
{"Shared Roster Groups","Gruppi di liste di contatti comuni"}.
|
||||
@@ -301,6 +323,7 @@
|
||||
{"Show Ordinary Table","Mostrare la tabella normale"}.
|
||||
{"Shut Down Service","Terminare il servizio"}.
|
||||
{"~s invites you to the room ~s","~s ti invita nella stanza ~s"}.
|
||||
{"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Alcuni client Jabber possono conservare la password nel tuo computer. Utilizza tale funzione soltanto se ritieni che il tuo computer sia sicuro."}.
|
||||
{"Specify the access model","Specificare il modello di accesso"}.
|
||||
{"Specify the event message type","Specificare il tipo di messaggio di evento"}.
|
||||
{"Specify the publisher model","Definire il modello di pubblicazione"}.
|
||||
@@ -325,9 +348,18 @@
|
||||
{"Sunday","Domenica"}.
|
||||
{"That nickname is already in use by another occupant","Il nickname è già in uso all'interno della conferenza"}.
|
||||
{"That nickname is registered by another person","Questo nickname è registrato da un'altra persona"}.
|
||||
{"The captcha is valid.","Il captcha è valido."}.
|
||||
{"The CAPTCHA is valid.","Il CAPTCHA è valido."}.
|
||||
{"The CAPTCHA verification has failed","La verifica del CAPTCHA ha avuto esito negativo"}.
|
||||
{"The collections with which a node is affiliated","Le collezioni a cui è affiliato un nodo"}.
|
||||
{"the password is","la password è"}.
|
||||
{"The password is too weak","La password è troppo debole"}.
|
||||
{"The password of your Jabber account was successfully changed.","Il cambio di password del tuo account Jabber è andato a buon fine."}.
|
||||
{"There was an error changing the password: ","Si è verificato un errore nel cambio di password: "}.
|
||||
{"There was an error creating the account: ","Si è verificato un errore nella creazione dell'account: "}.
|
||||
{"There was an error deleting the account: ","Si è verificato un errore nella cancellazione dell'account: "}.
|
||||
{"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Non fa differenza fra minuscolo e maiuscolo: macbeth, MacBeth e Macbeth si equivalgono."}.
|
||||
{"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Questa pagina consente di creare un account Jabber in questo server Jabber. Il tuo JID (Jabber IDentifier) avrà la forma: nome_utente@server. Leggi attentamente le istruzioni per compilare i campi correttamente."}.
|
||||
{"This page allows to unregister a Jabber account in this Jabber server.","Questa pagina consente di eliminare un account Jabber da questo server Jabber."}.
|
||||
{"This participant is kicked from the room because he sent an error message","Partecipante espulso dalla stanza perché ha inviato un messaggio non valido"}.
|
||||
{"This participant is kicked from the room because he sent an error message to another participant","Partecipante espulso dalla stanza perché ha inviato un messaggio non valido a un altro partecipante"}.
|
||||
{"This participant is kicked from the room because he sent an error presence","Partecipante espulso dalla stanza perché ha inviato una presenza non valido"}.
|
||||
@@ -336,6 +368,7 @@
|
||||
{"Time delay","Ritardo"}.
|
||||
{"Time","Ora"}.
|
||||
{"To","A"}.
|
||||
{"Too many CAPTCHA requests","Troppe richieste CAPTCHA"}.
|
||||
{"To ~s","A ~s"}.
|
||||
{"Traffic rate limit is exceeded","Limite di traffico superato"}.
|
||||
{"Transactions Aborted:","Transazioni abortite:"}.
|
||||
@@ -343,8 +376,10 @@
|
||||
{"Transactions Logged:","Transazioni con log:"}.
|
||||
{"Transactions Restarted:","Transazioni riavviate:"}.
|
||||
{"Tuesday","Martedì"}.
|
||||
{"Unable to generate a captcha","Impossibile generare un captcha"}.
|
||||
{"Unable to generate a CAPTCHA","Impossibile generare un CAPTCHA"}.
|
||||
{"Unauthorized","Non autorizzato"}.
|
||||
{"Unregister a Jabber account","Elimina un account Jabber"}.
|
||||
{"Unregister","Elimina"}.
|
||||
{"Update ","Aggiornare "}.
|
||||
{"Update","Aggiornare"}.
|
||||
{"Update message of the day (don't send)","Aggiornare il messaggio del giorno (MOTD) (non inviarlo)"}.
|
||||
@@ -353,7 +388,9 @@
|
||||
{"Update script","Script di aggiornamento"}.
|
||||
{"Uptime:","Tempo dall'avvio:"}.
|
||||
{"Use of STARTTLS required","Utilizzo di STARTTLS obbligatorio"}.
|
||||
{"User JID","JID utente"}.
|
||||
{"User Management","Gestione degli utenti"}.
|
||||
{"Username:","Nome utente:"}.
|
||||
{"Users are not allowed to register accounts so quickly","Non è consentito agli utenti registrare account così rapidamente"}.
|
||||
{"Users Last Activity","Ultima attività degli utenti"}.
|
||||
{"Users","Utenti"}.
|
||||
@@ -364,13 +401,21 @@
|
||||
{"Virtual Hosts","Host Virtuali"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Non è consentito ai visitatori cambiare il nickname in questa stanza"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Non è consentito ai visitatori l'invio di messaggi a tutti i presenti"}.
|
||||
{"Voice request","Richiesta di parola"}.
|
||||
{"Voice requests are disabled in this conference","In questa conferenza le richieste di parola sono escluse"}.
|
||||
{"Wednesday","Mercoledì"}.
|
||||
{"When to send the last published item","Quando inviare l'ultimo elemento pubblicato"}.
|
||||
{"Whether to allow subscriptions","Consentire iscrizioni?"}.
|
||||
{"You can later change your password using a Jabber client.","Potrai in seguito cambiare la password utilizzando un client Jabber."}.
|
||||
{"You have been banned from this room","Sei stata/o bandita/o da questa stanza"}.
|
||||
{"You must fill in field \"Nickname\" in the form","Si deve riempire il campo \"Nickname\" nel modulo"}.
|
||||
{"You need a client that supports x:data and CAPTCHA to register","La registrazione richiede un client che supporti x:data e CAPTCHA"}.
|
||||
{"You need a client that supports x:data to register the nickname","Per registrare il nickname è necessario un client che supporti x:data"}.
|
||||
{"You need an x:data capable client to configure mod_irc settings","Per la configurazione del modulo IRC è necessario un client che supporti x:data"}.
|
||||
{"You need an x:data capable client to configure room","Per la configurazione della stanza è necessario un client che supporti x:data"}.
|
||||
{"You need an x:data capable client to search","Per effettuare ricerche è necessario un client che supporti x:data"}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","In base alla tua attuale lista privacy questa stanza è stata esclusa dalla navigazione."}.
|
||||
{"Your contact offline message queue is full. The message has been discarded.","La coda dei messaggi offline del contatto è piena. Il messaggio è stato scartato"}.
|
||||
{"Your Jabber account was successfully created.","La creazione del tuo account Jabber è andata a buon fine."}.
|
||||
{"Your Jabber account was successfully deleted.","La cancellazione del tuo account Jabber è andata a buon fine."}.
|
||||
{"Your messages to ~s are being blocked. To unblock them, visit ~s","I messaggi verso ~s sono bloccati. Per sbloccarli, visitare ~s"}.
|
||||
+421
-353
File diff suppressed because it is too large
Load Diff
@@ -15,16 +15,18 @@
|
||||
{"A friendly name for the node","ノードのフレンドリネーム"}.
|
||||
{"All activity","すべて"}.
|
||||
{"Allow this Jabber ID to subscribe to this pubsub node?","この Jabber ID に、この pubsubノードの購読を許可しますか ?"}.
|
||||
{"Allow users to change the subject","ユーザーによる件名の変更を許可"}.
|
||||
{"Allow users to change the subject","ユーザーによる題の変更を許可"}.
|
||||
{"Allow users to query other users","ユーザーによる他のユーザーへのクエリーを許可"}.
|
||||
{"Allow users to send invites","ユーザーによる招待を許可"}.
|
||||
{"Allow users to send private messages","ユーザーによるプライベートメッセージの送信を許可"}.
|
||||
{"Allow visitors to change nickname","ビジターのニックネームの変更を許可"}.
|
||||
{"Allow visitors to send status text in presence updates","ビジターによるプレゼンス更新のステータス文の送信を許可"}.
|
||||
{"Allow visitors to change nickname","傍聴者のニックネームの変更を許可"}.
|
||||
{"Allow visitors to send private messages to","傍聴者によるプライベートメッセージの送信を次の相手に許可"}.
|
||||
{"Allow visitors to send status text in presence updates","傍聴者によるプレゼンス更新のステータス文の送信を許可"}.
|
||||
{"Allow visitors to send voice requests","傍聴者による発言権の要求を許可"}.
|
||||
{"All Users","全ユーザー"}.
|
||||
{"Announcements","アナウンス"}.
|
||||
{"anyone","誰でも"}.
|
||||
{"A password is required to enter this room","チャットルームに入るにはパスワードが必要です"}.
|
||||
{"anyone","誰にでも"}.
|
||||
{"A password is required to enter this room","この談話室に入るにはパスワードが必要です"}.
|
||||
{"April","4月"}.
|
||||
{"August","8月"}.
|
||||
{"Backup","バックアップ"}.
|
||||
@@ -33,27 +35,27 @@
|
||||
{"Backup to File at ","ファイルにバックアップ: "}.
|
||||
{"Bad format","不正なフォーマット"}.
|
||||
{"Birthday","誕生日"}.
|
||||
{"CAPTCHA web page","CAPTCHA web ページ"}.
|
||||
{"CAPTCHA web page","CAPTCHA ウェブページ"}.
|
||||
{"Change Password","パスワードを変更"}.
|
||||
{"Change User Password","パスワードを変更"}.
|
||||
{"Characters not allowed:","使用できない文字:"}.
|
||||
{"Chatroom configuration modified","チャットルームの設定が変更されました"}.
|
||||
{"Chatroom is created","チャットルームを作りました"}.
|
||||
{"Chatroom is destroyed","チャットルームを削除しました"}.
|
||||
{"Chatroom is started","チャットルームを開始しました"}.
|
||||
{"Chatroom is stopped","チャットルームを停止しました"}.
|
||||
{"Chatrooms","チャットルーム"}.
|
||||
{"Chatroom configuration modified","談話室の設定が変更されました"}.
|
||||
{"Chatroom is created","談話室を作りました"}.
|
||||
{"Chatroom is destroyed","談話室を削除しました"}.
|
||||
{"Chatroom is started","談話室を開始しました"}.
|
||||
{"Chatroom is stopped","談話室を停止しました"}.
|
||||
{"Chatrooms","談話室"}.
|
||||
{"Choose a username and password to register with this server","サーバーに登録するユーザー名とパスワードを選択してください"}.
|
||||
{"Choose modules to stop","停止するモジュールを選択"}.
|
||||
{"Choose storage type of tables","テーブルのストレージタイプを選択"}.
|
||||
{"Choose whether to approve this entity's subscription.","このエントリを承認するかどうかを選択してください"}.
|
||||
{"City","都道府県"}.
|
||||
{"Commands","コマンド"}.
|
||||
{"Conference room does not exist","カンファレンスルームは存在しません"}.
|
||||
{"Configuration of room ~s","チャットルーム ~s の設定"}.
|
||||
{"Conference room does not exist","会議室は存在しません"}.
|
||||
{"Configuration of room ~s","談話室 ~s の設定"}.
|
||||
{"Configuration","設定"}.
|
||||
{"Connected Resources:","接続リソース:"}.
|
||||
{"Connections parameters","接続パラメータ"}.
|
||||
{"Connections parameters","接続パラメーター"}.
|
||||
{"Country","国"}.
|
||||
{"CPU Time:","CPU時間:"}.
|
||||
{"Database","データーベース"}.
|
||||
@@ -75,12 +77,13 @@
|
||||
{"Dump Backup to Text File at ","テキストファイルにバックアップ: "}.
|
||||
{"Dump to Text File","テキストファイルに出力"}.
|
||||
{"Edit Properties","プロパティを編集"}.
|
||||
{"Either approve or decline the voice request.","発言権の要求を承認または却下します。"}.
|
||||
{"ejabberd IRC module","ejabberd IRC module"}.
|
||||
{"ejabberd MUC module","ejabberd MUC module"}.
|
||||
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe module"}.
|
||||
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}.
|
||||
{"ejabberd vCard module","ejabberd vCard module"}.
|
||||
{"ejabberd Web Admin","ejabberd Web 管理"}.
|
||||
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe モジュール"}.
|
||||
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams モジュール"}.
|
||||
{"ejabberd vCard module","ejabberd vCard モジュール"}.
|
||||
{"ejabberd Web Admin","ejabberd ウェブ管理"}.
|
||||
{"Elements","要素"}.
|
||||
{"Email","メールアドレス"}.
|
||||
{"Enable logging","ロギングを有効"}.
|
||||
@@ -98,12 +101,14 @@
|
||||
{"Erlang Jabber Server","Erlang Jabber Server"}.
|
||||
{"Error","エラー"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","例: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","CAPTCHA 試験を免除する Jabber ID"}.
|
||||
{"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 を取り出すことに失敗しました"}.
|
||||
{"Family Name","姓"}.
|
||||
{"February","2月"}.
|
||||
{"Fill in fields to search for any matching Jabber User","項目を埋めて Jabber User を検索してください"}.
|
||||
{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","フォームを埋めて Jabber User を検索して下さい(* を使用すると部分文字列にマッチします)"}.
|
||||
{"Fill in fields to search for any matching Jabber User","欄を埋めて Jabber User を検索してください"}.
|
||||
{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","欄を埋めて Jabber User を検索してください (* を使用すると部分文字列にマッチします)"}.
|
||||
{"Friday","金曜日"}.
|
||||
{"From ~s","差出人 ~s"}.
|
||||
{"From","差出人"}.
|
||||
@@ -113,16 +118,17 @@
|
||||
{"Get User Last Login Time","最終ログイン時間を取得"}.
|
||||
{"Get User Password","パスワードを取得"}.
|
||||
{"Get User Statistics","ユーザー統計を取得"}.
|
||||
{"Grant voice to this person?","この人に発言権を与えますか ?"}.
|
||||
{"Group ","グループ"}.
|
||||
{"Groups","グループ"}.
|
||||
{"has been banned","はバンされました"}.
|
||||
{"has been kicked","はキックされました"}.
|
||||
{"has been kicked because of an affiliation change","は分掌が変更されたためキックされました"}.
|
||||
{"has been kicked because of a system shutdown","はシステムシャットダウンのためキックされました"}.
|
||||
{"has been kicked because the room has been changed to members-only","はチャットルームのメンバーのみに変更されたためキックされました"}.
|
||||
{" has set the subject to: "," は件名を設定しました: "}.
|
||||
{"has been kicked because the room has been changed to members-only","は談話室がメンバー制に変更されたためキックされました"}.
|
||||
{" has set the subject to: "," は題を設定しました: "}.
|
||||
{"Host","ホスト"}.
|
||||
{"If you don't see the CAPTCHA image here, visit the web page.","ここに CAPTCHA 画像が表示されない場合、web ページを参照してください。"}.
|
||||
{"If you don't see the CAPTCHA image here, visit the web page.","ここに CAPTCHA 画像が表示されない場合、ウェブページを参照してください。"}.
|
||||
{"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","別のポートやパスワード、文字エンコーディングを使用したい場合、'{\"irc server\", \"encoding\", port, \"password\"}' という形式のリストを入力してください。デフォルトでエンコーディングは \"~s\" を使用し、ポートは ~p、パスワードは空になっています。"}.
|
||||
{"Import Directory","ディレクトリインポート"}.
|
||||
{"Import File","ファイルからインポート"}.
|
||||
@@ -136,7 +142,7 @@
|
||||
{"Incorrect password","パスワードが違います"}.
|
||||
{"Invalid affiliation: ~s","無効な分掌です: ~s"}.
|
||||
{"Invalid role: ~s","無効な役です: ~s"}.
|
||||
{"IP addresses","IPアドレス"}.
|
||||
{"IP addresses","IP アドレス"}.
|
||||
{"IP","IP"}.
|
||||
{"IRC channel (don't put the first #)","IRC チャンネル (先頭に#は不要)"}.
|
||||
{"IRC server","IRC サーバー"}.
|
||||
@@ -146,14 +152,14 @@
|
||||
{"IRC Username","IRC ユーザー名"}.
|
||||
{"is now known as","は名前を変更しました: "}.
|
||||
{"It is not allowed to send private messages of type \"groupchat\"","種別が\"groupchat\" であるプライベートメッセージを送信することはできません"}.
|
||||
{"It is not allowed to send private messages to the conference","カンファレンスルームにプライベートメッセージを送信することはできません"}.
|
||||
{"It is not allowed to send private messages to the conference","この会議にプライベートメッセージを送信することはできません"}.
|
||||
{"It is not allowed to send private messages","プライベートメッセージを送信することはできません"}.
|
||||
{"Jabber Account Registration","Jabber アカウント登録"}.
|
||||
{"Jabber ID","Jabber ID"}.
|
||||
{"Jabber ID ~s is invalid","Jabber ID ~s は無効です"}.
|
||||
{"January","1月"}.
|
||||
{"Join IRC channel","IRC チャンネルに参加"}.
|
||||
{"joins the room","がチャットルームに参加しました"}.
|
||||
{"joins the room","が談話室に参加しました"}.
|
||||
{"Join the IRC channel here.","この IRC チャンネルに参加します。"}.
|
||||
{"Join the IRC channel in this Jabber ID: ~s","Jabber ID: ~s でこの IRC チャンネルに参加"}.
|
||||
{"July","7月"}.
|
||||
@@ -162,31 +168,32 @@
|
||||
{"Last login","最終ログイン"}.
|
||||
{"Last month","先月"}.
|
||||
{"Last year","去年"}.
|
||||
{"leaves the room","がチャットルームから退出しました"}.
|
||||
{"leaves the room","が談話室から退出しました"}.
|
||||
{"Listened Ports at ","Listen ポート "}.
|
||||
{"Listened Ports","Listenポート"}.
|
||||
{"Listened Ports","Listen ポート"}.
|
||||
{"List of modules to start","起動モジュールの一覧"}.
|
||||
{"Low level update script","低レベル更新スクリプト"}.
|
||||
{"Make participants list public","参加者一覧を公開"}.
|
||||
{"Make room captcha protected","チャットルームを CAPTCHA で保護"}.
|
||||
{"Make room members-only","チャットルームをメンバーのみに制限"}.
|
||||
{"Make room moderated","チャットルームをモデレート化"}.
|
||||
{"Make room password protected","チャットルームにパスワードを設定"}.
|
||||
{"Make room persistent","チャットルームを永続化"}.
|
||||
{"Make room public searchable","チャットルームを検索可"}.
|
||||
{"Make room CAPTCHA protected","談話室を CAPTCHA で保護"}.
|
||||
{"Make room members-only","談話室をメンバーのみに制限"}.
|
||||
{"Make room moderated","談話室をモデレート化"}.
|
||||
{"Make room password protected","談話室をパスワードで保護"}.
|
||||
{"Make room persistent","談話室を永続化"}.
|
||||
{"Make room public searchable","談話室を検索可"}.
|
||||
{"March","3月"}.
|
||||
{"Maximum Number of Occupants","最大在室者数"}.
|
||||
{"Max # of items to persist","アイテムの最大保存数"}.
|
||||
{"Max payload size in bytes","最大ぺイロードサイズ (byte)"}.
|
||||
{"May","5月"}.
|
||||
{"Members:","メンバー:"}.
|
||||
{"Membership is required to enter this room","チャットルームに入るにはメンバーでなければなりません"}.
|
||||
{"Membership is required to enter this room","この談話室に入るにはメンバーでなければなりません"}.
|
||||
{"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","パスワードは記憶するか、紙に書いて安全な場所に保管してください。もしあなたがパスワードを忘れてしまった場合、Jabber ではパスワードのリカバリを自動的に行うことはできません。"}.
|
||||
{"Memory","メモリ"}.
|
||||
{"Message body","本文"}.
|
||||
{"Middle Name","ミドルネーム"}.
|
||||
{"Minimum interval between voice requests (in seconds)","発言権の要求の最小時間間隔 (秒)"}.
|
||||
{"Moderator privileges required","モデレーター権限が必要です"}.
|
||||
{"moderators only","モデレーターのみ"}.
|
||||
{"moderators only","モデレーターにのみ"}.
|
||||
{"Modified modules","変更されたモジュール"}.
|
||||
{"Module","モジュール"}.
|
||||
{"Modules","モジュール"}.
|
||||
@@ -198,8 +205,9 @@
|
||||
{"New Password:","新しいパスワード:"}.
|
||||
{"Nickname","ニックネーム"}.
|
||||
{"Nickname Registration at ","ニックネーム登録: "}.
|
||||
{"Nickname ~s does not exist in the room","ニックネーム ~s はこのチャットルームにいません"}.
|
||||
{"Nickname ~s does not exist in the room","ニックネーム ~s はこの談話室にいません"}.
|
||||
{"No body provided for announce message","アナウンスメッセージはありませんでした"}.
|
||||
{"nobody","誰にも許可しない"}.
|
||||
{"No Data","データなし"}.
|
||||
{"Node ","ノード "}.
|
||||
{"Node ID","ノードID"}.
|
||||
@@ -225,10 +233,11 @@
|
||||
{"Online Users:","オンラインユーザー:"}.
|
||||
{"Online Users","オンラインユーザー"}.
|
||||
{"Only deliver notifications to available users","有効なユーザーにのみ告知を送信する"}.
|
||||
{"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 occupants are allowed to send messages to the conference","在室者のみがカンファレンスにメッセージを送ることができます"}.
|
||||
{"Only occupants are allowed to send queries to the conference","在室者のみがカンファレンスにクエリーを送信することができます"}.
|
||||
{"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 service administrators are allowed to send service messages","サービス管理者のみがサービスメッセージを送信できます"}.
|
||||
{"Options","オプション"}.
|
||||
{"Organization Name","会社名"}.
|
||||
@@ -236,7 +245,7 @@
|
||||
{"Outgoing s2s Connections:","外向き s2s コネクション:"}.
|
||||
{"Outgoing s2s Connections","外向き s2s コネクション"}.
|
||||
{"Outgoing s2s Servers:","外向き s2s サービス:"}.
|
||||
{"Owner privileges required","オーナー権限が必要です"}.
|
||||
{"Owner privileges required","主宰者の権限が必要です"}.
|
||||
{"Packet","パケット"}.
|
||||
{"Password:","パスワード"}.
|
||||
{"Password","パスワード"}.
|
||||
@@ -250,6 +259,7 @@
|
||||
{"Persist items to storage","アイテムをストレージに保存する"}.
|
||||
{"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","新しい発言権の要求を送るまで少し間をおいてください"}.
|
||||
{"Pong","Pong"}.
|
||||
{"Port","ポート"}.
|
||||
{"Port ~b","ポート ~b"}.
|
||||
@@ -259,12 +269,12 @@
|
||||
{"Publish-Subscribe","Publish-Subscribe"}.
|
||||
{"PubSub subscriber request","PubSub 購読者のリクエスト"}.
|
||||
{"Purge all items when the relevant publisher goes offline","公開者がオフラインになるときに、すべてのアイテムを削除"}.
|
||||
{"Queries to the conference members are not allowed in this room","このチャットルームでは、カンファレンスメンバーへのクエリーは禁止されています"}.
|
||||
{"Queries to the conference members are not allowed in this room","この談話室では、会議のメンバーへのクエリーは禁止されています"}.
|
||||
{"RAM and disc copy","RAM, ディスクコピー"}.
|
||||
{"RAM copy","RAMコピー"}.
|
||||
{"RAM copy","RAM コピー"}.
|
||||
{"Raw","Raw"}.
|
||||
{"Really delete message of the day?","本当にお知らせメッセージを削除しますか ?"}.
|
||||
{"Recipient is not in the conference room","受信者がカンファレンスルームにいません"}.
|
||||
{"Recipient is not in the conference room","受信者はこの会議室にいません"}.
|
||||
{"Register a Jabber account","Jabber アカウントを登録"}.
|
||||
{"Registered Users:","登録ユーザー:"}.
|
||||
{"Registered Users","登録ユーザー"}.
|
||||
@@ -283,11 +293,11 @@
|
||||
{"Restore binary backup after next ejabberd restart (requires less memory):","ejabberd の再起動時にバイナリバックアップからリストア (メモリ少):"}.
|
||||
{"Restore binary backup immediately:","直ちにバイナリバックアップからリストア:"}.
|
||||
{"Restore plain text backup immediately:","直ちにプレーンテキストバックアップからリストア:"}.
|
||||
{"Room Configuration","チャットルーム設定"}.
|
||||
{"Room creation is denied by service policy","サービスポリシーによってチャットルームの作成が禁止されています"}.
|
||||
{"Room description","チャットルームの説明"}.
|
||||
{"Room Occupants","在室者の数"}.
|
||||
{"Room title","チャットルームタイトル"}.
|
||||
{"Room Configuration","談話室の設定"}.
|
||||
{"Room creation is denied by service policy","サービスポリシーによって談話室の作成が禁止されています"}.
|
||||
{"Room description","談話室の説明"}.
|
||||
{"Room Occupants","在室者"}.
|
||||
{"Room title","談話室のタイトル"}.
|
||||
{"Roster groups allowed to subscribe","名簿グループは購読を許可しました"}.
|
||||
{"Roster of ","名簿: "}.
|
||||
{"Roster size","名簿サイズ"}.
|
||||
@@ -309,11 +319,11 @@
|
||||
{"Set message of the day and send to online users","お知らせメッセージを設定し、オンラインユーザーに送信"}.
|
||||
{"Set message of the day on all hosts and send to online users","全ホストのお知らせメッセージを設定し、オンラインユーザーに送信"}.
|
||||
{"Shared Roster Groups","共有名簿グループ"}.
|
||||
{"Show Integral Table","Integral テーブルを表示"}.
|
||||
{"Show Ordinary Table","Ordinary テーブルを表示"}.
|
||||
{"Show Integral Table","累積の表を表示"}.
|
||||
{"Show Ordinary Table","通常の表を表示"}.
|
||||
{"Shut Down Service","サービスを停止"}.
|
||||
{"~s invites you to the room ~s","~s はあなたをチャットルーム ~s に招待しています"}.
|
||||
{"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Jabber クライアントはコンピューターにあなたのパスワードを記憶できます。この機能を使用する場合、コンピューターが安全であることを確認してください。"}.
|
||||
{"~s invites you to the room ~s","~s はあなたを談話室 ~s に招待しています"}.
|
||||
{"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Jabber クライアントはコンピューターにパスワードを記憶できます。コンピューターが安全であると信頼できる場合にのみ、この機能を使用してください。"}.
|
||||
{"Specify the access model","アクセスモデルを設定する"}.
|
||||
{"Specify the event message type","イベントメッセージ種別を設定"}.
|
||||
{"Specify the publisher model","公開モデルを指定する"}.
|
||||
@@ -330,15 +340,15 @@
|
||||
{"Storage Type","ストレージタイプ"}.
|
||||
{"Store binary backup:","バイナリバックアップを保存:"}.
|
||||
{"Store plain text backup:","プレーンテキストバックアップを保存:"}.
|
||||
{"Subject","件名"}.
|
||||
{"Subject","題"}.
|
||||
{"Submitted","送信完了"}.
|
||||
{"Submit","送信"}.
|
||||
{"Subscriber Address","購読者のアドレス"}.
|
||||
{"Subscription","認可"}.
|
||||
{"Sunday","日曜日"}.
|
||||
{"That nickname is already in use by another occupant","ニックネームは既にほかの在室者によって使用されています"}.
|
||||
{"That nickname is already in use by another occupant","そのニックネームは既にほかの在室者によって使用されています"}.
|
||||
{"That nickname is registered by another person","ニックネームはほかの人によって登録されています"}.
|
||||
{"The captcha is valid.","CAPTCHA は有効です。"}.
|
||||
{"The CAPTCHA is valid.","CAPTCHA は有効です。"}.
|
||||
{"The CAPTCHA verification has failed","CAPTCHA 検証は失敗しました"}.
|
||||
{"The collections with which a node is affiliated","提携されたノードの集合です"}.
|
||||
{"the password is","パスワードは"}.
|
||||
@@ -348,15 +358,16 @@
|
||||
{"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 create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","ここは Jabber サーバーにアカウントを作成するページです。あなたの JID (JabberID) は username@server のような形式になります。注意事項どおり、正しく項目を記入してください。"}.
|
||||
{"This page allows to unregister a Jabber account in this Jabber server.","ここはサーバーの Jabber アカウントの削除を行うページです。"}.
|
||||
{"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","ここはこの Jabber サーバーにアカウントを作成するページです。あなたの JID (JabberID) は username@server のような形式になります。注意事項どおり、正しく項目を記入してください。"}.
|
||||
{"This page allows to unregister a Jabber account in this Jabber server.","ここはこの Jabber サーバーのアカウントを削除するページです。"}.
|
||||
{"This participant is kicked from the room because he sent an error message to another participant","他の参加者にエラーメッセージを送信したため、この参加者はキックされました"}.
|
||||
{"This participant is kicked from the room because he sent an error message","エラーメッセージを送信したため、この参加者はキックされました"}.
|
||||
{"This participant is kicked from the room because he sent an error presence","エラープレゼンスを送信したため、この参加者はキックされました"}.
|
||||
{"This room is not anonymous","このチャットルームは非匿名です"}.
|
||||
{"This room is not anonymous","この談話室は非匿名です"}.
|
||||
{"Thursday","木曜日"}.
|
||||
{"Time delay","遅延時間"}.
|
||||
{"Time","時間"}.
|
||||
{"Too many CAPTCHA requests","CAPTCHA 要求が多すぎます"}.
|
||||
{"To ~s","宛先 ~s"}.
|
||||
{"To","宛先"}.
|
||||
{"Traffic rate limit is exceeded","トラフィックレートの制限を超えました"}.
|
||||
@@ -365,8 +376,7 @@
|
||||
{"Transactions Logged:","トランザクションのログ: "}.
|
||||
{"Transactions Restarted:","トランザクションの再起動:"}.
|
||||
{"Tuesday","火曜日"}.
|
||||
{"Unable to generate a captcha","CAPTCHA を生成することができません"}.
|
||||
{"Unable to generate a CAPTCHA","CAPTCHA を生成できませんでした"}.
|
||||
{"Unable to generate a CAPTCHA","CAPTCHA を生成できません"}.
|
||||
{"Unauthorized","認証されていません"}.
|
||||
{"Unregister a Jabber account","Jabber アカウントを削除"}.
|
||||
{"Unregister","削除"}.
|
||||
@@ -380,29 +390,32 @@
|
||||
{"Use of STARTTLS required","STARTTLS の使用が必要です"}.
|
||||
{"User ","ユーザー "}.
|
||||
{"User","ユーザー"}.
|
||||
{"User JID","ユーザー JID"}.
|
||||
{"User Management","ユーザー管理"}.
|
||||
{"Username:","ユーザー名:"}.
|
||||
{"Users","ユーザー"}.
|
||||
{"Users are not allowed to register accounts so quickly","早すぎるユーザーアカウント登録は許可されていません"}.
|
||||
{"Users are not allowed to register accounts so quickly","それほど速くアカウントを登録することはできません"}.
|
||||
{"Users Last Activity","ユーザーの活動履歴"}.
|
||||
{"Validate","検証"}.
|
||||
{"vCard User Search","vCard ユーザー検索"}.
|
||||
{"Virtual Hosts","ヴァーチャルホスト"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","ビジターはこのチャットルームでニックネームを変更することはできません"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","ビジターはすべての在室者にメッセージを送信することはできません"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","傍聴者はこの談話室でニックネームを変更することはできません"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","傍聴者はすべての在室者にメッセージを送信することはできません"}.
|
||||
{"Voice requests are disabled in this conference","この会議では、発言権の要求はできません"}.
|
||||
{"Voice request","発言権を要求"}.
|
||||
{"Wednesday","水曜日"}.
|
||||
{"When to send the last published item","最後の公開アイテムを送信するタイミングで"}.
|
||||
{"Whether to allow subscriptions","購読を許可するかどうか"}.
|
||||
{"You can later change your password using a Jabber client.","あなたは後から Jabber クライアントを使用してパスワードを変更することができます。"}.
|
||||
{"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 をサポートする必要があります"}.
|
||||
{"You need an x:data capable client to configure mod_irc settings","mod_irc の設定にはクライアントが x:data をサポートする必要があります"}.
|
||||
{"You need an x:data capable client to configure room","チャットルームを設定するにはクライアントが x:data をサポートする必要があります"}.
|
||||
{"You need an x:data capable client to search","検索を行うためにはクライアントが x:data をサポートする必要があります"}.
|
||||
{"You can later change your password using a Jabber client.","あなたは後で Jabber クライアントを使用してパスワードを変更できます。"}.
|
||||
{"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 をサポートするクライアントが必要です"}.
|
||||
{"You need an x:data capable client to configure mod_irc settings","mod_irc の設定には x:data をサポートするクライアントが必要です"}.
|
||||
{"You need an x:data capable client to configure room","談話室を設定するには x:data をサポートするクライアントが必要です"}.
|
||||
{"You need an x:data capable client to search","検索を行うためには x:data をサポートするクライアントが必要です"}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","あなたのプライバシーリストはこのスタンザのルーティングを拒否しました。"}.
|
||||
{"Your contact offline message queue is full. The message has been discarded.","宛先のオフラインメッセージキューが一杯です。このメッセージは破棄されます。"}.
|
||||
{"Your contact offline message queue is full. The message has been discarded.","相手先のオフラインメッセージキューが一杯です。このメッセージは破棄されます。"}.
|
||||
{"Your Jabber account was successfully created.","Jabber アカウントの作成に成功しました。"}.
|
||||
{"Your Jabber account was successfully deleted.","Jabber アカウントの削除に成功しました。"}.
|
||||
{"Your messages to ~s are being blocked. To unblock them, visit ~s","~s 宛のメッセージはブロックされています、解除するにはこちらを見てください ~s"}.
|
||||
{"Your messages to ~s are being blocked. To unblock them, visit ~s","~s 宛のメッセージはブロックされています。解除するにはこちらを見てください ~s"}.
|
||||
+446
-397
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,9 @@
|
||||
{"Allow users to send invites","Gebruikers mogen uitnodigingen verzenden"}.
|
||||
{"Allow users to send private messages","Gebruikers mogen privéberichten verzenden"}.
|
||||
{"Allow visitors to change nickname","Sta bezoekers toe hun naam te veranderen"}.
|
||||
{"Allow visitors to send private messages to","Gebruikers mogen privéberichten verzenden aan"}.
|
||||
{"Allow visitors to send status text in presence updates","Sta bezoekers toe hun statusbericht in te stellen"}.
|
||||
{"Allow visitors to send voice requests","Gebruikers mogen stemaanvragen verzenden"}.
|
||||
{"All Users","Alle gebruikers"}.
|
||||
{"Announcements","Mededelingen"}.
|
||||
{"anyone","iedereen"}.
|
||||
@@ -33,8 +35,10 @@
|
||||
{"Backup to File at ","Binaire backup maken op "}.
|
||||
{"Bad format","Slecht formaat"}.
|
||||
{"Birthday","Geboortedatum"}.
|
||||
{"CAPTCHA web page","CAPTCHA webpagina."}.
|
||||
{"Change Password","Wachtwoord wijzigen"}.
|
||||
{"Change User Password","Verander Gebruikerswachtwoord"}.
|
||||
{"Characters not allowed:","Niet-toegestane karakters:"}.
|
||||
{"Chatroom configuration modified","De instellingen van de chatruimte werden veranderd"}.
|
||||
{"Chatroom is created","Gespreksruimte gecreëerd"}.
|
||||
{"Chatroom is destroyed","Gespreksruimte vernietigd"}.
|
||||
@@ -69,9 +73,11 @@
|
||||
{"Description:","Beschrijving:"}.
|
||||
{"Disc only copy","Harde schijf"}.
|
||||
{"Displayed Groups:","Weergegeven groepen:"}.
|
||||
{"Don't tell your password to anybody, not even the administrators of the Jabber server.","Geef Uw wachtwoord aan niemand, zelfs niet aan de beheerders van deze Jabber-server."}.
|
||||
{"Dump Backup to Text File at ","Backup naar een tekstbestand schrijven op "}.
|
||||
{"Dump to Text File","Backup naar een tekstbestand schrijven"}.
|
||||
{"Edit Properties","Eigenschappen bewerken"}.
|
||||
{"Either approve or decline the voice request.","Keur stemaanvraag goed of af."}.
|
||||
{"ejabberd IRC module","ejabberd's IRC-module"}.
|
||||
{"ejabberd MUC module","ejabberd's MUC module"}.
|
||||
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe module"}.
|
||||
@@ -95,8 +101,10 @@
|
||||
{"Erlang Jabber Server","Erlang Jabber Server"}.
|
||||
{"Error","Fout"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Voorbeeld: [{\"irc.example.org\", \"koi8-r\", 6667, \"geheim\"}, {\"vendetta.example.net\", \"iso8859-1\", 7000}, {irc,testserver.nl\", \"utf-8\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Geen CAPTCHA test voor Jabber IDs"}.
|
||||
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exporteer data van alle gebruikers in de server naar PIEFXIS-bestanden (XEP-0227):"}.
|
||||
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Exporteer data van alle gebruikers van een host naar PIEXFIS-bestanden (XEP-0227):"}.
|
||||
{"Failed to extract JID from your voice request approval","Er kon geen JID worden ontleend uit deze stemaanvraag"}.
|
||||
{"Family Name","Achternaam"}.
|
||||
{"February","Februari"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Vul de velden in om te zoeken naar Jabber-gebruikers op deze server"}.
|
||||
@@ -110,6 +118,7 @@
|
||||
{"Get User Last Login Time","Tijd van Laatste Aanmelding Opvragen"}.
|
||||
{"Get User Password","Gebruikerswachtwoord Opvragen"}.
|
||||
{"Get User Statistics","Gebruikers-statistieken Opvragen"}.
|
||||
{"Grant voice to this person?","Stemaanvraag honoreren voor deze persoon?"}.
|
||||
{"Group ","Groep "}.
|
||||
{"Groups","Groepen"}.
|
||||
{"has been banned","werd verbannen"}.
|
||||
@@ -119,6 +128,7 @@
|
||||
{"has been kicked","werd gekicked"}.
|
||||
{" has set the subject to: "," veranderde het onderwerp in: "}.
|
||||
{"Host","Host"}.
|
||||
{"If you don't see the CAPTCHA image here, visit the web page.","Als U het CAPTCHA-plaatje niet ziet, bezoek dan de webpagina."}.
|
||||
{"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Als u verschillende poorten, wachtwoorden en coderingen wilt opgeven voor elke IRC-server, vul dan deze lijst met het volgende formaat: '{\"IRC-server\", \"codering\", poort, \"wachtwoord\"}'. Standaard gebruikt deze service de codering \"~s\", poort ~p, leeg wachtwoord."}.
|
||||
{"Import Directory","Directory importeren"}.
|
||||
{"Import File","Bestand importeren"}.
|
||||
@@ -144,6 +154,7 @@
|
||||
{"It is not allowed to send private messages","Het is niet toegestaan priveberichten te sturen"}.
|
||||
{"It is not allowed to send private messages of type \"groupchat\"","Er mogen geen privéberichten van het type \"groupchat\" worden verzonden"}.
|
||||
{"It is not allowed to send private messages to the conference","Er mogen geen privéberichten naar de chatruimte worden verzonden"}.
|
||||
{"Jabber Account Registration","Jabber-account registratie"}.
|
||||
{"Jabber ID","Jabber ID"}.
|
||||
{"Jabber ID ~s is invalid","De Jabber ID ~s is ongeldig"}.
|
||||
{"January","Januari"}.
|
||||
@@ -163,7 +174,7 @@
|
||||
{"List of modules to start","Lijst met op te starten modules"}.
|
||||
{"Low level update script","Lowlevel script voor de opwaardering"}.
|
||||
{"Make participants list public","Deelnemerslijst publiek maken"}.
|
||||
{"Make room captcha protected","Chatruimte beveiligen met een geautomatiseerde Turing test"}.
|
||||
{"Make room CAPTCHA protected","Chatruimte beveiligen met een geautomatiseerde Turing test"}.
|
||||
{"Make room members-only","Chatruimte enkel toegankelijk maken voor leden"}.
|
||||
{"Make room moderated","Chatruimte gemodereerd maken"}.
|
||||
{"Make room password protected","Chatruimte beveiligen met een wachtwoord"}.
|
||||
@@ -176,9 +187,11 @@
|
||||
{"May","Mei"}.
|
||||
{"Members:","Groepsleden:"}.
|
||||
{"Membership is required to enter this room","U moet lid zijn om deze chatruimte te kunnen betreden"}.
|
||||
{"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Onthou het wachtwoord, of schrijf het op en bewaar het op een veilige plaats. Met Jabber is er geen geautomatiseerde manier om het wachtwoord terug te halen als U het vergeet."}.
|
||||
{"Memory","Geheugen"}.
|
||||
{"Message body","Bericht"}.
|
||||
{"Middle Name","Tussennaam"}.
|
||||
{"Minimum interval between voice requests (in seconds)","Minimale interval tussen stemaanvragen (in seconden)"}.
|
||||
{"Moderator privileges required","U hebt moderatorprivileges nodig"}.
|
||||
{"moderators only","moderators"}.
|
||||
{"Modified modules","Gewijzigde modules"}.
|
||||
@@ -189,9 +202,11 @@
|
||||
{"Name:","Naam:"}.
|
||||
{"Name","Naam"}.
|
||||
{"Never","Nooit"}.
|
||||
{"New Password:","Nieuw Wachtwoord:"}.
|
||||
{"Nickname","Bijnaam"}.
|
||||
{"Nickname Registration at ","Registratie van een bijnaam op "}.
|
||||
{"Nickname ~s does not exist in the room","De bijnaam ~s bestaat niet in deze chatruimte"}.
|
||||
{"nobody","niemand"}.
|
||||
{"No body provided for announce message","De mededeling bevat geen bericht"}.
|
||||
{"No Data","Geen gegevens"}.
|
||||
{"Node ID","Node ID"}.
|
||||
@@ -213,12 +228,14 @@
|
||||
{"Offline Messages:","Offline berichten:"}.
|
||||
{"Offline Messages","Offline berichten"}.
|
||||
{"OK","OK"}.
|
||||
{"Old Password:","Oud Wachtwoord:"}.
|
||||
{"Online","Online"}.
|
||||
{"Online Users:","Online gebruikers:"}.
|
||||
{"Online Users","Online gebruikers"}.
|
||||
{"Only deliver notifications to available users","Notificaties alleen verzenden naar online gebruikers"}.
|
||||
{"Only moderators and participants are allowed to change the subject in this room","Alleen moderators en deelnemers mogen het onderwerp van deze chatruimte veranderen"}.
|
||||
{"Only moderators are allowed to change the subject in this room","Alleen moderators mogen het onderwerp van deze chatruimte veranderen"}.
|
||||
{"Only moderators can approve voice requests","Alleen moderators kunnen stemaanvragen goedkeuren"}.
|
||||
{"Only occupants are allowed to send messages to the conference","Alleen aanwezigen mogen berichten naar de chatruimte verzenden"}.
|
||||
{"Only occupants are allowed to send queries to the conference","Alleen aanwezigen mogen verzoeken verzenden naar de chatruimte"}.
|
||||
{"Only service administrators are allowed to send service messages","Alleen beheerders van deze dienst mogen mededelingen verzenden naar alle chatruimtes"}.
|
||||
@@ -231,6 +248,7 @@
|
||||
{"Owner privileges required","U hebt eigenaarsprivileges nodig"}.
|
||||
{"Packet","Pakket"}.
|
||||
{"Password ~b","Wachtwoord ~b"}.
|
||||
{"Password Verification:","Wachtwoord Bevestiging:"}.
|
||||
{"Password Verification","Wachtwoord Bevestiging"}.
|
||||
{"Password:","Wachtwoord:"}.
|
||||
{"Password","Wachtwoord"}.
|
||||
@@ -241,6 +259,7 @@
|
||||
{"Persist items to storage","Items in het geheugen bewaren"}.
|
||||
{"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.","Merk op dat volgende opties enkel backups maken van de ingebouwde database Mnesia. Als U de ODBC module gebruikt dan moeten daarvan afzonderlijke backups gemaakt worden."}.
|
||||
{"Please, wait for a while before sending new voice request","Wacht s.v.p. met het maken van een nieuwe stemaanvraag."}.
|
||||
{"Pong","Pong"}.
|
||||
{"Port ~b","Poort ~b"}.
|
||||
{"Port","Poort"}.
|
||||
@@ -256,8 +275,10 @@
|
||||
{"Raw","Ruw"}.
|
||||
{"Really delete message of the day?","Wilt u het bericht van de dag verwijderen?"}.
|
||||
{"Recipient is not in the conference room","De ontvanger is niet in de chatruimte"}.
|
||||
{"Register a Jabber account","Registreer een Jabber-account"}.
|
||||
{"Registered Users:","Geregistreerde gebruikers:"}.
|
||||
{"Registered Users","Geregistreerde gebruikers"}.
|
||||
{"Register","Registreer"}.
|
||||
{"Registration in mod_irc for ","Registratie van "}.
|
||||
{"Remote copy","Op andere nodes in de cluster"}.
|
||||
{"Remove All Offline Messages","Verwijder alle offline berichten"}.
|
||||
@@ -294,6 +315,7 @@
|
||||
{"Send announcement to all users on all hosts","Stuur aankondiging aan alle gebruikers op alle hosts"}.
|
||||
{"September","September"}.
|
||||
{"Server ~b","Server ~b"}.
|
||||
{"Server:","Server:"}.
|
||||
{"Set message of the day and send to online users","Bericht van de dag instellen en verzenden naar online gebruikers"}.
|
||||
{"Set message of the day on all hosts and send to online users","Stel bericht-van-de-dag in op alle hosts en stuur naar aanwezige gebruikers"}.
|
||||
{"Shared Roster Groups","Gedeelde rostergroepen"}.
|
||||
@@ -301,6 +323,7 @@
|
||||
{"Show Ordinary Table","Deel van tabel laten zien"}.
|
||||
{"Shut Down Service","Stop Service"}.
|
||||
{"~s invites you to the room ~s","~s nodigt je uit voor het groepsgesprek ~s"}.
|
||||
{"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Sommige Jabber-clienten kunnen het wachtwoord opslaan op Uw computer. Gebruik deze mogelijkheid alleen als U vertrouwd dat Uw computer afdoende beveiligd is."}.
|
||||
{"Specify the access model","Geef toegangsmodel"}.
|
||||
{"Specify the event message type","Geef type van eventbericht"}.
|
||||
{"Specify the publisher model","Publicatietype opgeven"}.
|
||||
@@ -325,9 +348,18 @@
|
||||
{"Sunday","Zondag"}.
|
||||
{"That nickname is already in use by another occupant","Deze bijnaam is al in gebruik door een andere aanwezige"}.
|
||||
{"That nickname is registered by another person","Deze bijnaam is al geregistreerd door iemand anders"}.
|
||||
{"The captcha is valid.","De geautomatiseerde Turing-test is geslaagd."}.
|
||||
{"The CAPTCHA is valid.","De geautomatiseerde Turing-test is geslaagd."}.
|
||||
{"The CAPTCHA verification has failed","De CAPTCHA-verificatie is mislukt"}.
|
||||
{"The collections with which a node is affiliated","De collecties waar een node mee is gerelateerd"}.
|
||||
{"the password is","het wachtwoord is"}.
|
||||
{"The password is too weak","Het wachtwoord is te zwak"}.
|
||||
{"The password of your Jabber account was successfully changed.","Het wachtwoord van Uw Jabber-account is succesvol veranderd."}.
|
||||
{"There was an error changing the password: ","Er was een fout bij het veranderen van het wachtwoord:"}.
|
||||
{"There was an error creating the account: ","Er was een fout bij het creeern van de account:"}.
|
||||
{"There was an error deleting the account: ","Er was een fout bij het verwijderen van de account."}.
|
||||
{"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Dit is niet hoofdlettergevoelig: macbeth is hetzelfde als MacBeth en Macbeth."}.
|
||||
{"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Deze pagina maakt het mogelijk een Jabber-account te registreren op deze server. Uw JID (Jabber IDentiteit) zal er als volg uit zien: gebruikersnaam@server. Lees de instructies zorgvuldig teneinde de velden correct in te vullen."}.
|
||||
{"This page allows to unregister a Jabber account in this Jabber server.","Deze pagina maakt het mogelijk een Jabber-account op deze server op te heffen."}.
|
||||
{"This participant is kicked from the room because he sent an error message","Deze deelnemer wordt weggestuurd vanwege het sturen van een foutmeldingsbericht"}.
|
||||
{"This participant is kicked from the room because he sent an error message to another participant","Deze deelnemer wordt weggestuurd vanwege het sturen van een foutmeldingsbericht aan een andere deelnemer"}.
|
||||
{"This participant is kicked from the room because he sent an error presence","Deze deelnemer wordt weggestuurd vanwege het sturen van een foutmelding-aanwezigheid"}.
|
||||
@@ -336,6 +368,7 @@
|
||||
{"Time delay","Vertraging"}.
|
||||
{"Time","Tijd"}.
|
||||
{"To","Aan"}.
|
||||
{"Too many CAPTCHA requests","Te veel CAPTCHA-aanvragen"}.
|
||||
{"To ~s","Naar ~s"}.
|
||||
{"Traffic rate limit is exceeded","Dataverkeerslimiet overschreden"}.
|
||||
{"Transactions Aborted:","Afgebroken transacties:"}.
|
||||
@@ -343,8 +376,10 @@
|
||||
{"Transactions Logged:","Gelogde transacties:"}.
|
||||
{"Transactions Restarted:","Herstarte transacties:"}.
|
||||
{"Tuesday","Dinsdag"}.
|
||||
{"Unable to generate a captcha","Het generen van een gautomatiseerde Turing test is mislukt"}.
|
||||
{"Unable to generate a CAPTCHA","Het generen van een CAPTCHA is mislukt"}.
|
||||
{"Unauthorized","Niet geautoriseerd"}.
|
||||
{"Unregister a Jabber account","Opheffen van Jabber-account"}.
|
||||
{"Unregister","Opheffen"}.
|
||||
{"Update","Bijwerken"}.
|
||||
{"Update message of the day (don't send)","Bericht van de dag bijwerken (niet verzenden)"}.
|
||||
{"Update message of the day on all hosts (don't send)","Verander bericht-van-de-dag op alle hosts (niet versturen)"}.
|
||||
@@ -355,7 +390,9 @@
|
||||
{"Use of STARTTLS required","Gebruik van STARTTLS is vereist"}.
|
||||
{"User ","Gebruiker "}.
|
||||
{"User","Gebruiker"}.
|
||||
{"User JID","JID Gebruiker"}.
|
||||
{"User Management","Gebruikersbeheer"}.
|
||||
{"Username:","Gebruikersnaam:"}.
|
||||
{"Users are not allowed to register accounts so quickly","Het is gebruikers niet toegestaan zo snel achter elkaar te registreren"}.
|
||||
{"Users","Gebruikers"}.
|
||||
{"Users Last Activity","Laatste activiteit van gebruikers"}.
|
||||
@@ -364,13 +401,21 @@
|
||||
{"Virtual Hosts","Virtuele hosts"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Het is bezoekers niet toegestaan hun naam te veranderen in dit kanaal"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Bezoekers mogen geen berichten verzenden naar alle aanwezigen"}.
|
||||
{"Voice requests are disabled in this conference","Stemaanvragen zijn uitgeschakeld voor deze chatruimte"}.
|
||||
{"Voice request","Stemaanvraag"}.
|
||||
{"Wednesday","Woensdag"}.
|
||||
{"When to send the last published item","Wanneer het laatst gepubliceerde item verzonden moet worden"}.
|
||||
{"Whether to allow subscriptions","Abonnementsaanvraag toestaan"}.
|
||||
{"You can later change your password using a Jabber client.","U can het wachtwoord later veranderen met een Jabber-client."}.
|
||||
{"You have been banned from this room","U werd verbannen uit deze chatruimte"}.
|
||||
{"You must fill in field \"Nickname\" in the form","U moet het veld \"bijnaam\" invullen"}.
|
||||
{"You need a client that supports x:data and CAPTCHA to register","U hebt een client nodig die x:data en CAPTCHA ondersteunt om een bijnaam te registreren"}.
|
||||
{"You need a client that supports x:data to register the nickname","U hebt een client nodig die x:data ondersteunt om een bijnaam te registreren"}.
|
||||
{"You need an x:data capable client to configure mod_irc settings","U hebt een client nodig die x:data ondersteunt om dit IRC-transport in te stellen"}.
|
||||
{"You need an x:data capable client to configure room","U hebt een client nodig die x:data ondersteunt om deze chatruimte in te stellen"}.
|
||||
{"You need an x:data capable client to search","U hebt een client nodig die x:data ondersteunt om te zoeken"}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","Uw actieve privacy-lijst verbied het routeren van dit stanza."}.
|
||||
{"Your contact offline message queue is full. The message has been discarded.","Te veel offline berichten voor dit contactpersoon. Het bericht is niet opgeslagen."}.
|
||||
{"Your Jabber account was successfully created.","Uw Jabber-account is succesvol gecreeerd."}.
|
||||
{"Your Jabber account was successfully deleted.","Uw Jabber-account is succesvol verwijderd."}.
|
||||
{"Your messages to ~s are being blocked. To unblock them, visit ~s","Uw berichten aan ~s worden geblokkeerd. Om ze te deblokkeren, ga naar ~s"}.
|
||||
+409
-348
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,9 @@
|
||||
{"Allow users to send invites","Tillat brukere å sende invitasjoner"}.
|
||||
{"Allow users to send private messages","Tillat brukere å sende private meldinger"}.
|
||||
{"Allow visitors to change nickname","Tillat besøkende å endre kallenavn"}.
|
||||
{"Allow visitors to send private messages to","Tillat brukere å sende private meldinger til"}.
|
||||
{"Allow visitors to send status text in presence updates","Tillat besøkende å sende status tekst i "}.
|
||||
{"Allow visitors to send voice requests","Tillat brukere å sende lyd forespørsler"}.
|
||||
{"All Users","Alle Brukere"}.
|
||||
{"Announcements","Kunngjøringer"}.
|
||||
{"anyone","hvem som helst"}.
|
||||
@@ -33,8 +35,10 @@
|
||||
{"Backup to File at ","Sikkerhetskopiere til Fil på "}.
|
||||
{"Bad format","Feil format"}.
|
||||
{"Birthday","Fødselsdag"}.
|
||||
{"CAPTCHA web page","CAPTCHA web side"}.
|
||||
{"Change Password","Endre Passord"}.
|
||||
{"Change User Password","Endre Brukers Passord"}.
|
||||
{"Characters not allowed:","Ikke godtatte tegn:"}.
|
||||
{"Chatroom configuration modified","Samtalerommets konfigurasjon er endret"}.
|
||||
{"Chatroom is created","Samtalerom er opprettet"}.
|
||||
{"Chatroom is destroyed","Samtalerom er fjernet"}.
|
||||
@@ -69,9 +73,11 @@
|
||||
{"Description:","Beskrivelse:"}.
|
||||
{"Disc only copy","Kun diskkopi"}.
|
||||
{"Displayed Groups:","Viste grupper:"}.
|
||||
{"Don't tell your password to anybody, not even the administrators of the Jabber server.","Ikke fortell passordet til noen, ikke en gang til administratoren av Jabber serveren."}.
|
||||
{"Dump Backup to Text File at ","Dump Sikkerhetskopi til Tekstfil på "}.
|
||||
{"Dump to Text File","Dump til Tekstfil"}.
|
||||
{"Edit Properties","Redigere Egenskaper"}.
|
||||
{"Either approve or decline the voice request.","Enten godkjenn eller forby lyd forespørselen"}.
|
||||
{"ejabberd IRC module","ejabberd IRC modul"}.
|
||||
{"ejabberd MUC module","ejabberd MUC modul"}.
|
||||
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe modul"}.
|
||||
@@ -95,8 +101,10 @@
|
||||
{"Erlang Jabber Server","Erlang Jabber Server"}.
|
||||
{"Error","Feil"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Eksempel: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Ekskluder Jabber IDer fra CAPTCHA utfordring"}.
|
||||
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Eksporter data om alle brukere i en server til PIEFXIS filer"}.
|
||||
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Eksporter data om alle brukere i en host til PIEFXIS filer (XEP-0227):"}.
|
||||
{"Failed to extract JID from your voice request approval","Feilet i forsøk på å hente JID fra din lyd forespørsel godkjenning"}.
|
||||
{"Family Name","Etternavn"}.
|
||||
{"February","februar"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Fyll inn felt for å søke etter Jabber brukere"}.
|
||||
@@ -110,6 +118,7 @@
|
||||
{"Get User Last Login Time","Vis Brukers Siste Påloggings Tidspunkt"}.
|
||||
{"Get User Password","Hent Brukers Passord"}.
|
||||
{"Get User Statistics","Vis Bruker Statistikk"}.
|
||||
{"Grant voice to this person?","Gi lyd til denne personen?"}.
|
||||
{"Group ","Gruppe "}.
|
||||
{"Groups","Grupper"}.
|
||||
{"has been banned","har blitt bannlyst"}.
|
||||
@@ -119,6 +128,7 @@
|
||||
{"has been kicked","har blitt kastet ut"}.
|
||||
{" has set the subject to: "," har satt emnet til: "}.
|
||||
{"Host","Maskin"}.
|
||||
{"If you don't see the CAPTCHA image here, visit the web page.","Dersom du ikke ser CAPTCHA bilde her, besøk web siden. "}.
|
||||
{"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Om du ønsker å spesifisere tekstkoding for IRC tjenere, fyller du ut en liste med verdier i formatet '{\"irc server\", \"encoding\", port, \"password\"}'. Denne tjenesten bruker \"~s\" som standard, port ~p, empty password."}.
|
||||
{"Import Directory","Importer Katalog"}.
|
||||
{"Import File","Importer File"}.
|
||||
@@ -144,6 +154,7 @@
|
||||
{"It is not allowed to send private messages","Det er ikke tillatt å sende private meldinger"}.
|
||||
{"It is not allowed to send private messages of type \"groupchat\"","Det er ikke tillatt å sende private meldinger med typen "}.
|
||||
{"It is not allowed to send private messages to the conference","Det er ikke tillatt å sende private meldinger til "}.
|
||||
{"Jabber Account Registration","Jabber Konto Registrering"}.
|
||||
{"Jabber ID","Jabber ID"}.
|
||||
{"Jabber ID ~s is invalid","Ugyldig Jabber ID ~s"}.
|
||||
{"January","januar"}.
|
||||
@@ -163,7 +174,7 @@
|
||||
{"List of modules to start","Liste over moduler som skal startes"}.
|
||||
{"Low level update script","Lavnivå oppdaterings skript"}.
|
||||
{"Make participants list public","Gjør deltakerlisten offentlig"}.
|
||||
{"Make room captcha protected","Gjør rommet captcha beskyttet"}.
|
||||
{"Make room CAPTCHA protected","Gjør rommet CAPTCHA beskyttet"}.
|
||||
{"Make room members-only","Gjør rommet tilgjengelig kun for medlemmer"}.
|
||||
{"Make room moderated","Gjør rommet redaktørstyrt"}.
|
||||
{"Make room password protected","Passordbeskytt rommet"}.
|
||||
@@ -176,9 +187,11 @@
|
||||
{"May","mai"}.
|
||||
{"Membership is required to enter this room","Medlemskap kreves for tilgang til samtalerommet"}.
|
||||
{"Members:","Medlemmer:"}.
|
||||
{"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Husk passordet, eller skriv det ned på et papir lagret på et trygt sted. I Jabber er det ingen automatisert måte å gjenskape passordet om du glemmer det. "}.
|
||||
{"Memory","Minne"}.
|
||||
{"Message body","Meldingskropp"}.
|
||||
{"Middle Name","Mellomnavn"}.
|
||||
{"Minimum interval between voice requests (in seconds)","Minimums interval mellom lyd forespørsler (i sekunder)"}.
|
||||
{"Moderator privileges required","Redaktørprivilegier kreves"}.
|
||||
{"moderators only","kun for redaktører"}.
|
||||
{"Modified modules","Endrede moduler"}.
|
||||
@@ -189,9 +202,11 @@
|
||||
{"Name:","Navn:"}.
|
||||
{"Name","Navn"}.
|
||||
{"Never","Aldri"}.
|
||||
{"New Password:","Nytt Passord:"}.
|
||||
{"Nickname","Kallenavn"}.
|
||||
{"Nickname Registration at ","Registrer Kallenavn på "}.
|
||||
{"Nickname ~s does not exist in the room","Kallenavn ~s eksisterer ikke i dette rommet"}.
|
||||
{"nobody","ingen"}.
|
||||
{"No body provided for announce message","Ingen meldingskropp gitt for kunngjørings melding"}.
|
||||
{"No Data","Ingen Data"}.
|
||||
{"Node ID","Node ID"}.
|
||||
@@ -213,12 +228,14 @@
|
||||
{"Offline Messages:","Frakoblede Meldinger:"}.
|
||||
{"Offline Messages","Frakoblede Meldinger"}.
|
||||
{"OK","OK"}.
|
||||
{"Old Password:","Gammelt Passord:"}.
|
||||
{"Online","Tilkoblet"}.
|
||||
{"Online Users:","Tilkoblede Brukere:"}.
|
||||
{"Online Users","Tilkoblede Brukere"}.
|
||||
{"Only deliver notifications to available users","Send kunngjøringer bare til tilgjengelige brukere"}.
|
||||
{"Only moderators and participants are allowed to change the subject in this room","Bare redaktører og deltakere kan endre emnet i dette rommet"}.
|
||||
{"Only moderators are allowed to change the subject in this room","Bare ordstyrer tillates å endre emnet i dette rommet"}.
|
||||
{"Only moderators can approve voice requests","Bare ordstyrer kan godkjenne lyd forespørsler"}.
|
||||
{"Only occupants are allowed to send messages to the conference","Bare deltakere får sende normale meldinger til konferansen"}.
|
||||
{"Only occupants are allowed to send queries to the conference","Bare deltakere er tillatt å sende forespørsler til "}.
|
||||
{"Only service administrators are allowed to send service messages","Bare tjeneste administratorer er tilatt å sende tjeneste "}.
|
||||
@@ -233,6 +250,7 @@
|
||||
{"Password ~b","Passord ~b"}.
|
||||
{"Password:","Passord:"}.
|
||||
{"Password","Passord"}.
|
||||
{"Password Verification:","Passord Bekreftelse:"}.
|
||||
{"Password Verification","Passord Bekreftelse"}.
|
||||
{"Path to Dir","Sti til Katalog"}.
|
||||
{"Path to File","Sti til Fil"}.
|
||||
@@ -241,6 +259,7 @@
|
||||
{"Persist items to storage","Vedvarende elementer til lagring"}.
|
||||
{"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.","Merk at disse valgene vil bare sikkerhetskopiere den innebygde Mnesia databasen. Dersom du bruker ODBC modulen må du også ta backup av din SQL database."}.
|
||||
{"Please, wait for a while before sending new voice request","Vennligst vent en stund før du sender en ny lyd forespørsel"}.
|
||||
{"Pong","Pong"}.
|
||||
{"Port ~b","Port ~b"}.
|
||||
{"Port","Port"}.
|
||||
@@ -256,8 +275,10 @@
|
||||
{"Raw","Rå"}.
|
||||
{"Really delete message of the day?","Virkelig slette melding for dagen?"}.
|
||||
{"Recipient is not in the conference room","Mottakeren er ikke i konferanserommet"}.
|
||||
{"Register a Jabber account","Registrer en Jabber konto"}.
|
||||
{"Registered Users:","Registrerte Brukere:"}.
|
||||
{"Registered Users","Registrerte Brukere"}.
|
||||
{"Register","Registrer"}.
|
||||
{"Registration in mod_irc for ","Registrering i mod_irc for "}.
|
||||
{"Remote copy","Lagres ikke lokalt"}.
|
||||
{"Remove All Offline Messages","Fjern Alle Frakoblede Meldinger"}.
|
||||
@@ -294,6 +315,7 @@
|
||||
{"Send announcement to all users","Send kunngjøring til alle brukere"}.
|
||||
{"September","september"}.
|
||||
{"Server ~b","Server ~b"}.
|
||||
{"Server:","Server:"}.
|
||||
{"Set message of the day and send to online users","Angi melding for dagen og send til tilkoblede brukere"}.
|
||||
{"Set message of the day on all hosts and send to online users","Angi melding for dagen på alle maskiner og send til "}.
|
||||
{"Shared Roster Groups","Delte Kontaktgrupper"}.
|
||||
@@ -301,6 +323,7 @@
|
||||
{"Show Ordinary Table","Vis Ordinær Tabell"}.
|
||||
{"Shut Down Service","Avslutt Tjeneste"}.
|
||||
{"~s invites you to the room ~s","~s inviterer deg til rommet ~s"}.
|
||||
{"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Noen Jabber klienter kan lagre passordet på datamaskinen. Bruk bare den funksjonen dersom du er sikker på at maskinen er trygg."}.
|
||||
{"Specify the access model","Spesifiser aksess modellen"}.
|
||||
{"Specify the event message type","Spesifiser hendelsesbeskjed type"}.
|
||||
{"Specify the publisher model","Angi publiserings modell"}.
|
||||
@@ -325,9 +348,18 @@
|
||||
{"Sunday","søndag"}.
|
||||
{"That nickname is already in use by another occupant","Det kallenavnet er allerede i bruk av en annen deltaker"}.
|
||||
{"That nickname is registered by another person","Det kallenavnet er registrert av en annen person"}.
|
||||
{"The captcha is valid.","Captchaen er ikke gyldig"}.
|
||||
{"The CAPTCHA is valid.","Captchaen er ikke gyldig"}.
|
||||
{"The CAPTCHA verification has failed","CAPTCHA godkjenningen har feilet"}.
|
||||
{"The collections with which a node is affiliated","Samlingene som en node er assosiert med"}.
|
||||
{"the password is","passordet er"}.
|
||||
{"The password is too weak","Passordet er for svakt"}.
|
||||
{"The password of your Jabber account was successfully changed.","Passordet for din Jabber konto ble endret."}.
|
||||
{"There was an error changing the password: ","En feil skjedde under endring av passordet:"}.
|
||||
{"There was an error creating the account: ","En feil skjedde under oppretting av kontoen:"}.
|
||||
{"There was an error deleting the account: ","En feil skjedde under sletting av kontoen: "}.
|
||||
{"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Denne er ufølsom for små og store bokstaver: macbeth er det samme som MacBeth og Macbeth. "}.
|
||||
{"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Denne siden lar deg lage en Jabber konto på denne Jabber serveren. Din JID (Jabber ID) vil være i formatet: brukernavn@server. Vennligst les instruksjonene nøye slik at du fyller ut skjemaet riktig."}.
|
||||
{"This page allows to unregister a Jabber account in this Jabber server.","Denne siden lar deg avregistrere en Jabber konto på denne Jabber serveren."}.
|
||||
{"This participant is kicked from the room because he sent an error message","Denne deltakeren er kastet ut av rommet fordi han sendte en feilmelding"}.
|
||||
{"This participant is kicked from the room because he sent an error message to another participant","Denne deltakeren er kastet ut av rommet fordi han sendte en feilmelding til en annen deltaker"}.
|
||||
{"This participant is kicked from the room because he sent an error presence","Denne deltakeren er kastet ut av rommet fordi han sendte feil tilstederværelse"}.
|
||||
@@ -335,6 +367,7 @@
|
||||
{"Thursday","torsdag"}.
|
||||
{"Time delay","Tids forsinkelse"}.
|
||||
{"Time","Tid"}.
|
||||
{"Too many CAPTCHA requests","For mange CAPTCHA forespørsler"}.
|
||||
{"To ~s","Til ~s"}.
|
||||
{"To","Til"}.
|
||||
{"Traffic rate limit is exceeded","Trafikkmengde grense overskredet"}.
|
||||
@@ -343,8 +376,10 @@
|
||||
{"Transactions Logged:","Loggede Transasksjoner:"}.
|
||||
{"Transactions Restarted:","Omstartede Transasksjoner:"}.
|
||||
{"Tuesday","tirsdag"}.
|
||||
{"Unable to generate a captcha","Umulig å generere en captcha"}.
|
||||
{"Unable to generate a CAPTCHA","Umulig å generere en CAPTCHA"}.
|
||||
{"Unauthorized","Uautorisert"}.
|
||||
{"Unregister a Jabber account","Avregistrer en Jabber konto"}.
|
||||
{"Unregister","Avregistrer"}.
|
||||
{"Update message of the day (don't send)","Oppdater melding for dagen (ikke send)"}.
|
||||
{"Update message of the day on all hosts (don't send)","Oppdater melding for dagen på alle maskiner (ikke send)"}.
|
||||
{"Update ","Oppdater "}.
|
||||
@@ -355,7 +390,9 @@
|
||||
{"Use of STARTTLS required","Bruk av STARTTLS kreves"}.
|
||||
{"User ","Bruker "}.
|
||||
{"User","Bruker"}.
|
||||
{"User JID","Bruker JID"}.
|
||||
{"User Management","Bruker Behandling"}.
|
||||
{"Username:","Brukernavn:"}.
|
||||
{"Users are not allowed to register accounts so quickly","Brukere får ikke lov til registrere kontoer så fort"}.
|
||||
{"Users","Brukere"}.
|
||||
{"Users Last Activity","Brukers Siste Aktivitet"}.
|
||||
@@ -364,13 +401,21 @@
|
||||
{"Virtual Hosts","Virtuella Maskiner"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Besøkende får ikke lov å endre kallenavn i dette "}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Besøkende får ikke sende meldinger til alle deltakere"}.
|
||||
{"Voice request","Lyd forespørsel"}.
|
||||
{"Voice requests are disabled in this conference","Lyd forespørsler er blokkert i denne konferansen"}.
|
||||
{"Wednesday","onsdag"}.
|
||||
{"When to send the last published item","Når skal siste publiserte artikkel sendes"}.
|
||||
{"Whether to allow subscriptions","Om man skal tillate abonnenter"}.
|
||||
{"You can later change your password using a Jabber client.","Du kan når som helst endre passordet via en Jabber klient."}.
|
||||
{"You have been banned from this room","Du har blitt bannlyst i dette rommet."}.
|
||||
{"You must fill in field \"Nickname\" in the form","Du må fylle inn feltet \"Nickname\" i skjemaet"}.
|
||||
{"You need a client that supports x:data and CAPTCHA to register","Du trenger en klient som støtter x:data og CAPTCHA for registrering "}.
|
||||
{"You need a client that supports x:data to register the nickname","Du trenger en klient som støtter x:data for å registrere kallenavnet"}.
|
||||
{"You need an x:data capable client to configure mod_irc settings","Du trenger en x:data kompatibel klient for å konfigurere mod_irc instillinger"}.
|
||||
{"You need an x:data capable client to configure room","Du trenger en klient som støtter x:data for å "}.
|
||||
{"You need an x:data capable client to search","Du tregner en klient som støtter x:data for å kunne "}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","Din aktive privat liste har blokkert rutingen av denne strofen."}.
|
||||
{"Your contact offline message queue is full. The message has been discarded.","Kontaktens frakoblede meldingskø er full. Meldingen har blitt kassert."}.
|
||||
{"Your Jabber account was successfully created.","Din Jabber konto ble opprettet"}.
|
||||
{"Your Jabber account was successfully deleted.","Dni Jabber konto er blitt sltettet."}.
|
||||
{"Your messages to ~s are being blocked. To unblock them, visit ~s","Dine meldinger til ~s blir blokkert. For å åpne igjen, besøk ~s"}.
|
||||
+412
-350
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,9 @@
|
||||
{"Allow users to send invites","Pozwól użytkownikom wysyłać zaproszenia"}.
|
||||
{"Allow users to send private messages","Pozwól użytkownikom wysyłać prywatne wiadomości"}.
|
||||
{"Allow visitors to change nickname","Pozwól uczestnikom na zmianę nicka"}.
|
||||
{"Allow visitors to send private messages to","Pozwól użytkownikom wysyłać prywatne wiadomości"}.
|
||||
{"Allow visitors to send status text in presence updates","Pozwól uczestnikom na wysyłanie statusów opisowych"}.
|
||||
{"Allow visitors to send voice requests","Pozwól użytkownikom wysyłać zaproszenia"}.
|
||||
{"All Users","Wszyscy użytkownicy"}.
|
||||
{"Announcements","Powiadomienia"}.
|
||||
{"anyone","wszystkich"}.
|
||||
@@ -75,6 +77,7 @@
|
||||
{"Dump Backup to Text File at ","Zapisz kopię zapasową w pliku tekstowym na "}.
|
||||
{"Dump to Text File","Wykonaj kopie do pliku tekstowego"}.
|
||||
{"Edit Properties","Edytuj właściwości"}.
|
||||
{"Either approve or decline the voice request.","Zatwierdź lub odrzuć żądanie głosowe"}.
|
||||
{"ejabberd IRC module","Moduł IRC ejabberd"}.
|
||||
{"ejabberd MUC module","Moduł MUC"}.
|
||||
{"ejabberd Publish-Subscribe module","Moduł Publish-Subscribe"}.
|
||||
@@ -98,8 +101,10 @@
|
||||
{"Erlang Jabber Server","Erlang Jabber Server"}.
|
||||
{"Error","Błąd"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Przykład: [{\"wroclaw.irc.pl\",\"utf-8\"}, {\"warszawa.irc.pl\", \"iso8859-2\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Pomiń Jabber ID z żądania CAPTCHA"}.
|
||||
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Eksportuj dane wszystkich użytkowników serwera do plików w formacie PIEFXIS (XEP-0227):"}.
|
||||
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Eksportuj dane użytkowników z hosta do plików w formacie PIEFXIS (XEP-0227):"}.
|
||||
{"Failed to extract JID from your voice request approval","Nie udało się wydobyć JID-u z twojego żądania"}.
|
||||
{"Family Name","Nazwisko"}.
|
||||
{"February","Luty"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Wypełnij pola aby znaleźć pasujących użytkowników Jabbera"}.
|
||||
@@ -113,6 +118,7 @@
|
||||
{"Get User Last Login Time","Pokaż czas ostatniego zalogowania uzytkownika"}.
|
||||
{"Get User Password","Pobierz hasło użytkownika"}.
|
||||
{"Get User Statistics","Pobierz statystyki użytkownika"}.
|
||||
{"Grant voice to this person?","Udzielić głosu tej osobie?"}.
|
||||
{"Group ","Grupa "}.
|
||||
{"Groups","Grupy"}.
|
||||
{"has been banned","został wykluczony"}.
|
||||
@@ -168,7 +174,7 @@
|
||||
{"List of modules to start","Lista modułów do uruchomienia"}.
|
||||
{"Low level update script","Skrypt aktualizacji niskiego poziomu"}.
|
||||
{"Make participants list public","Upublicznij listę uczestników"}.
|
||||
{"Make room captcha protected","Pokój zabezpieczony captchą"}.
|
||||
{"Make room CAPTCHA protected","Pokój zabezpieczony captchą"}.
|
||||
{"Make room members-only","Pokój tylko dla członków"}.
|
||||
{"Make room moderated","Pokój moderowany"}.
|
||||
{"Make room password protected","Pokój zabezpieczony hasłem"}.
|
||||
@@ -185,6 +191,7 @@
|
||||
{"Memory","Pamięć"}.
|
||||
{"Message body","Treść wiadomości"}.
|
||||
{"Middle Name","Drugie imię"}.
|
||||
{"Minimum interval between voice requests (in seconds)","Minimalny odstęp między żądaniami głosowymi (w sekundach)"}.
|
||||
{"Moderator privileges required","Wymagane uprawnienia moderatora"}.
|
||||
{"moderators only","tylko moderatorzy"}.
|
||||
{"Modified modules","Zmodyfikowane moduły"}.
|
||||
@@ -199,6 +206,7 @@
|
||||
{"Nickname","Nazwa użytkownika"}.
|
||||
{"Nickname Registration at ","Rejestracja nazwy użytkownika na "}.
|
||||
{"Nickname ~s does not exist in the room","Nie ma nicka ~s w tym pokoju"}.
|
||||
{"nobody","nikt"}.
|
||||
{"No body provided for announce message","Brak treści powiadomienia"}.
|
||||
{"No Data","Brak danych"}.
|
||||
{"Node ID","ID węzła"}.
|
||||
@@ -227,6 +235,7 @@
|
||||
{"Only deliver notifications to available users","Dostarczaj powiadomienia tylko dostępnym użytkownikom"}.
|
||||
{"Only moderators and participants are allowed to change the subject in this room","Tylko moderatorzy i uczestnicy mogą zmienić temat tego pokoju"}.
|
||||
{"Only moderators are allowed to change the subject in this room","Tylko moderatorzy mogą zmienić temat tego pokoju"}.
|
||||
{"Only moderators can approve voice requests","Tylko moderatorzy mogą zatwierdzać żądania głosowe"}.
|
||||
{"Only occupants are allowed to send messages to the conference","Tylko uczestnicy mogą wysyłać wiadomości na konferencję"}.
|
||||
{"Only occupants are allowed to send queries to the conference","Tylko uczestnicy mogą wysyłać zapytania do konferencji"}.
|
||||
{"Only service administrators are allowed to send service messages","Tylko administratorzy mogą wysyłać wiadomości"}.
|
||||
@@ -250,6 +259,7 @@
|
||||
{"Persist items to storage","Przechowuj na stałe dane PubSub"}.
|
||||
{"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.","Te opcje kopii zapasowych dotyczą tylko wbudowanej bazy danych typu Mnesia. Jeśli korzystasz z modułu ODBC, musisz wykonać kopie bazy we własnym zakresie."}.
|
||||
{"Please, wait for a while before sending new voice request","Proszę poczekać chwile, zanim wyślesz nowe żądanie głosowe"}.
|
||||
{"Pong","Pong"}.
|
||||
{"Port ~b","Port ~b"}.
|
||||
{"Port","Port"}.
|
||||
@@ -274,7 +284,7 @@
|
||||
{"Remove All Offline Messages","Usuń wszystkie wiadomości typu 'Offline'"}.
|
||||
{"Remove User","Usuń użytkownika"}.
|
||||
{"Remove","Usuń"}.
|
||||
{"Replaced by new connection","Zastąpione przez nowe połączenie"}.
|
||||
{"Replaced by new connection","Połączenie zostało zastąpione"}.
|
||||
{"Resources","Zasoby"}.
|
||||
{"Restart Service","Restart usługi"}.
|
||||
{"Restart","Uruchom ponownie"}.
|
||||
@@ -338,7 +348,7 @@
|
||||
{"Sunday","Niedziela"}.
|
||||
{"That nickname is already in use by another occupant","Ta nazwa użytkownika jest używana przez kogoś innego"}.
|
||||
{"That nickname is registered by another person","Ta nazwa użytkownika jest już zarejestrowana przez inną osobę"}.
|
||||
{"The captcha is valid.","Captcha jest poprawna."}.
|
||||
{"The CAPTCHA is valid.","Captcha jest poprawna."}.
|
||||
{"The CAPTCHA verification has failed","Weryfikacja CAPTCHA nie powiodła się."}.
|
||||
{"The collections with which a node is affiliated","Grupy, do których należy węzeł"}.
|
||||
{"the password is","hasło to:"}.
|
||||
@@ -358,6 +368,7 @@
|
||||
{"Time","Czas"}.
|
||||
{"Time delay","Opóźnienie"}.
|
||||
{"To","Do"}.
|
||||
{"Too many CAPTCHA requests","Za dużo żądań CAPTCHA"}.
|
||||
{"To ~s","Do ~s"}.
|
||||
{"Traffic rate limit is exceeded","Limit transferu przekroczony"}.
|
||||
{"Transactions Aborted:","Transakcje anulowane:"}.
|
||||
@@ -365,7 +376,6 @@
|
||||
{"Transactions Logged:","Transakcje zalogowane:"}.
|
||||
{"Transactions Restarted:","Transakcje uruchomione ponownie:"}.
|
||||
{"Tuesday","Wtorek"}.
|
||||
{"Unable to generate a captcha","Nie można wygenerować captcha"}.
|
||||
{"Unable to generate a CAPTCHA","Nie można wygenerować CAPTCHA"}.
|
||||
{"Unauthorized","Nie autoryzowano"}.
|
||||
{"Unregister a Jabber account","Usuń konto Jabber"}.
|
||||
@@ -377,7 +387,8 @@
|
||||
{"Update script","Skrypt aktualizacji"}.
|
||||
{"Update ","Uaktualnij "}.
|
||||
{"Uptime:","Czas pracy:"}.
|
||||
{"Use of STARTTLS required","Wymagane użycie STARTTLS"}.
|
||||
{"Use of STARTTLS required","Wymagane jest użycie STARTTLS"}.
|
||||
{"User JID","Użytkownik "}.
|
||||
{"User Management","Zarządzanie użytkownikami"}.
|
||||
{"Username:","Nazwa użytkownika:"}.
|
||||
{"Users are not allowed to register accounts so quickly","Użytkowncy nie mogą tak szybko rejestrować nowych kont"}.
|
||||
@@ -390,6 +401,8 @@
|
||||
{"Virtual Hosts","Wirtualne Hosty"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Uczestnicy tego pokoju nie mogą zmieniać swoich nicków"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Odwiedzający nie mogą wysyłać wiadomości do wszystkich obecnych"}.
|
||||
{"Voice requests are disabled in this conference","Głosowe żądania są wyłączone w tym pokoju"}.
|
||||
{"Voice request","Żądanie głosowe"}.
|
||||
{"Wednesday","Środa"}.
|
||||
{"When to send the last published item","Kiedy wysłać ostatnio opublikowaną rzecz"}.
|
||||
{"Whether to allow subscriptions","Czy pozwolić na subskrypcje"}.
|
||||
@@ -401,7 +414,7 @@
|
||||
{"You need an x:data capable client to configure mod_irc settings","Potrzebujesz klienta obsługującego x:data aby skonfigurować mod_irc"}.
|
||||
{"You need an x:data capable client to configure room","Potrzebujesz klienta obsługującego x:data aby skonfigurować pokój"}.
|
||||
{"You need an x:data capable client to search","Potrzebujesz klienta obsługującego x:data aby wyszukiwać"}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","Twoja aktywna lista prywatności zabrania"}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","Aktualna lista prywatności zabrania przesyłania tej stanzy"}.
|
||||
{"Your contact offline message queue is full. The message has been discarded.","Kolejka wiadomości offline adresata jest pełna. Wiadomość została odrzucona."}.
|
||||
{"Your Jabber account was successfully created.","Twoje konto zostało stworzone."}.
|
||||
{"Your Jabber account was successfully deleted.","Twoje konto zostało usunięte."}.
|
||||
+373
-318
File diff suppressed because it is too large
Load Diff
@@ -73,6 +73,7 @@
|
||||
{"Dump Backup to Text File at ","Exportar backup para texto em "}.
|
||||
{"Dump to Text File","Exportar para arquivo de texto"}.
|
||||
{"Edit Properties","Editar propriedades"}.
|
||||
{"Either approve or decline the voice request.","Você deve aprovar/desaprovar a requisição de voz."}.
|
||||
{"ejabberd IRC module","Módulo de IRC para ejabberd"}.
|
||||
{"ejabberd MUC module","Módulo de MUC para ejabberd"}.
|
||||
{"ejabberd Publish-Subscribe module","Módulo para Publicar Tópicos do ejabberd"}.
|
||||
@@ -96,8 +97,10 @@
|
||||
{"Erlang Jabber Server","Servidor Jabber em Erlang"}.
|
||||
{"Error","Erro"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Exemplo: [{\"irc.teste.net\", \"koi8-r\"}, 6667, \"senha\"}, {\"dominio.foo.net\", \"iso8859-1\", 7000}, {\"irc.servidordeteste.net\", \"utf-8\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Excluir IDs Jabber de serem submetidos ao CAPTCHA"}.
|
||||
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Exportar todos os dados de todos os usuários no servidor, para arquivos formato PIEFXIS (XEP-0227):"}.
|
||||
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Exportar dados dos usuários em um host, para arquivos PIEFXIS (XEP-0227):"}.
|
||||
{"Failed to extract JID from your voice request approval","Não foi possível extrair o JID (Jabber ID) da requisição de voz"}.
|
||||
{"Family Name","Sobrenome"}.
|
||||
{"February","Fevereiro"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Preencha campos para buscar usuários Jabber que concordem"}.
|
||||
@@ -132,7 +135,7 @@
|
||||
{"Improper message type","Tipo de mensagem incorreto"}.
|
||||
{"Incorrect password","Senha incorreta"}.
|
||||
{"Invalid affiliation: ~s","Afiliação não válida: ~s"}.
|
||||
{"Invalid role: ~s","Rol não válido: ~s"}.
|
||||
{"Invalid role: ~s","Cargo (role) é não válido: ~s"}.
|
||||
{"IP addresses","Endereços IP"}.
|
||||
{"IP","IP"}.
|
||||
{"IRC channel (don't put the first #)","Canal IRC (não coloque o #)"}.
|
||||
@@ -144,7 +147,7 @@
|
||||
{"is now known as","é agora conhecido como"}.
|
||||
{"It is not allowed to send private messages","Não é permitido enviar mensagens privadas"}.
|
||||
{"It is not allowed to send private messages of type \"groupchat\"","No está permitido enviar mensagens privados do tipo \"groupchat\""}.
|
||||
{"It is not allowed to send private messages to the conference","Impedir o envio de mensagens privados a la sala"}.
|
||||
{"It is not allowed to send private messages to the conference","Impedir o envio de mensagens privadas para a sala"}.
|
||||
{"Jabber Account Registration","Registros de Contas Jabber"}.
|
||||
{"Jabber ID","ID Jabber"}.
|
||||
{"Jabber ID ~s is invalid","O Jabber ID ~s não es válido"}.
|
||||
@@ -165,7 +168,7 @@
|
||||
{"List of modules to start","Listas de módulos para inicializar"}.
|
||||
{"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 senha da sala"}.
|
||||
{"Make room CAPTCHA protected","Tornar protegida a senha da sala"}.
|
||||
{"Make room members-only","Tornar sala apenas para membros"}.
|
||||
{"Make room moderated","Tornar a sala moderada"}.
|
||||
{"Make room password protected","Tornar protegida a senha da sala"}.
|
||||
@@ -182,6 +185,7 @@
|
||||
{"Memory","Memória"}.
|
||||
{"Message body","Corpo da mensagem"}.
|
||||
{"Middle Name","Nome do meio"}.
|
||||
{"Minimum interval between voice requests (in seconds)","O intervalo mínimo entre requisições de voz (em segundos)"}.
|
||||
{"Moderator privileges required","Se necessita privilégios de moderador"}.
|
||||
{"moderators only","apenas moderadores"}.
|
||||
{"Modified modules","Módulos atualizados"}.
|
||||
@@ -195,6 +199,7 @@
|
||||
{"Nickname","Apelido"}.
|
||||
{"Nickname Registration at ","Registro do apelido em "}.
|
||||
{"Nickname ~s does not exist in the room","O nick ~s não existe em la sala"}.
|
||||
{"nobody","ninguém"}.
|
||||
{"No body provided for announce message","Nenhum corpo de texto fornecido para anunciar mensagem"}.
|
||||
{"No Data","Nenhum dado"}.
|
||||
{"Node ID","ID do Tópico"}.
|
||||
@@ -203,7 +208,7 @@
|
||||
{"Nodes","Nós"}.
|
||||
{"No limit","Ilimitado"}.
|
||||
{"None","Nenhum"}.
|
||||
{"No resource provided","Recurso não foi fornecido"}.
|
||||
{"No resource provided","Nenhum recurso foi informado"}.
|
||||
{"Not Found","Não encontrado"}.
|
||||
{"Notify subscribers when items are removed from the node","Notificar subscritores quando os elementos se eliminem do nodo"}.
|
||||
{"Notify subscribers when the node configuration changes","Notificar subscritores quando cambia la configuração do nodo"}.
|
||||
@@ -222,6 +227,7 @@
|
||||
{"Only deliver notifications to available users","Solo enviar notificações aos usuários disponíveis"}.
|
||||
{"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","Solo os ocupantes podem enviar mensagens a la sala"}.
|
||||
{"Only occupants are allowed to send queries to the conference","Solo os ocupantes podem enviar consultas a la sala"}.
|
||||
{"Only service administrators are allowed to send service messages","Apenas administradores possuem permissão para enviar mensagens de serviço"}.
|
||||
@@ -244,11 +250,12 @@
|
||||
{"Persist items to storage","Persistir elementos ao armazenar"}.
|
||||
{"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 você esteja utilizando o modulo ODBC, você precisará fazer backup de 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"}.
|
||||
{"Port ~b","Porta ~b"}.
|
||||
{"Port","Porta"}.
|
||||
{"Present real Jabber IDs to","Tornar o Jabber ID real visível por"}.
|
||||
{"private, ","privado"}.
|
||||
{"private, ","privado, "}.
|
||||
{"Protocol","Porta"}.
|
||||
{"Publish-Subscribe","Publicação de Tópico"}.
|
||||
{"PubSub subscriber request","PubSub requisição de assinante"}.
|
||||
@@ -265,7 +272,7 @@
|
||||
{"Registration in mod_irc for ","Registro em mod_irc para "}.
|
||||
{"Remote copy","Copia remota"}.
|
||||
{"Remove All Offline Messages","Remover Todas as Mensagens Offline"}.
|
||||
{"Remove","Borrar"}.
|
||||
{"Remove","Remover"}.
|
||||
{"Remove User","Remover usuário"}.
|
||||
{"Replaced by new connection","Substituído por nova conexão"}.
|
||||
{"Resources","Recursos"}.
|
||||
@@ -330,7 +337,8 @@
|
||||
{"Sunday","Domingo"}.
|
||||
{"That nickname is already in use by another occupant","O apelido (nick) já está sendo utilizado"}.
|
||||
{"That nickname is registered by another person","O nick já está registrado por outra pessoa"}.
|
||||
{"The captcha is valid.","O captcha é inválido."}.
|
||||
{"The CAPTCHA is valid.","O CAPTCHA é inválido."}.
|
||||
{"The CAPTCHA verification has failed","A verificação do CAPTCHA falhou"}.
|
||||
{"The collections with which a node is affiliated","As coleções com as quais o nó está relacionado"}.
|
||||
{"the password is","a senha é"}.
|
||||
{"The password of your Jabber account was successfully changed.","A senha da sua conta Jabber foi mudada com sucesso."}.
|
||||
@@ -347,6 +355,7 @@
|
||||
{"Thursday","Quinta"}.
|
||||
{"Time delay","Intervalo (Tempo)"}.
|
||||
{"Time","Fecha"}.
|
||||
{"Too many CAPTCHA requests","Número excessivo de requisições para o CAPTCHA"}.
|
||||
{"To","Para"}.
|
||||
{"To ~s","Para ~s"}.
|
||||
{"Traffic rate limit is exceeded","Limite de banda excedido"}.
|
||||
@@ -355,7 +364,7 @@
|
||||
{"Transactions Logged:","Transações de log:"}.
|
||||
{"Transactions Restarted:","Transações reiniciadas:"}.
|
||||
{"Tuesday","Terça"}.
|
||||
{"Unable to generate a captcha","Impossível gerar um captcha"}.
|
||||
{"Unable to generate a CAPTCHA","Impossível gerar um CAPTCHA"}.
|
||||
{"Unauthorized","Não Autorizado"}.
|
||||
{"Unregister a Jabber account","Deletar conta Jabber"}.
|
||||
{"Unregister","Deletar registro"}.
|
||||
@@ -366,7 +375,7 @@
|
||||
{"Update plan","Plano de Atualização"}.
|
||||
{"Update script","Script de atualização"}.
|
||||
{"Uptime:","Uptime:"}.
|
||||
{"Use of STARTTLS required","É obrigatório usar STARTTLS"}.
|
||||
{"Use of STARTTLS required","É obrigatório uso de STARTTLS"}.
|
||||
{"User Management","Gerenciamento de Usuários"}.
|
||||
{"Users are not allowed to register accounts so quickly","Usuários não estão autorizados a registrar contas imediatamente"}.
|
||||
{"Users Last Activity","Ultimas atividades dos usuários"}.
|
||||
@@ -378,6 +387,8 @@
|
||||
{"Virtual Hosts","Hosts virtuais"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Nesta sala, os visitantes não pode mudar seus apelidos"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Os visitantes não podem enviar mensagens a todos os ocupantes"}.
|
||||
{"Voice request","Requisição de voz"}.
|
||||
{"Voice requests are disabled in this conference","Requisições de voz estào desabilitadas nesta conferência"}.
|
||||
{"Wednesday","Quarta"}.
|
||||
{"When to send the last published item","Quando enviar o último tópico publicado"}.
|
||||
{"Whether to allow subscriptions","Permitir subscrições"}.
|
||||
@@ -387,7 +398,7 @@
|
||||
{"You need an x:data capable client to configure mod_irc settings","Necessitas um cliente com suporte de x:data para configurar las opções de mod_irc"}.
|
||||
{"You need an x:data capable client to configure room","Necessitas um cliente com suporte de x:data para configurar la sala"}.
|
||||
{"You need an x:data capable client to search","Necessitas um cliente com suporte de x:data para poder buscar"}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","Sua lista de privacidade ativa negou o roteamento desta estada."}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","Sua lista de privacidade ativa negou o roteamento deste."}.
|
||||
{"Your contact offline message queue is full. The message has been discarded.","Sua fila de mensagens offline esta cheia. Sua mensagem foi descartada"}.
|
||||
{"Your Jabber account was successfully created.","Sua conta jabber foi criada corretamente."}.
|
||||
{"Your Jabber account was successfully deleted.","Sua conta Jabber foi deletada com sucesso."}.
|
||||
File diff suppressed because it is too large
Load Diff
+369
-311
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,9 @@
|
||||
{"Allow users to send invites","Разрешить пользователям посылать приглашения"}.
|
||||
{"Allow users to send private messages","Разрешить приватные сообщения"}.
|
||||
{"Allow visitors to change nickname","Разрешить посетителям изменять псевдоним"}.
|
||||
{"Allow visitors to send private messages to","Разрешить посетителям посылать приватные сообщения"}.
|
||||
{"Allow visitors to send status text in presence updates","Разрешить посетителям вставлять текcт статуса в сообщения о присутствии"}.
|
||||
{"Allow visitors to send voice requests","Разрешить посетителям запрашивать право голоса"}.
|
||||
{"All Users","Все пользователи"}.
|
||||
{"Announcements","Объявления"}.
|
||||
{"anyone","всем участникам"}.
|
||||
@@ -75,6 +77,7 @@
|
||||
{"Dump Backup to Text File at ","Копирование в текстовый файл на "}.
|
||||
{"Dump to Text File","Копирование в текстовый файл"}.
|
||||
{"Edit Properties","Изменить параметры"}.
|
||||
{"Either approve or decline the voice request.","Подтвердите или отклоните право голоса."}.
|
||||
{"ejabberd IRC module","ejabberd IRC модуль"}.
|
||||
{"ejabberd MUC module","ejabberd MUC модуль"}.
|
||||
{"ejabberd Publish-Subscribe module","Модуль ejabberd Публикации-Подписки"}.
|
||||
@@ -98,8 +101,10 @@
|
||||
{"Erlang Jabber Server","Erlang Jabber Server"}.
|
||||
{"Error","Ошибка"}.
|
||||
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Пример: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}.
|
||||
{"Exclude Jabber IDs from CAPTCHA challenge","Исключить показ капчи для списка Jabber ID"}.
|
||||
{"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 из вашего запроса на право голоса"}.
|
||||
{"Family Name","Фамилия"}.
|
||||
{"February","февраля"}.
|
||||
{"Fill in fields to search for any matching Jabber User","Заполните форму для поиска пользователя Jabber"}.
|
||||
@@ -113,6 +118,7 @@
|
||||
{"Get User Last Login Time","Получить время последнего подключения пользователя"}.
|
||||
{"Get User Password","Получить пароль пользователя"}.
|
||||
{"Get User Statistics","Получить статистику по пользователю"}.
|
||||
{"Grant voice to this person?","Предоставить голос?"}.
|
||||
{"Groups","Группы"}.
|
||||
{"Group ","Группа "}.
|
||||
{"has been banned","запретили входить в комнату"}.
|
||||
@@ -168,7 +174,7 @@
|
||||
{"List of modules to start","Список запускаемых модулей"}.
|
||||
{"Low level update script","Низкоуровневый сценарий обновления"}.
|
||||
{"Make participants list public","Сделать список участников видимым всем"}.
|
||||
{"Make room captcha protected","Сделать комнату защищённой капчей"}.
|
||||
{"Make room CAPTCHA protected","Сделать комнату защищённой капчей"}.
|
||||
{"Make room members-only","Комната только для зарегистрированных участников"}.
|
||||
{"Make room moderated","Сделать комнату модерируемой"}.
|
||||
{"Make room password protected","Сделать комнату защищённой паролем"}.
|
||||
@@ -185,6 +191,7 @@
|
||||
{"Memory","Память"}.
|
||||
{"Message body","Тело сообщения"}.
|
||||
{"Middle Name","Отчество"}.
|
||||
{"Minimum interval between voice requests (in seconds)","Минимальный интервал между запросами на право голоса"}.
|
||||
{"Moderator privileges required","Требуются права модератора"}.
|
||||
{"moderators only","только модераторам"}.
|
||||
{"Modified modules","Изменённые модули"}.
|
||||
@@ -200,6 +207,7 @@
|
||||
{"Nickname ~s does not exist in the room","Псевдоним ~s в комнате отсутствует"}.
|
||||
{"Nickname","Псевдоним"}.
|
||||
{"No body provided for announce message","Тело объявления не должно быть пустым"}.
|
||||
{"nobody","никто"}.
|
||||
{"No Data","Нет данных"}.
|
||||
{"Node ID","ID узла"}.
|
||||
{"Node not found","Узел не найден"}.
|
||||
@@ -227,6 +235,7 @@
|
||||
{"Only deliver notifications to available users","Доставлять уведомления только доступным пользователям"}.
|
||||
{"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 service administrators are allowed to send service messages","Только администратор службы может посылать служебные сообщения"}.
|
||||
@@ -250,6 +259,7 @@
|
||||
{"Persist items to storage","Сохранять публикации в хранилище"}.
|
||||
{"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), то его резервное копирование следует осуществлять отдельно."}.
|
||||
{"Please, wait for a while before sending new voice request","Пожалуйста, подождите перед тем как подать новый запрос на право голоса"}.
|
||||
{"Pong","Понг"}.
|
||||
{"Port ~b","Порт ~b"}.
|
||||
{"Port","Порт"}.
|
||||
@@ -338,7 +348,7 @@
|
||||
{"Sunday","Воскресенье"}.
|
||||
{"That nickname is already in use by another occupant","Этот псевдоним уже занят другим участником"}.
|
||||
{"That nickname is registered by another person","Этот псевдоним зарегистрирован кем-то другим"}.
|
||||
{"The captcha is valid.","Проверка капчи прошла успешно."}.
|
||||
{"The CAPTCHA is valid.","Проверка капчи прошла успешно."}.
|
||||
{"The CAPTCHA verification has failed","Проверка капчи не пройдена"}.
|
||||
{"The collections with which a node is affiliated","Имя коллекции, в которую входит узел"}.
|
||||
{"The password is too weak","Слишком слабый пароль"}.
|
||||
@@ -357,6 +367,7 @@
|
||||
{"Thursday","Четверг"}.
|
||||
{"Time delay","По истечение"}.
|
||||
{"Time","Время"}.
|
||||
{"Too many CAPTCHA requests","Слишком много запросов капчи"}.
|
||||
{"To ~s","К ~s"}.
|
||||
{"To","Кому"}.
|
||||
{"Traffic rate limit is exceeded","Превышен лимит скорости посылки информации"}.
|
||||
@@ -365,7 +376,6 @@
|
||||
{"Transactions Logged:","Транзакции запротоколированные:"}.
|
||||
{"Transactions Restarted:","Транзакции перезапущенные:"}.
|
||||
{"Tuesday","Вторник"}.
|
||||
{"Unable to generate a captcha","Не получилось создать капчу"}.
|
||||
{"Unable to generate a CAPTCHA","Не получилось создать капчу"}.
|
||||
{"Unauthorized","Не авторизован"}.
|
||||
{"Unregister a Jabber account","Удалить Jabber-аккаунт"}.
|
||||
@@ -378,6 +388,7 @@
|
||||
{"Update ","Обновление "}.
|
||||
{"Uptime:","Время работы:"}.
|
||||
{"Use of STARTTLS required","Вы обязаны использовать STARTTLS"}.
|
||||
{"User JID","JID пользователя"}.
|
||||
{"User Management","Управление пользователями"}.
|
||||
{"Username:","Имя пользователя:"}.
|
||||
{"Users are not allowed to register accounts so quickly","Пользователи не могут регистрировать учётные записи так быстро"}.
|
||||
@@ -390,6 +401,8 @@
|
||||
{"Virtual Hosts","Виртуальные хосты"}.
|
||||
{"Visitors are not allowed to change their nicknames in this room","Посетителям запрещено изменять свои псевдонимы в этой комнате"}.
|
||||
{"Visitors are not allowed to send messages to all occupants","Посетителям не разрешается посылать сообщения всем присутствующим"}.
|
||||
{"Voice requests are disabled in this conference","Запросы на право голоса отключены в этой конференции"}.
|
||||
{"Voice request","Запрос на право голоса"}.
|
||||
{"Wednesday","Среда"}.
|
||||
{"When to send the last published item","Когда посылать последний опубликованный элемент"}.
|
||||
{"Whether to allow subscriptions","Разрешить подписку"}.
|
||||
+372
-315
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user