Compare commits
1088 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 485100f907 | |||
| 240977a0da | |||
| cdc9c93b9b | |||
| 529d6d8a93 | |||
| dd9281da13 | |||
| 1b8794c991 | |||
| 48c96dc1a9 | |||
| 439fe0b504 | |||
| e03d41647b | |||
| 23c5fd9a4f | |||
| 08e54dd621 | |||
| 8918227fc3 | |||
| 5ba13df519 | |||
| dd4d45fd28 | |||
| 82b3bbf360 | |||
| d59d4e27ec | |||
| e6d1ff85f1 | |||
| ef6af11f17 | |||
| 6bdf29676c | |||
| 56241feb58 | |||
| 9fcc12dca7 | |||
| bbb1f7002d | |||
| 812acf0688 | |||
| 60b6a508e0 | |||
| 34d09018a7 | |||
| 7cdc51becd | |||
| 2d43c07c62 | |||
| 514df9ac18 | |||
| a8c3ed5ed4 | |||
| e7308b7d86 | |||
| 4e49919d16 | |||
| 9ba471e210 | |||
| 6dca89f616 | |||
| 1698956f34 | |||
| b54e1e49ba | |||
| 5e4c547856 | |||
| 50b19b47e0 | |||
| a3083b5d71 | |||
| 32ad7d3761 | |||
| 7f073fbcd8 | |||
| 826387446a | |||
| af9183cd54 | |||
| 242c3c1da5 | |||
| 212d44f419 | |||
| 63a60f1cd8 | |||
| 08ce16f7ca | |||
| 051e1be832 | |||
| 9bccac03f5 | |||
| c9333f247a | |||
| c658f871a5 | |||
| a0607f6740 | |||
| 47c2118fa7 | |||
| 59f4efe3dd | |||
| bd1ff0e897 | |||
| 5b42fc1d0d | |||
| 515f8b22c0 | |||
| 4352cb9fed | |||
| 5968bc9318 | |||
| a65a78ebfe | |||
| 08e642b988 | |||
| 42932fd19e | |||
| b204f9349f | |||
| 03246f5ff4 | |||
| 57e3f49352 | |||
| b661bee4b1 | |||
| 47f6fc8dd2 | |||
| 42b2e6c5ab | |||
| 303eea5e4d | |||
| bd064fa3fc | |||
| 12d9d97baa | |||
| ae66c17ec0 | |||
| 614bd9dd72 | |||
| e15a9a2b9e | |||
| f1ac793d56 | |||
| 97c9058246 | |||
| a820d735c0 | |||
| a303373b0f | |||
| d8ace67a50 | |||
| 344a2611f2 | |||
| c2b22bd6c1 | |||
| abeee837fc | |||
| 7a9d2cabc0 | |||
| e4a4839880 | |||
| ab2a90181c | |||
| bca87e2c89 | |||
| 418718de31 | |||
| 0b1a6d7e79 | |||
| 395b74a89f | |||
| a5849a0dab | |||
| 8639da0e00 | |||
| cf67b9ec54 | |||
| ddaa8c7c1d | |||
| b072342aa9 | |||
| 10edbe3e09 | |||
| 783ebd1080 | |||
| 242b3d3968 | |||
| cf8e70abc8 | |||
| 5676adff30 | |||
| e31f6409a6 | |||
| a57c694f21 | |||
| 0e5b343f1b | |||
| 25f7f974b9 | |||
| fbd6ea8a48 | |||
| 3a02c4369f | |||
| 19975962ea | |||
| 6a0e24fb14 | |||
| e9e56ed183 | |||
| 6686a64d5f | |||
| c26b56679e | |||
| 98b411523d | |||
| 4b9d299e90 | |||
| 49c4aa238f | |||
| e709d6561c | |||
| f06805534c | |||
| 3202b7a9a1 | |||
| 4f12359b9c | |||
| f599c2ef82 | |||
| b2680a776b | |||
| b67a114ef5 | |||
| 224a3e13c9 | |||
| 382fb62f29 | |||
| b6b70ec0d4 | |||
| 4835537776 | |||
| ce98226603 | |||
| c05626a1ba | |||
| 514c25caef | |||
| 00e32ee4b6 | |||
| 44700d91ba | |||
| 2531f37e5c | |||
| 62aab0fce4 | |||
| e706e24b92 | |||
| 11ee896f10 | |||
| 1f21f64d5f | |||
| ebb97bec44 | |||
| 0c6ef98d01 | |||
| 6cd3867197 | |||
| b04c6b7d75 | |||
| af49472373 | |||
| 75f150f7ae | |||
| 98419c6662 | |||
| 2b3890f1b0 | |||
| 06d4f1ff33 | |||
| 5ae23a7301 | |||
| 8376370ae1 | |||
| 054413d8f4 | |||
| ce99db0595 | |||
| f953621ed2 | |||
| 474536817e | |||
| daed6a05a6 | |||
| 9daf2dd925 | |||
| 1413f5dd23 | |||
| b06adf1df2 | |||
| 11829906ac | |||
| 78f494dd2e | |||
| 76e9555d55 | |||
| e77172a784 | |||
| 675a1e0b0f | |||
| 54c8ae4d2b | |||
| 5c6a37b20f | |||
| 50b3206f06 | |||
| 7a3092a859 | |||
| 66c9f6458d | |||
| d1df522fd9 | |||
| e47b016e76 | |||
| 28661d20bd | |||
| 9c174e30b2 | |||
| 40d725e9c1 | |||
| 5cf4e200ba | |||
| 902c6d476b | |||
| 74749f5dbb | |||
| fe9b191382 | |||
| 5d5b4cdfb5 | |||
| cbbfe32d8b | |||
| 7121a95428 | |||
| 41c393466c | |||
| 7d8ad17fa1 | |||
| 44293235e5 | |||
| ec3ea61585 | |||
| 90e1f3f29d | |||
| 2060022b19 | |||
| 681d81bdcc | |||
| c72e0a6ca6 | |||
| 189d02cee0 | |||
| 79a9a0ed29 | |||
| 78dfb832b8 | |||
| 354a710e70 | |||
| 8eb1e5c68c | |||
| a22aad0a4b | |||
| ae07fd7f10 | |||
| 86809dff06 | |||
| 35dc164233 | |||
| 170be1fbd5 | |||
| 35b7203e01 | |||
| efc4996625 | |||
| 88558453fb | |||
| ee2b5be7f4 | |||
| ce98843dd4 | |||
| 5f2e33bdd0 | |||
| 0452ffc1df | |||
| e24e05c6af | |||
| e697a3e262 | |||
| 8cb71255eb | |||
| 675cc3e0ea | |||
| 5f0a84a331 | |||
| 9b8ae80dab | |||
| 0633dd5802 | |||
| 2b363c7aee | |||
| 2aeee9eab4 | |||
| ed792274e3 | |||
| dbdda745af | |||
| df86ecdd87 | |||
| e1c8e88d87 | |||
| b6c88fb17e | |||
| 24df1262bb | |||
| 484e5de072 | |||
| 568ab526e2 | |||
| a8238d6a54 | |||
| 9eb2685f90 | |||
| db57394399 | |||
| 88928c0149 | |||
| 2161063e5e | |||
| 29462f0053 | |||
| 3162ec0d66 | |||
| e4054aab79 | |||
| 8028a9545a | |||
| 7c1b4d0fcd | |||
| 17e3ed513b | |||
| 65c85eab03 | |||
| 5151136d17 | |||
| debbddb763 | |||
| 8b588d2ff3 | |||
| 90ee405d81 | |||
| b0fa27395f | |||
| ce83e2261e | |||
| 06cd373a18 | |||
| 46fb2d0f56 | |||
| 21f2c57920 | |||
| 5667b4b0f9 | |||
| 91e8249284 | |||
| 1bb2bae62b | |||
| 152e0d77c1 | |||
| 9d6ec1ba12 | |||
| 0c29f07758 | |||
| 7f93b72a1d | |||
| e5e64c99f3 | |||
| 85c703a8f7 | |||
| 2832130afc | |||
| f751023bd6 | |||
| f0a68b85f0 | |||
| 02fa719a87 | |||
| 5a184b0433 | |||
| d22ee24e72 | |||
| a6e5a5ca9a | |||
| 8513e31498 | |||
| 6efdd0f350 | |||
| 0ed210877a | |||
| a06f1a0ba5 | |||
| 4bd5846d40 | |||
| 3c7ab13374 | |||
| df439f27ee | |||
| d37d43495b | |||
| 6f922275eb | |||
| 94de13981b | |||
| 43e729293a | |||
| f3af117108 | |||
| bd06bc00e2 | |||
| 9e95150803 | |||
| 532aba993b | |||
| 79685da90b | |||
| 280aa2f1b0 | |||
| 668d45cbc7 | |||
| e2f4cb5838 | |||
| 6658806820 | |||
| a7341957f2 | |||
| 2cb0cedc6b | |||
| 77a1f728cf | |||
| d576902bd4 | |||
| a3da27e917 | |||
| 3f015c829c | |||
| 2732c8f6fc | |||
| 3192687334 | |||
| 126653e01b | |||
| ce7acafe37 | |||
| 216a0c97b9 | |||
| 3c8308bb8d | |||
| 1c6aa5e84e | |||
| 609a1d07cf | |||
| 8c026582ab | |||
| 81df1ae3af | |||
| 22435ca562 | |||
| f464189819 | |||
| 89e504c55f | |||
| c1d3d1318e | |||
| d120e0ad91 | |||
| c17ec50e3a | |||
| 368ba3fc55 | |||
| cd098c5adc | |||
| 221e58fff0 | |||
| 9b043ae276 | |||
| abc09054e5 | |||
| 07a193d4dc | |||
| cf09ed2df2 | |||
| 0cc1ae0a6a | |||
| e1efd29156 | |||
| 05feab35c4 | |||
| 2198fbce97 | |||
| b8ab80d1f3 | |||
| 30e5c9bd3e | |||
| 251756de00 | |||
| 3e987d3bae | |||
| 138cc25355 | |||
| a15f186253 | |||
| 59ec3d36f4 | |||
| d7250111ce | |||
| adfb924808 | |||
| 48f2adde98 | |||
| c378ea403e | |||
| 692ccd2e20 | |||
| 5882c9b456 | |||
| db41643bea | |||
| cb076924cc | |||
| cce4056040 | |||
| 7ad525b542 | |||
| 5bf64381cb | |||
| f435d0a103 | |||
| e4d21c1941 | |||
| 5414cbe821 | |||
| e6b1521b29 | |||
| 2a7d9d93c8 | |||
| dfd2045523 | |||
| 9e35af54e0 | |||
| d87151aee6 | |||
| 4ecd8a0780 | |||
| 803c31f760 | |||
| 978c92f5e1 | |||
| 315e330237 | |||
| f55a8d045d | |||
| 32397aa0c3 | |||
| 1a58a201f8 | |||
| 2acbf4625b | |||
| 7566d254e4 | |||
| 68dee8cbb3 | |||
| f7e8d287d5 | |||
| 80b44d8c15 | |||
| 30bca124f4 | |||
| d7891a5562 | |||
| 1d396b4716 | |||
| 7f3fceb432 | |||
| 81581f7794 | |||
| 47175adc74 | |||
| 350827f8f4 | |||
| f1ea67817c | |||
| 30e729a150 | |||
| 8c56fbc0d8 | |||
| a59ccc6c9c | |||
| 62903155fd | |||
| 25ca6e5582 | |||
| 37a54cd498 | |||
| 6f972fa3fe | |||
| 10f7b5a548 | |||
| f2876bdad7 | |||
| 05c2995c7a | |||
| 2fa6e2fd90 | |||
| 9b3e160e18 | |||
| 15dd88385f | |||
| f581e391ac | |||
| dd42d52ff9 | |||
| e45f7ddfec | |||
| 7cc7b74f1e | |||
| ddfe8742c7 | |||
| ba9a79c89c | |||
| 13ad754ecc | |||
| 0b02d42836 | |||
| ee0a8d2966 | |||
| 793ca45dda | |||
| 6e20e9bcf9 | |||
| b8d2a72333 | |||
| 0760c7273c | |||
| 9bd099013f | |||
| 68fb12153e | |||
| e19d1e9571 | |||
| 1820b4f63b | |||
| 64150cc7c5 | |||
| 63aabed320 | |||
| 051e2c639c | |||
| 3b22efeaee | |||
| a72a7f830a | |||
| 73f0b6707a | |||
| fd7bf7fed3 | |||
| 1aadb797b3 | |||
| 7140c8d844 | |||
| 7a90cda8ff | |||
| 35eeaa5869 | |||
| 024713a441 | |||
| 32fbfe1981 | |||
| 9c5427e0c2 | |||
| 8f5a1c4a2a | |||
| 7d3609d954 | |||
| fc7ba53c37 | |||
| 2b1fea01cd | |||
| c20bfb3422 | |||
| 011b7ac3f2 | |||
| a96d72330d | |||
| 7d626b4f5c | |||
| e903348dd3 | |||
| bee251d928 | |||
| c658907331 | |||
| 97a4d57f2e | |||
| 3fec782494 | |||
| 9756b452d6 | |||
| 7fa9a387ae | |||
| 48254a1e10 | |||
| 52525eb76d | |||
| 8679cfd2f3 | |||
| 25af3fb029 | |||
| 2bceebc39d | |||
| 92532a0d66 | |||
| b673539a2a | |||
| e1aaa1c99d | |||
| aa9eb001d0 | |||
| 101e808124 | |||
| 766b7c65a6 | |||
| 0516a3dc0e | |||
| 3d185c0fb8 | |||
| 7815164216 | |||
| 65f4094804 | |||
| 06450f4a82 | |||
| ce0beb550c | |||
| 96c0483533 | |||
| 1274bcdba9 | |||
| 5dcc97c85a | |||
| e6e8e64f84 | |||
| ac7105d39e | |||
| 6deceeec2e | |||
| 9edcbadd60 | |||
| f65492e27f | |||
| 1df61a82c8 | |||
| 73509686f1 | |||
| 93e521d65e | |||
| 50511fcff7 | |||
| 5e26190b98 | |||
| f22bd6eb46 | |||
| 0ba6c78ed0 | |||
| 636d68e0a9 | |||
| 7e6d1c24c2 | |||
| 67918b17d3 | |||
| 3abe3aeeec | |||
| 51fa438340 | |||
| 35a11526f9 | |||
| 0cfec92c14 | |||
| e5f64bc24a | |||
| cc6f4b90fb | |||
| 5c48ba4609 | |||
| 3ca62a797a | |||
| b66dab1313 | |||
| 58110e4bc1 | |||
| ea96615460 | |||
| 61d1411ab3 | |||
| 1a506da932 | |||
| b8c26671c4 | |||
| 92e38190aa | |||
| 09918b5912 | |||
| 2e88d001d6 | |||
| 1a0db3de3a | |||
| 250876ea1a | |||
| 66510c1d78 | |||
| d6f1d3df5b | |||
| 72dbb6e7c1 | |||
| b1082a96c9 | |||
| ed17586cf0 | |||
| 26b8dd75f7 | |||
| c3473c2077 | |||
| e216654c52 | |||
| cc3391cc1c | |||
| b8d56a7c11 | |||
| 9ce1f12b66 | |||
| 1bb9e83501 | |||
| de1a66dfbe | |||
| 2e18122cd9 | |||
| 8fe551cc68 | |||
| 09c3496ff1 | |||
| fa3108e6e2 | |||
| 9cf596c67b | |||
| 478a12637d | |||
| 4d977535f2 | |||
| 95613a11ab | |||
| 2cd193f97c | |||
| 33a9d6a3c3 | |||
| fdb863ce70 | |||
| 43fc29873e | |||
| e216a54ead | |||
| 77a96b0ec6 | |||
| d4cdc3a246 | |||
| 5199ede4a2 | |||
| b4b4e247dd | |||
| c50f6c218f | |||
| 5866124138 | |||
| f6bdc6fdb2 | |||
| 8f25baada6 | |||
| aaef1a14b4 | |||
| 22e8f5fd51 | |||
| 88ab787ba6 | |||
| eb9faffadd | |||
| 3b0eee785f | |||
| 5ef542a638 | |||
| ffdaff3740 | |||
| 56d273477e | |||
| a35b9dd9cc | |||
| c69720a1ab | |||
| 56fc0efbc8 | |||
| d3c477646f | |||
| a58de70f06 | |||
| 800965a957 | |||
| fcf672c50e | |||
| b66e369a1d | |||
| 9dd03c873c | |||
| e42bb47ce3 | |||
| dc7fa076d7 | |||
| 960cf495c6 | |||
| 0f12804a49 | |||
| 3c7c71cfa6 | |||
| aac190255b | |||
| 85a08a087b | |||
| 637d9b054b | |||
| 1bfb0ab39c | |||
| 4ef1cdec12 | |||
| 0534678028 | |||
| 70606d7f1a | |||
| bb39ecbc08 | |||
| 54e6e1a5fb | |||
| 5bb7a0b0db | |||
| 330456bcf0 | |||
| 396bd5eb3d | |||
| dd79dea81d | |||
| 976a8c9cc9 | |||
| a095477b4c | |||
| 950aca380c | |||
| 985b0a1933 | |||
| a7841ed486 | |||
| a11e833a98 | |||
| 62ee051c6e | |||
| 5424ead01d | |||
| 96d385bf82 | |||
| 8e2258b16a | |||
| dc4c00a78c | |||
| 1d1250b056 | |||
| f87b46f454 | |||
| 133d2ae6d5 | |||
| 5418b37314 | |||
| 6353a06a5d | |||
| 58b9077b51 | |||
| 10fcfa860a | |||
| 4fc3d511ce | |||
| 032ce9e53c | |||
| 5f2dcc51ce | |||
| 0aa64381ff | |||
| 6c8b037422 | |||
| d63ea000c7 | |||
| 5e148df0a9 | |||
| 4b1c59e199 | |||
| d8f05acb67 | |||
| d6f4c99243 | |||
| c25aa8378f | |||
| 63b6e0d381 | |||
| 911b8188d2 | |||
| 167edacb5f | |||
| 53d47483c8 | |||
| 8c1568ff93 | |||
| 7b5895c90d | |||
| 115cb23bd8 | |||
| 62806607bf | |||
| b25b5c2f98 | |||
| 444c385f23 | |||
| ee8bbccb2a | |||
| 66237abd35 | |||
| 0973a8d6c1 | |||
| fbead19c88 | |||
| baf574d6c4 | |||
| e3c801f1f5 | |||
| f773edcb98 | |||
| 2a73068aac | |||
| 926de60f5d | |||
| 5971eb3da0 | |||
| 04fd5567a7 | |||
| 4f8c132b53 | |||
| a98685e0bb | |||
| df5d673e63 | |||
| 12733bd21b | |||
| f6767ed061 | |||
| de10a7a8ce | |||
| 5081a180fa | |||
| a576f3a6d1 | |||
| 3201f8e513 | |||
| 92003fa4dc | |||
| 818d9c8c42 | |||
| cbe6553baa | |||
| 5d3870faa3 | |||
| 2d8ce266bd | |||
| 0042f18c1f | |||
| 0982a9bc3c | |||
| 50327a0cfc | |||
| 5802062746 | |||
| 69de1780a0 | |||
| 6e8895f9e9 | |||
| e93762a720 | |||
| 268065e5c4 | |||
| d7878ef131 | |||
| 908bedeaa6 | |||
| 504860f065 | |||
| 3a96d72a7f | |||
| d88e4d495f | |||
| 66a4e405e0 | |||
| 0a77b9f43e | |||
| 470669fa6b | |||
| af29fb21df | |||
| be50d57ddd | |||
| 35d19b32f4 | |||
| 654d907dcf | |||
| b013c29c7e | |||
| 0ed23980a6 | |||
| a78862e05e | |||
| bcb44ccb6f | |||
| 736a182544 | |||
| 97bb1250ba | |||
| b0b7ac101c | |||
| 3e35d44b0f | |||
| 6691c59a7a | |||
| 1391d5a304 | |||
| 8f595b58a7 | |||
| 5bdc6c0822 | |||
| 1925b94131 | |||
| ddb043aa71 | |||
| fc794b680a | |||
| a71065fcda | |||
| 7165196211 | |||
| f782955c06 | |||
| 3f13396d73 | |||
| 88365ed507 | |||
| 061d5f2380 | |||
| 2d17a2850c | |||
| cc58ce6301 | |||
| d3c8fb7705 | |||
| 9fe16a29e1 | |||
| 31a3cc7b10 | |||
| a8dc5f80d1 | |||
| 81d9770d4f | |||
| cdb191bb48 | |||
| 633b68db11 | |||
| e890525788 | |||
| 6b8c61b3a2 | |||
| 4849ac9781 | |||
| cd18d3d8a7 | |||
| a0908ba393 | |||
| 02dbe39b06 | |||
| 67a00939db | |||
| 5d7a704ca5 | |||
| cee90a886e | |||
| 6b6d07745d | |||
| 05362b9a7d | |||
| bf2a2f291f | |||
| 8368a0850a | |||
| 01a2c9fe12 | |||
| 6aefd24eb3 | |||
| 3241c2506b | |||
| 48d6ae1def | |||
| f2dc8c0442 | |||
| b174e2c9c6 | |||
| fb17c1b99f | |||
| e790e66f47 | |||
| c64e77a08c | |||
| cf53d834e9 | |||
| a2a4a4970e | |||
| 31fa36003f | |||
| cd1c41e448 | |||
| 54cc49bc70 | |||
| fe662c1a0a | |||
| fddd6110e0 | |||
| 2b63d07329 | |||
| b82b93f8f0 | |||
| 7129aebe76 | |||
| 2bcf822637 | |||
| 6658c0d386 | |||
| 0b93cb7ece | |||
| b51e2aa213 | |||
| d18d99e8ec | |||
| 9b8364b6c8 | |||
| 959419419f | |||
| 2988d84cfb | |||
| c0eb85ce53 | |||
| 56a4bf8f3c | |||
| 9cc332d6b3 | |||
| 120682ec8b | |||
| a67b3dc6a6 | |||
| f4c98f635b | |||
| 069bf6dec6 | |||
| a59bef1afe | |||
| d0f3696596 | |||
| c923bb5c10 | |||
| 9a93acc62a | |||
| 8770fc98e1 | |||
| 18433e289f | |||
| 168712ebbd | |||
| 44ae6bcc83 | |||
| 02790b105e | |||
| d88c08e074 | |||
| 9937cb48fd | |||
| 5444475b1d | |||
| 264a40f217 | |||
| a26f90a346 | |||
| ca9d04ba6b | |||
| 4e86a71ab2 | |||
| 3682888655 | |||
| 3adf720bc1 | |||
| d7a999eaf5 | |||
| 64333f69ea | |||
| b8a7720986 | |||
| 7c9415356d | |||
| c97aade33e | |||
| ab751d290a | |||
| f496d22074 | |||
| 86b680a3ad | |||
| 78dba217bf | |||
| 3b14b35252 | |||
| 878c762cdf | |||
| 920f2678ac | |||
| b6182e6fe8 | |||
| 41fe062a8d | |||
| 4c5f97bb9a | |||
| f9c24ab16d | |||
| 72b536b52d | |||
| 598c79ff86 | |||
| da66eb5714 | |||
| c290b4284f | |||
| fcb978248f | |||
| 5774edfe79 | |||
| 5c23187d2c | |||
| 0a7eb33772 | |||
| 9de075029b | |||
| d110cbb6e2 | |||
| 5f1f126613 | |||
| e40baf0bda | |||
| aa7d5df6a0 | |||
| 177d5fec86 | |||
| 0c0d79fd93 | |||
| 87ae2d7996 | |||
| b1acd1183f | |||
| 265aa54bc2 | |||
| 1e82db5655 | |||
| f2ca4cb3cd | |||
| cf784772c9 | |||
| 0567d528c6 | |||
| 36e3f4bc2a | |||
| 2a6c50832e | |||
| d759875db8 | |||
| 1510ee0b3c | |||
| 3729acc5b0 | |||
| 9fa5f37f74 | |||
| 0ddd2e0ebf | |||
| 7827faae4b | |||
| 245fe04289 | |||
| 6876a37e61 | |||
| 00c613b351 | |||
| 81fe380de2 | |||
| 179e8934cf | |||
| 8bfb6fdd4e | |||
| 89f81c89da | |||
| ad948d33c0 | |||
| 6fa55e7c38 | |||
| 2febbe5ffb | |||
| 578ecad93c | |||
| f5b0cd1793 | |||
| 3a0b4ad8da | |||
| 408f9b515e | |||
| f45dc46856 | |||
| b75780b9cd | |||
| 19614678e9 | |||
| 55ea097bce | |||
| 9d9037856c | |||
| 5087e9c2df | |||
| 178a0a3e1b | |||
| 05ef009552 | |||
| 316da00345 | |||
| f449df161a | |||
| 3e4ed83cb3 | |||
| f5f353d90a | |||
| bfde473c3b | |||
| c93bf732db | |||
| 7bcbea2108 | |||
| 997ac58329 | |||
| 085b61eea5 | |||
| 31fd83b2ae | |||
| 4b4c039fde | |||
| 0b3cf26406 | |||
| 12e01a5119 | |||
| ba6c88cb90 | |||
| e5815553cb | |||
| cba6e1b3ab | |||
| 0f864d9466 | |||
| 117f31125d | |||
| 510fde58d8 | |||
| 191fc1b4e8 | |||
| 41de5e78d0 | |||
| 5b6d042de2 | |||
| e30d41e5f0 | |||
| e1f01f0c8a | |||
| e56c6545fa | |||
| cb0627e6b2 | |||
| 6c0419db2b | |||
| 232cb3dd45 | |||
| 430fc8eb62 | |||
| e469b6ffb4 | |||
| a1068df602 | |||
| f819272b88 | |||
| 9fb188afbc | |||
| 70050b52ad | |||
| 44484fa4ae | |||
| 69b52196bd | |||
| f7cb7ef014 | |||
| b9cd5ca07f | |||
| 6017785e10 | |||
| 186fda098c | |||
| b6e1858ce6 | |||
| 7ab4f32c1a | |||
| 7113f2b8ba | |||
| c526c02d92 | |||
| f3ecba0445 | |||
| 06f42bc749 | |||
| 72da5bd062 | |||
| e56a76299c | |||
| c5af421cee | |||
| 91245141e9 | |||
| 2d67ff2249 | |||
| 0ef6973457 | |||
| 1aeaa794e1 | |||
| b932afb0cd | |||
| 9a142eb807 | |||
| 069d28b1ed | |||
| 301b1b7a7a | |||
| 113ed66f49 | |||
| a90c337297 | |||
| 071c1dcb64 | |||
| c4ed1c2764 | |||
| 4b1bdb563e | |||
| 0822108fc8 | |||
| 02064ae12a | |||
| 782caaa678 | |||
| ee849338dd | |||
| 7e2380ab0c | |||
| b0a950b6dd | |||
| dd11ed82d7 | |||
| bdc278399d | |||
| b71c4c0e52 | |||
| d0a185f2d9 | |||
| 0aa22e5149 | |||
| 8b29af629b | |||
| e5aac80cb4 | |||
| 4e014b4c5c | |||
| cebdb87387 | |||
| 8e41bdc25e | |||
| 28f4131d50 | |||
| f6e2840947 | |||
| c3ef56702a | |||
| 489385d565 | |||
| ce3317da7a | |||
| d6a9ef5bc1 | |||
| ac74b7dca1 | |||
| d81b07bd5f | |||
| 95a8f58314 | |||
| f3594ec881 | |||
| 7a186e242d | |||
| b2e16ffb12 | |||
| ac025ee6f2 | |||
| b1b3aba439 | |||
| 719b4d1183 | |||
| a098d1ec62 | |||
| ac548f2e95 | |||
| 6808865068 | |||
| 7a9fa52e91 | |||
| d523357ba8 | |||
| 933351ab4c | |||
| fadcc85553 | |||
| 7decd58aaa | |||
| c1439ddd5b | |||
| 603ec9cb19 | |||
| 485aae8134 | |||
| 039ac46963 | |||
| 4892b01eb4 | |||
| 03e2b0f0bf | |||
| 0124d292b5 | |||
| b8fbac72ac | |||
| e8c0e21f71 | |||
| a85a953e8e | |||
| c950fc05f0 | |||
| 0db99ccb4b | |||
| 6aab450c16 | |||
| c15d230a57 | |||
| f310d7bb12 | |||
| 67d6ca9f10 | |||
| 5b112c86bf | |||
| 57181c0a76 | |||
| 6314a96b05 | |||
| 4294ba6b52 | |||
| 519f3db6b6 | |||
| e7901f9d70 | |||
| 1030f041e3 | |||
| c76253cb0a | |||
| 33e82de475 | |||
| b475df2250 | |||
| 720741b725 | |||
| bc9f178b6d | |||
| 6cdead166b | |||
| 0542c65a07 | |||
| f4081a363b | |||
| a3ea6e7723 | |||
| 7d68112265 | |||
| ed34b04e9b | |||
| 96a690f607 | |||
| 3c4057ff55 | |||
| ff67860cdb | |||
| 87b5e2500b | |||
| 56df6e7ba8 | |||
| c0b346e0b8 | |||
| 635dfa2eae | |||
| 6ffd5ffd0c | |||
| e11bcf9c43 | |||
| adbd174959 | |||
| 1c34f89c19 | |||
| bbfd089b7e | |||
| 1e679e6f84 | |||
| 61cdee97fc | |||
| 7d767fac7f | |||
| 9426c67302 | |||
| a664d6389e | |||
| 7c159e3881 | |||
| 70bfc5b4a8 | |||
| 940ca9311d | |||
| b2de1d7438 | |||
| 1a2dd3680f | |||
| 68cc1e775c | |||
| a1e8d3c3dc | |||
| ae25fa994c | |||
| 009a5007ff | |||
| cb30f7733d | |||
| eec63dbefe | |||
| 218eeae797 | |||
| 8b2d308498 | |||
| 26a5811744 | |||
| 0d4e1abbd1 | |||
| 5b019ab48c | |||
| f2b5153a8c | |||
| 6fd89f5fe0 | |||
| 0b304731c5 | |||
| 63da351038 | |||
| cad02bb1b0 | |||
| f61c933a7a | |||
| 28f66ddd7c | |||
| a1e45ab56c | |||
| f664e39374 | |||
| e7733ce7d9 | |||
| e1ba499bd6 | |||
| fd885d0818 | |||
| 67c9de6461 | |||
| ca0dd09944 | |||
| b703b4f022 | |||
| f30c9d49f7 | |||
| af5457ba09 | |||
| a31154c035 | |||
| b2a2e0f135 | |||
| 85eb8f022c | |||
| 589bc73838 | |||
| 649d3b753b | |||
| c377708da1 | |||
| 326e8da06d | |||
| 44a9ceac0b | |||
| 5c1168c33f | |||
| dd458c637e | |||
| 2f3f6f8b71 | |||
| 11326692f2 | |||
| 9d144bd495 | |||
| a284722fd0 | |||
| c0a89e328a | |||
| 99fd621aed | |||
| 5183f7724d | |||
| 0c57044c59 | |||
| 5e2c105396 | |||
| 0ce3a3665a | |||
| b0e72ece43 | |||
| 8b5e6e4a13 | |||
| 43bfa0efbc | |||
| ca298c7c39 | |||
| 48d8498dbb | |||
| 19bec62eb5 | |||
| 5e5a8bbdcf | |||
| 7c2ccb2cb7 | |||
| 435e5e6263 | |||
| e564f9ae31 | |||
| 68cf45a8b9 | |||
| 94b23482a9 | |||
| 1e968f5487 | |||
| 14e771d871 | |||
| 56ef607904 | |||
| 17fe272dc5 | |||
| d5d906184f | |||
| 3b2c2b5c04 | |||
| 39cfee239d | |||
| 1f02567507 | |||
| 4f5d54f062 | |||
| fc2b71a04e | |||
| 87b964a7f6 | |||
| 4cf83ca3a7 | |||
| 3d9997288d | |||
| 527472f18c | |||
| d2b8569452 | |||
| 3482ee5c75 | |||
| 3029e84faf | |||
| 044e55b98e | |||
| 60a09285b7 | |||
| ba47fd4649 | |||
| 2de2d00f14 | |||
| 7b8c01da12 | |||
| 9021ba01ac | |||
| b8db0a8ed6 | |||
| 2a68591181 | |||
| 94ac777f93 | |||
| 0ea6c1dcf6 | |||
| 2ce6d49a40 | |||
| c7476875e6 | |||
| 22ee16fd9d | |||
| c68ac1d5eb | |||
| a23c76fb82 | |||
| fd4f5c0996 | |||
| b080b8f54d | |||
| 5a8dea1591 | |||
| a849b384f8 | |||
| fedfe5427c | |||
| 1176e1f096 | |||
| 22c25e4413 | |||
| 557820707b | |||
| 0078a3b904 | |||
| 65d352d5de | |||
| 64997d9961 | |||
| ce42b6be01 | |||
| 7606be93d5 | |||
| e2665c5da9 | |||
| 32d548d99b | |||
| 25ddb6c69d | |||
| 0baaad30b1 | |||
| 31491ebe16 | |||
| b10e10efae | |||
| 02f96d0f41 | |||
| 2129a33077 | |||
| 5cfe57ece5 | |||
| 03667d0c73 | |||
| f2acf57412 | |||
| efccee55e3 | |||
| 6ff81946cf | |||
| 08d482b064 | |||
| dd5389df23 | |||
| e01bece552 | |||
| 3d0d9cb354 | |||
| afc7f5aa37 | |||
| f14a966680 | |||
| 6c564775c4 | |||
| 1e55e018e5 | |||
| 9605e2b2a4 | |||
| a910ab8171 | |||
| 32e5781a6a | |||
| f5290a8e44 | |||
| 5fdd1c39fe | |||
| 769975f6d7 | |||
| 1bda40dac7 | |||
| 5ef60bf594 | |||
| 666608544b | |||
| 3dd2a614ac | |||
| 50682b98d6 | |||
| cf87c5664f | |||
| 247ca872f6 | |||
| e7fe4dc474 | |||
| c6b5dd6c4f | |||
| 309bdfbe28 | |||
| ed679279fd | |||
| fad7612cf1 | |||
| df92d96d4f | |||
| 7ef8dfb4e0 | |||
| 7f653cfe76 | |||
| 5cc8e807df | |||
| d364eab74b | |||
| 404a7c3381 |
+6
-3
@@ -3,7 +3,7 @@ language: erlang
|
||||
otp_release:
|
||||
- 17.5
|
||||
- 18.3
|
||||
- 19.1
|
||||
- 19.2
|
||||
|
||||
services:
|
||||
- riak
|
||||
@@ -21,18 +21,21 @@ before_install:
|
||||
- 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
|
||||
- sudo apt-get -qq -o Dpkg::Options::=--force-confold install mysql-server
|
||||
- sudo mysql_upgrade
|
||||
# /END MYSQL 5.6
|
||||
- pip install --user coveralls-merge
|
||||
|
||||
install:
|
||||
- sudo apt-get -qq install libexpat1-dev libyaml-dev libpam0g-dev libsqlite3-dev
|
||||
- sudo apt-get -qq install libexpat1-dev libyaml-dev libpam0g-dev libsqlite3-dev libgd-dev libwebp-dev
|
||||
|
||||
before_script:
|
||||
# Ulimit: See Travis-CI issue report: https://github.com/travis-ci/travis-ci/issues/3328
|
||||
- echo 'ulimit -n 4096' > riak
|
||||
- sudo mv riak /etc/default/riak
|
||||
- mkdir "$PWD/ebin"
|
||||
- sed 's/^storage_backend.*/storage_backend = leveldb/' /etc/riak/riak.conf > riak.conf
|
||||
- sudo mv riak.conf /etc/riak/riak.conf
|
||||
- echo "[{riak_kv, [{add_paths, [\"$PWD/ebin/\"]}]}]." > advanced.config
|
||||
- sudo mv advanced.config /etc/riak/advanced.config
|
||||
- sudo service riak restart
|
||||
|
||||
+420
-84
@@ -1,5 +1,5 @@
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.9 (SunOS)
|
||||
Version: GnuPG v1.4.5 (GNU/Linux)
|
||||
|
||||
mQGiBD4+owwRBAC14GIfUfCyEDSIePvEW3SAFUdJBtoQHH/nJKZyQT7h9bPlUWC3
|
||||
RODjQReyCITRrdwyrKUGku2FmeVGwn2u2WmDMNABLnpprWPkBdCk96+OmSLN9brZ
|
||||
@@ -10,87 +10,423 @@ 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
|
||||
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
|
||||
AcOphrnJ
|
||||
=443I
|
||||
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
|
||||
XDR51P1TEw9mC1btHj+7m7Iq1a5ke5wIC7ENZiilr0yPqeWgL5+LC98dz/L85hqA
|
||||
wIoGeOfMhrlaVbAZEj4yQTAJDA35vZHVsQmp87il0m+fZX04OBLXBzw86EoAAZ7Q
|
||||
EoH4qFcT9k1T363tvNnIm3mEvkQ5WjE1R9uchJa1g7hdlNQlVkjFmPZrJK9fl4z5
|
||||
6Dto89Po4Sge48jDH0pias4HATYHsxW819nz5jZzGcxLnFRRR5iITVZi9qzsHP7N
|
||||
bUh3qxuWCHS9xziXpOcSZY848xXw63Y5jDJfpzupzu/KHj6CzXYJUEEqp9MluoGb
|
||||
/BCCEPzdZ0ovyxFutM/BRcc6DvE6sTDF/UES21ROqfuwtJ6qJYWX+lBIgyCJvj4o
|
||||
RdbzxUleePuzqCzmwrIXtoOKW0Rlj4SCeF9yCwUMBTGW5/nCLmN4dwf1KW2RP2Eg
|
||||
4ERbuUy7QnwRP5UCl+0ISZJyYUISfg8fmPIdQsetUK9Cj+Q5jpB2GXwELXWnIK6h
|
||||
K/6jXp+EGEXSqdIE53vAFe7LwfHiP/D5M71D2h62sdIOmUm3lm7xMOnM5tKlBiV+
|
||||
4jJSUmriCT62zo710+6iLGqmUUYlEll6Ppvo8yuanXkYRCFJpSSP7VP0bBqIZgQT
|
||||
EQIAJgUCTnc9dgIbIwUJEPPzpwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEIxx
|
||||
jTtQcuH1Ut4AoIKjhdf70899d+7JFq3LD7zeeyI0AJ9Z+YyE1HZSnzYi73brScil
|
||||
bIV6sbQ7TXlTUUwgUGFja2FnZSBzaWduaW5nIGtleSAod3d3Lm15c3FsLmNvbSkg
|
||||
PGJ1aWxkQG15c3FsLmNvbT6IbwQwEQIALwUCTnc9rSgdIGJ1aWxkQG15c3FsLmNv
|
||||
bSB3aWxsIHN0b3Agd29ya2luZyBzb29uAAoJEIxxjTtQcuH1tT0An3EMrSjEkUv2
|
||||
9OX05JkLiVfQr0DPAJwKtL1ycnLPv15pGMvSzav8JyWN3IhlBBMRAgAdBQJHrJS0
|
||||
BQkNMFioBQsHCgMEAxUDAgMWAgECF4AAEgkQjHGNO1By4fUHZUdQRwABAa6SAJ9/
|
||||
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
|
||||
roUTAKClYAhZuX2nUNwH4vlEJQHDqYa5yQ==
|
||||
=HfUN
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
+106
-11
@@ -1,25 +1,120 @@
|
||||
FROM debian:jessie
|
||||
FROM debian:jessie-slim
|
||||
MAINTAINER Rafael Römhild <rafael@roemhild.de>
|
||||
|
||||
ENV XMPP_DOMAIN=localhost \
|
||||
ENV EJABBERD_BRANCH=17.08 \
|
||||
EJABBERD_USER=ejabberd \
|
||||
EJABBERD_HTTPS=true \
|
||||
EJABBERD_STARTTLS=true \
|
||||
EJABBERD_S2S_SSL=true \
|
||||
EJABBERD_HOME=/opt/ejabberd \
|
||||
PATH=/opt/ejabberd/bin:/usr/sbin:/usr/bin:/sbin:/bin \
|
||||
EJABBERD_DEBUG_MODE=false \
|
||||
HOME=$EJABBERD_HOME \
|
||||
PATH=$EJABBERD_HOME/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/sbin \
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
XMPP_DOMAIN=localhost \
|
||||
# Set default locale for the environment
|
||||
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
|
||||
# Add ejabberd user and group
|
||||
RUN groupadd -r $EJABBERD_USER \
|
||||
&& useradd -r -m \
|
||||
-g $EJABBERD_USER \
|
||||
-d $EJABBERD_HOME \
|
||||
$EJABBERD_USER
|
||||
|
||||
# Install packages and perform cleanup
|
||||
RUN set -x \
|
||||
&& buildDeps=' \
|
||||
git-core \
|
||||
build-essential \
|
||||
automake \
|
||||
libssl-dev \
|
||||
zlib1g-dev \
|
||||
libexpat-dev \
|
||||
libyaml-dev \
|
||||
libsqlite3-dev \
|
||||
erlang-src erlang-dev \
|
||||
' \
|
||||
&& requiredAptPackages=' \
|
||||
wget \
|
||||
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 \
|
||||
&& cd /tmp \
|
||||
&& git clone https://github.com/processone/ejabberd.git \
|
||||
--branch $EJABBERD_BRANCH --single-branch --depth=1 \
|
||||
&& cd ejabberd \
|
||||
&& chmod +x ./autogen.sh \
|
||||
&& ./autogen.sh \
|
||||
&& ./configure --enable-user=$EJABBERD_USER \
|
||||
--enable-all \
|
||||
--disable-tools \
|
||||
--disable-pam \
|
||||
&& make debug=$EJABBERD_DEBUG_MODE \
|
||||
&& make install \
|
||||
&& mkdir $EJABBERD_HOME/ssl \
|
||||
&& mkdir $EJABBERD_HOME/conf \
|
||||
&& mkdir $EJABBERD_HOME/backup \
|
||||
&& mkdir $EJABBERD_HOME/upload \
|
||||
&& mkdir $EJABBERD_HOME/database \
|
||||
&& mkdir $EJABBERD_HOME/module_source \
|
||||
&& cd $EJABBERD_HOME \
|
||||
&& rm -rf /tmp/ejabberd \
|
||||
&& rm -rf /usr/local/etc/ejabberd \
|
||||
&& ln -sf $EJABBERD_HOME/conf /usr/local/etc/ejabberd \
|
||||
&& chown -R $EJABBERD_USER: $EJABBERD_HOME \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& apt-get purge -y --auto-remove $buildDeps
|
||||
|
||||
RUN wget -P /usr/local/share/ca-certificates/cacert.org http://www.cacert.org/certs/root.crt http://www.cacert.org/certs/class3.crt; \
|
||||
update-ca-certificates
|
||||
|
||||
# Create logging directories
|
||||
RUN mkdir -p /var/log/ejabberd
|
||||
RUN touch /var/log/ejabberd/crash.log /var/log/ejabberd/error.log /var/log/ejabberd/erlang.log
|
||||
|
||||
# Wrapper for setting config on disk from environment
|
||||
# allows setting things like XMPP domain at runtime
|
||||
ADD ./docker/run.sh /sbin/run
|
||||
|
||||
# Add run scripts
|
||||
ADD ./docker/scripts $EJABBERD_HOME/scripts
|
||||
ADD https://raw.githubusercontent.com/rankenstein/ejabberd-auth-mysql/master/auth_mysql.py $EJABBERD_HOME/scripts/lib/auth_mysql.py
|
||||
RUN chmod a+rx $EJABBERD_HOME/scripts/lib/auth_mysql.py
|
||||
|
||||
# Add config templates
|
||||
ADD ./docker/conf /opt/ejabberd/conf
|
||||
|
||||
# Continue as user
|
||||
USER ejabberd
|
||||
USER $EJABBERD_USER
|
||||
|
||||
# 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"]
|
||||
WORKDIR $EJABBERD_HOME
|
||||
|
||||
VOLUME ["$EJABBERD_HOME/database", "$EJABBERD_HOME/ssl", "$EJABBERD_HOME/backup", "$EJABBERD_HOME/upload"]
|
||||
EXPOSE 4560 5222 5269 5280 5443
|
||||
|
||||
ENTRYPOINT ["/opt/ejabberd/docker/start.sh"]
|
||||
CMD ["start"]
|
||||
ENTRYPOINT ["run"]
|
||||
|
||||
+31
-9
@@ -46,6 +46,15 @@ SODIR = $(PRIVDIR)/lib
|
||||
# /usr/lib/ejabberd/priv/msgs
|
||||
MSGSDIR = $(PRIVDIR)/msgs
|
||||
|
||||
# /usr/lib/ejabberd/priv/css
|
||||
CSSDIR = $(PRIVDIR)/css
|
||||
|
||||
# /usr/lib/ejabberd/priv/img
|
||||
IMGDIR = $(PRIVDIR)/img
|
||||
|
||||
# /usr/lib/ejabberd/priv/js
|
||||
JSDIR = $(PRIVDIR)/js
|
||||
|
||||
# /usr/lib/ejabberd/priv/sql
|
||||
SQLDIR = $(PRIVDIR)/sql
|
||||
|
||||
@@ -84,6 +93,7 @@ deps: deps/.got
|
||||
deps/.got:
|
||||
rm -rf deps/.got
|
||||
rm -rf deps/.built
|
||||
mkdir -p deps
|
||||
$(REBAR) get-deps && :> deps/.got
|
||||
|
||||
deps/.built: deps/.got
|
||||
@@ -102,7 +112,7 @@ xref: all
|
||||
|
||||
|
||||
translations:
|
||||
contrib/extract_translations/prepare-translation.sh -updateall
|
||||
tools/prepare-tr.sh
|
||||
|
||||
edoc:
|
||||
$(ERL) -noinput +B -eval \
|
||||
@@ -123,13 +133,13 @@ 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:=$(sort $(shell $(REBAR) -q list-deps|$(SED) -ne '/ TAG / s/ .*// p; / REV / s/ .*// p; / BRANCH / s/ .*// p'))
|
||||
|
||||
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_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)/COPY* deps/$(DEP)/LICENSE* deps/$(DEP)/lib/*/ebin/*.beam deps/$(DEP)/lib/*/ebin/*.app))
|
||||
DEPS_FILES_FILTERED=$(filter-out %/epam %/eimp %/mac_listener 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_FILES=$(filter-out %/configure.beam,$(call FILES_WILDCARD,ebin/*.beam ebin/*.app priv/msgs/*.msg priv/css/*.css priv/img/*.png priv/js/*.js priv/lib/* include/*.hrl COPYING))
|
||||
MAIN_DIRS=$(sort $(dir $(MAIN_FILES)) priv/bin priv/sql)
|
||||
|
||||
define DEP_VERSION_template
|
||||
@@ -148,14 +158,20 @@ $(foreach file,$(DEPS_FILES_FILTERED) $(MAIN_FILES),$(eval $(call COPY_template,
|
||||
$(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/)
|
||||
$(call TO_DEST,deps/epam/priv/bin/epam): $(LIBDIR)/%: deps/epam/priv/bin/epam $(call TO_DEST,deps/epam/priv/bin/)
|
||||
$(INSTALL) -m 750 $(O_USER) $< $@
|
||||
|
||||
$(call TO_DEST,deps/eimp/priv/bin/eimp): $(LIBDIR)/%: deps/eimp/priv/bin/eimp $(call TO_DEST,deps/eimp/priv/bin/)
|
||||
$(INSTALL) -m 755 $(O_USER) $< $@
|
||||
|
||||
$(call TO_DEST,deps/fs/priv/mac_listener): $(LIBDIR)/%: deps/fs/priv/mac_listener $(call TO_DEST,deps/fs/priv/)
|
||||
$(INSTALL) -m 755 $(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) $< $@
|
||||
$(INSTALL) -m 755 $(O_USER) $< $@
|
||||
|
||||
copy-files-sub2: $(call TO_DEST,$(DEPS_FILES) $(MAIN_FILES) priv/bin/captcha.sh priv/sql/lite.sql)
|
||||
|
||||
@@ -247,8 +263,14 @@ uninstall-binary:
|
||||
rm -fr $(PBINDIR)
|
||||
rm -f $(SODIR)/*.so
|
||||
rm -fr $(SODIR)
|
||||
rm -f $(MSGSDIR)/*.msgs
|
||||
rm -f $(MSGSDIR)/*.msg
|
||||
rm -fr $(MSGSDIR)
|
||||
rm -f $(CSSDIR)/*.css
|
||||
rm -fr $(CSSDIR)
|
||||
rm -f $(IMGDIR)/*.png
|
||||
rm -fr $(IMGDIR)
|
||||
rm -f $(JSDIR)/*.js
|
||||
rm -fr $(JSDIR)
|
||||
rm -f $(SQLDIR)/*.sql
|
||||
rm -fr $(SQLDIR)
|
||||
rm -fr $(PRIVDIR)
|
||||
@@ -295,7 +317,7 @@ dialyzer/erlang.plt:
|
||||
@mkdir -p dialyzer
|
||||
@dialyzer --build_plt --output_plt dialyzer/erlang.plt \
|
||||
-o dialyzer/erlang.log --apps kernel stdlib sasl crypto \
|
||||
public_key ssl mnesia inets odbc tools compiler erts webtool \
|
||||
public_key ssl mnesia inets odbc tools compiler erts \
|
||||
runtime_tools asn1 observer xmerl et gs wx syntax_tools; \
|
||||
status=$$? ; if [ $$status -ne 2 ]; then exit $$status; else exit 0; fi
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ To compile ejabberd you need:
|
||||
- GCC.
|
||||
- Libexpat 1.95 or higher.
|
||||
- Libyaml 0.1.4 or higher.
|
||||
- Erlang/OTP 17.1 or higher.
|
||||
- Erlang/OTP 17.5 or higher.
|
||||
- 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).
|
||||
@@ -116,11 +116,14 @@ To compile ejabberd you need:
|
||||
needed on systems with GNU Libc.
|
||||
- ImageMagick's Convert program. Optional. For CAPTCHA challenges.
|
||||
|
||||
If your system splits packages in libraries and development headers, you must
|
||||
install the development packages also.
|
||||
|
||||
### 1. Compile and install on *nix systems
|
||||
|
||||
To compile ejabberd, execute the following commands. The first one is only
|
||||
necessary if your source tree didn't come with a `configure` script.
|
||||
necessary if your source tree didn't come with a `configure` script (In this
|
||||
case you need autoconf installed).
|
||||
|
||||
./autogen.sh
|
||||
./configure
|
||||
|
||||
+1
-1
@@ -7,4 +7,4 @@ config :ejabberd,
|
||||
|
||||
# Customize Mnesia directory:
|
||||
config :mnesia,
|
||||
dir: 'mnesiadb/'
|
||||
dir: 'database/'
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ defmodule Ejabberd.ConfigFile do
|
||||
|
||||
module :mod_client_state do
|
||||
@opts [
|
||||
drop_chat_states: true,
|
||||
queue_chat_states: true,
|
||||
queue_presence: false]
|
||||
end
|
||||
|
||||
|
||||
+1
-1
@@ -560,7 +560,7 @@ modules:
|
||||
mod_caps: {}
|
||||
mod_carboncopy: {}
|
||||
mod_client_state:
|
||||
drop_chat_states: true
|
||||
queue_chat_states: true
|
||||
queue_presence: false
|
||||
mod_configure: {} # requires mod_adhoc
|
||||
mod_disco: {}
|
||||
|
||||
+51
-6
@@ -3,8 +3,8 @@
|
||||
|
||||
AC_PREREQ(2.53)
|
||||
AC_INIT(ejabberd, m4_esyscmd([echo `git describe --tags 2>/dev/null || echo 0.0` | sed 's/-g.*//;s/-/./' | tr -d '\012']), [ejabberd@process-one.net], [ejabberd])
|
||||
REQUIRE_ERLANG_MIN="6.1 (Erlang/OTP 17.1)"
|
||||
REQUIRE_ERLANG_MAX="9.0.0 (No Max)"
|
||||
REQUIRE_ERLANG_MIN="6.4 (Erlang/OTP 17.5)"
|
||||
REQUIRE_ERLANG_MAX="100.0.0 (No Max)"
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
@@ -66,7 +66,7 @@ if test "x$MAKE" = "x"; then
|
||||
fi
|
||||
|
||||
# Change default prefix
|
||||
AC_PREFIX_DEFAULT(/)
|
||||
AC_PREFIX_DEFAULT(/usr/local)
|
||||
|
||||
AC_ARG_ENABLE(hipe,
|
||||
[AC_HELP_STRING([--enable-hipe], [compile natively with HiPE, not recommended (default: no)])],
|
||||
@@ -84,6 +84,14 @@ 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(new_sql_schema,
|
||||
[AC_HELP_STRING([--enable-new-sql-schema], [use new SQL schema (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) new_sql_schema=true ;;
|
||||
no) new_sql_schema=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-new-sql-schema) ;;
|
||||
esac],[new_sql_schema=false])
|
||||
|
||||
AC_ARG_ENABLE(full_xml,
|
||||
[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
|
||||
[case "${enableval}" in
|
||||
@@ -101,10 +109,10 @@ AC_ARG_ENABLE(mssql,
|
||||
esac],[db_type=generic])
|
||||
|
||||
AC_ARG_ENABLE(all,
|
||||
[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)])],
|
||||
[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-stun --enable-sip --enable-debug --enable-tools (useful for Dialyzer checks, default: no)])],
|
||||
[case "${enableval}" in
|
||||
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 ;;
|
||||
yes) odbc=true mysql=true pgsql=true sqlite=true pam=true zlib=true riak=true redis=true elixir=true iconv=true stun=true sip=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 stun=false sip=false debug=false tools=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
|
||||
esac],[])
|
||||
|
||||
@@ -212,6 +220,38 @@ AC_ARG_ENABLE(latest_deps,
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-latest-deps) ;;
|
||||
esac],[if test "x$latest_deps" = "x"; then latest_deps=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(system_deps,
|
||||
[AC_HELP_STRING([--enable-system-deps], [makes rebar use localy installed dependences instead of downloading them (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) system_deps=true ;;
|
||||
no) system_deps=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-system-deps) ;;
|
||||
esac],[if test "x$system_deps" = "x"; then system_deps=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(stun,
|
||||
[AC_HELP_STRING([--enable-stun], [enable STUN/TURN support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) stun=true ;;
|
||||
no) stun=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-stun) ;;
|
||||
esac],[if test "x$stun" = "x"; then stun=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(sip,
|
||||
[AC_HELP_STRING([--enable-sip], [enable SIP support (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) sip=true ;;
|
||||
no) sip=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-sip) ;;
|
||||
esac],[if test "x$sip" = "x"; then sip=false; fi])
|
||||
|
||||
AC_ARG_ENABLE(graphics,
|
||||
[AC_HELP_STRING([--enable-graphics], [enable support for graphic images manipulation (default: yes)])],
|
||||
[case "${enableval}" in
|
||||
yes) graphics=true ;;
|
||||
no) graphics=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-graphics) ;;
|
||||
esac],[if test "x$graphics" = "x"; then graphics=true; fi])
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
vars.config
|
||||
src/ejabberd.app.src])
|
||||
@@ -241,6 +281,7 @@ fi
|
||||
|
||||
AC_SUBST(hipe)
|
||||
AC_SUBST(roster_gateway_workaround)
|
||||
AC_SUBST(new_sql_schema)
|
||||
AC_SUBST(full_xml)
|
||||
AC_SUBST(db_type)
|
||||
AC_SUBST(odbc)
|
||||
@@ -253,9 +294,13 @@ AC_SUBST(riak)
|
||||
AC_SUBST(redis)
|
||||
AC_SUBST(elixir)
|
||||
AC_SUBST(iconv)
|
||||
AC_SUBST(stun)
|
||||
AC_SUBST(sip)
|
||||
AC_SUBST(debug)
|
||||
AC_SUBST(graphics)
|
||||
AC_SUBST(tools)
|
||||
AC_SUBST(latest_deps)
|
||||
AC_SUBST(system_deps)
|
||||
AC_SUBST(CFLAGS)
|
||||
AC_SUBST(CPPFLAGS)
|
||||
AC_SUBST(LDFLAGS)
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
extract_translations - auxiliary tool that extracts lines to be translated
|
||||
from ejabberd source tree.
|
||||
|
||||
Building:
|
||||
erlc extract_translations.erl
|
||||
|
||||
Invoking 1:
|
||||
erl -noinput -s extract_translations -extra dirname message_file
|
||||
|
||||
where dirname is the directory "src" in ejabberd's source tree root,
|
||||
message_file is a file with translated messages (src/msgs/*.msg).
|
||||
|
||||
Result is a list of messages from source files which aren't contained in
|
||||
message file.
|
||||
|
||||
Invoking 2:
|
||||
erl -noinput -s extract_translations -extra -unused dirname message_file
|
||||
|
||||
Result is a list of messages from message file which aren't in source
|
||||
files anymore.
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : extract_translations.erl
|
||||
%%% Author : Sergei Golovan <sgolovan@nes.ru>
|
||||
%%% Purpose : Auxiliary tool for interface/messages translators
|
||||
%%% Created : 23 Apr 2005 by Sergei Golovan <sgolovan@nes.ru>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(extract_translations).
|
||||
-author('sgolovan@nes.ru').
|
||||
|
||||
-export([start/0]).
|
||||
|
||||
-define(STATUS_SUCCESS, 0).
|
||||
-define(STATUS_ERROR, 1).
|
||||
-define(STATUS_USAGE, 2).
|
||||
|
||||
-include_lib("kernel/include/file.hrl").
|
||||
|
||||
|
||||
start() ->
|
||||
ets:new(translations, [named_table, public]),
|
||||
ets:new(translations_obsolete, [named_table, public]),
|
||||
ets:new(files, [named_table, public]),
|
||||
ets:new(vars, [named_table, public]),
|
||||
case init:get_plain_arguments() of
|
||||
["-srcmsg2po", Dir, File] ->
|
||||
print_po_header(File),
|
||||
Status = process(Dir, File, srcmsg2po),
|
||||
halt(Status);
|
||||
["-unused", Dir, File] ->
|
||||
Status = process(Dir, File, unused),
|
||||
halt(Status);
|
||||
[Dir, File] ->
|
||||
Status = process(Dir, File, used),
|
||||
halt(Status);
|
||||
_ ->
|
||||
print_usage(),
|
||||
halt(?STATUS_USAGE)
|
||||
end.
|
||||
|
||||
|
||||
process(Dir, File, Used) ->
|
||||
case load_file(File) of
|
||||
{error, Reason} ->
|
||||
io:format("~s: ~s~n", [File, file:format_error(Reason)]),
|
||||
?STATUS_ERROR;
|
||||
_ ->
|
||||
FileList = find_src_files(Dir),
|
||||
lists:foreach(
|
||||
fun(F) ->
|
||||
parse_file(Dir, F, Used)
|
||||
end, FileList),
|
||||
case Used of
|
||||
unused ->
|
||||
ets:foldl(fun({Key, _}, _) ->
|
||||
io:format("~p~n", [Key])
|
||||
end, ok, translations);
|
||||
srcmsg2po ->
|
||||
ets:foldl(fun({Key, Trans}, _) ->
|
||||
print_translation_obsolete(Key, Trans)
|
||||
end, ok, translations_obsolete);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
?STATUS_SUCCESS
|
||||
end.
|
||||
|
||||
parse_file(Dir, File, Used) ->
|
||||
ets:delete_all_objects(vars),
|
||||
case epp:parse_file(File, [Dir, filename:dirname(File) | code:get_path()], []) of
|
||||
{ok, Forms} ->
|
||||
lists:foreach(
|
||||
fun(F) ->
|
||||
parse_form(Dir, File, F, Used)
|
||||
end, Forms);
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
parse_form(Dir, File, Form, Used) ->
|
||||
case Form of
|
||||
%%{undefined, Something} ->
|
||||
%% io:format("Undefined: ~p~n", [Something]);
|
||||
{call,
|
||||
_,
|
||||
{remote, _, {atom, _, translate}, {atom, _, translate}},
|
||||
[_, {string, Line, Str}]
|
||||
} ->
|
||||
process_string(Dir, File, Line, Str, Used);
|
||||
{call,
|
||||
_,
|
||||
{remote, _, {atom, _, translate}, {atom, _, translate}},
|
||||
[_,
|
||||
{bin,_,
|
||||
[{bin_element,_,
|
||||
{string,Line,Str},
|
||||
default,default}]}]
|
||||
} ->
|
||||
process_string(Dir, File, Line, Str, Used);
|
||||
{call,
|
||||
_,
|
||||
{remote, _, {atom, _, translate}, {atom, _, translate}},
|
||||
[_, {var, _, Name}]
|
||||
} ->
|
||||
case ets:lookup(vars, Name) of
|
||||
[{_Name, Value, Line}] ->
|
||||
process_string(Dir, File, Line, Value, Used);
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
{match,
|
||||
_,
|
||||
{var, _, Name},
|
||||
{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) ->
|
||||
parse_form(Dir, File, F, Used)
|
||||
end, L);
|
||||
T when is_tuple(T) ->
|
||||
lists:foreach(
|
||||
fun(F) ->
|
||||
parse_form(Dir, File, F, Used)
|
||||
end, tuple_to_list(T));
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
process_string(_Dir, _File, _Line, "", _Used) ->
|
||||
ok;
|
||||
|
||||
process_string(_Dir, File, Line, Str, Used) ->
|
||||
case {ets:lookup(translations, Str), Used} of
|
||||
{[{_Key, _Trans}], unused} ->
|
||||
ets:delete(translations, Str);
|
||||
{[{_Key, _Trans}], used} ->
|
||||
ok;
|
||||
{[{_Key, Trans}], srcmsg2po} ->
|
||||
ets:delete(translations_obsolete, Str),
|
||||
print_translation(File, Line, Str, Trans);
|
||||
{_, used} ->
|
||||
case ets:lookup(files, File) of
|
||||
[{_}] ->
|
||||
ok;
|
||||
_ ->
|
||||
io:format("~n% ~s~n", [File]),
|
||||
ets:insert(files, {File})
|
||||
end,
|
||||
case Str of
|
||||
[] -> ok;
|
||||
_ -> io:format("{~p, \"\"}.~n", [Str])
|
||||
end,
|
||||
ets:insert(translations, {Str, ""});
|
||||
{_, srcmsg2po} ->
|
||||
case ets:lookup(files, File) of
|
||||
[{_}] ->
|
||||
ok;
|
||||
_ ->
|
||||
ets:insert(files, {File})
|
||||
end,
|
||||
ets:insert(translations, {Str, ""}),
|
||||
print_translation(File, Line, Str, "");
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
load_file(File) ->
|
||||
case file:consult(File) of
|
||||
{ok, Terms} ->
|
||||
lists:foreach(
|
||||
fun({Orig, Trans}) ->
|
||||
case Trans of
|
||||
"" ->
|
||||
ok;
|
||||
_ ->
|
||||
ets:insert(translations, {Orig, Trans}),
|
||||
ets:insert(translations_obsolete, {Orig, Trans})
|
||||
end
|
||||
end, Terms);
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
find_src_files(Dir) ->
|
||||
case file:list_dir(Dir) of
|
||||
{ok, FileList} ->
|
||||
recurse_filelist(
|
||||
lists:map(
|
||||
fun(F) ->
|
||||
filename:join(Dir, F)
|
||||
end, FileList));
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
recurse_filelist(FileList) ->
|
||||
recurse_filelist(FileList, []).
|
||||
|
||||
recurse_filelist([], Acc) ->
|
||||
lists:reverse(Acc);
|
||||
|
||||
recurse_filelist([H | T], Acc) ->
|
||||
case file:read_file_info(H) of
|
||||
{ok, #file_info{type = directory}} ->
|
||||
recurse_filelist(T, lists:reverse(find_src_files(H)) ++ Acc);
|
||||
{ok, #file_info{type = regular}} ->
|
||||
case string:substr(H, string:len(H) - 3) of
|
||||
".erl" ->
|
||||
recurse_filelist(T, [H | Acc]);
|
||||
".hrl" ->
|
||||
recurse_filelist(T, [H | Acc]);
|
||||
_ ->
|
||||
recurse_filelist(T, Acc)
|
||||
end;
|
||||
_ ->
|
||||
recurse_filelist(T, Acc)
|
||||
end.
|
||||
|
||||
|
||||
print_usage() ->
|
||||
io:format(
|
||||
"Usage: extract_translations [-unused] dir file~n"
|
||||
"~n"
|
||||
"Example:~n"
|
||||
" extract_translations . ./msgs/ru.msg~n"
|
||||
).
|
||||
|
||||
|
||||
%%%
|
||||
%%% Gettext
|
||||
%%%
|
||||
|
||||
print_po_header(File) ->
|
||||
MsgProps = get_msg_header_props(File),
|
||||
{Language, [LastT | AddT]} = prepare_props(MsgProps),
|
||||
print_po_header(Language, LastT, AddT).
|
||||
|
||||
get_msg_header_props(File) ->
|
||||
{ok, F} = file:open(File, [read]),
|
||||
Lines = get_msg_header_props(F, []),
|
||||
file:close(F),
|
||||
Lines.
|
||||
|
||||
get_msg_header_props(F, Lines) ->
|
||||
String = io:get_line(F, ""),
|
||||
case io_lib:fread("% ", String) of
|
||||
{ok, [], RemString} ->
|
||||
case io_lib:fread("~s", RemString) of
|
||||
{ok, [Key], Value} when Value /= "\n" ->
|
||||
%% The first character in Value is a blankspace:
|
||||
%% And the last characters are 'slash n'
|
||||
ValueClean = string:substr(Value, 2, string:len(Value)-2),
|
||||
get_msg_header_props(F, Lines ++ [{Key, ValueClean}]);
|
||||
_ ->
|
||||
get_msg_header_props(F, Lines)
|
||||
end;
|
||||
_ ->
|
||||
Lines
|
||||
end.
|
||||
|
||||
prepare_props(MsgProps) ->
|
||||
Language = proplists:get_value("Language:", MsgProps),
|
||||
Authors = proplists:get_all_values("Author:", MsgProps),
|
||||
{Language, Authors}.
|
||||
|
||||
print_po_header(Language, LastTranslator, AdditionalTranslatorsList) ->
|
||||
AdditionalTranslatorsString = build_additional_translators(AdditionalTranslatorsList),
|
||||
HeaderString =
|
||||
"msgid \"\"\n"
|
||||
"msgstr \"\"\n"
|
||||
++ "\"X-Language: " ++ Language ++ "\\n\"\n"
|
||||
"\"Last-Translator: " ++ LastTranslator ++ "\\n\"\n"
|
||||
++ AdditionalTranslatorsString ++
|
||||
"\"MIME-Version: 1.0\\n\"\n"
|
||||
"\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
|
||||
"\"Content-Transfer-Encoding: 8bit\\n\"\n",
|
||||
io:format("~s~n", [HeaderString]).
|
||||
|
||||
build_additional_translators(List) ->
|
||||
lists:foldl(
|
||||
fun(T, Str) ->
|
||||
Str ++ "\"X-Additional-Translator: " ++ T ++ "\\n\"\n"
|
||||
end,
|
||||
"",
|
||||
List).
|
||||
|
||||
print_translation(File, Line, Str, StrT) ->
|
||||
StrQ = ejabberd_regexp:greplace(list_to_binary(Str), <<"\\\"">>, <<"\\\\\"">>),
|
||||
StrTQ = ejabberd_regexp:greplace(list_to_binary(StrT), <<"\\\"">>, <<"\\\\\"">>),
|
||||
io:format("#: ~s:~p~nmsgid \"~s\"~nmsgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
|
||||
|
||||
print_translation_obsolete(Str, StrT) ->
|
||||
File = "unknown.erl",
|
||||
Line = 1,
|
||||
StrQ = ejabberd_regexp:greplace(Str, "\\\"", "\\\\\""),
|
||||
StrTQ = ejabberd_regexp:greplace(StrT, "\\\"", "\\\\\""),
|
||||
io:format("#: ~s:~p~n#~~ msgid \"~s\"~n#~~ msgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
|
||||
|
||||
@@ -1,366 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Frontend for ejabberd's extract_translations.erl
|
||||
# by Badlop
|
||||
|
||||
# How to create template files for a new language:
|
||||
# NEWLANG=zh
|
||||
# cp msgs/ejabberd.pot msgs/$NEWLANG.po
|
||||
# echo \{\"\",\"\"\}. > msgs/$NEWLANG.msg
|
||||
# ../../extract_translations/prepare-translation.sh -updateall
|
||||
|
||||
prepare_dirs ()
|
||||
{
|
||||
# Where is Erlang binary
|
||||
ERL=`which erl`
|
||||
|
||||
EJA_SRC_DIR=$EJA_DIR/src/
|
||||
EJA_MSGS_DIR=$EJA_DIR/priv/msgs/
|
||||
EXTRACT_DIR=$EJA_DIR/contrib/extract_translations/
|
||||
EXTRACT_ERL=$EXTRACT_DIR/extract_translations.erl
|
||||
EXTRACT_BEAM=$EXTRACT_DIR/extract_translations.beam
|
||||
|
||||
SRC_DIR=$RUN_DIR/src
|
||||
EBIN_DIR=$RUN_DIR/ebin
|
||||
MSGS_DIR=$EJA_DIR/priv/msgs
|
||||
|
||||
if !([[ -n $EJA_DIR ]])
|
||||
then
|
||||
echo "ejabberd dir does not exist: $EJA_DIR"
|
||||
fi
|
||||
|
||||
if !([[ -x $EXTRACT_BEAM ]])
|
||||
then
|
||||
sh -c "cd $EXTRACT_DIR; $ERL -compile $EXTRACT_ERL"
|
||||
fi
|
||||
}
|
||||
|
||||
extract_lang ()
|
||||
{
|
||||
MSGS_FILE=$1
|
||||
MSGS_FILE2=$MSGS_FILE.translate
|
||||
MSGS_PATH=$MSGS_DIR/$MSGS_FILE
|
||||
MSGS_PATH2=$MSGS_DIR/$MSGS_FILE2
|
||||
|
||||
echo -n "Extracting language strings for '$MSGS_FILE':"
|
||||
|
||||
echo -n " new..."
|
||||
cd $SRC_DIR
|
||||
$ERL -pa $EXTRACT_DIR -noinput -noshell -s extract_translations -s init stop -extra . $MSGS_PATH >$MSGS_PATH.new
|
||||
sed -e 's/^% \.\//% /g;' $MSGS_PATH.new > $MSGS_PATH.new2
|
||||
mv $MSGS_PATH.new2 $MSGS_PATH.new
|
||||
|
||||
echo -n " old..."
|
||||
$ERL -pa $EXTRACT_DIR -noinput -noshell -s extract_translations -s init stop -extra -unused . $MSGS_PATH >$MSGS_PATH.unused
|
||||
find_unused_full $MSGS_FILE $MSGS_FILE.unused
|
||||
|
||||
echo "" >$MSGS_PATH2
|
||||
echo " ***** Translation file for ejabberd ***** " >>$MSGS_PATH2
|
||||
echo "" >>$MSGS_PATH2
|
||||
|
||||
echo "" >>$MSGS_PATH2
|
||||
echo " *** New strings: Can you please translate them? *** " >>$MSGS_PATH2
|
||||
cat $MSGS_PATH.new >>$MSGS_PATH2
|
||||
|
||||
echo "" >>$MSGS_PATH2
|
||||
echo "" >>$MSGS_PATH2
|
||||
echo " *** Unused strings: They will be removed automatically *** " >>$MSGS_PATH2
|
||||
cat $MSGS_PATH.unused.full >>$MSGS_PATH2
|
||||
|
||||
echo "" >>$MSGS_PATH2
|
||||
echo "" >>$MSGS_PATH2
|
||||
echo " *** Already translated strings: you can also modify any of them if you want *** " >>$MSGS_PATH2
|
||||
echo "" >>$MSGS_PATH2
|
||||
cat $MSGS_PATH.old_cleaned >>$MSGS_PATH2
|
||||
|
||||
echo " ok"
|
||||
|
||||
rm $MSGS_PATH.new
|
||||
rm $MSGS_PATH.old_cleaned
|
||||
rm $MSGS_PATH.unused.full
|
||||
}
|
||||
|
||||
extract_lang_all ()
|
||||
{
|
||||
cd $MSGS_DIR
|
||||
for i in $( ls *.msg ) ; do
|
||||
extract_lang $i;
|
||||
done
|
||||
|
||||
echo -e "File\tMissing\tLanguage\t\tLast translator"
|
||||
echo -e "----\t-------\t--------\t\t---------------"
|
||||
cd $MSGS_DIR
|
||||
for i in $( ls *.msg ) ; do
|
||||
MISSING=`cat $i.translate | grep "\", \"\"}." | wc -l`
|
||||
LANGUAGE=`grep "X-Language:" $i.translate | sed 's/% Language: //g'`
|
||||
LASTAUTH=`grep "Author:" $i.translate | head -n 1 | sed 's/% Author: //g'`
|
||||
echo -e "$i\t$MISSING\t$LANGUAGE\t$LASTAUTH"
|
||||
done
|
||||
|
||||
cd $MSGS_DIR
|
||||
REVISION=`git describe --always`
|
||||
zip $HOME/ejabberd-langs-$REVISION.zip *.translate;
|
||||
|
||||
rm *.translate
|
||||
}
|
||||
|
||||
find_unused_full ()
|
||||
{
|
||||
DATFILE=$1
|
||||
DATFILEI=$1.old_cleaned
|
||||
DELFILE=$2
|
||||
cd msgs
|
||||
|
||||
DATFILE1=$DATFILE.t1
|
||||
DATFILE2=$DATFILE.t2
|
||||
|
||||
DELFILE1=$DELFILE.t1
|
||||
DELFILE2=$DELFILE.t2
|
||||
DELFILEF=$DATFILE.unused.full
|
||||
echo "" >$DELFILEF
|
||||
|
||||
grep -v "\\\\" $DELFILE >$DELFILE2
|
||||
echo ENDFILEMARK >>$DELFILE2
|
||||
cp $DATFILE $DATFILEI
|
||||
cp $DATFILE $DATFILE2
|
||||
|
||||
cp $DELFILE2 $DELFILE1
|
||||
STRING=`head -1 $DELFILE1`
|
||||
until [[ $STRING == ENDFILEMARK ]]; do
|
||||
cp $DELFILE2 $DELFILE1
|
||||
cp $DATFILE2 $DATFILE1
|
||||
|
||||
STRING=`head -1 $DELFILE1`
|
||||
|
||||
cat $DATFILE1 | grep "$STRING" >>$DELFILEF
|
||||
cat $DATFILE1 | grep -v "$STRING" >$DATFILE2
|
||||
cat $DELFILE1 | grep -v "$STRING" >$DELFILE2
|
||||
done
|
||||
|
||||
mv $DATFILE2 $DATFILEI
|
||||
|
||||
rm -f $MSGS_PATH.t1
|
||||
rm $MSGS_PATH.unused
|
||||
rm -f $MSGS_PATH.unused.t1
|
||||
rm $MSGS_PATH.unused.t2
|
||||
|
||||
cd ..
|
||||
}
|
||||
|
||||
extract_lang_srcmsg2po ()
|
||||
{
|
||||
LANG=$1
|
||||
LANG_CODE=$LANG.$PROJECT
|
||||
MSGS_PATH=$MSGS_DIR/$LANG_CODE.msg
|
||||
PO_PATH=$MSGS_DIR/$LANG_CODE.po
|
||||
|
||||
echo $MSGS_PATH
|
||||
|
||||
cd $SRC_DIR
|
||||
$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
|
||||
|
||||
rm $PO_PATH.*
|
||||
}
|
||||
|
||||
extract_lang_src2pot ()
|
||||
{
|
||||
LANG_CODE=$PROJECT
|
||||
MSGS_PATH=$MSGS_DIR/$LANG_CODE.msg
|
||||
POT_PATH=$MSGS_DIR/$LANG_CODE.pot
|
||||
|
||||
echo -n "" >$MSGS_PATH
|
||||
echo "% Language: Language Name" >>$MSGS_PATH
|
||||
echo "% Author: Translator name and contact method" >>$MSGS_PATH
|
||||
echo "" >>$MSGS_PATH
|
||||
|
||||
cd $SRC_DIR
|
||||
$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
|
||||
msguniq --sort-by-file $POT_PATH.2 --output-file=$POT_PATH
|
||||
|
||||
rm $POT_PATH.*
|
||||
rm $MSGS_PATH
|
||||
|
||||
# If the project is a specific module, not the main ejabberd
|
||||
if [[ $PROJECT != ejabberd ]] ; then
|
||||
# Remove from project.pot the strings that are already present in the general ejabberd
|
||||
EJABBERD_MSG_FILE=$EJA_MSGS_DIR/es.po # This is just some file with translated strings
|
||||
POT_PATH_TEMP=$POT_PATH.temp
|
||||
msgattrib --set-obsolete --only-file=$EJABBERD_MSG_FILE -o $POT_PATH_TEMP $POT_PATH
|
||||
mv $POT_PATH_TEMP $POT_PATH
|
||||
fi
|
||||
}
|
||||
|
||||
extract_lang_popot2po ()
|
||||
{
|
||||
LANG_CODE=$1
|
||||
PO_PATH=$MSGS_DIR/$LANG_CODE.po
|
||||
POT_PATH=$MSGS_DIR/$PROJECT.pot
|
||||
|
||||
msgmerge $PO_PATH $POT_PATH >$PO_PATH.translate 2>/dev/null
|
||||
mv $PO_PATH.translate $PO_PATH
|
||||
}
|
||||
|
||||
extract_lang_po2msg ()
|
||||
{
|
||||
LANG_CODE=$1
|
||||
PO_PATH=$LANG_CODE.po
|
||||
MS_PATH=$PO_PATH.ms
|
||||
MSGID_PATH=$PO_PATH.msgid
|
||||
MSGSTR_PATH=$PO_PATH.msgstr
|
||||
MSGS_PATH=$LANG_CODE.msg
|
||||
|
||||
cd $MSGS_DIR
|
||||
|
||||
# Check PO has correct ~
|
||||
# Let's convert to C format so we can use msgfmt
|
||||
PO_TEMP=$LANG_CODE.po.temp
|
||||
cat $PO_PATH | sed 's/%/perc/g' | sed 's/~/%/g' | sed 's/#:.*/#, c-format/g' >$PO_TEMP
|
||||
msgfmt $PO_TEMP --check-format
|
||||
result=$?
|
||||
rm $PO_TEMP
|
||||
if [ $result -ne 0 ] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
msgattrib $PO_PATH --translated --no-fuzzy --no-obsolete --no-location --no-wrap | grep "^msg" | tail --lines=+3 >$MS_PATH
|
||||
grep "^msgid" $PO_PATH.ms | sed 's/^msgid //g' >$MSGID_PATH
|
||||
grep "^msgstr" $PO_PATH.ms | sed 's/^msgstr //g' >$MSGSTR_PATH
|
||||
echo "%% -*- coding: latin-1 -*-" >$MSGS_PATH
|
||||
paste $MSGID_PATH $MSGSTR_PATH --delimiter=, | awk '{print "{" $0 "}."}' | sort -g >>$MSGS_PATH
|
||||
|
||||
rm $MS_PATH
|
||||
rm $MSGID_PATH
|
||||
rm $MSGSTR_PATH
|
||||
}
|
||||
|
||||
extract_lang_updateall ()
|
||||
{
|
||||
echo "Generating POT"
|
||||
extract_lang_src2pot
|
||||
|
||||
cd $MSGS_DIR
|
||||
echo ""
|
||||
echo -e "File Missing Language Last translator"
|
||||
echo -e "---- ------- -------- ---------------"
|
||||
for i in $( ls *.msg ) ; do
|
||||
LANG_CODE=${i%.msg}
|
||||
echo -n $LANG_CODE | awk '{printf "%-6s", $1 }'
|
||||
|
||||
# Convert old MSG file to PO
|
||||
PO=$LANG_CODE.po
|
||||
[ -f $PO ] || extract_lang_srcmsg2po $LANG_CODE
|
||||
|
||||
extract_lang_popot2po $LANG_CODE
|
||||
extract_lang_po2msg $LANG_CODE
|
||||
|
||||
MISSING=`msgfmt --statistics $PO 2>&1 | awk '{printf "%5s", $4 }'`
|
||||
echo -n " $MISSING"
|
||||
|
||||
LANGUAGE=`grep "X-Language:" $PO | sed 's/\"X-Language: //g' | sed 's/\\\\n\"//g' | awk '{printf "%-12s", $1}'`
|
||||
echo -n " $LANGUAGE"
|
||||
|
||||
LASTAUTH=`grep "Last-Translator" $PO | sed 's/\"Last-Translator: //g' | sed 's/\\\\n\"//g'`
|
||||
echo " $LASTAUTH"
|
||||
done
|
||||
echo ""
|
||||
rm messages.mo
|
||||
|
||||
cd ..
|
||||
}
|
||||
|
||||
translation_instructions ()
|
||||
{
|
||||
echo ""
|
||||
echo " A new file has been created for you, with the current, the new and the deprecated strings:"
|
||||
echo " $MSGS_PATH2"
|
||||
echo ""
|
||||
echo " At the end of that file you will find the strings you must update:"
|
||||
echo " - Untranslated strings are like this: {"March", ""}."
|
||||
echo " To translate the string, add the text inside the commas. Example:"
|
||||
echo " {"March", "Marzo"}."
|
||||
echo " - Old strings that are not used: "Woowoa""
|
||||
echo " Search the entire file for those strings and remove them"
|
||||
echo ""
|
||||
echo " Once you have translated all the strings and removed all the old ones,"
|
||||
echo " rename the file to overwrite the previous one:"
|
||||
echo " $MSGS_PATH"
|
||||
}
|
||||
|
||||
EJA_DIR=`pwd`
|
||||
RUN_DIR=`pwd`
|
||||
PROJECT=ejabberd
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
PARAM=$1
|
||||
shift
|
||||
case $PARAM in
|
||||
--) break ;;
|
||||
-project)
|
||||
PROJECT=$1
|
||||
shift
|
||||
;;
|
||||
-ejadir)
|
||||
EJA_DIR=$1
|
||||
shift
|
||||
;;
|
||||
-rundir)
|
||||
RUN_DIR=$1
|
||||
shift
|
||||
;;
|
||||
-lang)
|
||||
LANGU=$1
|
||||
prepare_dirs
|
||||
extract_lang $LANGU
|
||||
shift
|
||||
;;
|
||||
-langall)
|
||||
prepare_dirs
|
||||
extract_lang_all
|
||||
;;
|
||||
-srcmsg2po)
|
||||
LANG_CODE=$1
|
||||
prepare_dirs
|
||||
extract_lang_srcmsg2po $LANG_CODE
|
||||
shift
|
||||
;;
|
||||
-popot2po)
|
||||
LANG_CODE=$1
|
||||
prepare_dirs
|
||||
extract_lang_popot2po $LANG_CODE
|
||||
shift
|
||||
;;
|
||||
-src2pot)
|
||||
prepare_dirs
|
||||
extract_lang_src2pot
|
||||
;;
|
||||
-po2msg)
|
||||
LANG_CODE=$1
|
||||
prepare_dirs
|
||||
extract_lang_po2msg $LANG_CODE
|
||||
shift
|
||||
;;
|
||||
-updateall)
|
||||
prepare_dirs
|
||||
extract_lang_updateall
|
||||
;;
|
||||
*)
|
||||
echo "Options:"
|
||||
echo " -langall"
|
||||
echo " -lang LANGUAGE_FILE"
|
||||
echo " -srcmsg2po LANGUAGE Construct .msg file using source code to PO file"
|
||||
echo " -src2pot Generate template POT file from source code"
|
||||
echo " -popot2po LANGUAGE Update PO file with template POT file"
|
||||
echo " -po2msg LANGUAGE Export PO file to MSG file"
|
||||
echo " -updateall Generate POT and update all PO"
|
||||
echo ""
|
||||
echo "Example:"
|
||||
echo " ./prepare-translation.sh -lang es.msg"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
+84
-42
@@ -1,21 +1,23 @@
|
||||
ejabberd container
|
||||
|
||||
- [Introduction](#introduction)
|
||||
- [Version](#version)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Usage](#usage)
|
||||
- [Persistence](#persistence)
|
||||
- [SSL Certificates](#ssl-certificates)
|
||||
- [Base Image](#base-image)
|
||||
- [Ejabberd Configuration](#ejabberd-configuration)
|
||||
- [Cluster Example](#cluster-example)
|
||||
- [Runtime Configuration](#runtime-configuration)
|
||||
- [Served Hostnames](#served-hostnames)
|
||||
- [Authentication](#authentication)
|
||||
- [Admins](#admins)
|
||||
- [Users](#users)
|
||||
- [SSL](#ssl)
|
||||
- [Erlang](#erlang)
|
||||
- [Modules](#modules)
|
||||
- [Logging](#logging)
|
||||
- [Mount Configurations](#mount-configurations)
|
||||
- [Erlang Configuration](#erlang-configuration)
|
||||
- [Maintenance](#maintenance)
|
||||
- [Register Users](#register-users)
|
||||
- [Creating Backups](#creating-backups)
|
||||
@@ -28,11 +30,29 @@ ejabberd container
|
||||
|
||||
# Introduction
|
||||
|
||||
Dockerfile to build an [ejabberd](https://www.ejabberd.im/) container image.
|
||||
This [ejabberd][] docker container is based on the work done by [rroemhild][]. See more [in this blogpost][].
|
||||
This container includes the necessary files to build your own containerized ejabberd,
|
||||
but *IT IS NOT* used to generate official images on the docker [hub][].
|
||||
This container is not maintained by [ProcessOne][].
|
||||
|
||||
Docker Tag Names are based on ejabberd versions in git [tags][]. The image tag `:latest` is based on the master branch.
|
||||
[ProcessOne][] provides and maintain official containers on the docker [hub][], which targets developers for now and will becomes production ready in a near future.
|
||||
These [new containers] allow to build and run ejabberd in a simple and lightweight environment.
|
||||
|
||||
[tags]: https://github.com/rroemhild/ejabberd/tags
|
||||
[ejabberd]: https://www.ejabberd.im/
|
||||
[rroemhild]: https://github.com/rroemhild/docker-ejabberd/
|
||||
[in this blogpost]: https://blog.process-one.net/ejabberd-16-12/
|
||||
[hub]: https://hub.docker.com/r/ejabberd/ecs/
|
||||
[new containers]: https://github.com/processone/docker-ejabberd/
|
||||
[ProcessOne]: https://www.process-one.net/
|
||||
|
||||
## Version
|
||||
|
||||
Current Version: `17.08`
|
||||
|
||||
Docker Tag Names are based on ejabberd versions in git [branches][] and [tags][]. The image tag `:latest` is based on the master branch.
|
||||
|
||||
[tags]: https://github.com/rroemhild/docker-ejabberd/tags
|
||||
[branches]: https://github.com/rroemhild/docker-ejabberd/branches
|
||||
|
||||
# Quick Start
|
||||
|
||||
@@ -46,13 +66,20 @@ docker run -d \
|
||||
-p 5280:5280 \
|
||||
-h 'xmpp.example.de' \
|
||||
-e "XMPP_DOMAIN=example.de" \
|
||||
-e "ERLANG_NODE=nodename" \
|
||||
-e "ERLANG_NODE=ejabberd" \
|
||||
-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
|
||||
```
|
||||
|
||||
or with the [docker-compose](examples/docker-compose/docker-compose.yml) example
|
||||
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/rroemhild/docker-ejabberd/master/examples/docker-compose/docker-compose.yml
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
# Usage
|
||||
|
||||
## Persistence
|
||||
@@ -68,7 +95,7 @@ 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
|
||||
docker run -d --name ejabberd --volumes-from ejabberd-data rroemhild/ejabberd
|
||||
```
|
||||
|
||||
## SSL Certificates
|
||||
@@ -100,7 +127,11 @@ 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
|
||||
## Cluster Example
|
||||
|
||||
The [docker-compose-cluster](examples/docker-compose-cluster) example demonstrates how to extend this container image to setup a multi-master cluster.
|
||||
|
||||
# Runtime 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`).
|
||||
|
||||
@@ -138,6 +169,26 @@ 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.
|
||||
|
||||
### Password format
|
||||
|
||||
The variable `EJABBERD_AUTH_PASSWORD_FORMAT` controls in which format user passwords are
|
||||
stored. Possible values are `plain` and `scram`. The default is to store
|
||||
[SCRAM](https://en.wikipedia.org/wiki/Salted_Challenge_Response_Authentication_Mechanism)bled
|
||||
passwords, meaning that it is impossible to obtain the original plain password from the
|
||||
stored information.
|
||||
|
||||
NOTE: SCRAM does not work with SIP/TURN foreign authentication methods. In this case, you
|
||||
may have to disable the option. More details can be found here:
|
||||
https://docs.ejabberd.im/admin/configuration/#internal
|
||||
|
||||
If using SCRAM with an SQL database that has plaintext passwords stored, use the command
|
||||
|
||||
```
|
||||
ejabberdctl convert_to_scram example.org
|
||||
```
|
||||
|
||||
to convert all your existing plaintext passwords to scrambled format.
|
||||
|
||||
### 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.
|
||||
@@ -215,28 +266,38 @@ EJABBERD_USERS=admin@example.ninja:password1234 user1@test.com user1@xyz.io
|
||||
```
|
||||
|
||||
## SSL
|
||||
|
||||
- **EJABBERD_SKIP_MAKE_SSLCERT**: Skip generating ssl certificates. Default: false
|
||||
- **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`.
|
||||
- **EJABBERD_STARTTLS**: Set to `false` to disable StartTLS for client to server connections. Defaults
|
||||
to `true`.
|
||||
- **EJABBERD_S2S_SSL**: Set to `false` to disable SSL in server 2 server connections. Defaults to `true`.
|
||||
- **EJABBERD_HTTPS**: If your proxy terminates SSL you may want to disable HTTPS on port 5280 and 5443. Defaults to `true`.
|
||||
- **EJABBERD_PROTOCOL_OPTIONS_TLSV1**: Allow TLSv1 protocol. Defaults to `false`.
|
||||
- **EJABBERD_PROTOCOL_OPTIONS_TLSV1_1**: Allow TLSv1.1 protocol. Defaults to `true`.
|
||||
- **EJABBERD_CIPHERS**: Cipher suite. Defaults to `HIGH:!aNULL:!3DES`.
|
||||
- **EJABBERD_DHPARAM**: Set to `true` to use or generate custom DH parameters. Defaults to `false`.
|
||||
- **EJABBERD_SKIP_MAKE_DHPARAM**: Skip generating DH params. Default: false
|
||||
|
||||
## Erlang
|
||||
- **ERLANG_NODE**: Allows to explicitly specify erlang node for ejabberd. Set to `ejabberd` lets erlang add the hostname. Defaults to `ejabberd@localhost`.
|
||||
- **ERLANG_COOKIE**: Set erlang cookie. Defaults to auto-generated cookie.
|
||||
- **ERLANG_OPTIONS**: Overwrite additional options passed to erlang while starting ejabberd.
|
||||
|
||||
## 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`.
|
||||
- **EJABBERD_SKIP_MODULES_UPDATE**: If you do not need to update ejabberd modules specs, skip the update task and speedup start. Defaults to `false`.
|
||||
- **EJABBERD_MOD_MUC_ADMIN**: Activate the mod_muc_admin module. Defaults to `false`.
|
||||
- **EJABBERD_MOD_ADMIN_EXTRA**: Activate the mod_muc_admin module. Defaults to `true`.
|
||||
- **EJABBERD_REGISTER_TRUSTED_NETWORK_ONLY**: Only allow user registration from the trusted_network access rule. Defaults to `true`.
|
||||
- **EJABBERD_MOD_VERSION**: Activate the mod_version module. Defaults to `true`.
|
||||
- **EJABBERD_SOURCE_MODULES**: List of modules, which will be installed from sources localized in ${EJABBERD_HOME}/module_source.
|
||||
- **EJABBERD_CONTRIB_MODULES**: List of modules, which will be installed from contrib repository.
|
||||
- **EJABBERD_RESTART_AFTER_MODULE_INSTALL**: If any modules were installed, restart the server, if the option is enabled.
|
||||
- **EJABBERD_CUSTOM_AUTH_MODULE_OVERRIDE**: If a custom module was defined for handling auth, we need to override the pre-defined auth methods in the config.
|
||||
|
||||
## Logging
|
||||
|
||||
Use the **EJABBERD_LOGLEVEL** environment variable to set verbosity. Default: `4` (Info).
|
||||
Use the **EJABBERD_LOGLEVEL** environment variable to set verbosity. Defaults to `4` (Info).
|
||||
|
||||
```
|
||||
loglevel: Verbosity of log files generated by ejabberd.
|
||||
@@ -276,25 +337,6 @@ Example configuration files can be downloaded from the ejabberd [github](https:/
|
||||
|
||||
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:
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#!/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
|
||||
@@ -123,8 +123,10 @@ auth_method:
|
||||
- {{ auth_method }}
|
||||
{%- endfor %}
|
||||
|
||||
auth_password_format: {{ env.get('EJABBERD_AUTH_PASSWORD_FORMAT', 'scram') }}
|
||||
|
||||
{%- if 'anonymous' in env.get('EJABBERD_AUTH_METHOD', 'internal').split() %}
|
||||
anonymous_protocol: login_anon
|
||||
anonymous_protocol: both
|
||||
allow_multiple_connections: true
|
||||
{%- endif %}
|
||||
|
||||
@@ -300,7 +302,7 @@ modules:
|
||||
mod_caps: {}
|
||||
mod_carboncopy: {}
|
||||
mod_client_state:
|
||||
drop_chat_states: true
|
||||
queue_chat_states: true
|
||||
queue_presence: false
|
||||
mod_configure: {} # requires mod_adhoc
|
||||
mod_disco: {}
|
||||
@@ -311,6 +313,8 @@ modules:
|
||||
## docroot: "/var/www"
|
||||
## accesslog: "/var/log/ejabberd/access.log"
|
||||
mod_last: {}
|
||||
mod_mam:
|
||||
default: always
|
||||
mod_muc:
|
||||
host: "conference.@HOST@"
|
||||
access: muc
|
||||
@@ -345,6 +349,8 @@ modules:
|
||||
- "flat"
|
||||
- "hometree"
|
||||
- "pep" # pep requires mod_caps
|
||||
mod_push: {}
|
||||
mod_push_keepalive: {}
|
||||
mod_register:
|
||||
##
|
||||
## Protect In-Band account registrations with CAPTCHA.
|
||||
@@ -404,12 +410,13 @@ host_config:
|
||||
{%- 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'] }}
|
||||
sql_type: {{ env['EJABBERD_ODBC_TYPE'] }}
|
||||
sql_server: "{{ env['EJABBERD_ODBC_SERVER'] }}"
|
||||
sql_database: "{{ env['EJABBERD_ODBC_DATABASE'] }}"
|
||||
sql_username: "{{ env['EJABBERD_ODBC_USERNAME'] }}"
|
||||
sql_password: "{{ env['EJABBERD_ODBC_PASSWORD'] }}"
|
||||
|
||||
default_db: sql
|
||||
{% endif %}
|
||||
|
||||
{%- if env['EJABBERD_DEFAULT_DB'] is defined %}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# Default: true
|
||||
#
|
||||
POLL={{ env['POLL'] or 'true' }}
|
||||
#POLL=true
|
||||
|
||||
#.
|
||||
#' SMP: SMP support ([enable|auto|disable])
|
||||
@@ -24,7 +24,7 @@ POLL={{ env['POLL'] or 'true' }}
|
||||
#
|
||||
# Default: auto
|
||||
#
|
||||
SMP={{ env['SMP'] or 'auto' }}
|
||||
#SMP=auto
|
||||
|
||||
#.
|
||||
#' ERL_MAX_PORTS: Maximum number of simultaneously open Erlang ports
|
||||
@@ -36,7 +36,7 @@ SMP={{ env['SMP'] or 'auto' }}
|
||||
# Default: 32000
|
||||
# Maximum: 268435456
|
||||
#
|
||||
ERL_MAX_PORTS={{ env['ERL_MAX_PORTS'] or '32000' }}
|
||||
#ERL_MAX_PORTS=32000
|
||||
|
||||
#.
|
||||
#' FIREWALL_WINDOW: Range of allowed ports to pass through a firewall
|
||||
@@ -48,9 +48,7 @@ ERL_MAX_PORTS={{ env['ERL_MAX_PORTS'] or '32000' }}
|
||||
# Default: not defined
|
||||
# Example: 4200-4210
|
||||
#
|
||||
{%- if env['FIREWALL_WINDOW'] %}
|
||||
FIREWALL_WINDOW={{ env['FIREWALL_WINDOW'] }}
|
||||
{%- endif %}
|
||||
#FIREWALL_WINDOW=
|
||||
|
||||
#.
|
||||
#' INET_DIST_INTERFACE: IP address where this Erlang node listens other nodes
|
||||
@@ -58,11 +56,9 @@ FIREWALL_WINDOW={{ env['FIREWALL_WINDOW'] }}
|
||||
# This communication is used by ejabberdctl command line tool,
|
||||
# and in a cluster of several ejabberd nodes.
|
||||
#
|
||||
# Default: 0.0.0.0
|
||||
# Default: 127.0.0.1
|
||||
#
|
||||
{%- if env['INET_DIST_INTERFACE'] %}
|
||||
INET_DIST_INTERFACE={{ env['INET_DIST_INTERFACE'] }}
|
||||
{%- endif %}
|
||||
#INET_DIST_INTERFACE=127.0.0.1
|
||||
|
||||
#.
|
||||
#' ERL_EPMD_ADDRESS: IP addresses where epmd listens for connections
|
||||
@@ -78,9 +74,7 @@ INET_DIST_INTERFACE={{ env['INET_DIST_INTERFACE'] }}
|
||||
#
|
||||
# Default: 0.0.0.0
|
||||
#
|
||||
{%- if env['ERL_EPMD_ADDRESS'] %}
|
||||
ERL_EPMD_ADDRESS={{ env['ERL_EPMD_ADDRESS'] }}
|
||||
{%- endif %}
|
||||
#ERL_EPMD_ADDRESS=127.0.0.1
|
||||
|
||||
#.
|
||||
#' ERL_PROCESSES: Maximum number of Erlang processes
|
||||
@@ -94,7 +88,7 @@ ERL_EPMD_ADDRESS={{ env['ERL_EPMD_ADDRESS'] }}
|
||||
# Default: 250000
|
||||
# Maximum: 268435456
|
||||
#
|
||||
ERL_PROCESSES={{ env['ERL_PROCESSES'] or '250000' }}
|
||||
#ERL_PROCESSES=250000
|
||||
|
||||
#.
|
||||
#' ERL_MAX_ETS_TABLES: Maximum number of ETS and Mnesia tables
|
||||
@@ -107,7 +101,7 @@ ERL_PROCESSES={{ env['ERL_PROCESSES'] or '250000' }}
|
||||
#
|
||||
# Default: 1400
|
||||
#
|
||||
ERL_MAX_ETS_TABLES={{ env['ERL_MAX_ETS_TABLES'] or '1400' }}
|
||||
#ERL_MAX_ETS_TABLES=1400
|
||||
|
||||
#.
|
||||
#' ERL_OPTIONS: Additional Erlang options
|
||||
@@ -122,7 +116,7 @@ ERL_MAX_ETS_TABLES={{ env['ERL_MAX_ETS_TABLES'] or '1400' }}
|
||||
#
|
||||
# Default: ""
|
||||
#
|
||||
ERL_OPTIONS="{{ env['ERL_OPTIONS'] or '-noshell' }}"
|
||||
ERL_OPTIONS="{{ env['ERL_OPTIONS'] or "-noshell" }}"
|
||||
|
||||
#.
|
||||
#' ERLANG_NODE: Erlang node name
|
||||
@@ -140,7 +134,7 @@ ERL_OPTIONS="{{ env['ERL_OPTIONS'] or '-noshell' }}"
|
||||
#
|
||||
# Default: ejabberd@localhost
|
||||
#
|
||||
ERLANG_NODE={{ env['ERLANG_NODE'] or 'ejabberd@localhost' }}
|
||||
ERLANG_NODE={{ env['ERLANG_NODE'] or "ejabberd@localhost" }}
|
||||
|
||||
#.
|
||||
#' EJABBERD_PID_PATH: ejabberd PID file
|
||||
@@ -163,7 +157,7 @@ ERLANG_NODE={{ env['ERLANG_NODE'] or 'ejabberd@localhost' }}
|
||||
#
|
||||
# Default: $ETC_DIR/ejabberd.yml
|
||||
#
|
||||
EJABBERD_CONFIG_PATH={{ env['EJABBERD_CONFIG_PATH'] or '/opt/ejabberd/conf/ejabberd.yml' }}
|
||||
#EJABBERD_CONFIG_PATH=/etc/ejabberd/ejabberd.yml
|
||||
|
||||
#.
|
||||
#' CONTRIB_MODULES_PATH: contributed ejabberd modules path
|
||||
@@ -173,19 +167,7 @@ EJABBERD_CONFIG_PATH={{ env['EJABBERD_CONFIG_PATH'] or '/opt/ejabberd/conf/ejabb
|
||||
#
|
||||
# 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' }}
|
||||
#CONTRIB_MODULES_PATH=/opt/ejabberd-modules
|
||||
|
||||
#.
|
||||
#' EJABBERD_BYPASS_WARNINGS: Bypass LIVE warning
|
||||
@@ -195,5 +177,11 @@ CONTRIB_MODULES_CONF_DIR={{ env['CONTRIB_MODULES_CONF_DIR'] or '/opt/ejabberd/mo
|
||||
EJABBERD_BYPASS_WARNINGS=true
|
||||
|
||||
#.
|
||||
#'
|
||||
# vim: foldmarker=#',#. foldmethod=marker:
|
||||
#' SPOOL_DIR: Database spool dir
|
||||
#
|
||||
# Specify the full path to the database spool dir used in binary installer for
|
||||
# backwards compatibility.
|
||||
#
|
||||
# Docker: rroemhild/ejabberd
|
||||
#
|
||||
SPOOL_DIR=$EJABBERD_HOME/database/$ERLANG_NODE
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{lookup,["file","native"]}.
|
||||
{host,{127,0,0,1}, ["localhost","hostalias"]}.
|
||||
{file, resolv, "/etc/resolv.conf"}.
|
||||
@@ -0,0 +1,3 @@
|
||||
FROM rroemhild/ejabberd
|
||||
ENV EJABBERD_HOME /opt/ejabberd
|
||||
COPY ./scripts $EJABBERD_HOME/scripts
|
||||
@@ -0,0 +1,23 @@
|
||||
# Ejabberd cluster with docker compose
|
||||
|
||||
This example uses [dnsdocker](https://github.com/tonistiigi/dnsdock) to discover other nodes and setup a multi-master cluster.
|
||||
|
||||
Build the ejabberd cluster image:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/rroemhild/docker-ejabberd.git
|
||||
cd docker-ejabberd/examples/docker-compose-cluster
|
||||
docker-compose build
|
||||
```
|
||||
|
||||
Start dnsdocker and the first ejabberd node:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
Wait until the first ejabberd node is up and running `docker-compose logs ejabberd`, then add some ejabberd nodes to the cluster:
|
||||
|
||||
```bash
|
||||
docker-compose scale ejabberd=4
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
dnsdock:
|
||||
image: tonistiigi/dnsdock
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
ports:
|
||||
- 172.17.42.1:53:53/udp
|
||||
|
||||
ejabberd:
|
||||
build: .
|
||||
ports:
|
||||
- 5222
|
||||
- 5269
|
||||
- 5280
|
||||
environment:
|
||||
- XMPP_DOMAIN=example.com
|
||||
- ERLANG_NODE=ejabberd
|
||||
- EJABBERD_ADMINS=admin@example.com
|
||||
- EJABBERD_USERS=admin@example.com:test321 user@example.com
|
||||
- ERLANG_COOKIE=testCluster
|
||||
- SKIP_MODULES_UPDATE=true
|
||||
- EJABBERD_CLUSTER=true
|
||||
- USE_DNS=true
|
||||
dns: 172.17.42.1
|
||||
domainname: dockercomposecluster_ejabberd.docker
|
||||
tty: true
|
||||
@@ -0,0 +1,37 @@
|
||||
# overwrite get_nodename to discover hostname from DNS
|
||||
get_nodename() {
|
||||
local hostname=${HOSTNAME}
|
||||
|
||||
# get hostname from dns
|
||||
if ( is_true ${USE_DNS} ); then
|
||||
# wait for dns registration
|
||||
sleep 1
|
||||
|
||||
nodename=$(discover_dns_hostname ${HOSTIP})
|
||||
|
||||
is_set ${nodename} \
|
||||
&& hostname=${nodename}
|
||||
fi
|
||||
|
||||
echo $hostname
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# discover hostname from dns with a reverse lookup
|
||||
discover_dns_hostname() {
|
||||
local hostip=$1
|
||||
|
||||
# try to get the hostname from dns
|
||||
local dnsname=$(drill -x ${hostip} \
|
||||
| grep PTR \
|
||||
| awk '{print $5}' \
|
||||
| grep -E "^[a-zA-Z0-9]+([-._]?[a-zA-Z0-9]+)*.[a-zA-Z]+\.$" \
|
||||
| cut -d '.' -f1 \
|
||||
| tail -1)
|
||||
|
||||
is_set ${dnsname} \
|
||||
&& echo ${dnsname}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
get_cluster_node_from_dns() {
|
||||
local cluster_host=$(drill ${DOMAINNAME} \
|
||||
| grep ${DOMAINNAME} \
|
||||
| grep -v ${HOSTIP} \
|
||||
| awk '{print $5}' \
|
||||
| grep -v "^$" \
|
||||
| head -1)
|
||||
echo $(discover_dns_hostname ${cluster_host})
|
||||
}
|
||||
|
||||
|
||||
file_exist ${FIRST_START_DONE_FILE} \
|
||||
&& exit 0
|
||||
|
||||
|
||||
join_cluster $(get_cluster_node_from_dns)
|
||||
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1 @@
|
||||
# simple docker-compose example
|
||||
@@ -0,0 +1,11 @@
|
||||
ejabberd:
|
||||
image: rroemhild/ejabberd
|
||||
ports:
|
||||
- 5222:5222
|
||||
- 5269:5269
|
||||
- 5280:5280
|
||||
environment:
|
||||
- ERLANG_NODE=ejabberd
|
||||
- XMPP_DOMAIN=example.com xyz.io
|
||||
- EJABBERD_ADMINS=admin@example.com
|
||||
- EJABBERD_USERS=admin@example.com:password4321 user1@xyz.io
|
||||
@@ -1,22 +0,0 @@
|
||||
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))"
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,36 +0,0 @@
|
||||
#!/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
+99
@@ -0,0 +1,99 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
# discover hostname
|
||||
readonly nodename=$(get_nodename)
|
||||
|
||||
is_zero ${ERLANG_NODE} \
|
||||
&& export ERLANG_NODE="ejabberd@localhost"
|
||||
|
||||
## backward compatibility
|
||||
# if ERLANG_NODE is true reset it to "ejabberd" and add
|
||||
# hostname to the nodename.
|
||||
# else: export ${ERLANG_NODE} with nodename
|
||||
if (is_true ${ERLANG_NODE}); then
|
||||
export ERLANG_NODE="ejabberd@${nodename}"
|
||||
fi
|
||||
|
||||
|
||||
run_scripts() {
|
||||
local run_script_dir="${EJABBERD_HOME}/scripts/${1}"
|
||||
for script in ${run_script_dir}/*.sh ; do
|
||||
if [ -f ${script} -a -x ${script} ] ; then
|
||||
${script}
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
pre_scripts() {
|
||||
run_scripts "pre"
|
||||
}
|
||||
|
||||
|
||||
post_scripts() {
|
||||
run_scripts "post"
|
||||
}
|
||||
|
||||
stop_scripts() {
|
||||
run_scripts "stop"
|
||||
}
|
||||
|
||||
|
||||
ctl() {
|
||||
local action="$1"
|
||||
${EJABBERDCTL} ${action} >/dev/null
|
||||
}
|
||||
|
||||
|
||||
_trap() {
|
||||
echo "Stopping ejabberd..."
|
||||
stop_scripts
|
||||
if ctl stop ; then
|
||||
local cnt=0
|
||||
sleep 1
|
||||
while ctl status || test $? = 1 ; do
|
||||
cnt=`expr $cnt + 1`
|
||||
if [ $cnt -ge 60 ] ; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Catch signals and shutdown ejabberd
|
||||
trap _trap SIGTERM SIGINT
|
||||
|
||||
## run ejabberd
|
||||
case "$@" in
|
||||
start)
|
||||
pre_scripts
|
||||
tail -n 0 -F ${LOGDIR}/crash.log \
|
||||
${LOGDIR}/error.log \
|
||||
${LOGDIR}/erlang.log &
|
||||
echo "Starting ejabberd..."
|
||||
exec ${EJABBERDCTL} "foreground" &
|
||||
child=$!
|
||||
${EJABBERDCTL} "started"
|
||||
post_scripts
|
||||
wait $child
|
||||
;;
|
||||
live)
|
||||
pre_scripts
|
||||
echo "Starting ejabberd in 'live' mode..."
|
||||
exec ${EJABBERDCTL} "live"
|
||||
;;
|
||||
shell)
|
||||
exec "/bin/bash"
|
||||
;;
|
||||
*)
|
||||
exec $@
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,53 @@
|
||||
readonly HOSTIP=$(hostname -i)
|
||||
readonly HOSTNAME=$(hostname -f)
|
||||
readonly DOMAINNAME=$(hostname -d)
|
||||
|
||||
readonly ERLANGCOOKIEFILE="${EJABBERD_HOME}/.erlang.cookie"
|
||||
readonly EJABBERDCTL="/usr/local/sbin/ejabberdctl"
|
||||
readonly CONFIGFILE="${EJABBERD_HOME}/conf/ejabberd.yml"
|
||||
readonly CONFIGTEMPLATE="${EJABBERD_HOME}/conf/ejabberd.yml.tpl"
|
||||
readonly CTLCONFIGFILE="${EJABBERD_HOME}/conf/ejabberdctl.cfg"
|
||||
readonly CTLCONFIGTEMPLATE="${EJABBERD_HOME}/conf/ejabberdctl.cfg.tpl"
|
||||
readonly SSLCERTDIR="${EJABBERD_HOME}/ssl"
|
||||
readonly SSLCERTHOST="${SSLCERTDIR}/host.pem"
|
||||
readonly SSLDHPARAM="${SSLCERTDIR}/dh.pem"
|
||||
readonly LOGDIR="/usr/local/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))"
|
||||
|
||||
# backward compatibility environment variables
|
||||
set +e
|
||||
|
||||
[[ -n $EJABBERD_ADMIN ]] \
|
||||
&& export EJABBERD_ADMINS=${EJABBERD_ADMIN}
|
||||
|
||||
[[ -n $AUTH_METHOD ]] \
|
||||
&& export EJABBERD_AUTH_METHOD=${AUTH_METHOD}
|
||||
|
||||
[[ -n $SKIP_MODULES_UPDATE ]] \
|
||||
&& export EJABBERD_SKIP_MODULES_UPDATE=${SKIP_MODULES_UPDATE}
|
||||
|
||||
[[ -n $ERL_OPTIONS ]] \
|
||||
&& export ERLANG_OPTIONS=${ERL_OPTIONS}
|
||||
|
||||
[[ -n $SSLCERT_HOST ]] \
|
||||
&& export EJABBERD_SSLCERT_HOST=${SSLCERT_HOST}
|
||||
|
||||
[[ -n $SSLCERT_EXAMPLE_COM ]] \
|
||||
&& export EJABBERD_SSLCERT_EXAMPLE_COM=${SSLCERT_EXAMPLE_COM}
|
||||
|
||||
[[ -n $LOGLEVEL ]] \
|
||||
&& export EJABBERD_LOGLEVEL=${LOGLEVEL}
|
||||
|
||||
[[ -n $EJABBERD_WEB_ADMIN_SSL ]] \
|
||||
&& export EJABBERD_HTTPS=${EJABBERD_WEB_ADMIN_SSL}
|
||||
|
||||
set -e
|
||||
@@ -29,16 +29,10 @@ is_true() {
|
||||
}
|
||||
|
||||
|
||||
log() {
|
||||
local message=$1
|
||||
echo $message
|
||||
}
|
||||
|
||||
|
||||
# overwrite this function to get hostname from other sources
|
||||
# like dns or etcd
|
||||
get_nodename() {
|
||||
log ${HOSTNAME}
|
||||
echo ${HOSTNAME}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,25 +42,25 @@ join_cluster() {
|
||||
is_zero ${cluster_node} \
|
||||
&& exit 0
|
||||
|
||||
log "Join cluster..."
|
||||
echo "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}..."
|
||||
echo "Waiting for ${erlang_cluster_node}..."
|
||||
sleep 2
|
||||
response=$(${EJABBERDCTL} ping ${erlang_cluster_node})
|
||||
done
|
||||
|
||||
log "Join cluster at ${erlang_cluster_node}... "
|
||||
echo "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"
|
||||
echo "cloud not join cluster"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
+5
-5
@@ -3,14 +3,14 @@ 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"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
run_modules_update_specs() {
|
||||
log "Updating module specs... "
|
||||
echo -n 'Updating module specs... '
|
||||
${EJABBERDCTL} modules_update_specs
|
||||
}
|
||||
|
||||
+26
-27
@@ -3,55 +3,54 @@ 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"
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/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"
|
||||
local module_install_folder=${EJABBERD_HOME}/.ejabberd-modules/sources
|
||||
|
||||
echo "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"
|
||||
echo "Error: Module ${module_name} not found in ${EJABBERD_HOME}/module_source"
|
||||
echo "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}"
|
||||
echo "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}"
|
||||
echo "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}"
|
||||
echo "Running module_check on ${module_name}"
|
||||
${EJABBERDCTL} module_check ${module_name}
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Module check failed for ${module_name}"
|
||||
echo "Module check failed for ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
log "Module check succeeded for ${module_name}"
|
||||
echo "Module check succeeded for ${module_name}"
|
||||
|
||||
# Install the module
|
||||
log "Running module_install on ${module_name}"
|
||||
echo "Running module_install on ${module_name}"
|
||||
${EJABBERDCTL} module_install ${module_name}
|
||||
if [ $? -ne 0 ]; then
|
||||
log "Module installation failed for ${module_name}"
|
||||
echo "Module installation failed for ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
log "Module installation succeeded for ${module_name}"
|
||||
echo "Module installation succeeded for ${module_name}"
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -62,18 +61,18 @@ install_module_from_ejabberd_contrib() {
|
||||
# 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}"
|
||||
echo "Error: Module already installed: ejabberd_contrib ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
|
||||
# Install the module
|
||||
log "Running module_install on ejabberd_contrib ${module_name}"
|
||||
echo "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}"
|
||||
echo "Module installation failed for ejabberd_contrib ${module_name}"
|
||||
return 1;
|
||||
fi
|
||||
log "Module installation succeeded for ejabberd_contrib ${module_name}"
|
||||
echo "Module installation succeeded for ejabberd_contrib ${module_name}"
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -86,21 +85,21 @@ enable_custom_auth_module_override() {
|
||||
required_prefix="ejabberd_auth_"
|
||||
|
||||
if [[ "${module_name}" != "${required_prefix}"* ]]; then
|
||||
log "Error: module_name must begin with ${required_prefix}"
|
||||
echo "Error: module_name must begin with ${required_prefix}"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
log "Checking custom auth module: ${module_name}"
|
||||
echo "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}"
|
||||
echo "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."
|
||||
echo "Custom auth module ${module_name} configuration complete."
|
||||
}
|
||||
|
||||
file_exist ${FIRST_START_DONE_FILE} \
|
||||
@@ -133,7 +132,7 @@ 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)"
|
||||
echo "Restarting ejabberd after successful module installation(s)"
|
||||
${EJABBERDCTL} restart
|
||||
child=$!
|
||||
${EJABBERDCTL} "started"
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/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 ]] \
|
||||
&& echo "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
|
||||
|
||||
|
||||
##################################
|
||||
## Keep for backward compatibility
|
||||
|
||||
register_all_ejabberd_admins() {
|
||||
# add all admins from environment $EJABBERD_ADMINS with the passwords from
|
||||
# environment $EJABBERD_ADMIN_PASS.
|
||||
|
||||
local passwords
|
||||
local IFS=' '
|
||||
read -a passwords <<< "${EJABBERD_ADMIN_PWD}"
|
||||
|
||||
for admin in ${EJABBERD_ADMINS} ; do
|
||||
local user=${admin%%@*}
|
||||
local domain=${admin#*@}
|
||||
local password=${passwords[0]}
|
||||
passwords=("${passwords[@]:1}")
|
||||
register_user ${user} ${domain} ${password}
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
register_all_ejabberd_admins_randpw() {
|
||||
# add all admins from environment $EJABBERD_ADMINS with a random
|
||||
# password and write the password to stdout.
|
||||
|
||||
for admin in ${EJABBERD_ADMINS} ; do
|
||||
local user=${admin%%@*}
|
||||
local domain=${admin#*@}
|
||||
local password=$(randpw)
|
||||
|
||||
register_user ${user} ${domain} ${password}
|
||||
local retval=$?
|
||||
|
||||
[[ ${retval} -eq 0 ]] \
|
||||
&& echo "Password for user ${user}@${domain} is ${password}"
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
is_set ${EJABBERD_ADMIN_PWD} \
|
||||
&& register_all_ejabberd_admins
|
||||
|
||||
|
||||
is_true ${EJABBERD_ADMIN_RANDPWD} \
|
||||
&& register_all_ejabberd_admins_randpw
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Write a first-start-done file
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
if [ ! -e "${FIRST_START_DONE_FILE}" ]; then
|
||||
touch ${FIRST_START_DONE_FILE}
|
||||
fi
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
readonly whoami=$(whoami)
|
||||
|
||||
|
||||
change_ejabberd_run_user() {
|
||||
echo "Change ejabberd install user to root..."
|
||||
sed -i "s/INSTALLUSER=${EJABBERD_USER}/INSTALLUSER=${whoami}/" ${EJABBERDCTL}
|
||||
}
|
||||
|
||||
|
||||
[[ "${whoami}" == "root" ]] \
|
||||
&& change_ejabberd_run_user
|
||||
|
||||
|
||||
exit 0
|
||||
+6
-7
@@ -1,10 +1,10 @@
|
||||
#!/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"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
# Instead of having to mount a direction, specify the ssl certs
|
||||
# via environment variables:
|
||||
@@ -12,9 +12,9 @@ source "${EJABBERD_HOME}/docker/lib/functions.sh"
|
||||
# For example: `EJABBERD_SSLCERT_EXAMPLE_COM`.
|
||||
|
||||
write_file_from_env() {
|
||||
log "Writing $1 to $2"
|
||||
echo "Writing $1 to $2"
|
||||
mkdir -p "$(dirname $2)"
|
||||
log "${!1}" > $2
|
||||
echo "${!1}" > $2
|
||||
}
|
||||
|
||||
# Write the host certificate
|
||||
@@ -30,5 +30,4 @@ for xmpp_domain in ${XMPP_DOMAIN} ; do
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
exit 0
|
||||
+25
-9
@@ -1,10 +1,10 @@
|
||||
#!/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"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
make_snakeoil_certificate() {
|
||||
@@ -20,7 +20,7 @@ make_snakeoil_certificate() {
|
||||
-keyout /tmp/selfsigned.key \
|
||||
-out /tmp/selfsigned.crt
|
||||
|
||||
log "Writing ssl cert and private key to '${certfile}'..."
|
||||
echo "Writing ssl cert and private key to '${certfile}'..."
|
||||
cat /tmp/selfsigned.crt /tmp/selfsigned.key > ${certfile}
|
||||
rm /tmp/selfsigned.crt /tmp/selfsigned.key
|
||||
}
|
||||
@@ -43,7 +43,8 @@ make_host_snakeoil_certificate() {
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Generating snakeoil ssl cert for ${domain}..."
|
||||
echo -n "Missing ssl cert for your host. "
|
||||
echo "Generating snakeoil ssl cert for ${domain}..."
|
||||
|
||||
make_snakeoil_certificate ${domain} ${SSLCERTHOST}
|
||||
}
|
||||
@@ -53,17 +54,33 @@ make_domain_snakeoil_certificate() {
|
||||
local domain=$1
|
||||
local certfile=$2
|
||||
|
||||
log "Generating snakeoil ssl cert for ${domain}..."
|
||||
echo -n "Missing ssl cert for your xmpp domain. "
|
||||
echo "Generating snakeoil ssl cert for ${domain}..."
|
||||
|
||||
make_snakeoil_certificate ${domain} ${certfile}
|
||||
}
|
||||
|
||||
|
||||
## backward compatibility
|
||||
# link old xmpp_domain.pem file to the first <domainname>.pem in XMPP_DOMAIN
|
||||
readonly SSLCERTDOMAIN="${SSLCERTDIR}/xmpp_domain.pem"
|
||||
if file_exist ${SSLCERTDOMAIN} ; then
|
||||
for xmpp_domain in ${XMPP_DOMAIN} ; do
|
||||
file_exist "${SSLCERTDIR}/${xmpp_domain}.pem" \
|
||||
|| ln -s ${SSLCERTDOMAIN} "${SSLCERTDIR}/${xmpp_domain}.pem"
|
||||
break
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
is_true ${EJABBERD_SKIP_MAKE_SSLCERT} \
|
||||
&& echo "Skip certificate generation" \
|
||||
&& exit 0
|
||||
|
||||
# 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"
|
||||
@@ -71,5 +88,4 @@ for xmpp_domain in ${XMPP_DOMAIN} ; do
|
||||
|| make_domain_snakeoil_certificate ${xmpp_domain} ${domain_certfile}
|
||||
done
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
make_dhparam() {
|
||||
local dhfile=$1
|
||||
local bits=$2
|
||||
|
||||
echo "Writing dh file to '${dhfile}'..."
|
||||
openssl dhparam -out ${dhfile} ${bits}
|
||||
}
|
||||
|
||||
|
||||
is_true ${EJABBERD_SKIP_MAKE_DHPARAM} \
|
||||
&& echo "Skip DH param generation" \
|
||||
&& exit 0
|
||||
|
||||
if is_true ${EJABBERD_DHPARAM} ; then
|
||||
file_exist ${SSLDHPARAM} \
|
||||
|| make_dhparam ${SSLDHPARAM} 4096
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1,14 +1,14 @@
|
||||
#!/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"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
set_erlang_cookie() {
|
||||
chmod 600 ${ERLANGCOOKIEFILE}
|
||||
log "Set erlang cookie to ${ERLANG_COOKIE}..."
|
||||
echo "Set erlang cookie to ${ERLANG_COOKIE}..."
|
||||
echo ${ERLANG_COOKIE} > ${ERLANGCOOKIEFILE}
|
||||
chmod 400 ${ERLANGCOOKIEFILE}
|
||||
}
|
||||
@@ -22,5 +22,4 @@ file_exist ${FIRST_START_DONE_FILE} \
|
||||
is_set ${ERLANG_COOKIE} \
|
||||
&& set_erlang_cookie
|
||||
|
||||
|
||||
exit 0
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
make_config() {
|
||||
if [ ! -e ${CONFIGFILE} ]; then
|
||||
echo "Generating ejabberd config file..."
|
||||
cat ${CONFIGTEMPLATE} \
|
||||
| python -c "${PYTHON_JINJA2}" \
|
||||
> ${CONFIGFILE}
|
||||
else
|
||||
echo "ejabberd config file exists."
|
||||
fi
|
||||
|
||||
if [ ! -e ${CTLCONFIGFILE} ]; then
|
||||
echo "Generating ejabberdctl config file..."
|
||||
cat ${CTLCONFIGTEMPLATE} \
|
||||
| python -c "${PYTHON_JINJA2}" \
|
||||
> ${CTLCONFIGFILE}
|
||||
else
|
||||
echo "ejabberdctl config file exists."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
file_exist ${FIRST_START_DONE_FILE} \
|
||||
&& exit 0
|
||||
|
||||
|
||||
# generate config file
|
||||
make_config
|
||||
|
||||
exit 0
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/config.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
|
||||
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
|
||||
|
||||
|
||||
leave_cluster() {
|
||||
echo "Leave cluster... "
|
||||
rm ${CLUSTER_NODE_FILE}
|
||||
NO_WARNINGS=true ${EJABBERDCTL} leave_cluster
|
||||
}
|
||||
|
||||
|
||||
file_exist ${CLUSTER_NODE_FILE} \
|
||||
&& leave_cluster
|
||||
|
||||
|
||||
exit 0
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/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
|
||||
@@ -11,8 +11,8 @@ Restart=on-failure
|
||||
RestartSec=5
|
||||
ExecStart=/bin/sh -c '@ctlscriptpath@/ejabberdctl start && @ctlscriptpath@/ejabberdctl started'
|
||||
ExecStop=/bin/sh -c '@ctlscriptpath@/ejabberdctl stop && @ctlscriptpath@/ejabberdctl stopped'
|
||||
ExecReload=@ctlscriptpath@/ejabberdctl reload_config
|
||||
PrivateDevices=true
|
||||
ProtectSystem=full
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
+216
-68
@@ -88,7 +88,7 @@ log_rate_limit: 100
|
||||
##
|
||||
## hosts: Domains served by ejabberd.
|
||||
## You can define one or several, for example:
|
||||
## hosts:
|
||||
## hosts:
|
||||
## - "example.net"
|
||||
## - "example.com"
|
||||
## - "example.org"
|
||||
@@ -103,6 +103,38 @@ hosts:
|
||||
##
|
||||
## route_subdomains: s2s
|
||||
|
||||
###. ============
|
||||
###' Certificates
|
||||
|
||||
## List all available PEM files containing certificates for your domains,
|
||||
## chains of certificates or certificate keys. Full chains will be built
|
||||
## automatically by ejabberd.
|
||||
##
|
||||
## certfiles:
|
||||
## - "/etc/letsencrypt/live/example.org/*.pem"
|
||||
## - "/etc/letsencrypt/live/example.com/*.pem"
|
||||
##
|
||||
## If your system provides only a single CA file (CentOS/FreeBSD):
|
||||
## ca_file: "/etc/ssl/certs/ca-bundle.pem"
|
||||
|
||||
###. =================
|
||||
###' TLS configuration
|
||||
|
||||
## define_macro:
|
||||
## 'TLS_CIPHERS': "HIGH:!aNULL:!eNULL:!3DES:@STRENGTH"
|
||||
## 'TLS_OPTIONS':
|
||||
## - "no_sslv3"
|
||||
## - "cipher_server_preference"
|
||||
## - "no_compression"
|
||||
## 'DH_FILE': "/path/to/dhparams.pem" # generated with: openssl dhparam -out dhparams.pem 2048
|
||||
##
|
||||
## c2s_dhfile: 'DH_FILE'
|
||||
## s2s_dhfile: 'DH_FILE'
|
||||
## c2s_ciphers: 'TLS_CIPHERS'
|
||||
## s2s_ciphers: 'TLS_CIPHERS'
|
||||
## c2s_protocol_options: 'TLS_OPTIONS'
|
||||
## s2s_protocol_options: 'TLS_OPTIONS'
|
||||
|
||||
###. ===============
|
||||
###' LISTENING PORTS
|
||||
|
||||
@@ -110,16 +142,15 @@ hosts:
|
||||
## listen: The ports ejabberd will listen on, which service each is handled
|
||||
## by and what options to start it with.
|
||||
##
|
||||
listen:
|
||||
-
|
||||
listen:
|
||||
-
|
||||
port: 5222
|
||||
ip: "::"
|
||||
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:
|
||||
## certificate, uncomment this line:
|
||||
##
|
||||
## certfile: "/path/to/ssl.pem"
|
||||
## starttls: true
|
||||
##
|
||||
## To enforce TLS encryption for client connections,
|
||||
@@ -127,27 +158,40 @@ listen:
|
||||
##
|
||||
## starttls_required: true
|
||||
##
|
||||
## Custom OpenSSL options
|
||||
## Stream compression
|
||||
##
|
||||
## zlib: true
|
||||
##
|
||||
## protocol_options:
|
||||
## - "no_sslv3"
|
||||
## - "no_tlsv1"
|
||||
max_stanza_size: 65536
|
||||
shaper: c2s_shaper
|
||||
access: c2s
|
||||
-
|
||||
-
|
||||
port: 5269
|
||||
ip: "::"
|
||||
module: ejabberd_s2s_in
|
||||
-
|
||||
port: 5280
|
||||
ip: "::"
|
||||
module: ejabberd_http
|
||||
request_handlers:
|
||||
"/ws": ejabberd_http_ws
|
||||
"/bosh": mod_bosh
|
||||
"/api": mod_http_api
|
||||
## "/pub/archive": mod_http_fileserver
|
||||
web_admin: true
|
||||
## register: true
|
||||
captcha: true
|
||||
##
|
||||
## ejabberd_service: Interact with external components (transports, ...)
|
||||
##
|
||||
## -
|
||||
## -
|
||||
## port: 8888
|
||||
## ip: "::"
|
||||
## module: ejabberd_service
|
||||
## access: all
|
||||
## shaper_rule: fast
|
||||
## ip: "127.0.0.1"
|
||||
## privilege_access:
|
||||
## privilege_access:
|
||||
## roster: "both"
|
||||
## message: "outgoing"
|
||||
## presence: "roster"
|
||||
@@ -165,7 +209,7 @@ listen:
|
||||
##
|
||||
## ejabberd_stun: Handles STUN Binding requests
|
||||
##
|
||||
## -
|
||||
## -
|
||||
## port: 3478
|
||||
## transport: udp
|
||||
## module: ejabberd_stun
|
||||
@@ -173,51 +217,45 @@ listen:
|
||||
##
|
||||
## To handle XML-RPC requests that provide admin credentials:
|
||||
##
|
||||
## -
|
||||
## -
|
||||
## port: 4560
|
||||
## ip: "::"
|
||||
## module: ejabberd_xmlrpc
|
||||
## access_commands: {}
|
||||
-
|
||||
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
|
||||
## maxsessions: 10
|
||||
## timeout: 5000
|
||||
## access_commands:
|
||||
## admin:
|
||||
## commands: all
|
||||
## options: []
|
||||
|
||||
##
|
||||
## To enable secure http upload
|
||||
##
|
||||
## -
|
||||
## port: 5444
|
||||
## ip: "::"
|
||||
## module: ejabberd_http
|
||||
## request_handlers:
|
||||
## "": mod_http_upload
|
||||
## tls: true
|
||||
## protocol_options: 'TLSOPTS'
|
||||
## dhfile: 'DHFILE'
|
||||
## ciphers: 'CIPHERS'
|
||||
|
||||
## Disabling digest-md5 SASL authentication. digest-md5 requires plain-text
|
||||
## password storage (see auth_password_format option).
|
||||
## disable_sasl_mechanisms: "digest-md5"
|
||||
|
||||
###. ==================
|
||||
###' S2S GLOBAL OPTIONS
|
||||
|
||||
##
|
||||
## 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: Enable STARTTLS for S2S connections.
|
||||
## Allowed values are: false, optional or required
|
||||
## You must specify 'certfiles' option
|
||||
##
|
||||
## 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
|
||||
##
|
||||
@@ -229,12 +267,12 @@ listen:
|
||||
## Outgoing S2S options
|
||||
##
|
||||
## Preferred address families (which to try first) and connect timeout
|
||||
## in milliseconds.
|
||||
## in seconds.
|
||||
##
|
||||
## outgoing_s2s_families:
|
||||
## - ipv4
|
||||
## - ipv6
|
||||
## outgoing_s2s_timeout: 10000
|
||||
## outgoing_s2s_timeout: 190
|
||||
|
||||
###. ==============
|
||||
###' AUTHENTICATION
|
||||
@@ -406,7 +444,7 @@ shaper:
|
||||
## This option specifies the maximum number of elements in the queue
|
||||
## of the FSM. Refer to the documentation for details.
|
||||
##
|
||||
max_fsm_queue: 1000
|
||||
max_fsm_queue: 10000
|
||||
|
||||
###. ====================
|
||||
###' ACCESS CONTROL LISTS
|
||||
@@ -429,7 +467,7 @@ acl:
|
||||
|
||||
## Local users: don't modify this.
|
||||
##
|
||||
local:
|
||||
local:
|
||||
user_regexp: ""
|
||||
|
||||
##
|
||||
@@ -451,6 +489,8 @@ acl:
|
||||
loopback:
|
||||
ip:
|
||||
- "127.0.0.0/8"
|
||||
- "::1/128"
|
||||
- "::FFFF:127.0.0.1/128"
|
||||
|
||||
##
|
||||
## Bad XMPP servers
|
||||
@@ -501,29 +541,77 @@ access_rules:
|
||||
announce:
|
||||
- allow: admin
|
||||
## Only admins can use the configuration interface:
|
||||
configure:
|
||||
configure:
|
||||
- allow: admin
|
||||
## Only accounts of the local ejabberd server can create rooms:
|
||||
muc_create:
|
||||
muc_create:
|
||||
- allow: local
|
||||
## Only accounts on the local ejabberd server can create Pubsub nodes:
|
||||
pubsub_createnode:
|
||||
pubsub_createnode:
|
||||
- allow: local
|
||||
## In-band registration allows registration of any possible username.
|
||||
## To disable in-band registration, replace 'allow' with 'deny'.
|
||||
register:
|
||||
register:
|
||||
- allow
|
||||
## Only allow to register from localhost
|
||||
trusted_network:
|
||||
trusted_network:
|
||||
- allow: loopback
|
||||
## Do not establish S2S connections with bad servers
|
||||
## s2s:
|
||||
## If you enable this you also have to uncomment "s2s_access: s2s"
|
||||
## s2s:
|
||||
## - 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 that connect from 127.0.0.1 to execute all
|
||||
## commands except start and stop with any available access method
|
||||
## (ejabberdctl, http-api, xmlrpc depending what is enabled on server).
|
||||
##
|
||||
## If you remove "console commands" there will be one added by
|
||||
## default allowing executing all commands, but if you just change
|
||||
## permissions in it, version from config file will be used instead
|
||||
## of default one.
|
||||
##
|
||||
api_permissions:
|
||||
"console commands":
|
||||
from:
|
||||
- ejabberd_ctl
|
||||
who: all
|
||||
what: "*"
|
||||
"admin access":
|
||||
who:
|
||||
- access:
|
||||
- allow:
|
||||
- acl: loopback
|
||||
- acl: admin
|
||||
- oauth:
|
||||
- scope: "ejabberd:admin"
|
||||
- access:
|
||||
- allow:
|
||||
- acl: loopback
|
||||
- acl: admin
|
||||
what:
|
||||
- "*"
|
||||
- "!stop"
|
||||
- "!start"
|
||||
"public commands":
|
||||
who:
|
||||
- ip: "127.0.0.1/8"
|
||||
what:
|
||||
- "status"
|
||||
- "connected_users_number"
|
||||
|
||||
## 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
|
||||
@@ -573,15 +661,45 @@ language: "en"
|
||||
##
|
||||
## captcha_limit: 5
|
||||
|
||||
###. ====
|
||||
###' ACME
|
||||
##
|
||||
## In order to use the acme certificate acquiring through "Let's Encrypt"
|
||||
## an http listener has to be configured to listen to port 80 so that
|
||||
## the authorization challenges posed by "Let's Encrypt" can be solved.
|
||||
##
|
||||
## A simple way of doing this would be to add the following in the listening
|
||||
## section and to configure port forwarding from 80 to 5280 either via NAT
|
||||
## (for ipv4 only) or using frontends such as haproxy/nginx/sslh/etc.
|
||||
## -
|
||||
## port: 5280
|
||||
## ip: "::"
|
||||
## module: ejabberd_http
|
||||
|
||||
acme:
|
||||
|
||||
## A contact mail that the ACME Certificate Authority can contact in case of
|
||||
## an authorization issue, such as a server-initiated certificate revocation.
|
||||
## It is not mandatory to provide an email address but it is highly suggested.
|
||||
contact: "mailto:example-admin@example.com"
|
||||
|
||||
|
||||
## The ACME Certificate Authority URL.
|
||||
## This could either be:
|
||||
## - https://acme-v01.api.letsencrypt.org - (Default) for the production CA
|
||||
## - https://acme-staging.api.letsencrypt.org - for the staging CA
|
||||
## - http://localhost:4000 - for a local version of the CA
|
||||
ca_url: "https://acme-v01.api.letsencrypt.org"
|
||||
|
||||
###. =======
|
||||
###' MODULES
|
||||
|
||||
##
|
||||
## Modules enabled in all ejabberd virtual hosts.
|
||||
##
|
||||
modules:
|
||||
modules:
|
||||
mod_adhoc: {}
|
||||
## mod_admin_extra: {}
|
||||
mod_admin_extra: {}
|
||||
mod_announce: # recommends mod_adhoc
|
||||
access: announce
|
||||
mod_blocking: {} # requires mod_privacy
|
||||
@@ -589,16 +707,26 @@ modules:
|
||||
mod_carboncopy: {}
|
||||
mod_client_state: {}
|
||||
mod_configure: {} # requires mod_adhoc
|
||||
##mod_delegation: {} # for xep0356
|
||||
## mod_delegation: {} # for xep0356
|
||||
mod_disco: {}
|
||||
## mod_echo: {}
|
||||
mod_echo: {}
|
||||
mod_irc: {}
|
||||
mod_http_bind: {}
|
||||
mod_bosh: {}
|
||||
## mod_http_fileserver:
|
||||
## docroot: "/var/www"
|
||||
## accesslog: "/var/log/ejabberd/access.log"
|
||||
## mod_http_upload:
|
||||
## # docroot: "@HOME@/upload"
|
||||
## put_url: "https://@HOST@:5444"
|
||||
## thumbnail: false # otherwise needs the identify command from ImageMagick installed
|
||||
## mod_http_upload_quota:
|
||||
## max_days: 30
|
||||
mod_last: {}
|
||||
mod_muc:
|
||||
## XEP-0313: Message Archive Management
|
||||
## You might want to setup a SQL backend for MAM because the mnesia database is
|
||||
## limited to 2GB which might be exceeded on large servers
|
||||
## mod_mam: {} # for xep0313, mnesia is limited to 2GB, better use an SQL backend
|
||||
mod_muc:
|
||||
## host: "conference.@HOST@"
|
||||
access:
|
||||
- allow
|
||||
@@ -606,9 +734,10 @@ modules:
|
||||
- allow: admin
|
||||
access_create: muc_create
|
||||
access_persistent: muc_create
|
||||
mod_muc_admin: {}
|
||||
## mod_muc_log: {}
|
||||
## mod_multicast: {}
|
||||
mod_offline:
|
||||
mod_offline:
|
||||
access_max_user_messages: max_user_offline_messages
|
||||
mod_ping: {}
|
||||
## mod_pres_counter:
|
||||
@@ -617,17 +746,19 @@ modules:
|
||||
mod_privacy: {}
|
||||
mod_private: {}
|
||||
## mod_proxy65: {}
|
||||
mod_pubsub:
|
||||
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:
|
||||
plugins:
|
||||
- "flat"
|
||||
- "hometree"
|
||||
- "pep" # pep requires mod_caps
|
||||
mod_push: {}
|
||||
mod_push_keepalive: {}
|
||||
## mod_register:
|
||||
##
|
||||
## Protect In-Band account registrations with CAPTCHA.
|
||||
@@ -667,7 +798,24 @@ modules:
|
||||
mod_time: {}
|
||||
mod_vcard:
|
||||
search: false
|
||||
mod_vcard_xupdate: {}
|
||||
## Convert all avatars posted by Android clients from WebP to JPEG
|
||||
## mod_avatar: # this module needs compile option --enable-graphics
|
||||
## convert:
|
||||
## webp: jpeg
|
||||
mod_version: {}
|
||||
mod_stream_mgmt: {}
|
||||
## Non-SASL Authentication (XEP-0078) is now disabled by default
|
||||
## because it's obsoleted and is used mostly by abandoned
|
||||
## client software
|
||||
## mod_legacy_auth: {}
|
||||
## The module for S2S dialback (XEP-0220). Please note that you cannot
|
||||
## rely solely on dialback if you want to federate with other servers,
|
||||
## because a lot of servers have dialback disabled and instead rely on
|
||||
## PKIX authentication. Make sure you have proper certificates installed
|
||||
## and check your accessibility at https://check.messaging.one/
|
||||
mod_s2s_dialback: {}
|
||||
mod_http_api: {}
|
||||
|
||||
##
|
||||
## Enable modules with custom options in a specific virtual host
|
||||
|
||||
+176
-306
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
|
||||
# define default configuration
|
||||
POLL=true
|
||||
@@ -7,138 +7,94 @@ ERL_MAX_PORTS=32000
|
||||
ERL_PROCESSES=250000
|
||||
ERL_MAX_ETS_TABLES=1400
|
||||
FIREWALL_WINDOW=""
|
||||
INET_DIST_INTERFACE=""
|
||||
ERLANG_NODE=ejabberd@localhost
|
||||
|
||||
# define default environment variables
|
||||
SCRIPT_DIR=`cd ${0%/*} && pwd`
|
||||
ERL={{erl}}
|
||||
IEX={{bindir}}/iex
|
||||
EPMD={{epmd}}
|
||||
INSTALLUSER={{installuser}}
|
||||
ERL_LIBS={{libdir}}
|
||||
SCRIPT_DIR=$(cd "${0%/*}" && pwd)
|
||||
ERL="{{erl}}"
|
||||
IEX="{{bindir}}/iex"
|
||||
EPMD="{{epmd}}"
|
||||
INSTALLUSER="{{installuser}}"
|
||||
|
||||
# check the proper system user is used if defined
|
||||
if [ "$INSTALLUSER" != "" ] ; then
|
||||
EXEC_CMD="false"
|
||||
for GID in `id -G`; do
|
||||
if [ $GID -eq 0 ] ; then
|
||||
INSTALLUSER_HOME=$(getent passwd "$INSTALLUSER" | cut -d: -f6)
|
||||
if [ -n "$INSTALLUSER_HOME" ] && [ ! -d "$INSTALLUSER_HOME" ] ; then
|
||||
mkdir -p "$INSTALLUSER_HOME"
|
||||
chown "$INSTALLUSER" "$INSTALLUSER_HOME"
|
||||
fi
|
||||
EXEC_CMD="su $INSTALLUSER -c"
|
||||
# check the proper system user is used
|
||||
case $(id -un) in
|
||||
"$INSTALLUSER")
|
||||
EXEC_CMD="as_current_user"
|
||||
;;
|
||||
root)
|
||||
if [ -n "$INSTALLUSER" ] ; then
|
||||
EXEC_CMD="as_install_user"
|
||||
else
|
||||
EXEC_CMD="as_current_user"
|
||||
echo "WARNING: This is not recommended to run ejabberd as root" >&2
|
||||
fi
|
||||
done
|
||||
if [ `id -g` -eq `id -g $INSTALLUSER` ] ; then
|
||||
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="bash -c"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if [ -n "$INSTALLUSER" ] ; then
|
||||
echo "ERROR: This command can only be run by root or the user $INSTALLUSER" >&2
|
||||
exit 7
|
||||
else
|
||||
EXEC_CMD="as_current_user"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# parse command line parameters
|
||||
declare -a ARGS=()
|
||||
while [ $# -ne 0 ] ; do
|
||||
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") ;;
|
||||
for arg; do
|
||||
case $arg in
|
||||
-n|--node) ERLANG_NODE_ARG=$2; shift;;
|
||||
-s|--spool) SPOOL_DIR=$2; shift;;
|
||||
-l|--logs) LOGS_DIR=$2; shift;;
|
||||
-f|--config) EJABBERD_CONFIG_PATH=$2; shift;;
|
||||
-c|--ctl-config) EJABBERDCTL_CONFIG_PATH=$2; shift;;
|
||||
-d|--config-dir) ETC_DIR=$2; shift;;
|
||||
-t|--no-timeout) NO_TIMEOUT="--no-timeout";;
|
||||
--) :;;
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Define ejabberd variable if they have not been defined from the command line
|
||||
if [ "$ETC_DIR" = "" ] ; then
|
||||
ETC_DIR={{sysconfdir}}/ejabberd
|
||||
fi
|
||||
if [ "$EJABBERDCTL_CONFIG_PATH" = "" ] ; then
|
||||
EJABBERDCTL_CONFIG_PATH=$ETC_DIR/ejabberdctl.cfg
|
||||
fi
|
||||
if [ -f "$EJABBERDCTL_CONFIG_PATH" ] ; then
|
||||
. "$EJABBERDCTL_CONFIG_PATH"
|
||||
fi
|
||||
if [ "$EJABBERD_CONFIG_PATH" = "" ] ; then
|
||||
EJABBERD_CONFIG_PATH=$ETC_DIR/ejabberd.yml
|
||||
fi
|
||||
if [ "$LOGS_DIR" = "" ] ; then
|
||||
LOGS_DIR={{localstatedir}}/log/ejabberd
|
||||
fi
|
||||
if [ "$SPOOL_DIR" = "" ] ; then
|
||||
SPOOL_DIR={{localstatedir}}/lib/ejabberd
|
||||
fi
|
||||
if [ "$EJABBERD_DOC_PATH" = "" ] ; then
|
||||
EJABBERD_DOC_PATH={{docdir}}
|
||||
fi
|
||||
if [ "$ERLANG_NODE_ARG" != "" ] ; then
|
||||
ERLANG_NODE=$ERLANG_NODE_ARG
|
||||
fi
|
||||
if [ "{{release}}" != "true" -a "$EJABBERD_BIN_PATH" = "" ] ; then
|
||||
EJABBERD_BIN_PATH={{libdir}}/ejabberd/priv/bin
|
||||
fi
|
||||
EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
|
||||
DATETIME=`date "+%Y%m%d-%H%M%S"`
|
||||
ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump
|
||||
ERL_INETRC=$ETC_DIR/inetrc
|
||||
# define ejabberd variables if not already defined from the command line
|
||||
: "${ETC_DIR:="{{sysconfdir}}/ejabberd"}"
|
||||
: "${LOGS_DIR:="{{localstatedir}}/log/ejabberd"}"
|
||||
: "${SPOOL_DIR:="{{localstatedir}}/lib/ejabberd"}"
|
||||
: "${EJABBERD_CONFIG_PATH:="$ETC_DIR/ejabberd.yml"}"
|
||||
: "${EJABBERDCTL_CONFIG_PATH:="$ETC_DIR/ejabberdctl.cfg"}"
|
||||
[ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
|
||||
[ -n "$ERLANG_NODE_ARG" ] && ERLANG_NODE="$ERLANG_NODE_ARG"
|
||||
[ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && S="-s"
|
||||
: "${EJABBERD_DOC_PATH:="{{docdir}}"}"
|
||||
: "${EJABBERD_LOG_PATH:="$LOGS_DIR/ejabberd.log"}"
|
||||
|
||||
# define mnesia options
|
||||
MNESIA_OPTS="-mnesia dir \"\\\"$SPOOL_DIR\\\"\" $MNESIA_OPTIONS"
|
||||
# define erl parameters
|
||||
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"
|
||||
KERNEL_OPTS=""
|
||||
if [ "$FIREWALL_WINDOW" != "" ] ; then
|
||||
KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
|
||||
if [ -n "$FIREWALL_WINDOW" ] ; then
|
||||
ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
|
||||
fi
|
||||
if [ "$INET_DIST_INTERFACE" != "" ] ; then
|
||||
INET_DIST_INTERFACE2="$(echo $INET_DIST_INTERFACE | sed 's/\./,/g')"
|
||||
if [ "$INET_DIST_INTERFACE" != "$INET_DIST_INTERFACE2" ] ; then
|
||||
INET_DIST_INTERFACE2="{$INET_DIST_INTERFACE2}"
|
||||
if [ -n "$INET_DIST_INTERFACE" ] ; then
|
||||
INET_DIST_INTERFACE2=$("$ERL" -noshell -eval 'case inet:parse_address("'$INET_DIST_INTERFACE'") of {ok,IP} -> io:format("~p",[IP]); _ -> ok end.' -s erlang halt)
|
||||
if [ -n "$INET_DIST_INTERFACE2" ] ; then
|
||||
ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_use_interface $INET_DIST_INTERFACE2"
|
||||
fi
|
||||
KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_use_interface \"${INET_DIST_INTERFACE2}\""
|
||||
fi
|
||||
if [ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] ; then
|
||||
NAME="-sname"
|
||||
else
|
||||
NAME="-name"
|
||||
fi
|
||||
IEXNAME="-$NAME"
|
||||
ERL_LIBS={{libdir}}
|
||||
ERL_CRASH_DUMP="$LOGS_DIR"/erl_crash_$(date "+%Y%m%d-%H%M%S").dump
|
||||
ERL_INETRC="$ETC_DIR"/inetrc
|
||||
|
||||
# define ejabberd environment parameters
|
||||
if [ "$EJABBERD_CONFIG_PATH" != "${EJABBERD_CONFIG_PATH%.yml}" ] ; then
|
||||
rate=$(sed '/^[ ]*log_rate_limit/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
|
||||
rotate=$(sed '/^[ ]*log_rotate_size/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
|
||||
count=$(sed '/^[ ]*log_rotate_count/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
|
||||
date=$(sed '/^[ ]*log_rotate_date/!d;s/.*://;s/ *//' $EJABBERD_CONFIG_PATH)
|
||||
else
|
||||
rate=$(sed '/^[ ]*log_rate_limit/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
|
||||
rotate=$(sed '/^[ ]*log_rotate_size/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
|
||||
count=$(sed '/^[ ]*log_rotate_count/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
|
||||
date=$(sed '/^[ ]*log_rotate_date/!d;s/.*,//;s/ *//;s/}\.//' $EJABBERD_CONFIG_PATH)
|
||||
fi
|
||||
[ -z "$rate" ] || EJABBERD_OPTS="log_rate_limit $rate"
|
||||
[ -z "$rotate" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_size $rotate"
|
||||
[ -z "$count" ] || EJABBERD_OPTS="${EJABBERD_OPTS} log_rotate_count $count"
|
||||
[ -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"
|
||||
# define ejabberd parameters
|
||||
EJABBERD_OPTS="$EJABBERD_OPTS\
|
||||
$(sed '/^log_rate_limit/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
|
||||
$(sed '/^log_rotate_size/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
|
||||
$(sed '/^log_rotate_count/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
|
||||
$(sed '/^log_rotate_date/!d;s/:[ \t]*\(.[^ ]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")"
|
||||
[ -n "$EJABBERD_OPTS" ] && EJABBERD_OPTS="-ejabberd $EJABBERD_OPTS"
|
||||
EJABBERD_OPTS="-mnesia dir \"$SPOOL_DIR\" $MNESIA_OPTIONS $EJABBERD_OPTS -s ejabberd"
|
||||
|
||||
# export global variables
|
||||
export EJABBERD_CONFIG_PATH
|
||||
export EJABBERD_LOG_PATH
|
||||
export EJABBERD_BIN_PATH
|
||||
export EJABBERD_DOC_PATH
|
||||
export EJABBERD_PID_PATH
|
||||
export ERL_CRASH_DUMP
|
||||
@@ -150,116 +106,26 @@ export CONTRIB_MODULES_PATH
|
||||
export CONTRIB_MODULES_CONF_DIR
|
||||
export ERL_LIBS
|
||||
|
||||
shell_escape_str()
|
||||
# run command either directly or via su $INSTALLUSER
|
||||
exec_cmd()
|
||||
{
|
||||
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
|
||||
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
|
||||
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
|
||||
# Elixir shell is hidden as default
|
||||
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
|
||||
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
|
||||
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"
|
||||
case $EXEC_CMD in
|
||||
as_install_user) su -s /bin/sh -c '"$0" "$@"' "$INSTALLUSER" -- "$@" ;;
|
||||
as_current_user) "$@" ;;
|
||||
esac
|
||||
}
|
||||
exec_erl()
|
||||
{
|
||||
NODE=$1; shift
|
||||
exec_cmd "$ERL" ${S:--}name "$NODE" $ERLANG_OPTS "$@"
|
||||
}
|
||||
exec_iex()
|
||||
{
|
||||
NODE=$1; shift
|
||||
exec_cmd "$IEX" -${S:--}name "$NODE" --erl "$ERLANG_OPTS" "$@"
|
||||
}
|
||||
|
||||
# usage
|
||||
debugwarning()
|
||||
{
|
||||
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
|
||||
@@ -279,14 +145,13 @@ debugwarning()
|
||||
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
|
||||
echo " EJABBERD_BYPASS_WARNINGS=true"
|
||||
echo "Press return to continue"
|
||||
read foo
|
||||
read -r input
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
livewarning()
|
||||
{
|
||||
check_start
|
||||
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
|
||||
echo "--------------------------------------------------------------------"
|
||||
echo ""
|
||||
@@ -303,37 +168,11 @@ livewarning()
|
||||
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
|
||||
echo " EJABBERD_BYPASS_WARNINGS=true"
|
||||
echo "Press return to continue"
|
||||
read foo
|
||||
read -r input
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
etop()
|
||||
{
|
||||
NID=$(uid top)
|
||||
$EXEC_CMD "$ERL \
|
||||
$NAME $NID \
|
||||
-hidden -s etop -s erlang halt -output text -node $ERLANG_NODE"
|
||||
}
|
||||
|
||||
ping()
|
||||
{
|
||||
[ -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 \
|
||||
$PING_NAME $NID \
|
||||
-hidden $KERNEL_OPTS $ERLANG_OPTS \
|
||||
-eval 'io:format(\"~p~n\",[net_adm:ping('\"'\"'$PEER'\"'\"')])' \
|
||||
-s erlang halt -output text -noinput"
|
||||
}
|
||||
|
||||
help()
|
||||
{
|
||||
echo ""
|
||||
@@ -355,33 +194,16 @@ help()
|
||||
echo ""
|
||||
}
|
||||
|
||||
# common control function
|
||||
ctl()
|
||||
{
|
||||
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
|
||||
2) help;;
|
||||
3) help;;
|
||||
*) :;;
|
||||
esac
|
||||
return $result
|
||||
}
|
||||
|
||||
# dynamic node name helper
|
||||
uid()
|
||||
{
|
||||
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)$$)
|
||||
[ -z "$uuid" ] && [ -f /proc/sys/kernel/random/uuid ] && uuid=$(cat /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}
|
||||
[ $# -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
|
||||
@@ -391,56 +213,104 @@ stop_epmd()
|
||||
}
|
||||
|
||||
# make sure node not already running and node name unregistered
|
||||
# if all ok, ensure runtime directory exists and make it current directory
|
||||
check_start()
|
||||
{
|
||||
"$EPMD" -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && {
|
||||
ps ux | grep -v grep | grep -q " $ERLANG_NODE " && {
|
||||
pgrep -f "$ERLANG_NODE" >/dev/null && {
|
||||
echo "ERROR: The ejabberd node '$ERLANG_NODE' is already running."
|
||||
exit 4
|
||||
} || {
|
||||
ps ux | grep -v grep | grep -q beam && {
|
||||
echo "ERROR: The ejabberd node '$ERLANG_NODE' is registered,"
|
||||
echo " but no related beam process has been found."
|
||||
echo "Shutdown all other erlang nodes, and call 'epmd -kill'."
|
||||
exit 5
|
||||
} || {
|
||||
"$EPMD" -kill >/dev/null
|
||||
}
|
||||
}
|
||||
pgrep beam >/dev/null && {
|
||||
echo "ERROR: The ejabberd node '$ERLANG_NODE' is registered,"
|
||||
echo " but no related beam process has been found."
|
||||
echo "Shutdown all other erlang nodes, and call 'epmd -kill'."
|
||||
exit 5
|
||||
}
|
||||
"$EPMD" -kill >/dev/null
|
||||
}
|
||||
}
|
||||
|
||||
# allow sync calls
|
||||
wait_for_status()
|
||||
wait_status()
|
||||
{
|
||||
# args: status try delay
|
||||
# return: 0 OK, 1 KO
|
||||
timeout=$2
|
||||
timeout="$2"
|
||||
status=4
|
||||
while [ $status -ne $1 ] ; do
|
||||
sleep $3
|
||||
timeout=`expr $timeout - 1`
|
||||
[ $timeout -eq 0 ] && {
|
||||
status=$1
|
||||
} || {
|
||||
ctl status > /dev/null
|
||||
status=$?
|
||||
}
|
||||
while [ "$status" -ne "$1" ] ; do
|
||||
sleep "$3"
|
||||
timeout=$((timeout - 1))
|
||||
if [ $timeout -eq 0 ] ; then
|
||||
status="$1"
|
||||
else
|
||||
exec_erl "$(uid ctl)" -hidden -noinput -s ejabberd_ctl \
|
||||
-extra "$ERLANG_NODE" $NO_TIMEOUT status > /dev/null
|
||||
status="$?"
|
||||
fi
|
||||
done
|
||||
[ $timeout -eq 0 ] && return 1 || return 0
|
||||
[ $timeout -gt 0 ]
|
||||
}
|
||||
|
||||
# main handler
|
||||
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[@]}";;
|
||||
# ensure we can change current directory to SPOOL_DIR
|
||||
[ -d "$SPOOL_DIR" ] || exec_cmd mkdir -p "$SPOOL_DIR"
|
||||
cd "$SPOOL_DIR" || {
|
||||
echo "ERROR: can not access directory $SPOOL_DIR"
|
||||
exit 6
|
||||
}
|
||||
|
||||
# main
|
||||
case $1 in
|
||||
start)
|
||||
check_start
|
||||
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -noinput -detached
|
||||
;;
|
||||
foreground)
|
||||
check_start
|
||||
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -noinput
|
||||
;;
|
||||
live)
|
||||
livewarning
|
||||
check_start
|
||||
exec_erl "$ERLANG_NODE" $EJABBERD_OPTS
|
||||
;;
|
||||
debug)
|
||||
debugwarning
|
||||
exec_erl "$(uid debug)" -hidden -remsh "$ERLANG_NODE"
|
||||
;;
|
||||
etop)
|
||||
exec_erl "$(uid top)" -hidden -node "$ERLANG_NODE" -s etop \
|
||||
-s erlang halt -output text
|
||||
;;
|
||||
iexdebug)
|
||||
debugwarning
|
||||
exec_iex "$(uid debug)" --remsh "$ERLANG_NODE"
|
||||
;;
|
||||
iexlive)
|
||||
livewarning
|
||||
exec_iex "$ERLANG_NODE" --erl "$EJABBERD_OPTS" --app ejabberd
|
||||
;;
|
||||
ping)
|
||||
PEER=${2:-$ERLANG_NODE}
|
||||
[ "$PEER" = "${PEER%.*}" ] && PS="-s"
|
||||
exec_cmd "$ERL" ${PS:--}name "$(uid ping "$(hostname $PS)")" $ERLANG_OPTS \
|
||||
-noinput -hidden -eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \
|
||||
-s erlang halt -output text
|
||||
;;
|
||||
started)
|
||||
wait_status 0 30 2 # wait 30x2s before timeout
|
||||
;;
|
||||
stopped)
|
||||
wait_status 3 30 2 && stop_epmd # wait 30x2s before timeout
|
||||
;;
|
||||
*)
|
||||
exec_erl "$(uid ctl)" -hidden -noinput -s ejabberd_ctl \
|
||||
-extra "$ERLANG_NODE" $NO_TIMEOUT "$@"
|
||||
result=$?
|
||||
case $result in
|
||||
2|3) help;;
|
||||
*) :;;
|
||||
esac
|
||||
exit $result
|
||||
;;
|
||||
esac
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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
-2
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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
|
||||
@@ -48,4 +48,4 @@
|
||||
-define(HEADER(CType),
|
||||
[CType, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_HEADERS]).
|
||||
|
||||
-define(PROCNAME, ejabberd_mod_bosh).
|
||||
-define(BOSH_CACHE, bosh_cache).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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
|
||||
@@ -33,15 +33,13 @@
|
||||
|
||||
-define(SQL_DIR, filename:join(["priv", "sql"])).
|
||||
|
||||
-define(CONFIG_PATH, <<"ejabberd.cfg">>).
|
||||
-define(CONFIG_PATH, <<"ejabberd.yml">>).
|
||||
|
||||
-define(LOG_PATH, <<"ejabberd.log">>).
|
||||
-define(LOG_PATH, "ejabberd.log").
|
||||
|
||||
-define(EJABBERD_URI, <<"http://www.process-one.net/en/ejabberd/">>).
|
||||
|
||||
-define(COPYRIGHT, "Copyright (c) 2002-2016 ProcessOne").
|
||||
|
||||
-define(S2STIMEOUT, timer:minutes(10)).
|
||||
-define(COPYRIGHT, "Copyright (c) 2002-2017 ProcessOne").
|
||||
|
||||
%%-define(DBGFSM, true).
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
|
||||
-record(challenge, {
|
||||
type = <<"http-01">> :: bitstring(),
|
||||
status = pending :: pending | valid | invalid,
|
||||
uri = "" :: url(),
|
||||
token = <<"">> :: bitstring()
|
||||
}).
|
||||
|
||||
-record(data_acc, {
|
||||
id :: list(),
|
||||
ca_url :: url(),
|
||||
key :: jose_jwk:key()
|
||||
}).
|
||||
-type data_acc() :: #data_acc{}.
|
||||
|
||||
-record(data_cert, {
|
||||
domain :: bitstring(),
|
||||
pem :: pem(),
|
||||
path :: string()
|
||||
}).
|
||||
-type data_cert() :: #data_cert{}.
|
||||
|
||||
%%
|
||||
%% Types
|
||||
%%
|
||||
|
||||
%% Acme configuration
|
||||
-type acme_config() :: [{ca_url, url()} | {contact, bitstring()}].
|
||||
|
||||
%% The main data type that ejabberd_acme keeps
|
||||
-type acme_data() :: proplist().
|
||||
|
||||
%% The list of certificates kept in data
|
||||
-type data_certs() :: proplist(bitstring(), data_cert()).
|
||||
|
||||
%% The certificate saved in pem format
|
||||
-type pem() :: bitstring().
|
||||
|
||||
-type nonce() :: string().
|
||||
-type url() :: string().
|
||||
-type proplist() :: [{_, _}].
|
||||
-type proplist(X,Y) :: [{X,Y}].
|
||||
-type dirs() :: #{string() => url()}.
|
||||
-type jws() :: map().
|
||||
-type handle_resp_fun() :: fun(({ok, proplist(), proplist()}) -> {ok, _, nonce()}).
|
||||
|
||||
-type acme_challenge() :: #challenge{}.
|
||||
|
||||
%% Options
|
||||
-type account_opt() :: string().
|
||||
-type verbose_opt() :: string().
|
||||
-type domains_opt() :: string().
|
||||
|
||||
@@ -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(passwd, {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$1',
|
||||
password = <<"">> :: binary() | scram() | '_'}).
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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-2016 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-2016 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-2016 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-2016 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,5 +22,5 @@
|
||||
token = <<"">> :: binary() | '_',
|
||||
us = {<<"">>, <<"">>} :: {binary(), binary()} | '_',
|
||||
scope = [] :: [binary()] | '_',
|
||||
expire :: integer() | '$1'
|
||||
expire :: integer() | '$1' | '_'
|
||||
}).
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
-define(ROUTES_CACHE, routes_cache).
|
||||
|
||||
-type local_hint() :: integer() | {apply, atom(), atom()}.
|
||||
|
||||
-record(route, {domain :: binary() | '_',
|
||||
server_host :: binary() | '_',
|
||||
pid :: undefined | pid(),
|
||||
local_hint :: local_hint() | undefined | '_'}).
|
||||
+24
-1
@@ -1,13 +1,36 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% 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).
|
||||
|
||||
-define(SM_CACHE, sm_cache).
|
||||
|
||||
-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()}
|
||||
| {num_stanzas_in, non_neg_integer()}].
|
||||
| {num_stanzas_in, non_neg_integer()}
|
||||
| offline].
|
||||
-type prio() :: undefined | integer().
|
||||
|
||||
-endif.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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
|
||||
@@ -27,6 +27,9 @@
|
||||
-define(SQL_UPSERT_T(Table, Fields),
|
||||
ejabberd_sql:sql_query_t(?SQL_UPSERT_MARK(Table, Fields))).
|
||||
|
||||
-define(SQL_INSERT_MARK, sql_insert__mark_).
|
||||
-define(SQL_INSERT(Table, Fields), ?SQL_INSERT_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-2016 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
-2
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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
|
||||
@@ -27,7 +27,7 @@
|
||||
-record(eldap_search,
|
||||
{scope = wholeSubtree :: scope(),
|
||||
base = <<"">> :: binary(),
|
||||
filter :: eldap:filter(),
|
||||
filter :: eldap:filter() | undefined,
|
||||
limit = 0 :: non_neg_integer(),
|
||||
attributes = [] :: [binary()],
|
||||
types_only = false :: boolean(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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
|
||||
|
||||
+9
-9
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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
|
||||
@@ -471,15 +471,15 @@
|
||||
|
||||
-type(iq() :: iq_request() | iq_reply()).
|
||||
|
||||
-record(rsm_in, {max :: integer() | error,
|
||||
direction :: before | aft,
|
||||
id :: binary(),
|
||||
index :: integer() | error}).
|
||||
-record(rsm_in, {max :: integer() | error | undefined,
|
||||
direction :: before | aft | undefined,
|
||||
id :: binary() | undefined,
|
||||
index :: integer() | error | undefined}).
|
||||
|
||||
-record(rsm_out, {count :: integer(),
|
||||
index :: integer(),
|
||||
first :: binary(),
|
||||
last :: binary()}).
|
||||
-record(rsm_out, {count :: integer() | undefined,
|
||||
index :: integer() | undefined,
|
||||
first :: binary() | undefined,
|
||||
last :: binary() | undefined}).
|
||||
|
||||
-type(rsm_in() :: #rsm_in{}).
|
||||
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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,6 +17,7 @@
|
||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-define(PRINT(Format, Args), io:format(Format, Args)).
|
||||
-compile([{parse_transform, lager_transform}]).
|
||||
|
||||
|
||||
@@ -1,3 +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(motd, {server = <<"">> :: binary(),
|
||||
packet = #xmlel{} :: xmlel()}).
|
||||
|
||||
|
||||
@@ -1,3 +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(caps_features,
|
||||
{node_pair = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
features = [] :: [binary()] | pos_integer()
|
||||
|
||||
@@ -1,4 +1,27 @@
|
||||
-type matchspec_atom() :: '_' | '$1' | '$2' | '$3'.
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% 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' | '$4'.
|
||||
-record(carboncopy, {us :: {binary(), binary()} | matchspec_atom(),
|
||||
resource :: binary() | matchspec_atom(),
|
||||
version :: binary() | matchspec_atom()}).
|
||||
version :: binary() | matchspec_atom(),
|
||||
node = node() :: node() | matchspec_atom()}).
|
||||
|
||||
-define(CARBONCOPY_CACHE, carboncopy_cache).
|
||||
|
||||
@@ -1,3 +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.
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-type conn_param() :: {binary(), binary(), inet:port_number(), binary()} |
|
||||
{binary(), binary(), inet:port_number()} |
|
||||
{binary(), binary()} |
|
||||
|
||||
@@ -1,3 +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()}).
|
||||
|
||||
@@ -1,3 +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(archive_msg,
|
||||
{us = {<<"">>, <<"">>} :: {binary(), binary()} | '$2',
|
||||
id = <<>> :: binary() | '_',
|
||||
|
||||
+10
-7
@@ -1,7 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : mod_muc.hrl
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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
|
||||
@@ -23,11 +22,15 @@
|
||||
{'_', 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()}).
|
||||
|
||||
-record(muc_online_room,
|
||||
{name_host :: {binary(), binary()} | '$1' | {'_', binary()} | '_',
|
||||
pid :: pid() | '$2' | '_' | '$1'}).
|
||||
|
||||
-record(muc_online_users, {us :: {binary(), binary()},
|
||||
resource :: binary() | '_',
|
||||
room :: binary() | '_' | '$1',
|
||||
host :: binary() | '_' | '$2'}).
|
||||
|
||||
+12
-19
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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
|
||||
@@ -28,9 +28,8 @@
|
||||
|
||||
-record(lqueue,
|
||||
{
|
||||
queue :: ?TQUEUE,
|
||||
len :: integer(),
|
||||
max :: integer()
|
||||
queue :: p1_queue:queue(),
|
||||
max = 0 :: integer()
|
||||
}).
|
||||
|
||||
-type lqueue() :: #lqueue{}.
|
||||
@@ -65,7 +64,8 @@
|
||||
logging = false :: boolean(),
|
||||
vcard = <<"">> :: binary(),
|
||||
captcha_whitelist = (?SETS):empty() :: ?TGB_SET,
|
||||
mam = false :: boolean()
|
||||
mam = false :: boolean(),
|
||||
pubsub = <<"">> :: binary()
|
||||
}).
|
||||
|
||||
-type config() :: #config{}.
|
||||
@@ -80,7 +80,7 @@
|
||||
role :: role(),
|
||||
%%is_subscriber = false :: boolean(),
|
||||
%%subscriptions = [] :: [binary()],
|
||||
last_presence :: xmlel()
|
||||
last_presence :: presence() | undefined
|
||||
}).
|
||||
|
||||
-record(subscriber, {jid :: jid(),
|
||||
@@ -91,10 +91,10 @@
|
||||
{
|
||||
message_time = 0 :: integer(),
|
||||
presence_time = 0 :: integer(),
|
||||
message_shaper :: shaper:shaper(),
|
||||
presence_shaper :: shaper:shaper(),
|
||||
message :: xmlel(),
|
||||
presence :: {binary(), xmlel()}
|
||||
message_shaper = none :: shaper:shaper(),
|
||||
presence_shaper = none :: shaper:shaper(),
|
||||
message :: message() | undefined,
|
||||
presence :: {binary(), presence()} | undefined
|
||||
}).
|
||||
|
||||
-record(state,
|
||||
@@ -113,17 +113,10 @@
|
||||
nicks = (?DICT):new() :: ?TDICT,
|
||||
affiliations = (?DICT):new() :: ?TDICT,
|
||||
history :: lqueue(),
|
||||
subject = <<"">> :: binary(),
|
||||
subject = [] :: [text()],
|
||||
subject_author = <<"">> :: binary(),
|
||||
just_created = false :: boolean(),
|
||||
activity = treap:empty() :: treap:treap(),
|
||||
room_shaper = none :: shaper:shaper(),
|
||||
room_queue = queue:new() :: ?TQUEUE
|
||||
room_queue :: p1_queue:queue() | undefined
|
||||
}).
|
||||
|
||||
-record(muc_online_users, {us = {<<>>, <<>>} :: {binary(), binary()},
|
||||
resource = <<>> :: binary() | '_',
|
||||
room = <<>> :: binary() | '_' | '$1',
|
||||
host = <<>> :: binary() | '_' | '$2'}).
|
||||
|
||||
-type muc_online_users() :: #muc_online_users{}.
|
||||
|
||||
+23
-3
@@ -1,10 +1,30 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% 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 | '_',
|
||||
timestamp :: erlang:timestamp() | '_' | undefined,
|
||||
expire :: erlang:timestamp() | never | undefined | '_',
|
||||
from = #jid{} :: jid() | '_',
|
||||
to = #jid{} :: jid() | '_',
|
||||
packet = #xmlel{} :: xmlel() | '_'}).
|
||||
packet = #xmlel{} :: xmlel() | message() | '_'}).
|
||||
|
||||
-record(state,
|
||||
{host = <<"">> :: binary(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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
|
||||
@@ -38,11 +38,3 @@
|
||||
-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()],
|
||||
needdb = false :: boolean()}).
|
||||
|
||||
-type userlist() :: #userlist{}.
|
||||
|
||||
-export_type([userlist/0]).
|
||||
|
||||
@@ -1,3 +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(private_storage,
|
||||
{usns = {<<"">>, <<"">>, <<"">>} :: {binary(), binary(), binary() |
|
||||
'$1' | '_'},
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
%%% RFC 1928 constants.
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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,24 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% ejabberd, Copyright (C) 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(push_session,
|
||||
{us = {<<"">>, <<"">>} :: {binary(), binary()},
|
||||
timestamp = p1_time_compat:timestamp() :: erlang:timestamp(),
|
||||
service = {<<"">>, <<"">>, <<"">>} :: ljid(),
|
||||
node = <<"">> :: binary(),
|
||||
xml :: undefined | xmlel()}).
|
||||
@@ -1,6 +1,6 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2016 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,3 +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(sr_group, {group_host = {<<"">>, <<"">>} :: {'$1' | binary(), '$2' | binary()},
|
||||
opts = [] :: list() | '_' | '$2'}).
|
||||
|
||||
|
||||
@@ -1,3 +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(vcard_search,
|
||||
{us, user, luser, fn, lfn, family, lfamily, given,
|
||||
lgiven, middle, lmiddle, nickname, lnickname, bday,
|
||||
|
||||
@@ -1,2 +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()}).
|
||||
|
||||
+17
-27
@@ -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-2016, ProcessOne
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2016, 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-2016 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").
|
||||
|
||||
@@ -109,13 +104,6 @@
|
||||
).
|
||||
%% @type affiliation() = 'none' | 'owner' | 'publisher' | 'publish-only' | 'member' | 'outcast'.
|
||||
|
||||
-type(subscription() :: 'none'
|
||||
| 'pending'
|
||||
| 'unconfigured'
|
||||
| 'subscribed'
|
||||
).
|
||||
%% @type subscription() = 'none' | 'pending' | 'unconfigured' | 'subscribed'.
|
||||
|
||||
-type(accessModel() :: 'open'
|
||||
| 'presence'
|
||||
| 'roster'
|
||||
@@ -150,6 +138,7 @@
|
||||
-record(pubsub_state,
|
||||
{
|
||||
stateid ,% :: {jlib:ljid(), mod_pubsub:nodeIdx()},
|
||||
nodeidx ,% :: mod_pubsub:nodeIdx(),
|
||||
items = [] ,% :: [mod_pubsub:itemId(),...],
|
||||
affiliation = 'none',% :: mod_pubsub:affiliation(),
|
||||
subscriptions = [] % :: [{mod_pubsub:subscription(), mod_pubsub:subId()}]
|
||||
@@ -158,6 +147,7 @@
|
||||
-record(pubsub_item,
|
||||
{
|
||||
itemid ,% :: {mod_pubsub:itemId(), mod_pubsub:nodeIdx()},
|
||||
nodeidx ,% :: mod_pubsub:nodeIdx(),
|
||||
creation = {unknown, unknown},% :: {erlang:timestamp(), jlib:ljid()},
|
||||
modification = {unknown, unknown},% :: {erlang:timestamp(), jlib:ljid()},
|
||||
payload = [] % :: mod_pubsub:payload()
|
||||
@@ -171,7 +161,7 @@
|
||||
|
||||
-record(pubsub_last_item,
|
||||
{
|
||||
nodeid ,% :: mod_pubsub:nodeIdx(),
|
||||
nodeid ,% :: {binary(), mod_pubsub:nodeIdx()},
|
||||
itemid ,% :: mod_pubsub:itemId(),
|
||||
creation ,% :: {erlang:timestamp(), jlib:ljid()},
|
||||
payload % :: mod_pubsub:payload()
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
-define(T(S), <<S>>).
|
||||
@@ -3,18 +3,18 @@ defmodule Ejabberd.Mixfile do
|
||||
|
||||
def project do
|
||||
[app: :ejabberd,
|
||||
version: "16.12.0",
|
||||
description: description,
|
||||
elixir: "~> 1.3",
|
||||
version: "17.12.0",
|
||||
description: description(),
|
||||
elixir: "~> 1.4",
|
||||
elixirc_paths: ["lib"],
|
||||
compile_path: ".",
|
||||
compilers: [:asn1] ++ Mix.compilers,
|
||||
erlc_options: erlc_options,
|
||||
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]
|
||||
package: package(),
|
||||
deps: deps()]
|
||||
end
|
||||
|
||||
def description do
|
||||
@@ -25,39 +25,62 @@ defmodule Ejabberd.Mixfile do
|
||||
|
||||
def application do
|
||||
[mod: {:ejabberd_app, []},
|
||||
applications: [:ssl],
|
||||
included_applications: [:lager, :mnesia, :p1_utils, :cache_tab,
|
||||
applications: [:ssl, :os_mon],
|
||||
included_applications: [:lager, :mnesia, :inets, :p1_utils, :cache_tab,
|
||||
:fast_tls, :stringprep, :fast_xml, :xmpp,
|
||||
:stun, :fast_yaml, :esip, :jiffy, :p1_oauth2]
|
||||
++ cond_apps]
|
||||
:stun, :fast_yaml, :esip, :jiffy, :p1_oauth2, :fs]
|
||||
++ cond_apps()]
|
||||
end
|
||||
|
||||
defp if_function_exported(mod, fun, arity, okResult) do
|
||||
:code.ensure_loaded(mod)
|
||||
if :erlang.function_exported(mod, fun, arity) do
|
||||
okResult
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
defp erlc_options do
|
||||
# Use our own includes + includes from all dependencies
|
||||
includes = ["include"] ++ deps_include(["fast_xml", "xmpp"])
|
||||
[:debug_info, {:d, :ELIXIR_ENABLED}] ++ Enum.map(includes, fn(path) -> {:i, path} end)
|
||||
includes = ["include"] ++ deps_include(["fast_xml", "xmpp", "p1_utils"])
|
||||
[:debug_info, {:d, :ELIXIR_ENABLED}] ++ cond_options() ++ Enum.map(includes, fn(path) -> {:i, path} end) ++
|
||||
if_function_exported(:crypto, :strong_rand_bytes, 1, [{:d, :STRONG_RAND_BYTES}]) ++
|
||||
if_function_exported(:rand, :uniform, 1, [{:d, :RAND_UNIFORM}]) ++
|
||||
if_function_exported(:gb_sets, :iterator_from, 2, [{:d, :GB_SETS_ITERATOR_FROM}]) ++
|
||||
if_function_exported(:public_key, :short_name_hash, 1, [{:d, :SHORT_NAME_HASH}])
|
||||
end
|
||||
|
||||
defp cond_options do
|
||||
for {:true, option} <- [{config(:graphics), {:d, :GRAPHICS}}], do:
|
||||
option
|
||||
end
|
||||
|
||||
defp deps do
|
||||
[{:lager, "~> 3.2"},
|
||||
[{:lager, "~> 3.4.0"},
|
||||
{:p1_utils, "~> 1.0"},
|
||||
{:fast_xml, "~> 1.1", manager: :rebar},
|
||||
{:xmpp, "~> 1.1"},
|
||||
{: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"},
|
||||
{:stun, github: "processone/stun", tag: "1.0.17", override: true, manager: :rebar},
|
||||
{:esip, github: "processone/esip", tag: "1.0.18", override: true, manager: :rebar},
|
||||
{:jiffy, "~> 0.14.7"},
|
||||
{:p1_oauth2, "~> 0.6.1"},
|
||||
{:distillery, "~> 1.0"},
|
||||
{:ex_doc, ">= 0.0.0", only: :dev}]
|
||||
++ cond_deps
|
||||
{:ex_doc, ">= 0.0.0", only: :dev},
|
||||
{:fs, "~> 2.12.0"}]
|
||||
++ cond_deps()
|
||||
end
|
||||
|
||||
defp deps_include(deps) do
|
||||
Enum.map(deps, fn dep -> "deps/#{dep}/include" end)
|
||||
base = case Mix.Project.deps_paths()[:ejabberd] do
|
||||
nil -> "deps"
|
||||
_ -> ".."
|
||||
end
|
||||
Enum.map(deps, fn dep -> base<>"/#{dep}/include" end)
|
||||
end
|
||||
|
||||
defp cond_deps do
|
||||
@@ -66,12 +89,13 @@ defmodule Ejabberd.Mixfile do
|
||||
{config(:sqlite), {:sqlite3, "~> 1.1"}},
|
||||
{config(:riak), {:riakc, "~> 2.4"}},
|
||||
{config(:redis), {:eredis, "~> 1.0"}},
|
||||
{config(:zlib), {:ezlib, "~> 1.0"}},
|
||||
{config(:zlib), {:ezlib, github: "processone/ezlib", tag: "1.0.3", override: true, manager: :rebar}},
|
||||
{config(:iconv), {:iconv, "~> 1.0"}},
|
||||
{config(:pam), {:p1_pam, "~> 1.0"}},
|
||||
{config(:pam), {:epam, "~> 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:
|
||||
{config(:tools), {:moka, github: "processone/moka", tag: "1.0.5c"}},
|
||||
{config(:graphics), {:eimp, github: "processone/eimp", tag: "1.0.1"}}], do:
|
||||
dep
|
||||
end
|
||||
|
||||
@@ -81,11 +105,12 @@ defmodule Ejabberd.Mixfile do
|
||||
{config(:pgsql), :p1_pgsql},
|
||||
{config(:sqlite), :sqlite3},
|
||||
{config(:zlib), :ezlib},
|
||||
{config(:iconv), :iconv}], do:
|
||||
{config(:iconv), :iconv},
|
||||
{config(:graphics), :eimp}], do:
|
||||
app
|
||||
end
|
||||
|
||||
def package do
|
||||
defp package do
|
||||
[# These are the default files included in the package
|
||||
files: ["lib", "src", "priv", "mix.exs", "include", "README.md", "COPYING"],
|
||||
maintainers: ["ProcessOne"],
|
||||
@@ -96,7 +121,7 @@ defmodule Ejabberd.Mixfile do
|
||||
"ProcessOne" => "http://www.process-one.net/"}]
|
||||
end
|
||||
|
||||
def vars do
|
||||
defp vars do
|
||||
case :file.consult("vars.config") do
|
||||
{:ok,config} -> config
|
||||
_ -> [zlib: true, iconv: true]
|
||||
@@ -104,7 +129,7 @@ defmodule Ejabberd.Mixfile do
|
||||
end
|
||||
|
||||
defp config(key) do
|
||||
case vars[key] do
|
||||
case vars()[key] do
|
||||
nil -> false
|
||||
value -> value
|
||||
end
|
||||
@@ -128,7 +153,12 @@ defmodule Mix.Tasks.Compile.Asn1 do
|
||||
mappings = Enum.zip(source_paths, dest_paths)
|
||||
options = project[:asn1_options] || []
|
||||
|
||||
Erlang.compile(manifest(), mappings, :asn1, :erl, opts[:force], fn
|
||||
force = case opts[:force] do
|
||||
:true -> [force: true]
|
||||
_ -> [force: false]
|
||||
end
|
||||
|
||||
Erlang.compile(manifest(), mappings, :asn1, :erl, force, fn
|
||||
input, output ->
|
||||
options = options ++ [:noobj, outdir: Erlang.to_erl_file(Path.dirname(output))]
|
||||
case :asn1ct.compile(Erlang.to_erl_file(input), options) do
|
||||
@@ -138,7 +168,7 @@ defmodule Mix.Tasks.Compile.Asn1 do
|
||||
end)
|
||||
end
|
||||
|
||||
def manifests, do: [manifest]
|
||||
def manifests, do: [manifest()]
|
||||
defp manifest, do: Path.join(Mix.Project.manifest_path, @manifest)
|
||||
|
||||
def clean, do: Erlang.clean(manifest())
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
%{"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]}]}}
|
||||
%{"cache_tab": {:hex, :cache_tab, "1.0.12", "a06a4ffbd4da8469791ba941512a6a45ed8c11865b4606a368e21b332da3638a", [:rebar3], [{:p1_utils, "1.0.10", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"distillery": {:hex, :distillery, "1.5.2", "eec18b2d37b55b0bcb670cf2bcf64228ed38ce8b046bb30a9b636a6f5a4c0080", [:mix], [], "hexpm"},
|
||||
"earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], [], "hexpm"},
|
||||
"eimp": {:git, "https://github.com/processone/eimp.git", "23796118176be98195db9f831f17dde74d1553e1", [tag: "1.0.1"]},
|
||||
"eredis": {:hex, :eredis, "1.1.0", "8d8d74496f35216679b97726b75fb1c8715e99dd7f3ef9f9824a2264c3e0aac0", [:rebar3], [], "hexpm"},
|
||||
"esip": {:git, "https://github.com/processone/esip.git", "7f33f6ed81a058d151912d417c874a9ea87b0470", [tag: "1.0.18"]},
|
||||
"ex_doc": {:hex, :ex_doc, "0.18.1", "37c69d2ef62f24928c1f4fdc7c724ea04aecfdf500c4329185f8e3649c915baf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"ezlib": {:git, "https://github.com/processone/ezlib.git", "ec6491d788436bb096022843e6ec7f58d2973ae3", [tag: "1.0.3"]},
|
||||
"fast_tls": {:hex, :fast_tls, "1.0.18", "8be28c77ff1c1123e436cacaac39f850ea14a588abc09205b2813c5cb610d784", [], [{:p1_utils, "1.0.10", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"fast_xml": {:hex, :fast_xml, "1.1.26", "ffa4e0ab68b44f1f9eb7a93b04f2563825cada881c010dfc0586979ac1edf7d0", [], [{:p1_utils, "1.0.10", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"fast_yaml": {:hex, :fast_yaml, "1.0.12", "ee8527d388255cf7a24fc1e6cb2d09dca4e506966dd9d86e61d3d90f236a3e2e", [], [{:p1_utils, "1.0.10", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"fs": {:hex, :fs, "2.12.0", "ad631efacc9a5683c8eaa1b274e24fa64a1b8eb30747e9595b93bec7e492e25e", [:rebar3], [], "hexpm"},
|
||||
"goldrush": {:hex, :goldrush, "0.1.9", "f06e5d5f1277da5c413e84d5a2924174182fb108dabb39d5ec548b27424cd106", [:rebar3], [], "hexpm"},
|
||||
"hamcrest": {:hex, :basho_hamcrest, "0.4.1", "fb7b2c92d252a1e9db936750b86089addaebeb8f87967fb4bbdda61e8863338e", [:make, :mix, :rebar3], [], "hexpm"},
|
||||
"iconv": {:hex, :iconv, "1.0.6", "3b424a80039059767f1037dc6a49ff07c2f88df14068c16dc938c4f377a77b4c", [:rebar3], [{:p1_utils, "1.0.10", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"jiffy": {:hex, :jiffy, "0.14.11", "919a87d491c5a6b5e3bbc27fafedc3a0761ca0b4c405394f121f582fd4e3f0e5", [:rebar3], [], "hexpm"},
|
||||
"lager": {:hex, :lager, "3.4.2", "150b9a17b23ae6d3265cc10dc360747621cf217b7a22b8cddf03b2909dbf7aa5", [:rebar3], [{:goldrush, "0.1.9", [hex: :goldrush, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"p1_mysql": {:hex, :p1_mysql, "1.0.4", "7b9d7957a9d031813a0e6bcea5a7f5e91b54db805a92709a445cf75cf934bc1d", [:rebar3], [], "hexpm"},
|
||||
"p1_oauth2": {:hex, :p1_oauth2, "0.6.2", "cc381038920e3d34ef32aa10ba7eb637bdff38a946748c4fd99329ff484a3889", [:rebar3], [], "hexpm"},
|
||||
"p1_pgsql": {:hex, :p1_pgsql, "1.1.4", "eadbbddee8d52145694bf86bdfe8c1ae8353a55e152410146b8c2711756d6041", [:rebar3], [], "hexpm"},
|
||||
"p1_utils": {:hex, :p1_utils, "1.0.10", "a6d6927114bac79cf6468a10824125492034af7071adc6ed5ebc4ddb443845d4", [:rebar3], [], "hexpm"},
|
||||
"riak_pb": {:hex, :riak_pb, "2.3.2", "48ffbf66dbb3f136ab9a7134bac4e496754baa5ef58c4f50a61326736d996390", [:make, :mix, :rebar3], [{:hamcrest, "~> 0.4.1", [hex: :basho_hamcrest, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"riakc": {:hex, :riakc, "2.5.3", "6132d9e687a0dfd314b2b24c4594302ca8b55568a5d733c491d8fb6cd4004763", [:make, :mix, :rebar3], [{:riak_pb, "~> 2.3", [hex: :riak_pb, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"sqlite3": {:hex, :sqlite3, "1.1.5", "794738b6d07b6d36ec6d42492cb9d629bad9cf3761617b8b8d728e765db19840", [:rebar3], [], "hexpm"},
|
||||
"stringprep": {:hex, :stringprep, "1.0.10", "552d784eb60652220fce9131f8bb0ebc62fdffd6482c4f08f2e7d61300227c28", [:rebar3], [{:p1_utils, "1.0.10", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"stun": {:git, "https://github.com/processone/stun.git", "b4d3fe315f46ae6ad16f4dc0bfe0a3ebb6e3aee6", [tag: "1.0.17"]},
|
||||
"xmpp": {:hex, :xmpp, "1.1.17", "d4a6dcd3de7ddbe40f8a2ee1fff0d5e88314bbd90e783f1cbdc6b8e093e96a50", [:rebar3], [{:fast_xml, "1.1.26", [hex: :fast_xml, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.10", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stringprep, "1.0.10", [hex: :stringprep, repo: "hexpm", optional: false]}], "hexpm"}}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
-module(override_deps_versions).
|
||||
-export([preprocess/2, 'pre_update-deps'/2, new_replace/1, new_replace/0]).
|
||||
|
||||
preprocess(Config, _Dirs) ->
|
||||
update_deps(Config).
|
||||
|
||||
update_deps(Config) ->
|
||||
LocalDeps = rebar_config:get_local(Config, deps, []),
|
||||
TopDeps = case rebar_config:get_xconf(Config, top_deps, []) of
|
||||
[] -> LocalDeps;
|
||||
Val -> Val
|
||||
end,
|
||||
Config2 = rebar_config:set_xconf(Config, top_deps, TopDeps),
|
||||
NewDeps = lists:map(fun({Name, _, _} = Dep) ->
|
||||
case lists:keyfind(Name, 1, TopDeps) of
|
||||
false -> Dep;
|
||||
TopDep -> TopDep
|
||||
end
|
||||
end, LocalDeps),
|
||||
%io:format("LD ~p~n", [LocalDeps]),
|
||||
%io:format("TD ~p~n", [TopDeps]),
|
||||
|
||||
Config3 = rebar_config:set(Config2, deps, NewDeps),
|
||||
{ok, Config3, []}.
|
||||
|
||||
|
||||
'pre_update-deps'(Config, _Dirs) ->
|
||||
{ok, Config2, _} = update_deps(Config),
|
||||
|
||||
case code:is_loaded(old_rebar_config) of
|
||||
false ->
|
||||
{_, Beam, _} = code:get_object_code(rebar_config),
|
||||
NBeam = rename(Beam, old_rebar_config),
|
||||
code:load_binary(old_rebar_config, "blank", NBeam),
|
||||
replace_mod(Beam);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
{ok, Config2}.
|
||||
|
||||
new_replace() ->
|
||||
old_rebar_config:new().
|
||||
new_replace(Config) ->
|
||||
NC = old_rebar_config:new(Config),
|
||||
{ok, Conf, _} = update_deps(NC),
|
||||
Conf.
|
||||
|
||||
replace_mod(Beam) ->
|
||||
{ok, {_, [{exports, Exports}]}} = beam_lib:chunks(Beam, [exports]),
|
||||
Funcs = lists:filtermap(
|
||||
fun({module_info, _}) ->
|
||||
false;
|
||||
({Name, Arity}) ->
|
||||
Args = args(Arity),
|
||||
Call = case Name of
|
||||
new ->
|
||||
[erl_syntax:application(
|
||||
erl_syntax:abstract(override_deps_versions),
|
||||
erl_syntax:abstract(new_replace),
|
||||
Args)];
|
||||
_ ->
|
||||
[erl_syntax:application(
|
||||
erl_syntax:abstract(old_rebar_config),
|
||||
erl_syntax:abstract(Name),
|
||||
Args)]
|
||||
end,
|
||||
{true, erl_syntax:function(erl_syntax:abstract(Name),
|
||||
[erl_syntax:clause(Args, none,
|
||||
Call)])}
|
||||
end, Exports),
|
||||
Forms0 = ([erl_syntax:attribute(erl_syntax:abstract(module),
|
||||
[erl_syntax:abstract(rebar_config)])]
|
||||
++ Funcs),
|
||||
Forms = [erl_syntax:revert(Form) || Form <- Forms0],
|
||||
%io:format("--------------------------------------------------~n"
|
||||
% "~s~n",
|
||||
% [[erl_pp:form(Form) || Form <- Forms]]),
|
||||
{ok, Mod, Bin} = compile:forms(Forms, [report, export_all]),
|
||||
code:purge(rebar_config),
|
||||
{module, Mod} = code:load_binary(rebar_config, "mock", Bin).
|
||||
|
||||
|
||||
args(0) ->
|
||||
[];
|
||||
args(N) ->
|
||||
[arg(N) | args(N-1)].
|
||||
|
||||
arg(N) ->
|
||||
erl_syntax:variable(list_to_atom("A"++integer_to_list(N))).
|
||||
|
||||
rename(BeamBin0, Name) ->
|
||||
BeamBin = replace_in_atab(BeamBin0, Name),
|
||||
update_form_size(BeamBin).
|
||||
|
||||
%% Replace the first atom of the atom table with the new name
|
||||
replace_in_atab(<<"Atom", CnkSz0:32, Cnk:CnkSz0/binary, Rest/binary>>, Name) ->
|
||||
replace_first_atom(<<"Atom">>, Cnk, CnkSz0, Rest, latin1, Name);
|
||||
replace_in_atab(<<"AtU8", CnkSz0:32, Cnk:CnkSz0/binary, Rest/binary>>, Name) ->
|
||||
replace_first_atom(<<"AtU8">>, Cnk, CnkSz0, Rest, unicode, Name);
|
||||
replace_in_atab(<<C, Rest/binary>>, Name) ->
|
||||
<<C, (replace_in_atab(Rest, Name))/binary>>.
|
||||
|
||||
replace_first_atom(CnkName, Cnk, CnkSz0, Rest, Encoding, Name) ->
|
||||
<<NumAtoms:32, NameSz0:8, _Name0:NameSz0/binary, CnkRest/binary>> = Cnk,
|
||||
NumPad0 = num_pad_bytes(CnkSz0),
|
||||
<<_:NumPad0/unit:8, NextCnks/binary>> = Rest,
|
||||
NameBin = atom_to_binary(Name, Encoding),
|
||||
NameSz = byte_size(NameBin),
|
||||
CnkSz = CnkSz0 + NameSz - NameSz0,
|
||||
NumPad = num_pad_bytes(CnkSz),
|
||||
<<CnkName/binary, CnkSz:32, NumAtoms:32, NameSz:8, NameBin:NameSz/binary,
|
||||
CnkRest/binary, 0:NumPad/unit:8, NextCnks/binary>>.
|
||||
|
||||
|
||||
%% Calculate the number of padding bytes that have to be added for the
|
||||
%% BinSize to be an even multiple of ?beam_num_bytes_alignment.
|
||||
num_pad_bytes(BinSize) ->
|
||||
case 4 - (BinSize rem 4) of
|
||||
4 -> 0;
|
||||
N -> N
|
||||
end.
|
||||
|
||||
%% Update the size within the top-level form
|
||||
update_form_size(<<"FOR1", _OldSz:32, Rest/binary>> = Bin) ->
|
||||
Sz = size(Bin) - 8,
|
||||
<<"FOR1", Sz:32, Rest/binary>>.
|
||||
@@ -0,0 +1,36 @@
|
||||
-module(override_opts).
|
||||
-export([preprocess/2]).
|
||||
|
||||
override_opts(override, Config, Opts) ->
|
||||
lists:foldl(fun({Opt, Value}, Conf) ->
|
||||
rebar_config:set(Conf, Opt, Value)
|
||||
end, Config, Opts);
|
||||
override_opts(add, Config, Opts) ->
|
||||
lists:foldl(fun({Opt, Value}, Conf) ->
|
||||
V = rebar_config:get_local(Conf, Opt, []),
|
||||
rebar_config:set(Conf, Opt, [Value | V])
|
||||
end, Config, Opts).
|
||||
|
||||
preprocess(Config, _Dirs) ->
|
||||
Overrides = rebar_config:get_local(Config, overrides, []),
|
||||
TopOverrides = case rebar_config:get_xconf(Config, top_overrides, []) of
|
||||
[] -> Overrides;
|
||||
Val -> Val
|
||||
end,
|
||||
Config2 = rebar_config:set_xconf(Config, top_overrides, TopOverrides),
|
||||
try
|
||||
Config3 = case rebar_app_utils:load_app_file(Config2, _Dirs) of
|
||||
{ok, C, AppName, _AppData} ->
|
||||
lists:foldl(fun({Type, AppName2, Opts}, Conf1) when
|
||||
AppName2 == AppName ->
|
||||
override_opts(Type, Conf1, Opts);
|
||||
(_, Conf2) ->
|
||||
Conf2
|
||||
end, C, TopOverrides);
|
||||
_ ->
|
||||
Config2
|
||||
end,
|
||||
{ok, Config3, []}
|
||||
catch
|
||||
error:badarg -> {ok, Config2, []}
|
||||
end.
|
||||
@@ -0,0 +1,279 @@
|
||||
html,body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
background: #f9f9f9;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
body {
|
||||
min-width: 990px;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #3eaffa;
|
||||
}
|
||||
a:hover,
|
||||
a:active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
#container {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
margin: 0 auto;
|
||||
max-width: 1280px;
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
margin-bottom: -30px;
|
||||
z-index: 1;
|
||||
}
|
||||
html>body #container {
|
||||
height: auto;
|
||||
}
|
||||
#header h1 {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background-color: #49cbc1;
|
||||
}
|
||||
#header h1 a {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: url('@BASE@logo.png') 10px center no-repeat transparent;
|
||||
background-size: auto 25px;
|
||||
display: block;
|
||||
text-indent: -9999px;
|
||||
}
|
||||
#clearcopyright {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
}
|
||||
#copyrightouter {
|
||||
position: relative;
|
||||
display: table;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
z-index: 2;
|
||||
}
|
||||
#copyright {
|
||||
display: table-cell;
|
||||
vertical-align: bottom;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
}
|
||||
#copyright a {
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
}
|
||||
#copyright p {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
background-color: #30353E;
|
||||
font-size: 0.75em;
|
||||
text-align: center;
|
||||
}
|
||||
#navigation {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 30%;
|
||||
}
|
||||
#navigation ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 90%;
|
||||
background: #fff;
|
||||
}
|
||||
#navigation ul li {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
|
||||
border-bottom: 1px solid #f9f9f9;
|
||||
text-align: left;
|
||||
}
|
||||
#navigation ul li a {
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
color: #333;
|
||||
}
|
||||
ul li #navhead a, ul li #navheadsub a, ul li #navheadsubsub a {
|
||||
font-size: 1.5em;
|
||||
color: inherit;
|
||||
}
|
||||
#navitemsub {
|
||||
border-left: 0.5em solid #424a55;
|
||||
}
|
||||
#navitemsubsub {
|
||||
border-left: 2em solid #424a55;
|
||||
}
|
||||
#navheadsub,
|
||||
#navheadsubsub {
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
#navhead,
|
||||
#navheadsub,
|
||||
#navheadsubsub {
|
||||
border-top: 3px solid #49cbc1;
|
||||
background: #424a55;
|
||||
color: #fff;
|
||||
}
|
||||
#lastactivity li {
|
||||
padding: 2px;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
thead tr td {
|
||||
background: #3eaffa;
|
||||
color: #fff;
|
||||
}
|
||||
thead tr td a {
|
||||
color: #fff;
|
||||
}
|
||||
td.copy {
|
||||
text-align: center;
|
||||
}
|
||||
tr.head {
|
||||
color: #fff;
|
||||
background-color: #3b547a;
|
||||
text-align: center;
|
||||
}
|
||||
tr.oddraw {
|
||||
color: #412c75;
|
||||
background-color: #ccd4df;
|
||||
text-align: center;
|
||||
}
|
||||
tr.evenraw {
|
||||
color: #412c75;
|
||||
background-color: #dbe0e8;
|
||||
text-align: center;
|
||||
}
|
||||
td.leftheader {
|
||||
color: #412c75;
|
||||
background-color: #ccccc1;
|
||||
padding-left: 5px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
td.leftcontent {
|
||||
color: #000044;
|
||||
background-color: #e6e6df;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
td.rightcontent {
|
||||
color: #000044;
|
||||
text-align: justify;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #000044;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
h2 {
|
||||
color: #000044;
|
||||
text-align: center;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
h3 {
|
||||
color: #000044;
|
||||
text-align: left;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 2px;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
#content ul {
|
||||
padding-left: 1.1em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
#content ul li {
|
||||
list-style-type: disc;
|
||||
padding: 5px;
|
||||
}
|
||||
#content ul.nolistyle>li {
|
||||
list-style-type: none;
|
||||
}
|
||||
#content {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding-top: 25px;
|
||||
width: 70%;
|
||||
}
|
||||
div.guidelink,
|
||||
p[dir=ltr] {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
|
||||
margin: 0;
|
||||
margin-right: 1em;
|
||||
}
|
||||
div.guidelink a,
|
||||
p[dir=ltr] a {
|
||||
display: inline-block;
|
||||
border-radius: 3px;
|
||||
padding: 3px;
|
||||
|
||||
background: #3eaffa;
|
||||
|
||||
text-transform: uppercase;
|
||||
font-size: 0.75em;
|
||||
color: #fff;
|
||||
}
|
||||
table {
|
||||
margin-top: 1em;
|
||||
}
|
||||
table tr td {
|
||||
padding: 0.5em;
|
||||
}
|
||||
table tr:nth-child(odd) {
|
||||
background: #fff;
|
||||
}
|
||||
table.withtextareas>tbody>tr>td {
|
||||
vertical-align: top;
|
||||
}
|
||||
textarea {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
input,
|
||||
select {
|
||||
font-size: 1em;
|
||||
}
|
||||
p.result {
|
||||
border: 1px;
|
||||
border-style: dashed;
|
||||
border-color: #FE8A02;
|
||||
padding: 1em;
|
||||
margin-right: 1em;
|
||||
background: #FFE3C9;
|
||||
}
|
||||
*.alignright {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: sans-serif;
|
||||
color: #fff;
|
||||
}
|
||||
h1 {
|
||||
font-size: 3em;
|
||||
color: #444;
|
||||
}
|
||||
p {
|
||||
line-height: 1.5em;
|
||||
color: #888;
|
||||
}
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
a:hover,
|
||||
a:active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #424A55;
|
||||
background-image: -webkit-linear-gradient(270deg, rgba(48,52,62,0) 24%, #30353e 100%);
|
||||
background-image: linear-gradient(-180deg, rgba(48,52,62,0) 24%, #30353e 100%);
|
||||
}
|
||||
.section {
|
||||
padding: 3em;
|
||||
}
|
||||
.white.section {
|
||||
background: #fff;
|
||||
border-bottom: 4px solid #41AFCA;
|
||||
}
|
||||
.white.section a {
|
||||
text-decoration: none;
|
||||
color: #41AFCA;
|
||||
}
|
||||
.white.section a:hover,
|
||||
.white.section a:active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.block {
|
||||
margin: 0 auto;
|
||||
max-width: 900px;
|
||||
width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
.ts {color: #AAAAAA; text-decoration: none;}
|
||||
.mrcm {color: #009900; font-style: italic; font-weight: bold;}
|
||||
.msc {color: #009900; font-style: italic; font-weight: bold;}
|
||||
.msm {color: #000099; font-style: italic; font-weight: bold;}
|
||||
.mj {color: #009900; font-style: italic;}
|
||||
.ml {color: #009900; font-style: italic;}
|
||||
.mk {color: #009900; font-style: italic;}
|
||||
.mb {color: #009900; font-style: italic;}
|
||||
.mnc {color: #009900; font-style: italic;}
|
||||
.mn {color: #0000AA;}
|
||||
.mne {color: #AA0099;}
|
||||
a.nav {color: #AAAAAA; font-family: monospace; letter-spacing: 3px; text-decoration: none;}
|
||||
div.roomtitle {border-bottom: #224466 solid 3pt; margin-left: 20pt;}
|
||||
div.roomtitle {color: #336699; font-size: 24px; font-weight: bold; font-family: sans-serif; letter-spacing: 3px; text-decoration: none;}
|
||||
a.roomjid {color: #336699; font-size: 24px; font-weight: bold; font-family: sans-serif; letter-spacing: 3px; margin-left: 20pt; text-decoration: none;}
|
||||
div.logdate {color: #663399; font-size: 20px; font-weight: bold; font-family: sans-serif; letter-spacing: 2px; border-bottom: #224466 solid 1pt; margin-left:80pt; margin-top:20px;}
|
||||
div.roomsubject {color: #336699; font-size: 18px; font-family: sans-serif; margin-left: 80pt; margin-bottom: 10px;}
|
||||
div.rc {color: #336699; font-size: 12px; font-family: sans-serif; margin-left: 50%; text-align: right; background: #f3f6f9; border-bottom: 1px solid #336699; border-right: 4px solid #336699;}
|
||||
div.rct {font-weight: bold; background: #e3e6e9; padding-right: 10px;}
|
||||
div.rcos {padding-right: 10px;}
|
||||
div.rcoe {color: green;}
|
||||
div.rcod {color: red;}
|
||||
div.rcoe:after {content: ": v";}
|
||||
div.rcod:after {content: ": x";}
|
||||
div.rcot:after {}
|
||||
.legend {width: 100%; margin-top: 30px; border-top: #224466 solid 1pt; padding: 10px 0px 10px 0px; text-align: left; font-family: monospace; letter-spacing: 2px;}
|
||||
.w3c {position: absolute; right: 10px; width: 60%; text-align: right; font-family: monospace; letter-spacing: 1px;}
|
||||
@@ -0,0 +1,103 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
font-family: sans-serif;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3em;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.5em;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
a:hover,
|
||||
a:active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
em {
|
||||
display: inline-block;
|
||||
padding: 0 5px;
|
||||
background: #f4f4f4;
|
||||
border-radius: 5px;
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
form {
|
||||
color: #444;
|
||||
}
|
||||
label {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
input[type=password] {
|
||||
margin-bottom: 1em;
|
||||
padding: 0.4em;
|
||||
max-width: 330px;
|
||||
width: 100%;
|
||||
border: 1px solid #c4c4c4;
|
||||
border-radius: 5px;
|
||||
outline: 0;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
input[type=text]:focus,
|
||||
input[type=password]:focus,
|
||||
input[type=text]:active,
|
||||
input[type=password]:active {
|
||||
border-color: #41AFCA;
|
||||
}
|
||||
|
||||
input[type=submit] {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #424A55;
|
||||
background-image: -webkit-linear-gradient(270deg, rgba(48,52,62,0) 24%, #30353e 100%);
|
||||
background-image: linear-gradient(-180deg, rgba(48,52,62,0) 24%, #30353e 100%);
|
||||
}
|
||||
|
||||
.section {
|
||||
padding: 3em;
|
||||
}
|
||||
.white.section {
|
||||
background: #fff;
|
||||
border-bottom: 4px solid #41AFCA;
|
||||
}
|
||||
|
||||
.white.section a {
|
||||
text-decoration: none;
|
||||
color: #41AFCA;
|
||||
}
|
||||
.white.section a:hover,
|
||||
.white.section a:active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.container > .section {
|
||||
background: #424A55;
|
||||
}
|
||||
|
||||
.block {
|
||||
margin: 0 auto;
|
||||
max-width: 900px;
|
||||
width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
@viewport {
|
||||
width: device-width;
|
||||
zoom: 1.0;
|
||||
}
|
||||
|
||||
html,body {
|
||||
font-family: sans-serif;
|
||||
background: white;
|
||||
|
||||
padding: 0.5em;
|
||||
margin: auto;
|
||||
max-width: 800px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
form {
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
ul > li {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
ol > li {
|
||||
margin-bottom: 2em;
|
||||
font-weight: bold;
|
||||
font-size: 0.75em;
|
||||
}
|
||||
ol > li > ul {
|
||||
list-style: decimal;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
ol > li > ul > li {
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
input {
|
||||
display: block;
|
||||
padding: 0.25em;
|
||||
font-size: 1.5em;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 0;
|
||||
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
input:focus {
|
||||
border-color: #428bca;
|
||||
}
|
||||
input[type=submit] {
|
||||
padding: 0.33em 1em;
|
||||
background-color: #428bca;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
color: #fff;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 177 B |
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user