Compare commits
1202 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b2c2b5c04 | |||
| 39cfee239d | |||
| 1f02567507 | |||
| 4f5d54f062 | |||
| fc2b71a04e | |||
| 87b964a7f6 | |||
| 4cf83ca3a7 | |||
| 3d9997288d | |||
| 527472f18c | |||
| d2b8569452 | |||
| 3482ee5c75 | |||
| 3029e84faf | |||
| ba47fd4649 | |||
| 2de2d00f14 | |||
| 2a68591181 | |||
| 94ac777f93 | |||
| 0ea6c1dcf6 | |||
| 2ce6d49a40 | |||
| c7476875e6 | |||
| ce42b6be01 | |||
| 7606be93d5 | |||
| e2665c5da9 | |||
| 32d548d99b | |||
| 25ddb6c69d | |||
| 03667d0c73 | |||
| f2acf57412 | |||
| efccee55e3 | |||
| 6ff81946cf | |||
| 08d482b064 | |||
| 3d0d9cb354 | |||
| afc7f5aa37 | |||
| f14a966680 | |||
| 9605e2b2a4 | |||
| a910ab8171 | |||
| 32e5781a6a | |||
| f5290a8e44 | |||
| 5fdd1c39fe | |||
| 769975f6d7 | |||
| 1bda40dac7 | |||
| 5ef60bf594 | |||
| 666608544b | |||
| c6b5dd6c4f | |||
| ed679279fd | |||
| fad7612cf1 | |||
| df92d96d4f | |||
| 7ef8dfb4e0 | |||
| b30b70db70 | |||
| 08f73a5aeb | |||
| 3811a61573 | |||
| cc14e223c6 | |||
| 1a4f63f058 | |||
| bcc04d93e1 | |||
| 2976c2d921 | |||
| a50247c20d | |||
| fdf69dcd0d | |||
| a3b12fd745 | |||
| 8a7ea85a7e | |||
| a681874f67 | |||
| 1c8edd07a1 | |||
| 1883a98d1c | |||
| 0c2491d9ea | |||
| 23f7075313 | |||
| 23786c95c9 | |||
| 847376924e | |||
| d7e1f6d7b3 | |||
| 34f2a8a4f2 | |||
| 68cf6845e1 | |||
| 294d58a393 | |||
| 732eecac43 | |||
| a3c134c43b | |||
| 309fd56fb4 | |||
| 8618af4e34 | |||
| 32f484a349 | |||
| 92db9ff105 | |||
| 95a4b1b266 | |||
| 2cd70280d2 | |||
| fc7e52df71 | |||
| 56b30ab598 | |||
| 3ac73f9607 | |||
| 18609befa4 | |||
| ae297a4ae6 | |||
| 9432a16893 | |||
| ca1b22bdd4 | |||
| 4d6eb31264 | |||
| e1539e5769 | |||
| 993cbcb133 | |||
| d554827ebc | |||
| 0f11b1be36 | |||
| 28d0a1b9d2 | |||
| 49f1275e20 | |||
| b14843d098 | |||
| 8f692f51d8 | |||
| 560038c808 | |||
| d12210f4e1 | |||
| 9c3ebb7d22 | |||
| b6ddcf3e58 | |||
| cbda2e038e | |||
| 6a4f2a78ff | |||
| 12683b4aaf | |||
| 5d434c1aea | |||
| 6f2f1e87c9 | |||
| 3325e69ae6 | |||
| 114ca786ee | |||
| ee8cc1dac2 | |||
| 9ab169bc63 | |||
| 24ef90c556 | |||
| c0e7b298db | |||
| cc63bcc997 | |||
| a2fb493f91 | |||
| ebadcf71c2 | |||
| fbfbb96872 | |||
| 577eeb642f | |||
| 7ffab38b44 | |||
| 2786df651a | |||
| c0b5c6e9d4 | |||
| 3189bb3bb9 | |||
| 3908a80ac9 | |||
| 1a02a2a51d | |||
| b8e8e4b971 | |||
| 04fdf69737 | |||
| e57de02e0f | |||
| c5e7b4738f | |||
| e6365979bd | |||
| 274303f248 | |||
| 507e756b69 | |||
| 3f91668c46 | |||
| c7ae916afc | |||
| 049a6d97f1 | |||
| 13c6039700 | |||
| de7a143a2c | |||
| 9aff7e52a8 | |||
| d00a634025 | |||
| daab95e3b5 | |||
| 45e77ea483 | |||
| e69937d93a | |||
| f57f267c54 | |||
| b8dcc911a3 | |||
| 995c97671d | |||
| 1c90b19d74 | |||
| 8ced3bdbe9 | |||
| 3cd174cb56 | |||
| e69ddd981f | |||
| b1723c6e2d | |||
| 5a01b5f1fc | |||
| 2929f5b5bc | |||
| 4d4ad922a2 | |||
| 8df68266f2 | |||
| 2b93de6912 | |||
| 909e0eb5dd | |||
| e75dd17e2c | |||
| 41794c57d6 | |||
| 5ffc01db53 | |||
| 717159a98f | |||
| 309962fb8b | |||
| 3765210698 | |||
| 13d5da4da6 | |||
| 75c15d3853 | |||
| ebefd0d8d6 | |||
| 7e9f1a6dc1 | |||
| 132033d01a | |||
| 21d78ed7f4 | |||
| b8f22ff538 | |||
| 534e73f732 | |||
| de81c50199 | |||
| 5d552c8463 | |||
| 78a44e0176 | |||
| 566ac872fe | |||
| 42bede77a1 | |||
| 35506f5470 | |||
| e841a6ec34 | |||
| e9dd3ffe9c | |||
| 56c91d3c58 | |||
| bd060bc1bb | |||
| 49d3b7ec1d | |||
| 5e723bc90e | |||
| bab71f0832 | |||
| 62db030942 | |||
| 2a63d0e95a | |||
| 149cc9654f | |||
| 9d977e484a | |||
| f6236d456d | |||
| ed6bc9081b | |||
| cdafd3254b | |||
| 509776a0d1 | |||
| 2ab72bcd00 | |||
| 0212559ca7 | |||
| 1bdbe54442 | |||
| a5e737157c | |||
| 0a3fcc9ade | |||
| 7621564839 | |||
| 686305bb21 | |||
| c3b62d2f75 | |||
| f56840a682 | |||
| 059a806bb0 | |||
| 3ec68a4ecf | |||
| 3b876875e9 | |||
| d19552f464 | |||
| 4c5460f0bd | |||
| 90acec8a2b | |||
| 305d4c05dc | |||
| 67720c7713 | |||
| fd6f0f94b5 | |||
| a1faecc4c9 | |||
| d97e777c9b | |||
| b693601dd1 | |||
| 4935ac8866 | |||
| ead7e21037 | |||
| 0f67a8f98b | |||
| a915fd161e | |||
| dffcfe74d4 | |||
| 5c48263579 | |||
| 6a3691ef7c | |||
| d701230555 | |||
| e54ba3db5b | |||
| 0ae84a646f | |||
| b01fbfadf3 | |||
| 438dbc8bda | |||
| 8accb8ee0c | |||
| a78c3422cd | |||
| 695d22ef95 | |||
| 98e0123ca4 | |||
| 9cee3760db | |||
| 1de0bb83a0 | |||
| 7566e267a7 | |||
| 15ebb79160 | |||
| 767dba8f3b | |||
| a42bf67957 | |||
| 6f538545b4 | |||
| d4b4f35a0e | |||
| acab2270f1 | |||
| ac6f701033 | |||
| d327119cf7 | |||
| 3112a7187f | |||
| 7100c67be6 | |||
| fa31e3ef23 | |||
| 58969fb854 | |||
| 53209b9ab1 | |||
| ceda073766 | |||
| a4ec064455 | |||
| e7787e2f33 | |||
| 5bcfcf4c5e | |||
| 9fa92092bf | |||
| f2cc81dfea | |||
| 8244c1fa8c | |||
| ed62d705d8 | |||
| da291d804c | |||
| 662b6f1020 | |||
| 27999a122f | |||
| 151668ac10 | |||
| 405a0a21c1 | |||
| c39501a48d | |||
| c3543e002d | |||
| e987b88848 | |||
| 2f596b0e10 | |||
| 054382f074 | |||
| 96d05dad8f | |||
| 1aca541639 | |||
| d0761039ff | |||
| fe1bf27ef3 | |||
| d222fed228 | |||
| 8fd888eb2b | |||
| 41386d718d | |||
| 26a040e2d5 | |||
| 4bd45bada7 | |||
| ad39da0b0a | |||
| c29a48695d | |||
| 36ab9cc2ea | |||
| 5ec972b00f | |||
| 6c943aa293 | |||
| 803270fc6b | |||
| e6f7233351 | |||
| 58a72bd395 | |||
| d2621130a3 | |||
| a8368278ec | |||
| 621f0e2b7c | |||
| 7a538bb88b | |||
| af0a493c66 | |||
| f304149615 | |||
| 3803a8de3c | |||
| 1edca899ff | |||
| c6afb9731b | |||
| 5ec2874a96 | |||
| 417284a921 | |||
| af2999a783 | |||
| 48ce34987d | |||
| e29f47893f | |||
| c770a54aac | |||
| 96a748d34f | |||
| 45eb49125b | |||
| 31592fe51f | |||
| f1afea223b | |||
| 1bfa1c613b | |||
| d5659735b3 | |||
| 23d9fb0592 | |||
| 8dd2044a27 | |||
| e13edff6ae | |||
| 8af85d913f | |||
| 20a510d877 | |||
| 8821cf8b27 | |||
| 4d19fb518f | |||
| e7217e6320 | |||
| 5b4f347da8 | |||
| 38666cfd58 | |||
| 877d0752e2 | |||
| 0ab08f4eeb | |||
| 4ee8af633b | |||
| bf9d6b5534 | |||
| 28dde294e5 | |||
| 31faa4eb9a | |||
| ffba664f2c | |||
| 50596dc4d3 | |||
| e63fe5c216 | |||
| 1fc58ace2f | |||
| 522a186a38 | |||
| c4b14d045a | |||
| 9c6ee60f1a | |||
| efc744092b | |||
| a0c8012c66 | |||
| b62aa3d2dc | |||
| 91e26fbf7a | |||
| c2ef55a075 | |||
| d969e917c6 | |||
| 4ff8d7918a | |||
| 9a5f0751be | |||
| b487ccfb34 | |||
| ca217dc105 | |||
| 8b81b9ecb1 | |||
| cbdc106427 | |||
| bc33a3873d | |||
| 72b0fb49e8 | |||
| 111aa83f5e | |||
| abb4446b51 | |||
| a417fbf45b | |||
| 5d06c6acbf | |||
| 78fa9e08a5 | |||
| 3c1e4f0dfd | |||
| 4add262090 | |||
| 76eba3647a | |||
| 2ef58a33a9 | |||
| d02d7b2b6a | |||
| 90ea3ca361 | |||
| bf45c9eeee | |||
| a9c6748ec7 | |||
| 4982639d05 | |||
| c5c394e929 | |||
| 6ea7153e31 | |||
| c0272ae766 | |||
| e258462b6b | |||
| 0bcbd12776 | |||
| 2a49f8cae7 | |||
| 674a8039ef | |||
| 4bf8ce7681 | |||
| eb1d385d4e | |||
| 5cd1cf5096 | |||
| 792e6a7c1c | |||
| 19ad6e6145 | |||
| 39640b67c7 | |||
| d2d3b961eb | |||
| fb2603d3cd | |||
| 4a49dfecf3 | |||
| f19d2fdcff | |||
| a093e9d441 | |||
| 42e6f72ee9 | |||
| 9bf1bac7df | |||
| f91f2bc3d2 | |||
| 3c58a93eb8 | |||
| a080322055 | |||
| fd365b2893 | |||
| fad088a3c4 | |||
| 91865c66c0 | |||
| 7a74a4836a | |||
| b31ebd2ea0 | |||
| 96e912b09a | |||
| 8275e95a16 | |||
| 1097d31d63 | |||
| c409ed2f2c | |||
| 72445bb374 | |||
| 984c4cf6bd | |||
| 2a8005e47f | |||
| 7781f39b74 | |||
| e5fd1ee4f6 | |||
| 9ff7257287 | |||
| 12f74b4aa7 | |||
| fede85c9bd | |||
| 23858469b7 | |||
| c26d38a893 | |||
| da310a5173 | |||
| 839490b0d9 | |||
| dbc0498279 | |||
| c183092aa4 | |||
| 5d4f8bcf0d | |||
| 179fcd9521 | |||
| d7ad99f147 | |||
| 4b0d71d402 | |||
| b4a430541d | |||
| bfa61eaa46 | |||
| 68555ff466 | |||
| caf2c20210 | |||
| 1485b56211 | |||
| 2c70c572c8 | |||
| d4d1941133 | |||
| 814b80c644 | |||
| 4332dddbc4 | |||
| 57aeef74d5 | |||
| 12b58b9870 | |||
| caf7b54305 | |||
| c5d9d35e7b | |||
| ffbe97d988 | |||
| bdfef09c0f | |||
| dd38bef8b1 | |||
| 6983dfa21f | |||
| cbfab687e8 | |||
| c2753cd51c | |||
| 5458d8bfcb | |||
| 7748dd4e5d | |||
| 0c0c6465ba | |||
| b5a90be3cb | |||
| 1d317e8068 | |||
| 8f8c499cfa | |||
| 9fcb81dea9 | |||
| 5d90292849 | |||
| 490a758050 | |||
| f79ac6874e | |||
| 655cbf6055 | |||
| bc802a4049 | |||
| a4a9dd7f03 | |||
| 483ef09263 | |||
| 33e0283f0d | |||
| 673a654c47 | |||
| 48c88b61b6 | |||
| fca2f24231 | |||
| 8bc3dc9c49 | |||
| 9a8e197d7e | |||
| 749033598d | |||
| f6e960d326 | |||
| 786bd4f26c | |||
| 5f48d2641b | |||
| 1a62d4e04b | |||
| 6b38d19085 | |||
| 661b041302 | |||
| 368b202144 | |||
| caaf02eaa0 | |||
| 32de9a56a5 | |||
| febbc2bb5a | |||
| 71f27ee7d4 | |||
| c718cbbd9f | |||
| 12c0d888b1 | |||
| 4220a2b98c | |||
| de9f80f2ce | |||
| be3a4acb55 | |||
| 3820aaa421 | |||
| e300f8095d | |||
| b31c0d9e2e | |||
| 8e04a7ef4d | |||
| 16b1d8541a | |||
| 0737958b45 | |||
| 024124decb | |||
| 88ac1dc56b | |||
| 8be1d49961 | |||
| 10d4c16a97 | |||
| ce0d1704c6 | |||
| 2e28d06744 | |||
| 3446aba753 | |||
| 75366ca2fd | |||
| f56cff925c | |||
| 94461948db | |||
| 0b438d09d1 | |||
| 06bf8cb032 | |||
| 1794dd19d0 | |||
| 1b5c50a384 | |||
| a9b456ccb3 | |||
| 2ebdd8915e | |||
| e54400a8e4 | |||
| 065f5272e6 | |||
| 751be3cca6 | |||
| cd0244eb71 | |||
| f029488260 | |||
| eeeb190680 | |||
| 95ff94b054 | |||
| 7744339347 | |||
| 2efa8677c9 | |||
| c928956d73 | |||
| 7ddeac38b6 | |||
| 3a8da27d86 | |||
| 52d45604ba | |||
| 804190e4a8 | |||
| 4b9613e8fe | |||
| b2f53fb962 | |||
| c91c5aa352 | |||
| 6f2b0179e7 | |||
| 8583958268 | |||
| d1425f0d78 | |||
| f1138baa80 | |||
| 1fb1e8721b | |||
| 0a09f27373 | |||
| 7b308e0d41 | |||
| 9004608181 | |||
| 26bce5dee3 | |||
| 34cf693231 | |||
| 0e61e57ed9 | |||
| 34cbed54cd | |||
| 4ccc40bce5 | |||
| 53f3a45803 | |||
| 858d880675 | |||
| a4f213837e | |||
| 5173de503c | |||
| 8a7b31ca63 | |||
| f8d2589ee5 | |||
| 78d4200f05 | |||
| 60803f5780 | |||
| 5c3074c0fb | |||
| 4789ddf1ee | |||
| 41c3751fa1 | |||
| 8305cc293b | |||
| 4d5eab6662 | |||
| 3a1fc6fb66 | |||
| 5c1db176a9 | |||
| 0503d899cf | |||
| 0093326f7d | |||
| 9ef52b8c64 | |||
| d201f013b2 | |||
| 5352037680 | |||
| bbb90b9928 | |||
| 9c27f31d72 | |||
| e7843bf92b | |||
| db240413ab | |||
| 8e883a76e3 | |||
| 622bff23a4 | |||
| be0dd51e51 | |||
| fc2b7018cc | |||
| 17f87eb899 | |||
| 1ade88402c | |||
| f252b9d489 | |||
| 1d3959b5a2 | |||
| e81302dc79 | |||
| 9e68c4c0d9 | |||
| 1981e13326 | |||
| fffae97940 | |||
| 49658e1655 | |||
| c55319c81e | |||
| 13ead140f4 | |||
| ca329826cb | |||
| 14b53fbcb0 | |||
| b055c2a13a | |||
| 639e9fab4e | |||
| c958fa2f06 | |||
| 30e814dd4b | |||
| 8c16fdf59f | |||
| a2f0e157bc | |||
| 2a9dd548b5 | |||
| 3f3ecad981 | |||
| 70452ba25a | |||
| 1b02c5fbf3 | |||
| 9d87a4a6d4 | |||
| f6ba91ff97 | |||
| 420ae65590 | |||
| 8f72c27b88 | |||
| 4f009e64fc | |||
| ba74c1c367 | |||
| ba2680df61 | |||
| 2529acc36c | |||
| ff199a323d | |||
| 64bb371285 | |||
| 9bd446e519 | |||
| 792f47b4bd | |||
| be2a9e35ae | |||
| 068db1a2d9 | |||
| 4717d64d7a | |||
| f7f40cf9a6 | |||
| bcf07fd032 | |||
| ff4a0e1808 | |||
| 51238bff83 | |||
| 86d5cf6d6c | |||
| b2ffa1db96 | |||
| 0ea0ba3004 | |||
| d6700bdc5b | |||
| 13c6430341 | |||
| 12a8d915cd | |||
| 6cb60aaff5 | |||
| 575ef9c619 | |||
| 5e5328da4a | |||
| 6da07d78b5 | |||
| 0c0ce17bc0 | |||
| 8a6c51290a | |||
| 671bc4e573 | |||
| 07196b6c62 | |||
| 53e1100cc4 | |||
| 47050db6b8 | |||
| d54f211514 | |||
| b46ed7044a | |||
| b202004862 | |||
| 8700a3401e | |||
| 82082f1799 | |||
| 3493a87469 | |||
| 6a10916dda | |||
| 639c2fb640 | |||
| c585f74730 | |||
| d18fe138aa | |||
| d6f02a51e4 | |||
| 9c369b7a8c | |||
| d8bb5d9c01 | |||
| 26d3a978cc | |||
| 0f06ed8a9b | |||
| d1db9f92c4 | |||
| 52fde758b3 | |||
| b79aef3bbc | |||
| bae24464d3 | |||
| ef90a389c1 | |||
| 36164d9446 | |||
| 45321fa2e2 | |||
| 65ad70d7dc | |||
| a37cf33358 | |||
| 58478e52bf | |||
| cebdfb6523 | |||
| b79f09d0eb | |||
| beeb1c82d9 | |||
| 2660dcabba | |||
| f0e6def3ed | |||
| 8487b51ecd | |||
| f7d4aae64d | |||
| 97e3a33077 | |||
| 1aae8a9fda | |||
| fafeeb80c2 | |||
| 655c22021b | |||
| 382c6ce1fb | |||
| 0bdcafdb02 | |||
| e5e4f39c01 | |||
| 222572bd56 | |||
| 64fdbe7866 | |||
| fb0ecf3361 | |||
| 52571e8624 | |||
| 901d2e0aed | |||
| 860db2ddca | |||
| c8c4a41b66 | |||
| 79d64e0d71 | |||
| f8e3560ad2 | |||
| 398f1de5ae | |||
| 0b439a7d5b | |||
| ae69f09257 | |||
| ef70ce65ab | |||
| b5d1ce795f | |||
| cd094bc903 | |||
| 2d7e03f5e1 | |||
| b2abc1edb7 | |||
| 7fd4808cde | |||
| 5eef8a8bcf | |||
| cd2e2b1a88 | |||
| 5958a91428 | |||
| 15d184a909 | |||
| 8c8a6869be | |||
| 695592a38c | |||
| bd3b7cd2df | |||
| b67dc00db2 | |||
| 127342449e | |||
| b4739396ec | |||
| 1dbdd58b1b | |||
| c5dbdfc71a | |||
| 86dfbe6ece | |||
| b83ec483e9 | |||
| afd3accf75 | |||
| 0935f493ee | |||
| 373f9fb0eb | |||
| 60c0c8e968 | |||
| 18557fa3d6 | |||
| a938af4180 | |||
| d5c29360fb | |||
| 48a1d818d6 | |||
| eb36440c2e | |||
| 47039aed15 | |||
| d45ad3e3a5 | |||
| 5ad8c790c7 | |||
| 5efcf0a175 | |||
| 0916694e0e | |||
| 2900aa208f | |||
| 27b4217a9d | |||
| a9e50468b6 | |||
| abf768274a | |||
| f78b170c24 | |||
| 991529a657 | |||
| b2279d481d | |||
| 267fdb2e95 | |||
| d9f1061b8a | |||
| dd654fa794 | |||
| 1b9b5f8e6a | |||
| 67b9b82261 | |||
| 2eee2de6e2 | |||
| acc11195f8 | |||
| be7f65da05 | |||
| 232915184c | |||
| 9ac6e4edf7 | |||
| 490aa2c6a6 | |||
| ca9ac019eb | |||
| e24da5789e | |||
| 47266de6d7 | |||
| f243c30847 | |||
| 2a2a47b5c6 | |||
| b5f1479763 | |||
| a8f92ae767 | |||
| 97d345d287 | |||
| ef2e2e45b3 | |||
| 3290a5ff15 | |||
| 7988e2e350 | |||
| dc0ca51ef1 | |||
| 78c4a0d65f | |||
| 91233eafaa | |||
| da0751239c | |||
| 3dc55c6d47 | |||
| d35c5ebde5 | |||
| 3cfcdbb245 | |||
| 7c2998a55d | |||
| fced8dc3d9 | |||
| c00cfca8e7 | |||
| 3c480a5b0b | |||
| b160bd7ac1 | |||
| 809057678b | |||
| 36ac1cd6c7 | |||
| ead83b008c | |||
| 6f25122f8c | |||
| bf79f223df | |||
| e58b62f737 | |||
| 82cf7f7ca8 | |||
| 6d7891ed16 | |||
| c7c70ffa0a | |||
| 78a44d8099 | |||
| b49a615e21 | |||
| 3b2d0fd24a | |||
| aa15148898 | |||
| 3809b898aa | |||
| e386bf6b58 | |||
| 221d8e0e5d | |||
| 53d12caa56 | |||
| b0ef3e66a8 | |||
| 7a9e93839a | |||
| 54ddc990c2 | |||
| 4afe0b195c | |||
| 494e638f03 | |||
| 915ccbbdfb | |||
| 381065397f | |||
| a08ecc0f41 | |||
| eace5fc463 | |||
| 0afcf561d6 | |||
| 46568fb959 | |||
| c7cf95ba99 | |||
| 914578a85e | |||
| df4c551f06 | |||
| a3a33bd5fc | |||
| 7066338948 | |||
| cb27a3540e | |||
| 61e914a83f | |||
| b90c3764c0 | |||
| bdce5556bd | |||
| 57f7b34b90 | |||
| f8cf1aef91 | |||
| e7ef65a22d | |||
| 107569a17d | |||
| 0112135096 | |||
| 4be9cc1b6d | |||
| 95475966fd | |||
| ef04dd75aa | |||
| 3441157a38 | |||
| c98df3c0da | |||
| c924cd42ff | |||
| 31c194a682 | |||
| 5b7dc0c215 | |||
| 0e3026539e | |||
| dc7b2c45c2 | |||
| cf9ef456b7 | |||
| 7b5825a205 | |||
| 2d103b4ae1 | |||
| 939bb244e1 | |||
| f19a54e9a1 | |||
| ef02053a9d | |||
| d9bb3730b7 | |||
| 7b72247b2c | |||
| 34bc698526 | |||
| efbaba5d04 | |||
| c985a2bd3d | |||
| 74053b114e | |||
| b40154f8f4 | |||
| 3c2cd91fb1 | |||
| 367adc2113 | |||
| 5b5548b8ca | |||
| 058b3d96bf | |||
| 68675effac | |||
| 3fef1a4435 | |||
| 7f25c3b3e8 | |||
| dcefb6bbe3 | |||
| 5351e8236d | |||
| 9440049208 | |||
| b871fbba1b | |||
| 91573a8e82 | |||
| 55c567ff00 | |||
| 5a4b7817df | |||
| 50e5cdc2fa | |||
| 5045fb584d | |||
| 357e48fb6b | |||
| 9ceeaf213b | |||
| 9297782868 | |||
| 0d1edc4771 | |||
| 1336c6c9fa | |||
| 8b03c0a385 | |||
| 15ee72138a | |||
| 92a0181932 | |||
| 035c63fd2a | |||
| 9e6efaf9bc | |||
| f4ee8a2505 | |||
| 842d52352a | |||
| e31799a3b1 | |||
| 1860801e36 | |||
| ae4fa22180 | |||
| b5121a346d | |||
| b6289d646f | |||
| c065a2c5b9 | |||
| 6e40573c13 | |||
| eb0890284a | |||
| 16c1b9a5c2 | |||
| 83accedded | |||
| 8e6a301026 | |||
| 4013629e5d | |||
| 6e14a47316 | |||
| 304afd75ac | |||
| 9c3d57e63e | |||
| 44978ce978 | |||
| 10d6c330a5 | |||
| e95cf420a2 | |||
| 3ecd7e850c | |||
| fee5873310 | |||
| 96b09c587d | |||
| 79853ad44f | |||
| 9a049442ff | |||
| e21f25f5b9 | |||
| 1f9fd25ff8 | |||
| 968576d4f2 | |||
| d8fbe8a289 | |||
| 6d7ce0237a | |||
| 2d042f078e | |||
| 3d8219d8f9 | |||
| 7f3bffe821 | |||
| 99255631dd | |||
| ba35c1ed9d | |||
| 437e768e4a | |||
| c58a4be6ee | |||
| 6374ef4866 | |||
| eeac7f9b02 | |||
| 8c49d1e1af | |||
| 382c7c21ad | |||
| 59fe967ebb | |||
| 6d8c7232d8 | |||
| 6b126171da | |||
| 56523784e1 | |||
| 1c6d20924b | |||
| ebaf750a9b | |||
| 217ba09408 | |||
| 24617b5e25 | |||
| d9ec923357 | |||
| a9de13c5d9 | |||
| 2c856c71f6 | |||
| 576c10ee3a | |||
| 44f581c3b5 | |||
| b971449f12 | |||
| 9db9cbd814 | |||
| 5b4aefbacd | |||
| 8f9c18edf2 | |||
| 4b0860e7de | |||
| eece6e69cb | |||
| d40a091eda | |||
| c9c59f00ad | |||
| 47a67c7320 | |||
| c579313821 | |||
| 06f2237132 | |||
| 4f7f66fae8 | |||
| eaaab45c14 | |||
| 041e886b87 | |||
| 3908c9710c | |||
| 5680d4c3e9 | |||
| 8e6adb4b3c | |||
| 17be70339c | |||
| d6323a7b5e | |||
| 02a519a11e | |||
| 1de085ec23 | |||
| 217b6da5fd | |||
| d5b3e6af00 | |||
| 4839ba5ae4 | |||
| 2bca8d5121 | |||
| 583476380a | |||
| c0da9b43ce | |||
| 30d171e79e | |||
| d36c351fc7 | |||
| 10ed4a1c85 | |||
| 04a315eb52 | |||
| cf2f80bd09 | |||
| ebd5ee36d9 | |||
| 2bfb619d19 | |||
| 6af9aa3de8 | |||
| 3af055fabe | |||
| ed30bd64cd | |||
| 0b1620a45c | |||
| bf49c292f8 | |||
| 8098f7d9a8 | |||
| a31f59ea31 | |||
| f44bf00e0d | |||
| 7435ee464f | |||
| 268f0b30ec | |||
| 30388fa2bf | |||
| 942072cf9d | |||
| e207d0af56 | |||
| 89dda473cf | |||
| dfc29ea03c | |||
| 315fc9493e | |||
| 5539db37b6 | |||
| 71ee0d56fa | |||
| 9ae1371c6e | |||
| e83ae9e461 | |||
| 0de222d998 | |||
| b137ee3beb | |||
| 99b5c5712c | |||
| bad50b8dd1 | |||
| ba11165fb4 | |||
| 9b837860cd | |||
| a457105831 | |||
| e8ba7bce24 | |||
| 59c471aad5 | |||
| 80fc34fb0c | |||
| fa55ac5c8f | |||
| dc52ec904c | |||
| d3ee2a9c18 | |||
| 54dc2f56c6 | |||
| ae77b1300a | |||
| b20db3b736 | |||
| aaa84dc118 | |||
| d89bbba181 | |||
| 239b1c6f74 | |||
| b2c6e397fc | |||
| 621dff7307 | |||
| bdeb4a7e32 | |||
| fc2d5da112 | |||
| 28569d6209 | |||
| 22696e8388 | |||
| 6c499f510b | |||
| 0b492f43fe | |||
| 60175784f0 | |||
| 14c0ff1c82 | |||
| a7e3df4fec | |||
| 67b5162df9 | |||
| a2a692d081 | |||
| dae41ec183 | |||
| 0920511de2 | |||
| e97195b3a6 | |||
| a3931e6b73 | |||
| 7cc951ab1b | |||
| dae1ec2b7b | |||
| f933cae2d6 | |||
| 5a85b0fb52 | |||
| a189655f31 | |||
| 42f86e7c3b | |||
| 3d42be5394 | |||
| 46a85d3f9b | |||
| e2c1368e0e | |||
| 3d3034cd11 | |||
| b62607037a | |||
| 278d8a6fcd | |||
| 2ddbd032ee | |||
| 5e4ed4266d | |||
| 3feceb8279 | |||
| 6b775fb9a1 | |||
| 05bc0d4d17 | |||
| a150bf8fdc | |||
| bd383fb8c1 | |||
| 9741dba51f | |||
| ee1cf939c5 | |||
| 0125870f92 | |||
| 63777f830d | |||
| 6ac839dd76 | |||
| c31875cad0 | |||
| 7ab3b0d793 | |||
| ad448efa1d | |||
| c8bc6cecdc | |||
| 33b67f54ba | |||
| a83c5a8f3a | |||
| 1d452c98c1 | |||
| 09ab01084d | |||
| fc1237963a | |||
| ddaa409ee2 | |||
| b244bce49c | |||
| 6cb1905f7c | |||
| db04cdf2ca | |||
| 58c8fc5770 | |||
| 35ec0d58a4 | |||
| 11afa45646 | |||
| 89f63a4fdf | |||
| 85f4f90b45 | |||
| 8117092e6a | |||
| 89b1700279 | |||
| 9cd048c442 | |||
| 3dccc20d8b | |||
| a61b0c303d | |||
| 0183b2487e | |||
| f448ff608a | |||
| fd3e3a99c5 | |||
| 776fe8b32a | |||
| 04b3efd14c | |||
| 64d96778b4 | |||
| 3e1425b905 | |||
| 65e6dfb9dd | |||
| c7931b4a4f | |||
| 0ad0fd2187 | |||
| 15245e9ec4 | |||
| c7b67ff00b | |||
| 00f502f6e9 | |||
| 0d750ff169 | |||
| 6d8263df15 | |||
| 006e96612c | |||
| 14815b9a45 | |||
| bbd428a0e1 | |||
| e1539a11be | |||
| 3f5a20c90a | |||
| efda70e73a | |||
| c01e3f24a5 | |||
| da45a064a8 | |||
| 98bad73d56 | |||
| fb8a511365 | |||
| 94c620cc27 | |||
| fc013442bb | |||
| 5deb6a91f7 | |||
| b73678992b | |||
| 91d205715e | |||
| 1d2dc6cdc1 | |||
| 4cdb30d59e | |||
| 48deb47021 | |||
| 0df6d7ae39 | |||
| a18a3dfbb1 | |||
| babb484cfc | |||
| f3cb5e0d77 | |||
| c42e026f9c | |||
| 1f4916041e | |||
| 8cf0d31ee9 | |||
| cfe0aea219 | |||
| 88c9991f90 | |||
| d88d5d6807 | |||
| 2d22507636 | |||
| d039b9b72b | |||
| 48909bdbee | |||
| 99fdba0745 | |||
| bb5a8a42c3 | |||
| 6957e892dd | |||
| c8986ffa5e | |||
| c6798fc515 | |||
| 5ffdfdd95d | |||
| 08b0530164 | |||
| b5cc4a3a7d | |||
| bae333788b | |||
| 5fd1aa0d04 | |||
| 11ad96fced | |||
| 0e330da2a6 | |||
| 5bb70e844d | |||
| 6efdf78ce3 | |||
| 3b69d26368 | |||
| 51b9dd029b | |||
| 2b00c13ad8 | |||
| a8683d5bcf | |||
| 6052f7bfa8 | |||
| 7d1c75d0e8 | |||
| aaa718741e | |||
| e3005f68e7 | |||
| 8ee5f9fb6f | |||
| 3bdd5d0d25 | |||
| 1a32f20c07 | |||
| 6357ea1d5d | |||
| 86a8606fd1 | |||
| c4943cffe8 | |||
| 10c920ef13 | |||
| 469e93f37b | |||
| e09afe367f | |||
| 4c47ee63f2 | |||
| be4d687a86 | |||
| 07baf2d973 | |||
| 325c17f277 | |||
| 14609dbfa2 | |||
| 59ba09826b | |||
| 90fd7f3780 | |||
| c2f6bf0343 | |||
| 67f93b0d60 | |||
| 7a69dab596 | |||
| 5ce0b062ff | |||
| 3e57850da7 | |||
| 95a9100623 | |||
| d0df7be722 | |||
| 5ac10d6555 | |||
| 29db302808 | |||
| b9f751e099 | |||
| 0a846d03bf | |||
| 5c329a7699 | |||
| daad71bc7e | |||
| ba916c3162 | |||
| f9e12d900c | |||
| c3888cb0ca | |||
| e412438aba | |||
| 086fbc6a50 | |||
| ff22782752 | |||
| e5ae35c66b | |||
| 3397a9be5e | |||
| f1ecbf80fb | |||
| 9eeee67da7 | |||
| 9cc5a5d467 | |||
| 44f5e411c5 | |||
| fee2530b1c | |||
| 87fb5132be | |||
| 95265dd3ad | |||
| 7eddfe073b | |||
| 16881597c9 | |||
| f3ff660eae | |||
| 4480749a52 | |||
| b4ae1b63bc | |||
| 67a70b9107 | |||
| 0e29307ad5 | |||
| 2659e2c4a0 | |||
| 49a8de7c56 | |||
| 2f9f4e6938 | |||
| 43626f5c97 | |||
| 53d72bd85a | |||
| f6d8f47451 | |||
| aa5caa30e2 | |||
| 3ee5195b7a | |||
| 55a92c2983 | |||
| 415a75c25a | |||
| 20709f9880 | |||
| 113c315857 | |||
| 842db2ca15 | |||
| 9c80cb2b26 | |||
| 58c1bc4276 | |||
| de7422b372 | |||
| d252b9948c | |||
| 341be9b682 | |||
| fec7e47169 | |||
| 46bf190fd0 | |||
| e54e543a66 | |||
| ff46738218 | |||
| 4566325241 | |||
| 1b368a86b7 | |||
| 9d2f1d5f0d | |||
| eeb705fc2f | |||
| 8bff06bea9 | |||
| 99f506135b | |||
| 2814dd2cb8 | |||
| bee767158d | |||
| 915383e150 | |||
| 43e7814714 | |||
| 32fe74c923 | |||
| f112a91321 | |||
| 1d5a441ce8 | |||
| a497cdff5e | |||
| 47b17acbaf | |||
| 788049be7b | |||
| 62ea763089 | |||
| 3e7ee6af6d | |||
| b5a09f8b15 | |||
| 5dfd95e5a7 | |||
| 6f2e178de1 | |||
| 137a4ee087 | |||
| b2eb9f197a | |||
| 2a115a83d2 | |||
| 1472bd398a | |||
| c6f48022a4 | |||
| d048d1e619 | |||
| efdf5636be | |||
| 81a7ca7b1e | |||
| 92b9fb30e0 | |||
| c62bd0c911 | |||
| 8a2fa62cac | |||
| 2d22d6061e | |||
| 7c1e7e5b5f | |||
| 1f2b7e8f20 | |||
| 06701b126b | |||
| ff4a00b1f3 | |||
| 97a93263c1 | |||
| 28e28e926a | |||
| 5e467b96a1 | |||
| 53bd0ee818 | |||
| 70606667c6 | |||
| 7d99484859 | |||
| 35c33a8a29 | |||
| 98c172aed6 | |||
| 25f95d6954 | |||
| 4fce1a17d7 | |||
| 1578f17eff | |||
| 87273619a6 | |||
| b5ac0db895 | |||
| 6d25db6600 | |||
| 880114a909 | |||
| 653105a44f | |||
| f938c2a5e2 | |||
| 6a23cad454 | |||
| 6aeb9dcb38 | |||
| 83dd79a6a7 | |||
| 6378c673df | |||
| c7750689e8 | |||
| 41d65f8fe2 | |||
| 24fa95fd60 | |||
| 67d3b50598 | |||
| 3e49bf0e83 | |||
| 917d48f30b | |||
| d9814709e2 |
@@ -0,0 +1,3 @@
|
||||
.git
|
||||
.win32
|
||||
.examples
|
||||
@@ -0,0 +1,15 @@
|
||||
> What version of ejabberd are you using?
|
||||
|
||||
|
||||
|
||||
> What operating system (version) are you using?
|
||||
|
||||
|
||||
|
||||
> How did you install ejabberd (source, package, distribution)?
|
||||
|
||||
|
||||
|
||||
> What did not work as expected? Are there error messages in the log? What
|
||||
> was the unexpected behavior? What was the expected result?
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
We are open to contributions for ejabberd, as GitHub pull requests (PR).
|
||||
Here are a few points to consider before submitting your PR. (You can
|
||||
remove the whole text after reading.)
|
||||
|
||||
1. Does this PR address an issue? Please reference it in the PR
|
||||
description.
|
||||
|
||||
2. Have you properly described the proposed change?
|
||||
|
||||
3. Please make sure the change is atomic and does only touch the needed
|
||||
modules. If you have other changes/fixes to provide, please submit
|
||||
them as separate PRs.
|
||||
|
||||
4. If your change or new feature involves storage backends, did you make
|
||||
sure your change works with all backends?
|
||||
|
||||
5. Do you provide tests? How can we check the behavior of the code?
|
||||
|
||||
6. Did you consider documentation changes in the
|
||||
processone/docs.ejabberd.im repository?
|
||||
@@ -29,6 +29,7 @@
|
||||
/doc/version.tex
|
||||
/ebin/
|
||||
/ejabberd.init
|
||||
/ejabberd.service
|
||||
/ejabberdctl.example
|
||||
XmppAddr.hrl
|
||||
/rel/ejabberd/
|
||||
@@ -39,8 +40,10 @@ XmppAddr.hrl
|
||||
/vars.config
|
||||
/dialyzer/
|
||||
/test/*.beam
|
||||
/test/*.ctc
|
||||
/logs/
|
||||
/priv/sql
|
||||
/rel/ejabberd
|
||||
/_build
|
||||
/mnesiadb
|
||||
/.rebar
|
||||
|
||||
+27
-4
@@ -1,11 +1,13 @@
|
||||
language: erlang
|
||||
|
||||
otp_release:
|
||||
- 17.1
|
||||
- 17.5
|
||||
- 18.3
|
||||
- 19.1
|
||||
|
||||
services:
|
||||
- riak
|
||||
- redis-server
|
||||
|
||||
before_install:
|
||||
#
|
||||
@@ -16,15 +18,26 @@ before_install:
|
||||
# See: https://github.com/travis-ci/travis-ci/issues/1986
|
||||
#
|
||||
- sudo sed -i -e s/table_cache/table_open_cache/ -e /log_slow_queries/d /etc/mysql/my.cnf
|
||||
- sudo apt-key adv --keyserver pgp.mit.edu --recv-keys 5072E1F5
|
||||
- sudo apt-key adv --import .travis/mysql_repo_key.asc
|
||||
- sudo add-apt-repository 'deb http://repo.mysql.com/apt/ubuntu/ precise mysql-5.6'
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get -qq -o Dpkg::Options::=--force-confold install mysql-server-5.6
|
||||
# /END MYSQL 5.6
|
||||
- pip install --user coveralls-merge
|
||||
|
||||
install:
|
||||
- sudo apt-get -qq install libexpat1-dev libyaml-dev libpam0g-dev libsqlite3-dev
|
||||
|
||||
before_script:
|
||||
# Ulimit: See Travis-CI issue report: https://github.com/travis-ci/travis-ci/issues/3328
|
||||
- echo 'ulimit -n 4096' > riak
|
||||
- sudo mv riak /etc/default/riak
|
||||
- mkdir "$PWD/ebin"
|
||||
- echo "[{riak_kv, [{add_paths, [\"$PWD/ebin/\"]}]}]." > advanced.config
|
||||
- sudo mv advanced.config /etc/riak/advanced.config
|
||||
- sudo service riak restart
|
||||
- sudo riak-admin wait-for-service riak_kv 'riak@127.0.0.1'
|
||||
- sudo riak-admin test
|
||||
- mysql -u root -e "CREATE USER 'ejabberd_test'@'localhost' IDENTIFIED BY 'ejabberd_test';"
|
||||
- mysql -u root -e "CREATE DATABASE ejabberd_test;"
|
||||
- mysql -u root -e "GRANT ALL ON ejabberd_test.* TO 'ejabberd_test'@'localhost';"
|
||||
@@ -34,16 +47,26 @@ before_script:
|
||||
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure --enable-all --disable-odbc --disable-elixir
|
||||
- ./configure --prefix=/tmp/ejabberd --enable-all --disable-odbc
|
||||
- make
|
||||
- make install
|
||||
- make xref
|
||||
- ERL_LIBS=$PWD make test
|
||||
- sed -i -e 's/ct:pal/ct:log/' test/suite.erl
|
||||
- ln -sf ../sql priv/
|
||||
- escript ./rebar skip_deps=true ct -v
|
||||
- grep -q 'TEST COMPLETE, \([[:digit:]]*\) ok, .* of \1 ' logs/raw.log
|
||||
|
||||
after_script:
|
||||
- find logs -name suite.log -exec cat '{}' ';'
|
||||
|
||||
after_failure:
|
||||
- find logs -name exunit.log -exec cat '{}' ';'
|
||||
# Try checking Riak database logs
|
||||
- tail -n 100000 /var/log/riak/*.log
|
||||
- find logs -name ejabberd.log -exec cat '{}' ';'
|
||||
|
||||
after_success:
|
||||
- coveralls-merge erlang.json
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.9 (SunOS)
|
||||
|
||||
mQGiBD4+owwRBAC14GIfUfCyEDSIePvEW3SAFUdJBtoQHH/nJKZyQT7h9bPlUWC3
|
||||
RODjQReyCITRrdwyrKUGku2FmeVGwn2u2WmDMNABLnpprWPkBdCk96+OmSLN9brZ
|
||||
fw2vOUgCmYv2hW0hyDHuvYlQA/BThQoADgj8AW6/0Lo7V1W9/8VuHP0gQwCgvzV3
|
||||
BqOxRznNCRCRxAuAuVztHRcEAJooQK1+iSiunZMYD1WufeXfshc57S/+yeJkegNW
|
||||
hxwR9pRWVArNYJdDRT+rf2RUe3vpquKNQU/hnEIUHJRQqYHo8gTxvxXNQc7fJYLV
|
||||
K2HtkrPbP72vwsEKMYhhr0eKCbtLGfls9krjJ6sBgACyP/Vb7hiPwxh6rDZ7ITnE
|
||||
kYpXBACmWpP8NJTkamEnPCia2ZoOHODANwpUkP43I7jsDmgtobZX9qnrAXw+uNDI
|
||||
QJEXM6FSbi0LLtZciNlYsafwAPEOMDKpMqAK6IyisNtPvaLd8lH0bPAnWqcyefep
|
||||
rv0sxxqUEMcM3o7wwgfN83POkDasDbs3pjwPhxvhz6//62zQJ7Q2TXlTUUwgUmVs
|
||||
ZWFzZSBFbmdpbmVlcmluZyA8bXlzcWwtYnVpbGRAb3NzLm9yYWNsZS5jb20+iGkE
|
||||
ExECACkCGyMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAIZAQUCUwHUZgUJGmbLywAK
|
||||
CRCMcY07UHLh9V+DAKCjS1gGwgVI/eut+5L+l2v3ybl+ZgCcD7ZoA341HtoroV3U
|
||||
6xRD09fUgeq0O015U1FMIFBhY2thZ2Ugc2lnbmluZyBrZXkgKHd3dy5teXNxbC5j
|
||||
b20pIDxidWlsZEBteXNxbC5jb20+iG8EMBECAC8FAk53Pa0oHSBidWlsZEBteXNx
|
||||
bC5jb20gd2lsbCBzdG9wIHdvcmtpbmcgc29vbgAKCRCMcY07UHLh9bU9AJ9xDK0o
|
||||
xJFL9vTl9OSZC4lX0K9AzwCcCrS9cnJyz79eaRjL0s2r/CcljdyIZQQTEQIAHQUC
|
||||
R6yUtAUJDTBYqAULBwoDBAMVAwIDFgIBAheAABIJEIxxjTtQcuH1B2VHUEcAAQGu
|
||||
kgCffz4GUEjzXkOi71VcwgCxASTgbe0An34LPr1j9fCbrXWXO14msIADfb5piEwE
|
||||
ExECAAwFAj4+o9EFgwlmALsACgkQSVDhKrJykfIk4QCfWbEeKN+3TRspe+5xKj+k
|
||||
QJSammIAnjUz0xFWPlVx0f8o38qNG1bq0cU9iEwEExECAAwFAj5CggMFgwliIokA
|
||||
CgkQtvXNTca6JD+WkQCgiGmnoGjMojynp5ppvMXkyUkfnykAoK79E6h8rwkSDZou
|
||||
iz7nMRisH8uyiEYEEBECAAYFAj+s468ACgkQr8UjSHiDdA/2lgCg21IhIMMABTYd
|
||||
p/IBiUsP/JQLiEoAnRzMywEtujQz/E9ono7H1DkebDa4iEYEEBECAAYFAj+0Q3cA
|
||||
CgkQhZavqzBzTmbGwwCdFqD1frViC7WRt8GKoOS7hzNN32kAnirlbwpnT7a6NOsQ
|
||||
83nk11a2dePhiEYEEBECAAYFAkNbs+oACgkQi9gubzC5S1x/dACdELKoXQKkwJN0
|
||||
gZztsM7kjsIgyFMAnRRMbHQ7V39XC90OIpaPjk3a01tgiEYEExECAAYFAkTxMyYA
|
||||
CgkQ9knE9GCTUwwKcQCgibak/SwhxWH1ijRhgYCo5GtM4vcAnAhtzL57wcw1Kg1X
|
||||
m7nVGetUqJ7fiEwEEBECAAwFAkGBywEFgwYi2YsACgkQGFnQH2d7oexCjQCcD8sJ
|
||||
NDc/mS8m8OGDUOx9VMWcnGkAnj1YWOD+Qhxo3mI/Ul9oEAhNkjcfiEwEEBECAAwF
|
||||
AkGByzQFgwYi2VgACgkQgcL36+ITtpIiIwCdFVNVUB8xe8mFXoPm4d9Z54PTjpMA
|
||||
niSPA/ZsfJ3oOMLKar4F0QPPrdrGiEwEEBECAAwFAkGBy2IFgwYi2SoACgkQa3Ds
|
||||
2V3D9HMJqgCbBYzr5GPXOXgP88jKzmdbjweqXeEAnRss4G2G/3qD7uhTL1SPT1SH
|
||||
jWUXiEwEEBECAAwFAkHQkyQFgwXUEWgACgkQfSXKCsEpp8JiVQCghvWvkPqowsw8
|
||||
w7WSseTcw1tflvkAni+vLHl/DqIly0LkZYn5jzK1dpvfiEwEEBECAAwFAkIrW7oF
|
||||
gwV5SNIACgkQ5hukiRXruavzEwCgkzL5QkLSypcw9LGHcFSx1ya0VL4An35nXkum
|
||||
g6cCJ1NP8r2I4NcZWIrqiEwEEhECAAwFAkAqWToFgwd6S1IACgkQPKEfNJT6+GEm
|
||||
XACcD+A53A5OGM7w750W11ukq4iZ9ckAnRMvndAqn3YTOxxlLPj2UPZiSgSqiEwE
|
||||
EhECAAwFAkA9+roFgwdmqdIACgkQ8tdcY+OcZZyy3wCgtDcwlaq20w0cNuXFLLNe
|
||||
EUaFFTwAni6RHN80moSVAdDTRkzZacJU3M5QiEwEEhECAAwFAkEOCoQFgwaWmggA
|
||||
CgkQOcor9D1qil/83QCeITZ9wIo7XAMjC6y4ZWUL4m+edZsAoMOhRIRi42fmrNFu
|
||||
vNZbnMGej81viEwEEhECAAwFAkKApTQFgwUj/1gACgkQBA3AhXyDn6jjJACcD1A4
|
||||
UtXk84J13JQyoH9+dy24714Aniwlsso/9ndICJOkqs2j5dlHFq6oiEwEExECAAwF
|
||||
Aj5NTYQFgwlXVwgACgkQLbt2v63UyTMFDACglT5G5NVKf5Mj65bFSlPzb92zk2QA
|
||||
n1uc2h19/IwwrsbIyK/9POJ+JMP7iEwEExECAAwFAkHXgHYFgwXNJBYACgkQZu/b
|
||||
yM2C/T4/vACfXe67xiSHB80wkmFZ2krb+oz/gBAAnjR2ucpbaonkQQgnC3GnBqmC
|
||||
vNaJiEwEExECAAwFAkIYgQ4FgwWMI34ACgkQdsEDHKIxbqGg7gCfQi2HcrHn+yLF
|
||||
uNlH1oSOh48ZM0oAn3hKV0uIRJphonHaUYiUP1ttWgdBiGUEExECAB0FCwcKAwQD
|
||||
FQMCAxYCAQIXgAUCS3AvygUJEPPzpwASB2VHUEcAAQEJEIxxjTtQcuH1sNsAniYp
|
||||
YBGqy/HhMnw3WE8kXahOOR5KAJ4xUmWPGYP4l3hKxyNK9OAUbpDVYIh7BDARAgA7
|
||||
BQJCdzX1NB0AT29wcy4uLiBzaG91bGQgaGF2ZSBiZWVuIGxvY2FsISBJJ20gKnNv
|
||||
KiBzdHVwaWQuLi4ACgkQOcor9D1qil/vRwCdFo08f66oKLiuEAqzlf9iDlPozEEA
|
||||
n2EgvCYLCCHjfGosrkrU3WK5NFVgiI8EMBECAE8FAkVvAL9IHQBTaG91bGQgaGF2
|
||||
ZSBiZWVuIGEgbG9jYWwgc2lnbmF0dXJlLCBvciBzb21ldGhpbmcgLSBXVEYgd2Fz
|
||||
IEkgdGhpbmtpbmc/AAoJEDnKK/Q9aopfoPsAn3BVqKOalJeF0xPSvLR90PsRlnmG
|
||||
AJ44oisY7Tl3NJbPgZal8W32fbqgbIkCIgQQAQIADAUCQYHLhQWDBiLZBwAKCRCq
|
||||
4+bOZqFEaKgvEACCErnaHGyUYa0wETjj6DLEXsqeOiXad4i9aBQxnD35GUgcFofC
|
||||
/nCY4XcnCMMEnmdQ9ofUuU3OBJ6BNJIbEusAabgLooebP/3KEaiCIiyhHYU5jarp
|
||||
ZAh+Zopgs3Oc11mQ1tIaS69iJxrGTLodkAsAJAeEUwTPq9fHFFzC1eGBysoyFWg4
|
||||
bIjz/zClI+qyTbFA5g6tRoiXTo8ko7QhY2AA5UGEg+83Hdb6akC04Z2QRErxKAqr
|
||||
phHzj8XpjVOsQAdAi/qVKQeNKROlJ+iq6+YesmcWGfzeb87dGNweVFDJIGA0qY27
|
||||
pTb2lExYjsRFN4Cb13NfodAbMTOxcAWZ7jAPCxAPlHUG++mHMrhQXEToZnBFE4nb
|
||||
nC7vOBNgWdjUgXcpkUCkop4b17BFpR+k8ZtYLSS8p2LLz4uAeCcSm2/msJxT7rC/
|
||||
FvoH8428oHincqs2ICo9zO/Ud4HmmO0O+SsZdVKIIjinGyOVWb4OOzkAlnnhEZ3o
|
||||
6hAHcREIsBgPwEYVTj/9ZdC0AO44Nj9cU7awaqgtrnwwfr/o4V2gl8bLSkltZU27
|
||||
/29HeuOeFGjlFe0YrDd/aRNsxbyb2O28H4sG1CVZmC5uK1iQBDiSyA7Q0bbdofCW
|
||||
oQzm5twlpKWnY8Oe0ub9XP5p/sVfck4FceWFHwv+/PC9RzSl33lQ6vM2wIkCIgQT
|
||||
AQIADAUCQp8KHAWDBQWacAAKCRDYwgoJWiRXzyE+D/9uc7z6fIsalfOYoLN60ajA
|
||||
bQbI/uRKBFugyZ5RoaItusn9Z2rAtn61WrFhu4uCSJtFN1ny2RERg40f56pTghKr
|
||||
D+YEt+Nze6+FKQ5AbGIdFsR/2bUk+ZZRSt83e14Lcb6ii/fJfzkoIox9ltkifQxq
|
||||
Y7Tvk4noKu4oLSc8O1Wsfc/y0B9sYUUCmUfcnq58DEmGie9ovUslmyt5NPnveXxp
|
||||
5UeaRc5Rqt9tK2B4A+7/cqENrdZJbAMSunt2+2fkYiRunAFPKPBdJBsY1sxeL/A9
|
||||
aKe0viKEXQdAWqdNZKNCi8rd/oOP99/9lMbFudAbX6nL2DSb1OG2Z7NWEqgIAzjm
|
||||
pwYYPCKeVz5Q8R+if9/fe5+STY/55OaI33fJ2H3v+U435VjYqbrerWe36xJItcJe
|
||||
qUzW71fQtXi1CTEl3w2ch7VF5oj/QyjabLnAlHgSlkSi6p7By5C2MnbCHlCfPnIi
|
||||
nPhFoRcRGPjJe9nFwGs+QblvS/Chzc2WX3s/2SWm4gEUKRX4zsAJ5ocyfa/vkxCk
|
||||
SxK/erWlCPf/J1T70+i5waXDN/E3enSet/WL7h94pQKpjz8OdGL4JSBHuAVGA+a+
|
||||
dknqnPF0KMKLhjrgV+L7O84FhbmAP7PXm3xmiMPriXf+el5fZZequQoIagf8rdRH
|
||||
HhRJxQgI0HNknkaOqs8dtrkCDQQ+PqMdEAgA7+GJfxbMdY4wslPnjH9rF4N2qfWs
|
||||
EN/lxaZoJYc3a6M02WCnHl6ahT2/tBK2w1QI4YFteR47gCvtgb6O1JHffOo2HfLm
|
||||
RDRiRjd1DTCHqeyX7CHhcghj/dNRlW2Z0l5QFEcmV9U0Vhp3aFfWC4Ujfs3LU+hk
|
||||
AWzE7zaD5cH9J7yv/6xuZVw411x0h4UqsTcWMu0iM1BzELqX1DY7LwoPEb/O9Rkb
|
||||
f4fmLe11EzIaCa4PqARXQZc4dhSinMt6K3X4BrRsKTfozBu74F47D8Ilbf5vSYHb
|
||||
uE5p/1oIDznkg/p8kW+3FxuWrycciqFTcNz215yyX39LXFnlLzKUb/F5GwADBQf+
|
||||
Lwqqa8CGrRfsOAJxim63CHfty5mUc5rUSnTslGYEIOCR1BeQauyPZbPDsDD9MZ1Z
|
||||
aSafanFvwFG6Llx9xkU7tzq+vKLoWkm4u5xf3vn55VjnSd1aQ9eQnUcXiL4cnBGo
|
||||
TbOWI39EcyzgslzBdC++MPjcQTcA7p6JUVsP6oAB3FQWg54tuUo0Ec8bsM8b3Ev4
|
||||
2LmuQT5NdKHGwHsXTPtl0klk4bQk4OajHsiy1BMahpT27jWjJlMiJc+IWJ0mghkK
|
||||
Ht926s/ymfdf5HkdQ1cyvsz5tryVI3Fx78XeSYfQvuuwqp2H139pXGEkg0n6KdUO
|
||||
etdZWhe70YGNPw1yjWJT1IhUBBgRAgAMBQJOdz3tBQkT+wG4ABIHZUdQRwABAQkQ
|
||||
jHGNO1By4fUUmwCbBYr2+bBEn/L2BOcnw9Z/QFWuhRMAoKVgCFm5fadQ3Afi+UQl
|
||||
AcOphrnJ
|
||||
=443I
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
FROM debian:jessie
|
||||
MAINTAINER Rafael Römhild <rafael@roemhild.de>
|
||||
|
||||
ENV XMPP_DOMAIN=localhost \
|
||||
EJABBERD_HOME=/opt/ejabberd \
|
||||
PATH=/opt/ejabberd/bin:/usr/sbin:/usr/bin:/sbin:/bin \
|
||||
LC_ALL=C.UTF-8 \
|
||||
LANG=en_US.UTF-8 \
|
||||
LANGUAGE=en_US.UTF-8
|
||||
|
||||
# bootstrap
|
||||
COPY . /tmp/ejabberd
|
||||
RUN /tmp/ejabberd/docker/bootstrap.sh
|
||||
|
||||
# Continue as user
|
||||
USER ejabberd
|
||||
|
||||
# Set workdir to ejabberd root
|
||||
WORKDIR /opt/ejabberd
|
||||
|
||||
VOLUME ["/opt/ejabberd/conf", "/opt/ejabberd/database", "/opt/ejabberd/ssl", "/opt/ejabberd/backup", "/opt/ejabberd/upload", "/opt/ejabberd/modules"]
|
||||
|
||||
EXPOSE 4560 5222 5269 5280 5443
|
||||
|
||||
ENTRYPOINT ["/opt/ejabberd/docker/start.sh"]
|
||||
+76
-54
@@ -17,6 +17,9 @@ BINDIR = $(DESTDIR)@bindir@
|
||||
# /sbin/
|
||||
SBINDIR = $(DESTDIR)@sbindir@
|
||||
|
||||
# /lib/
|
||||
LIBDIR = $(DESTDIR)@libdir@
|
||||
|
||||
# /lib/ejabberd/
|
||||
EJABBERDDIR = $(DESTDIR)@libdir@/ejabberd
|
||||
|
||||
@@ -105,27 +108,80 @@ edoc:
|
||||
$(ERL) -noinput +B -eval \
|
||||
'case edoc:application(ejabberd, ".", []) of ok -> halt(0); error -> halt(1) end.'
|
||||
|
||||
spec:
|
||||
$(ERL) -noinput +B -pa ebin -pa deps/*/ebin -eval \
|
||||
'case xml_gen:compile("tools/xmpp_codec.spec") of ok -> halt(0); _ -> halt(1) end.'
|
||||
JOIN_PATHS=$(if $(wordlist 2,1000,$(1)),$(firstword $(1))/$(call JOIN_PATHS,$(wordlist 2,1000,$(1))),$(1))
|
||||
|
||||
DLLs := $(wildcard deps/*/priv/*.so) $(wildcard deps/*/priv/lib/*.so)
|
||||
VERSIONED_DEP=$(if $(DEP_$(1)_VERSION),$(DEP_$(1)_VERSION),$(1))
|
||||
|
||||
install: all
|
||||
ELIXIR_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,$(word 2,$(1))) $(wordlist 5,1000,$(1))
|
||||
DEPS_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,$(word 2,$(1))) $(wordlist 3,1000,$(1))
|
||||
MAIN_TO_DEST=$(LIBDIR) $(call VERSIONED_DEP,ejabberd) $(1)
|
||||
TO_DEST_SINGLE=$(if $(subst XdepsX,,X$(word 1,$(1))X),$(call MAIN_TO_DEST,$(1)),$(if $(subst XlibX,,X$(word 3,$(1))X),$(call DEPS_TO_DEST,$(1)),$(call ELIXIR_TO_DEST,$(1))))
|
||||
TO_DEST=$(foreach path,$(1),$(call JOIN_PATHS,$(call TO_DEST_SINGLE,$(subst /, ,$(path)))))
|
||||
|
||||
FILTER_DIRS=$(foreach path,$(1),$(if $(wildcard $(path)/*),,$(path)))
|
||||
FILES_WILDCARD=$(call FILTER_DIRS,$(foreach w,$(1),$(wildcard $(w))))
|
||||
|
||||
ifeq ($(MAKECMDGOALS),copy-files-sub)
|
||||
|
||||
DEPS:=$(sort $(shell $(REBAR) list-deps|$(SED) -e '/^=/d;s/ .*//'))
|
||||
|
||||
DEPS_FILES=$(call FILES_WILDCARD,$(foreach DEP,$(DEPS),deps/$(DEP)/ebin/*.beam deps/$(DEP)/ebin/*.app deps/$(DEP)/priv/* deps/$(DEP)/priv/lib/* deps/$(DEP)/priv/bin/* deps/$(DEP)/include/*.hrl deps/$(DEP)/lib/*/ebin/*.beam deps/$(DEP)/lib/*/ebin/*.app))
|
||||
DEPS_FILES_FILTERED=$(filter-out %/epam deps/elixir/ebin/elixir.app,$(DEPS_FILES))
|
||||
DEPS_DIRS=$(sort deps/ $(foreach DEP,$(DEPS),deps/$(DEP)/) $(dir $(DEPS_FILES)))
|
||||
|
||||
MAIN_FILES=$(filter-out %/configure.beam,$(call FILES_WILDCARD,ebin/*.beam ebin/*.app priv/msgs/*.msg priv/lib/* include/*.hrl))
|
||||
MAIN_DIRS=$(sort $(dir $(MAIN_FILES)) priv/bin priv/sql)
|
||||
|
||||
define DEP_VERSION_template
|
||||
DEP_$(1)_VERSION:=$(shell $(SED) -e '/vsn/!d;s/.*, *"/$(1)-/;s/".*//' $(2) 2>/dev/null)
|
||||
endef
|
||||
|
||||
$(foreach DEP,$(DEPS),$(eval $(call DEP_VERSION_template,$(DEP),deps/$(DEP)/ebin/$(DEP).app)))
|
||||
$(eval $(call DEP_VERSION_template,ejabberd,ebin/ejabberd.app))
|
||||
|
||||
define COPY_template
|
||||
$(call TO_DEST,$(1)): $(1) $(call TO_DEST,$(dir $(1))) ; $$(INSTALL) -m 644 $(1) $(call TO_DEST,$(1))
|
||||
endef
|
||||
|
||||
$(foreach file,$(DEPS_FILES_FILTERED) $(MAIN_FILES),$(eval $(call COPY_template,$(file))))
|
||||
|
||||
$(sort $(call TO_DEST,$(MAIN_DIRS) $(DEPS_DIRS))):
|
||||
$(INSTALL) -d $@
|
||||
|
||||
$(call TO_DEST,deps/p1_pam/priv/bin/epam): $(LIBDIR)/%: deps/p1_pam/priv/bin/epam $(call TO_DEST,deps/p1_pam/priv/bin/)
|
||||
$(INSTALL) -m 750 $(O_USER) $< $@
|
||||
|
||||
$(call TO_DEST,priv/sql/lite.sql): sql/lite.sql $(call TO_DEST,priv/sql)
|
||||
$(INSTALL) -m 644 $< $@
|
||||
|
||||
$(call TO_DEST,priv/bin/captcha.sh): tools/captcha.sh $(call TO_DEST,priv/bin)
|
||||
$(INSTALL) -m 750 $(O_USER) $< $@
|
||||
|
||||
copy-files-sub2: $(call TO_DEST,$(DEPS_FILES) $(MAIN_FILES) priv/bin/captcha.sh priv/sql/lite.sql)
|
||||
|
||||
endif
|
||||
|
||||
copy-files:
|
||||
$(MAKE) copy-files-sub
|
||||
|
||||
copy-files-sub: copy-files-sub2
|
||||
|
||||
install: all copy-files
|
||||
#
|
||||
# Configuration files
|
||||
$(INSTALL) -d -m 750 $(G_USER) $(ETCDIR)
|
||||
[ -f $(ETCDIR)/ejabberd.yml ] \
|
||||
&& $(INSTALL) -b -m 640 $(G_USER) ejabberd.yml.example $(ETCDIR)/ejabberd.yml-new \
|
||||
|| $(INSTALL) -b -m 640 $(G_USER) ejabberd.yml.example $(ETCDIR)/ejabberd.yml
|
||||
$(SED) -e "s*{{rootdir}}*@prefix@*" \
|
||||
-e "s*{{installuser}}*@INSTALLUSER@*" \
|
||||
-e "s*{{bindir}}*@bindir@*" \
|
||||
-e "s*{{libdir}}*@libdir@*" \
|
||||
-e "s*{{sysconfdir}}*@sysconfdir@*" \
|
||||
-e "s*{{localstatedir}}*@localstatedir@*" \
|
||||
-e "s*{{docdir}}*@docdir@*" \
|
||||
-e "s*{{erl}}*@ERL@*" ejabberdctl.template \
|
||||
$(SED) -e "s*{{rootdir}}*@prefix@*g" \
|
||||
-e "s*{{installuser}}*@INSTALLUSER@*g" \
|
||||
-e "s*{{bindir}}*@bindir@*g" \
|
||||
-e "s*{{libdir}}*@libdir@*g" \
|
||||
-e "s*{{sysconfdir}}*@sysconfdir@*g" \
|
||||
-e "s*{{localstatedir}}*@localstatedir@*g" \
|
||||
-e "s*{{docdir}}*@docdir@*g" \
|
||||
-e "s*{{erl}}*@ERL@*g" \
|
||||
-e "s*{{epmd}}*@EPMD@*g" ejabberdctl.template \
|
||||
> ejabberdctl.example
|
||||
[ -f $(ETCDIR)/ejabberdctl.cfg ] \
|
||||
&& $(INSTALL) -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg-new \
|
||||
@@ -142,49 +198,15 @@ install: all
|
||||
[ -f deps/elixir/bin/mix ] && $(INSTALL) -m 550 $(G_USER) deps/elixir/bin/mix $(BINDIR)/mix || true
|
||||
#
|
||||
# Init script
|
||||
$(SED) -e "s*@ctlscriptpath@*$(SBINDIR)*" \
|
||||
-e "s*@installuser@*$(INIT_USER)*" ejabberd.init.template \
|
||||
$(SED) -e "s*@ctlscriptpath@*$(SBINDIR)*g" \
|
||||
-e "s*@installuser@*$(INIT_USER)*g" 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)
|
||||
# Install Elixir and Elixir dependancies
|
||||
-$(INSTALL) -m 644 deps/*/lib/*/ebin/*.app $(BEAMDIR)
|
||||
-$(INSTALL) -m 644 deps/*/lib/*/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)
|
||||
$(INSTALL) -m 750 $(O_USER) tools/joincluster $(PBINDIR)
|
||||
$(INSTALL) -m 750 $(O_USER) tools/leavecluster $(PBINDIR)
|
||||
[ -f deps/p1_pam/priv/bin/epam ] \
|
||||
&& $(INSTALL) -m 750 $(O_USER) deps/p1_pam/priv/bin/epam $(PBINDIR) \
|
||||
|| true
|
||||
#
|
||||
# Binary system libraries
|
||||
$(INSTALL) -d $(SODIR)
|
||||
$(INSTALL) -m 644 $(DLLs) $(SODIR)
|
||||
[ -f $(SODIR)/jiffy.so ] && (cd $(PRIVDIR); ln -s lib/jiffy.so; true) || true
|
||||
[ -f $(SODIR)/sqlite3_drv.so ] && (cd $(PRIVDIR); ln -s lib/sqlite3_drv.so; true) || true
|
||||
#
|
||||
# Translated strings
|
||||
$(INSTALL) -d $(MSGSDIR)
|
||||
$(INSTALL) -m 644 priv/msgs/*.msg $(MSGSDIR)
|
||||
#
|
||||
# Copy lite.sql
|
||||
[ -d deps/sqlite3 ] && $(INSTALL) -d $(SQLDIR) || true
|
||||
[ -d deps/sqlite3 ] && $(INSTALL) -m 644 sql/lite.sql $(SQLDIR) || true
|
||||
# Service script
|
||||
$(SED) -e "s*@ctlscriptpath@*$(SBINDIR)*g" ejabberd.service.template \
|
||||
> ejabberd.service
|
||||
chmod 644 ejabberd.service
|
||||
#
|
||||
# Spool directory
|
||||
$(INSTALL) -d -m 750 $(O_USER) $(SPOOLDIR)
|
||||
@@ -317,5 +339,5 @@ quicktest:
|
||||
$(REBAR) skip_deps=true ct suites=elixir
|
||||
|
||||
.PHONY: src edoc dialyzer Makefile TAGS clean clean-rel distclean rel \
|
||||
install uninstall uninstall-binary uninstall-all translations deps test spec \
|
||||
install uninstall uninstall-binary uninstall-all translations deps test \
|
||||
quicktest erlang_plt deps_plt ejabberd_plt
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
ejabberd Community Edition [](https://travis-ci.org/processone/ejabberd)
|
||||
=========================================
|
||||
ejabberd Community Edition
|
||||
==========================
|
||||
|
||||
[](https://travis-ci.org/processone/ejabberd) [](https://hex.pm/packages/ejabberd)
|
||||
|
||||
ejabberd is a distributed, fault-tolerant technology that allows the creation
|
||||
of large-scale instant messaging applications. The server can reliably support
|
||||
@@ -107,7 +109,7 @@ To compile ejabberd you need:
|
||||
- Libexpat 1.95 or higher.
|
||||
- Libyaml 0.1.4 or higher.
|
||||
- Erlang/OTP 17.1 or higher.
|
||||
- OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption.
|
||||
- OpenSSL 1.0.0 or higher, for STARTTLS, SASL and SSL encryption.
|
||||
- Zlib 1.2.3 or higher, for Stream Compression support (XEP-0138). Optional.
|
||||
- PAM library. Optional. For Pluggable Authentication Modules (PAM).
|
||||
- GNU Iconv 1.8 or higher, for the IRC Transport (mod_irc). Optional. Not
|
||||
@@ -162,7 +164,7 @@ https://github.com/processone/ejabberd-vagrant-dev.
|
||||
To start ejabberd in development mode from the repository directory, you can
|
||||
type a command like:
|
||||
|
||||
EJABBERD_CONFIG_PATH=ejabberd.yml erl -pa ebin -pa deps/*/ebin -pa test -s ejabberd
|
||||
EJABBERD_CONFIG_PATH=ejabberd.yml erl -pa ebin -pa deps/*/ebin -pa test -pa deps/elixir/lib/*/ebin/ -s ejabberd
|
||||
|
||||
Links
|
||||
-----
|
||||
|
||||
@@ -1,301 +0,0 @@
|
||||
-- LDAPv3 ASN.1 specification, taken from RFC 2251
|
||||
|
||||
-- Lightweight-Directory-Access-Protocol-V3 DEFINITIONS
|
||||
ELDAPv3 DEFINITIONS
|
||||
IMPLICIT TAGS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
LDAPMessage ::= SEQUENCE {
|
||||
messageID MessageID,
|
||||
protocolOp CHOICE {
|
||||
bindRequest BindRequest,
|
||||
bindResponse BindResponse,
|
||||
unbindRequest UnbindRequest,
|
||||
searchRequest SearchRequest,
|
||||
searchResEntry SearchResultEntry,
|
||||
searchResDone SearchResultDone,
|
||||
searchResRef SearchResultReference,
|
||||
modifyRequest ModifyRequest,
|
||||
modifyResponse ModifyResponse,
|
||||
addRequest AddRequest,
|
||||
addResponse AddResponse,
|
||||
delRequest DelRequest,
|
||||
delResponse DelResponse,
|
||||
modDNRequest ModifyDNRequest,
|
||||
modDNResponse ModifyDNResponse,
|
||||
compareRequest CompareRequest,
|
||||
compareResponse CompareResponse,
|
||||
abandonRequest AbandonRequest,
|
||||
extendedReq ExtendedRequest,
|
||||
extendedResp ExtendedResponse },
|
||||
controls [0] Controls OPTIONAL }
|
||||
|
||||
MessageID ::= INTEGER (0 .. maxInt)
|
||||
|
||||
maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --
|
||||
|
||||
LDAPString ::= OCTET STRING
|
||||
|
||||
LDAPOID ::= OCTET STRING
|
||||
|
||||
LDAPDN ::= LDAPString
|
||||
|
||||
RelativeLDAPDN ::= LDAPString
|
||||
|
||||
AttributeType ::= LDAPString
|
||||
|
||||
AttributeDescription ::= LDAPString
|
||||
|
||||
|
||||
|
||||
|
||||
-- Wahl, et. al. Standards Track [Page 44]
|
||||
--
|
||||
-- RFC 2251 LDAPv3 December 1997
|
||||
|
||||
|
||||
AttributeDescriptionList ::= SEQUENCE OF
|
||||
AttributeDescription
|
||||
|
||||
AttributeValue ::= OCTET STRING
|
||||
|
||||
AttributeValueAssertion ::= SEQUENCE {
|
||||
attributeDesc AttributeDescription,
|
||||
assertionValue AssertionValue }
|
||||
|
||||
AssertionValue ::= OCTET STRING
|
||||
|
||||
Attribute ::= SEQUENCE {
|
||||
type AttributeDescription,
|
||||
vals SET OF AttributeValue }
|
||||
|
||||
MatchingRuleId ::= LDAPString
|
||||
|
||||
LDAPResult ::= SEQUENCE {
|
||||
resultCode ENUMERATED {
|
||||
success (0),
|
||||
operationsError (1),
|
||||
protocolError (2),
|
||||
timeLimitExceeded (3),
|
||||
sizeLimitExceeded (4),
|
||||
compareFalse (5),
|
||||
compareTrue (6),
|
||||
authMethodNotSupported (7),
|
||||
strongAuthRequired (8),
|
||||
-- 9 reserved --
|
||||
referral (10), -- new
|
||||
adminLimitExceeded (11), -- new
|
||||
unavailableCriticalExtension (12), -- new
|
||||
confidentialityRequired (13), -- new
|
||||
saslBindInProgress (14), -- new
|
||||
noSuchAttribute (16),
|
||||
undefinedAttributeType (17),
|
||||
inappropriateMatching (18),
|
||||
constraintViolation (19),
|
||||
attributeOrValueExists (20),
|
||||
invalidAttributeSyntax (21),
|
||||
-- 22-31 unused --
|
||||
noSuchObject (32),
|
||||
aliasProblem (33),
|
||||
invalidDNSyntax (34),
|
||||
-- 35 reserved for undefined isLeaf --
|
||||
aliasDereferencingProblem (36),
|
||||
-- 37-47 unused --
|
||||
inappropriateAuthentication (48),
|
||||
|
||||
-- Wahl, et. al. Standards Track [Page 45]
|
||||
--
|
||||
-- RFC 2251 LDAPv3 December 1997
|
||||
|
||||
|
||||
invalidCredentials (49),
|
||||
insufficientAccessRights (50),
|
||||
busy (51),
|
||||
unavailable (52),
|
||||
unwillingToPerform (53),
|
||||
loopDetect (54),
|
||||
-- 55-63 unused --
|
||||
namingViolation (64),
|
||||
objectClassViolation (65),
|
||||
notAllowedOnNonLeaf (66),
|
||||
notAllowedOnRDN (67),
|
||||
entryAlreadyExists (68),
|
||||
objectClassModsProhibited (69),
|
||||
-- 70 reserved for CLDAP --
|
||||
affectsMultipleDSAs (71), -- new
|
||||
-- 72-79 unused --
|
||||
other (80) },
|
||||
-- 81-90 reserved for APIs --
|
||||
matchedDN LDAPDN,
|
||||
errorMessage LDAPString,
|
||||
referral [3] Referral OPTIONAL }
|
||||
|
||||
Referral ::= SEQUENCE OF LDAPURL
|
||||
|
||||
LDAPURL ::= LDAPString -- limited to characters permitted in URLs
|
||||
|
||||
Controls ::= SEQUENCE OF Control
|
||||
|
||||
Control ::= SEQUENCE {
|
||||
controlType LDAPOID,
|
||||
criticality BOOLEAN DEFAULT FALSE,
|
||||
controlValue OCTET STRING OPTIONAL }
|
||||
|
||||
BindRequest ::= [APPLICATION 0] SEQUENCE {
|
||||
version INTEGER (1 .. 127),
|
||||
name LDAPDN,
|
||||
authentication AuthenticationChoice }
|
||||
|
||||
AuthenticationChoice ::= CHOICE {
|
||||
simple [0] OCTET STRING,
|
||||
-- 1 and 2 reserved
|
||||
sasl [3] SaslCredentials }
|
||||
|
||||
SaslCredentials ::= SEQUENCE {
|
||||
mechanism LDAPString,
|
||||
credentials OCTET STRING OPTIONAL }
|
||||
|
||||
BindResponse ::= [APPLICATION 1] SEQUENCE {
|
||||
|
||||
-- Wahl, et. al. Standards Track [Page 46]
|
||||
--
|
||||
-- RFC 2251 LDAPv3 December 1997
|
||||
|
||||
|
||||
COMPONENTS OF LDAPResult,
|
||||
serverSaslCreds [7] OCTET STRING OPTIONAL }
|
||||
|
||||
UnbindRequest ::= [APPLICATION 2] NULL
|
||||
|
||||
SearchRequest ::= [APPLICATION 3] SEQUENCE {
|
||||
baseObject LDAPDN,
|
||||
scope ENUMERATED {
|
||||
baseObject (0),
|
||||
singleLevel (1),
|
||||
wholeSubtree (2) },
|
||||
derefAliases ENUMERATED {
|
||||
neverDerefAliases (0),
|
||||
derefInSearching (1),
|
||||
derefFindingBaseObj (2),
|
||||
derefAlways (3) },
|
||||
sizeLimit INTEGER (0 .. maxInt),
|
||||
timeLimit INTEGER (0 .. maxInt),
|
||||
typesOnly BOOLEAN,
|
||||
filter Filter,
|
||||
attributes AttributeDescriptionList }
|
||||
|
||||
Filter ::= CHOICE {
|
||||
and [0] SET OF Filter,
|
||||
or [1] SET OF Filter,
|
||||
not [2] Filter,
|
||||
equalityMatch [3] AttributeValueAssertion,
|
||||
substrings [4] SubstringFilter,
|
||||
greaterOrEqual [5] AttributeValueAssertion,
|
||||
lessOrEqual [6] AttributeValueAssertion,
|
||||
present [7] AttributeDescription,
|
||||
approxMatch [8] AttributeValueAssertion,
|
||||
extensibleMatch [9] MatchingRuleAssertion }
|
||||
|
||||
SubstringFilter ::= SEQUENCE {
|
||||
type AttributeDescription,
|
||||
-- at least one must be present
|
||||
substrings SEQUENCE OF CHOICE {
|
||||
initial [0] LDAPString,
|
||||
any [1] LDAPString,
|
||||
final [2] LDAPString } }
|
||||
|
||||
MatchingRuleAssertion ::= SEQUENCE {
|
||||
matchingRule [1] MatchingRuleId OPTIONAL,
|
||||
type [2] AttributeDescription OPTIONAL,
|
||||
matchValue [3] AssertionValue,
|
||||
dnAttributes [4] BOOLEAN DEFAULT FALSE }
|
||||
|
||||
-- Wahl, et. al. Standards Track [Page 47]
|
||||
--
|
||||
-- RFC 2251 LDAPv3 December 1997
|
||||
|
||||
SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
|
||||
objectName LDAPDN,
|
||||
attributes PartialAttributeList }
|
||||
|
||||
PartialAttributeList ::= SEQUENCE OF SEQUENCE {
|
||||
type AttributeDescription,
|
||||
vals SET OF AttributeValue }
|
||||
|
||||
SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
|
||||
|
||||
SearchResultDone ::= [APPLICATION 5] LDAPResult
|
||||
|
||||
ModifyRequest ::= [APPLICATION 6] SEQUENCE {
|
||||
object LDAPDN,
|
||||
modification SEQUENCE OF SEQUENCE {
|
||||
operation ENUMERATED {
|
||||
add (0),
|
||||
delete (1),
|
||||
replace (2) },
|
||||
modification AttributeTypeAndValues } }
|
||||
|
||||
AttributeTypeAndValues ::= SEQUENCE {
|
||||
type AttributeDescription,
|
||||
vals SET OF AttributeValue }
|
||||
|
||||
ModifyResponse ::= [APPLICATION 7] LDAPResult
|
||||
|
||||
AddRequest ::= [APPLICATION 8] SEQUENCE {
|
||||
entry LDAPDN,
|
||||
attributes AttributeList }
|
||||
|
||||
AttributeList ::= SEQUENCE OF SEQUENCE {
|
||||
type AttributeDescription,
|
||||
vals SET OF AttributeValue }
|
||||
|
||||
AddResponse ::= [APPLICATION 9] LDAPResult
|
||||
|
||||
DelRequest ::= [APPLICATION 10] LDAPDN
|
||||
|
||||
DelResponse ::= [APPLICATION 11] LDAPResult
|
||||
|
||||
ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
|
||||
entry LDAPDN,
|
||||
newrdn RelativeLDAPDN,
|
||||
deleteoldrdn BOOLEAN,
|
||||
newSuperior [0] LDAPDN OPTIONAL }
|
||||
|
||||
ModifyDNResponse ::= [APPLICATION 13] LDAPResult
|
||||
|
||||
-- Wahl, et. al. Standards Track [Page 48]
|
||||
--
|
||||
-- RFC 2251 LDAPv3 December 1997
|
||||
|
||||
|
||||
CompareRequest ::= [APPLICATION 14] SEQUENCE {
|
||||
entry LDAPDN,
|
||||
ava AttributeValueAssertion }
|
||||
|
||||
CompareResponse ::= [APPLICATION 15] LDAPResult
|
||||
|
||||
AbandonRequest ::= [APPLICATION 16] MessageID
|
||||
|
||||
ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
|
||||
requestName [0] LDAPOID,
|
||||
requestValue [1] OCTET STRING OPTIONAL }
|
||||
|
||||
ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
|
||||
COMPONENTS OF LDAPResult,
|
||||
responseName [10] LDAPOID OPTIONAL,
|
||||
response [11] OCTET STRING OPTIONAL }
|
||||
|
||||
passwdModifyOID LDAPOID ::= "1.3.6.1.4.1.4203.1.11.1"
|
||||
|
||||
PasswdModifyRequestValue ::= SEQUENCE {
|
||||
userIdentity [0] OCTET STRING OPTIONAL,
|
||||
oldPasswd [1] OCTET STRING OPTIONAL,
|
||||
newPasswd [2] OCTET STRING OPTIONAL }
|
||||
|
||||
PasswdModifyResponseValue ::= SEQUENCE {
|
||||
genPasswd [0] OCTET STRING OPTIONAL }
|
||||
|
||||
END
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ use Mix.Config
|
||||
config :ejabberd,
|
||||
file: "config/ejabberd.yml",
|
||||
log_path: 'log/ejabberd.log'
|
||||
|
||||
|
||||
# Customize Mnesia directory:
|
||||
config :mnesia,
|
||||
dir: 'mnesiadb/'
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
defmodule Ejabberd.ConfigFile do
|
||||
use Ejabberd.Config
|
||||
|
||||
def start do
|
||||
[loglevel: 4,
|
||||
log_rotate_size: 10485760,
|
||||
log_rotate_date: "",
|
||||
log_rotate_count: 1,
|
||||
log_rate_limit: 100,
|
||||
auth_method: :internal,
|
||||
max_fsm_queue: 1000,
|
||||
language: "en",
|
||||
allow_contrib_modules: true,
|
||||
hosts: ["localhost"],
|
||||
shaper: shaper,
|
||||
acl: acl,
|
||||
access: access]
|
||||
end
|
||||
|
||||
defp shaper do
|
||||
[normal: 1000,
|
||||
fast: 50000,
|
||||
max_fsm_queue: 1000]
|
||||
end
|
||||
|
||||
defp acl do
|
||||
[local:
|
||||
[user_regexp: "", loopback: [ip: "127.0.0.0/8"]]]
|
||||
end
|
||||
|
||||
defp access do
|
||||
[max_user_sessions: [all: 10],
|
||||
max_user_offline_messages: [admin: 5000, all: 100],
|
||||
local: [local: :allow],
|
||||
c2s: [blocked: :deny, all: :allow],
|
||||
c2s_shaper: [admin: :none, all: :normal],
|
||||
s2s_shaper: [all: :fast],
|
||||
announce: [admin: :allow],
|
||||
configure: [admin: :allow],
|
||||
muc_admin: [admin: :allow],
|
||||
muc_create: [local: :allow],
|
||||
muc: [all: :allow],
|
||||
pubsub_createnode: [local: :allow],
|
||||
register: [all: :allow],
|
||||
trusted_network: [loopback: :allow]]
|
||||
end
|
||||
|
||||
listen :ejabberd_c2s do
|
||||
@opts [
|
||||
port: 5222,
|
||||
max_stanza_size: 65536,
|
||||
shaper: :c2s_shaper,
|
||||
access: :c2s]
|
||||
end
|
||||
|
||||
listen :ejabberd_s2s_in do
|
||||
@opts [port: 5269]
|
||||
end
|
||||
|
||||
listen :ejabberd_http do
|
||||
@opts [
|
||||
port: 5280,
|
||||
web_admin: true,
|
||||
http_poll: true,
|
||||
http_bind: true,
|
||||
captcha: true]
|
||||
end
|
||||
|
||||
module :mod_adhoc do
|
||||
end
|
||||
|
||||
module :mod_announce do
|
||||
@opts [access: :announce]
|
||||
end
|
||||
|
||||
module :mod_blocking do
|
||||
end
|
||||
|
||||
module :mod_caps do
|
||||
end
|
||||
|
||||
module :mod_carboncopy do
|
||||
end
|
||||
|
||||
module :mod_client_state do
|
||||
@opts [
|
||||
drop_chat_states: true,
|
||||
queue_presence: false]
|
||||
end
|
||||
|
||||
module :mod_configure do
|
||||
end
|
||||
|
||||
module :mod_disco do
|
||||
end
|
||||
|
||||
module :mod_irc do
|
||||
end
|
||||
|
||||
module :mod_http_bind do
|
||||
end
|
||||
|
||||
module :mod_last do
|
||||
end
|
||||
|
||||
module :mod_muc do
|
||||
@opts [
|
||||
access: :muc,
|
||||
access_create: :muc_create,
|
||||
access_persistent: :muc_create,
|
||||
access_admin: :muc_admin]
|
||||
end
|
||||
|
||||
module :mod_offline do
|
||||
@opts [access_max_user_messages: :max_user_offline_messages]
|
||||
end
|
||||
|
||||
module :mod_ping do
|
||||
end
|
||||
|
||||
module :mod_privacy do
|
||||
end
|
||||
|
||||
module :mod_private do
|
||||
end
|
||||
|
||||
module :mod_pubsub do
|
||||
@opts [
|
||||
access_createnode: :pubsub_createnode,
|
||||
ignore_pep_from_offline: true,
|
||||
last_item_cache: true,
|
||||
plugins: ["flat", "hometree", "pep"]]
|
||||
end
|
||||
|
||||
module :mod_register do
|
||||
@opts [welcome_message: [
|
||||
subject: "Welcome!",
|
||||
body: "Hi.\nWelcome to this XMPP Server",
|
||||
ip_access: :trusted_network,
|
||||
access: :register]]
|
||||
end
|
||||
|
||||
module :mod_roster do
|
||||
end
|
||||
|
||||
module :mod_shared_roster do
|
||||
end
|
||||
|
||||
module :mod_stats do
|
||||
end
|
||||
|
||||
module :mod_time do
|
||||
end
|
||||
|
||||
module :mod_version do
|
||||
end
|
||||
|
||||
# Example of how to define a hook, called when the event
|
||||
# specified is triggered.
|
||||
#
|
||||
# @event: Name of the event
|
||||
# @opts: Params are optional. Available: :host and :priority.
|
||||
# If missing, defaults are used. (host: :global | priority: 50)
|
||||
# @callback Could be an anonymous function or a callback from a module,
|
||||
# use the &ModuleName.function/arity format for that.
|
||||
hook :register_user, [host: "localhost"], fn(user, server) ->
|
||||
info("User registered: #{user} on #{server}")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,667 @@
|
||||
###
|
||||
### ejabberd configuration file
|
||||
###
|
||||
###
|
||||
|
||||
### The parameters used in this configuration file are explained in more detail
|
||||
### in the ejabberd Installation and Operation Guide.
|
||||
### Please consult the Guide in case of doubts, it is included with
|
||||
### your copy of ejabberd, and is also available online at
|
||||
### http://www.process-one.net/en/ejabberd/docs/
|
||||
|
||||
### The configuration file is written in YAML.
|
||||
### Refer to http://en.wikipedia.org/wiki/YAML for the brief description.
|
||||
### However, ejabberd treats different literals as different types:
|
||||
###
|
||||
### - unquoted or single-quoted strings. They are called "atoms".
|
||||
### Example: dog, 'Jupiter', '3.14159', YELLOW
|
||||
###
|
||||
### - numeric literals. Example: 3, -45.0, .0
|
||||
###
|
||||
### - quoted or folded strings.
|
||||
### Examples of quoted string: "Lizzard", "orange".
|
||||
### Example of folded string:
|
||||
### > Art thou not Romeo,
|
||||
### and a Montague?
|
||||
|
||||
### =======
|
||||
### LOGGING
|
||||
|
||||
##
|
||||
## loglevel: Verbosity of log files generated by ejabberd.
|
||||
## 0: No ejabberd log at all (not recommended)
|
||||
## 1: Critical
|
||||
## 2: Error
|
||||
## 3: Warning
|
||||
## 4: Info
|
||||
## 5: Debug
|
||||
##
|
||||
loglevel: 4
|
||||
|
||||
##
|
||||
## rotation: Describe how to rotate logs. Either size and/or date can trigger
|
||||
## log rotation. Setting count to N keeps N rotated logs. Setting count to 0
|
||||
## does not disable rotation, it instead rotates the file and keeps no previous
|
||||
## versions around. Setting size to X rotate log when it reaches X bytes.
|
||||
## To disable rotation set the size to 0 and the date to ""
|
||||
## Date syntax is taken from the syntax newsyslog uses in newsyslog.conf.
|
||||
## Some examples:
|
||||
## $D0 rotate every night at midnight
|
||||
## $D23 rotate every day at 23:00 hr
|
||||
## $W0D23 rotate every week on Sunday at 23:00 hr
|
||||
## $W5D16 rotate every week on Friday at 16:00 hr
|
||||
## $M1D0 rotate on the first day of every month at midnight
|
||||
## $M5D6 rotate on every 5th day of the month at 6:00 hr
|
||||
##
|
||||
log_rotate_size: 10485760
|
||||
log_rotate_date: ""
|
||||
log_rotate_count: 1
|
||||
|
||||
##
|
||||
## overload protection: If you want to limit the number of messages per second
|
||||
## allowed from error_logger, which is a good idea if you want to avoid a flood
|
||||
## of messages when system is overloaded, you can set a limit.
|
||||
## 100 is ejabberd's default.
|
||||
log_rate_limit: 100
|
||||
|
||||
##
|
||||
## watchdog_admins: Only useful for developers: if an ejabberd process
|
||||
## consumes a lot of memory, send live notifications to these XMPP
|
||||
## accounts.
|
||||
##
|
||||
## watchdog_admins:
|
||||
## - "bob@example.com"
|
||||
|
||||
|
||||
### ================
|
||||
### SERVED HOSTNAMES
|
||||
|
||||
##
|
||||
## hosts: Domains served by ejabberd.
|
||||
## You can define one or several, for example:
|
||||
## hosts:
|
||||
## - "example.net"
|
||||
## - "example.com"
|
||||
## - "example.org"
|
||||
##
|
||||
hosts:
|
||||
- "localhost"
|
||||
|
||||
##
|
||||
## route_subdomains: Delegate subdomains to other XMPP servers.
|
||||
## For example, if this ejabberd serves example.org and you want
|
||||
## to allow communication with an XMPP server called im.example.org.
|
||||
##
|
||||
## route_subdomains: s2s
|
||||
|
||||
### ===============
|
||||
### LISTENING PORTS
|
||||
|
||||
##
|
||||
## listen: The ports ejabberd will listen on, which service each is handled
|
||||
## by and what options to start it with.
|
||||
##
|
||||
listen:
|
||||
-
|
||||
port: 5222
|
||||
module: ejabberd_c2s
|
||||
##
|
||||
## If TLS is compiled in and you installed a SSL
|
||||
## certificate, specify the full path to the
|
||||
## file and uncomment these lines:
|
||||
##
|
||||
## certfile: "/path/to/ssl.pem"
|
||||
## starttls: true
|
||||
##
|
||||
## To enforce TLS encryption for client connections,
|
||||
## use this instead of the "starttls" option:
|
||||
##
|
||||
## starttls_required: true
|
||||
##
|
||||
## Custom OpenSSL options
|
||||
##
|
||||
## protocol_options:
|
||||
## - "no_sslv3"
|
||||
## - "no_tlsv1"
|
||||
max_stanza_size: 65536
|
||||
shaper: c2s_shaper
|
||||
access: c2s
|
||||
-
|
||||
port: 5269
|
||||
module: ejabberd_s2s_in
|
||||
##
|
||||
## ejabberd_service: Interact with external components (transports, ...)
|
||||
##
|
||||
## -
|
||||
## port: 8888
|
||||
## module: ejabberd_service
|
||||
## access: all
|
||||
## shaper_rule: fast
|
||||
## ip: "127.0.0.1"
|
||||
## hosts:
|
||||
## "icq.example.org":
|
||||
## password: "secret"
|
||||
## "sms.example.org":
|
||||
## password: "secret"
|
||||
|
||||
##
|
||||
## ejabberd_stun: Handles STUN Binding requests
|
||||
##
|
||||
## -
|
||||
## port: 3478
|
||||
## transport: udp
|
||||
## module: ejabberd_stun
|
||||
|
||||
##
|
||||
## To handle XML-RPC requests that provide admin credentials:
|
||||
##
|
||||
## -
|
||||
## port: 4560
|
||||
## module: ejabberd_xmlrpc
|
||||
-
|
||||
port: 5280
|
||||
module: ejabberd_http
|
||||
## request_handlers:
|
||||
## "/pub/archive": mod_http_fileserver
|
||||
web_admin: true
|
||||
http_poll: true
|
||||
http_bind: true
|
||||
## register: true
|
||||
captcha: true
|
||||
|
||||
##
|
||||
## s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections.
|
||||
## Allowed values are: false optional required required_trusted
|
||||
## You must specify a certificate file.
|
||||
##
|
||||
## s2s_use_starttls: optional
|
||||
|
||||
##
|
||||
## s2s_certfile: Specify a certificate file.
|
||||
##
|
||||
## s2s_certfile: "/path/to/ssl.pem"
|
||||
|
||||
## Custom OpenSSL options
|
||||
##
|
||||
## s2s_protocol_options:
|
||||
## - "no_sslv3"
|
||||
## - "no_tlsv1"
|
||||
|
||||
##
|
||||
## domain_certfile: Specify a different certificate for each served hostname.
|
||||
##
|
||||
## host_config:
|
||||
## "example.org":
|
||||
## domain_certfile: "/path/to/example_org.pem"
|
||||
## "example.com":
|
||||
## domain_certfile: "/path/to/example_com.pem"
|
||||
|
||||
##
|
||||
## S2S whitelist or blacklist
|
||||
##
|
||||
## Default s2s policy for undefined hosts.
|
||||
##
|
||||
## s2s_access: s2s
|
||||
|
||||
##
|
||||
## Outgoing S2S options
|
||||
##
|
||||
## Preferred address families (which to try first) and connect timeout
|
||||
## in milliseconds.
|
||||
##
|
||||
## outgoing_s2s_families:
|
||||
## - ipv4
|
||||
## - ipv6
|
||||
## outgoing_s2s_timeout: 10000
|
||||
|
||||
### ==============
|
||||
### AUTHENTICATION
|
||||
|
||||
##
|
||||
## auth_method: Method used to authenticate the users.
|
||||
## The default method is the internal.
|
||||
## If you want to use a different method,
|
||||
## comment this line and enable the correct ones.
|
||||
##
|
||||
auth_method: internal
|
||||
|
||||
##
|
||||
## 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
|
||||
## Make sure the script is executable by ejabberd.
|
||||
##
|
||||
## auth_method: external
|
||||
## extauth_program: "/path/to/authentication/script"
|
||||
|
||||
##
|
||||
## Authentication using ODBC
|
||||
## Remember to setup a database in the next section.
|
||||
##
|
||||
## auth_method: odbc
|
||||
|
||||
##
|
||||
## Authentication using PAM
|
||||
##
|
||||
## auth_method: pam
|
||||
## pam_service: "pamservicename"
|
||||
|
||||
##
|
||||
## Authentication using LDAP
|
||||
##
|
||||
## auth_method: ldap
|
||||
##
|
||||
## List of LDAP servers:
|
||||
## ldap_servers:
|
||||
## - "localhost"
|
||||
##
|
||||
## Encryption of connection to LDAP servers:
|
||||
## ldap_encrypt: none
|
||||
## ldap_encrypt: tls
|
||||
##
|
||||
## Port to connect to on LDAP servers:
|
||||
## ldap_port: 389
|
||||
## ldap_port: 636
|
||||
##
|
||||
## LDAP manager:
|
||||
## ldap_rootdn: "dc=example,dc=com"
|
||||
##
|
||||
## Password of LDAP manager:
|
||||
## ldap_password: "******"
|
||||
##
|
||||
## Search base of LDAP directory:
|
||||
## ldap_base: "dc=example,dc=com"
|
||||
##
|
||||
## LDAP attribute that holds user ID:
|
||||
## ldap_uids:
|
||||
## - "mail": "%u@mail.example.org"
|
||||
##
|
||||
## LDAP filter:
|
||||
## ldap_filter: "(objectClass=shadowAccount)"
|
||||
|
||||
##
|
||||
## Anonymous login support:
|
||||
## auth_method: anonymous
|
||||
## anonymous_protocol: sasl_anon | login_anon | both
|
||||
## allow_multiple_connections: true | false
|
||||
##
|
||||
## host_config:
|
||||
## "public.example.org":
|
||||
## auth_method: anonymous
|
||||
## allow_multiple_connections: false
|
||||
## anonymous_protocol: sasl_anon
|
||||
##
|
||||
## To use both anonymous and internal authentication:
|
||||
##
|
||||
## host_config:
|
||||
## "public.example.org":
|
||||
## auth_method:
|
||||
## - internal
|
||||
## - anonymous
|
||||
|
||||
### ==============
|
||||
### DATABASE SETUP
|
||||
|
||||
## ejabberd by default uses the internal Mnesia database,
|
||||
## so you do not necessarily need this section.
|
||||
## This section provides configuration examples in case
|
||||
## you want to use other database backends.
|
||||
## Please consult the ejabberd Guide for details on database creation.
|
||||
|
||||
##
|
||||
## MySQL server:
|
||||
##
|
||||
## odbc_type: mysql
|
||||
## odbc_server: "server"
|
||||
## odbc_database: "database"
|
||||
## odbc_username: "username"
|
||||
## odbc_password: "password"
|
||||
##
|
||||
## If you want to specify the port:
|
||||
## odbc_port: 1234
|
||||
|
||||
##
|
||||
## PostgreSQL server:
|
||||
##
|
||||
## odbc_type: pgsql
|
||||
## odbc_server: "server"
|
||||
## odbc_database: "database"
|
||||
## odbc_username: "username"
|
||||
## odbc_password: "password"
|
||||
##
|
||||
## If you want to specify the port:
|
||||
## odbc_port: 1234
|
||||
##
|
||||
## If you use PostgreSQL, have a large database, and need a
|
||||
## faster but inexact replacement for "select count(*) from users"
|
||||
##
|
||||
## pgsql_users_number_estimate: true
|
||||
|
||||
##
|
||||
## ODBC compatible or MSSQL server:
|
||||
##
|
||||
## odbc_type: odbc
|
||||
## odbc_server: "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"
|
||||
|
||||
##
|
||||
## Number of connections to open to the database for each virtual host
|
||||
##
|
||||
## odbc_pool_size: 10
|
||||
|
||||
##
|
||||
## Interval to make a dummy SQL request to keep the connections to the
|
||||
## database alive. Specify in seconds: for example 28800 means 8 hours
|
||||
##
|
||||
## odbc_keepalive_interval: undefined
|
||||
|
||||
### ===============
|
||||
### TRAFFIC SHAPERS
|
||||
|
||||
shaper:
|
||||
##
|
||||
## The "normal" shaper limits traffic speed to 1000 B/s
|
||||
##
|
||||
normal: 1000
|
||||
|
||||
##
|
||||
## The "fast" shaper limits traffic speed to 50000 B/s
|
||||
##
|
||||
fast: 50000
|
||||
|
||||
##
|
||||
## This option specifies the maximum number of elements in the queue
|
||||
## of the FSM. Refer to the documentation for details.
|
||||
##
|
||||
max_fsm_queue: 1000
|
||||
|
||||
###. ====================
|
||||
###' ACCESS CONTROL LISTS
|
||||
acl:
|
||||
##
|
||||
## The 'admin' ACL grants administrative privileges to XMPP accounts.
|
||||
## You can put here as many accounts as you want.
|
||||
##
|
||||
## admin:
|
||||
## user:
|
||||
## - "aleksey": "localhost"
|
||||
## - "ermine": "example.org"
|
||||
##
|
||||
## Blocked users
|
||||
##
|
||||
## blocked:
|
||||
## user:
|
||||
## - "baduser": "example.org"
|
||||
## - "test"
|
||||
|
||||
## Local users: don't modify this.
|
||||
##
|
||||
local:
|
||||
user_regexp: ""
|
||||
|
||||
##
|
||||
## More examples of ACLs
|
||||
##
|
||||
## jabberorg:
|
||||
## server:
|
||||
## - "jabber.org"
|
||||
## aleksey:
|
||||
## user:
|
||||
## - "aleksey": "jabber.ru"
|
||||
## test:
|
||||
## user_regexp: "^test"
|
||||
## user_glob: "test*"
|
||||
|
||||
##
|
||||
## Loopback network
|
||||
##
|
||||
loopback:
|
||||
ip:
|
||||
- "127.0.0.0/8"
|
||||
|
||||
##
|
||||
## Bad XMPP servers
|
||||
##
|
||||
## bad_servers:
|
||||
## server:
|
||||
## - "xmpp.zombie.org"
|
||||
## - "xmpp.spam.com"
|
||||
|
||||
##
|
||||
## Define specific ACLs in a virtual host.
|
||||
##
|
||||
## host_config:
|
||||
## "localhost":
|
||||
## acl:
|
||||
## admin:
|
||||
## user:
|
||||
## - "bob-local": "localhost"
|
||||
|
||||
### ============
|
||||
### ACCESS RULES
|
||||
access:
|
||||
## Maximum number of simultaneous sessions allowed for a single user:
|
||||
max_user_sessions:
|
||||
all: 10
|
||||
## Maximum number of offline messages that users can have:
|
||||
max_user_offline_messages:
|
||||
admin: 5000
|
||||
all: 100
|
||||
## This rule allows access only for local users:
|
||||
local:
|
||||
local: allow
|
||||
## Only non-blocked users can use c2s connections:
|
||||
c2s:
|
||||
blocked: deny
|
||||
all: allow
|
||||
## For C2S connections, all users except admins use the "normal" shaper
|
||||
c2s_shaper:
|
||||
admin: none
|
||||
all: normal
|
||||
## All S2S connections use the "fast" shaper
|
||||
s2s_shaper:
|
||||
all: fast
|
||||
## Only admins can send announcement messages:
|
||||
announce:
|
||||
admin: allow
|
||||
## Only admins can use the configuration interface:
|
||||
configure:
|
||||
admin: allow
|
||||
## Admins of this server are also admins of the MUC service:
|
||||
muc_admin:
|
||||
admin: allow
|
||||
## Only accounts of the local ejabberd server can create rooms:
|
||||
muc_create:
|
||||
local: allow
|
||||
## All users are allowed to use the MUC service:
|
||||
muc:
|
||||
all: allow
|
||||
## Only accounts on the local ejabberd server can create Pubsub nodes:
|
||||
pubsub_createnode:
|
||||
local: allow
|
||||
## In-band registration allows registration of any possible username.
|
||||
## To disable in-band registration, replace 'allow' with 'deny'.
|
||||
register:
|
||||
all: allow
|
||||
## Only allow to register from localhost
|
||||
trusted_network:
|
||||
loopback: allow
|
||||
## Do not establish S2S connections with bad servers
|
||||
## s2s:
|
||||
## bad_servers: deny
|
||||
## all: allow
|
||||
|
||||
## By default the frequency of account registrations from the same IP
|
||||
## is limited to 1 account every 10 minutes. To disable, specify: infinity
|
||||
## registration_timeout: 600
|
||||
|
||||
##
|
||||
## Define specific Access Rules in a virtual host.
|
||||
##
|
||||
## host_config:
|
||||
## "localhost":
|
||||
## access:
|
||||
## c2s:
|
||||
## admin: allow
|
||||
## all: deny
|
||||
## register:
|
||||
## all: deny
|
||||
|
||||
### ================
|
||||
### DEFAULT LANGUAGE
|
||||
|
||||
##
|
||||
## language: Default language used for server messages.
|
||||
##
|
||||
language: "en"
|
||||
|
||||
##
|
||||
## Set a different default language in a virtual host.
|
||||
##
|
||||
## host_config:
|
||||
## "localhost":
|
||||
## language: "ru"
|
||||
|
||||
### =======
|
||||
### CAPTCHA
|
||||
|
||||
##
|
||||
## Full path to a script that generates the image.
|
||||
##
|
||||
## captcha_cmd: "/lib/ejabberd/priv/bin/captcha.sh"
|
||||
|
||||
##
|
||||
## Host for the URL and port where ejabberd listens for CAPTCHA requests.
|
||||
##
|
||||
## captcha_host: "example.org:5280"
|
||||
|
||||
##
|
||||
## Limit CAPTCHA calls per minute for JID/IP to avoid DoS.
|
||||
##
|
||||
## captcha_limit: 5
|
||||
|
||||
### =======
|
||||
### MODULES
|
||||
|
||||
##
|
||||
## Modules enabled in all ejabberd virtual hosts.
|
||||
##
|
||||
modules:
|
||||
mod_adhoc: {}
|
||||
## mod_admin_extra: {}
|
||||
mod_announce: # recommends mod_adhoc
|
||||
access: announce
|
||||
mod_blocking: {} # requires mod_privacy
|
||||
mod_caps: {}
|
||||
mod_carboncopy: {}
|
||||
mod_client_state:
|
||||
drop_chat_states: true
|
||||
queue_presence: false
|
||||
mod_configure: {} # requires mod_adhoc
|
||||
mod_disco: {}
|
||||
## mod_echo: {}
|
||||
mod_irc: {}
|
||||
mod_http_bind: {}
|
||||
## mod_http_fileserver:
|
||||
## docroot: "/var/www"
|
||||
## accesslog: "/var/log/ejabberd/access.log"
|
||||
mod_last: {}
|
||||
mod_muc:
|
||||
## host: "conference.@HOST@"
|
||||
access: muc
|
||||
access_create: muc_create
|
||||
access_persistent: muc_create
|
||||
access_admin: muc_admin
|
||||
## mod_muc_log: {}
|
||||
mod_offline:
|
||||
access_max_user_messages: max_user_offline_messages
|
||||
mod_ping: {}
|
||||
## mod_pres_counter:
|
||||
## count: 5
|
||||
## interval: 60
|
||||
mod_privacy: {}
|
||||
mod_private: {}
|
||||
## mod_proxy65: {}
|
||||
mod_pubsub:
|
||||
access_createnode: pubsub_createnode
|
||||
## reduces resource comsumption, but XEP incompliant
|
||||
ignore_pep_from_offline: true
|
||||
## XEP compliant, but increases resource comsumption
|
||||
## ignore_pep_from_offline: false
|
||||
last_item_cache: false
|
||||
plugins:
|
||||
- "flat"
|
||||
- "hometree"
|
||||
- "pep" # pep requires mod_caps
|
||||
mod_register:
|
||||
##
|
||||
## Protect In-Band account registrations with CAPTCHA.
|
||||
##
|
||||
## captcha_protected: true
|
||||
|
||||
##
|
||||
## Set the minimum informational entropy for passwords.
|
||||
##
|
||||
## password_strength: 32
|
||||
|
||||
##
|
||||
## After successful registration, the user receives
|
||||
## a message with this subject and body.
|
||||
##
|
||||
welcome_message:
|
||||
subject: "Welcome!"
|
||||
body: |-
|
||||
Hi.
|
||||
Welcome to this XMPP server.
|
||||
|
||||
##
|
||||
## When a user registers, send a notification to
|
||||
## these XMPP accounts.
|
||||
##
|
||||
## registration_watchers:
|
||||
## - "admin1@example.org"
|
||||
|
||||
##
|
||||
## Only clients in the server machine can register accounts
|
||||
##
|
||||
ip_access: trusted_network
|
||||
|
||||
##
|
||||
## Local c2s or remote s2s users cannot register accounts
|
||||
##
|
||||
## access_from: deny
|
||||
|
||||
access: register
|
||||
mod_roster: {}
|
||||
mod_shared_roster: {}
|
||||
mod_stats: {}
|
||||
mod_time: {}
|
||||
mod_vcard: {}
|
||||
mod_version: {}
|
||||
|
||||
##
|
||||
## Enable modules with custom options in a specific virtual host
|
||||
##
|
||||
## host_config:
|
||||
## "localhost":
|
||||
## modules:
|
||||
## mod_echo:
|
||||
## host: "mirror.localhost"
|
||||
|
||||
##
|
||||
## Enable modules management via ejabberdctl for installation and
|
||||
## uninstallation of public/private contributed modules
|
||||
## (enabled by default)
|
||||
##
|
||||
|
||||
allow_contrib_modules: true
|
||||
|
||||
### Local Variables:
|
||||
### mode: yaml
|
||||
### End:
|
||||
### vim: set filetype=yaml tabstop=8
|
||||
+14
-28
@@ -30,6 +30,7 @@ fi
|
||||
|
||||
AC_PATH_TOOL(ERL, erl, , [${extra_erl_path}$PATH])
|
||||
AC_PATH_TOOL(ERLC, erlc, , [${extra_erl_path}$PATH])
|
||||
AC_PATH_TOOL(EPMD, epmd, , [${extra_erl_path}$PATH])
|
||||
|
||||
AC_ERLANG_NEED_ERL
|
||||
AC_ERLANG_NEED_ERLC
|
||||
@@ -83,14 +84,6 @@ AC_ARG_ENABLE(roster_gateway_workaround,
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-roster-gateway-workaround) ;;
|
||||
esac],[roster_gateway_workaround=false])
|
||||
|
||||
AC_ARG_ENABLE(transient_supervisors,
|
||||
[AC_HELP_STRING([--disable-transient-supervisors], [disable Erlang supervision for transient processes (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=true])
|
||||
|
||||
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
|
||||
@@ -108,10 +101,10 @@ AC_ARG_ENABLE(mssql,
|
||||
esac],[db_type=generic])
|
||||
|
||||
AC_ARG_ENABLE(all,
|
||||
[AC_HELP_STRING([--enable-all], [same as --enable-nif --enable-odbc --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-riak --enable-redis --enable-elixir --enable-iconv --enable-debug --enable-lager --enable-tools (useful for Dialyzer checks, default: no)])],
|
||||
[AC_HELP_STRING([--enable-all], [same as --enable-odbc --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-riak --enable-redis --enable-elixir --enable-iconv --enable-debug --enable-tools (useful for Dialyzer checks, default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) nif=true odbc=true mysql=true pgsql=true sqlite=true pam=true zlib=true riak=true redis=true elixir=true iconv=true debug=true lager=true tools=true ;;
|
||||
no) nif=false odbc=false mysql=false pgsql=false sqlite=false pam=false zlib=false riak=false redis=false elixir=false iconv=false debug=false lager=false tools=false ;;
|
||||
yes) odbc=true mysql=true pgsql=true sqlite=true pam=true zlib=true riak=true redis=true elixir=true iconv=true debug=true tools=true ;;
|
||||
no) odbc=false mysql=false pgsql=false sqlite=false pam=false zlib=false riak=false redis=false elixir=false iconv=false debug=false tools=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
|
||||
esac],[])
|
||||
|
||||
@@ -123,14 +116,6 @@ AC_ARG_ENABLE(tools,
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-tools) ;;
|
||||
esac],[if test "x$tools" = "x"; then tools=false; fi])
|
||||
|
||||
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(odbc,
|
||||
[AC_HELP_STRING([--enable-odbc], [enable pure ODBC support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
@@ -219,13 +204,13 @@ AC_ARG_ENABLE(debug,
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
|
||||
esac],[if test "x$debug" = "x"; then debug=true; fi])
|
||||
|
||||
AC_ARG_ENABLE(lager,
|
||||
[AC_HELP_STRING([--enable-lager], [enable lager support (default: yes)])],
|
||||
AC_ARG_ENABLE(latest_deps,
|
||||
[AC_HELP_STRING([--enable-latest-deps], [makes rebar use latest commits for dependences instead of tagged versions (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) lager=true ;;
|
||||
no) lager=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-lager) ;;
|
||||
esac],[if test "x$lager" = "x"; then lager=true; fi])
|
||||
yes) latest_deps=true ;;
|
||||
no) latest_deps=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-latest-deps) ;;
|
||||
esac],[if test "x$latest_deps" = "x"; then latest_deps=false; fi])
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
vars.config
|
||||
@@ -256,9 +241,7 @@ fi
|
||||
|
||||
AC_SUBST(hipe)
|
||||
AC_SUBST(roster_gateway_workaround)
|
||||
AC_SUBST(transient_supervisors)
|
||||
AC_SUBST(full_xml)
|
||||
AC_SUBST(nif)
|
||||
AC_SUBST(db_type)
|
||||
AC_SUBST(odbc)
|
||||
AC_SUBST(mysql)
|
||||
@@ -271,7 +254,10 @@ AC_SUBST(redis)
|
||||
AC_SUBST(elixir)
|
||||
AC_SUBST(iconv)
|
||||
AC_SUBST(debug)
|
||||
AC_SUBST(lager)
|
||||
AC_SUBST(tools)
|
||||
AC_SUBST(latest_deps)
|
||||
AC_SUBST(CFLAGS)
|
||||
AC_SUBST(CPPFLAGS)
|
||||
AC_SUBST(LDFLAGS)
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -115,6 +115,12 @@ parse_form(Dir, File, Form, Used) ->
|
||||
{string, Line, Value}
|
||||
} ->
|
||||
ets:insert(vars, {Name, Value, Line});
|
||||
{match,
|
||||
_,
|
||||
{var, _, Name},
|
||||
{bin,Line,[{bin_element,_,{string,_,Value},_,_}]}
|
||||
} ->
|
||||
ets:insert(vars, {Name, Value, Line});
|
||||
L when is_list(L) ->
|
||||
lists:foreach(
|
||||
fun(F) ->
|
||||
@@ -236,9 +242,7 @@ print_usage() ->
|
||||
print_po_header(File) ->
|
||||
MsgProps = get_msg_header_props(File),
|
||||
{Language, [LastT | AddT]} = prepare_props(MsgProps),
|
||||
application:load(ejabberd),
|
||||
{ok, Version} = application:get_key(ejabberd, vsn),
|
||||
print_po_header(Version, Language, LastT, AddT).
|
||||
print_po_header(Language, LastT, AddT).
|
||||
|
||||
get_msg_header_props(File) ->
|
||||
{ok, F} = file:open(File, [read]),
|
||||
@@ -268,12 +272,11 @@ prepare_props(MsgProps) ->
|
||||
Authors = proplists:get_all_values("Author:", MsgProps),
|
||||
{Language, Authors}.
|
||||
|
||||
print_po_header(Version, Language, LastTranslator, AdditionalTranslatorsList) ->
|
||||
print_po_header(Language, LastTranslator, AdditionalTranslatorsList) ->
|
||||
AdditionalTranslatorsString = build_additional_translators(AdditionalTranslatorsList),
|
||||
HeaderString =
|
||||
"msgid \"\"\n"
|
||||
"msgstr \"\"\n"
|
||||
"\"Project-Id-Version: " ++ Version ++ "\\n\"\n"
|
||||
++ "\"X-Language: " ++ Language ++ "\\n\"\n"
|
||||
"\"Last-Translator: " ++ LastTranslator ++ "\\n\"\n"
|
||||
++ AdditionalTranslatorsString ++
|
||||
|
||||
@@ -157,7 +157,7 @@ extract_lang_srcmsg2po ()
|
||||
echo $MSGS_PATH
|
||||
|
||||
cd $SRC_DIR
|
||||
$ERL -pa $EXTRACT_DIR -pa $EBIN_DIR -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$PO_PATH.1
|
||||
$ERL -pa $EXTRACT_DIR -pa $EBIN_DIR -pa $EJA_SRC_DIR -pa ../include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$PO_PATH.1
|
||||
sed -e 's/ \[\]$/ \"\"/g;' $PO_PATH.1 > $PO_PATH.2
|
||||
msguniq --sort-by-file $PO_PATH.2 --output-file=$PO_PATH
|
||||
|
||||
@@ -176,7 +176,7 @@ extract_lang_src2pot ()
|
||||
echo "" >>$MSGS_PATH
|
||||
|
||||
cd $SRC_DIR
|
||||
$ERL -pa $EXTRACT_DIR -pa $EBIN_DIR -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$POT_PATH.1
|
||||
$ERL -pa $EXTRACT_DIR -pa $EBIN_DIR -pa $EJA_SRC_DIR -pa ../include -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$POT_PATH.1
|
||||
sed -e 's/ \[\]$/ \"\"/g;' $POT_PATH.1 > $POT_PATH.2
|
||||
|
||||
#msguniq --sort-by-file $POT_PATH.2 $EJA_MSGS_DIR --output-file=$POT_PATH
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{level, details}.
|
||||
{incl_dirs, ["src", "ebin"]}.
|
||||
{excl_mods, [eldap, 'ELDAPv3']}.
|
||||
{export, "logs/all.coverdata"}.
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
ejabberd container
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Usage](#usage)
|
||||
- [Persistence](#persistence)
|
||||
- [SSL Certificates](#ssl-certificates)
|
||||
- [Base Image](#base-image)
|
||||
- [Ejabberd Configuration](#ejabberd-configuration)
|
||||
- [Served Hostnames](#served-hostnames)
|
||||
- [Authentication](#authentication)
|
||||
- [Admins](#admins)
|
||||
- [Users](#users)
|
||||
- [SSL](#ssl)
|
||||
- [Modules](#modules)
|
||||
- [Logging](#logging)
|
||||
- [Mount Configurations](#mount-configurations)
|
||||
- [Erlang Configuration](#erlang-configuration)
|
||||
- [Maintenance](#maintenance)
|
||||
- [Register Users](#register-users)
|
||||
- [Creating Backups](#creating-backups)
|
||||
- [Restoring Backups](#restoring-backups)
|
||||
- [Debug](#debug)
|
||||
- [Erlang Shell](#erlang-shell)
|
||||
- [System Shell](#system-shell)
|
||||
- [System Commands](#system-commands)
|
||||
- [Exposed Ports](#exposed-ports)
|
||||
|
||||
# Introduction
|
||||
|
||||
Dockerfile to build an [ejabberd](https://www.ejabberd.im/) container image.
|
||||
|
||||
Docker Tag Names are based on ejabberd versions in git [tags][]. The image tag `:latest` is based on the master branch.
|
||||
|
||||
[tags]: https://github.com/rroemhild/ejabberd/tags
|
||||
|
||||
# Quick Start
|
||||
|
||||
You can start of with the following container:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name "ejabberd" \
|
||||
-p 5222:5222 \
|
||||
-p 5269:5269 \
|
||||
-p 5280:5280 \
|
||||
-h 'xmpp.example.de' \
|
||||
-e "XMPP_DOMAIN=example.de" \
|
||||
-e "ERLANG_NODE=nodename" \
|
||||
-e "EJABBERD_ADMINS=admin@example.de admin2@example.de" \
|
||||
-e "EJABBERD_USERS=admin@example.de:password1234 admin2@example.de" \
|
||||
-e "TZ=Europe/Berlin" \
|
||||
rroemhild/ejabberd
|
||||
```
|
||||
|
||||
# Usage
|
||||
|
||||
## Persistence
|
||||
|
||||
For storage of the application data, you can mount volumes at
|
||||
|
||||
* `/opt/ejabberd/ssl`
|
||||
* `/opt/ejabberd/backup`
|
||||
* `/opt/ejabberd/upload`
|
||||
* `/opt/ejabberd/database`
|
||||
|
||||
or use a data container
|
||||
|
||||
```bash
|
||||
docker create --name ejabberd-data rroemhild/ejabberd-data
|
||||
docker run -d --name ejabberd --volumes-from processone-data rroemhild/ejabberd
|
||||
```
|
||||
|
||||
## SSL Certificates
|
||||
|
||||
TLS is enabled by default and the run script will auto-generate two snake-oil certificates during boot if you don't provide your SSL certificates.
|
||||
|
||||
To use your own certificates, there are two options.
|
||||
|
||||
1. Mount the volume `/opt/ejabberd/ssl` to a local directory with the `.pem` files:
|
||||
|
||||
* /tmp/ssl/host.pem (SERVER_HOSTNAME)
|
||||
* /tmp/ssl/xmpp_domain.pem (XMPP_DOMAIN)
|
||||
|
||||
Make sure that the certificate and private key are in one `.pem` file. If one file is missing it will be auto-generated. I.e. you can provide your certificate for your **XMMP_DOMAIN** and use a snake-oil certificate for the `SERVER_HOSTNAME`.
|
||||
|
||||
2. Specify the certificates via environment variables: **EJABBERD_SSLCERT_HOST** and **EJABBERD_SSLCERT_EXAMPLE_COM**. For the
|
||||
domain certificates, make sure you match the domain names given in **XMPP_DOMAIN** and replace dots and dashes with underscore.
|
||||
|
||||
## Base Image
|
||||
|
||||
Build your own ejabberd container image and add your config templates, certificates or [extend](#cluster-example) it for your needs.
|
||||
|
||||
```
|
||||
FROM rroemhild/ejabberd
|
||||
ADD ./ejabberd.yml.tpl /opt/ejabberd/conf/ejabberd.yml.tpl
|
||||
ADD ./ejabberdctl.cfg.tpl /opt/ejabberd/conf/ejabberdctl.cfg.tpl
|
||||
ADD ./example.com.pem /opt/ejabberd/ssl/example.com.pem
|
||||
```
|
||||
|
||||
If you need root privileges switch to `USER root` and go back to `USER ejabberd` when you're done.
|
||||
|
||||
# Ejabberd Configuration
|
||||
|
||||
You can additionally provide extra runtime configuration in a downstream image by replacing the config template `ejabberd.yml.tpl` with one based on this image's template and include extra interpolation of environment variables. The template is parsed by Jinja2 with the runtime environment (equivalent to Python's `os.environ` available as `env`).
|
||||
|
||||
## Served Hostnames
|
||||
|
||||
By default the container will serve the XMPP domain `localhost`. In order to serve a different domain at runtime, provide the **XMPP_DOMAIN** variable with a domain name. You can add more domains separated with whitespace.
|
||||
|
||||
```
|
||||
XMPP_DOMAIN=example.ninja xyz.io test.com
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
Authentication methods can be set with the **EJABBERD_AUTH_METHOD** environment variable. The default authentication mode is `internal`.
|
||||
|
||||
Supported authentication methods:
|
||||
|
||||
* anonymous
|
||||
* internal
|
||||
* external
|
||||
* ldap
|
||||
|
||||
Internal and anonymous authentication example:
|
||||
|
||||
```
|
||||
EJABBERD_AUTH_METHOD=internal anonymous
|
||||
```
|
||||
|
||||
[External authentication](http://docs.ejabberd.im/admin/guide/configuration/#external-script) example:
|
||||
```
|
||||
EJABBERD_AUTH_METHOD=external
|
||||
EJABBERD_EXTAUTH_PROGRAM="/opt/ejabberd/scripts/authenticate-user.sh"
|
||||
EJABBERD_EXTAUTH_INSTANCES=3
|
||||
EJABBERD_EXTAUTH_CACHE=600
|
||||
```
|
||||
**EJABBERD_EXTAUTH_INSTANCES** must be an integer with a minimum value of 1. **EJABBERD_EXTAUTH_CACHE** can be set to "false" or an integer value representing cache time in seconds. Note that caching should not be enabled if internal auth is also enabled.
|
||||
|
||||
### MySQL Authentication
|
||||
|
||||
Set `EJABBERD_AUTH_METHOD=external` and `EJABBERD_EXTAUTH_PROGRAM=/opt/ejabberd/scripts/lib/auth_mysql.py` to enable MySQL authentication. Use the following environment variables to configure the database connection and the layout of the database. Password changing, registration, and unregistration are optional features and are enabled only if the respective queries are provided.
|
||||
|
||||
- **AUTH_MYSQL_HOST**: The MySQL host
|
||||
- **AUTH_MYSQL_USER**: Username to connect to the MySQL host
|
||||
- **AUTH_MYSQL_PASSWORD**: Password to connect to the MySQL host
|
||||
- **AUTH_MYSQL_DATABASE**: Database name where to find the user information
|
||||
- **AUTH_MYSQL_HASHALG**: Format of the password in the database. Default is cleartext. Options are `crypt`, `md5`, `sha1`, `sha224`, `sha256`, `sha384`, `sha512`. `crypt` is recommended, as it is salted. When setting the password, `crypt` uses SHA-512 (prefix `$6$`).
|
||||
- **AUTH_MYSQL_QUERY_GETPASS**: Get the password for a user. Use the placeholders `%(user)s`, `%(host)s`. Example: `SELECT password FROM users WHERE username = CONCAT(%(user)s, '@', %(host)s)`
|
||||
- **AUTH_MYSQL_QUERY_SETPASS**: Update the password for a user. Leave empty to disable. Placeholder `%(password)s` contains the hashed password. Example: `UPDATE users SET password = %(password)s WHERE username = CONCAT(%(user)s, '@', %(host)s)`
|
||||
- **AUTH_MYSQL_QUERY_REGISTER**: Register a new user. Leave empty to disable. Example: `INSERT INTO users ( username, password ) VALUES ( CONCAT(%(user)s, '@', %(host)s), %(password)s )`
|
||||
- **AUTH_MYSQL_QUERY_UNREGISTER**: Removes a user. Leave empty to disable. Example: `DELETE FROM users WHERE username = CONCAT(%(user)s, '@', %(host)s)`
|
||||
|
||||
Note that the MySQL authentication script writes a debug log into the file `/var/log/ejabberd/extauth.log`. To get its content, execute the following command:
|
||||
|
||||
```bash
|
||||
docker exec -ti ejabberd tail -n50 -f /var/log/ejabberd/extauth.log
|
||||
```
|
||||
|
||||
To find out more about the mysql authentication script, check out the [ejabberd-auth-mysql](https://github.com/rankenstein/ejabberd-auth-mysql) repository.
|
||||
|
||||
### LDAP Auth
|
||||
|
||||
Full documentation http://docs.ejabberd.im/admin/guide/configuration/#ldap.
|
||||
|
||||
Connection
|
||||
|
||||
- **EJABBERD_LDAP_SERVERS**: List of IP addresses or DNS names of your LDAP servers. This option is required.
|
||||
- **EJABBERD_LDAP_ENCRYPT**: The value `tls` enables encryption by using LDAP over SSL. The default value is: `none`.
|
||||
- **EJABBERD_LDAP_TLS_VERIFY**: `false|soft|hard` This option specifies whether to verify LDAP server certificate or not when TLS is enabled. The default is `false` which means no checks are performed.
|
||||
- **EJABBERD_LDAP_TLS_CACERTFILE**: Path to file containing PEM encoded CA certificates.
|
||||
- **EJABBERD_LDAP_TLS_DEPTH**: Specifies the maximum verification depth when TLS verification is enabled. The default value is 1.
|
||||
- **EJABBERD_LDAP_PORT**: The default port is `389` if encryption is disabled; and `636` if encryption is enabled.
|
||||
- **EJABBERD_LDAP_ROOTDN**: Bind DN. The default value is "" which means ‘anonymous connection’.
|
||||
- **EJABBERD_LDAP_PASSWORD**: Bind password. The default value is "".
|
||||
- **EJABBERD_LDAP_DEREF_ALIASES**: `never|always|finding|searching`
|
||||
Whether or not to dereference aliases. The default is `never`.
|
||||
|
||||
Authentication
|
||||
|
||||
- **EJABBERD_LDAP_BASE**: LDAP base directory which stores users accounts. This option is required.
|
||||
- **EJABBERD_LDAP_UIDS**: `ldap_uidattr:ldap_uidattr_format` The default attributes are `uid:%u`.
|
||||
- **EJABBERD_LDAP_FILTER**: RFC 4515 LDAP filter. The default Filter value is undefined.
|
||||
- **EJABBERD_LDAP_DN_FILTER**: `{ Filter: FilterAttrs }` This filter is applied on the results returned by the main filter. By default ldap_dn_filter is undefined.
|
||||
|
||||
## Admins
|
||||
|
||||
Set one or more admin user (seperated by whitespace) with the **EJABBERD_ADMINS** environment variable. You can register admin users with the **EJABBERD_USERS** environment variable during container startup, use you favorite XMPP client or the `ejabberdctl` command line utility.
|
||||
|
||||
```
|
||||
EJABBERD_ADMINS=admin@example.ninja
|
||||
```
|
||||
|
||||
## Users
|
||||
|
||||
Automatically register users during container startup. Uses random password if you don't provide a password for the user. Format is `JID:PASSWORD`. Register more users separated with whitespace.
|
||||
|
||||
Register the admin user from **EJABBERD_ADMINS** with a give password:
|
||||
|
||||
```
|
||||
EJABBERD_USERS=admin@example.ninja:password1234
|
||||
```
|
||||
|
||||
Or without a random password printed to stdout (check container logs):
|
||||
|
||||
```
|
||||
EJABBERD_USERS=admin@example.ninja
|
||||
```
|
||||
|
||||
Register more than one user:
|
||||
|
||||
```
|
||||
EJABBERD_USERS=admin@example.ninja:password1234 user1@test.com user1@xyz.io
|
||||
```
|
||||
|
||||
## SSL
|
||||
|
||||
- **EJABBERD_SSLCERT_HOST**: SSL Certificate for the hostname.
|
||||
- **EJABBERD_SSLCERT_EXAMPLE_COM**: SSL Certificates for XMPP domains.
|
||||
- **EJABBERD_STARTTLS**: Set to `false` to disable StartTLS for client to server connections. Default: `true`.
|
||||
- **EJABBERD_S2S_SSL**: Set to `false` to disable SSL in server 2 server connections. Default: `true`.
|
||||
- **EJABBERD_HTTPS**: If your proxy terminates SSL you may want to disable HTTPS on port 5280 and 5443. Default: `true`.
|
||||
- **EJABBERD_PROTOCOL_OPTIONS_TLSV1**: Allow TLSv1 protocol. Default: `false`.
|
||||
- **EJABBERD_PROTOCOL_OPTIONS_TLSV1_1**: Allow TLSv1.1 protocol. Default: `true`.
|
||||
- **EJABBERD_CIPHERS**: Cipher suite. Default: `HIGH:!aNULL:!3DES`.
|
||||
- **EJABBERD_DHPARAM**: Set to `true` to use or generate custom DH parameters. Default: `false`.
|
||||
|
||||
## Modules
|
||||
|
||||
- **EJABBERD_SKIP_MODULES_UPDATE**: If you do not need to update ejabberd modules specs, skip the update task and speedup start. Default: `false`.
|
||||
- **EJABBERD_MOD_MUC_ADMIN**: Activate the mod_muc_admin module. Default: `false`.
|
||||
- **EJABBERD_MOD_ADMIN_EXTRA**: Activate the mod_muc_admin module. Default: `true`.
|
||||
- **EJABBERD_REGISTER_TRUSTED_NETWORK_ONLY**: Only allow user registration from the trusted_network access rule. Default: `true`.
|
||||
- **EJABBERD_MOD_VERSION**: Activate the mod_version module. Default: `true`.
|
||||
|
||||
## Logging
|
||||
|
||||
Use the **EJABBERD_LOGLEVEL** environment variable to set verbosity. Default: `4` (Info).
|
||||
|
||||
```
|
||||
loglevel: Verbosity of log files generated by ejabberd.
|
||||
0: No ejabberd log at all (not recommended)
|
||||
1: Critical
|
||||
2: Error
|
||||
3: Warning
|
||||
4: Info
|
||||
5: Debug
|
||||
```
|
||||
|
||||
## Mount Configurations
|
||||
|
||||
If you prefer to use your own configuration files and avoid passing docker environment variables (```-e```), you can do so by mounting a host directory.
|
||||
Pass in an additional ```-v``` to the ```docker run``` command, like so:
|
||||
```
|
||||
docker run -d \
|
||||
--name "ejabberd" \
|
||||
-p 5222:5222 \
|
||||
-p 5269:5269 \
|
||||
-p 5280:5280 \
|
||||
-h 'xmpp.example.de' \
|
||||
-v /<host_path>/conf:/opt/ejabberd/conf \
|
||||
rroemhild/ejabberd
|
||||
```
|
||||
|
||||
Your ```/<host_path>/conf``` folder should look like so:
|
||||
|
||||
```
|
||||
/<host_path>/conf/
|
||||
├── ejabberdctl.cfg
|
||||
├── ejabberd.yml
|
||||
└── inetrc
|
||||
```
|
||||
|
||||
Example configuration files can be downloaded from the ejabberd [github](https://github.com/rroemhild/ejabberd) page.
|
||||
|
||||
When these files exist in ```/opt/ejabberd/conf```, the run script will ignore the configuration templates.
|
||||
|
||||
## Erlang Configuration
|
||||
|
||||
With the following environment variables you can configure options that are passed by ejabberdctl to the erlang runtime system when starting ejabberd.
|
||||
|
||||
- **POLL**: Set to `false` to disable Kernel polling. Default: `true`.
|
||||
- **SMP**: SMP support `enable`, `auto`, `disable`. Default: `auto`.
|
||||
- **ERL_MAX_PORTS**: Maximum number of simultaneously open Erlang ports. Default: `32000`.
|
||||
- **FIREWALL_WINDOW**: Range of allowed ports to pass through a firewall. Default: `not defined`.
|
||||
- **INET_DIST_INTERFACE**: IP address where this Erlang node listens other nodes. Default: `0.0.0.0`.
|
||||
- **ERL_EPMD_ADDRESS**: IP addresses where epmd listens for connections. Default: `0.0.0.0`.
|
||||
- **ERL_PROCESSES**: Maximum number of Erlang processes. Default: `250000`.
|
||||
- **ERL_MAX_ETS_TABLES**: Maximum number of Erlang processes. Default: `1400`.
|
||||
- **ERLANG_OPTIONS**: Overwrite additional options passed to erlang while starting ejabberd. Default: `-noshell`
|
||||
- **ERLANG_NODE**: Allows to explicitly specify erlang node for ejabberd. Set to `nodename` lets erlang add the hostname. Default: `ejabberd@localhost`.
|
||||
- **EJABBERD_CONFIG_PATH**: ejabberd configuration file. Default: `/opt/ejabberd/conf/ejabberd.yml`.
|
||||
- **CONTRIB_MODULES_PATH**: contributed ejabberd modules path. Default: `/opt/ejabberd/modules`.
|
||||
- **CONTRIB_MODULES_CONF_DIR**: configuration directory for contributed modules. Default: `/opt/ejabberd/modules/conf`.
|
||||
- **ERLANG_COOKIE**: Set erlang cookie. Default is to auto-generated cookie.
|
||||
|
||||
# Maintenance
|
||||
|
||||
The `ejabberdctl` command is in the search path and can be run by:
|
||||
|
||||
```bash
|
||||
docker exec CONTAINER ejabberdctl help
|
||||
```
|
||||
|
||||
## Register Users
|
||||
|
||||
```bash
|
||||
docker exec CONTAINER ejabberdctl register user XMPP_DOMAIN PASSWORD
|
||||
```
|
||||
|
||||
## Creating Backups
|
||||
|
||||
Create a backupfile with ejabberdctl and copy the file from the container to localhost
|
||||
|
||||
```bash
|
||||
docker exec CONTAINER ejabberdctl backup /opt/ejabberd/backup/ejabberd.backup
|
||||
docker cp CONTAINER:/opt/ejabberd/backup/ejabberd.backup /tmp/ejabberd.backup
|
||||
```
|
||||
|
||||
## Restoring Backups
|
||||
|
||||
Copy the backupfile from localhost to the running container and restore with ejabberdctl
|
||||
|
||||
```bash
|
||||
docker cp /tmp/ejabberd.backup CONTAINER:/opt/ejabberd/backup/ejabberd.backup
|
||||
docker exec CONTAINER ejabberdctl restore /opt/ejabberd/backup/ejabberd.backup
|
||||
```
|
||||
|
||||
# Debug
|
||||
|
||||
## Erlang Shell
|
||||
|
||||
Set `-i` and `-t` option and append `live` to get an interactive erlang shell:
|
||||
|
||||
```bash
|
||||
docker run -i -t -P rroemhild/ejabberd live
|
||||
```
|
||||
|
||||
You can terminate the erlang shell with `q().`.
|
||||
|
||||
## System Shell
|
||||
|
||||
```bash
|
||||
docker run -i -t rroemhild/ejabberd shell
|
||||
```
|
||||
|
||||
## System Commands
|
||||
|
||||
```bash
|
||||
docker run -i -t rroemhild/ejabberd env
|
||||
```
|
||||
|
||||
# Exposed Ports
|
||||
|
||||
* 4560 (XMLRPC)
|
||||
* 5222 (Client 2 Server)
|
||||
* 5269 (Server 2 Server)
|
||||
* 5280 (HTTP admin/websocket/http-bind)
|
||||
* 5443 (HTTP Upload)
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
export DEBIAN_FRONTEND="noninteractive"
|
||||
|
||||
readonly buildDeps='
|
||||
git-core
|
||||
build-essential
|
||||
automake
|
||||
libssl-dev
|
||||
zlib1g-dev
|
||||
libexpat-dev
|
||||
libyaml-dev
|
||||
libsqlite3-dev
|
||||
erlang-src erlang-dev'
|
||||
|
||||
readonly requiredAptPackages='
|
||||
locales
|
||||
ldnsutils
|
||||
python2.7
|
||||
python-jinja2
|
||||
ca-certificates
|
||||
libyaml-0-2
|
||||
erlang-base erlang-snmp erlang-ssl erlang-ssh erlang-webtool
|
||||
erlang-tools erlang-xmerl erlang-corba erlang-diameter erlang-eldap
|
||||
erlang-eunit erlang-ic erlang-odbc erlang-os-mon
|
||||
erlang-parsetools erlang-percept erlang-typer
|
||||
python-mysqldb
|
||||
imagemagick'
|
||||
|
||||
apt-key adv \
|
||||
--keyserver keys.gnupg.net \
|
||||
--recv-keys 434975BD900CCBE4F7EE1B1ED208507CA14F4FCA
|
||||
|
||||
apt-get update
|
||||
apt-get install -y $buildDeps $requiredAptPackages --no-install-recommends
|
||||
dpkg-reconfigure locales && locale-gen C.UTF-8
|
||||
/usr/sbin/update-locale LANG=C.UTF-8
|
||||
echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen
|
||||
locale-gen
|
||||
|
||||
# add ejabberd user
|
||||
useradd --home $EJABBERD_HOME -M --system ejabberd
|
||||
mkdir $EJABBERD_HOME
|
||||
|
||||
cd /tmp/ejabberd
|
||||
chmod +x ./autogen.sh
|
||||
./autogen.sh
|
||||
./configure --enable-user=ejabberd \
|
||||
--enable-all \
|
||||
--disable-tools \
|
||||
--disable-pam
|
||||
|
||||
make debug=$EJABBERD_DEBUG_MODE
|
||||
make install
|
||||
|
||||
cd $EJABBERD_HOME
|
||||
mkdir -p logs ssl backup upload module_source modules/conf
|
||||
mv /tmp/ejabberd/docker $EJABBERD_HOME
|
||||
|
||||
# Move config to homedir
|
||||
mv /etc/ejabberd conf
|
||||
ln -s $EJABBERD_HOME/conf /etc/ejabberd
|
||||
|
||||
# rename original configs
|
||||
mv conf/ejabberd.yml conf/ejabberd.yml.orig
|
||||
mv conf/ejabberdctl.cfg conf/ejabberdctl.cfg.orig
|
||||
|
||||
# clean up
|
||||
rm -rf /tmp/ejabberd
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
apt-get purge -y --auto-remove $buildDeps
|
||||
|
||||
# change owner for ejabberd home
|
||||
chown -R ejabberd $EJABBERD_HOME
|
||||
@@ -0,0 +1,434 @@
|
||||
###
|
||||
### ejabberd configuration file
|
||||
###
|
||||
###
|
||||
|
||||
### The parameters used in this configuration file are explained in more detail
|
||||
### in the ejabberd Installation and Operation Guide.
|
||||
### Please consult the Guide in case of doubts, it is included with
|
||||
### your copy of ejabberd, and is also available online at
|
||||
### http://www.process-one.net/en/ejabberd/docs/
|
||||
|
||||
### =======
|
||||
### LOGGING
|
||||
|
||||
loglevel: {{ env['EJABBERD_LOGLEVEL'] or 4 }}
|
||||
log_rotate_size: 10485760
|
||||
log_rotate_count: 0
|
||||
log_rate_limit: 100
|
||||
|
||||
## watchdog_admins:
|
||||
## - "bob@example.com"
|
||||
|
||||
### ================
|
||||
### SERVED HOSTNAMES
|
||||
|
||||
hosts:
|
||||
{%- for xmpp_domain in env['XMPP_DOMAIN'].split() %}
|
||||
- "{{ xmpp_domain }}"
|
||||
{%- endfor %}
|
||||
|
||||
##
|
||||
## route_subdomains: Delegate subdomains to other XMPP servers.
|
||||
## For example, if this ejabberd serves example.org and you want
|
||||
## to allow communication with an XMPP server called im.example.org.
|
||||
##
|
||||
## route_subdomains: s2s
|
||||
|
||||
### ===============
|
||||
### LISTENING PORTS
|
||||
|
||||
listen:
|
||||
-
|
||||
port: 5222
|
||||
module: ejabberd_c2s
|
||||
{%- if env['EJABBERD_STARTTLS'] == "true" %}
|
||||
starttls_required: true
|
||||
{%- endif %}
|
||||
protocol_options:
|
||||
- "no_sslv3"
|
||||
{%- if env.get('EJABBERD_PROTOCOL_OPTIONS_TLSV1', "false") == "false" %}
|
||||
- "no_tlsv1"
|
||||
{%- endif %}
|
||||
{%- if env.get('EJABBERD_PROTOCOL_OPTIONS_TLSV1_1', "true") == "false" %}
|
||||
- "no_tlsv1_1"
|
||||
{%- endif %}
|
||||
max_stanza_size: 65536
|
||||
shaper: c2s_shaper
|
||||
access: c2s
|
||||
ciphers: "{{ env.get('EJABBERD_CIPHERS', 'HIGH:!aNULL:!3DES') }}"
|
||||
{%- if env.get('EJABBERD_DHPARAM', false) == "true" %}
|
||||
dhfile: "/opt/ejabberd/ssl/dh.pem"
|
||||
{%- endif %}
|
||||
-
|
||||
port: 5269
|
||||
module: ejabberd_s2s_in
|
||||
-
|
||||
port: 4560
|
||||
module: ejabberd_xmlrpc
|
||||
access_commands:
|
||||
configure:
|
||||
all: []
|
||||
|
||||
-
|
||||
port: 5280
|
||||
module: ejabberd_http
|
||||
request_handlers:
|
||||
"/websocket": ejabberd_http_ws
|
||||
## "/pub/archive": mod_http_fileserver
|
||||
web_admin: true
|
||||
http_bind: true
|
||||
## register: true
|
||||
captcha: true
|
||||
{%- if env['EJABBERD_HTTPS'] == "true" %}
|
||||
tls: true
|
||||
certfile: "/opt/ejabberd/ssl/host.pem"
|
||||
{% endif %}
|
||||
-
|
||||
port: 5443
|
||||
module: ejabberd_http
|
||||
request_handlers:
|
||||
"": mod_http_upload
|
||||
{%- if env['EJABBERD_HTTPS'] == "true" %}
|
||||
tls: true
|
||||
certfile: "/opt/ejabberd/ssl/host.pem"
|
||||
{% endif %}
|
||||
|
||||
|
||||
### SERVER TO SERVER
|
||||
### ================
|
||||
|
||||
{%- if env['EJABBERD_S2S_SSL'] == "true" %}
|
||||
s2s_use_starttls: required
|
||||
s2s_certfile: "/opt/ejabberd/ssl/host.pem"
|
||||
s2s_protocol_options:
|
||||
- "no_sslv3"
|
||||
{%- if env.get('EJABBERD_PROTOCOL_OPTIONS_TLSV1', "false") == "false" %}
|
||||
- "no_tlsv1"
|
||||
{%- endif %}
|
||||
{%- if env.get('EJABBERD_PROTOCOL_OPTIONS_TLSV1_1', "true") == "false" %}
|
||||
- "no_tlsv1_1"
|
||||
{%- endif %}
|
||||
s2s_ciphers: "{{ env.get('EJABBERD_CIPHERS', 'HIGH:!aNULL:!3DES') }}"
|
||||
{%- if env.get('EJABBERD_DHPARAM', false) == "true" %}
|
||||
s2s_dhfile: "/opt/ejabberd/ssl/dh.pem"
|
||||
{%- endif %}
|
||||
{% endif %}
|
||||
|
||||
### ==============
|
||||
### AUTHENTICATION
|
||||
|
||||
auth_method:
|
||||
{%- for auth_method in env.get('EJABBERD_AUTH_METHOD', 'internal').split() %}
|
||||
- {{ auth_method }}
|
||||
{%- endfor %}
|
||||
|
||||
{%- if 'anonymous' in env.get('EJABBERD_AUTH_METHOD', 'internal').split() %}
|
||||
anonymous_protocol: login_anon
|
||||
allow_multiple_connections: true
|
||||
{%- endif %}
|
||||
|
||||
|
||||
## LDAP authentication
|
||||
|
||||
{%- if 'ldap' in env.get('EJABBERD_AUTH_METHOD', 'internal').split() %}
|
||||
|
||||
ldap_servers:
|
||||
{%- for ldap_server in env.get('EJABBERD_LDAP_SERVERS', 'internal').split() %}
|
||||
- "{{ ldap_server }}"
|
||||
{%- endfor %}
|
||||
|
||||
ldap_encrypt: {{ env.get('EJABBERD_LDAP_ENCRYPT', 'none') }}
|
||||
ldap_tls_verify: {{ env.get('EJABBERD_LDAP_TLS_VERIFY', 'false') }}
|
||||
|
||||
{%- if env['EJABBERD_LDAP_TLS_CACERTFILE'] %}
|
||||
ldap_tls_cacertfile: "{{ env['EJABBERD_LDAP_TLS_CACERTFILE'] }}"
|
||||
{%- endif %}
|
||||
|
||||
ldap_tls_depth: {{ env.get('EJABBERD_LDAP_TLS_DEPTH', 1) }}
|
||||
|
||||
{%- if env['EJABBERD_LDAP_PORT'] %}
|
||||
ldap_port: {{ env['EJABBERD_LDAP_PORT'] }}
|
||||
{%- endif %}
|
||||
|
||||
{%- if env['EJABBERD_LDAP_ROOTDN'] %}
|
||||
ldap_rootdn: "{{ env['EJABBERD_LDAP_ROOTDN'] }}"
|
||||
{%- endif %}
|
||||
|
||||
{%- if env['EJABBERD_LDAP_PASSWORD'] %}
|
||||
ldap_password: "{{ env['EJABBERD_LDAP_PASSWORD'] }}"
|
||||
{%- endif %}
|
||||
|
||||
ldap_deref_aliases: {{ env.get('EJABBERD_LDAP_DEREF_ALIASES', 'never') }}
|
||||
ldap_base: "{{ env['EJABBERD_LDAP_BASE'] }}"
|
||||
|
||||
{%- if env['EJABBERD_LDAP_UIDS'] %}
|
||||
ldap_uids:
|
||||
{%- for ldap_uid in env['EJABBERD_LDAP_UIDS'].split() %}
|
||||
"{{ ldap_uid.split(':')[0] }}": "{{ ldap_uid.split(':')[1] }}"
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
|
||||
{%- if env['EJABBERD_LDAP_FILTER'] %}
|
||||
ldap_filter: "{{ env['EJABBERD_LDAP_FILTER'] }}"
|
||||
{%- endif %}
|
||||
|
||||
{%- if env['EJABBERD_LDAP_DN_FILTER'] %}
|
||||
ldap_dn_filter:
|
||||
{%- for dn_filter in env['EJABBERD_LDAP_DN_FILTER'].split() %}
|
||||
"{{ dn_filter.split(':')[0] }}": ["{{ dn_filter.split(':')[1] }}"]
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
|
||||
{%- endif %}
|
||||
|
||||
{%- if 'external' in env.get('EJABBERD_AUTH_METHOD', 'internal').split() %}
|
||||
{%- if env['EJABBERD_EXTAUTH_PROGRAM'] %}
|
||||
extauth_program: "{{ env['EJABBERD_EXTAUTH_PROGRAM'] }}"
|
||||
{%- endif %}
|
||||
{%- if env['EJABBERD_EXTAUTH_INSTANCES'] %}
|
||||
extauth_instances: {{ env['EJABBERD_EXTAUTH_INSTANCES'] }}
|
||||
{%- endif %}
|
||||
{%- if 'internal' in env.get('EJABBERD_AUTH_METHOD').split() %}
|
||||
extauth_cache: false
|
||||
{%- elif env['EJABBERD_EXTAUTH_CACHE'] %}
|
||||
extauth_cache: {{ env['EJABBERD_EXTAUTH_CACHE'] }}
|
||||
{%- endif %}
|
||||
{% endif %}
|
||||
|
||||
### ===============
|
||||
### TRAFFIC SHAPERS
|
||||
|
||||
shaper:
|
||||
normal: 1000
|
||||
fast: 50000
|
||||
max_fsm_queue: 1000
|
||||
|
||||
### ====================
|
||||
### ACCESS CONTROL LISTS
|
||||
|
||||
acl:
|
||||
admin:
|
||||
user:
|
||||
{%- if env['EJABBERD_ADMINS'] %}
|
||||
{%- for admin in env['EJABBERD_ADMINS'].split() %}
|
||||
- "{{ admin.split('@')[0] }}": "{{ admin.split('@')[1] }}"
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
- "admin": "{{ env['XMPP_DOMAIN'].split()[0] }}"
|
||||
{%- endif %}
|
||||
local:
|
||||
user_regexp: ""
|
||||
|
||||
### ============
|
||||
### ACCESS RULES
|
||||
|
||||
access:
|
||||
## Maximum number of simultaneous sessions allowed for a single user:
|
||||
max_user_sessions:
|
||||
all: 10
|
||||
## Maximum number of offline messages that users can have:
|
||||
max_user_offline_messages:
|
||||
admin: 5000
|
||||
all: 100
|
||||
## This rule allows access only for local users:
|
||||
local:
|
||||
local: allow
|
||||
## Only non-blocked users can use c2s connections:
|
||||
c2s:
|
||||
blocked: deny
|
||||
all: allow
|
||||
## For C2S connections, all users except admins use the "normal" shaper
|
||||
c2s_shaper:
|
||||
admin: none
|
||||
all: normal
|
||||
## All S2S connections use the "fast" shaper
|
||||
s2s_shaper:
|
||||
all: fast
|
||||
## Only admins can send announcement messages:
|
||||
announce:
|
||||
admin: allow
|
||||
## Only admins can use the configuration interface:
|
||||
configure:
|
||||
admin: allow
|
||||
## Admins of this server are also admins of the MUC service:
|
||||
muc_admin:
|
||||
admin: allow
|
||||
## Only accounts of the local ejabberd server, or only admins can create rooms, depending on environment variable:
|
||||
muc_create:
|
||||
{%- if env['EJABBERD_MUC_CREATE_ADMIN_ONLY'] == "true" %}
|
||||
admin: allow
|
||||
{% else %}
|
||||
local: allow
|
||||
{% endif %}
|
||||
## All users are allowed to use the MUC service:
|
||||
muc:
|
||||
all: allow
|
||||
## Only accounts on the local ejabberd server can create Pubsub nodes:
|
||||
pubsub_createnode:
|
||||
local: allow
|
||||
## In-band registration allows registration of any possible username.
|
||||
register:
|
||||
{%- if env['EJABBERD_REGISTER_ADMIN_ONLY'] == "true" %}
|
||||
all: deny
|
||||
admin: allow
|
||||
{% else %}
|
||||
all: allow
|
||||
{% endif %}
|
||||
## Only allow to register from localhost
|
||||
trusted_network:
|
||||
loopback: allow
|
||||
soft_upload_quota:
|
||||
all: 400 # MiB
|
||||
hard_upload_quota:
|
||||
all: 500 # MiB
|
||||
|
||||
|
||||
language: "en"
|
||||
|
||||
### =======
|
||||
### MODULES
|
||||
|
||||
modules:
|
||||
mod_adhoc: {}
|
||||
{%- if env['EJABBERD_MOD_ADMIN_EXTRA'] == "true" %}
|
||||
mod_admin_extra: {}
|
||||
{% endif %}
|
||||
mod_announce: # recommends mod_adhoc
|
||||
access: announce
|
||||
mod_blocking: {} # requires mod_privacy
|
||||
mod_caps: {}
|
||||
mod_carboncopy: {}
|
||||
mod_client_state:
|
||||
drop_chat_states: true
|
||||
queue_presence: false
|
||||
mod_configure: {} # requires mod_adhoc
|
||||
mod_disco: {}
|
||||
## mod_echo: {}
|
||||
mod_irc: {}
|
||||
mod_http_bind: {}
|
||||
## mod_http_fileserver:
|
||||
## docroot: "/var/www"
|
||||
## accesslog: "/var/log/ejabberd/access.log"
|
||||
mod_last: {}
|
||||
mod_muc:
|
||||
host: "conference.@HOST@"
|
||||
access: muc
|
||||
access_create: muc_create
|
||||
access_persistent: muc_create
|
||||
access_admin: muc_admin
|
||||
history_size: 50
|
||||
default_room_options:
|
||||
persistent: true
|
||||
{%- if env['EJABBERD_MOD_MUC_ADMIN'] == "true" %}
|
||||
mod_muc_admin: {}
|
||||
{% endif %}
|
||||
## mod_muc_log: {}
|
||||
## mod_multicast: {}
|
||||
mod_offline:
|
||||
access_max_user_messages: max_user_offline_messages
|
||||
mod_ping: {}
|
||||
## mod_pres_counter:
|
||||
## count: 5
|
||||
## interval: 60
|
||||
mod_privacy: {}
|
||||
mod_private: {}
|
||||
## mod_proxy65: {}
|
||||
mod_pubsub:
|
||||
access_createnode: pubsub_createnode
|
||||
## reduces resource comsumption, but XEP incompliant
|
||||
ignore_pep_from_offline: true
|
||||
## XEP compliant, but increases resource comsumption
|
||||
## ignore_pep_from_offline: false
|
||||
last_item_cache: false
|
||||
plugins:
|
||||
- "flat"
|
||||
- "hometree"
|
||||
- "pep" # pep requires mod_caps
|
||||
mod_register:
|
||||
##
|
||||
## Protect In-Band account registrations with CAPTCHA.
|
||||
##
|
||||
## captcha_protected: true
|
||||
|
||||
##
|
||||
## Set the minimum informational entropy for passwords.
|
||||
##
|
||||
## password_strength: 32
|
||||
|
||||
##
|
||||
## After successful registration, the user receives
|
||||
## a message with this subject and body.
|
||||
##
|
||||
welcome_message:
|
||||
subject: "Welcome!"
|
||||
body: |-
|
||||
Hi.
|
||||
Welcome to this XMPP server.
|
||||
|
||||
##
|
||||
## Only clients in the server machine can register accounts
|
||||
##
|
||||
{%- if env['EJABBERD_REGISTER_TRUSTED_NETWORK_ONLY'] == "true" %}
|
||||
ip_access: trusted_network
|
||||
{% endif %}
|
||||
|
||||
access: register
|
||||
mod_roster: {}
|
||||
mod_shared_roster: {}
|
||||
mod_stats: {}
|
||||
mod_time: {}
|
||||
mod_vcard: {}
|
||||
{% if env.get('EJABBERD_MOD_VERSION', true) == "true" %}
|
||||
mod_version: {}
|
||||
{% endif %}
|
||||
mod_http_upload:
|
||||
docroot: "/opt/ejabberd/upload"
|
||||
{%- if env['EJABBERD_HTTPS'] == "true" %}
|
||||
put_url: "https://@HOST@:5443"
|
||||
{%- else %}
|
||||
put_url: "http://@HOST@:5443"
|
||||
{% endif %}
|
||||
mod_http_upload_quota:
|
||||
max_days: 10
|
||||
|
||||
### ============
|
||||
### HOST CONFIG
|
||||
|
||||
host_config:
|
||||
{%- for xmpp_domain in env['XMPP_DOMAIN'].split() %}
|
||||
"{{ xmpp_domain }}":
|
||||
domain_certfile: "/opt/ejabberd/ssl/{{ xmpp_domain }}.pem"
|
||||
{%- endfor %}
|
||||
|
||||
{%- if env['EJABBERD_CONFIGURE_ODBC'] == "true" %}
|
||||
### ====================
|
||||
### ODBC DATABASE CONFIG
|
||||
odbc_type: {{ env['EJABBERD_ODBC_TYPE'] }}
|
||||
odbc_server: {{ env['EJABBERD_ODBC_SERVER'] }}
|
||||
odbc_database: {{ env['EJABBERD_ODBC_DATABASE'] }}
|
||||
odbc_username: {{ env['EJABBERD_ODBC_USERNAME'] }}
|
||||
odbc_password: {{ env['EJABBERD_ODBC_PASSWORD'] }}
|
||||
odbc_pool_size: {{ env['EJABBERD_ODBC_POOL_SIZE'] }}
|
||||
{% endif %}
|
||||
|
||||
{%- if env['EJABBERD_DEFAULT_DB'] is defined %}
|
||||
default_db: {{ env['EJABBERD_DEFAULT_DB'] }}
|
||||
{% endif %}
|
||||
|
||||
### =====================
|
||||
### SESSION MANAGEMENT DB
|
||||
sm_db_type: {{ env['EJABBERD_SESSION_DB'] or "mnesia" }}
|
||||
|
||||
{%- if env['EJABBERD_CONFIGURE_REDIS'] == "true" %}
|
||||
### ====================
|
||||
### REDIS DATABASE CONFIG
|
||||
redis_server: {{ env['EJABBERD_REDIS_SERVER'] or "localhost" }}
|
||||
redis_port: {{ env['EJABBERD_REDIS_PORT'] or 6379 }}
|
||||
{%- if env['EJABBERD_REDIS_PASSWORD'] is defined %}
|
||||
redis_password: {{ env['EJABBERD_REDIS_PASSWORD'] }}
|
||||
{% endif %}
|
||||
redis_db: {{ env['EJABBERD_REDIS_DB'] or 0}}
|
||||
redis_reconnect_timeout: {{ env['EJABBERD_REDIS_RECONNECT_TIMEOUT'] or 1 }}
|
||||
redis_connect_timeout: {{ env['EJABBERD_REDIS_CONNECT_TIMEOUT'] or 1 }}
|
||||
{% endif %}
|
||||
@@ -0,0 +1,199 @@
|
||||
#
|
||||
# In this file you can configure options that are passed by ejabberdctl
|
||||
# to the erlang runtime system when starting ejabberd
|
||||
#
|
||||
|
||||
#' POLL: Kernel polling ([true|false])
|
||||
#
|
||||
# The kernel polling option requires support in the kernel.
|
||||
# Additionally, you need to enable this feature while compiling Erlang.
|
||||
#
|
||||
# Default: true
|
||||
#
|
||||
POLL={{ env['POLL'] or 'true' }}
|
||||
|
||||
#.
|
||||
#' SMP: SMP support ([enable|auto|disable])
|
||||
#
|
||||
# Explanation in Erlang/OTP documentation:
|
||||
# enable: starts the Erlang runtime system with SMP support enabled.
|
||||
# This may fail if no runtime system with SMP support is available.
|
||||
# auto: starts the Erlang runtime system with SMP support enabled if it
|
||||
# is available and more than one logical processor are detected.
|
||||
# disable: starts a runtime system without SMP support.
|
||||
#
|
||||
# Default: auto
|
||||
#
|
||||
SMP={{ env['SMP'] or 'auto' }}
|
||||
|
||||
#.
|
||||
#' ERL_MAX_PORTS: Maximum number of simultaneously open Erlang ports
|
||||
#
|
||||
# ejabberd consumes two or three ports for every connection, either
|
||||
# from a client or from another Jabber server. So take this into
|
||||
# account when setting this limit.
|
||||
#
|
||||
# Default: 32000
|
||||
# Maximum: 268435456
|
||||
#
|
||||
ERL_MAX_PORTS={{ env['ERL_MAX_PORTS'] or '32000' }}
|
||||
|
||||
#.
|
||||
#' FIREWALL_WINDOW: Range of allowed ports to pass through a firewall
|
||||
#
|
||||
# If Ejabberd is configured to run in cluster, and a firewall is blocking ports,
|
||||
# it's possible to make Erlang use a defined range of port (instead of dynamic
|
||||
# ports) for node communication.
|
||||
#
|
||||
# Default: not defined
|
||||
# Example: 4200-4210
|
||||
#
|
||||
{%- if env['FIREWALL_WINDOW'] %}
|
||||
FIREWALL_WINDOW={{ env['FIREWALL_WINDOW'] }}
|
||||
{%- endif %}
|
||||
|
||||
#.
|
||||
#' INET_DIST_INTERFACE: IP address where this Erlang node listens other nodes
|
||||
#
|
||||
# This communication is used by ejabberdctl command line tool,
|
||||
# and in a cluster of several ejabberd nodes.
|
||||
#
|
||||
# Default: 0.0.0.0
|
||||
#
|
||||
{%- if env['INET_DIST_INTERFACE'] %}
|
||||
INET_DIST_INTERFACE={{ env['INET_DIST_INTERFACE'] }}
|
||||
{%- endif %}
|
||||
|
||||
#.
|
||||
#' ERL_EPMD_ADDRESS: IP addresses where epmd listens for connections
|
||||
#
|
||||
# IMPORTANT: This option works only in Erlang/OTP R14B03 and newer.
|
||||
#
|
||||
# This environment variable may be set to a comma-separated
|
||||
# list of IP addresses, in which case the epmd daemon
|
||||
# will listen only on the specified address(es) and on the
|
||||
# loopback address (which is implicitly added to the list if it
|
||||
# has not been specified). The default behaviour is to listen on
|
||||
# all available IP addresses.
|
||||
#
|
||||
# Default: 0.0.0.0
|
||||
#
|
||||
{%- if env['ERL_EPMD_ADDRESS'] %}
|
||||
ERL_EPMD_ADDRESS={{ env['ERL_EPMD_ADDRESS'] }}
|
||||
{%- endif %}
|
||||
|
||||
#.
|
||||
#' ERL_PROCESSES: Maximum number of Erlang processes
|
||||
#
|
||||
# Erlang consumes a lot of lightweight processes. If there is a lot of activity
|
||||
# on ejabberd so that the maximum number of processes is reached, people will
|
||||
# experience greater latency times. As these processes are implemented in
|
||||
# Erlang, and therefore not related to the operating system processes, you do
|
||||
# not have to worry about allowing a huge number of them.
|
||||
#
|
||||
# Default: 250000
|
||||
# Maximum: 268435456
|
||||
#
|
||||
ERL_PROCESSES={{ env['ERL_PROCESSES'] or '250000' }}
|
||||
|
||||
#.
|
||||
#' ERL_MAX_ETS_TABLES: Maximum number of ETS and Mnesia tables
|
||||
#
|
||||
# The number of concurrent ETS and Mnesia tables is limited. When the limit is
|
||||
# reached, errors will appear in the logs:
|
||||
# ** Too many db tables **
|
||||
# You can safely increase this limit when starting ejabberd. It impacts memory
|
||||
# consumption but the difference will be quite small.
|
||||
#
|
||||
# Default: 1400
|
||||
#
|
||||
ERL_MAX_ETS_TABLES={{ env['ERL_MAX_ETS_TABLES'] or '1400' }}
|
||||
|
||||
#.
|
||||
#' ERL_OPTIONS: Additional Erlang options
|
||||
#
|
||||
# The next variable allows to specify additional options passed to erlang while
|
||||
# starting ejabberd. Some useful options are -noshell, -detached, -heart. When
|
||||
# ejabberd is started from an init.d script options -noshell and -detached are
|
||||
# added implicitly. See erl(1) for more info.
|
||||
#
|
||||
# It might be useful to add "-pa /usr/local/lib/ejabberd/ebin" if you
|
||||
# want to add local modules in this path.
|
||||
#
|
||||
# Default: ""
|
||||
#
|
||||
ERL_OPTIONS="{{ env['ERL_OPTIONS'] or '-noshell' }}"
|
||||
|
||||
#.
|
||||
#' ERLANG_NODE: Erlang node name
|
||||
#
|
||||
# The next variable allows to explicitly specify erlang node for ejabberd
|
||||
# It can be given in different formats:
|
||||
# ERLANG_NODE=ejabberd
|
||||
# Lets erlang add hostname to the node (ejabberd uses short name in this case)
|
||||
# ERLANG_NODE=ejabberd@hostname
|
||||
# Erlang uses node name as is (so make sure that hostname is a real
|
||||
# machine hostname or you'll not be able to control ejabberd)
|
||||
# ERLANG_NODE=ejabberd@hostname.domainname
|
||||
# The same as previous, but erlang will use long hostname
|
||||
# (see erl (1) manual for details)
|
||||
#
|
||||
# Default: ejabberd@localhost
|
||||
#
|
||||
ERLANG_NODE={{ env['ERLANG_NODE'] or 'ejabberd@localhost' }}
|
||||
|
||||
#.
|
||||
#' EJABBERD_PID_PATH: ejabberd PID file
|
||||
#
|
||||
# Indicate the full path to the ejabberd Process identifier (PID) file.
|
||||
# If this variable is defined, ejabberd writes the PID file when starts,
|
||||
# and deletes it when stops.
|
||||
# Remember to create the directory and grant write permission to ejabberd.
|
||||
#
|
||||
# Default: don't write PID file
|
||||
#
|
||||
#EJABBERD_PID_PATH=/var/run/ejabberd/ejabberd.pid
|
||||
|
||||
#.
|
||||
#' EJABBERD_CONFIG_PATH: ejabberd configuration file
|
||||
#
|
||||
# Specify the full path to the ejabberd configuration file. If the file name has
|
||||
# yml or yaml extension, it is parsed as a YAML file; otherwise, Erlang syntax is
|
||||
# expected.
|
||||
#
|
||||
# Default: $ETC_DIR/ejabberd.yml
|
||||
#
|
||||
EJABBERD_CONFIG_PATH={{ env['EJABBERD_CONFIG_PATH'] or '/opt/ejabberd/conf/ejabberd.yml' }}
|
||||
|
||||
#.
|
||||
#' CONTRIB_MODULES_PATH: contributed ejabberd modules path
|
||||
#
|
||||
# Specify the full path to the contributed ejabberd modules. If the path is not
|
||||
# defined, ejabberd will use ~/.ejabberd-modules in home of user running ejabberd.
|
||||
#
|
||||
# Default: $HOME/.ejabberd-modules
|
||||
#
|
||||
CONTRIB_MODULES_PATH={{ env['CONTRIB_MODULES_PATH'] or '/opt/ejabberd/modules' }}
|
||||
|
||||
#.
|
||||
#' CONTRIB_MODULES_CONF_DIR: configuration directory for contributed modules
|
||||
#
|
||||
# Specify the full path to the configuration directory for contributed ejabberd
|
||||
# modules. In order to configure a module named mod_foo, a mod_foo.yml file can
|
||||
# be created in this directory. This file will then be used instead of the
|
||||
# default configuration file provided with the module.
|
||||
#
|
||||
# Default: $CONTRIB_MODULES_PATH/conf
|
||||
#
|
||||
CONTRIB_MODULES_CONF_DIR={{ env['CONTRIB_MODULES_CONF_DIR'] or '/opt/ejabberd/modules/conf' }}
|
||||
|
||||
#.
|
||||
#' EJABBERD_BYPASS_WARNINGS: Bypass LIVE warning
|
||||
#
|
||||
# Default: don't bypass the warning
|
||||
#
|
||||
EJABBERD_BYPASS_WARNINGS=true
|
||||
|
||||
#.
|
||||
#'
|
||||
# vim: foldmarker=#',#. foldmethod=marker:
|
||||
@@ -0,0 +1,22 @@
|
||||
readonly HOSTIP=$(hostname -i)
|
||||
readonly HOSTNAME=$(hostname -f)
|
||||
readonly DOMAINNAME=$(hostname -d)
|
||||
|
||||
readonly DOCKER_LIB="${EJABBERD_HOME}/docker/lib"
|
||||
readonly ERLANGCOOKIEFILE="${EJABBERD_HOME}/.erlang.cookie"
|
||||
readonly EJABBERDCTL="/sbin/ejabberdctl"
|
||||
readonly CONFIGDIR="${EJABBERD_HOME}/conf"
|
||||
readonly CONFIGTMPDIR="${EJABBERD_HOME}/docker/conf"
|
||||
readonly SSLCERTDIR="${EJABBERD_HOME}/ssl"
|
||||
readonly SSLCERTHOST="${SSLCERTDIR}/host.pem"
|
||||
readonly LOGDIR="/var/log/ejabberd"
|
||||
readonly FIRST_START_DONE_FILE="${EJABBERD_HOME}/first-start-done"
|
||||
readonly CLUSTER_NODE_FILE="${EJABBERD_HOME}/cluster-done"
|
||||
|
||||
readonly PYTHON_JINJA2="import os;
|
||||
import sys;
|
||||
import jinja2;
|
||||
sys.stdout.write(
|
||||
jinja2.Template
|
||||
(sys.stdin.read()
|
||||
).render(env=os.environ))"
|
||||
@@ -0,0 +1,72 @@
|
||||
is_set() {
|
||||
local var=$1
|
||||
|
||||
[[ -n $var ]]
|
||||
}
|
||||
|
||||
|
||||
is_zero() {
|
||||
local var=$1
|
||||
|
||||
[[ -z $var ]]
|
||||
}
|
||||
|
||||
|
||||
file_exist() {
|
||||
local file=$1
|
||||
|
||||
[[ -e $file ]]
|
||||
}
|
||||
|
||||
|
||||
is_true() {
|
||||
local var=${1,,}
|
||||
local choices=("yes" "1" "y" "true")
|
||||
for ((i=0;i < ${#choices[@]};i++)) {
|
||||
[[ "${choices[i]}" == $var ]] && return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
|
||||
log() {
|
||||
local message=$1
|
||||
echo $message
|
||||
}
|
||||
|
||||
|
||||
# overwrite this function to get hostname from other sources
|
||||
# like dns or etcd
|
||||
get_nodename() {
|
||||
log ${HOSTNAME}
|
||||
}
|
||||
|
||||
|
||||
join_cluster() {
|
||||
local cluster_node=$1
|
||||
|
||||
is_zero ${cluster_node} \
|
||||
&& exit 0
|
||||
|
||||
log "Join cluster..."
|
||||
|
||||
local erlang_node_name=${ERLANG_NODE%@*}
|
||||
local erlang_cluster_node="${erlang_node_name}@${cluster_node}"
|
||||
|
||||
response=$(${EJABBERDCTL} ping ${erlang_cluster_node})
|
||||
while [ "$response" != "pong" ]; do
|
||||
log "Waiting for ${erlang_cluster_node}..."
|
||||
sleep 2
|
||||
response=$(${EJABBERDCTL} ping ${erlang_cluster_node})
|
||||
done
|
||||
|
||||
log "Join cluster at ${erlang_cluster_node}... "
|
||||
NO_WARNINGS=true ${EJABBERDCTL} join_cluster $erlang_cluster_node
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
touch ${CLUSTER_NODE_FILE}
|
||||
else
|
||||
log "cloud not join cluster"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
# Overridable file
|
||||
@@ -0,0 +1 @@
|
||||
# Overridable file
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Updates the known modules as to be found in https://github.com/processone/ejabberd-contrib
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
run_modules_update_specs() {
|
||||
log "Updating module specs... "
|
||||
${EJABBERDCTL} modules_update_specs
|
||||
}
|
||||
|
||||
|
||||
is_true ${EJABBERD_SKIP_MODULES_UPDATE} \
|
||||
&& exit 0
|
||||
|
||||
run_modules_update_specs
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+144
@@ -0,0 +1,144 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Installs modules as defined in environment variables
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
install_module_from_source() {
|
||||
local module_name=$1
|
||||
local module_source_path=${EJABBERD_HOME}/module_source/${module_name}
|
||||
local module_install_folder=${EJABBERD_HOME}/.ejabberd-modules/sources/${module_name}
|
||||
|
||||
log "Analyzing module ${module_name} for installation"
|
||||
# Make sure that the module exists in the source folder before attempting a copy
|
||||
|
||||
if [ ! -d ${module_source_path} ]; then
|
||||
log "Error: Module ${module_name} not found in ${EJABBERD_HOME}/module_source"
|
||||
log "Please use a shared volume to populate your module in ${EJABBERD_HOME}/module_source"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
# Check to see if the module is already installed
|
||||
local install_count=$(${EJABBERDCTL} modules_installed | grep -ce "^${module_name}[[:space:]]")
|
||||
if [ $install_count -gt 0 ]; then
|
||||
log "Error: Module already installed: ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
# Copy the module into the shared folder
|
||||
log "Copying module to ejabberd folder ${module_install_folder}"
|
||||
mkdir -p ${module_install_folder}
|
||||
cp -R ${module_source_path} ${module_install_folder}
|
||||
|
||||
# Run the ejabberdctl module_check on the module
|
||||
log "Running module_check on ${module_name}"
|
||||
${EJABBERDCTL} module_check ${module_name}
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Module check failed for ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
log "Module check succeeded for ${module_name}"
|
||||
|
||||
# Install the module
|
||||
log "Running module_install on ${module_name}"
|
||||
${EJABBERDCTL} module_install ${module_name}
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Module installation failed for ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
log "Module installation succeeded for ${module_name}"
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
install_module_from_ejabberd_contrib() {
|
||||
local module_name=$1
|
||||
|
||||
# Check to see if the module is already installed
|
||||
local install_count=$(${EJABBERDCTL} modules_installed | grep -ce "^${module_name}[[:space:]]")
|
||||
if [ $install_count -gt 0 ]; then
|
||||
log "Error: Module already installed: ejabberd_contrib ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
# Install the module
|
||||
log "Running module_install on ejabberd_contrib ${module_name}"
|
||||
${EJABBERDCTL} module_install ${module_name}
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Module installation failed for ejabberd_contrib ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
log "Module installation succeeded for ejabberd_contrib ${module_name}"
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enable_custom_auth_module_override() {
|
||||
module_name=$1;
|
||||
# When using custom authentication modules, the module name must be
|
||||
# in the following pattern: ejabberd_auth_foo, where foo is the
|
||||
# value you will use for your auth_method yml configuration.
|
||||
required_prefix="ejabberd_auth_"
|
||||
|
||||
if [[ "${module_name}" != "${required_prefix}"* ]]; then
|
||||
log "Error: module_name must begin with ${required_prefix}"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
log "Checking custom auth module: ${module_name}"
|
||||
# Make sure the auth module is installed
|
||||
local install_count=$(${EJABBERDCTL} modules_installed | grep -ce "^${module_name}[[:space:]]")
|
||||
if [ $install_count -eq 0 ]; then
|
||||
log "Error: custom auth_module not installed: ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
custom_auth_method=${module_name#$required_prefix}
|
||||
echo -e "\nauth_method: [${custom_auth_method}]" >> ${CONFIGFILE}
|
||||
log "Custom auth module ${module_name} configuration complete."
|
||||
}
|
||||
|
||||
file_exist ${FIRST_START_DONE_FILE} \
|
||||
&& exit 0
|
||||
|
||||
is_restart_needed=0;
|
||||
|
||||
if [ -n "${EJABBERD_SOURCE_MODULES}" ]; then
|
||||
for module_name in ${EJABBERD_SOURCE_MODULES} ; do
|
||||
install_module_from_source ${module_name}
|
||||
done
|
||||
is_restart_needed=1;
|
||||
fi
|
||||
|
||||
# Check the EJABBERD_CONTRIB_MODULES variable for any ejabberd_contrib modules
|
||||
if [ -n "${EJABBERD_CONTRIB_MODULES}" ]; then
|
||||
for module_name in ${EJABBERD_CONTRIB_MODULES} ; do
|
||||
install_module_from_ejabberd_contrib ${module_name}
|
||||
done
|
||||
is_restart_needed=1;
|
||||
fi
|
||||
|
||||
# If a custom module was defined for handling auth, we need to override
|
||||
# the pre-defined auth methods in the config.
|
||||
if [ -n "${EJABBERD_CUSTOM_AUTH_MODULE_OVERRIDE}" ]; then
|
||||
enable_custom_auth_module_override "${EJABBERD_CUSTOM_AUTH_MODULE_OVERRIDE}"
|
||||
is_restart_needed=1;
|
||||
fi
|
||||
|
||||
# If any modules were installed, restart the server, if the option is enabled
|
||||
if [ ${is_restart_needed} -eq 1 ]; then
|
||||
if is_true ${EJABBERD_RESTART_AFTER_MODULE_INSTALL} ; then
|
||||
log "Restarting ejabberd after successful module installation(s)"
|
||||
${EJABBERDCTL} restart
|
||||
child=$!
|
||||
${EJABBERDCTL} "started"
|
||||
wait $child
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
# Do not exit if users already registered
|
||||
set +e
|
||||
|
||||
randpw() {
|
||||
< /dev/urandom tr -dc A-Z-a-z-0-9 | head -c ${1:-16};
|
||||
echo;
|
||||
}
|
||||
|
||||
|
||||
register_user() {
|
||||
local user=$1
|
||||
local domain=$2
|
||||
local password=$3
|
||||
|
||||
${EJABBERDCTL} register ${user} ${domain} ${password}
|
||||
return $?
|
||||
}
|
||||
|
||||
|
||||
register_all_users() {
|
||||
# register users from environment $EJABBERD_USERS with given
|
||||
# password or random password written to stout. Use whitespace
|
||||
# to seperate users.
|
||||
#
|
||||
# sample:
|
||||
# - add a user with an given password:
|
||||
# -e "EJABBERD_USERS=admin@example.com:adminSecret"
|
||||
# - add a user with a random password:
|
||||
# -e "EJABBERD_USERS=user@example.com"
|
||||
# - set password for admin and use random for user1:
|
||||
# -e "EJABBERD_USERS=admin@example.com:adminSecret user@example.com"
|
||||
|
||||
for user in ${EJABBERD_USERS} ; do
|
||||
local jid=${user%%:*}
|
||||
local password=${user#*:}
|
||||
|
||||
local username=${jid%%@*}
|
||||
local domain=${jid#*@}
|
||||
|
||||
[[ "${password}" == "${jid}" ]] \
|
||||
&& password=$(randpw)
|
||||
|
||||
register_user ${username} ${domain} ${password}
|
||||
local retval=$?
|
||||
|
||||
[[ ${retval} -eq 0 ]] \
|
||||
&& log "Password for user ${username}@${domain} is ${password}"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
file_exist ${FIRST_START_DONE_FILE} \
|
||||
&& exit 0
|
||||
|
||||
|
||||
file_exist ${CLUSTER_NODE_FILE} \
|
||||
&& exit 0
|
||||
|
||||
|
||||
is_set ${EJABBERD_USERS} \
|
||||
&& register_all_users
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Write a first-start-done file
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
if [ ! -e "${FIRST_START_DONE_FILE}" ]; then
|
||||
touch ${FIRST_START_DONE_FILE}
|
||||
fi
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
# Instead of having to mount a direction, specify the ssl certs
|
||||
# via environment variables:
|
||||
# `EJABBERD_SSLCERT_HOST` and `EJABBERD_SSLCERT_{domain_name}`.
|
||||
# For example: `EJABBERD_SSLCERT_EXAMPLE_COM`.
|
||||
|
||||
write_file_from_env() {
|
||||
log "Writing $1 to $2"
|
||||
mkdir -p "$(dirname $2)"
|
||||
log "${!1}" > $2
|
||||
}
|
||||
|
||||
# Write the host certificate
|
||||
is_set ${EJABBERD_SSLCERT_HOST} \
|
||||
&& write_file_from_env "EJABBERD_SSLCERT_HOST" ${SSLCERTHOST}
|
||||
|
||||
# Write the domain certificates for each XMPP_DOMAIN
|
||||
for xmpp_domain in ${XMPP_DOMAIN} ; do
|
||||
var="EJABBERD_SSLCERT_$(echo $xmpp_domain | awk '{print toupper($0)}' | sed 's/\./_/g;s/-/_/g')"
|
||||
if is_set ${!var} ; then
|
||||
file_exist "${SSLCERTDIR}/${xmpp_domain}.pem" \
|
||||
|| write_file_from_env "$var" "${SSLCERTDIR}/${xmpp_domain}.pem"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
make_snakeoil_certificate() {
|
||||
local domain=$1
|
||||
local certfile=$2
|
||||
|
||||
openssl req -subj "/CN=${domain}" \
|
||||
-new \
|
||||
-newkey rsa:4096 \
|
||||
-days 365 \
|
||||
-nodes \
|
||||
-x509 \
|
||||
-keyout /tmp/selfsigned.key \
|
||||
-out /tmp/selfsigned.crt
|
||||
|
||||
log "Writing ssl cert and private key to '${certfile}'..."
|
||||
cat /tmp/selfsigned.crt /tmp/selfsigned.key > ${certfile}
|
||||
rm /tmp/selfsigned.crt /tmp/selfsigned.key
|
||||
}
|
||||
|
||||
|
||||
make_host_snakeoil_certificate() {
|
||||
local IFS=@
|
||||
local domain='localhost'
|
||||
local erlang_node=${ERLANG_NODE}
|
||||
|
||||
if is_true ${erlang_node} ; then
|
||||
domain=${HOSTNAME}
|
||||
elif is_set ${erlang_node} ; then
|
||||
set ${erlang_node}
|
||||
local nodehost=$2
|
||||
if is_zero ${nodehost} ; then
|
||||
domain=${HOSTNAME}
|
||||
else
|
||||
domain=${nodehost}
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Generating snakeoil ssl cert for ${domain}..."
|
||||
|
||||
make_snakeoil_certificate ${domain} ${SSLCERTHOST}
|
||||
}
|
||||
|
||||
|
||||
make_domain_snakeoil_certificate() {
|
||||
local domain=$1
|
||||
local certfile=$2
|
||||
|
||||
log "Generating snakeoil ssl cert for ${domain}..."
|
||||
|
||||
make_snakeoil_certificate ${domain} ${certfile}
|
||||
}
|
||||
|
||||
|
||||
# generate host ssl cert if missing
|
||||
file_exist ${SSLCERTHOST} \
|
||||
|| make_host_snakeoil_certificate
|
||||
|
||||
|
||||
# generate xmmp domain ssl certificates if missing
|
||||
for xmpp_domain in ${XMPP_DOMAIN} ; do
|
||||
domain_certfile="${SSLCERTDIR}/${xmpp_domain}.pem"
|
||||
file_exist ${domain_certfile} \
|
||||
|| make_domain_snakeoil_certificate ${xmpp_domain} ${domain_certfile}
|
||||
done
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
make_dhparam() {
|
||||
local dhfile=$1
|
||||
local bits=$2
|
||||
|
||||
log "Writing dh file to '${dhfile}'..."
|
||||
openssl dhparam -out ${dhfile} ${bits}
|
||||
}
|
||||
|
||||
if is_true ${EJABBERD_DHPARAM} ; then
|
||||
file_exist ${SSLDHPARAM} \
|
||||
|| make_dhparam ${SSLDHPARAM} 4096
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
set_erlang_cookie() {
|
||||
chmod 600 ${ERLANGCOOKIEFILE}
|
||||
log "Set erlang cookie to ${ERLANG_COOKIE}..."
|
||||
echo ${ERLANG_COOKIE} > ${ERLANGCOOKIEFILE}
|
||||
chmod 400 ${ERLANGCOOKIEFILE}
|
||||
}
|
||||
|
||||
|
||||
file_exist ${FIRST_START_DONE_FILE} \
|
||||
&& exit 0
|
||||
|
||||
|
||||
# set erlang cookie if ERLANG_COOKIE is set in environemt
|
||||
is_set ${ERLANG_COOKIE} \
|
||||
&& set_erlang_cookie
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
make_config() {
|
||||
local filename=$1
|
||||
local template="${CONFIGTMPDIR}/${filename}.tpl"
|
||||
local configfile="${CONFIGDIR}/${filename}"
|
||||
|
||||
file_exist $configfile \
|
||||
&& return 1
|
||||
|
||||
if [ ! -e ${configfile} ]; then
|
||||
log "Generating ${configfile} config file..."
|
||||
cat $template \
|
||||
| python -c "${PYTHON_JINJA2}" \
|
||||
> $configfile
|
||||
else
|
||||
echo "File ${configfile} exists."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# /opt/ejabberd/conf/ejabberd.yml
|
||||
make_config "ejabberd.yml"
|
||||
|
||||
# /opt/ejabberd/conf/ejabberdctl.cfg
|
||||
make_config "ejabberdctl.cfg"
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Environment
|
||||
export EJABBERD_HTTPS=${EJABBERD_HTTPS:-'true'}
|
||||
export EJABBERD_STARTTLS=${EJABBERD_STARTTLS:-'true'}
|
||||
export EJABBERD_S2S_SSL=${EJABBERD_S2S_SSL:-'true'}
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
# discover hostname
|
||||
readonly nodename=$(get_nodename)
|
||||
|
||||
# set erlang node to node name from get_nodename
|
||||
if [[ "$ERLANG_NODE" == "nodename" ]]; then
|
||||
export ERLANG_NODE="ejabberd@${nodename}"
|
||||
fi
|
||||
|
||||
|
||||
run_scripts() {
|
||||
local run_script=$1
|
||||
local run_script_dir="${EJABBERD_HOME}/docker/${run_script}"
|
||||
|
||||
log "Run ${run_script} scripts..."
|
||||
for script in ${run_script_dir}/*.sh ; do
|
||||
if [ -f ${script} -a -x ${script} ] ; then
|
||||
${script}
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
_trap() {
|
||||
run_scripts "stop"
|
||||
log "Stopping ejabberd..."
|
||||
$EJABBERDCTL stop
|
||||
$EJABBERDCTL stopped
|
||||
exit 0
|
||||
}
|
||||
|
||||
|
||||
# Catch signals and shutdown ejabberd
|
||||
trap _trap SIGTERM SIGINT
|
||||
|
||||
# print logfiles to stdout
|
||||
tail -F ${LOGDIR}/crash.log \
|
||||
${LOGDIR}/error.log \
|
||||
${LOGDIR}/erlang.log \
|
||||
${LOGDIR}/ejabberd.log &
|
||||
|
||||
# start ejabberd
|
||||
run_scripts "pre"
|
||||
log "Starting ejabberd..."
|
||||
$EJABBERDCTL start
|
||||
$EJABBERDCTL started
|
||||
log "Ejabberd started."
|
||||
run_scripts "post"
|
||||
|
||||
# run forever
|
||||
while true; do sleep 1; done
|
||||
|
||||
log "Ejabberd stopped."
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/docker/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
|
||||
|
||||
leave_cluster() {
|
||||
log "Leave cluster..."
|
||||
rm ${CLUSTER_NODE_FILE}
|
||||
NO_WARNINGS=true ${EJABBERDCTL} leave_cluster
|
||||
}
|
||||
|
||||
|
||||
file_exist ${CLUSTER_NODE_FILE} \
|
||||
&& leave_cluster
|
||||
|
||||
|
||||
exit 0
|
||||
@@ -3,15 +3,16 @@ Description=XMPP Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
User=ejabberd
|
||||
Group=ejabberd
|
||||
LimitNOFILE=16000
|
||||
LimitNOFILE=65536
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
ExecStart=/bin/sh @ctlscriptpath@/ejabberdctl start
|
||||
ExecStop=@ctlscriptpath@/ejabberdctl stop
|
||||
ExecReload=@ctlscriptpath@/ejabberdctl reload_config
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/bin/sh -c '@ctlscriptpath@/ejabberdctl start && @ctlscriptpath@/ejabberdctl started'
|
||||
ExecStop=/bin/sh -c '@ctlscriptpath@/ejabberdctl stop && @ctlscriptpath@/ejabberdctl stopped'
|
||||
PrivateDevices=true
|
||||
ProtectSystem=full
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
+127
-85
@@ -147,6 +147,15 @@ listen:
|
||||
## access: all
|
||||
## shaper_rule: fast
|
||||
## ip: "127.0.0.1"
|
||||
## privilege_access:
|
||||
## roster: "both"
|
||||
## message: "outgoing"
|
||||
## presence: "roster"
|
||||
## delegations:
|
||||
## "urn:xmpp:mam:1":
|
||||
## filtering: ["node"]
|
||||
## "http://jabber.org/protocol/pubsub":
|
||||
## filtering: []
|
||||
## hosts:
|
||||
## "icq.example.org":
|
||||
## password: "secret"
|
||||
@@ -167,6 +176,7 @@ listen:
|
||||
## -
|
||||
## port: 4560
|
||||
## module: ejabberd_xmlrpc
|
||||
## access_commands: {}
|
||||
-
|
||||
port: 5280
|
||||
module: ejabberd_http
|
||||
@@ -253,10 +263,10 @@ auth_method: internal
|
||||
## extauth_program: "/path/to/authentication/script"
|
||||
|
||||
##
|
||||
## Authentication using ODBC
|
||||
## Authentication using SQL
|
||||
## Remember to setup a database in the next section.
|
||||
##
|
||||
## auth_method: odbc
|
||||
## auth_method: sql
|
||||
|
||||
##
|
||||
## Authentication using PAM
|
||||
@@ -329,26 +339,26 @@ auth_method: internal
|
||||
##
|
||||
## MySQL server:
|
||||
##
|
||||
## odbc_type: mysql
|
||||
## odbc_server: "server"
|
||||
## odbc_database: "database"
|
||||
## odbc_username: "username"
|
||||
## odbc_password: "password"
|
||||
## sql_type: mysql
|
||||
## sql_server: "server"
|
||||
## sql_database: "database"
|
||||
## sql_username: "username"
|
||||
## sql_password: "password"
|
||||
##
|
||||
## If you want to specify the port:
|
||||
## odbc_port: 1234
|
||||
## sql_port: 1234
|
||||
|
||||
##
|
||||
## PostgreSQL server:
|
||||
##
|
||||
## odbc_type: pgsql
|
||||
## odbc_server: "server"
|
||||
## odbc_database: "database"
|
||||
## odbc_username: "username"
|
||||
## odbc_password: "password"
|
||||
## sql_type: pgsql
|
||||
## sql_server: "server"
|
||||
## sql_database: "database"
|
||||
## sql_username: "username"
|
||||
## sql_password: "password"
|
||||
##
|
||||
## If you want to specify the port:
|
||||
## odbc_port: 1234
|
||||
## sql_port: 1234
|
||||
##
|
||||
## If you use PostgreSQL, have a large database, and need a
|
||||
## faster but inexact replacement for "select count(*) from users"
|
||||
@@ -358,25 +368,25 @@ auth_method: internal
|
||||
##
|
||||
## SQLite:
|
||||
##
|
||||
## odbc_type: sqlite
|
||||
## odbc_database: "/path/to/database.db"
|
||||
## sql_type: sqlite
|
||||
## sql_database: "/path/to/database.db"
|
||||
|
||||
##
|
||||
## ODBC compatible or MSSQL server:
|
||||
##
|
||||
## odbc_type: odbc
|
||||
## odbc_server: "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"
|
||||
## sql_type: odbc
|
||||
## sql_server: "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"
|
||||
|
||||
##
|
||||
## Number of connections to open to the database for each virtual host
|
||||
##
|
||||
## odbc_pool_size: 10
|
||||
## sql_pool_size: 10
|
||||
|
||||
##
|
||||
## Interval to make a dummy SQL request to keep the connections to the
|
||||
## database alive. Specify in seconds: for example 28800 means 8 hours
|
||||
##
|
||||
## odbc_keepalive_interval: undefined
|
||||
## sql_keepalive_interval: undefined
|
||||
|
||||
###. ===============
|
||||
###' TRAFFIC SHAPERS
|
||||
@@ -407,14 +417,14 @@ acl:
|
||||
##
|
||||
## admin:
|
||||
## user:
|
||||
## - "aleksey": "localhost"
|
||||
## - "ermine": "example.org"
|
||||
## - "aleksey@localhost"
|
||||
## - "ermine@example.org"
|
||||
##
|
||||
## Blocked users
|
||||
##
|
||||
## blocked:
|
||||
## user:
|
||||
## - "baduser": "example.org"
|
||||
## - "baduser@example.org"
|
||||
## - "test"
|
||||
|
||||
## Local users: don't modify this.
|
||||
@@ -430,7 +440,7 @@ acl:
|
||||
## - "jabber.org"
|
||||
## aleksey:
|
||||
## user:
|
||||
## - "aleksey": "jabber.ru"
|
||||
## - "aleksey@jabber.ru"
|
||||
## test:
|
||||
## user_regexp: "^test"
|
||||
## user_glob: "test*"
|
||||
@@ -458,61 +468,95 @@ acl:
|
||||
## acl:
|
||||
## admin:
|
||||
## user:
|
||||
## - "bob-local": "localhost"
|
||||
## - "bob-local@localhost"
|
||||
|
||||
###. ============
|
||||
###' SHAPER RULES
|
||||
|
||||
shaper_rules:
|
||||
## Maximum number of simultaneous sessions allowed for a single user:
|
||||
max_user_sessions: 10
|
||||
## Maximum number of offline messages that users can have:
|
||||
max_user_offline_messages:
|
||||
- 5000: admin
|
||||
- 100
|
||||
## For C2S connections, all users except admins use the "normal" shaper
|
||||
c2s_shaper:
|
||||
- none: admin
|
||||
- normal
|
||||
## All S2S connections use the "fast" shaper
|
||||
s2s_shaper: fast
|
||||
|
||||
###. ============
|
||||
###' ACCESS RULES
|
||||
access:
|
||||
## Maximum number of simultaneous sessions allowed for a single user:
|
||||
max_user_sessions:
|
||||
all: 10
|
||||
## Maximum number of offline messages that users can have:
|
||||
max_user_offline_messages:
|
||||
admin: 5000
|
||||
all: 100
|
||||
access_rules:
|
||||
## This rule allows access only for local users:
|
||||
local:
|
||||
local: allow
|
||||
local:
|
||||
- allow: local
|
||||
## Only non-blocked users can use c2s connections:
|
||||
c2s:
|
||||
blocked: deny
|
||||
all: allow
|
||||
## For C2S connections, all users except admins use the "normal" shaper
|
||||
c2s_shaper:
|
||||
admin: none
|
||||
all: normal
|
||||
## All S2S connections use the "fast" shaper
|
||||
s2s_shaper:
|
||||
all: fast
|
||||
c2s:
|
||||
- deny: blocked
|
||||
- allow
|
||||
## Only admins can send announcement messages:
|
||||
announce:
|
||||
admin: allow
|
||||
announce:
|
||||
- allow: admin
|
||||
## Only admins can use the configuration interface:
|
||||
configure:
|
||||
admin: allow
|
||||
## Admins of this server are also admins of the MUC service:
|
||||
muc_admin:
|
||||
admin: allow
|
||||
- allow: admin
|
||||
## Only accounts of the local ejabberd server can create rooms:
|
||||
muc_create:
|
||||
local: allow
|
||||
## All users are allowed to use the MUC service:
|
||||
muc:
|
||||
all: allow
|
||||
- allow: local
|
||||
## Only accounts on the local ejabberd server can create Pubsub nodes:
|
||||
pubsub_createnode:
|
||||
local: allow
|
||||
- allow: local
|
||||
## In-band registration allows registration of any possible username.
|
||||
## To disable in-band registration, replace 'allow' with 'deny'.
|
||||
register:
|
||||
all: allow
|
||||
- allow
|
||||
## Only allow to register from localhost
|
||||
trusted_network:
|
||||
loopback: allow
|
||||
- allow: loopback
|
||||
## Do not establish S2S connections with bad servers
|
||||
## s2s:
|
||||
## bad_servers: deny
|
||||
## all: allow
|
||||
## - deny:
|
||||
## - ip: "XXX.XXX.XXX.XXX/32"
|
||||
## - deny:
|
||||
## - ip: "XXX.XXX.XXX.XXX/32"
|
||||
## - allow
|
||||
|
||||
## ===============
|
||||
## API PERMISSIONS
|
||||
## ===============
|
||||
##
|
||||
## This section allows you to define who and using what method
|
||||
## can execute commands offered by ejabberd.
|
||||
##
|
||||
## By default "console commands" section allow executing all commands
|
||||
## issued using ejabberdctl command, and "admin access" section allows
|
||||
## users in admin acl to execute all commands except start and stop
|
||||
## with any available access method (ejabberdctl, http-api, xmlrpc
|
||||
## depending what is enabled on server).
|
||||
##
|
||||
## Remember to not remove "console commands" section when doing modifications
|
||||
## or ejabberdctl will not be able to execute commands!
|
||||
##
|
||||
##
|
||||
## api_permissions:
|
||||
## "console commands":
|
||||
## from:
|
||||
## - ejabberd_ctl
|
||||
## who: all
|
||||
## what: "*"
|
||||
## "admin access":
|
||||
## who:
|
||||
## - admin
|
||||
## - oauth:
|
||||
## - scope: "ejabberd:admin"
|
||||
## - admin
|
||||
## what:
|
||||
## - "*"
|
||||
## - "!stop"
|
||||
## - "!start"
|
||||
|
||||
## By default the frequency of account registrations from the same IP
|
||||
## is limited to 1 account every 10 minutes. To disable, specify: infinity
|
||||
@@ -525,10 +569,10 @@ access:
|
||||
## "localhost":
|
||||
## access:
|
||||
## c2s:
|
||||
## admin: allow
|
||||
## all: deny
|
||||
## - allow: admin
|
||||
## - deny
|
||||
## register:
|
||||
## all: deny
|
||||
## - deny
|
||||
|
||||
###. ================
|
||||
###' DEFAULT LANGUAGE
|
||||
@@ -579,6 +623,7 @@ modules:
|
||||
mod_carboncopy: {}
|
||||
mod_client_state: {}
|
||||
mod_configure: {} # requires mod_adhoc
|
||||
##mod_delegation: {} # for xep0356
|
||||
mod_disco: {}
|
||||
## mod_echo: {}
|
||||
mod_irc: {}
|
||||
@@ -589,10 +634,12 @@ modules:
|
||||
mod_last: {}
|
||||
mod_muc:
|
||||
## host: "conference.@HOST@"
|
||||
access: muc
|
||||
access:
|
||||
- allow
|
||||
access_admin:
|
||||
- allow: admin
|
||||
access_create: muc_create
|
||||
access_persistent: muc_create
|
||||
access_admin: muc_admin
|
||||
## mod_muc_log: {}
|
||||
## mod_multicast: {}
|
||||
mod_offline:
|
||||
@@ -615,50 +662,45 @@ modules:
|
||||
- "flat"
|
||||
- "hometree"
|
||||
- "pep" # pep requires mod_caps
|
||||
mod_register:
|
||||
## mod_register:
|
||||
##
|
||||
## Protect In-Band account registrations with CAPTCHA.
|
||||
##
|
||||
## captcha_protected: true
|
||||
|
||||
## captcha_protected: true
|
||||
##
|
||||
## Set the minimum informational entropy for passwords.
|
||||
##
|
||||
## password_strength: 32
|
||||
|
||||
## password_strength: 32
|
||||
##
|
||||
## After successful registration, the user receives
|
||||
## a message with this subject and body.
|
||||
##
|
||||
welcome_message:
|
||||
subject: "Welcome!"
|
||||
body: |-
|
||||
Hi.
|
||||
Welcome to this XMPP server.
|
||||
|
||||
## welcome_message:
|
||||
## subject: "Welcome!"
|
||||
## body: |-
|
||||
## Hi.
|
||||
## Welcome to this XMPP server.
|
||||
##
|
||||
## When a user registers, send a notification to
|
||||
## these XMPP accounts.
|
||||
##
|
||||
## registration_watchers:
|
||||
## - "admin1@example.org"
|
||||
|
||||
## registration_watchers:
|
||||
## - "admin1@example.org"
|
||||
##
|
||||
## Only clients in the server machine can register accounts
|
||||
##
|
||||
ip_access: trusted_network
|
||||
|
||||
## ip_access: trusted_network
|
||||
##
|
||||
## Local c2s or remote s2s users cannot register accounts
|
||||
##
|
||||
## access_from: deny
|
||||
|
||||
access: register
|
||||
## access_from: deny
|
||||
## access: register
|
||||
mod_roster: {}
|
||||
mod_shared_roster: {}
|
||||
mod_stats: {}
|
||||
mod_time: {}
|
||||
mod_vcard: {}
|
||||
mod_vcard:
|
||||
search: false
|
||||
mod_version: {}
|
||||
|
||||
##
|
||||
|
||||
@@ -169,6 +169,18 @@
|
||||
#
|
||||
#CONTRIB_MODULES_PATH=/opt/ejabberd-modules
|
||||
|
||||
#.
|
||||
#' CONTRIB_MODULES_CONF_DIR: configuration directory for contributed modules
|
||||
#
|
||||
# Specify the full path to the configuration directory for contributed ejabberd
|
||||
# modules. In order to configure a module named mod_foo, a mod_foo.yml file can
|
||||
# be created in this directory. This file will then be used instead of the
|
||||
# default configuration file provided with the module.
|
||||
#
|
||||
# Default: $CONTRIB_MODULES_PATH/conf
|
||||
#
|
||||
#CONTRIB_MODULES_CONF_DIR=/etc/ejabberd/modules
|
||||
|
||||
#.
|
||||
#'
|
||||
# vim: foldmarker=#',#. foldmethod=marker:
|
||||
|
||||
+145
-187
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
# define default configuration
|
||||
POLL=true
|
||||
@@ -13,8 +13,9 @@ ERLANG_NODE=ejabberd@localhost
|
||||
SCRIPT_DIR=`cd ${0%/*} && pwd`
|
||||
ERL={{erl}}
|
||||
IEX={{bindir}}/iex
|
||||
EPMD={{bindir}}/epmd
|
||||
EPMD={{epmd}}
|
||||
INSTALLUSER={{installuser}}
|
||||
ERL_LIBS={{libdir}}
|
||||
|
||||
# check the proper system user is used if defined
|
||||
if [ "$INSTALLUSER" != "" ] ; then
|
||||
@@ -30,30 +31,31 @@ if [ "$INSTALLUSER" != "" ] ; then
|
||||
fi
|
||||
done
|
||||
if [ `id -g` -eq `id -g $INSTALLUSER` ] ; then
|
||||
EXEC_CMD="sh -c"
|
||||
EXEC_CMD="bash -c"
|
||||
fi
|
||||
if [ "$EXEC_CMD" = "false" ] ; then
|
||||
echo "This command can only be run by root or the user $INSTALLUSER" >&2
|
||||
exit 4
|
||||
fi
|
||||
else
|
||||
EXEC_CMD="sh -c"
|
||||
EXEC_CMD="bash -c"
|
||||
fi
|
||||
|
||||
# parse command line parameters
|
||||
ARGS=""
|
||||
declare -a ARGS=()
|
||||
while [ $# -ne 0 ] ; do
|
||||
PARAM=$1
|
||||
PARAM="$1"
|
||||
shift
|
||||
case $PARAM in
|
||||
--) break ;;
|
||||
--no-timeout) EJABBERD_NO_TIMEOUT="--no-timeout" ;;
|
||||
--node) ERLANG_NODE_ARG=$1 ; shift ;;
|
||||
--config-dir) ETC_DIR="$1" ; shift ;;
|
||||
--config) EJABBERD_CONFIG_PATH="$1" ; shift ;;
|
||||
--ctl-config) EJABBERDCTL_CONFIG_PATH="$1" ; shift ;;
|
||||
--logs) LOGS_DIR="$1" ; shift ;;
|
||||
--spool) SPOOL_DIR="$1" ; shift ;;
|
||||
*) ARGS="$ARGS $PARAM" ;;
|
||||
*) ARGS=("${ARGS[@]}" "$PARAM") ;;
|
||||
esac
|
||||
done
|
||||
|
||||
@@ -81,30 +83,11 @@ if [ "$EJABBERD_DOC_PATH" = "" ] ; then
|
||||
fi
|
||||
if [ "$ERLANG_NODE_ARG" != "" ] ; then
|
||||
ERLANG_NODE=$ERLANG_NODE_ARG
|
||||
NODE=${ERLANG_NODE%@*}
|
||||
fi
|
||||
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
|
||||
if [ "{{release}}" != "true" -a "$EJABBERD_BIN_PATH" = "" ] ; then
|
||||
EJABBERD_BIN_PATH={{libdir}}/ejabberd/priv/bin
|
||||
fi
|
||||
EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
|
||||
SASL_LOG_PATH=$LOGS_DIR/erlang.log
|
||||
DATETIME=`date "+%Y%m%d-%H%M%S"`
|
||||
ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump
|
||||
ERL_INETRC=$ETC_DIR/inetrc
|
||||
@@ -112,7 +95,6 @@ ERL_INETRC=$ETC_DIR/inetrc
|
||||
# define mnesia options
|
||||
MNESIA_OPTS="-mnesia dir \"\\\"$SPOOL_DIR\\\"\" $MNESIA_OPTIONS"
|
||||
# define erl parameters
|
||||
ERL_OPTIONS=$(echo $ERL_OPTIONS | sed 's/ /\\ /g')
|
||||
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
|
||||
KERNEL_OPTS=""
|
||||
if [ "$FIREWALL_WINDOW" != "" ] ; then
|
||||
@@ -150,14 +132,12 @@ fi
|
||||
[ -z "$date" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_date '$date'"
|
||||
[ -z "$EJABBERD_OPTS" ] || EJABBERD_OPTS="-ejabberd ${EJABBERD_OPTS}"
|
||||
|
||||
[ -d $SPOOL_DIR ] || $EXEC_CMD "mkdir -p $SPOOL_DIR"
|
||||
cd $SPOOL_DIR
|
||||
[ -d "$SPOOL_DIR" ] || $EXEC_CMD "mkdir -p $SPOOL_DIR"
|
||||
cd "$SPOOL_DIR"
|
||||
|
||||
# export global variables
|
||||
export EJABBERD_CONFIG_PATH
|
||||
export EJABBERD_MSGS_PATH
|
||||
export EJABBERD_LOG_PATH
|
||||
export EJABBERD_SO_PATH
|
||||
export EJABBERD_BIN_PATH
|
||||
export EJABBERD_DOC_PATH
|
||||
export EJABBERD_PID_PATH
|
||||
@@ -167,75 +147,117 @@ export ERL_INETRC
|
||||
export ERL_MAX_PORTS
|
||||
export ERL_MAX_ETS_TABLES
|
||||
export CONTRIB_MODULES_PATH
|
||||
export CONTRIB_MODULES_CONF_DIR
|
||||
export ERL_LIBS
|
||||
|
||||
shell_escape_str()
|
||||
{
|
||||
if test $# -eq 0; then
|
||||
printf '"" '
|
||||
else
|
||||
shell_escape "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
shell_escape()
|
||||
{
|
||||
local RES=()
|
||||
for i in "$@"; do
|
||||
if test -z "$i"; then
|
||||
printf '"" '
|
||||
else
|
||||
printf '%q ' "$i"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# start server
|
||||
start()
|
||||
{
|
||||
check_start
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME $ERLANG_NODE \
|
||||
-noinput -detached \
|
||||
-pa $EJABBERD_EBIN_PATH \
|
||||
$MNESIA_OPTS \
|
||||
$KERNEL_OPTS \
|
||||
$EJABBERD_OPTS \
|
||||
-s ejabberd \
|
||||
-sasl sasl_error_logger \\{file,\\\"$SASL_LOG_PATH\\\"\\} \
|
||||
$ERLANG_OPTS $ARGS \"$@\""
|
||||
CMD="`shell_escape \"$ERL\" \"$NAME\" \"$ERLANG_NODE\"` \
|
||||
-noinput -detached \
|
||||
$MNESIA_OPTS \
|
||||
$KERNEL_OPTS \
|
||||
$EJABBERD_OPTS \
|
||||
-s ejabberd \
|
||||
$ERLANG_OPTS \
|
||||
`shell_escape \"${ARGS[@]}\" \"$@\"`"
|
||||
$EXEC_CMD "$CMD"
|
||||
}
|
||||
|
||||
# attach to server
|
||||
debug()
|
||||
{
|
||||
debugwarning
|
||||
TTY=`tty | sed -e 's/.*\///g'`
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME debug-${TTY}-${ERLANG_NODE} \
|
||||
-remsh $ERLANG_NODE \
|
||||
-hidden \
|
||||
$KERNEL_OPTS \
|
||||
$ERLANG_OPTS $ARGS \"$@\""
|
||||
NID=$(uid debug)
|
||||
CMD="`shell_escape \"$ERL\" \"$NAME\" \"$NID\"` \
|
||||
-remsh $ERLANG_NODE \
|
||||
-hidden \
|
||||
$KERNEL_OPTS \
|
||||
$ERLANG_OPTS \
|
||||
`shell_escape \"${ARGS[@]}\" \"$@\"`"
|
||||
$EXEC_CMD "$CMD"
|
||||
}
|
||||
|
||||
# attach to server using Elixir
|
||||
iexdebug()
|
||||
{
|
||||
debugwarning
|
||||
TTY=`tty | sed -e 's/.*\///g'`
|
||||
# Elixir shell is hidden as default
|
||||
$EXEC_CMD "$IEX \
|
||||
$IEXNAME debug-${TTY}-${ERLANG_NODE} \
|
||||
--remsh $ERLANG_NODE \
|
||||
--erl \"$KERNEL_OPTS\" \
|
||||
--erl \"$ERLANG_OPTS\" --erl \"$ARGS\" --erl \"$@\""
|
||||
NID=$(uid debug)
|
||||
CMD="`shell_escape \"$IEX\" \"$IEXNAME\" \"$NID\"` \
|
||||
-remsh $ERLANG_NODE \
|
||||
--erl `shell_escape \"$KERNEL_OPTS\"` \
|
||||
--erl `shell_escape \"$ERLANG_OPTS\"` \
|
||||
--erl `shell_escape \"${ARGS[@]}\"` \
|
||||
--erl `shell_escape_str \"$@\"`"
|
||||
$EXEC_CMD "ERL_PATH=\"$ERL\" $CMD"
|
||||
}
|
||||
|
||||
# start interactive server
|
||||
live()
|
||||
{
|
||||
livewarning
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME $ERLANG_NODE \
|
||||
-pa $EJABBERD_EBIN_PATH \
|
||||
$MNESIA_OPTS \
|
||||
$KERNEL_OPTS \
|
||||
$EJABBERD_OPTS \
|
||||
-s ejabberd \
|
||||
$ERLANG_OPTS $ARGS \"$@\""
|
||||
CMD="`shell_escape \"$ERL\" \"$NAME\" \"${ERLANG_NODE}\"` \
|
||||
$MNESIA_OPTS \
|
||||
$KERNEL_OPTS \
|
||||
$EJABBERD_OPTS \
|
||||
-s ejabberd \
|
||||
$ERLANG_OPTS \
|
||||
`shell_escape \"${ARGS[@]}\" \"$@\"`"
|
||||
$EXEC_CMD "$CMD"
|
||||
}
|
||||
|
||||
# start interactive server with Elixir
|
||||
iexlive()
|
||||
{
|
||||
livewarning
|
||||
$EXEC_CMD "$IEX \
|
||||
$IEXNAME $ERLANG_NODE \
|
||||
-pa $EJABBERD_EBIN_PATH \
|
||||
--erl \"-mnesia dir \\\"$SPOOL_DIR\\\"\" \
|
||||
--erl \"$KERNEL_OPTS\" \
|
||||
--erl \"$EJABBERD_OPTS\" \
|
||||
--app ejabberd \
|
||||
--erl \"$ERLANG_OPTS\" --erl $ARGS --erl \"$@\""
|
||||
echo $@
|
||||
CMD="`shell_escape \"$IEX\" \"$IEXNAME\" \"${ERLANG_NODE}\"` \
|
||||
--erl \"-mnesia dir \\\"$SPOOL_DIR\\\"\" \
|
||||
--erl \"`shell_escape \"$KERNEL_OPTS\"`\" \
|
||||
--erl \"`shell_escape \"$EJABBERD_OPTS\"`\" \
|
||||
--app ejabberd \
|
||||
--erl `shell_escape \"$ERLANG_OPTS\"` \
|
||||
--erl `shell_escape \"${ARGS[@]}\"` \
|
||||
--erl `shell_escape_str \"$@\"`"
|
||||
$EXEC_CMD "ERL_PATH=\"$ERL\" $CMD"
|
||||
}
|
||||
|
||||
# start server in the foreground
|
||||
foreground()
|
||||
{
|
||||
check_start
|
||||
CMD="`shell_escape \"$ERL\" \"$NAME\" \"$ERLANG_NODE\"` \
|
||||
-noinput \
|
||||
$MNESIA_OPTS \
|
||||
$KERNEL_OPTS \
|
||||
$EJABBERD_OPTS \
|
||||
-s ejabberd \
|
||||
$ERLANG_OPTS \
|
||||
`shell_escape \"${ARGS[@]}\" \"$@\"`"
|
||||
$EXEC_CMD "$CMD"
|
||||
}
|
||||
|
||||
debugwarning()
|
||||
@@ -288,21 +310,27 @@ livewarning()
|
||||
|
||||
etop()
|
||||
{
|
||||
TTY=`tty | sed -e 's/.*\///g'`
|
||||
NID=$(uid top)
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME debug-${TTY}-${ERLANG_NODE} \
|
||||
$NAME $NID \
|
||||
-hidden -s etop -s erlang halt -output text -node $ERLANG_NODE"
|
||||
}
|
||||
|
||||
ping()
|
||||
{
|
||||
TTY=`tty | sed -e 's/.*\///g'`
|
||||
[ -z "$1" ] && PEER=${ERLANG_NODE} || PEER=$1
|
||||
if [ "$PEER" = "${PEER%.*}" ] ; then
|
||||
PING_NAME="-sname"
|
||||
PING_NODE=$(hostname -s)
|
||||
else
|
||||
PING_NAME="-name"
|
||||
PING_NODE=$(hostname)
|
||||
fi
|
||||
NID=$(uid ping ${PING_NODE})
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME ping-${TTY}-${ERLANG_NODE} \
|
||||
-hidden \
|
||||
-pa $EJABBERD_EBIN_PATH \
|
||||
$KERNEL_OPTS $ERLANG_OPTS \
|
||||
-eval 'io:format(\"~p~n\",[net_adm:ping($1)])' \
|
||||
$PING_NAME $NID \
|
||||
-hidden $KERNEL_OPTS $ERLANG_OPTS \
|
||||
-eval 'io:format(\"~p~n\",[net_adm:ping('\"'\"'$PEER'\"'\"')])' \
|
||||
-s erlang halt -output text -noinput"
|
||||
}
|
||||
|
||||
@@ -310,11 +338,12 @@ help()
|
||||
{
|
||||
echo ""
|
||||
echo "Commands to start an ejabberd node:"
|
||||
echo " start Start an ejabberd node in server mode"
|
||||
echo " debug Attach an interactive Erlang shell to a running ejabberd node"
|
||||
echo " iexdebug Attach an interactive Elixir shell to a running ejabberd node"
|
||||
echo " live Start an ejabberd node in live (interactive) mode"
|
||||
echo " iexlive Start an ejabberd node in live (interactive) mode, within an Elixir shell"
|
||||
echo " start Start an ejabberd node in server mode"
|
||||
echo " debug Attach an interactive Erlang shell to a running ejabberd node"
|
||||
echo " iexdebug Attach an interactive Elixir shell to a running ejabberd node"
|
||||
echo " live Start an ejabberd node in live (interactive) mode"
|
||||
echo " iexlive Start an ejabberd node in live (interactive) mode, within an Elixir shell"
|
||||
echo " foreground Start an ejabberd node in server mode (attached)"
|
||||
echo ""
|
||||
echo "Optional parameters when starting an ejabberd node:"
|
||||
echo " --config-dir dir Config ejabberd: $ETC_DIR"
|
||||
@@ -329,102 +358,42 @@ help()
|
||||
# common control function
|
||||
ctl()
|
||||
{
|
||||
COMMAND=$@
|
||||
|
||||
# Control number of connections identifiers
|
||||
# using flock if available. Expects a linux-style
|
||||
# flock that can lock a file descriptor.
|
||||
MAXCONNID=100
|
||||
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
|
||||
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
|
||||
ssresult=$?
|
||||
# segregate from possible flock exit(1)
|
||||
ssresult=`expr $ssresult \* 10`
|
||||
exit $ssresult
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
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`
|
||||
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;
|
||||
fi
|
||||
|
||||
NID=$(uid ctl)
|
||||
CMD="`shell_escape \"$ERL\" \"$NAME\" \"$NID\"` \
|
||||
-noinput -hidden $KERNEL_OPTS -s ejabberd_ctl \
|
||||
-extra `shell_escape \"$ERLANG_NODE\"` $EJABBERD_NO_TIMEOUT \
|
||||
`shell_escape \"$@\"`"
|
||||
$EXEC_CMD "$CMD"
|
||||
result=$?
|
||||
case $result in
|
||||
0) :;;
|
||||
1) :;;
|
||||
2) help;;
|
||||
3) help;;
|
||||
*) :;;
|
||||
esac
|
||||
return $result
|
||||
}
|
||||
|
||||
ctlexec()
|
||||
uid()
|
||||
{
|
||||
CONN_NAME=$1; shift
|
||||
COMMAND=$(echo $@ | sed 's/["&$;\|<>()]/\\&/g')
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME ${CONN_NAME} \
|
||||
-noinput \
|
||||
-hidden \
|
||||
-pa $EJABBERD_EBIN_PATH \
|
||||
$KERNEL_OPTS \
|
||||
-s ejabberd_ctl -extra $ERLANG_NODE $COMMAND"
|
||||
uuid=$(uuidgen 2>/dev/null)
|
||||
[ -z "$uuid" -a -f /proc/sys/kernel/random/uuid ] && uuid=$(</proc/sys/kernel/random/uuid)
|
||||
[ -z "$uuid" ] && uuid=$(printf "%X" $RANDOM$(date +%M%S)$$)
|
||||
uuid=${uuid%%-*}
|
||||
[ $# -eq 0 ] && echo ${uuid}-${ERLANG_NODE}
|
||||
[ $# -eq 1 ] && echo ${uuid}-${1}-${ERLANG_NODE}
|
||||
[ $# -eq 2 ] && echo ${uuid}-${1}@${2}
|
||||
}
|
||||
|
||||
# stop epmd if there is no other running node
|
||||
stop_epmd()
|
||||
{
|
||||
$EPMD -names 2>/dev/null | grep -q name || $EPMD -kill >/dev/null
|
||||
"$EPMD" -names 2>/dev/null | grep -q name || "$EPMD" -kill >/dev/null
|
||||
}
|
||||
|
||||
# make sure node not already running and node name unregistered
|
||||
check_start()
|
||||
{
|
||||
$EPMD -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && {
|
||||
"$EPMD" -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && {
|
||||
ps ux | grep -v grep | grep -q " $ERLANG_NODE " && {
|
||||
echo "ERROR: The ejabberd node '$ERLANG_NODE' is already running."
|
||||
exit 4
|
||||
@@ -435,22 +404,12 @@ check_start()
|
||||
echo "Shutdown all other erlang nodes, and call 'epmd -kill'."
|
||||
exit 5
|
||||
} || {
|
||||
$EPMD -kill >/dev/null
|
||||
"$EPMD" -kill >/dev/null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# cluster setup
|
||||
join_cluster()
|
||||
{
|
||||
$EXEC_CMD "$EJABBERD_BIN_PATH/joincluster $*"
|
||||
}
|
||||
leave_cluster()
|
||||
{
|
||||
$EXEC_CMD "$EJABBERD_BIN_PATH/leavecluster $*"
|
||||
}
|
||||
|
||||
# allow sync calls
|
||||
wait_for_status()
|
||||
{
|
||||
@@ -472,17 +431,16 @@ wait_for_status()
|
||||
}
|
||||
|
||||
# main handler
|
||||
case $ARGS in
|
||||
' start') start;;
|
||||
' debug') debug;;
|
||||
' iexdebug') iexdebug;;
|
||||
' live') live;;
|
||||
' iexlive') iexlive;;
|
||||
' ping'*) ping ${ARGS# ping};;
|
||||
' 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
|
||||
' join_cluster'*) join_cluster ${ARGS# join_cluster};;
|
||||
' leave_cluster'*) leave_cluster ${ARGS# leave_cluster};;
|
||||
*) ctl $ARGS;;
|
||||
case "${ARGS[0]}" in
|
||||
'start') start;;
|
||||
'debug') debug;;
|
||||
'iexdebug') iexdebug;;
|
||||
'live') live;;
|
||||
'iexlive') iexlive;;
|
||||
'foreground') foreground;;
|
||||
'ping'*) ping ${ARGS[1]};;
|
||||
'etop') etop;;
|
||||
'started') wait_for_status 0 30 2;; # wait 30x2s before timeout
|
||||
'stopped') wait_for_status 3 30 2 && stop_epmd;; # wait 30x2s before timeout
|
||||
*) ctl "${ARGS[@]}";;
|
||||
esac
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(CT_XML,
|
||||
{<<"Content-Type">>, <<"text/xml; charset=utf-8">>}).
|
||||
|
||||
-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).
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -39,7 +39,9 @@
|
||||
|
||||
-define(EJABBERD_URI, <<"http://www.process-one.net/en/ejabberd/">>).
|
||||
|
||||
-define(S2STIMEOUT, 600000).
|
||||
-define(COPYRIGHT, "Copyright (c) 2002-2017 ProcessOne").
|
||||
|
||||
-define(S2STIMEOUT, timer:minutes(10)).
|
||||
|
||||
%%-define(DBGFSM, true).
|
||||
|
||||
@@ -64,7 +66,7 @@
|
||||
|
||||
-define(TDICT, dict:dict()).
|
||||
-define(TGB_TREE, gb_trees:tree()).
|
||||
-define(TGB_SET, gb_set:set()).
|
||||
-define(TGB_SET, gb_sets:set()).
|
||||
-define(TQUEUE, queue:queue()).
|
||||
|
||||
-endif.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -26,24 +26,55 @@
|
||||
{tuple, [rterm()]} | {list, rterm()} |
|
||||
rescode | restuple.
|
||||
|
||||
-type oauth_scope() :: atom().
|
||||
|
||||
%% ejabberd_commands OAuth ReST ACL definition:
|
||||
%% Two fields exist that are used to control access on a command from ReST API:
|
||||
%% 1. Policy
|
||||
%% If policy is:
|
||||
%% - restricted: command is not exposed as OAuth Rest API.
|
||||
%% - admin: Command is allowed for user that have Admin Rest command enabled by access rule: commands_admin_access
|
||||
%% - user: Command might be called by any server user.
|
||||
%% - open: Command can be called by anyone.
|
||||
%%
|
||||
%% Policy is just used to control who can call the command. A specific additional access rules can be performed, as
|
||||
%% defined by access option.
|
||||
%% Access option can be a list of:
|
||||
%% - {Module, accessName, DefaultValue}: Reference and existing module access to limit who can use the command.
|
||||
%% - AccessRule name: direct name of the access rule to check in config file.
|
||||
%% TODO: Access option could be atom command (not a list). In the case, User performing the command, will be added as first parameter
|
||||
%% to command, so that the command can perform additional check.
|
||||
|
||||
-record(ejabberd_commands,
|
||||
{name :: atom(),
|
||||
{name :: atom(),
|
||||
tags = [] :: [atom()] | '_' | '$2',
|
||||
desc = "" :: string() | '_' | '$3',
|
||||
longdesc = "" :: string() | '_',
|
||||
module :: atom(),
|
||||
function :: atom(),
|
||||
version = 0 :: integer(),
|
||||
weight = 1 :: integer(),
|
||||
module :: atom() | '_',
|
||||
function :: atom() | '_',
|
||||
args = [] :: [aterm()] | '_' | '$1' | '$2',
|
||||
policy = restricted :: open | restricted | admin | user,
|
||||
result = {res, rescode} :: rterm() | '_' | '$2'}).
|
||||
%% access is: [accessRuleName] or [{Module, AccessOption, DefaultAccessRuleName}]
|
||||
access = [] :: [{atom(),atom(),atom()}|atom()],
|
||||
result = {res, rescode} :: rterm() | '_' | '$2',
|
||||
args_desc = none :: none | [string()] | '_',
|
||||
result_desc = none :: none | string() | '_',
|
||||
args_example = none :: none | [any()] | '_',
|
||||
result_example = none :: any()}).
|
||||
|
||||
%% TODO Fix me: Type is not up to date
|
||||
-type ejabberd_commands() :: #ejabberd_commands{name :: atom(),
|
||||
tags :: [atom()],
|
||||
desc :: string(),
|
||||
longdesc :: string(),
|
||||
version :: integer(),
|
||||
module :: atom(),
|
||||
function :: atom(),
|
||||
args :: [aterm()],
|
||||
policy :: open | restricted | admin | user,
|
||||
access :: [{atom(),atom(),atom()}|atom()],
|
||||
result :: rterm()}.
|
||||
|
||||
%% @type ejabberd_commands() = #ejabberd_commands{
|
||||
@@ -72,4 +103,3 @@
|
||||
|
||||
%% @type rterm() = {Name::atom(), Type::rtype()}.
|
||||
%% A result term is a tuple with the term name and the term type.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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,25 +19,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(request,
|
||||
{method, % :: method(),
|
||||
{method :: method(),
|
||||
path = [] :: [binary()],
|
||||
q = [] :: [{binary() | nokey, binary()}],
|
||||
us = {<<>>, <<>>} :: {binary(), binary()},
|
||||
auth :: {binary(), binary()} |
|
||||
{auth_jid, {binary(), binary()}, jlib:jid()},
|
||||
auth :: {binary(), binary()} | {oauth, binary(), []} | undefined,
|
||||
lang = <<"">> :: binary(),
|
||||
data = <<"">> :: binary(),
|
||||
ip :: {inet:ip_address(), inet:port_number()},
|
||||
host = <<"">> :: binary(),
|
||||
port = 5280 :: inet:port_number(),
|
||||
tp = http, % :: protocol(),
|
||||
opts = [] :: list(),
|
||||
tp = http :: protocol(),
|
||||
headers = [] :: [{atom() | binary(), binary()}]}).
|
||||
|
||||
|
||||
-record(ws,
|
||||
{socket :: inet:socket() | p1_tls:tls_socket(),
|
||||
sockmod = gen_tcp :: gen_tcp | p1_tls,
|
||||
{socket :: inet:socket() | fast_tls:tls_socket(),
|
||||
sockmod = gen_tcp :: gen_tcp | fast_tls,
|
||||
ip :: {inet:ip_address(), inet:port_number()},
|
||||
host = <<"">> :: binary(),
|
||||
port = 5280 :: inet:port_number(),
|
||||
@@ -47,3 +45,7 @@
|
||||
q = [] :: [{binary() | nokey, binary()}],
|
||||
buf :: binary(),
|
||||
http_opts = [] :: list()}).
|
||||
|
||||
-type method() :: 'GET' | 'HEAD' | 'DELETE' | 'OPTIONS' | 'PUT' | 'POST' | 'TRACE'.
|
||||
-type protocol() :: http | https.
|
||||
-type http_request() :: #request{}.
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(oauth_token, {
|
||||
token = <<"">> :: binary() | '_',
|
||||
us = {<<"">>, <<"">>} :: {binary(), binary()} | '_',
|
||||
scope = [] :: [binary()] | '_',
|
||||
expire :: integer() | '$1'
|
||||
}).
|
||||
+23
-2
@@ -1,12 +1,33 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-ifndef(EJABBERD_SM_HRL).
|
||||
-define(EJABBERD_SM_HRL, true).
|
||||
|
||||
-record(session, {sid, usr, us, priority, info}).
|
||||
-record(session, {sid, usr, us, priority, info = []}).
|
||||
-record(session_counter, {vhost, count}).
|
||||
-type sid() :: {erlang:timestamp(), pid()}.
|
||||
-type ip() :: {inet:ip_address(), inet:port_number()} | undefined.
|
||||
-type info() :: [{conn, atom()} | {ip, ip()} | {node, atom()}
|
||||
| {oor, boolean()} | {auth_module, atom()}].
|
||||
| {oor, boolean()} | {auth_module, atom()}
|
||||
| {num_stanzas_in, non_neg_integer()}].
|
||||
-type prio() :: undefined | integer().
|
||||
|
||||
-endif.
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(SQL_MARK, sql__mark_).
|
||||
-define(SQL(SQL), ?SQL_MARK(SQL)).
|
||||
|
||||
-define(SQL_UPSERT_MARK, sql_upsert__mark_).
|
||||
-define(SQL_UPSERT(Host, Table, Fields),
|
||||
ejabberd_sql:sql_query(Host, ?SQL_UPSERT_MARK(Table, Fields))).
|
||||
-define(SQL_UPSERT_T(Table, Fields),
|
||||
ejabberd_sql:sql_query_t(?SQL_UPSERT_MARK(Table, Fields))).
|
||||
|
||||
-record(sql_query, {hash, format_query, format_res, args, loc}).
|
||||
|
||||
-record(sql_escape, {string, integer, boolean}).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
+2
-6
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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,11 +19,7 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-include("ns.hrl").
|
||||
-ifdef(NO_EXT_LIB).
|
||||
-include("xml.hrl").
|
||||
-else.
|
||||
-include_lib("p1_xml/include/xml.hrl").
|
||||
-endif.
|
||||
-include("fxml.hrl").
|
||||
|
||||
-define(STANZA_ERROR(Code, Type, Condition),
|
||||
#xmlel{name = <<"error">>,
|
||||
|
||||
+8
-20
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -17,9 +17,8 @@
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
-define(PRINT(Format, Args), io:format(Format, Args)).
|
||||
|
||||
-ifdef(LAGER).
|
||||
-define(PRINT(Format, Args), io:format(Format, Args)).
|
||||
-compile([{parse_transform, lager_transform}]).
|
||||
|
||||
-define(DEBUG(Format, Args),
|
||||
@@ -37,20 +36,9 @@
|
||||
-define(CRITICAL_MSG(Format, Args),
|
||||
lager:critical(Format, Args)).
|
||||
|
||||
-else.
|
||||
|
||||
-define(DEBUG(Format, Args),
|
||||
p1_logger:debug_msg(?MODULE, ?LINE, Format, Args)).
|
||||
|
||||
-define(INFO_MSG(Format, Args),
|
||||
p1_logger:info_msg(?MODULE, ?LINE, Format, Args)).
|
||||
|
||||
-define(WARNING_MSG(Format, Args),
|
||||
p1_logger:warning_msg(?MODULE, ?LINE, Format, Args)).
|
||||
|
||||
-define(ERROR_MSG(Format, Args),
|
||||
p1_logger:error_msg(?MODULE, ?LINE, Format, Args)).
|
||||
|
||||
-define(CRITICAL_MSG(Format, Args),
|
||||
p1_logger:critical_msg(?MODULE, ?LINE, Format, Args)).
|
||||
-endif.
|
||||
%% Use only when trying to troubleshoot test problem with ExUnit
|
||||
-define(EXUNIT_LOG(Format, Args),
|
||||
case lists:keyfind(logger, 1, application:loaded_applications()) of
|
||||
false -> ok;
|
||||
_ -> 'Elixir.Logger':bare_log(error, io_lib:format(Format, Args), [?MODULE])
|
||||
end).
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(motd, {server = <<"">> :: binary(),
|
||||
packet = #xmlel{} :: xmlel()}).
|
||||
|
||||
-record(motd_users, {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$1',
|
||||
dummy = [] :: [] | '_'}).
|
||||
@@ -0,0 +1,24 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(caps_features,
|
||||
{node_pair = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
features = [] :: [binary()] | pos_integer()
|
||||
}).
|
||||
@@ -0,0 +1,24 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-type matchspec_atom() :: '_' | '$1' | '$2' | '$3'.
|
||||
-record(carboncopy, {us :: {binary(), binary()} | matchspec_atom(),
|
||||
resource :: binary() | matchspec_atom(),
|
||||
version :: binary() | matchspec_atom()}).
|
||||
@@ -0,0 +1,35 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-type conn_param() :: {binary(), binary(), inet:port_number(), binary()} |
|
||||
{binary(), binary(), inet:port_number()} |
|
||||
{binary(), binary()} |
|
||||
{binary()}.
|
||||
|
||||
-type irc_data() :: [{username, binary()} | {connections_params, [conn_param()]}].
|
||||
|
||||
-record(irc_connection,
|
||||
{jid_server_host = {#jid{}, <<"">>, <<"">>} :: {jid(), binary(), binary()},
|
||||
pid = self() :: pid()}).
|
||||
|
||||
-record(irc_custom,
|
||||
{us_host = {{<<"">>, <<"">>}, <<"">>} :: {{binary(), binary()},
|
||||
binary()},
|
||||
data = [] :: irc_data()}).
|
||||
@@ -0,0 +1,23 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(last_activity, {us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
timestamp = 0 :: non_neg_integer(),
|
||||
status = <<"">> :: binary()}).
|
||||
@@ -0,0 +1,35 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(archive_msg,
|
||||
{us = {<<"">>, <<"">>} :: {binary(), binary()} | '$2',
|
||||
id = <<>> :: binary() | '_',
|
||||
timestamp = p1_time_compat:timestamp() :: erlang:timestamp() | '_' | '$1',
|
||||
peer = {<<"">>, <<"">>, <<"">>} :: ljid() | '_' | '$3' | undefined,
|
||||
bare_peer = {<<"">>, <<"">>, <<"">>} :: ljid() | '_' | '$3',
|
||||
packet = #xmlel{} :: xmlel() | message() | '_',
|
||||
nick = <<"">> :: binary(),
|
||||
type = chat :: chat | groupchat}).
|
||||
|
||||
-record(archive_prefs,
|
||||
{us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
default = never :: never | always | roster,
|
||||
always = [] :: [ljid()],
|
||||
never = [] :: [ljid()]}).
|
||||
@@ -0,0 +1,32 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(muc_room, {name_host = {<<"">>, <<"">>} :: {binary(), binary()} |
|
||||
{'_', binary()},
|
||||
opts = [] :: list() | '_'}).
|
||||
|
||||
-record(muc_online_room,
|
||||
{name_host = {<<"">>, <<"">>} :: {binary(), binary()} | '$1' |
|
||||
{'_', binary()} | '_',
|
||||
pid = self() :: pid() | '$2' | '_' | '$1'}).
|
||||
|
||||
-record(muc_registered,
|
||||
{us_host = {{<<"">>, <<"">>}, <<"">>} :: {{binary(), binary()}, binary()} | '$1',
|
||||
nick = <<"">> :: binary()}).
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -53,9 +53,12 @@
|
||||
members_by_default = true :: boolean(),
|
||||
members_only = false :: boolean(),
|
||||
allow_user_invites = false :: boolean(),
|
||||
allow_subscription = false :: boolean(),
|
||||
password_protected = false :: boolean(),
|
||||
password = <<"">> :: binary(),
|
||||
anonymous = true :: boolean(),
|
||||
presence_broadcast = [moderator, participant, visitor] ::
|
||||
[moderator | participant | visitor],
|
||||
allow_voice_requests = true :: boolean(),
|
||||
voice_request_min_interval = 1800 :: non_neg_integer(),
|
||||
max_users = ?MAX_USERS_DEFAULT :: non_neg_integer() | none,
|
||||
@@ -68,15 +71,22 @@
|
||||
-type config() :: #config{}.
|
||||
|
||||
-type role() :: moderator | participant | visitor | none.
|
||||
-type affiliation() :: admin | member | outcast | owner | none.
|
||||
|
||||
-record(user,
|
||||
{
|
||||
jid :: jid(),
|
||||
nick :: binary(),
|
||||
role :: role(),
|
||||
%%is_subscriber = false :: boolean(),
|
||||
%%subscriptions = [] :: [binary()],
|
||||
last_presence :: xmlel()
|
||||
}).
|
||||
|
||||
-record(subscriber, {jid :: jid(),
|
||||
nick = <<>> :: binary(),
|
||||
nodes = [] :: [binary()]}).
|
||||
|
||||
-record(activity,
|
||||
{
|
||||
message_time = 0 :: integer(),
|
||||
@@ -96,6 +106,8 @@
|
||||
jid = #jid{} :: jid(),
|
||||
config = #config{} :: config(),
|
||||
users = (?DICT):new() :: ?TDICT,
|
||||
subscribers = (?DICT):new() :: ?TDICT,
|
||||
subscriber_nicks = (?DICT):new() :: ?TDICT,
|
||||
last_voice_request_time = treap:empty() :: treap:treap(),
|
||||
robots = (?DICT):new() :: ?TDICT,
|
||||
nicks = (?DICT):new() :: ?TDICT,
|
||||
@@ -115,5 +127,3 @@
|
||||
host = <<>> :: binary() | '_' | '$2'}).
|
||||
|
||||
-type muc_online_users() :: #muc_online_users{}.
|
||||
|
||||
-type muc_room_state() :: #state{}.
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(offline_msg,
|
||||
{us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
timestamp = p1_time_compat:timestamp() :: erlang:timestamp() | '_',
|
||||
expire = p1_time_compat:timestamp() :: erlang:timestamp() | never | '_',
|
||||
from = #jid{} :: jid() | '_',
|
||||
to = #jid{} :: jid() | '_',
|
||||
packet = #xmlel{} :: xmlel() | '_'}).
|
||||
|
||||
-record(state,
|
||||
{host = <<"">> :: binary(),
|
||||
access_max_offline_messages}).
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
@@ -22,9 +22,11 @@
|
||||
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,
|
||||
-type privacy() :: #privacy{}.
|
||||
|
||||
-record(listitem, {type = none :: listitem_type(),
|
||||
value = none :: listitem_value(),
|
||||
action = allow :: listitem_action(),
|
||||
order = 0 :: integer(),
|
||||
match_all = false :: boolean(),
|
||||
match_iq = false :: boolean(),
|
||||
@@ -33,6 +35,9 @@
|
||||
match_presence_out = false :: boolean()}).
|
||||
|
||||
-type listitem() :: #listitem{}.
|
||||
-type listitem_type() :: none | jid | group | subscription.
|
||||
-type listitem_value() :: none | both | from | to | jid:ljid() | binary().
|
||||
-type listitem_action() :: allow | deny.
|
||||
|
||||
-record(userlist, {name = none :: none | binary(),
|
||||
list = [] :: [listitem()],
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(private_storage,
|
||||
{usns = {<<"">>, <<"">>, <<"">>} :: {binary(), binary(), binary() |
|
||||
'$1' | '_'},
|
||||
xml = #xmlel{} :: xmlel() | '_' | '$1'}).
|
||||
@@ -2,7 +2,7 @@
|
||||
%%% RFC 1928 constants.
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 ProcessOne
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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,15 +20,15 @@
|
||||
|
||||
-record(roster,
|
||||
{
|
||||
usj = {<<>>, <<>>, {<<>>, <<>>, <<>>}} :: {binary(), binary(), ljid()} | '_',
|
||||
usj = {<<>>, <<>>, {<<>>, <<>>, <<>>}} :: {binary(), binary(), jid:ljid()} | '_',
|
||||
us = {<<>>, <<>>} :: {binary(), binary()} | '_',
|
||||
jid = {<<>>, <<>>, <<>>} :: ljid(),
|
||||
jid = {<<>>, <<>>, <<>>} :: jid:ljid(),
|
||||
name = <<>> :: binary() | '_',
|
||||
subscription = none :: subscription() | '_',
|
||||
ask = none :: ask() | '_',
|
||||
groups = [] :: [binary()] | '_',
|
||||
askmessage = <<"">> :: binary() | '_',
|
||||
xs = [] :: [xmlel()] | '_'
|
||||
xs = [] :: [fxml:xmlel()] | '_'
|
||||
}).
|
||||
|
||||
-record(roster_version,
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(sr_group, {group_host = {<<"">>, <<"">>} :: {'$1' | binary(), '$2' | binary()},
|
||||
opts = [] :: list() | '_' | '$2'}).
|
||||
|
||||
-record(sr_user, {us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
group_host = {<<"">>, <<"">>} :: {binary(), binary()}}).
|
||||
@@ -0,0 +1,28 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(vcard_search,
|
||||
{us, user, luser, fn, lfn, family, lfamily, given,
|
||||
lgiven, middle, lmiddle, nickname, lnickname, bday,
|
||||
lbday, ctry, lctry, locality, llocality, email, lemail,
|
||||
orgname, lorgname, orgunit, lorgunit}).
|
||||
|
||||
-record(vcard, {us = {<<"">>, <<"">>} :: {binary(), binary()} | binary(),
|
||||
vcard = #xmlel{} :: xmlel()}).
|
||||
@@ -0,0 +1,22 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(vcard_xupdate, {us = {<<>>, <<>>} :: {binary(), binary()},
|
||||
hash = <<>> :: binary()}).
|
||||
-155
@@ -1,155 +0,0 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2015 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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_TIME, <<"urn:xmpp:time">>).
|
||||
-define(NS_LAST, <<"jabber:iq:last">>).
|
||||
-define(NS_XDATA, <<"jabber:x:data">>).
|
||||
-define(NS_IQDATA, <<"jabber:iq:data">>).
|
||||
-define(NS_DELAY, <<"urn:xmpp:delay">>).
|
||||
-define(NS_HINTS, <<"urn:xmpp:hints">>).
|
||||
-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_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">>).
|
||||
-define(NS_MAM_TMP, <<"urn:xmpp:mam:tmp">>).
|
||||
-define(NS_MAM_0, <<"urn:xmpp:mam:0">>).
|
||||
-define(NS_MAM_1, <<"urn:xmpp:mam:1">>).
|
||||
-define(NS_SID_0, <<"urn:xmpp:sid:0">>).
|
||||
-define(NS_PING, <<"urn:xmpp:ping">>).
|
||||
-define(NS_CARBONS_2, <<"urn:xmpp:carbons:2">>).
|
||||
-define(NS_CARBONS_1, <<"urn:xmpp:carbons:1">>).
|
||||
-define(NS_FORWARD, <<"urn:xmpp:forward:0">>).
|
||||
-define(NS_CLIENT_STATE, <<"urn:xmpp:csi:0">>).
|
||||
-define(NS_STREAM_MGMT_2, <<"urn:xmpp:sm:2">>).
|
||||
-define(NS_STREAM_MGMT_3, <<"urn:xmpp:sm:3">>).
|
||||
-define(NS_NICK, <<"http://jabber.org/protocol/nick">>).
|
||||
+26
-20
@@ -1,27 +1,22 @@
|
||||
%%% ====================================================================
|
||||
%%% ``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.
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is ProcessOne.
|
||||
%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2015, 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.
|
||||
%%%
|
||||
%%% copyright 2006-2015 ProcessOne
|
||||
%%% 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.,
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%% This file contains pubsub types definition.
|
||||
%%% ====================================================================
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
@@ -65,7 +60,7 @@
|
||||
%% note: pos_integer() should always be used, but we allow anything else coded
|
||||
%% as binary, so one can have a custom implementation of nodetree with custom
|
||||
%% indexing (see nodetree_virtual). this also allows to use any kind of key for
|
||||
%% indexing nodes, as this can be usefull with external backends such as odbc.
|
||||
%% indexing nodes, as this can be usefull with external backends such as sql.
|
||||
|
||||
-type(itemId() :: binary()).
|
||||
%% @type itemId() = string().
|
||||
@@ -93,7 +88,12 @@
|
||||
|
||||
-type(subOptions() :: [mod_pubsub:subOption(),...]).
|
||||
|
||||
-type(pubOption() ::
|
||||
{Option::binary(),
|
||||
Values::[binary()]
|
||||
}).
|
||||
|
||||
-type(pubOptions() :: [mod_pubsub:pubOption()]).
|
||||
|
||||
-type(affiliation() :: 'none'
|
||||
| 'owner'
|
||||
@@ -171,3 +171,9 @@
|
||||
creation ,% :: {erlang:timestamp(), jlib:ljid()},
|
||||
payload % :: mod_pubsub:payload()
|
||||
}).
|
||||
|
||||
-record(pubsub_orphan,
|
||||
{
|
||||
nodeid ,% :: mod_pubsub:nodeIdx(),
|
||||
items = [] % :: list()
|
||||
}).
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
defmodule ExUnit.CTFormatter do
|
||||
@moduledoc false
|
||||
|
||||
use GenEvent
|
||||
|
||||
import ExUnit.Formatter, only: [format_time: 2, format_test_failure: 5,
|
||||
format_test_case_failure: 5]
|
||||
|
||||
def init(opts) do
|
||||
file = File.open! "exunit.log", [:append]
|
||||
# We do not print filter in log file as exclusion of test with tag
|
||||
# pending: true is always done
|
||||
config = %{
|
||||
file: file,
|
||||
seed: opts[:seed],
|
||||
trace: opts[:trace],
|
||||
colors: Keyword.put_new(opts[:colors], :enabled, false),
|
||||
width: 80,
|
||||
tests_counter: 0,
|
||||
failures_counter: 0,
|
||||
skipped_counter: 0,
|
||||
invalids_counter: 0
|
||||
}
|
||||
{:ok, config}
|
||||
end
|
||||
|
||||
def handle_event({:suite_started, _opts}, config) do
|
||||
{:ok, config}
|
||||
end
|
||||
|
||||
def handle_event({:suite_finished, run_us, load_us}, config) do
|
||||
print_suite(config, run_us, load_us)
|
||||
File.close config[:file]
|
||||
:remove_handler
|
||||
end
|
||||
|
||||
def handle_event({:test_started, %ExUnit.Test{} = test}, config) do
|
||||
if config.tests_counter == 0, do: IO.binwrite config[:file], "== Running #{test.case} ==\n\n"
|
||||
{:ok, config}
|
||||
end
|
||||
|
||||
def handle_event({:test_finished, %ExUnit.Test{state: nil} = _test}, config) do
|
||||
IO.binwrite config[:file], "."
|
||||
{:ok, %{config | tests_counter: config.tests_counter + 1}}
|
||||
end
|
||||
|
||||
def handle_event({:test_finished, %ExUnit.Test{state: {:skip, _}} = _test}, config) do
|
||||
{:ok, %{config | tests_counter: config.tests_counter + 1,
|
||||
skipped_counter: config.skipped_counter + 1}}
|
||||
end
|
||||
|
||||
def handle_event({:test_finished, %ExUnit.Test{state: {:invalid, _}} = _test}, config) do
|
||||
IO.binwrite config[:file], "?"
|
||||
{:ok, %{config | tests_counter: config.tests_counter + 1,
|
||||
invalids_counter: config.invalids_counter + 1}}
|
||||
end
|
||||
|
||||
def handle_event({:test_finished, %ExUnit.Test{state: {:failed, failures}} = test}, config) do
|
||||
formatted = format_test_failure(test, failures, config.failures_counter + 1,
|
||||
config.width, &formatter(&1, &2, config))
|
||||
print_failure(formatted, config)
|
||||
print_logs(test.logs)
|
||||
|
||||
{:ok, %{config | tests_counter: config.tests_counter + 1,
|
||||
failures_counter: config.failures_counter + 1}}
|
||||
end
|
||||
|
||||
def handle_event({:case_started, %ExUnit.TestCase{}}, config) do
|
||||
{:ok, config}
|
||||
end
|
||||
|
||||
def handle_event({:case_finished, %ExUnit.TestCase{state: nil}}, config) do
|
||||
{:ok, config}
|
||||
end
|
||||
|
||||
def handle_event({:case_finished, %ExUnit.TestCase{state: {:failed, failures}} = test_case}, config) do
|
||||
formatted = format_test_case_failure(test_case, failures, config.failures_counter + 1,
|
||||
config.width, &formatter(&1, &2, config))
|
||||
print_failure(formatted, config)
|
||||
{:ok, %{config | failures_counter: config.failures_counter + 1}}
|
||||
end
|
||||
|
||||
## Printing
|
||||
|
||||
defp print_suite(config, run_us, load_us) do
|
||||
IO.binwrite config[:file], "\n\n"
|
||||
IO.binwrite config[:file], format_time(run_us, load_us)
|
||||
IO.binwrite config[:file], "\n\n"
|
||||
|
||||
# singular/plural
|
||||
test_pl = pluralize(config.tests_counter, "test", "tests")
|
||||
failure_pl = pluralize(config.failures_counter, "failure", "failures")
|
||||
|
||||
message =
|
||||
"#{config.tests_counter} #{test_pl}, #{config.failures_counter} #{failure_pl}"
|
||||
|> if_true(config.skipped_counter > 0, & &1 <> ", #{config.skipped_counter} skipped")
|
||||
|> if_true(config.invalids_counter > 0, & &1 <> ", #{config.invalids_counter} invalid")
|
||||
|
||||
cond do
|
||||
config.failures_counter > 0 -> IO.binwrite config[:file], message
|
||||
config.invalids_counter > 0 -> IO.binwrite config[:file], message
|
||||
true -> IO.binwrite config[:file], message
|
||||
end
|
||||
|
||||
IO.binwrite config[:file], "\nRandomized with seed #{config.seed}\n\n\n\n"
|
||||
end
|
||||
|
||||
defp if_true(value, false, _fun), do: value
|
||||
defp if_true(value, true, fun), do: fun.(value)
|
||||
|
||||
defp print_failure(formatted, config) do
|
||||
IO.binwrite config[:file], "\n"
|
||||
IO.binwrite config[:file], formatted
|
||||
IO.binwrite config[:file], "\n"
|
||||
end
|
||||
|
||||
defp formatter(_, msg, _config),
|
||||
do: msg
|
||||
|
||||
defp pluralize(1, singular, _plural), do: singular
|
||||
defp pluralize(_, _singular, plural), do: plural
|
||||
|
||||
defp print_logs(""), do: nil
|
||||
|
||||
defp print_logs(output) do
|
||||
indent = "\n "
|
||||
output = String.replace(output, "\n", indent)
|
||||
IO.puts([" The following output was logged:", indent | output])
|
||||
end
|
||||
end
|
||||
@@ -1,2 +0,0 @@
|
||||
defmodule Ejabberd do
|
||||
end
|
||||
@@ -0,0 +1,119 @@
|
||||
defmodule Ejabberd.Config.Attr do
|
||||
@moduledoc """
|
||||
Module used to work with the attributes parsed from
|
||||
an elixir block (do...end).
|
||||
|
||||
Contains functions for extracting attrs from a block
|
||||
and validation.
|
||||
"""
|
||||
|
||||
@type attr :: {atom(), any()}
|
||||
|
||||
@attr_supported [
|
||||
active:
|
||||
[type: :boolean, default: true],
|
||||
git:
|
||||
[type: :string, default: ""],
|
||||
name:
|
||||
[type: :string, default: ""],
|
||||
opts:
|
||||
[type: :list, default: []],
|
||||
dependency:
|
||||
[type: :list, default: []]
|
||||
]
|
||||
|
||||
@doc """
|
||||
Takes a block with annotations and extracts the list
|
||||
of attributes.
|
||||
"""
|
||||
@spec extract_attrs_from_block_with_defaults(any()) :: [attr]
|
||||
def extract_attrs_from_block_with_defaults(block) do
|
||||
block
|
||||
|> extract_attrs_from_block
|
||||
|> put_into_list_if_not_already
|
||||
|> insert_default_attrs_if_missing
|
||||
end
|
||||
|
||||
@doc """
|
||||
Takes an attribute or a list of attrs and validate them.
|
||||
|
||||
Returns a {:ok, attr} or {:error, attr, cause} for each of the attributes.
|
||||
"""
|
||||
@spec validate([attr]) :: [{:ok, attr}] | [{:error, attr, atom()}]
|
||||
def validate(attrs) when is_list(attrs), do: Enum.map(attrs, &valid_attr?/1)
|
||||
def validate(attr), do: validate([attr]) |> List.first
|
||||
|
||||
@doc """
|
||||
Returns the type of an attribute, given its name.
|
||||
"""
|
||||
@spec get_type_for_attr(atom()) :: atom()
|
||||
def get_type_for_attr(attr_name) do
|
||||
@attr_supported
|
||||
|> Keyword.get(attr_name)
|
||||
|> Keyword.get(:type)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the default value for an attribute, given its name.
|
||||
"""
|
||||
@spec get_default_for_attr(atom()) :: any()
|
||||
def get_default_for_attr(attr_name) do
|
||||
@attr_supported
|
||||
|> Keyword.get(attr_name)
|
||||
|> Keyword.get(:default)
|
||||
end
|
||||
|
||||
# Private API
|
||||
|
||||
# Given an elixir block (do...end) returns a list with the annotations
|
||||
# or a single annotation.
|
||||
@spec extract_attrs_from_block(any()) :: [attr] | attr
|
||||
defp extract_attrs_from_block({:__block__, [], attrs}), do: Enum.map(attrs, &extract_attrs_from_block/1)
|
||||
defp extract_attrs_from_block({:@, _, [attrs]}), do: extract_attrs_from_block(attrs)
|
||||
defp extract_attrs_from_block({attr_name, _, [value]}), do: {attr_name, value}
|
||||
defp extract_attrs_from_block(nil), do: []
|
||||
|
||||
# In case extract_attrs_from_block returns a single attribute,
|
||||
# then put it into a list. (Ensures attrs are always into a list).
|
||||
@spec put_into_list_if_not_already([attr] | attr) :: [attr]
|
||||
defp put_into_list_if_not_already(attrs) when is_list(attrs), do: attrs
|
||||
defp put_into_list_if_not_already(attr), do: [attr]
|
||||
|
||||
# Given a list of attributes, it inserts the missing attribute with their
|
||||
# default value.
|
||||
@spec insert_default_attrs_if_missing([attr]) :: [attr]
|
||||
defp insert_default_attrs_if_missing(attrs) do
|
||||
Enum.reduce @attr_supported, attrs, fn({attr_name, _}, acc) ->
|
||||
case Keyword.has_key?(acc, attr_name) do
|
||||
true -> acc
|
||||
false -> Keyword.put(acc, attr_name, get_default_for_attr(attr_name))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Given an attribute, validates it and return a tuple with
|
||||
# {:ok, attr} or {:error, attr, cause}
|
||||
@spec valid_attr?(attr) :: {:ok, attr} | {:error, attr, atom()}
|
||||
defp valid_attr?({attr_name, param} = attr) do
|
||||
case Keyword.get(@attr_supported, attr_name) do
|
||||
nil -> {:error, attr, :attr_not_supported}
|
||||
[{:type, param_type} | _] -> case is_of_type?(param, param_type) do
|
||||
true -> {:ok, attr}
|
||||
false -> {:error, attr, :type_not_supported}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Given an attribute value and a type, it returns a true
|
||||
# if the value its of the type specified, false otherwise.
|
||||
|
||||
# Usefoul for checking if an attr value respects the type
|
||||
# specified for the annotation.
|
||||
@spec is_of_type?(any(), atom()) :: boolean()
|
||||
defp is_of_type?(param, type) when type == :boolean and is_boolean(param), do: true
|
||||
defp is_of_type?(param, type) when type == :string and is_bitstring(param), do: true
|
||||
defp is_of_type?(param, type) when type == :list and is_list(param), do: true
|
||||
defp is_of_type?(param, type) when type == :atom and is_atom(param), do: true
|
||||
defp is_of_type?(_param, type) when type == :any, do: true
|
||||
defp is_of_type?(_, _), do: false
|
||||
end
|
||||
@@ -0,0 +1,145 @@
|
||||
defmodule Ejabberd.Config do
|
||||
@moduledoc """
|
||||
Base module for configuration file.
|
||||
|
||||
Imports macros for the config DSL and contains functions
|
||||
for working/starting the configuration parsed.
|
||||
"""
|
||||
|
||||
alias Ejabberd.Config.EjabberdModule
|
||||
alias Ejabberd.Config.Attr
|
||||
alias Ejabberd.Config.EjabberdLogger
|
||||
|
||||
defmacro __using__(_opts) do
|
||||
quote do
|
||||
import Ejabberd.Config, only: :macros
|
||||
import Ejabberd.Logger
|
||||
|
||||
@before_compile Ejabberd.Config
|
||||
end
|
||||
end
|
||||
|
||||
# Validate the modules parsed and log validation errors at compile time.
|
||||
# Could be also possible to interrupt the compilation&execution by throwing
|
||||
# an exception if necessary.
|
||||
def __before_compile__(_env) do
|
||||
get_modules_parsed_in_order
|
||||
|> EjabberdModule.validate
|
||||
|> EjabberdLogger.log_errors
|
||||
end
|
||||
|
||||
@doc """
|
||||
Given the path of the config file, it evaluates it.
|
||||
"""
|
||||
def init(file_path, force \\ false) do
|
||||
init_already_executed = Ejabberd.Config.Store.get(:module_name) != []
|
||||
|
||||
case force do
|
||||
true ->
|
||||
Ejabberd.Config.Store.stop
|
||||
Ejabberd.Config.Store.start_link
|
||||
do_init(file_path)
|
||||
false ->
|
||||
if not init_already_executed, do: do_init(file_path)
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns a list with all the opts, formatted for ejabberd.
|
||||
"""
|
||||
def get_ejabberd_opts do
|
||||
get_general_opts
|
||||
|> Dict.put(:modules, get_modules_parsed_in_order())
|
||||
|> Dict.put(:listeners, get_listeners_parsed_in_order())
|
||||
|> Ejabberd.Config.OptsFormatter.format_opts_for_ejabberd
|
||||
end
|
||||
|
||||
@doc """
|
||||
Register the hooks defined inside the elixir config file.
|
||||
"""
|
||||
def start_hooks do
|
||||
get_hooks_parsed_in_order()
|
||||
|> Enum.each(&Ejabberd.Config.EjabberdHook.start/1)
|
||||
end
|
||||
|
||||
###
|
||||
### MACROS
|
||||
###
|
||||
|
||||
defmacro listen(module, do: block) do
|
||||
attrs = Attr.extract_attrs_from_block_with_defaults(block)
|
||||
|
||||
quote do
|
||||
Ejabberd.Config.Store.put(:listeners, %EjabberdModule{
|
||||
module: unquote(module),
|
||||
attrs: unquote(attrs)
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
defmacro module(module, do: block) do
|
||||
attrs = Attr.extract_attrs_from_block_with_defaults(block)
|
||||
|
||||
quote do
|
||||
Ejabberd.Config.Store.put(:modules, %EjabberdModule{
|
||||
module: unquote(module),
|
||||
attrs: unquote(attrs)
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
defmacro hook(hook_name, opts, fun) do
|
||||
quote do
|
||||
Ejabberd.Config.Store.put(:hooks, %Ejabberd.Config.EjabberdHook{
|
||||
hook: unquote(hook_name),
|
||||
opts: unquote(opts),
|
||||
fun: unquote(fun)
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
# Private API
|
||||
|
||||
defp do_init(file_path) do
|
||||
# File evaluation
|
||||
Code.eval_file(file_path) |> extract_and_store_module_name()
|
||||
|
||||
# Getting start/0 config
|
||||
Ejabberd.Config.Store.get(:module_name)
|
||||
|> case do
|
||||
nil -> IO.puts "[ ERR ] Configuration module not found."
|
||||
[module] -> call_start_func_and_store_data(module)
|
||||
end
|
||||
|
||||
# Fetching git modules and install them
|
||||
get_modules_parsed_in_order()
|
||||
|> EjabberdModule.fetch_git_repos
|
||||
end
|
||||
|
||||
# Returns the modules from the store
|
||||
defp get_modules_parsed_in_order,
|
||||
do: Ejabberd.Config.Store.get(:modules) |> Enum.reverse
|
||||
|
||||
# Returns the listeners from the store
|
||||
defp get_listeners_parsed_in_order,
|
||||
do: Ejabberd.Config.Store.get(:listeners) |> Enum.reverse
|
||||
|
||||
defp get_hooks_parsed_in_order,
|
||||
do: Ejabberd.Config.Store.get(:hooks) |> Enum.reverse
|
||||
|
||||
# Returns the general config options
|
||||
defp get_general_opts,
|
||||
do: Ejabberd.Config.Store.get(:general) |> List.first
|
||||
|
||||
# Gets the general ejabberd options calling
|
||||
# the start/0 function and stores them.
|
||||
defp call_start_func_and_store_data(module) do
|
||||
opts = apply(module, :start, [])
|
||||
Ejabberd.Config.Store.put(:general, opts)
|
||||
end
|
||||
|
||||
# Stores the configuration module name
|
||||
defp extract_and_store_module_name({{:module, mod, _bytes, _}, _}) do
|
||||
Ejabberd.Config.Store.put(:module_name, mod)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
defmodule Ejabberd.Config.EjabberdHook do
|
||||
@moduledoc """
|
||||
Module containing functions for manipulating
|
||||
ejabberd hooks.
|
||||
"""
|
||||
|
||||
defstruct hook: nil, opts: [], fun: nil
|
||||
|
||||
alias Ejabberd.Config.EjabberdHook
|
||||
|
||||
@type t :: %EjabberdHook{}
|
||||
|
||||
@doc """
|
||||
Register a hook to ejabberd.
|
||||
"""
|
||||
@spec start(EjabberdHook.t) :: none
|
||||
def start(%EjabberdHook{hook: hook, opts: opts, fun: fun}) do
|
||||
host = Keyword.get(opts, :host, :global)
|
||||
priority = Keyword.get(opts, :priority, 50)
|
||||
|
||||
:ejabberd_hooks.add(hook, host, fun, priority)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,70 @@
|
||||
defmodule Ejabberd.Config.EjabberdModule do
|
||||
@moduledoc """
|
||||
Module representing a module block in the configuration file.
|
||||
It offers functions for validation and for starting the modules.
|
||||
|
||||
Warning: The name is EjabberdModule to not collide with
|
||||
the already existing Elixir.Module.
|
||||
"""
|
||||
|
||||
@type t :: %{module: atom, attrs: [Attr.t]}
|
||||
|
||||
defstruct [:module, :attrs]
|
||||
|
||||
alias Ejabberd.Config.EjabberdModule
|
||||
alias Ejabberd.Config.Attr
|
||||
alias Ejabberd.Config.Validation
|
||||
|
||||
@doc """
|
||||
Given a list of modules / single module
|
||||
it runs different validators on them.
|
||||
|
||||
For each module, returns a {:ok, mod} or {:error, mod, errors}
|
||||
"""
|
||||
def validate(modules) do
|
||||
Validation.validate(modules)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Given a list of modules, it takes only the ones with
|
||||
a git attribute and tries to fetch the repo,
|
||||
then, it install them through :ext_mod.install/1
|
||||
"""
|
||||
@spec fetch_git_repos([EjabberdModule.t]) :: none()
|
||||
def fetch_git_repos(modules) do
|
||||
modules
|
||||
|> Enum.filter(&is_git_module?/1)
|
||||
|> Enum.each(&fetch_and_install_git_module/1)
|
||||
end
|
||||
|
||||
# Private API
|
||||
|
||||
defp is_git_module?(%EjabberdModule{attrs: attrs}) do
|
||||
case Keyword.get(attrs, :git) do
|
||||
"" -> false
|
||||
repo -> String.match?(repo, ~r/((git|ssh|http(s)?)|(git@[\w\.]+))(:(\/\/)?)([\w\.@\:\/\-~]+)(\.git)(\/)?/)
|
||||
end
|
||||
end
|
||||
|
||||
defp fetch_and_install_git_module(%EjabberdModule{attrs: attrs}) do
|
||||
repo = Keyword.get(attrs, :git)
|
||||
mod_name = case Keyword.get(attrs, :name) do
|
||||
"" -> infer_mod_name_from_git_url(repo)
|
||||
name -> name
|
||||
end
|
||||
|
||||
path = "#{:ext_mod.modules_dir()}/sources/ejabberd-contrib\/#{mod_name}"
|
||||
fetch_and_store_repo_source_if_not_exists(path, repo)
|
||||
:ext_mod.install(mod_name) # Have to check if overwrites an already present mod
|
||||
end
|
||||
|
||||
defp fetch_and_store_repo_source_if_not_exists(path, repo) do
|
||||
unless File.exists?(path) do
|
||||
IO.puts "[info] Fetching: #{repo}"
|
||||
:os.cmd('git clone #{repo} #{path}')
|
||||
end
|
||||
end
|
||||
|
||||
defp infer_mod_name_from_git_url(repo),
|
||||
do: String.split(repo, "/") |> List.last |> String.replace(".git", "")
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
defmodule Ejabberd.Config.EjabberdLogger do
|
||||
@moduledoc """
|
||||
Module used to log validation errors given validated modules
|
||||
given validated modules.
|
||||
"""
|
||||
|
||||
alias Ejabberd.Config.EjabberdModule
|
||||
|
||||
@doc """
|
||||
Given a list of modules validated, in the form of {:ok, mod} or
|
||||
{:error, mod, errors}, it logs to the user the errors found.
|
||||
"""
|
||||
@spec log_errors([EjabberdModule.t]) :: [EjabberdModule.t]
|
||||
def log_errors(modules_validated) when is_list(modules_validated) do
|
||||
Enum.each modules_validated, &do_log_errors/1
|
||||
modules_validated
|
||||
end
|
||||
|
||||
defp do_log_errors({:ok, _mod}), do: nil
|
||||
defp do_log_errors({:error, _mod, errors}), do: Enum.each errors, &do_log_errors/1
|
||||
defp do_log_errors({:attribute, errors}), do: Enum.each errors, &log_attribute_error/1
|
||||
defp do_log_errors({:dependency, errors}), do: Enum.each errors, &log_dependency_error/1
|
||||
|
||||
defp log_attribute_error({{attr_name, val}, :attr_not_supported}), do:
|
||||
IO.puts "[ WARN ] Annotation @#{attr_name} is not supported."
|
||||
|
||||
defp log_attribute_error({{attr_name, val}, :type_not_supported}), do:
|
||||
IO.puts "[ WARN ] Annotation @#{attr_name} with value #{inspect val} is not supported (type mismatch)."
|
||||
|
||||
defp log_dependency_error({module, :not_found}), do:
|
||||
IO.puts "[ WARN ] Module #{inspect module} was not found, but is required as a dependency."
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
defmodule Ejabberd.Config.OptsFormatter do
|
||||
@moduledoc """
|
||||
Module for formatting options parsed into the format
|
||||
ejabberd uses.
|
||||
"""
|
||||
|
||||
alias Ejabberd.Config.EjabberdModule
|
||||
|
||||
@doc """
|
||||
Takes a keyword list with keys corresponding to
|
||||
the keys requested by the ejabberd config (ex: modules: mods)
|
||||
and formats them to be correctly evaluated by ejabberd.
|
||||
|
||||
Look at how Config.get_ejabberd_opts/0 is constructed for
|
||||
more informations.
|
||||
"""
|
||||
@spec format_opts_for_ejabberd([{atom(), any()}]) :: list()
|
||||
def format_opts_for_ejabberd(opts) do
|
||||
opts
|
||||
|> format_attrs_for_ejabberd
|
||||
end
|
||||
|
||||
defp format_attrs_for_ejabberd(opts) when is_list(opts),
|
||||
do: Enum.map opts, &format_attrs_for_ejabberd/1
|
||||
|
||||
defp format_attrs_for_ejabberd({:listeners, mods}),
|
||||
do: {:listen, format_listeners_for_ejabberd(mods)}
|
||||
|
||||
defp format_attrs_for_ejabberd({:modules, mods}),
|
||||
do: {:modules, format_mods_for_ejabberd(mods)}
|
||||
|
||||
defp format_attrs_for_ejabberd({key, opts}) when is_atom(key),
|
||||
do: {key, opts}
|
||||
|
||||
defp format_mods_for_ejabberd(mods) do
|
||||
Enum.map mods, fn %EjabberdModule{module: mod, attrs: attrs} ->
|
||||
{mod, attrs[:opts]}
|
||||
end
|
||||
end
|
||||
|
||||
defp format_listeners_for_ejabberd(mods) do
|
||||
Enum.map mods, fn %EjabberdModule{module: mod, attrs: attrs} ->
|
||||
Keyword.put(attrs[:opts], :module, mod)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,55 @@
|
||||
defmodule Ejabberd.Config.Store do
|
||||
@moduledoc """
|
||||
Module used for storing the modules parsed from
|
||||
the configuration file.
|
||||
|
||||
Example:
|
||||
- Store.put(:modules, mod1)
|
||||
- Store.put(:modules, mod2)
|
||||
|
||||
- Store.get(:modules) :: [mod1, mod2]
|
||||
|
||||
Be carefoul: when retrieving data you get them
|
||||
in the order inserted into the store, which normally
|
||||
is the reversed order of how the modules are specified
|
||||
inside the configuration file. To resolve this just use
|
||||
a Enum.reverse/1.
|
||||
"""
|
||||
|
||||
@name __MODULE__
|
||||
|
||||
def start_link do
|
||||
Agent.start_link(fn -> %{} end, name: @name)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Stores a value based on the key. If the key already exists,
|
||||
then it inserts the new element, maintaining all the others.
|
||||
It uses a list for this.
|
||||
"""
|
||||
@spec put(atom, any) :: :ok
|
||||
def put(key, val) do
|
||||
Agent.update @name, &Map.update(&1, key, [val], fn coll ->
|
||||
[val | coll]
|
||||
end)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a value based on the key passed.
|
||||
Returns always a list.
|
||||
"""
|
||||
@spec get(atom) :: [any]
|
||||
def get(key) do
|
||||
Agent.get @name, &Map.get(&1, key, [])
|
||||
end
|
||||
|
||||
@doc """
|
||||
Stops the store.
|
||||
It uses Agent.stop underneath, so be aware that exit
|
||||
could be called.
|
||||
"""
|
||||
@spec stop() :: :ok
|
||||
def stop do
|
||||
Agent.stop @name
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
defmodule Ejabberd.Config.Validation do
|
||||
@moduledoc """
|
||||
Module used to validate a list of modules.
|
||||
"""
|
||||
|
||||
@type mod_validation :: {[EjabberdModule.t], EjabberdModule.t, map}
|
||||
@type mod_validation_result :: {:ok, EjabberdModule.t} | {:error, EjabberdModule.t, map}
|
||||
|
||||
alias Ejabberd.Config.EjabberdModule
|
||||
alias Ejabberd.Config.Attr
|
||||
alias Ejabberd.Config.Validator
|
||||
alias Ejabberd.Config.ValidatorUtility
|
||||
|
||||
@doc """
|
||||
Given a module or a list of modules it runs validators on them
|
||||
and returns {:ok, mod} or {:error, mod, errors}, for each
|
||||
of them.
|
||||
"""
|
||||
@spec validate([EjabberdModule.t] | EjabberdModule.t) :: [mod_validation_result]
|
||||
def validate(modules) when is_list(modules), do: Enum.map(modules, &do_validate(modules, &1))
|
||||
def validate(module), do: validate([module])
|
||||
|
||||
# Private API
|
||||
|
||||
@spec do_validate([EjabberdModule.t], EjabberdModule.t) :: mod_validation_result
|
||||
defp do_validate(modules, mod) do
|
||||
{modules, mod, %{}}
|
||||
|> Validator.Attrs.validate
|
||||
|> Validator.Dependencies.validate
|
||||
|> resolve_validation_result
|
||||
end
|
||||
|
||||
@spec resolve_validation_result(mod_validation) :: mod_validation_result
|
||||
defp resolve_validation_result({_modules, mod, errors}) do
|
||||
case errors do
|
||||
err when err == %{} -> {:ok, mod}
|
||||
err -> {:error, mod, err}
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
defmodule Ejabberd.Config.Validator.Attrs do
|
||||
@moduledoc """
|
||||
Validator module used to validate attributes.
|
||||
"""
|
||||
|
||||
# TODO: Duplicated from validator.ex !!!
|
||||
@type mod_validation :: {[EjabberdModule.t], EjabberdModule.t, map}
|
||||
|
||||
import Ejabberd.Config.ValidatorUtility
|
||||
alias Ejabberd.Config.Attr
|
||||
|
||||
@doc """
|
||||
Given a module (with the form used for validation)
|
||||
it runs Attr.validate/1 on each attribute and
|
||||
returns the validation tuple with the errors updated, if found.
|
||||
"""
|
||||
@spec validate(mod_validation) :: mod_validation
|
||||
def validate({modules, mod, errors}) do
|
||||
errors = Enum.reduce mod.attrs, errors, fn(attr, err) ->
|
||||
case Attr.validate(attr) do
|
||||
{:ok, attr} -> err
|
||||
{:error, attr, cause} -> put_error(err, :attribute, {attr, cause})
|
||||
end
|
||||
end
|
||||
|
||||
{modules, mod, errors}
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
defmodule Ejabberd.Config.Validator.Dependencies do
|
||||
@moduledoc """
|
||||
Validator module used to validate dependencies specified
|
||||
with the @dependency annotation.
|
||||
"""
|
||||
|
||||
# TODO: Duplicated from validator.ex !!!
|
||||
@type mod_validation :: {[EjabberdModule.t], EjabberdModule.t, map}
|
||||
import Ejabberd.Config.ValidatorUtility
|
||||
|
||||
@doc """
|
||||
Given a module (with the form used for validation)
|
||||
it checks if the @dependency annotation is respected and
|
||||
returns the validation tuple with the errors updated, if found.
|
||||
"""
|
||||
@spec validate(mod_validation) :: mod_validation
|
||||
def validate({modules, mod, errors}) do
|
||||
module_names = extract_module_names(modules)
|
||||
dependencies = mod.attrs[:dependency]
|
||||
|
||||
errors = Enum.reduce dependencies, errors, fn(req_module, err) ->
|
||||
case req_module in module_names do
|
||||
true -> err
|
||||
false -> put_error(err, :dependency, {req_module, :not_found})
|
||||
end
|
||||
end
|
||||
|
||||
{modules, mod, errors}
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
defmodule Ejabberd.Config.ValidatorUtility do
|
||||
@moduledoc """
|
||||
Module used as a base validator for validation modules.
|
||||
Imports utility functions for working with validation structures.
|
||||
"""
|
||||
|
||||
alias Ejabberd.Config.EjabberdModule
|
||||
|
||||
@doc """
|
||||
Inserts an error inside the errors collection, for the given key.
|
||||
If the key doesn't exists then it creates an empty collection
|
||||
and inserts the value passed.
|
||||
"""
|
||||
@spec put_error(map, atom, any) :: map
|
||||
def put_error(errors, key, val) do
|
||||
Map.update errors, key, [val], fn coll ->
|
||||
[val | coll]
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Given a list of modules it extracts and returns a list
|
||||
of the module names (which are Elixir.Module).
|
||||
"""
|
||||
@spec extract_module_names(EjabberdModule.t) :: [atom]
|
||||
def extract_module_names(modules) when is_list(modules) do
|
||||
modules
|
||||
|> Enum.map(&Map.get(&1, :module))
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
defmodule Ejabberd.ConfigUtil do
|
||||
@moduledoc """
|
||||
Module containing utility functions for
|
||||
the config file.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Returns true when the config file is based on elixir.
|
||||
"""
|
||||
@spec is_elixir_config(list) :: boolean
|
||||
def is_elixir_config(filename) when is_list(filename) do
|
||||
is_elixir_config(to_string(filename))
|
||||
end
|
||||
|
||||
def is_elixir_config(filename) do
|
||||
String.ends_with?(filename, "exs")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
defmodule Ejabberd.Module do
|
||||
|
||||
defmacro __using__(opts) do
|
||||
logger_enabled = Keyword.get(opts, :logger, true)
|
||||
|
||||
quote do
|
||||
@behaviour :gen_mod
|
||||
import Ejabberd.Module
|
||||
|
||||
unquote(if logger_enabled do
|
||||
quote do: import Ejabberd.Logger
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
# gen_mod callbacks
|
||||
def depends(_host, _opts), do: []
|
||||
def mod_opt_type(_), do: []
|
||||
end
|
||||
@@ -0,0 +1,94 @@
|
||||
defmodule Mix.Tasks.Ejabberd.Deps.Tree do
|
||||
use Mix.Task
|
||||
|
||||
alias Ejabberd.Config.EjabberdModule
|
||||
|
||||
@shortdoc "Lists all ejabberd modules and their dependencies"
|
||||
|
||||
@moduledoc """
|
||||
Lists all ejabberd modules and their dependencies.
|
||||
|
||||
The project must have ejabberd as a dependency.
|
||||
"""
|
||||
|
||||
def run(_argv) do
|
||||
# First we need to start manually the store to be available
|
||||
# during the compilation of the config file.
|
||||
Ejabberd.Config.Store.start_link
|
||||
Ejabberd.Config.init(:ejabberd_config.get_ejabberd_config_path())
|
||||
|
||||
Mix.shell.info "ejabberd modules"
|
||||
|
||||
Ejabberd.Config.Store.get(:modules)
|
||||
|> Enum.reverse # Because of how mods are stored inside the store
|
||||
|> format_mods
|
||||
|> Mix.shell.info
|
||||
end
|
||||
|
||||
defp format_mods(mods) when is_list(mods) do
|
||||
deps_tree = build_dependency_tree(mods)
|
||||
mods_used_as_dependency = get_mods_used_as_dependency(deps_tree)
|
||||
|
||||
keep_only_mods_not_used_as_dep(deps_tree, mods_used_as_dependency)
|
||||
|> format_mods_into_string
|
||||
end
|
||||
|
||||
defp build_dependency_tree(mods) do
|
||||
Enum.map mods, fn %EjabberdModule{module: mod, attrs: attrs} ->
|
||||
deps = attrs[:dependency]
|
||||
build_dependency_tree(mods, mod, deps)
|
||||
end
|
||||
end
|
||||
|
||||
defp build_dependency_tree(mods, mod, []), do: %{module: mod, dependency: []}
|
||||
defp build_dependency_tree(mods, mod, deps) when is_list(deps) do
|
||||
dependencies = Enum.map deps, fn dep ->
|
||||
dep_deps = get_dependencies_of_mod(mods, dep)
|
||||
build_dependency_tree(mods, dep, dep_deps)
|
||||
end
|
||||
|
||||
%{module: mod, dependency: dependencies}
|
||||
end
|
||||
|
||||
defp get_mods_used_as_dependency(mods) when is_list(mods) do
|
||||
Enum.reduce mods, [], fn(mod, acc) ->
|
||||
case mod do
|
||||
%{dependency: []} -> acc
|
||||
%{dependency: deps} -> get_mod_names(deps) ++ acc
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp get_mod_names([]), do: []
|
||||
defp get_mod_names(mods) when is_list(mods), do: Enum.map(mods, &get_mod_names/1) |> List.flatten
|
||||
defp get_mod_names(%{module: mod, dependency: deps}), do: [mod | get_mod_names(deps)]
|
||||
|
||||
defp keep_only_mods_not_used_as_dep(mods, mods_used_as_dep) do
|
||||
Enum.filter mods, fn %{module: mod} ->
|
||||
not mod in mods_used_as_dep
|
||||
end
|
||||
end
|
||||
|
||||
defp get_dependencies_of_mod(deps, mod_name) do
|
||||
Enum.find(deps, &(Map.get(&1, :module) == mod_name))
|
||||
|> Map.get(:attrs)
|
||||
|> Keyword.get(:dependency)
|
||||
end
|
||||
|
||||
defp format_mods_into_string(mods), do: format_mods_into_string(mods, 0)
|
||||
defp format_mods_into_string([], _indentation), do: ""
|
||||
defp format_mods_into_string(mods, indentation) when is_list(mods) do
|
||||
Enum.reduce mods, "", fn(mod, acc) ->
|
||||
acc <> format_mods_into_string(mod, indentation)
|
||||
end
|
||||
end
|
||||
|
||||
defp format_mods_into_string(%{module: mod, dependency: deps}, 0) do
|
||||
"\n├── #{mod}" <> format_mods_into_string(deps, 2)
|
||||
end
|
||||
|
||||
defp format_mods_into_string(%{module: mod, dependency: deps}, indentation) do
|
||||
spaces = Enum.reduce 0..indentation, "", fn(_, acc) -> " " <> acc end
|
||||
"\n│#{spaces}└── #{mod}" <> format_mods_into_string(deps, indentation + 4)
|
||||
end
|
||||
end
|
||||
@@ -1,21 +1,20 @@
|
||||
defmodule ModPresenceDemo do
|
||||
import Ejabberd.Logger # this allow using info, error, etc for logging
|
||||
@behaviour :gen_mod
|
||||
use Ejabberd.Module
|
||||
|
||||
def start(host, _opts) do
|
||||
info('Starting ejabberd module Presence Demo')
|
||||
Ejabberd.Hooks.add(:set_presence_hook, host, __ENV__.module, :on_presence, 50)
|
||||
Ejabberd.Hooks.add(:set_presence_hook, host, __MODULE__, :on_presence, 50)
|
||||
:ok
|
||||
end
|
||||
|
||||
|
||||
def stop(host) do
|
||||
info('Stopping ejabberd module Presence Demo')
|
||||
Ejabberd.Hooks.delete(:set_presence_hook, host, __ENV__.module, :on_presence, 50)
|
||||
Ejabberd.Hooks.delete(:set_presence_hook, host, __MODULE__, :on_presence, 50)
|
||||
:ok
|
||||
end
|
||||
|
||||
|
||||
def on_presence(user, _server, _resource, _packet) do
|
||||
info('Receive presence for #{user}')
|
||||
:none
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,55 +3,113 @@ defmodule Ejabberd.Mixfile do
|
||||
|
||||
def project do
|
||||
[app: :ejabberd,
|
||||
version: "15.09.0",
|
||||
elixir: "~> 1.0",
|
||||
version: "17.01.0",
|
||||
description: description,
|
||||
elixir: "~> 1.3",
|
||||
elixirc_paths: ["lib"],
|
||||
compile_path: ".",
|
||||
compilers: [:asn1] ++ Mix.compilers,
|
||||
erlc_options: erlc_options,
|
||||
erlc_paths: ["asn1", "src"],
|
||||
# Elixir tests are starting the part of ejabberd they need
|
||||
aliases: [test: "test --no-start"],
|
||||
package: package,
|
||||
deps: deps]
|
||||
end
|
||||
|
||||
def description do
|
||||
"""
|
||||
Robust, ubiquitous and massively scalable Jabber / XMPP Instant Messaging platform.
|
||||
"""
|
||||
end
|
||||
|
||||
def application do
|
||||
[mod: {:ejabberd_app, []},
|
||||
applications: [:ssl],
|
||||
included_applications: [:p1_logger,:p1_yaml,:p1_tls,:p1_xml,:p1_stringprep,:p1_zlib,:p1_cache_tab,:mnesia,:p1_utils,
|
||||
:p1_iconv,:esip,:p1_stun,:ehyperloglog,:p1_mysql,:p1_pgsql,:eredis]]
|
||||
included_applications: [:lager, :mnesia, :p1_utils, :cache_tab,
|
||||
:fast_tls, :stringprep, :fast_xml, :xmpp,
|
||||
:stun, :fast_yaml, :esip, :jiffy, :p1_oauth2]
|
||||
++ cond_apps]
|
||||
end
|
||||
|
||||
defp erlc_options do
|
||||
# Use our own includes + includes from all dependencies
|
||||
includes = ["include"] ++ Path.wildcard(Path.join("..", "/*/include"))
|
||||
[:debug_info] ++ Enum.map(includes, fn(path) -> {:i, path} end)
|
||||
includes = ["include"] ++ deps_include(["fast_xml", "xmpp"])
|
||||
[:debug_info, {:d, :ELIXIR_ENABLED}] ++ Enum.map(includes, fn(path) -> {:i, path} end)
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[{:p1_xml, git: "https://github.com/processone/xml"},
|
||||
{:p1_logger, git: "https://github.com/processone/p1_logger"},
|
||||
{:p1_yaml, git: "https://github.com/processone/p1_yaml"},
|
||||
{:p1_tls, git: "https://github.com/processone/tls"},
|
||||
{:p1_stringprep, git: "https://github.com/processone/stringprep"},
|
||||
{:p1_zlib, git: "https://github.com/processone/zlib"},
|
||||
{:p1_cache_tab, git: "https://github.com/processone/cache_tab"},
|
||||
{:p1_utils, git: "https://github.com/processone/p1_utils"},
|
||||
{:p1_iconv, git: "https://github.com/processone/eiconv"},
|
||||
{:esip, git: "https://github.com/processone/p1_sip"},
|
||||
{:p1_stun, git: "https://github.com/processone/stun"},
|
||||
{:ehyperloglog, git: "https://github.com/vaxelfel/eHyperLogLog"},
|
||||
{:p1_mysql, git: "https://github.com/processone/mysql"},
|
||||
{:p1_pgsql, git: "https://github.com/processone/pgsql"},
|
||||
{:eredis, git: "https://github.com/wooga/eredis"},
|
||||
{:exrm, "~> 0.19.2"}]
|
||||
[{:lager, "~> 3.2"},
|
||||
{:p1_utils, "~> 1.0"},
|
||||
{:cache_tab, "~> 1.0"},
|
||||
{:stringprep, "~> 1.0"},
|
||||
{:fast_yaml, "~> 1.0"},
|
||||
{:fast_tls, "~> 1.0"},
|
||||
{:fast_xml, "~> 1.1"},
|
||||
{:xmpp, "~> 1.1"},
|
||||
{:stun, "~> 1.0"},
|
||||
{:esip, "~> 1.0"},
|
||||
{:jiffy, "~> 0.14.7"},
|
||||
{:p1_oauth2, "~> 0.6.1"},
|
||||
{:distillery, "~> 1.0"},
|
||||
{:ex_doc, ">= 0.0.0", only: :dev}]
|
||||
++ cond_deps
|
||||
end
|
||||
|
||||
defp package do
|
||||
[licenses: ["GPLv2"],
|
||||
links: %{"Site" => "https://www.ejabberd.im",
|
||||
"Documentation" => "http://docs.ejabberd.im",
|
||||
"Source" => "https://github.com/processone/ejabberd"}]
|
||||
defp deps_include(deps) do
|
||||
Enum.map(deps, fn dep -> "deps/#{dep}/include" end)
|
||||
end
|
||||
|
||||
defp cond_deps do
|
||||
for {:true, dep} <- [{config(:mysql), {:p1_mysql, "~> 1.0"}},
|
||||
{config(:pgsql), {:p1_pgsql, "~> 1.1"}},
|
||||
{config(:sqlite), {:sqlite3, "~> 1.1"}},
|
||||
{config(:riak), {:riakc, "~> 2.4"}},
|
||||
{config(:redis), {:eredis, "~> 1.0"}},
|
||||
{config(:zlib), {:ezlib, "~> 1.0"}},
|
||||
{config(:iconv), {:iconv, "~> 1.0"}},
|
||||
{config(:pam), {:p1_pam, "~> 1.0"}},
|
||||
{config(:tools), {:luerl, github: "rvirding/luerl", tag: "v0.2"}},
|
||||
{config(:tools), {:meck, "~> 0.8.4"}},
|
||||
{config(:tools), {:moka, github: "processone/moka", tag: "1.0.5c"}}], do:
|
||||
dep
|
||||
end
|
||||
|
||||
defp cond_apps do
|
||||
for {:true, app} <- [{config(:redis), :eredis},
|
||||
{config(:mysql), :p1_mysql},
|
||||
{config(:pgsql), :p1_pgsql},
|
||||
{config(:sqlite), :sqlite3},
|
||||
{config(:zlib), :ezlib},
|
||||
{config(:iconv), :iconv}], do:
|
||||
app
|
||||
end
|
||||
|
||||
def package do
|
||||
[# These are the default files included in the package
|
||||
files: ["lib", "src", "priv", "mix.exs", "include", "README.md", "COPYING"],
|
||||
maintainers: ["ProcessOne"],
|
||||
licenses: ["GPLv2"],
|
||||
links: %{"Site" => "https://www.ejabberd.im",
|
||||
"Documentation" => "http://docs.ejabberd.im",
|
||||
"Source" => "https://github.com/processone/ejabberd",
|
||||
"ProcessOne" => "http://www.process-one.net/"}]
|
||||
end
|
||||
|
||||
def vars do
|
||||
case :file.consult("vars.config") do
|
||||
{:ok,config} -> config
|
||||
_ -> [zlib: true, iconv: true]
|
||||
end
|
||||
end
|
||||
|
||||
defp config(key) do
|
||||
case vars[key] do
|
||||
nil -> false
|
||||
value -> value
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
defmodule Mix.Tasks.Compile.Asn1 do
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
%{"cache_tab": {:hex, :cache_tab, "1.0.5", "022da45aa10c2ccfdc804e69af36e3be1717c7579f3578767a29bd8ceb3b3c92", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"distillery": {:hex, :distillery, "1.0.0", "a866a72bf2a3a5f078f5a249017ed951acda88a760d200512f91f585d74db1ec", [:mix], []},
|
||||
"earmark": {:hex, :earmark, "1.0.3", "89bdbaf2aca8bbb5c97d8b3b55c5dd0cff517ecc78d417e87f1d0982e514557b", [:mix], []},
|
||||
"esip": {:hex, :esip, "1.0.9", "256259792c07d2f888d56e89031b0d064ff795c395fdca11ee3aab912c56d9de", [:rebar3], [{:fast_tls, "1.0.8", [hex: :fast_tls, optional: false]}, {:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}, {:stun, "1.0.8", [hex: :stun, optional: false]}]},
|
||||
"ex_doc": {:hex, :ex_doc, "0.14.5", "c0433c8117e948404d93ca69411dd575ec6be39b47802e81ca8d91017a0cf83c", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]},
|
||||
"ezlib": {:hex, :ezlib, "1.0.1", "add8b2770a1a70c174aaea082b4a8668c0c7fdb03ee6cc81c6c68d3a6c3d767d", [:rebar3], []},
|
||||
"fast_tls": {:hex, :fast_tls, "1.0.8", "697dc84ab958aed36924d8d9df9a463103ddc92f53283bbd930c9015f05ecf0a", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"fast_xml": {:hex, :fast_xml, "1.1.18", "5cad4f35fa50070d38ef7cbb64975c6a8750e92b976f49e5bb88819f47451e69", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"fast_yaml": {:hex, :fast_yaml, "1.0.7", "c1fc7995c8422bb4dc2a3502f6432054d6c16fde86f259f50080bb1d09fc5e50", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"goldrush": {:hex, :goldrush, "0.1.8", "2024ba375ceea47e27ea70e14d2c483b2d8610101b4e852ef7f89163cdb6e649", [:rebar3], []},
|
||||
"iconv": {:hex, :iconv, "1.0.3", "f5c159f7e0ad2a3b55c6b5528ce71d7926f206df2f9bf83201a77cf1bc91c6f0", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"jiffy": {:hex, :jiffy, "0.14.7", "9f33b893edd6041ceae03bc1e50b412e858cc80b46f3d7535a7a9940a79a1c37", [:make, :rebar], []},
|
||||
"lager": {:hex, :lager, "3.2.1", "eef4e18b39e4195d37606d9088ea05bf1b745986cf8ec84f01d332456fe88d17", [:rebar3], [{:goldrush, "0.1.8", [hex: :goldrush, optional: false]}]},
|
||||
"p1_mysql": {:hex, :p1_mysql, "1.0.1", "d2be1cfc71bb4f1391090b62b74c3f5cb8e7a45b0076b8cb290cd6b2856c581b", [:rebar3], []},
|
||||
"p1_oauth2": {:hex, :p1_oauth2, "0.6.1", "4e021250cc198c538b097393671a41e7cebf463c248980320e038fe0316eb56b", [:rebar3], []},
|
||||
"p1_utils": {:hex, :p1_utils, "1.0.6", "ef0951ddf38e92b7e479af4b8dc950df76af8c1030432ef68b7fd7ad17c436fe", [:rebar3], []},
|
||||
"stringprep": {:hex, :stringprep, "1.0.7", "f709c7ee3697ae9d2becbbbba1dcea47e0f583e313b4eb7d0ced2163c595ee12", [:rebar3], [{:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"stun": {:hex, :stun, "1.0.8", "cfe6df914b12227ca0920e5e3d5b1203331c6662d0948859357c84d2c87a0411", [:rebar3], [{:fast_tls, "1.0.8", [hex: :fast_tls, optional: false]}, {:p1_utils, "1.0.6", [hex: :p1_utils, optional: false]}]},
|
||||
"xmpp": {:hex, :xmpp, "1.1.4", "fa9c890a779c57699d870e2e0966e4b6a66e92de19d0263a54df26f1be6ae046", [:rebar3], [{:fast_xml, "1.1.18", [hex: :fast_xml, optional: false]}, {:stringprep, "1.0.7", [hex: :stringprep, optional: false]}]}}
|
||||
@@ -0,0 +1,12 @@
|
||||
-module(deps_erl_opts).
|
||||
-export([preprocess/2]).
|
||||
|
||||
preprocess(Config, Dirs) ->
|
||||
ExtraOpts = rebar_config:get(Config, deps_erl_opts, []),
|
||||
Opts = rebar_config:get(Config, erl_opts, []),
|
||||
NewOpts = lists:foldl(fun(Opt, Acc) when is_tuple(Opt) ->
|
||||
lists:keystore(element(1, Opt), 1, Acc, Opt);
|
||||
(Opt, Acc) ->
|
||||
[Opt | lists:delete(Opt, Acc)]
|
||||
end, Opts, ExtraOpts),
|
||||
{ok, rebar_config:set(Config, erl_opts, NewOpts), []}.
|
||||
+49
-2
@@ -1,8 +1,10 @@
|
||||
%% -*- coding: latin-1 -*-
|
||||
{"Accept","Acceptar"}.
|
||||
{"Access Configuration","Configuració d'accesos"}.
|
||||
{"Access Control List Configuration","Configuració de la Llista de Control d'Accés"}.
|
||||
{"Access Control Lists","Llista de Control d'Accés"}.
|
||||
{"Access control lists","Llistes de Control de Accés"}.
|
||||
{"Access denied by service policy","Accés denegat per la política del servei"}.
|
||||
{"Access rules","Regles d'accés"}.
|
||||
{"Access Rules","Regles d'Accés"}.
|
||||
{"Action on user","Acció en l'usuari"}.
|
||||
@@ -11,6 +13,7 @@
|
||||
{"Add User","Afegir usuari"}.
|
||||
{"Administration","Administració"}.
|
||||
{"Administration of ","Administració de "}.
|
||||
{"Administrator privileges required","Es necessita tenir privilegis d'administrador"}.
|
||||
{"A friendly name for the node","Un nom per al node"}.
|
||||
{"All activity","Tota l'activitat"}.
|
||||
{"Allow this Jabber ID to subscribe to this pubsub node?","Permetre que aquesta Jabber ID es puga subscriure a aquest node pubsub"}.
|
||||
@@ -25,6 +28,7 @@
|
||||
{"All Users","Tots els usuaris"}.
|
||||
{"Announcements","Anuncis"}.
|
||||
{"anyone","qualsevol"}.
|
||||
{"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"}.
|
||||
@@ -49,6 +53,7 @@
|
||||
{"Choose whether to approve this entity's subscription.","Tria si aprova aquesta entitat de subscripció"}.
|
||||
{"City","Ciutat"}.
|
||||
{"Commands","Comandaments"}.
|
||||
{"Conference room does not exist","La sala de conferències no existeix"}.
|
||||
{"Configuration","Configuració"}.
|
||||
{"Configuration of room ~s","Configuració de la sala ~s"}.
|
||||
{"Connected Resources:","Recursos connectats:"}.
|
||||
@@ -83,6 +88,7 @@
|
||||
{"ejabberd Web Admin","Web d'administració del ejabberd"}.
|
||||
{"Elements","Elements"}.
|
||||
{"Email","Email"}.
|
||||
{"Empty Rooms","Sales buides "}.
|
||||
{"Enable logging","Habilitar el registre de la conversa"}.
|
||||
{"Enable message archiving","Activar l'emmagatzematge de missatges"}.
|
||||
{"Encoding for server ~b","Codificació pel servidor ~b"}.
|
||||
@@ -103,6 +109,7 @@
|
||||
{"Export all tables as SQL queries to a file:","Exporta totes les taules a un fitxer SQL:"}.
|
||||
{"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"}.
|
||||
@@ -136,6 +143,9 @@
|
||||
{"Import users data from jabberd14 spool directory:","Importar dades d'usuaris del directori de spool de jabberd14:"}.
|
||||
{"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"}.
|
||||
{"Incoming s2s Connections:","Connexions s2s d'entrada"}.
|
||||
{"Incorrect password","Contrasenya incorrecta"}.
|
||||
{"Invalid affiliation: ~s","Afiliació invàlida: ~s"}.
|
||||
{"Invalid role: ~s","Rol invàlid: ~s"}.
|
||||
{"IP addresses","Adreça IP"}.
|
||||
@@ -147,6 +157,10 @@
|
||||
{"IRC username","Nom d'usuari al IRC"}.
|
||||
{"IRC Username","Nom d'usuari al IRC"}.
|
||||
{"is now known as","ara es conegut com"}.
|
||||
{"It is not allowed to send error messages to the room. The participant (~s) has sent an error message (~s) and got kicked from the room","No està permés enviar missatges d'error a la sala. El participant (~s) ha enviat un missatge d'error (~s) i ha sigut expulsat de la sala"}.
|
||||
{"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"}.
|
||||
{"Jabber Account Registration","Registre de compte Jabber"}.
|
||||
{"Jabber ID","ID Jabber"}.
|
||||
{"Jabber ID ~s is invalid","El Jabber ID ~s no és vàlid"}.
|
||||
@@ -179,12 +193,15 @@
|
||||
{"Max # of items to persist","Màxim # d'elements que persistixen"}.
|
||||
{"Max payload size in bytes","Màxim tamany del payload en bytes"}.
|
||||
{"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","Moderador"}.
|
||||
{"Moderator privileges required","Es necessita tenir privilegis de moderador"}.
|
||||
{"moderators only","només moderadors"}.
|
||||
{"Modified modules","Mòduls modificats"}.
|
||||
{"Module","Mòdul"}.
|
||||
@@ -227,15 +244,21 @@
|
||||
{"Online Users","Usuaris conectats"}.
|
||||
{"Online Users:","Usuaris en línia:"}.
|
||||
{"Only deliver notifications to available users","Sols enviar notificacions als usuaris disponibles"}.
|
||||
{"Only members may query archives of this room","Només membres poden consultar l'arxiu de missatges d'aquesta sala"}.
|
||||
{"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 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ó"}.
|
||||
{"Organization Unit","Unitat de la organizació"}.
|
||||
{"Outgoing s2s Connections:","Connexions d'eixida s2s"}.
|
||||
{"Outgoing s2s Connections","Connexions s2s d'eixida"}.
|
||||
{"Outgoing s2s Servers:","Servidors d'eixida de s2s"}.
|
||||
{"Owner privileges required","Es requerixen privilegis de propietari de la sala"}.
|
||||
{"Packet","Paquet"}.
|
||||
{"Participant","Participant"}.
|
||||
{"Password ~b","Contrasenya ~b"}.
|
||||
{"Password:","Contrasenya:"}.
|
||||
{"Password","Contrasenya"}.
|
||||
@@ -249,6 +272,9 @@
|
||||
{"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 specify file name.","Per favor especifica el nom del fitxer."}.
|
||||
{"Please specify file size.","Per favor especifica la mida del fitxer."}.
|
||||
{"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"}.
|
||||
@@ -258,10 +284,12 @@
|
||||
{"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 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 nicknames","Sobrenoms registrats"}.
|
||||
{"Registered Users:","Usuaris registrats:"}.
|
||||
@@ -281,7 +309,9 @@
|
||||
{"Restore binary backup immediately:","Restaurar una còpia de seguretat binària ara mateix."}.
|
||||
{"Restore plain text backup immediately:","Restaurar una còpia de seguretat en format de text pla ara mateix:"}.
|
||||
{"Restore","Restaurar"}.
|
||||
{"Roles for which Presence is Broadcasted","Rols per als que sí se difon la seua presencia"}.
|
||||
{"Room Configuration","Configuració de la sala"}.
|
||||
{"Room creation is denied by service policy","Se t'ha denegat el crear la sala per política del servei"}.
|
||||
{"Room description","Descripció de la sala:"}.
|
||||
{"Room Occupants","Nombre d'ocupants"}.
|
||||
{"Room title","Títol de la sala"}.
|
||||
@@ -303,6 +333,7 @@
|
||||
{"September","Setembre"}.
|
||||
{"Server ~b","Servidor ~b"}.
|
||||
{"Server:","Servidor:"}.
|
||||
{"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"}.
|
||||
@@ -310,7 +341,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."}.
|
||||
{"Some Jabber clients can store your password in the computer, but you should do this only in your personal computer for safety reasons.","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"}.
|
||||
@@ -333,9 +364,13 @@
|
||||
{"Subscriber Address","Adreça del Subscriptor"}.
|
||||
{"Subscription","Subscripció"}.
|
||||
{"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 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","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: "}.
|
||||
@@ -347,16 +382,19 @@
|
||||
{"Thursday","Dijous"}.
|
||||
{"Time","Data"}.
|
||||
{"Time delay","Temps de retard"}.
|
||||
{"Too many CAPTCHA requests","Massa peticions de CAPTCHA"}.
|
||||
{"Too many (~p) failed authentications from this IP address (~s). The address will be unblocked at ~s UTC","Massa autenticacions (~p) han fallat des d'aquesta adreça IP (~s). L'adreça serà desbloquejada en ~s UTC"}.
|
||||
{"Too many unacked stanzas","Massa missatges sense haver reconegut la seva recepció"}.
|
||||
{"To","Per a"}.
|
||||
{"To ~s","A ~s"}.
|
||||
{"Total rooms","Nombre total de sales"}.
|
||||
{"Traffic rate limit is exceeded","El llímit de tràfic ha sigut sobrepassat"}.
|
||||
{"Transactions Aborted:","Transaccions Avortades"}.
|
||||
{"Transactions Committed:","Transaccions Realitzades:"}.
|
||||
{"Transactions Logged:","Transaccions registrades"}.
|
||||
{"Transactions Restarted:","Transaccions reiniciades"}.
|
||||
{"Tuesday","Dimarts"}.
|
||||
{"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"}.
|
||||
@@ -371,6 +409,7 @@
|
||||
{"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"}.
|
||||
{"User ~s","Usuari ~s"}.
|
||||
{"Users","Usuaris"}.
|
||||
@@ -378,16 +417,24 @@
|
||||
{"Validate","Validar"}.
|
||||
{"vCard User Search","Recerca de vCard d'usuari"}.
|
||||
{"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"}.
|
||||
{"Visitor","Visitant"}.
|
||||
{"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 sobrenom"}.
|
||||
{"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","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"}.
|
||||
|
||||
+504
-430
File diff suppressed because it is too large
Load Diff
+66
-2
@@ -1,8 +1,10 @@
|
||||
%% -*- coding: latin-1 -*-
|
||||
{"Accept","Přijmout"}.
|
||||
{"Access Configuration","Konfigurace přístupů"}.
|
||||
{"Access Control List Configuration","Konfigurace seznamu přístupových práv (ACL)"}.
|
||||
{"Access control lists","Seznamy přístupových práv (ACL)"}.
|
||||
{"Access Control Lists","Seznamy přístupových práv (ACL)"}.
|
||||
{"Access denied by service policy","Přístup byl zamítnut nastavením služby"}.
|
||||
{"Access rules","Pravidla přístupů"}.
|
||||
{"Access Rules","Pravidla přístupů"}.
|
||||
{"Action on user","Akce aplikovaná na uživatele"}.
|
||||
@@ -11,6 +13,7 @@
|
||||
{"Add User","Přidat uživatele"}.
|
||||
{"Administration","Administrace"}.
|
||||
{"Administration of ","Administrace "}.
|
||||
{"Administrator privileges required","Potřebujete práva administrátora"}.
|
||||
{"A friendly name for the node","Přívětivé jméno pro uzel"}.
|
||||
{"All activity","Všechny aktivity"}.
|
||||
{"Allow this Jabber ID to subscribe to this pubsub node?","Povolit tomuto Jabber ID odebírat tento pubsub uzel?"}.
|
||||
@@ -25,9 +28,11 @@
|
||||
{"All Users","Všichni uživatelé"}.
|
||||
{"Announcements","Oznámení"}.
|
||||
{"anyone","každému"}.
|
||||
{"A password is required to enter this room","Pro vstup do místnosti musíte zadat heslo"}.
|
||||
{"April",". dubna"}.
|
||||
{"August",". srpna"}.
|
||||
{"Backup Management","Správa zálohování"}.
|
||||
{"Backup of ~p","Záloha ~p"}.
|
||||
{"Backup to File at ","Záloha do souboru na "}.
|
||||
{"Backup","Zálohovat"}.
|
||||
{"Bad format","Nesprávný formát"}.
|
||||
@@ -48,6 +53,7 @@
|
||||
{"Choose whether to approve this entity's subscription.","Zvolte, zda chcete schválit odebírání touto entitou"}.
|
||||
{"City","Město"}.
|
||||
{"Commands","Příkazy"}.
|
||||
{"Conference room does not exist","Konferenční místnost neexistuje"}.
|
||||
{"Configuration","Konfigurace"}.
|
||||
{"Configuration of room ~s","Konfigurace místnosti ~s"}.
|
||||
{"Connected Resources:","Připojené zdroje:"}.
|
||||
@@ -55,6 +61,7 @@
|
||||
{"Country","Země"}.
|
||||
{"CPU Time:","Čas procesoru"}.
|
||||
{"Database","Databáze"}.
|
||||
{"Database Tables at ~p","Databázové tabulky na ~p"}.
|
||||
{"Database Tables Configuration at ","Konfigurace databázových tabulek "}.
|
||||
{"December",". prosince"}.
|
||||
{"Default users as participants","Uživatelé jsou implicitně členy"}.
|
||||
@@ -74,13 +81,16 @@
|
||||
{"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 Multicast service","Služba ejabberd Multicast"}.
|
||||
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe modul"}.
|
||||
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams modul"}.
|
||||
{"ejabberd vCard module","ejabberd vCard modul"}.
|
||||
{"ejabberd Web Admin","Webová administrace ejabberd"}.
|
||||
{"Elements","Položek"}.
|
||||
{"Email","E-mail"}.
|
||||
{"Empty Rooms","Prázdné konference"}.
|
||||
{"Enable logging","Zaznamenávat konverzace"}.
|
||||
{"Enable message archiving","Povolit ukládání historie zpráv"}.
|
||||
{"Encoding for server ~b","Kódování pro server ~b"}.
|
||||
{"End User Session","Ukončit sezení uživatele"}.
|
||||
{"Enter list of {Module, [Options]}","Vložte seznam modulů {Modul, [Parametry]}"}.
|
||||
@@ -96,8 +106,10 @@
|
||||
{"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 all tables as SQL queries to a file:","Zálohovat všechny tabulky jako SQL dotazy do souboru:"}.
|
||||
{"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"}.
|
||||
@@ -131,6 +143,9 @@
|
||||
{"Import users data from jabberd14 spool directory:","Importovat uživatele z jabberd14 spool souborů:"}.
|
||||
{"Import Users from Dir at ","Importovat uživatele z adresáře na "}.
|
||||
{"Import Users From jabberd14 Spool Files","Importovat uživatele z jabberd14 spool souborů"}.
|
||||
{"Improper message type","Nesprávný typ zprávy"}.
|
||||
{"Incoming s2s Connections:","Příchozí s2s spojení:"}.
|
||||
{"Incorrect password","Nesprávné heslo"}.
|
||||
{"Invalid affiliation: ~s","Neplatné přiřazení: ~s"}.
|
||||
{"Invalid role: ~s","Neplatná role: ~s"}.
|
||||
{"IP addresses","IP adresy"}.
|
||||
@@ -142,6 +157,10 @@
|
||||
{"IRC username","IRC přezdívka"}.
|
||||
{"IRC Username","IRC přezdívka"}.
|
||||
{"is now known as","se přejmenoval(a) na"}.
|
||||
{"It is not allowed to send error messages to the room. The participant (~s) has sent an error message (~s) and got kicked from the room","Není povoleno posílat chybové zprávy do konference. Účastník (~s) odeslal chybovou zprávu (~s) a byl vyhozen z konference."}.
|
||||
{"It is not allowed to send private messages","Je zakázáno posílat soukromé zprávy"}.
|
||||
{"It is not allowed to send private messages of type \"groupchat\"","Není dovoleno odeslání soukromé zprávy typu \"skupinová zpráva\" "}.
|
||||
{"It is not allowed to send private messages to the conference","Není povoleno odesílat soukromé zprávy do konference"}.
|
||||
{"Jabber Account Registration","Registrace účtu Jabberu"}.
|
||||
{"Jabber ID","Jabber ID"}.
|
||||
{"Jabber ID ~s is invalid","Jabber ID ~s je neplatné"}.
|
||||
@@ -160,6 +179,7 @@
|
||||
{"Listened Ports at ","Otevřené porty na "}.
|
||||
{"Listened Ports","Otevřené porty"}.
|
||||
{"List of modules to start","Seznam modulů, které mají být spuštěné"}.
|
||||
{"List of rooms","Seznam konferencí"}.
|
||||
{"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"}.
|
||||
@@ -174,16 +194,22 @@
|
||||
{"Max payload size in bytes","Maximální náklad v bajtech"}.
|
||||
{"May",". května"}.
|
||||
{"Members:","Členové:"}.
|
||||
{"Membership is required to enter this room","Pro vstup do místnosti musíte být členem"}.
|
||||
{"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.","Svoje heslo si zapamatujte, nebo si jej poznamenejte na papírek a ten uschovejte v bezpečí. Jabber nemá žádný automatizovaný způsob obnovy hesla."}.
|
||||
{"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","Moderátor"}.
|
||||
{"Moderator privileges required","Potřebujete práva moderátora"}.
|
||||
{"moderators only","moderátorům"}.
|
||||
{"Modified modules","Aktualizované moduly"}.
|
||||
{"Module","Modul"}.
|
||||
{"Modules at ~p","Moduly v ~p"}.
|
||||
{"Modules","Moduly"}.
|
||||
{"Monday","Pondělí"}.
|
||||
{"Multicast","Multicast"}.
|
||||
{"Multi-User Chat","Víceuživatelský chat"}.
|
||||
{"Name:","Jméno:"}.
|
||||
{"Name","Jméno"}.
|
||||
{"Never","Nikdy"}.
|
||||
@@ -196,6 +222,7 @@
|
||||
{"No Data","Žádná data"}.
|
||||
{"Node ID","ID uzlu"}.
|
||||
{"Node not found","Uzel nenalezen"}.
|
||||
{"Node ~p","Uzel ~p"}.
|
||||
{"Nodes","Uzly"}.
|
||||
{"No limit","Bez limitu"}.
|
||||
{"None","Nic"}.
|
||||
@@ -217,15 +244,21 @@
|
||||
{"Online Users:","Online uživatelé:"}.
|
||||
{"Online Users","Online uživatelé"}.
|
||||
{"Only deliver notifications to available users","Doručovat upozornění jen právě přihlášeným uživatelům"}.
|
||||
{"Only members may query archives of this room","Pouze moderátoři mají povoleno měnit téma místnosti"}.
|
||||
{"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"}.
|
||||
{"Options","Nastavení"}.
|
||||
{"Organization Name","Název firmy"}.
|
||||
{"Organization Unit","Oddělení"}.
|
||||
{"Outgoing s2s Connections:","Odchozí s2s spojení:"}.
|
||||
{"Outgoing s2s Connections","Odchozí s2s spojení"}.
|
||||
{"Outgoing s2s Servers:","Odchozí s2s servery:"}.
|
||||
{"Owner privileges required","Jsou vyžadována práva vlastníka"}.
|
||||
{"Packet","Paket"}.
|
||||
{"Participant","Účastník"}.
|
||||
{"Password ~b","Heslo ~b"}.
|
||||
{"Password:","Heslo:"}.
|
||||
{"Password","Heslo"}.
|
||||
@@ -235,9 +268,13 @@
|
||||
{"Path to File","Cesta k souboru"}.
|
||||
{"Pending","Čekající"}.
|
||||
{"Period: ","Čas: "}.
|
||||
{"Permanent rooms","Stálých konferencí"}.
|
||||
{"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 specify file name.","Zvolit jméno souboru."}.
|
||||
{"Please specify file size.","Zvolit velikost souboru."}.
|
||||
{"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"}.
|
||||
@@ -247,11 +284,14 @@
|
||||
{"Publish-Subscribe","Publish-Subscribe"}.
|
||||
{"PubSub subscriber request","Žádost odběratele PubSub"}.
|
||||
{"Purge all items when the relevant publisher goes offline","Smazat všechny položky, pokud se příslušný poskytovatel odpojí"}.
|
||||
{"Queries to the conference members are not allowed in this room","Požadavky (queries) na členy konference nejsou v této místnosti povolené"}.
|
||||
{"RAM and disc copy","Kopie RAM a disku"}.
|
||||
{"RAM copy","Kopie RAM"}.
|
||||
{"Raw","Zdroj"}.
|
||||
{"Really delete message of the day?","Skutečně smazat zprávu dne?"}.
|
||||
{"Recipient is not in the conference room","Příjemce se nenachází v konferenční místnosti"}.
|
||||
{"Register a Jabber account","Zaregistrujte si účet Jabberu"}.
|
||||
{"Registered nicknames","Registrované přezdívky"}.
|
||||
{"Registered Users","Registrovaní uživatelé"}.
|
||||
{"Registered Users:","Registrovaní živatelé:"}.
|
||||
{"Register","Zaregistrovat se"}.
|
||||
@@ -269,7 +309,9 @@
|
||||
{"Restore binary backup immediately:","Okamžitě obnovit binární zálohu:"}.
|
||||
{"Restore","Obnovit"}.
|
||||
{"Restore plain text backup immediately:","Okamžitě obnovit zálohu z textového souboru:"}.
|
||||
{"Roles for which Presence is Broadcasted","Role, pro které je zpráva o stavu šířena"}.
|
||||
{"Room Configuration","Nastavení místnosti"}.
|
||||
{"Room creation is denied by service policy","Pravidla služby nepovolují vytvořit místnost"}.
|
||||
{"Room description","Popis místnosti"}.
|
||||
{"Room Occupants","Počet účastníků"}.
|
||||
{"Room title","Název místnosti"}.
|
||||
@@ -298,7 +340,7 @@
|
||||
{"Show Ordinary Table","Zobrazit běžnou tabulku"}.
|
||||
{"Shut Down Service","Vypnout službu"}.
|
||||
{"~s invites you to the room ~s","~s vás zve do místnosti ~s"}.
|
||||
{"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Někteří klienti umí uložit vaše heslo na disk počítače. Tuto funkci používejte, pouze pokud věříte zabezpečení svého počítače."}.
|
||||
{"Some Jabber clients can store your password in the computer, but you should do this only in your personal computer for safety reasons.","Někteří klienti umí uložit vaše heslo na disk počítače. Tuto funkci používejte, pouze pokud věříte zabezpečení svého počítače."}.
|
||||
{"Specify the access model","Uveďte přístupový model"}.
|
||||
{"Specify the event message type","Zvolte typ zpráv pro události"}.
|
||||
{"Specify the publisher model","Specifikovat model pro publikování"}.
|
||||
@@ -321,32 +363,44 @@
|
||||
{"Subscriber Address","Adresa odběratele"}.
|
||||
{"Subscription","Přihlášení"}.
|
||||
{"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 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"}.
|
||||
{"The password is too weak","Heslo je příliš slabé"}.
|
||||
{"The password of your Jabber account was successfully changed.","Heslo vašeho účtu Jabberu bylo úspěšně změněno."}.
|
||||
{"There was an error changing the password: ","Při změně hesla došlo k chybě: "}.
|
||||
{"There was an error creating the account: ","Při vytváření účtu došlo k chybě."}.
|
||||
{"There was an error deleting the account: ","Při mazání účtu došlo k chybě: "}.
|
||||
{"This IP address is blacklisted in ~s","IP adresa je blokována na ~s"}.
|
||||
{"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Zde nezáleží na velikosti písmen: macbeth je stejný jako MacBeth a 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.","Na této stránce si můžete vytvořit účet na tomto serveru Jabberu. Vaše JID (Jabber IDentifikátor) bude mít tvar: uživatelskéjméno@server. Přečtěte si prosím pozorně instrukce pro vyplnění údajů."}.
|
||||
{"This page allows to unregister a Jabber account in this Jabber server.","Zde můžete zrušit registraci účtu na tomto serveru Jabberu."}.
|
||||
{"Thursday","Čtvrtek"}.
|
||||
{"Time","Čas"}.
|
||||
{"Time delay","Časový posun"}.
|
||||
{"Too many CAPTCHA requests","Přiliš mnoho CAPTCHA žádostí"}.
|
||||
{"Too many (~p) failed authentications from this IP address (~s). The address will be unblocked at ~s UTC","Příliš mnoho (~p) chybných pokusů o přihlášení z této IP adresy (~s). Adresa bude zablokována do ~s UTC"}.
|
||||
{"Too many unacked stanzas","Příliš mnoho nepotvrzených stanz"}.
|
||||
{"To","Pro"}.
|
||||
{"To ~s","Pro ~s"}.
|
||||
{"Total rooms","Celkem konferencí"}.
|
||||
{"Traffic rate limit is exceeded","Byl překročen limit"}.
|
||||
{"Transactions Aborted:","Transakce zrušena"}.
|
||||
{"Transactions Committed:","Transakce potvrzena"}.
|
||||
{"Transactions Logged:","Transakce zaznamenána"}.
|
||||
{"Transactions Restarted:","Transakce restartována"}.
|
||||
{"Tuesday","Úterý"}.
|
||||
{"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"}.
|
||||
{"Unregister","Zrušit registraci"}.
|
||||
{"Update","Aktualizovat"}.
|
||||
{"Update message of the day (don't send)","Aktualizovat zprávu dne (neodesílat)"}.
|
||||
{"Update message of the day on all hosts (don't send)","Aktualizovat zprávu dne pro všechny hostitele (neodesílat)"}.
|
||||
{"Update ~p","Aktualizovat ~p"}.
|
||||
{"Update plan","Aktualizovat plán"}.
|
||||
{"Update script","Aktualizované skripty"}.
|
||||
{"Uptime:","Čas běhu:"}.
|
||||
@@ -354,22 +408,32 @@
|
||||
{"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"}.
|
||||
{"Users Last Activity","Poslední aktivita uživatele"}.
|
||||
{"Users","Uživatelé"}.
|
||||
{"User ~s","Uživatel ~s"}.
|
||||
{"User","Uživatel"}.
|
||||
{"Validate","Ověřit"}.
|
||||
{"vCard User Search","Hledání uživatelů podle vizitek"}.
|
||||
{"Virtual Hosts","Virtuální hostitelé"}.
|
||||
{"Visitor","Návštěvník"}.
|
||||
{"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í"}.
|
||||
{"You can later change your password using a Jabber client.","Později můžete své heslo změnit pomocí klienta Jabberu."}.
|
||||
{"You have been banned from this room","Byl jste vyloučen z této místnosti"}.
|
||||
{"You must fill in field \"Nickname\" in the form","Musíte vyplnit políčko \"Přezdívka\" ve formuláři"}.
|
||||
{"You need a client that supports x:data and CAPTCHA to register","Pro registraci potřebujete klienta s podporou x:data a CAPTCHA"}.
|
||||
{"You need a client that supports x:data to register the nickname","Pro registraci přezdívky potřebujete klienta s podporou x:data"}.
|
||||
{"You need an x:data capable client to configure mod_irc settings","Pro konfiguraci mod_irc potřebujete klienta s podporou x:data"}.
|
||||
{"You need an x:data capable client to configure room","Ke konfiguraci místnosti potřebujete klienta podporujícího x:data"}.
|
||||
{"You need an x:data capable client to search","K vyhledávání potřebujete klienta podporujícího x:data"}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","Vaše nastavení soukromí znemožnilo směrování této stance."}.
|
||||
{"Your contact offline message queue is full. The message has been discarded.","Fronta offline zpráv pro váš kontakt je plná. Zpráva byla zahozena."}.
|
||||
{"Your Jabber account was successfully created.","Váš účet Jabberu byl úspěšně vytvořen."}.
|
||||
{"Your Jabber account was successfully deleted.","Váš účet Jabberu byl úspěšně smazán."}.
|
||||
{"Your messages to ~s are being blocked. To unblock them, visit ~s","Nesmíte posílat zprávy na ~s. Pro povolení navštivte ~s"}.
|
||||
|
||||
+522
-449
File diff suppressed because it is too large
Load Diff
+51
-4
@@ -1,8 +1,10 @@
|
||||
%% -*- coding: latin-1 -*-
|
||||
{"Accept","Akzeptieren"}.
|
||||
{"Access Configuration","Zugangskonfiguration"}.
|
||||
{"Access Control List Configuration","Konfiguration der Zugangskontrolllisten"}.
|
||||
{"Access control lists","Zugangskontroll-Listen (ACL)"}.
|
||||
{"Access Control Lists","Zugangskontroll-Listen (ACL)"}.
|
||||
{"Access denied by service policy","Zugang aufgrund der Dienstrichtlinien verweigert"}.
|
||||
{"Access rules","Zugangsregeln"}.
|
||||
{"Access Rules","Zugangsregeln"}.
|
||||
{"Action on user","Aktion auf Benutzer"}.
|
||||
@@ -11,6 +13,7 @@
|
||||
{"Add User","Benutzer hinzufügen"}.
|
||||
{"Administration of ","Administration von "}.
|
||||
{"Administration","Verwaltung"}.
|
||||
{"Administrator privileges required","Administratorenrechte benötigt"}.
|
||||
{"A friendly name for the node","Ein merkbarer Name für den Knoten"}.
|
||||
{"All activity","Alle Aktivitäten"}.
|
||||
{"Allow this Jabber ID to subscribe to this pubsub node?","Dieser Jabber-ID das Abonnement dieses pubsub-Knotens erlauben?"}.
|
||||
@@ -25,6 +28,7 @@
|
||||
{"All Users","Alle Benutzer"}.
|
||||
{"Announcements","Ankündigungen"}.
|
||||
{"anyone","jeden"}.
|
||||
{"A password is required to enter this room","Sie brauchen ein Passwort um diesen Raum zu betreten"}.
|
||||
{"April","April"}.
|
||||
{"August","August"}.
|
||||
{"Backup","Datensicherung"}.
|
||||
@@ -49,6 +53,7 @@
|
||||
{"Choose whether to approve this entity's subscription.","Wählen sie, ob dieses Abonnement akzeptiert werden soll."}.
|
||||
{"City","Stadt"}.
|
||||
{"Commands","Befehle"}.
|
||||
{"Conference room does not exist","Konferenzraum existiert nicht"}.
|
||||
{"Configuration","Konfiguration"}.
|
||||
{"Configuration of room ~s","Konfiguration für Raum ~s"}.
|
||||
{"Connected Resources:","Verbundene Ressourcen:"}.
|
||||
@@ -83,6 +88,7 @@
|
||||
{"ejabberd Web Admin","ejabberd Web-Admin"}.
|
||||
{"Elements","Elemente"}.
|
||||
{"Email","E-Mail"}.
|
||||
{"Empty Rooms","Leere Räume"}.
|
||||
{"Enable logging","Protokollierung aktivieren"}.
|
||||
{"Enable message archiving","Nachrichtenarchivierung aktivieren"}.
|
||||
{"Encoding for server ~b","Kodierung für Server ~b"}.
|
||||
@@ -103,6 +109,7 @@
|
||||
{"Export all tables as SQL queries to a file:","Alle Tabellen als SQL Abfragen in eine Datei exportieren:"}.
|
||||
{"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 bestimmten Jabber-Benutzern zu suchen"}.
|
||||
@@ -136,6 +143,9 @@
|
||||
{"Import users data from jabberd14 spool directory:","Importiere Benutzer von jabberd14 Spool Verzeichnis:"}.
|
||||
{"Import Users from Dir at ","Benutzer importieren aus dem Verzeichnis "}.
|
||||
{"Import Users From jabberd14 Spool Files","Importiere Benutzer aus jabberd14-Spool-Dateien"}.
|
||||
{"Improper message type","Unzulässiger Nachrichtentyp"}.
|
||||
{"Incoming s2s Connections:","Eingehende s2s-Verbindungen:"}.
|
||||
{"Incorrect password","Falsches Passwort"}.
|
||||
{"Invalid affiliation: ~s","Ungültige Mitgliedschaft: ~s"}.
|
||||
{"Invalid role: ~s","Ungültige Rolle: ~s"}.
|
||||
{"IP addresses","IP Adressen"}.
|
||||
@@ -147,6 +157,10 @@
|
||||
{"IRC username","IRC Benutzername"}.
|
||||
{"IRC Username","IRC-Benutzername"}.
|
||||
{"is now known as","ist nun bekannt als"}.
|
||||
{"It is not allowed to send error messages to the room. The participant (~s) has sent an error message (~s) and got kicked from the room","Es ist nicht erlaubt Fehlermeldungen an den Raum zu senden. Der Teilnehmer (~s) hat eine Fehlermeldung (~s) gesendet und wurde aus dem Raum entfernt"}.
|
||||
{"It is not allowed to send private messages","Es ist nicht erlaubt private Nachrichten zu senden"}.
|
||||
{"It is not allowed to send private messages of type \"groupchat\"","Es ist nicht erlaubt private Nachrichten des Typs \"Gruppenchat\" zu senden"}.
|
||||
{"It is not allowed to send private messages to the conference","Es ist nicht erlaubt private Nachrichten an den Raum zu schicken"}.
|
||||
{"Jabber Account Registration","Jabber Konto Anmeldung"}.
|
||||
{"Jabber ID","Jabber ID"}.
|
||||
{"Jabber ID ~s is invalid","Die Jabber-ID ~s ist ungültig"}.
|
||||
@@ -179,12 +193,15 @@
|
||||
{"Max # of items to persist","Maximale Anzahl dauerhaft zu speichernder Einträge"}.
|
||||
{"Max payload size in bytes","Maximale Nutzlastgrösse in Bytes"}.
|
||||
{"May","Mai"}.
|
||||
{"Membership is required to enter this room","Um diesen Raum zu betreten müssen sie Mitglied sein"}.
|
||||
{"Members:","Mitglieder:"}.
|
||||
{"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.","Merken sie sich ihr Passwort, oder schreiben sie es auf einen Zettel den sie sicher verwahren. Bei Jabber gibt es keine automatische Möglichkeit, das Passwort wiederherzustellen."}.
|
||||
{"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","Moderator"}.
|
||||
{"Moderator privileges required","Moderatorrechte benötigt"}.
|
||||
{"moderators only","ausschliesslich Moderatoren"}.
|
||||
{"Modified modules","Geänderte Module"}.
|
||||
{"Module","Modul"}.
|
||||
@@ -198,7 +215,7 @@
|
||||
{"Never","Nie"}.
|
||||
{"New Password:","Neues Passwort:"}.
|
||||
{"Nickname","Benutzername"}.
|
||||
{"Nickname Registration at ","Registrieren des Benutzernames auf"}.
|
||||
{"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ündigungsnachricht angegeben"}.
|
||||
@@ -227,15 +244,21 @@
|
||||
{"Online Users:","Angemeldete Benutzer:"}.
|
||||
{"Online Users","Angemeldete Benutzer"}.
|
||||
{"Only deliver notifications to available users","Benachrichtigungen nur an verfügbare Benutzer schicken"}.
|
||||
{"Only members may query archives of this room","Nur Mitglieder dürfen den Verlauf dieses Raumes abrufen"}.
|
||||
{"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"}.
|
||||
{"Options","Optionen"}.
|
||||
{"Organization Name","Name der Organisation"}.
|
||||
{"Organization Unit","Abteilung"}.
|
||||
{"Outgoing s2s Connections:","Ausgehende s2s-Verbindungen:"}.
|
||||
{"Outgoing s2s Connections","Ausgehende s2s-Verbindungen"}.
|
||||
{"Outgoing s2s Servers:","Ausgehende s2s-Server:"}.
|
||||
{"Owner privileges required","Besitzerrechte benötigt"}.
|
||||
{"Packet","Paket"}.
|
||||
{"Participant","Teilnehmer"}.
|
||||
{"Password ~b","Passwort ~b"}.
|
||||
{"Password:","Passwort:"}.
|
||||
{"Password","Passwort"}.
|
||||
@@ -245,10 +268,13 @@
|
||||
{"Path to File","Pfad zur Datei"}.
|
||||
{"Pending","Schwebend"}.
|
||||
{"Period: ","Zeitraum: "}.
|
||||
{"Permanent rooms","permanente Chaträume"}.
|
||||
{"Permanent rooms","Permanente Chaträume"}.
|
||||
{"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 specify file name.","Bitte geben Sie den Dateinamen an."}.
|
||||
{"Please specify file size.","Bitte geben Sie die Dateigröße an."}.
|
||||
{"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"}.
|
||||
@@ -258,10 +284,12 @@
|
||||
{"Publish-Subscribe","Publish-Subscribe"}.
|
||||
{"PubSub subscriber request","PubSub-Abonnenten-Anfrage"}.
|
||||
{"Purge all items when the relevant publisher goes offline","Alle Einträge entfernen, wenn der relevante Veröffentlicher offline geht"}.
|
||||
{"Queries to the conference members are not allowed in this room","Anfragen an die Teilnehmer sind in diesem Raum nicht erlaubt"}.
|
||||
{"RAM and disc copy","RAM und Festplatte"}.
|
||||
{"RAM copy","Nur RAM"}.
|
||||
{"Raw","Unformatiert"}.
|
||||
{"Really delete message of the day?","Die Nachricht des Tages wirklich löschen?"}.
|
||||
{"Recipient is not in the conference room","Der Empfänger ist nicht im Raum"}.
|
||||
{"Register a Jabber account","Jabber Konto registrieren"}.
|
||||
{"Register","Anmelden"}.
|
||||
{"Registered nicknames","Registrierte Benutzernamen"}.
|
||||
@@ -281,7 +309,9 @@
|
||||
{"Restore binary backup immediately:","Stelle binäre Sicherung sofort wieder her:"}.
|
||||
{"Restore plain text backup immediately:","Stelle Klartext-Sicherung sofort wieder her:"}.
|
||||
{"Restore","Wiederherstellung"}.
|
||||
{"Roles for which Presence is Broadcasted","Rollen, für die der Status übertragen wird"}.
|
||||
{"Room Configuration","Raum-Konfiguration"}.
|
||||
{"Room creation is denied by service policy","Anlegen des Raumes aufgrund der Dienstrichtlinien verweigert"}.
|
||||
{"Room description","Raum Beschreibung"}.
|
||||
{"Room Occupants","Teilnehmer in diesem Raum"}.
|
||||
{"Room title","Raumname"}.
|
||||
@@ -303,6 +333,7 @@
|
||||
{"September","September"}.
|
||||
{"Server ~b","Server ~b"}.
|
||||
{"Server:","Server:"}.
|
||||
{"Server","Server"}.
|
||||
{"Set message of the day and send to online users","Setze Nachricht des Tages und sende sie an alle angemeldeten Benutzer"}.
|
||||
{"Set message of the day on all hosts and send to online users","Setze Nachricht des Tages auf allen Hosts und sende sie an alle angemeldeten Benutzer"}.
|
||||
{"Shared Roster Groups","Gruppen der gemeinsamen Kontaktliste"}.
|
||||
@@ -310,7 +341,7 @@
|
||||
{"Show Ordinary Table","Gewöhnliche Tabelle anzeigen"}.
|
||||
{"Shut Down Service","Dienst herunterfahren"}.
|
||||
{"~s invites you to the room ~s","~s lädt sie in den Raum ~s ein"}.
|
||||
{"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Einige Jabber Client Programme speichern ihr Passwort auf ihrem Computer. Verwenden sie diese Möglichkeit nur auf Computern, die sie als sicher einstufen."}.
|
||||
{"Some Jabber clients can store your password in the computer, but you should do this only in your personal computer for safety reasons.","Einige Jabber Client Programme speichern ihr Passwort auf ihrem Computer. Verwenden sie diese Möglichkeit nur auf Computern, die sie als sicher einstufen."}.
|
||||
{"Specify the access model","Geben sie das Zugangsmodell an"}.
|
||||
{"Specify the event message type","Geben sie den Ereignis-Nachrichtentyp an"}.
|
||||
{"Specify the publisher model","Geben sie das Publikationsmodell an"}.
|
||||
@@ -333,9 +364,13 @@
|
||||
{"Subscriber Address","Abonnenten-Adresse"}.
|
||||
{"Subscription","Abonnement"}.
|
||||
{"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 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"}.
|
||||
{"The password is too weak","Das Passwort ist zu einfach"}.
|
||||
{"The password of your Jabber account was successfully changed.","Das Passwort von ihrem Jabber Konto wurde geändert."}.
|
||||
{"There was an error changing the password: ","Es trat ein Fehler beim Ändern des Passworts auf: "}.
|
||||
{"There was an error creating the account: ","Es trat ein Fehler beim Erstellen des Kontos auf: "}.
|
||||
@@ -348,15 +383,18 @@
|
||||
{"Time delay","Zeitverzögerung"}.
|
||||
{"Time","Zeit"}.
|
||||
{"To","An"}.
|
||||
{"Too many CAPTCHA requests","Zu viele CAPTCHA Anfragen"}.
|
||||
{"Too many (~p) failed authentications from this IP address (~s). The address will be unblocked at ~s UTC","Zu viele (~p) fehlgeschlagene Anmeldeversuche von dieser IP Adresse (~s). Die Adresse wird bis ~s UTC blockiert."}.
|
||||
{"Too many unacked stanzas","Zu viele unbestätigte Stanzas"}.
|
||||
{"To ~s","An ~s"}.
|
||||
{"Total rooms","Alle Chaträume"}.
|
||||
{"Traffic rate limit is exceeded","Datenratenlimit wurde überschritten"}.
|
||||
{"Transactions Aborted:","Abgebrochene Transaktionen:"}.
|
||||
{"Transactions Committed:","Durchgeführte Transaktionen:"}.
|
||||
{"Transactions Logged:","Protokollierte Transaktionen:"}.
|
||||
{"Transactions Restarted:","Neu gestartete Transaktionen:"}.
|
||||
{"Tuesday","Dienstag"}.
|
||||
{"Unable to generate a CAPTCHA","Konnte CAPTCHA nicht erstellen"}.
|
||||
{"Unauthorized","Nicht berechtigt"}.
|
||||
{"Unregister","Abmelden"}.
|
||||
{"Unregister a Jabber account","Jabber Konto entfernen"}.
|
||||
@@ -372,22 +410,31 @@
|
||||
{"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"}.
|
||||
{"Users","Benutzer"}.
|
||||
{"User ~s","Benutzer ~s"}.
|
||||
{"Users Last Activity","Letzte Benutzeraktivität"}.
|
||||
{"Validate","Validieren"}.
|
||||
{"vCard User Search","vCard-Benutzer-Suche"}.
|
||||
{"Virtual Hosts","Virtuelle Hosts"}.
|
||||
{"Visitor","Besucher"}.
|
||||
{"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 das letzte veröffentlichte Objekt gesendet werden soll"}.
|
||||
{"Whether to allow subscriptions","Ob Abonnements erlaubt sind"}.
|
||||
{"You can later change your password using a Jabber client.","Sie können das Passwort später mit einem Jabber Client Programm ändern."}.
|
||||
{"You have been banned from this room","Sie wurden aus diesem Raum verbannt"}.
|
||||
{"You must fill in field \"Nickname\" in the form","Sie müssen das Feld \"Benutzername\" ausfüllen"}.
|
||||
{"You need a client that supports x:data and CAPTCHA to register","Sie benötigen einen Client, der x:data und CAPTCHA unterstützt, um Ihren Benutzernamen zu registrieren"}.
|
||||
{"You need a client that supports x:data to register the nickname","Sie benötigen einen Client, der x:data unterstützt, um Ihren Benutzernamen zu registrieren"}.
|
||||
{"You need an x:data capable client to configure mod_irc settings","Sie benötigen einen Client, der x:data unterstützt, um die mod_irc-Einstellungen zu konfigurieren"}.
|
||||
{"You need an x:data capable client to configure room","Sie benötigen einen Client, der x:data unterstützt, um den Raum zu konfigurieren"}.
|
||||
{"You need an x:data capable client to search","Sie benötigen einen Client, der x:data unterstützt, um die Suche verwenden zu können"}.
|
||||
{"Your active privacy list has denied the routing of this stanza.","Ihre aktive Privacy Liste hat die Weiterleitung des Stanzas unterbunden."}.
|
||||
{"Your contact offline message queue is full. The message has been discarded.","Ihre Offline-Nachrichten-Warteschlange ist voll. Die Nachricht wurde verworfen."}.
|
||||
{"Your Jabber account was successfully created.","Ihr Jabber Konto wurde erfolgreich erstellt."}.
|
||||
{"Your Jabber account was successfully deleted.","Ihr Jabber Konto wurde erfolgreich gelöscht."}.
|
||||
{"Your messages to ~s are being blocked. To unblock them, visit ~s","Ihre Nachrichten an ~s werden blockiert. Um dies zu ändern, besuchen sie ~s"}.
|
||||
|
||||
+507
-433
File diff suppressed because it is too large
Load Diff
+495
-312
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