Hanno Böck commited on 2007-09-13 03:07:31
Zeige 28 geänderte Dateien mit 0 Einfügungen und 4973 Löschungen.
| ... | ... |
@@ -1,42 +0,0 @@ |
| 1 |
-# ChangeLog for net-im/ejabberd |
|
| 2 |
-# Copyright 2005-2006 BreakMyGentoo.net; Distributed under the GPL v2 |
|
| 3 |
-# $Header: $ |
|
| 4 |
- |
|
| 5 |
-*ejabberd-1.1.2-r5.ebuild (21 Nov 2006) |
|
| 6 |
- 21 Nov 2006; Lars Strojny <lars@strojny.net> ejabberd-1.1.2-r5.ebuild: |
|
| 7 |
- Bumping |
|
| 8 |
- |
|
| 9 |
-*ejabberd-1.1.1.ebuild (07 May 2006) |
|
| 10 |
- 02 Sep 2006; Lars Strojny <lars@strojny.net> ejabberd-1.1.1.ebuild, |
|
| 11 |
- files/ejabberd-1.1.1-http_binding.patch, files/ejabberd-1.1.1-proxy65.patch: |
|
| 12 |
- Added USE-flag httpbind and proxy for HTTP-binding (JEP-0124) implementation |
|
| 13 |
- by Stefan Strigler <zeank@jwchat.org> in order of Mabber (http://mabber.com) |
|
| 14 |
- and a Socks bytestream-implementation (JEP-0065) which is currently |
|
| 15 |
- experimental and supplied via bugtracker |
|
| 16 |
- (http://www.jabber.ru/bugzilla/show_bug.cgi?id=25) by Sander Devrieze |
|
| 17 |
- <s.devrieze@pandora.be>. |
|
| 18 |
- |
|
| 19 |
- 08 May 2006; Lars Strojny <lars@strojny.net> ejabberd-1.1.1.ebuild: |
|
| 20 |
- Used --enable-odbc instead of the custom make |
|
| 21 |
- |
|
| 22 |
- 07 May 2006; Lars Strojny <lars@strojny.net> ejabberd-1.1.1.ebuild: |
|
| 23 |
- Fixed buggy myconf |
|
| 24 |
- |
|
| 25 |
- 07 May 2006; Lars Strojny <lars@strojny.net> ejabberd-1.1.1.ebuild: |
|
| 26 |
- Added fix by Max Loparyev <max@city.veganet.ru> for "SET NAMES |
|
| 27 |
- 'utf8'" during MySQL-connect. Did some cleaning. |
|
| 28 |
- |
|
| 29 |
- 07 May 2006; Lars Strojny <lars@strojny.net> ejabberd-1.1.1.ebuild: |
|
| 30 |
- Version bump |
|
| 31 |
- |
|
| 32 |
-*ejabberd-1.0-r1.ebuild |
|
| 33 |
- 02 Mar 2006; Hendrik Brandt <heb@gnome-de.org> ChangeLog: |
|
| 34 |
- add missing digest file |
|
| 35 |
- |
|
| 36 |
- 26 Feb 2006; Lars Strojny <lars@breakmygentoo.net> ejabberd-1.0.0-r1.ebuild: |
|
| 37 |
- Added fix for DNS-SRV connections |
|
| 38 |
- |
|
| 39 |
- 16 Feb 2006; Lars Strojny <lars@breakmygentoo.net> ChangeLog: |
|
| 40 |
- Initial commit. This is a typical "just works" ebuild. Needs some love to |
|
| 41 |
- become more elegant. |
|
| 42 |
- |
| ... | ... |
@@ -1,104 +0,0 @@ |
| 1 |
-AUX ejabberd-1.1.1-http_binding.patch 27120 RMD160 33a486a0070317755217d2513f38e1fc51436cd8 SHA1 9b5079ed7134c9ec6b101e79921f9978de820475 SHA256 9edbe0257b9e3fb547bcdb4f4325627e279199adfd6753622665b762eb675ed0 |
|
| 2 |
-MD5 98f2370cd26723c02ae57ae780221663 files/ejabberd-1.1.1-http_binding.patch 27120 |
|
| 3 |
-RMD160 33a486a0070317755217d2513f38e1fc51436cd8 files/ejabberd-1.1.1-http_binding.patch 27120 |
|
| 4 |
-SHA256 9edbe0257b9e3fb547bcdb4f4325627e279199adfd6753622665b762eb675ed0 files/ejabberd-1.1.1-http_binding.patch 27120 |
|
| 5 |
-AUX ejabberd-1.1.1-mysql-connect-utf8.patch 622 RMD160 36bf34ba4a584ed19a4f93f709df0cfeb7d0ad7b SHA1 3fd01b6d6782bea7feeb3f784f393c04a7b7022c SHA256 747fbd494d6ebb75d5b73d407be10b0dba10f59a4a46561509c788d72a30ff08 |
|
| 6 |
-MD5 2b686065c6f72505ae252cdb5c7bebe8 files/ejabberd-1.1.1-mysql-connect-utf8.patch 622 |
|
| 7 |
-RMD160 36bf34ba4a584ed19a4f93f709df0cfeb7d0ad7b files/ejabberd-1.1.1-mysql-connect-utf8.patch 622 |
|
| 8 |
-SHA256 747fbd494d6ebb75d5b73d407be10b0dba10f59a4a46561509c788d72a30ff08 files/ejabberd-1.1.1-mysql-connect-utf8.patch 622 |
|
| 9 |
-AUX ejabberd-1.1.1-proxy65.patch 13293 RMD160 cdd06d4ca07773349ad4d97d854cff8b5547c8e2 SHA1 a6d9000a8b751efb1045830544a9e9a89e8122da SHA256 ade6a713cdb57c74ee29063104e4cf44476bb7fb5e63b3ea9f1353c20e9813aa |
|
| 10 |
-MD5 6284b9ed2a52690a62fbdca052c5a571 files/ejabberd-1.1.1-proxy65.patch 13293 |
|
| 11 |
-RMD160 cdd06d4ca07773349ad4d97d854cff8b5547c8e2 files/ejabberd-1.1.1-proxy65.patch 13293 |
|
| 12 |
-SHA256 ade6a713cdb57c74ee29063104e4cf44476bb7fb5e63b3ea9f1353c20e9813aa files/ejabberd-1.1.1-proxy65.patch 13293 |
|
| 13 |
-AUX ejabberd-1.1.1.confd 671 RMD160 e727a01c6e0418468bd785447b85d349a536f3ea SHA1 e40c4e24ed1976a781b9557d8ba186fb0fd5cda2 SHA256 fb8f66daaa4bf9063867b80ac6e677be7f6739d3c245bf389467df2ea687887d |
|
| 14 |
-MD5 03cdfdbfb294de6eccffda248d349040 files/ejabberd-1.1.1.confd 671 |
|
| 15 |
-RMD160 e727a01c6e0418468bd785447b85d349a536f3ea files/ejabberd-1.1.1.confd 671 |
|
| 16 |
-SHA256 fb8f66daaa4bf9063867b80ac6e677be7f6739d3c245bf389467df2ea687887d files/ejabberd-1.1.1.confd 671 |
|
| 17 |
-AUX ejabberd-1.1.1.initd 1260 RMD160 0565503966512228f21079213a8587d7ada7a823 SHA1 09d2ca4ab1a371fe2a987f649c6761742531c658 SHA256 cd06a6efdefda36993eb82fb6617a9a7e65228941f4deac42d583e96b1d6dfc9 |
|
| 18 |
-MD5 608e482a70b1cd9a1a78d721edc8d42d files/ejabberd-1.1.1.initd 1260 |
|
| 19 |
-RMD160 0565503966512228f21079213a8587d7ada7a823 files/ejabberd-1.1.1.initd 1260 |
|
| 20 |
-SHA256 cd06a6efdefda36993eb82fb6617a9a7e65228941f4deac42d583e96b1d6dfc9 files/ejabberd-1.1.1.initd 1260 |
|
| 21 |
-AUX ejabberd-1.1.2-http_binding.patch 29551 RMD160 6c1c9bc7516a5d4a13220be5d7508348aca1128a SHA1 d65a1fdf14c74154b25778e495568aeec6dcad77 SHA256 c55992c2b6e9ca36d9687237b990c27c47511bbe025d746d2380f122fecbda32 |
|
| 22 |
-MD5 8e25a0686567a645914aa51440e7d521 files/ejabberd-1.1.2-http_binding.patch 29551 |
|
| 23 |
-RMD160 6c1c9bc7516a5d4a13220be5d7508348aca1128a files/ejabberd-1.1.2-http_binding.patch 29551 |
|
| 24 |
-SHA256 c55992c2b6e9ca36d9687237b990c27c47511bbe025d746d2380f122fecbda32 files/ejabberd-1.1.2-http_binding.patch 29551 |
|
| 25 |
-AUX ejabberd-1.1.2-mod_irc-utf-8.patch 369 RMD160 11b3a06b4f8af77c6c368aeacfe8943eace50da5 SHA1 123a95c4535102aaa076435c464025e40f9fb889 SHA256 a3884a97f9e4239df643ac327c48baf78f77c9cffbd5d67f39f018a811dcdc9f |
|
| 26 |
-MD5 3ca38149e85443cac4dfc58ca8bf1c08 files/ejabberd-1.1.2-mod_irc-utf-8.patch 369 |
|
| 27 |
-RMD160 11b3a06b4f8af77c6c368aeacfe8943eace50da5 files/ejabberd-1.1.2-mod_irc-utf-8.patch 369 |
|
| 28 |
-SHA256 a3884a97f9e4239df643ac327c48baf78f77c9cffbd5d67f39f018a811dcdc9f files/ejabberd-1.1.2-mod_irc-utf-8.patch 369 |
|
| 29 |
-AUX ejabberd-1.1.2-mysql-connect-utf8.patch 622 RMD160 36bf34ba4a584ed19a4f93f709df0cfeb7d0ad7b SHA1 3fd01b6d6782bea7feeb3f784f393c04a7b7022c SHA256 747fbd494d6ebb75d5b73d407be10b0dba10f59a4a46561509c788d72a30ff08 |
|
| 30 |
-MD5 2b686065c6f72505ae252cdb5c7bebe8 files/ejabberd-1.1.2-mysql-connect-utf8.patch 622 |
|
| 31 |
-RMD160 36bf34ba4a584ed19a4f93f709df0cfeb7d0ad7b files/ejabberd-1.1.2-mysql-connect-utf8.patch 622 |
|
| 32 |
-SHA256 747fbd494d6ebb75d5b73d407be10b0dba10f59a4a46561509c788d72a30ff08 files/ejabberd-1.1.2-mysql-connect-utf8.patch 622 |
|
| 33 |
-AUX ejabberd-1.1.2-proxy65.patch 13293 RMD160 cdd06d4ca07773349ad4d97d854cff8b5547c8e2 SHA1 a6d9000a8b751efb1045830544a9e9a89e8122da SHA256 ade6a713cdb57c74ee29063104e4cf44476bb7fb5e63b3ea9f1353c20e9813aa |
|
| 34 |
-MD5 6284b9ed2a52690a62fbdca052c5a571 files/ejabberd-1.1.2-proxy65.patch 13293 |
|
| 35 |
-RMD160 cdd06d4ca07773349ad4d97d854cff8b5547c8e2 files/ejabberd-1.1.2-proxy65.patch 13293 |
|
| 36 |
-SHA256 ade6a713cdb57c74ee29063104e4cf44476bb7fb5e63b3ea9f1353c20e9813aa files/ejabberd-1.1.2-proxy65.patch 13293 |
|
| 37 |
-AUX ejabberd-1.1.2.confd 671 RMD160 e727a01c6e0418468bd785447b85d349a536f3ea SHA1 e40c4e24ed1976a781b9557d8ba186fb0fd5cda2 SHA256 fb8f66daaa4bf9063867b80ac6e677be7f6739d3c245bf389467df2ea687887d |
|
| 38 |
-MD5 03cdfdbfb294de6eccffda248d349040 files/ejabberd-1.1.2.confd 671 |
|
| 39 |
-RMD160 e727a01c6e0418468bd785447b85d349a536f3ea files/ejabberd-1.1.2.confd 671 |
|
| 40 |
-SHA256 fb8f66daaa4bf9063867b80ac6e677be7f6739d3c245bf389467df2ea687887d files/ejabberd-1.1.2.confd 671 |
|
| 41 |
-AUX ejabberd-1.1.2.initd 1260 RMD160 0565503966512228f21079213a8587d7ada7a823 SHA1 09d2ca4ab1a371fe2a987f649c6761742531c658 SHA256 cd06a6efdefda36993eb82fb6617a9a7e65228941f4deac42d583e96b1d6dfc9 |
|
| 42 |
-MD5 608e482a70b1cd9a1a78d721edc8d42d files/ejabberd-1.1.2.initd 1260 |
|
| 43 |
-RMD160 0565503966512228f21079213a8587d7ada7a823 files/ejabberd-1.1.2.initd 1260 |
|
| 44 |
-SHA256 cd06a6efdefda36993eb82fb6617a9a7e65228941f4deac42d583e96b1d6dfc9 files/ejabberd-1.1.2.initd 1260 |
|
| 45 |
-AUX ejabberd-1.1.3-http_binding.patch 29551 RMD160 6c1c9bc7516a5d4a13220be5d7508348aca1128a SHA1 d65a1fdf14c74154b25778e495568aeec6dcad77 SHA256 c55992c2b6e9ca36d9687237b990c27c47511bbe025d746d2380f122fecbda32 |
|
| 46 |
-MD5 8e25a0686567a645914aa51440e7d521 files/ejabberd-1.1.3-http_binding.patch 29551 |
|
| 47 |
-RMD160 6c1c9bc7516a5d4a13220be5d7508348aca1128a files/ejabberd-1.1.3-http_binding.patch 29551 |
|
| 48 |
-SHA256 c55992c2b6e9ca36d9687237b990c27c47511bbe025d746d2380f122fecbda32 files/ejabberd-1.1.3-http_binding.patch 29551 |
|
| 49 |
-AUX ejabberd-1.1.3-mod_irc-utf-8.patch 369 RMD160 11b3a06b4f8af77c6c368aeacfe8943eace50da5 SHA1 123a95c4535102aaa076435c464025e40f9fb889 SHA256 a3884a97f9e4239df643ac327c48baf78f77c9cffbd5d67f39f018a811dcdc9f |
|
| 50 |
-MD5 3ca38149e85443cac4dfc58ca8bf1c08 files/ejabberd-1.1.3-mod_irc-utf-8.patch 369 |
|
| 51 |
-RMD160 11b3a06b4f8af77c6c368aeacfe8943eace50da5 files/ejabberd-1.1.3-mod_irc-utf-8.patch 369 |
|
| 52 |
-SHA256 a3884a97f9e4239df643ac327c48baf78f77c9cffbd5d67f39f018a811dcdc9f files/ejabberd-1.1.3-mod_irc-utf-8.patch 369 |
|
| 53 |
-AUX ejabberd-1.1.3-mysql-connect-utf8.patch 659 RMD160 5d72e94d9634447eb07b03d8229e99a5d7e7a43f SHA1 7a7e5ccc60dfeb197567c6097f190ee241fcb95a SHA256 371c5de9be1c366f7a5ee0008621bce761acbab0b92e279e31326b6bdf8a6c52 |
|
| 54 |
-MD5 d014130a19d11bfa159b998a0f44796c files/ejabberd-1.1.3-mysql-connect-utf8.patch 659 |
|
| 55 |
-RMD160 5d72e94d9634447eb07b03d8229e99a5d7e7a43f files/ejabberd-1.1.3-mysql-connect-utf8.patch 659 |
|
| 56 |
-SHA256 371c5de9be1c366f7a5ee0008621bce761acbab0b92e279e31326b6bdf8a6c52 files/ejabberd-1.1.3-mysql-connect-utf8.patch 659 |
|
| 57 |
-AUX ejabberd-1.1.3-proxy65.patch 13293 RMD160 cdd06d4ca07773349ad4d97d854cff8b5547c8e2 SHA1 a6d9000a8b751efb1045830544a9e9a89e8122da SHA256 ade6a713cdb57c74ee29063104e4cf44476bb7fb5e63b3ea9f1353c20e9813aa |
|
| 58 |
-MD5 6284b9ed2a52690a62fbdca052c5a571 files/ejabberd-1.1.3-proxy65.patch 13293 |
|
| 59 |
-RMD160 cdd06d4ca07773349ad4d97d854cff8b5547c8e2 files/ejabberd-1.1.3-proxy65.patch 13293 |
|
| 60 |
-SHA256 ade6a713cdb57c74ee29063104e4cf44476bb7fb5e63b3ea9f1353c20e9813aa files/ejabberd-1.1.3-proxy65.patch 13293 |
|
| 61 |
-AUX ejabberd-1.1.3.confd 671 RMD160 e727a01c6e0418468bd785447b85d349a536f3ea SHA1 e40c4e24ed1976a781b9557d8ba186fb0fd5cda2 SHA256 fb8f66daaa4bf9063867b80ac6e677be7f6739d3c245bf389467df2ea687887d |
|
| 62 |
-MD5 03cdfdbfb294de6eccffda248d349040 files/ejabberd-1.1.3.confd 671 |
|
| 63 |
-RMD160 e727a01c6e0418468bd785447b85d349a536f3ea files/ejabberd-1.1.3.confd 671 |
|
| 64 |
-SHA256 fb8f66daaa4bf9063867b80ac6e677be7f6739d3c245bf389467df2ea687887d files/ejabberd-1.1.3.confd 671 |
|
| 65 |
-AUX ejabberd-1.1.3.initd 1260 RMD160 0565503966512228f21079213a8587d7ada7a823 SHA1 09d2ca4ab1a371fe2a987f649c6761742531c658 SHA256 cd06a6efdefda36993eb82fb6617a9a7e65228941f4deac42d583e96b1d6dfc9 |
|
| 66 |
-MD5 608e482a70b1cd9a1a78d721edc8d42d files/ejabberd-1.1.3.initd 1260 |
|
| 67 |
-RMD160 0565503966512228f21079213a8587d7ada7a823 files/ejabberd-1.1.3.initd 1260 |
|
| 68 |
-SHA256 cd06a6efdefda36993eb82fb6617a9a7e65228941f4deac42d583e96b1d6dfc9 files/ejabberd-1.1.3.initd 1260 |
|
| 69 |
-AUX inetrc 36 RMD160 4b79020864689ede547969610fde18fe490f5810 SHA1 1e0bae0f7251e2ae3b62ba9d3e5cc86bb5dd271e SHA256 0f383befc4c46134d88ce14d3bd06c404ef6575391f4ac0b5e8c28ba383b28fc |
|
| 70 |
-MD5 e088cd52d4316efddc54195dc939cd24 files/inetrc 36 |
|
| 71 |
-RMD160 4b79020864689ede547969610fde18fe490f5810 files/inetrc 36 |
|
| 72 |
-SHA256 0f383befc4c46134d88ce14d3bd06c404ef6575391f4ac0b5e8c28ba383b28fc files/inetrc 36 |
|
| 73 |
-DIST ejabberd-1.1.1.tar.gz 803278 RMD160 b9c0b7ab3fe1f1b2dce52e1460bba04b313ea534 SHA1 4f23d787afe75c7c866decdff6f539195449776e SHA256 52a97275537073066bd352f5718954f6994b272d1efa51187e17edf0c9b11082 |
|
| 74 |
-DIST ejabberd-1.1.2.tar.gz 836240 RMD160 e763752e6c5fb46c51b71e265ab2ceda6d043a0d SHA1 9e94bdbc10fee5b781405daf43a0b4abc4dee6c1 SHA256 029129a6bcb5d15dbccc5aa756f61c52692eb6882ec7aad0193aa940b6a20bb6 |
|
| 75 |
-DIST ejabberd-1.1.3.tar.gz 826057 RMD160 99b4c73ae29ef9814f5c572f8e3b3a82d960f5ee SHA1 66b00ca52fa4f4f4e097b0e897c3b5a2e4526603 SHA256 3b8ac67673fa6c08bc25382d3e99171ebc71d4759899eb5a730e65117256e703 |
|
| 76 |
-EBUILD ejabberd-1.1.1.ebuild 5044 RMD160 3c0213f2cd39fdb54505cc0b394b70477b10fbb4 SHA1 491cbd3d3ab8dde27a5280fdbf2783131da4fa7b SHA256 9346b48122eb7812e6beba93e223d0c1d027719877ef7307415edac56b1a1d06 |
|
| 77 |
-MD5 2d16ab0045996aa62fdc6867e8c62edb ejabberd-1.1.1.ebuild 5044 |
|
| 78 |
-RMD160 3c0213f2cd39fdb54505cc0b394b70477b10fbb4 ejabberd-1.1.1.ebuild 5044 |
|
| 79 |
-SHA256 9346b48122eb7812e6beba93e223d0c1d027719877ef7307415edac56b1a1d06 ejabberd-1.1.1.ebuild 5044 |
|
| 80 |
-EBUILD ejabberd-1.1.2-r5.ebuild 5072 RMD160 d1ad865d489b7856ea9b252ac0fc9444fa812cd7 SHA1 695f4b8715050907072e347ea846b59fe673c181 SHA256 ada01971d7d7b5362ad8b9a839a990eb1b2d8013f7c66fdbba502486b02cbbfb |
|
| 81 |
-MD5 27ae991ce72e44d8838c5e7c9f3a5331 ejabberd-1.1.2-r5.ebuild 5072 |
|
| 82 |
-RMD160 d1ad865d489b7856ea9b252ac0fc9444fa812cd7 ejabberd-1.1.2-r5.ebuild 5072 |
|
| 83 |
-SHA256 ada01971d7d7b5362ad8b9a839a990eb1b2d8013f7c66fdbba502486b02cbbfb ejabberd-1.1.2-r5.ebuild 5072 |
|
| 84 |
-EBUILD ejabberd-1.1.3-r1.ebuild 4312 RMD160 fd19cc00f401ca16d17ca31f7a891444ed9edd25 SHA1 a1983e32f9289d93313af6f9fd08bc1e37fbc605 SHA256 cdaa01e626f0d032c0ed780be0fc964b314fed492a88d96832c317026bb550d9 |
|
| 85 |
-MD5 2b495ac9aaca0c91f75e67f53e2ea96a ejabberd-1.1.3-r1.ebuild 4312 |
|
| 86 |
-RMD160 fd19cc00f401ca16d17ca31f7a891444ed9edd25 ejabberd-1.1.3-r1.ebuild 4312 |
|
| 87 |
-SHA256 cdaa01e626f0d032c0ed780be0fc964b314fed492a88d96832c317026bb550d9 ejabberd-1.1.3-r1.ebuild 4312 |
|
| 88 |
-MISC ChangeLog 1674 RMD160 a7cde836a8d747863d148edef3a9d1b7cf781af2 SHA1 529722882cfb1e1135eda10c99d0aa8e753704a3 SHA256 c37aa58a182a91857395f0c53c3299d19cfe4960d5240673c7606f18199d3681 |
|
| 89 |
-MD5 678fcb919ef8ac4a080934c500537f8d ChangeLog 1674 |
|
| 90 |
-RMD160 a7cde836a8d747863d148edef3a9d1b7cf781af2 ChangeLog 1674 |
|
| 91 |
-SHA256 c37aa58a182a91857395f0c53c3299d19cfe4960d5240673c7606f18199d3681 ChangeLog 1674 |
|
| 92 |
-MISC metadata.xml 386 RMD160 6851cac865de77f0052aa55b91845f98ba984bf2 SHA1 f3a72217775da32822787455f53a6168b4ce2acb SHA256 8fdc368bc07695d9ee0b988f09ef41799619a86f33faf839360c046f46ce8aa5 |
|
| 93 |
-MD5 de765f4e50f58226d0035d84531cf752 metadata.xml 386 |
|
| 94 |
-RMD160 6851cac865de77f0052aa55b91845f98ba984bf2 metadata.xml 386 |
|
| 95 |
-SHA256 8fdc368bc07695d9ee0b988f09ef41799619a86f33faf839360c046f46ce8aa5 metadata.xml 386 |
|
| 96 |
-MD5 87c80474a3cbcdf51830a748a411f0f4 files/digest-ejabberd-1.1.1 244 |
|
| 97 |
-RMD160 bdb61a1e0dd65fa91775a5f3b7c7516dc65bd8ff files/digest-ejabberd-1.1.1 244 |
|
| 98 |
-SHA256 d3659c3dbc43cf807fb7309da84ba62393e9257a7a16a3305621ee60f97378a6 files/digest-ejabberd-1.1.1 244 |
|
| 99 |
-MD5 a38033cd51c7bb84bc09310952063222 files/digest-ejabberd-1.1.2-r5 244 |
|
| 100 |
-RMD160 d8117ebc19953eb40137b4ebca37d7577ff9e5b6 files/digest-ejabberd-1.1.2-r5 244 |
|
| 101 |
-SHA256 e1ff34ed81425e1b009e60d29d7f6b9bdeff7cdba4407372cfdb8e40ca00efcb files/digest-ejabberd-1.1.2-r5 244 |
|
| 102 |
-MD5 9b247a2a345b5d2c9cdf1a1678f4edf9 files/digest-ejabberd-1.1.3-r1 244 |
|
| 103 |
-RMD160 59a1985b119be6cf343af1ea13929c233e59f0b4 files/digest-ejabberd-1.1.3-r1 244 |
|
| 104 |
-SHA256 5dad3cfcf7b609862a65b6d09c18ed318563573f866e6c19010c7b9ee7836998 files/digest-ejabberd-1.1.3-r1 244 |
| ... | ... |
@@ -1,197 +0,0 @@ |
| 1 |
-# Copyright 2005-2006 BreakMyGentoo.net |
|
| 2 |
-# Distributed under the terms of the GNU General Public License v2 |
|
| 3 |
-# $Header: $ |
|
| 4 |
- |
|
| 5 |
-inherit eutils multilib ssl-cert versionator |
|
| 6 |
- |
|
| 7 |
-JABBER_ETC="/etc/jabber" |
|
| 8 |
-JABBER_RUN="/var/run/jabber" |
|
| 9 |
-JABBER_SPOOL="/var/spool/jabber" |
|
| 10 |
-JABBER_LOG="/var/log/jabber" |
|
| 11 |
- |
|
| 12 |
-E_MYSQL_V="5" |
|
| 13 |
-E_MYSQL_N="mysql" |
|
| 14 |
-E_MYSQL=${E_MYSQL_N}-${E_MYSQL_V}
|
|
| 15 |
- |
|
| 16 |
-E_PGSQL_V="0.0.1" |
|
| 17 |
-E_PGSQL_N="pgsql-cvs" |
|
| 18 |
-E_PGSQL=${E_PGSQL_N}-${E_PGSQL_V}
|
|
| 19 |
- |
|
| 20 |
-DESCRIPTION="The Erlang Jabber Daemon" |
|
| 21 |
-HOMEPAGE="http://ejabberd.jabber.ru/" |
|
| 22 |
-SRC_URI="http://process-one.net/en/projects/ejabberd/download/${PV}/${P}.tar.gz"
|
|
| 23 |
-LICENSE="GPL-2" |
|
| 24 |
-SLOT="0" |
|
| 25 |
-KEYWORDS="~x86 ~amd64" |
|
| 26 |
-IUSE="${IUSE} irc ldap muc odbc postgres pubsub web mysql httpbind proxy"
|
|
| 27 |
- |
|
| 28 |
-DEPEND="${RDEPEND}
|
|
| 29 |
- >=net-im/jabber-base-0.00 |
|
| 30 |
- >=dev-libs/expat-1.95 |
|
| 31 |
- >=dev-lang/erlang-10.2.0 |
|
| 32 |
- odbc? ( dev-db/unixODBC ) |
|
| 33 |
- ldap? ( =net-nds/openldap-2* ) |
|
| 34 |
- postgres? ( =dev-erl/${E_PGSQL} )
|
|
| 35 |
- mysql? ( =dev-erl/${E_MYSQL} )"
|
|
| 36 |
- |
|
| 37 |
-RDEPEND="postgres? ( dev-db/postgresql ) |
|
| 38 |
- mysql? ( dev-db/mysql )" |
|
| 39 |
- |
|
| 40 |
-PROVIDE="virtual/jabber-server" |
|
| 41 |
-S=${WORKDIR}/${P}/src
|
|
| 42 |
- |
|
| 43 |
-src_unpack() {
|
|
| 44 |
- unpack ${A}
|
|
| 45 |
- MYSQL_P=$(best_version dev-db/mysql) |
|
| 46 |
- MYSQL_PV=${MYSQL_P/dev-db\/mysql-/}
|
|
| 47 |
- |
|
| 48 |
- # |
|
| 49 |
- # If we have to work with MySQL 4.1 or greater, ejabberd's native |
|
| 50 |
- # MySQL-driver has to be patched to query "SET NAMES 'utf8'" on connecting |
|
| 51 |
- # the database. |
|
| 52 |
- # |
|
| 53 |
- if use mysql && \ |
|
| 54 |
- (( \ |
|
| 55 |
- [ $(get_major_version ${MYSQL_PV}) -eq 4 ] && \
|
|
| 56 |
- [ $(get_major_version $(get_after_major_version ${MYSQL_PV})) -ge 1] \
|
|
| 57 |
- ) \ |
|
| 58 |
- || \ |
|
| 59 |
- [ $(get_major_version ${MYSQL_PV}) -ge 5 ] \
|
|
| 60 |
- ); then |
|
| 61 |
- epatch ${FILESDIR}/${P}-mysql-connect-utf8.patch
|
|
| 62 |
- fi |
|
| 63 |
- |
|
| 64 |
- cd ${S}
|
|
| 65 |
- if use httpbind; then |
|
| 66 |
- epatch ${FILESDIR}/${P}-http_binding.patch
|
|
| 67 |
- fi |
|
| 68 |
- |
|
| 69 |
- if use proxy; then |
|
| 70 |
- epatch ${FILESDIR}/${P}-proxy65.patch
|
|
| 71 |
- fi |
|
| 72 |
- |
|
| 73 |
- epatch ${FILESDIR}/${P}-mod_irc-charset.patch
|
|
| 74 |
-} |
|
| 75 |
- |
|
| 76 |
- |
|
| 77 |
-src_compile() {
|
|
| 78 |
- local myconf |
|
| 79 |
- |
|
| 80 |
- if ! use mysql && ! use postgres && ! use odbc; then |
|
| 81 |
- myconf="--disable-odbc" |
|
| 82 |
- else |
|
| 83 |
- myconf="--enable-odbc" |
|
| 84 |
- fi |
|
| 85 |
- |
|
| 86 |
- # |
|
| 87 |
- # configure ejabberd |
|
| 88 |
- # |
|
| 89 |
- econf ${myconf} \
|
|
| 90 |
- --enable-roster-gateway-workaround \ |
|
| 91 |
- $(use_enable irc mod_irc) \ |
|
| 92 |
- $(use_enable ldap eldap) \ |
|
| 93 |
- $(use_enable muc mod_muc) \ |
|
| 94 |
- $(use_enable pubsub mod_pubsub) \ |
|
| 95 |
- $(use_enable ssl tls) \ |
|
| 96 |
- $(use_enable web web) \ |
|
| 97 |
- || die "econf failed" |
|
| 98 |
- |
|
| 99 |
- # |
|
| 100 |
- # Build ejabberd core |
|
| 101 |
- # |
|
| 102 |
- emake || die "compiling ejabberd core failed" |
|
| 103 |
-} |
|
| 104 |
- |
|
| 105 |
-src_install() {
|
|
| 106 |
- # |
|
| 107 |
- # Install ejabberd |
|
| 108 |
- # |
|
| 109 |
- make \ |
|
| 110 |
- DESTDIR=${D} \
|
|
| 111 |
- EJABBERDDIR=${D}/usr/$(get_libdir)/erlang/lib/${P} \
|
|
| 112 |
- ETCDIR=${D}${JABBER_ETC} \
|
|
| 113 |
- LOGDIR=${D}${JABBER_LOG} \
|
|
| 114 |
- install \ |
|
| 115 |
- || die "install failed" |
|
| 116 |
- |
|
| 117 |
- |
|
| 118 |
- insinto /usr/share/doc/${PF}
|
|
| 119 |
- use postgres && doins odbc/pg.sql |
|
| 120 |
- use mysql && doins odbc/mysql.sql |
|
| 121 |
- dodoc doc/release_notes_${PV}.txt
|
|
| 122 |
- dohtml doc/*.{html,png}
|
|
| 123 |
- |
|
| 124 |
- |
|
| 125 |
- use postgres && {
|
|
| 126 |
- pa="-pa /usr/$(get_libdir)/erlang/lib/${E_PGSQL}/ebin"
|
|
| 127 |
- } |
|
| 128 |
- |
|
| 129 |
- use mysql && {
|
|
| 130 |
- pa=${pa}" -pa /usr/$(get_libdir)/erlang/lib/${E_MYSQL}/ebin"
|
|
| 131 |
- } |
|
| 132 |
- |
|
| 133 |
- # |
|
| 134 |
- # Create /usr/bin/ejabberd |
|
| 135 |
- # |
|
| 136 |
- cat <<EOF > ${T}/ejabberd
|
|
| 137 |
-#!/bin/bash |
|
| 138 |
- |
|
| 139 |
-erl -pa /usr/$(get_libdir)/erlang/lib/${P}/ebin \\
|
|
| 140 |
- ${pa} \\
|
|
| 141 |
- -sname ejabberd \\ |
|
| 142 |
- -s ejabberd \\ |
|
| 143 |
- -ejabberd config \"${JABBER_ETC}/ejabberd.cfg\" \\
|
|
| 144 |
- log_path \"${JABBER_LOG}/ejabberd.log\" \\
|
|
| 145 |
- -kernel inetrc \"${JABBER_ETC}/inetrc\" \\
|
|
| 146 |
- -sasl sasl_error_logger \{file,\"${JABBER_LOG}/sasl.log\"\} \\
|
|
| 147 |
- -mnesia dir \"${JABBER_SPOOL}\" \\
|
|
| 148 |
- \$@ |
|
| 149 |
-EOF |
|
| 150 |
- |
|
| 151 |
- # |
|
| 152 |
- # Create /usr/bin/ejabberdctl |
|
| 153 |
- # |
|
| 154 |
- cat <<EOF > ${T}/ejabberdctl
|
|
| 155 |
-#!/bin/sh |
|
| 156 |
- |
|
| 157 |
-exec env HOME=${JABBER_RUN} \\
|
|
| 158 |
- erl -pa /usr/$(get_libdir)/erlang/lib/${P}/ebin \\
|
|
| 159 |
- ${pa} \\
|
|
| 160 |
- -noinput \\ |
|
| 161 |
- -sname ejabberdctl \\ |
|
| 162 |
- -s ejabberd_ctl \\ |
|
| 163 |
- -extra \$@ |
|
| 164 |
-EOF |
|
| 165 |
- |
|
| 166 |
- dobin ${T}/ejabberdctl
|
|
| 167 |
- dobin ${T}/ejabberd
|
|
| 168 |
- |
|
| 169 |
- newinitd ${FILESDIR}/${P}.initd ${PN}
|
|
| 170 |
- newconfd ${FILESDIR}/${P}.confd ${PN}
|
|
| 171 |
- |
|
| 172 |
- insinto ${JABBER_ETC}
|
|
| 173 |
- if use ssl; then |
|
| 174 |
- docert ssl |
|
| 175 |
- rm -f ${D}${JABBER_ETC}/ssl.{crt,csr,key}
|
|
| 176 |
- fowners jabber:jabber ${JABBER_ETC}/ssl.pem
|
|
| 177 |
- fi |
|
| 178 |
- doins ${FILESDIR}/inetrc
|
|
| 179 |
-} |
|
| 180 |
- |
|
| 181 |
-pkg_postinst() {
|
|
| 182 |
- if [ ! -e ${JABBER_ETC}/ejabberd.cfg ]
|
|
| 183 |
- then |
|
| 184 |
- einfo "Configuration file has been installed in ${JABBER_ETC}/ejabberd.cfg."
|
|
| 185 |
- einfo "Edit it according to your needs. For configuration instructions," |
|
| 186 |
- einfo "please see /usr/share/doc/${PF}/html/guide.html"
|
|
| 187 |
- fi |
|
| 188 |
- if use ssl ; then |
|
| 189 |
- einfo "A script to generate a ssl key has been installed in" |
|
| 190 |
- einfo "${JABBER_ETC}/self-cert.sh . Use it and change the config file to"
|
|
| 191 |
- einfo "point to the full path" |
|
| 192 |
- fi |
|
| 193 |
- if ! use web ; then |
|
| 194 |
- einfo "The web USE flag is off, this will disable the web admin interface," |
|
| 195 |
- einfo "if this was not the intention then add web to your USE flags." |
|
| 196 |
- fi |
|
| 197 |
-} |
| ... | ... |
@@ -1,197 +0,0 @@ |
| 1 |
-# Copyright 2005-2006 BreakMyGentoo.net |
|
| 2 |
-# Distributed under the terms of the GNU General Public License v2 |
|
| 3 |
-# $Header: $ |
|
| 4 |
- |
|
| 5 |
-inherit eutils multilib ssl-cert versionator |
|
| 6 |
- |
|
| 7 |
-JABBER_ETC="/etc/jabber" |
|
| 8 |
-JABBER_RUN="/var/run/jabber" |
|
| 9 |
-JABBER_SPOOL="/var/spool/jabber" |
|
| 10 |
-JABBER_LOG="/var/log/jabber" |
|
| 11 |
- |
|
| 12 |
-E_MYSQL_V="0.1" |
|
| 13 |
-E_MYSQL_N="mysql" |
|
| 14 |
-E_MYSQL=${E_MYSQL_N}-${E_MYSQL_V}
|
|
| 15 |
- |
|
| 16 |
-E_PGSQL_V="0.0.1" |
|
| 17 |
-E_PGSQL_N="pgsql-cvs" |
|
| 18 |
-E_PGSQL=${E_PGSQL_N}-${E_PGSQL_V}
|
|
| 19 |
- |
|
| 20 |
-DESCRIPTION="The Erlang Jabber Daemon" |
|
| 21 |
-HOMEPAGE="http://ejabberd.jabber.ru/" |
|
| 22 |
-SRC_URI="http://process-one.net/en/projects/ejabberd/download/${PV}/${P}.tar.gz"
|
|
| 23 |
-LICENSE="GPL-2" |
|
| 24 |
-SLOT="0" |
|
| 25 |
-KEYWORDS="~x86 amd64" |
|
| 26 |
-IUSE="${IUSE} irc ldap muc odbc postgres pubsub web mysql httpbind proxy"
|
|
| 27 |
- |
|
| 28 |
-DEPEND="${RDEPEND}
|
|
| 29 |
- >=net-im/jabber-base-0.00 |
|
| 30 |
- >=dev-libs/expat-1.95 |
|
| 31 |
- >=dev-lang/erlang-10.2.0 |
|
| 32 |
- odbc? ( dev-db/unixODBC ) |
|
| 33 |
- ldap? ( =net-nds/openldap-2* ) |
|
| 34 |
- postgres? ( =dev-erl/${E_PGSQL} )
|
|
| 35 |
- mysql? ( =dev-erl/${E_MYSQL} )"
|
|
| 36 |
- |
|
| 37 |
-RDEPEND="postgres? ( dev-db/postgresql ) |
|
| 38 |
- mysql? ( dev-db/mysql )" |
|
| 39 |
- |
|
| 40 |
-PROVIDE="virtual/jabber-server" |
|
| 41 |
-S=${WORKDIR}/${P}/src
|
|
| 42 |
- |
|
| 43 |
-src_unpack() {
|
|
| 44 |
- unpack ${A}
|
|
| 45 |
- MYSQL_P=$(best_version dev-db/mysql) |
|
| 46 |
- MYSQL_PV=${MYSQL_P/dev-db\/mysql-/}
|
|
| 47 |
- |
|
| 48 |
- # |
|
| 49 |
- # If we have to work with MySQL 4.1 or greater, ejabberd's native |
|
| 50 |
- # MySQL-driver has to be patched to query "SET NAMES 'utf8'" on connecting |
|
| 51 |
- # the database. |
|
| 52 |
- # |
|
| 53 |
- if use mysql && \ |
|
| 54 |
- (( \ |
|
| 55 |
- [ $(get_major_version ${MYSQL_PV}) -eq 4 ] && \
|
|
| 56 |
- [ $(get_major_version $(get_after_major_version ${MYSQL_PV})) -ge 1] \
|
|
| 57 |
- ) \ |
|
| 58 |
- || \ |
|
| 59 |
- [ $(get_major_version ${MYSQL_PV}) -ge 5 ] \
|
|
| 60 |
- ); then |
|
| 61 |
- epatch ${FILESDIR}/${P}-mysql-connect-utf8.patch || die
|
|
| 62 |
- fi |
|
| 63 |
- |
|
| 64 |
- cd ${S}
|
|
| 65 |
- if use httpbind; then |
|
| 66 |
- epatch ${FILESDIR}/${P}-http_binding.patch || die
|
|
| 67 |
- fi |
|
| 68 |
- |
|
| 69 |
- if use proxy; then |
|
| 70 |
- epatch ${FILESDIR}/${P}-proxy65.patch || die
|
|
| 71 |
- fi |
|
| 72 |
- |
|
| 73 |
- epatch ${FILESDIR}/${P}-mod_irc-utf-8.patch || die
|
|
| 74 |
-} |
|
| 75 |
- |
|
| 76 |
- |
|
| 77 |
-src_compile() {
|
|
| 78 |
- local myconf |
|
| 79 |
- |
|
| 80 |
- if ! use mysql && ! use postgres && ! use odbc; then |
|
| 81 |
- myconf="--disable-odbc" |
|
| 82 |
- else |
|
| 83 |
- myconf="--enable-odbc" |
|
| 84 |
- fi |
|
| 85 |
- |
|
| 86 |
- # |
|
| 87 |
- # configure ejabberd |
|
| 88 |
- # |
|
| 89 |
- econf ${myconf} \
|
|
| 90 |
- --enable-roster-gateway-workaround \ |
|
| 91 |
- $(use_enable irc mod_irc) \ |
|
| 92 |
- $(use_enable ldap eldap) \ |
|
| 93 |
- $(use_enable muc mod_muc) \ |
|
| 94 |
- $(use_enable pubsub mod_pubsub) \ |
|
| 95 |
- $(use_enable ssl tls) \ |
|
| 96 |
- $(use_enable web web) \ |
|
| 97 |
- || die "econf failed" |
|
| 98 |
- |
|
| 99 |
- # |
|
| 100 |
- # Build ejabberd core |
|
| 101 |
- # |
|
| 102 |
- emake || die "compiling ejabberd core failed" |
|
| 103 |
-} |
|
| 104 |
- |
|
| 105 |
-src_install() {
|
|
| 106 |
- # |
|
| 107 |
- # Install ejabberd |
|
| 108 |
- # |
|
| 109 |
- make \ |
|
| 110 |
- DESTDIR=${D} \
|
|
| 111 |
- EJABBERDDIR=${D}/usr/$(get_libdir)/erlang/lib/${P} \
|
|
| 112 |
- ETCDIR=${D}${JABBER_ETC} \
|
|
| 113 |
- LOGDIR=${D}${JABBER_LOG} \
|
|
| 114 |
- install \ |
|
| 115 |
- || die "install failed" |
|
| 116 |
- |
|
| 117 |
- |
|
| 118 |
- insinto /usr/share/doc/${PF}
|
|
| 119 |
- use postgres && doins odbc/pg.sql |
|
| 120 |
- use mysql && doins odbc/mysql.sql |
|
| 121 |
- dodoc doc/release_notes_${PV}.txt
|
|
| 122 |
- dohtml doc/*.{html,png}
|
|
| 123 |
- |
|
| 124 |
- |
|
| 125 |
- use postgres && {
|
|
| 126 |
- pa="-pa /usr/$(get_libdir)/erlang/lib/${E_PGSQL}/ebin"
|
|
| 127 |
- } |
|
| 128 |
- |
|
| 129 |
- use mysql && {
|
|
| 130 |
- pa=${pa}" -pa /usr/$(get_libdir)/erlang/lib/${E_MYSQL}/ebin"
|
|
| 131 |
- } |
|
| 132 |
- |
|
| 133 |
- # |
|
| 134 |
- # Create /usr/bin/ejabberd |
|
| 135 |
- # |
|
| 136 |
- cat <<EOF > ${T}/ejabberd
|
|
| 137 |
-#!/bin/bash |
|
| 138 |
- |
|
| 139 |
-erl -pa /usr/$(get_libdir)/erlang/lib/${P}/ebin \\
|
|
| 140 |
- ${pa} \\
|
|
| 141 |
- -sname ejabberd \\ |
|
| 142 |
- -s ejabberd \\ |
|
| 143 |
- -ejabberd config \"${JABBER_ETC}/ejabberd.cfg\" \\
|
|
| 144 |
- log_path \"${JABBER_LOG}/ejabberd.log\" \\
|
|
| 145 |
- -kernel inetrc \"${JABBER_ETC}/inetrc\" \\
|
|
| 146 |
- -sasl sasl_error_logger \{file,\"${JABBER_LOG}/sasl.log\"\} \\
|
|
| 147 |
- -mnesia dir \"${JABBER_SPOOL}\" \\
|
|
| 148 |
- \$@ |
|
| 149 |
-EOF |
|
| 150 |
- |
|
| 151 |
- # |
|
| 152 |
- # Create /usr/bin/ejabberdctl |
|
| 153 |
- # |
|
| 154 |
- cat <<EOF > ${T}/ejabberdctl
|
|
| 155 |
-#!/bin/sh |
|
| 156 |
- |
|
| 157 |
-exec env HOME=${JABBER_RUN} \\
|
|
| 158 |
- erl -pa /usr/$(get_libdir)/erlang/lib/${P}/ebin \\
|
|
| 159 |
- ${pa} \\
|
|
| 160 |
- -noinput \\ |
|
| 161 |
- -sname ejabberdctl \\ |
|
| 162 |
- -s ejabberd_ctl \\ |
|
| 163 |
- -extra \$@ |
|
| 164 |
-EOF |
|
| 165 |
- |
|
| 166 |
- dobin ${T}/ejabberdctl
|
|
| 167 |
- dobin ${T}/ejabberd
|
|
| 168 |
- |
|
| 169 |
- newinitd ${FILESDIR}/${P}.initd ${PN}
|
|
| 170 |
- newconfd ${FILESDIR}/${P}.confd ${PN}
|
|
| 171 |
- |
|
| 172 |
- insinto ${JABBER_ETC}
|
|
| 173 |
- if use ssl; then |
|
| 174 |
- docert ssl |
|
| 175 |
- rm -f ${D}${JABBER_ETC}/ssl.{crt,csr,key}
|
|
| 176 |
- fowners jabber:jabber ${JABBER_ETC}/ssl.pem
|
|
| 177 |
- fi |
|
| 178 |
- doins ${FILESDIR}/inetrc
|
|
| 179 |
-} |
|
| 180 |
- |
|
| 181 |
-pkg_postinst() {
|
|
| 182 |
- if [ ! -e ${JABBER_ETC}/ejabberd.cfg ]
|
|
| 183 |
- then |
|
| 184 |
- einfo "Configuration file has been installed in ${JABBER_ETC}/ejabberd.cfg."
|
|
| 185 |
- einfo "Edit it according to your needs. For configuration instructions," |
|
| 186 |
- einfo "please see /usr/share/doc/${PF}/html/guide.html"
|
|
| 187 |
- fi |
|
| 188 |
- if use ssl ; then |
|
| 189 |
- einfo "A script to generate a ssl key has been installed in" |
|
| 190 |
- einfo "${JABBER_ETC}/self-cert.sh . Use it and change the config file to"
|
|
| 191 |
- einfo "point to the full path" |
|
| 192 |
- fi |
|
| 193 |
- if ! use web ; then |
|
| 194 |
- einfo "The web USE flag is off, this will disable the web admin interface," |
|
| 195 |
- einfo "if this was not the intention then add web to your USE flags." |
|
| 196 |
- fi |
|
| 197 |
-} |
| ... | ... |
@@ -1,182 +0,0 @@ |
| 1 |
-# Copyright 2005-2006 BreakMyGentoo.net |
|
| 2 |
-# Distributed under the terms of the GNU General Public License v2 |
|
| 3 |
-# $Header: $ |
|
| 4 |
- |
|
| 5 |
-inherit eutils multilib ssl-cert versionator |
|
| 6 |
- |
|
| 7 |
-JABBER_ETC="/etc/jabber" |
|
| 8 |
-JABBER_RUN="/var/run/jabber" |
|
| 9 |
-JABBER_SPOOL="/var/spool/jabber" |
|
| 10 |
-JABBER_LOG="/var/log/jabber" |
|
| 11 |
- |
|
| 12 |
-E_MYSQL_V="0.1" |
|
| 13 |
-E_MYSQL_N="mysql" |
|
| 14 |
-E_MYSQL=${E_MYSQL_N}-${E_MYSQL_V}
|
|
| 15 |
- |
|
| 16 |
-E_PGSQL_V="0.0.1" |
|
| 17 |
-E_PGSQL_N="pgsql-cvs" |
|
| 18 |
-E_PGSQL=${E_PGSQL_N}-${E_PGSQL_V}
|
|
| 19 |
- |
|
| 20 |
-DESCRIPTION="The Erlang Jabber Daemon" |
|
| 21 |
-HOMEPAGE="http://ejabberd.jabber.ru/" |
|
| 22 |
-SRC_URI="http://process-one.net/en/projects/ejabberd/download/${PV}/${P}.tar.gz"
|
|
| 23 |
-LICENSE="GPL-2" |
|
| 24 |
-SLOT="0" |
|
| 25 |
-KEYWORDS="~x86 amd64" |
|
| 26 |
-IUSE="${IUSE} irc ldap muc odbc postgres pubsub web mysql httpbind proxy"
|
|
| 27 |
- |
|
| 28 |
-DEPEND="${RDEPEND}
|
|
| 29 |
- >=net-im/jabber-base-0.00 |
|
| 30 |
- >=dev-libs/expat-1.95 |
|
| 31 |
- >=dev-lang/erlang-10.2.0 |
|
| 32 |
- odbc? ( dev-db/unixODBC ) |
|
| 33 |
- ldap? ( =net-nds/openldap-2* ) |
|
| 34 |
- postgres? ( =dev-erl/${E_PGSQL} )
|
|
| 35 |
- mysql? ( =dev-erl/${E_MYSQL} )"
|
|
| 36 |
- |
|
| 37 |
-RDEPEND="postgres? ( dev-db/postgresql ) |
|
| 38 |
- mysql? ( dev-db/mysql )" |
|
| 39 |
- |
|
| 40 |
-PROVIDE="virtual/jabber-server" |
|
| 41 |
-S=${WORKDIR}/${P}/src
|
|
| 42 |
- |
|
| 43 |
-src_unpack() {
|
|
| 44 |
- unpack ${A}
|
|
| 45 |
- MYSQL_P=$(best_version dev-db/mysql) |
|
| 46 |
- MYSQL_PV=${MYSQL_P/dev-db\/mysql-/}
|
|
| 47 |
- |
|
| 48 |
- |
|
| 49 |
- cd ${S}
|
|
| 50 |
- if use httpbind; then |
|
| 51 |
- epatch ${FILESDIR}/${P}-http_binding.patch || die
|
|
| 52 |
- fi |
|
| 53 |
- |
|
| 54 |
- if use proxy; then |
|
| 55 |
- epatch ${FILESDIR}/${P}-proxy65.patch || die
|
|
| 56 |
- fi |
|
| 57 |
- |
|
| 58 |
- epatch ${FILESDIR}/${P}-mod_irc-utf-8.patch || die
|
|
| 59 |
-} |
|
| 60 |
- |
|
| 61 |
- |
|
| 62 |
-src_compile() {
|
|
| 63 |
- local myconf |
|
| 64 |
- |
|
| 65 |
- if ! use mysql && ! use postgres && ! use odbc; then |
|
| 66 |
- myconf="--disable-odbc" |
|
| 67 |
- else |
|
| 68 |
- myconf="--enable-odbc" |
|
| 69 |
- fi |
|
| 70 |
- |
|
| 71 |
- # |
|
| 72 |
- # configure ejabberd |
|
| 73 |
- # |
|
| 74 |
- econf ${myconf} \
|
|
| 75 |
- --enable-roster-gateway-workaround \ |
|
| 76 |
- $(use_enable irc mod_irc) \ |
|
| 77 |
- $(use_enable ldap eldap) \ |
|
| 78 |
- $(use_enable muc mod_muc) \ |
|
| 79 |
- $(use_enable pubsub mod_pubsub) \ |
|
| 80 |
- $(use_enable ssl tls) \ |
|
| 81 |
- $(use_enable web web) \ |
|
| 82 |
- || die "econf failed" |
|
| 83 |
- |
|
| 84 |
- # |
|
| 85 |
- # Build ejabberd core |
|
| 86 |
- # |
|
| 87 |
- emake || die "compiling ejabberd core failed" |
|
| 88 |
-} |
|
| 89 |
- |
|
| 90 |
-src_install() {
|
|
| 91 |
- # |
|
| 92 |
- # Install ejabberd |
|
| 93 |
- # |
|
| 94 |
- make \ |
|
| 95 |
- DESTDIR=${D} \
|
|
| 96 |
- EJABBERDDIR=${D}/usr/$(get_libdir)/erlang/lib/${P} \
|
|
| 97 |
- ETCDIR=${D}${JABBER_ETC} \
|
|
| 98 |
- LOGDIR=${D}${JABBER_LOG} \
|
|
| 99 |
- install \ |
|
| 100 |
- || die "install failed" |
|
| 101 |
- |
|
| 102 |
- |
|
| 103 |
- insinto /usr/share/doc/${PF}
|
|
| 104 |
- use postgres && doins odbc/pg.sql |
|
| 105 |
- use mysql && doins odbc/mysql.sql |
|
| 106 |
- dodoc doc/release_notes_${PV}.txt
|
|
| 107 |
- dohtml doc/*.{html,png}
|
|
| 108 |
- |
|
| 109 |
- |
|
| 110 |
- use postgres && {
|
|
| 111 |
- pa="-pa /usr/$(get_libdir)/erlang/lib/${E_PGSQL}/ebin"
|
|
| 112 |
- } |
|
| 113 |
- |
|
| 114 |
- use mysql && {
|
|
| 115 |
- pa=${pa}" -pa /usr/$(get_libdir)/erlang/lib/${E_MYSQL}/ebin"
|
|
| 116 |
- } |
|
| 117 |
- |
|
| 118 |
- # |
|
| 119 |
- # Create /usr/bin/ejabberd |
|
| 120 |
- # |
|
| 121 |
- cat <<EOF > ${T}/ejabberd
|
|
| 122 |
-#!/bin/bash |
|
| 123 |
- |
|
| 124 |
-erl -pa /usr/$(get_libdir)/erlang/lib/${P}/ebin \\
|
|
| 125 |
- ${pa} \\
|
|
| 126 |
- -sname ejabberd \\ |
|
| 127 |
- -s ejabberd \\ |
|
| 128 |
- -ejabberd config \"${JABBER_ETC}/ejabberd.cfg\" \\
|
|
| 129 |
- log_path \"${JABBER_LOG}/ejabberd.log\" \\
|
|
| 130 |
- -kernel inetrc \"${JABBER_ETC}/inetrc\" \\
|
|
| 131 |
- -sasl sasl_error_logger \{file,\"${JABBER_LOG}/sasl.log\"\} \\
|
|
| 132 |
- -mnesia dir \"${JABBER_SPOOL}\" \\
|
|
| 133 |
- \$@ |
|
| 134 |
-EOF |
|
| 135 |
- |
|
| 136 |
- # |
|
| 137 |
- # Create /usr/bin/ejabberdctl |
|
| 138 |
- # |
|
| 139 |
- cat <<EOF > ${T}/ejabberdctl
|
|
| 140 |
-#!/bin/sh |
|
| 141 |
- |
|
| 142 |
-exec env HOME=${JABBER_RUN} \\
|
|
| 143 |
- erl -pa /usr/$(get_libdir)/erlang/lib/${P}/ebin \\
|
|
| 144 |
- ${pa} \\
|
|
| 145 |
- -noinput \\ |
|
| 146 |
- -sname ejabberdctl \\ |
|
| 147 |
- -s ejabberd_ctl \\ |
|
| 148 |
- -extra \$@ |
|
| 149 |
-EOF |
|
| 150 |
- |
|
| 151 |
- dobin ${T}/ejabberdctl
|
|
| 152 |
- dobin ${T}/ejabberd
|
|
| 153 |
- |
|
| 154 |
- newinitd ${FILESDIR}/${P}.initd ${PN}
|
|
| 155 |
- newconfd ${FILESDIR}/${P}.confd ${PN}
|
|
| 156 |
- |
|
| 157 |
- insinto ${JABBER_ETC}
|
|
| 158 |
- if use ssl; then |
|
| 159 |
- docert ssl |
|
| 160 |
- rm -f ${D}${JABBER_ETC}/ssl.{crt,csr,key}
|
|
| 161 |
- fowners jabber:jabber ${JABBER_ETC}/ssl.pem
|
|
| 162 |
- fi |
|
| 163 |
- doins ${FILESDIR}/inetrc
|
|
| 164 |
-} |
|
| 165 |
- |
|
| 166 |
-pkg_postinst() {
|
|
| 167 |
- if [ ! -e ${JABBER_ETC}/ejabberd.cfg ]
|
|
| 168 |
- then |
|
| 169 |
- einfo "Configuration file has been installed in ${JABBER_ETC}/ejabberd.cfg."
|
|
| 170 |
- einfo "Edit it according to your needs. For configuration instructions," |
|
| 171 |
- einfo "please see /usr/share/doc/${PF}/html/guide.html"
|
|
| 172 |
- fi |
|
| 173 |
- if use ssl ; then |
|
| 174 |
- einfo "A script to generate a ssl key has been installed in" |
|
| 175 |
- einfo "${JABBER_ETC}/self-cert.sh . Use it and change the config file to"
|
|
| 176 |
- einfo "point to the full path" |
|
| 177 |
- fi |
|
| 178 |
- if ! use web ; then |
|
| 179 |
- einfo "The web USE flag is off, this will disable the web admin interface," |
|
| 180 |
- einfo "if this was not the intention then add web to your USE flags." |
|
| 181 |
- fi |
|
| 182 |
-} |
| ... | ... |
@@ -1,855 +0,0 @@ |
| 1 |
-Index: src/ejabberd.cfg.example |
|
| 2 |
-=================================================================== |
|
| 3 |
---- src/ejabberd.cfg.example (Revision 565) |
|
| 4 |
-+++ src/ejabberd.cfg.example (Arbeitskopie) |
|
| 5 |
-@@ -124,7 +124,7 @@ |
|
| 6 |
- {5269, ejabberd_s2s_in, [{shaper, s2s_shaper},
|
|
| 7 |
- {max_stanza_size, 131072}
|
|
| 8 |
- ]}, |
|
| 9 |
-- {5280, ejabberd_http, [http_poll, web_admin]},
|
|
| 10 |
-+ {5280, ejabberd_http, [http_poll, http_bind, web_admin]},
|
|
| 11 |
- {8888, ejabberd_service, [{access, all},
|
|
| 12 |
- {hosts, ["icq.localhost", "sms.localhost"],
|
|
| 13 |
- [{password, "secret"}]}]}
|
|
| 14 |
-Index: src/web/Makefile.in |
|
| 15 |
-=================================================================== |
|
| 16 |
---- src/web/Makefile.in (Revision 565) |
|
| 17 |
-+++ src/web/Makefile.in (Arbeitskopie) |
|
| 18 |
-@@ -15,7 +15,8 @@ |
|
| 19 |
- $(OUTDIR)/ejabberd_http.beam \ |
|
| 20 |
- $(OUTDIR)/ejabberd_web.beam \ |
|
| 21 |
- $(OUTDIR)/ejabberd_web_admin.beam \ |
|
| 22 |
-- $(OUTDIR)/ejabberd_http_poll.beam |
|
| 23 |
-+ $(OUTDIR)/ejabberd_http_poll.beam \ |
|
| 24 |
-+ $(OUTDIR)/ejabberd_http_bind.beam |
|
| 25 |
- |
|
| 26 |
- all: $(OBJS) |
|
| 27 |
- |
|
| 28 |
-Index: src/web/ejabberd_http_bind.erl |
|
| 29 |
-=================================================================== |
|
| 30 |
---- src/web/ejabberd_http_bind.erl (Revision 0) |
|
| 31 |
-+++ src/web/ejabberd_http_bind.erl (Revision 0) |
|
| 32 |
-@@ -0,0 +1,654 @@ |
|
| 33 |
-+%%%---------------------------------------------------------------------- |
|
| 34 |
-+%%% File : ejabberd_http_bind.erl |
|
| 35 |
-+%%% Author : Stefan Strigler <steve@zeank.in-berlin.de> |
|
| 36 |
-+%%% Purpose : HTTP Binding support (JEP-0124) |
|
| 37 |
-+%%% Created : 21 Sep 2005 by Stefan Strigler <steve@zeank.in-berlin.de> |
|
| 38 |
-+%%% Id : $Id: ejabberd_http_bind.erl,v 1.2 2006/01/16 10:47:50 zeank Exp $ |
|
| 39 |
-+%%%---------------------------------------------------------------------- |
|
| 40 |
-+ |
|
| 41 |
-+-module(ejabberd_http_bind). |
|
| 42 |
-+-author('steve@zeank.in-berlin.de').
|
|
| 43 |
-+-vsn('$Revision: 1.2 $ ').
|
|
| 44 |
-+ |
|
| 45 |
-+-behaviour(gen_fsm). |
|
| 46 |
-+ |
|
| 47 |
-+%% External exports |
|
| 48 |
-+-export([start_link/2, |
|
| 49 |
-+ init/1, |
|
| 50 |
-+ handle_event/3, |
|
| 51 |
-+ handle_sync_event/4, |
|
| 52 |
-+ code_change/4, |
|
| 53 |
-+ handle_info/3, |
|
| 54 |
-+ terminate/3, |
|
| 55 |
-+ send/2, |
|
| 56 |
-+ setopts/2, |
|
| 57 |
-+ controlling_process/2, |
|
| 58 |
-+ close/1, |
|
| 59 |
-+ process_request/1]). |
|
| 60 |
-+ |
|
| 61 |
-+%-define(ejabberd_debug, true). |
|
| 62 |
-+ |
|
| 63 |
-+-include("ejabberd.hrl").
|
|
| 64 |
-+-include("jlib.hrl").
|
|
| 65 |
-+-include("ejabberd_http.hrl").
|
|
| 66 |
-+ |
|
| 67 |
-+-record(http_bind, {id, pid, hold, wait}).
|
|
| 68 |
-+ |
|
| 69 |
-+%% http binding request |
|
| 70 |
-+-record(hbr, {rid,
|
|
| 71 |
-+ key, |
|
| 72 |
-+ in, |
|
| 73 |
-+ out}). |
|
| 74 |
-+ |
|
| 75 |
-+-record(state, {id,
|
|
| 76 |
-+ rid = error, |
|
| 77 |
-+ key, |
|
| 78 |
-+ output = "", |
|
| 79 |
-+ input = "", |
|
| 80 |
-+ waiting_input = false, |
|
| 81 |
-+ last_receiver, |
|
| 82 |
-+ last_poll, |
|
| 83 |
-+ ctime = 0, |
|
| 84 |
-+ timer, |
|
| 85 |
-+ req_list = [] % list of requests |
|
| 86 |
-+ }). |
|
| 87 |
-+ |
|
| 88 |
-+ |
|
| 89 |
-+%-define(DBGFSM, true). |
|
| 90 |
-+ |
|
| 91 |
-+-ifdef(DBGFSM). |
|
| 92 |
-+-define(FSMOPTS, [{debug, [trace]}]).
|
|
| 93 |
-+-else. |
|
| 94 |
-+-define(FSMOPTS, []). |
|
| 95 |
-+-endif. |
|
| 96 |
-+ |
|
| 97 |
-+-define(MAX_REQUESTS, 2). % number of simultaneous requests |
|
| 98 |
-+-define(MIN_POLLING, "2"). % don't poll faster than that or we will shoot you |
|
| 99 |
-+-define(MAX_WAIT, 60). % max num of secs to keep a request on hold |
|
| 100 |
-+-define(MAX_INACTIVITY, 30000). % msecs to wait before terminating idle sessions |
|
| 101 |
-+-define(CT, {"Content-Type", "text/xml; charset=utf-8"}).
|
|
| 102 |
-+-define(BAD_REQUEST, ?CT). |
|
| 103 |
-+ |
|
| 104 |
-+ |
|
| 105 |
-+%%%---------------------------------------------------------------------- |
|
| 106 |
-+%%% API |
|
| 107 |
-+%%%---------------------------------------------------------------------- |
|
| 108 |
-+start(ID, Key) -> |
|
| 109 |
-+ mnesia:create_table(http_bind, |
|
| 110 |
-+ [{ram_copies, [node()]},
|
|
| 111 |
-+ {attributes, record_info(fields, http_bind)}]),
|
|
| 112 |
-+ supervisor:start_child(ejabberd_http_bind_sup, [ID, Key]). |
|
| 113 |
-+ |
|
| 114 |
-+start_link(ID, Key) -> |
|
| 115 |
-+ gen_fsm:start_link(?MODULE, [ID, Key], ?FSMOPTS). |
|
| 116 |
-+ |
|
| 117 |
-+send({http_bind, FsmRef}, Packet) ->
|
|
| 118 |
-+ gen_fsm:sync_send_all_state_event(FsmRef, {send, Packet}).
|
|
| 119 |
-+ |
|
| 120 |
-+setopts({http_bind, FsmRef}, Opts) ->
|
|
| 121 |
-+ case lists:member({active, once}, Opts) of
|
|
| 122 |
-+ true -> |
|
| 123 |
-+ gen_fsm:sync_send_all_state_event(FsmRef, activate); |
|
| 124 |
-+ _ -> |
|
| 125 |
-+ ok |
|
| 126 |
-+ end. |
|
| 127 |
-+ |
|
| 128 |
-+controlling_process(_Socket, _Pid) -> |
|
| 129 |
-+ ok. |
|
| 130 |
-+ |
|
| 131 |
-+close({http_bind, FsmRef}) ->
|
|
| 132 |
-+ catch gen_fsm:sync_send_all_state_event(FsmRef, close). |
|
| 133 |
-+ |
|
| 134 |
-+ |
|
| 135 |
-+process_request(#request{path = [],
|
|
| 136 |
-+ data = Data}) -> |
|
| 137 |
-+ case catch parse_request(Data) of |
|
| 138 |
-+ {ok, ID1, RID, Key, NewKey, Attrs, Packet} ->
|
|
| 139 |
-+ XmppDomain = xml:get_attr_s("to",Attrs),
|
|
| 140 |
-+ if |
|
| 141 |
-+ (ID1 == "") and (XmppDomain == "") -> |
|
| 142 |
-+ {200, [?CT], "<body type='terminate' condition='improper-addressing' xmlns='http://jabber.org/protocol/httpbind'/>"};
|
|
| 143 |
-+ true -> |
|
| 144 |
-+ ID = if |
|
| 145 |
-+ (ID1 == "") -> |
|
| 146 |
-+ %% create new session |
|
| 147 |
-+ NewID = sha:sha(term_to_binary({now(), make_ref()})),
|
|
| 148 |
-+ {ok, Pid} = start(NewID, Key),
|
|
| 149 |
-+ Wait = case |
|
| 150 |
-+ string:to_integer(xml:get_attr_s("wait",Attrs))
|
|
| 151 |
-+ of |
|
| 152 |
-+ {error, _} ->
|
|
| 153 |
-+ ?MAX_WAIT; |
|
| 154 |
-+ {CWait, _} ->
|
|
| 155 |
-+ if |
|
| 156 |
-+ (CWait > ?MAX_WAIT) -> |
|
| 157 |
-+ ?MAX_WAIT; |
|
| 158 |
-+ true -> |
|
| 159 |
-+ CWait |
|
| 160 |
-+ end |
|
| 161 |
-+ end, |
|
| 162 |
-+ Hold = case |
|
| 163 |
-+ string:to_integer(xml:get_attr_s("hold",Attrs))
|
|
| 164 |
-+ of |
|
| 165 |
-+ {error, _} ->
|
|
| 166 |
-+ (?MAX_REQUESTS - 1); |
|
| 167 |
-+ {CHold, _} ->
|
|
| 168 |
-+ if |
|
| 169 |
-+ (CHold > (?MAX_REQUESTS - 1)) -> |
|
| 170 |
-+ (?MAX_REQUESTS - 1); |
|
| 171 |
-+ true -> |
|
| 172 |
-+ CHold |
|
| 173 |
-+ end |
|
| 174 |
-+ end, |
|
| 175 |
-+ mnesia:transaction( |
|
| 176 |
-+ fun() -> |
|
| 177 |
-+ mnesia:write(#http_bind{id = NewID,
|
|
| 178 |
-+ pid = Pid, |
|
| 179 |
-+ wait = Wait, |
|
| 180 |
-+ hold = Hold}) |
|
| 181 |
-+ end), |
|
| 182 |
-+ InPacket = if |
|
| 183 |
-+ (XmppDomain /= "") -> |
|
| 184 |
-+ ["<stream:stream to='", |
|
| 185 |
-+ XmppDomain, |
|
| 186 |
-+ "' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>"]; |
|
| 187 |
-+ true -> |
|
| 188 |
-+ "" |
|
| 189 |
-+ end, |
|
| 190 |
-+ NewID; |
|
| 191 |
-+ true -> |
|
| 192 |
-+ %% old session |
|
| 193 |
-+ Type = xml:get_attr_s("type",Attrs),
|
|
| 194 |
-+ Wait = ?MAX_WAIT, |
|
| 195 |
-+ Hold = (?MAX_REQUESTS - 1), |
|
| 196 |
-+ if |
|
| 197 |
-+ (Type == "terminate") -> |
|
| 198 |
-+ %% terminate session |
|
| 199 |
-+ InPacket = Packet ++ "</stream:stream>"; |
|
| 200 |
-+ true -> |
|
| 201 |
-+ InPacket = Packet |
|
| 202 |
-+ end, |
|
| 203 |
-+ ID1 |
|
| 204 |
-+ end, |
|
| 205 |
-+ ?DEBUG("~n InPacket: ~s ~n", [InPacket]),
|
|
| 206 |
-+ case http_put(ID, RID, Key, NewKey, Hold, InPacket) of |
|
| 207 |
-+ {error, not_exists} ->
|
|
| 208 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 209 |
-+ {error, bad_key} ->
|
|
| 210 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 211 |
-+ [] -> |
|
| 212 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 213 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 214 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop), |
|
| 215 |
-+ {404, [?BAD_REQUEST], ""}
|
|
| 216 |
-+ end; |
|
| 217 |
-+ {error, polling_too_frequently} ->
|
|
| 218 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 219 |
-+ [] -> %% unlikely! (?) |
|
| 220 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 221 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 222 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop), |
|
| 223 |
-+ {403, [?BAD_REQUEST], ""}
|
|
| 224 |
-+ end; |
|
| 225 |
-+ {repeat, OutPacket} ->
|
|
| 226 |
-+ ?DEBUG("http_put said 'repeat!' ...", []),
|
|
| 227 |
-+ send_outpacket(ID, OutPacket); |
|
| 228 |
-+ ok -> |
|
| 229 |
-+ receive_loop(ID,ID1,RID,Wait,Hold,Attrs) |
|
| 230 |
-+ end |
|
| 231 |
-+ end; |
|
| 232 |
-+ _ -> |
|
| 233 |
-+ {400, [?BAD_REQUEST], ""}
|
|
| 234 |
-+ end; |
|
| 235 |
-+process_request(_Request) -> |
|
| 236 |
-+ {400, [], {xmlelement, "h1", [],
|
|
| 237 |
-+ [{xmlcdata, "400 Bad Request"}]}}.
|
|
| 238 |
-+ |
|
| 239 |
-+receive_loop(ID,ID1,RID,Wait,Hold,Attrs) -> |
|
| 240 |
-+ receive |
|
| 241 |
-+ after 100 -> ok |
|
| 242 |
-+ end, |
|
| 243 |
-+ prepare_response(ID,ID1,RID,Wait,Hold,Attrs). |
|
| 244 |
-+ |
|
| 245 |
-+prepare_response(ID,ID1,RID,Wait,Hold,Attrs) -> |
|
| 246 |
-+ case http_get(ID,RID) of |
|
| 247 |
-+ {error, not_exists} ->
|
|
| 248 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 249 |
-+ {ok, keep_on_hold} ->
|
|
| 250 |
-+ receive_loop(ID,ID1,RID,Wait,Hold,Attrs); |
|
| 251 |
-+ {ok, OutPacket} ->
|
|
| 252 |
-+ if |
|
| 253 |
-+ ID == ID1 -> |
|
| 254 |
-+ send_outpacket(ID, OutPacket); |
|
| 255 |
-+ true -> |
|
| 256 |
-+ To = xml:get_attr_s("to",Attrs),
|
|
| 257 |
-+ case xml_stream:parse_element(OutPacket++"</stream:stream>") of |
|
| 258 |
-+ El when element(1, El) == xmlelement -> |
|
| 259 |
-+ {xmlelement, _, OutAttrs, _} = El,
|
|
| 260 |
-+ AuthID = xml:get_attr_s("id", OutAttrs),
|
|
| 261 |
-+ StreamError = false; |
|
| 262 |
-+ {error, _} ->
|
|
| 263 |
-+ AuthID = "", |
|
| 264 |
-+ StreamError = true |
|
| 265 |
-+ end, |
|
| 266 |
-+ if |
|
| 267 |
-+ To == "" -> |
|
| 268 |
-+ {200, [?CT], "<body type='terminate' condition='improper-addressing' xmlns='http://jabber.org/protocol/httpbind'/>"};
|
|
| 269 |
-+ StreamError == true -> |
|
| 270 |
-+ {200, [?CT], "<body type='terminate' condition='host-unknown' xmlns='http://jabber.org/protocol/httpbind'/>"};
|
|
| 271 |
-+ true -> |
|
| 272 |
-+ {200, [?CT],
|
|
| 273 |
-+ xml:element_to_string( |
|
| 274 |
-+ {xmlelement,"body",
|
|
| 275 |
-+ [{"xmlns",
|
|
| 276 |
-+ "http://jabber.org/protocol/httpbind"}, |
|
| 277 |
-+ {"sid",ID},
|
|
| 278 |
-+ {"wait", integer_to_list(Wait)},
|
|
| 279 |
-+ {"requests", integer_to_list(Hold+1)},
|
|
| 280 |
-+ {"inactivity", integer_to_list(trunc(?MAX_INACTIVITY/1000))},
|
|
| 281 |
-+ {"polling", ?MIN_POLLING},
|
|
| 282 |
-+ {"authid", AuthID}
|
|
| 283 |
-+ ],[]})} |
|
| 284 |
-+ end |
|
| 285 |
-+ end |
|
| 286 |
-+ end. |
|
| 287 |
-+ |
|
| 288 |
-+send_outpacket(ID, OutPacket) -> |
|
| 289 |
-+ case OutPacket of |
|
| 290 |
-+ "" -> |
|
| 291 |
-+ {200, [?CT], "<body xmlns='http://jabber.org/protocol/httpbind'/>"};
|
|
| 292 |
-+ "</stream:stream>" -> |
|
| 293 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 294 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 295 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop) |
|
| 296 |
-+ end, |
|
| 297 |
-+ {200, [?CT], "<body xmlns='http://jabber.org/protocol/httpbind'/>"};
|
|
| 298 |
-+ _ -> |
|
| 299 |
-+ case xml_stream:parse_element("<body>"
|
|
| 300 |
-+ ++ OutPacket |
|
| 301 |
-+ ++ "</body>") |
|
| 302 |
-+ of |
|
| 303 |
-+ El when element(1, El) == xmlelement -> |
|
| 304 |
-+ {xmlelement, _, _, OEls} = El,
|
|
| 305 |
-+ TypedEls = [xml:replace_tag_attr("xmlns","jabber:client",OEl) ||
|
|
| 306 |
-+ OEl <- OEls], |
|
| 307 |
-+ ?DEBUG(" --- outgoing data --- ~n~s~n --- outgoing data END --- ~n",
|
|
| 308 |
-+ [xml:element_to_string( |
|
| 309 |
-+ {xmlelement,"body",
|
|
| 310 |
-+ [{"xmlns",
|
|
| 311 |
-+ "http://jabber.org/protocol/httpbind"}], |
|
| 312 |
-+ TypedEls})] |
|
| 313 |
-+ ), |
|
| 314 |
-+ {200, [?CT],
|
|
| 315 |
-+ xml:element_to_string( |
|
| 316 |
-+ {xmlelement,"body",
|
|
| 317 |
-+ [{"xmlns",
|
|
| 318 |
-+ "http://jabber.org/protocol/httpbind"}], |
|
| 319 |
-+ TypedEls})}; |
|
| 320 |
-+ {error, _} ->
|
|
| 321 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 322 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 323 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop) |
|
| 324 |
-+ end, |
|
| 325 |
-+ {200, [?CT],
|
|
| 326 |
-+ "<body type='terminate' condition='internal-server-error' xmlns='http://jabber.org/protocol/httpbind'/>"} |
|
| 327 |
-+ end |
|
| 328 |
-+ end. |
|
| 329 |
-+ |
|
| 330 |
-+%%%---------------------------------------------------------------------- |
|
| 331 |
-+%%% Callback functions from gen_fsm |
|
| 332 |
-+%%%---------------------------------------------------------------------- |
|
| 333 |
-+ |
|
| 334 |
-+%%---------------------------------------------------------------------- |
|
| 335 |
-+%% Func: init/1 |
|
| 336 |
-+%% Returns: {ok, StateName, StateData} |
|
|
| 337 |
-+%% {ok, StateName, StateData, Timeout} |
|
|
| 338 |
-+%% ignore | |
|
| 339 |
-+%% {stop, StopReason}
|
|
| 340 |
-+%%---------------------------------------------------------------------- |
|
| 341 |
-+init([ID, Key]) -> |
|
| 342 |
-+ ?INFO_MSG("started: ~p", [{ID, Key}]),
|
|
| 343 |
-+ Opts = [], % TODO |
|
| 344 |
-+ {ok, C2SPid} = ejabberd_c2s:start({?MODULE, {http_bind, self()}}, Opts),
|
|
| 345 |
-+ ejabberd_c2s:become_controller(C2SPid), |
|
| 346 |
-+ Timer = erlang:start_timer(?MAX_INACTIVITY, self(), []), |
|
| 347 |
-+ {ok, loop, #state{id = ID,
|
|
| 348 |
-+ key = Key, |
|
| 349 |
-+ timer = Timer}}. |
|
| 350 |
-+ |
|
| 351 |
-+%%---------------------------------------------------------------------- |
|
| 352 |
-+%% Func: StateName/2 |
|
| 353 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 354 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 355 |
-+%% {stop, Reason, NewStateData}
|
|
| 356 |
-+%%---------------------------------------------------------------------- |
|
| 357 |
-+ |
|
| 358 |
-+ |
|
| 359 |
-+%%---------------------------------------------------------------------- |
|
| 360 |
-+%% Func: StateName/3 |
|
| 361 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 362 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 363 |
-+%% {reply, Reply, NextStateName, NextStateData} |
|
|
| 364 |
-+%% {reply, Reply, NextStateName, NextStateData, Timeout} |
|
|
| 365 |
-+%% {stop, Reason, NewStateData} |
|
|
| 366 |
-+%% {stop, Reason, Reply, NewStateData}
|
|
| 367 |
-+%%---------------------------------------------------------------------- |
|
| 368 |
-+%state_name(Event, From, StateData) -> |
|
| 369 |
-+% Reply = ok, |
|
| 370 |
-+% {reply, Reply, state_name, StateData}.
|
|
| 371 |
-+ |
|
| 372 |
-+%%---------------------------------------------------------------------- |
|
| 373 |
-+%% Func: handle_event/3 |
|
| 374 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 375 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 376 |
-+%% {stop, Reason, NewStateData}
|
|
| 377 |
-+%%---------------------------------------------------------------------- |
|
| 378 |
-+handle_event(_Event, StateName, StateData) -> |
|
| 379 |
-+ {next_state, StateName, StateData}.
|
|
| 380 |
-+ |
|
| 381 |
-+%%---------------------------------------------------------------------- |
|
| 382 |
-+%% Func: handle_sync_event/4 |
|
| 383 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 384 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 385 |
-+%% {reply, Reply, NextStateName, NextStateData} |
|
|
| 386 |
-+%% {reply, Reply, NextStateName, NextStateData, Timeout} |
|
|
| 387 |
-+%% {stop, Reason, NewStateData} |
|
|
| 388 |
-+%% {stop, Reason, Reply, NewStateData}
|
|
| 389 |
-+%%---------------------------------------------------------------------- |
|
| 390 |
-+handle_sync_event({send, Packet}, _From, StateName, StateData) ->
|
|
| 391 |
-+ Output = [StateData#state.output | Packet], |
|
| 392 |
-+ Reply = ok, |
|
| 393 |
-+ {reply, Reply, StateName, StateData#state{output = Output}};
|
|
| 394 |
-+ |
|
| 395 |
-+handle_sync_event(activate, From, StateName, StateData) -> |
|
| 396 |
-+ case StateData#state.input of |
|
| 397 |
-+ "" -> |
|
| 398 |
-+ {reply, ok, StateName, StateData#state{waiting_input = From}};
|
|
| 399 |
-+ Input -> |
|
| 400 |
-+ From ! {tcp, {http_bind, self()}, list_to_binary(Input)},
|
|
| 401 |
-+ {reply, ok, StateName, StateData#state{input = "",
|
|
| 402 |
-+ waiting_input = false, |
|
| 403 |
-+ last_receiver = From}} |
|
| 404 |
-+ end; |
|
| 405 |
-+ |
|
| 406 |
-+handle_sync_event(stop, _From, _StateName, StateData) -> |
|
| 407 |
-+ Reply = ok, |
|
| 408 |
-+ {stop, normal, Reply, StateData};
|
|
| 409 |
-+ |
|
| 410 |
-+handle_sync_event({http_put, RID, Key, NewKey, Hold, Packet},
|
|
| 411 |
-+ _From, StateName, StateData) -> |
|
| 412 |
-+ %% check if RID valid |
|
| 413 |
-+ RidAllow = case RID of |
|
| 414 |
-+ error -> |
|
| 415 |
-+ false; |
|
| 416 |
-+ _ -> |
|
| 417 |
-+ case StateData#state.rid of |
|
| 418 |
-+ error -> |
|
| 419 |
-+ %% first request - nothing saved so far |
|
| 420 |
-+ true; |
|
| 421 |
-+ OldRID -> |
|
| 422 |
-+ ?DEBUG("state.rid/cur rid: ~p/~p", [OldRID, RID]),
|
|
| 423 |
-+ if |
|
| 424 |
-+ (OldRID < RID) and (RID =< (OldRID + Hold + 1)) -> |
|
| 425 |
-+ true; |
|
| 426 |
-+ (RID =< OldRID) and (RID > OldRID - Hold - 1) -> |
|
| 427 |
-+ repeat; |
|
| 428 |
-+ true -> |
|
| 429 |
-+ false |
|
| 430 |
-+ end |
|
| 431 |
-+ end |
|
| 432 |
-+ end, |
|
| 433 |
-+ %% check if key valid |
|
| 434 |
-+ KeyAllow = case RidAllow of |
|
| 435 |
-+ repeat -> |
|
| 436 |
-+ true; |
|
| 437 |
-+ false -> |
|
| 438 |
-+ false; |
|
| 439 |
-+ true -> |
|
| 440 |
-+ case StateData#state.key of |
|
| 441 |
-+ "" -> |
|
| 442 |
-+ true; |
|
| 443 |
-+ OldKey -> |
|
| 444 |
-+ NextKey = httpd_util:to_lower(hex( |
|
| 445 |
-+ binary_to_list(crypto:sha(Key)))), |
|
| 446 |
-+ ?DEBUG("Key/OldKey/NextKey: ~s/~s/~s", [Key, OldKey, NextKey]),
|
|
| 447 |
-+ if |
|
| 448 |
-+ OldKey == NextKey -> |
|
| 449 |
-+ true; |
|
| 450 |
-+ true -> |
|
| 451 |
-+ ?DEBUG("wrong key: ~s",[Key]),
|
|
| 452 |
-+ false |
|
| 453 |
-+ end |
|
| 454 |
-+ end |
|
| 455 |
-+ end, |
|
| 456 |
-+ {_,TSec,TMSec} = now(),
|
|
| 457 |
-+ TNow = TSec*1000*1000 + TMSec, |
|
| 458 |
-+ LastPoll = if |
|
| 459 |
-+ Packet == "" -> |
|
| 460 |
-+ TNow; |
|
| 461 |
-+ true -> |
|
| 462 |
-+ StateData#state.last_poll |
|
| 463 |
-+ end, |
|
| 464 |
-+ {MinPoll, _} = string:to_integer(?MIN_POLLING),
|
|
| 465 |
-+ if |
|
| 466 |
-+ (Packet == "") and (TNow - StateData#state.last_poll < MinPoll*1000*1000) -> |
|
| 467 |
-+ Reply = {error, polling_too_frequently},
|
|
| 468 |
-+ {reply, Reply, StateName, StateData};
|
|
| 469 |
-+ KeyAllow -> |
|
| 470 |
-+ case RidAllow of |
|
| 471 |
-+ false -> |
|
| 472 |
-+ Reply = {error, not_exists},
|
|
| 473 |
-+ {reply, Reply, StateName, StateData};
|
|
| 474 |
-+ repeat -> |
|
| 475 |
-+ ?DEBUG("repeating ~p", [RID]),
|
|
| 476 |
-+ [Out | _XS] = [El#hbr.out || El <- StateData#state.req_list, El#hbr.rid == RID], |
|
| 477 |
-+ case Out of |
|
| 478 |
-+ [[] | OutPacket] -> |
|
| 479 |
-+ Reply = {repeat, OutPacket};
|
|
| 480 |
-+ _ -> |
|
| 481 |
-+ Reply = {repeat, Out}
|
|
| 482 |
-+ end, |
|
| 483 |
-+ {reply, Reply, StateName, StateData#state{last_poll = LastPoll}};
|
|
| 484 |
-+ true -> |
|
| 485 |
-+ SaveKey = if |
|
| 486 |
-+ NewKey == "" -> |
|
| 487 |
-+ Key; |
|
| 488 |
-+ true -> |
|
| 489 |
-+ NewKey |
|
| 490 |
-+ end, |
|
| 491 |
-+ ?DEBUG(" -- SaveKey: ~s~n", [SaveKey]),
|
|
| 492 |
-+ |
|
| 493 |
-+ %% save request |
|
| 494 |
-+ ReqList = [#hbr{rid=RID,
|
|
| 495 |
-+ key=StateData#state.key, |
|
| 496 |
-+ in=StateData#state.input, |
|
| 497 |
-+ out=StateData#state.output |
|
| 498 |
-+ } | |
|
| 499 |
-+ [El || El <- StateData#state.req_list, |
|
| 500 |
-+ El#hbr.rid < RID, El#hbr.rid > (RID - 1 - Hold) ] |
|
| 501 |
-+ ], |
|
| 502 |
-+ |
|
| 503 |
-+ ?DEBUG("reqlist: ~p", [ReqList]),
|
|
| 504 |
-+ |
|
| 505 |
-+ case StateData#state.waiting_input of |
|
| 506 |
-+ false -> |
|
| 507 |
-+ cancel_timer(StateData#state.timer), |
|
| 508 |
-+ Timer = erlang:start_timer(?MAX_INACTIVITY, self(), []), |
|
| 509 |
-+ Input = Packet ++ [StateData#state.input], |
|
| 510 |
-+ Reply = ok, |
|
| 511 |
-+ {reply, Reply, StateName,
|
|
| 512 |
-+ StateData#state{input = Input,
|
|
| 513 |
-+ rid = RID, |
|
| 514 |
-+ key = SaveKey, |
|
| 515 |
-+ ctime = TNow, |
|
| 516 |
-+ timer = Timer, |
|
| 517 |
-+ last_poll = LastPoll, |
|
| 518 |
-+ req_list = ReqList |
|
| 519 |
-+ }}; |
|
| 520 |
-+ {Receiver, _Tag} ->
|
|
| 521 |
-+ Receiver ! {tcp, {http_bind, self()},
|
|
| 522 |
-+ list_to_binary(Packet)}, |
|
| 523 |
-+ cancel_timer(StateData#state.timer), |
|
| 524 |
-+ Timer = erlang:start_timer(?MAX_INACTIVITY, self(), []), |
|
| 525 |
-+ Reply = ok, |
|
| 526 |
-+ {reply, Reply, StateName,
|
|
| 527 |
-+ StateData#state{waiting_input = false,
|
|
| 528 |
-+ last_receiver = Receiver, |
|
| 529 |
-+ input = "", |
|
| 530 |
-+ rid = RID, |
|
| 531 |
-+ key = SaveKey, |
|
| 532 |
-+ ctime = TNow, |
|
| 533 |
-+ timer = Timer, |
|
| 534 |
-+ last_poll = LastPoll, |
|
| 535 |
-+ req_list = ReqList |
|
| 536 |
-+ }} |
|
| 537 |
-+ end |
|
| 538 |
-+ end; |
|
| 539 |
-+ true -> |
|
| 540 |
-+ Reply = {error, bad_key},
|
|
| 541 |
-+ {reply, Reply, StateName, StateData}
|
|
| 542 |
-+ end; |
|
| 543 |
-+ |
|
| 544 |
-+handle_sync_event({http_get, RID, Wait, Hold}, _From, StateName, StateData) ->
|
|
| 545 |
-+ {_,TSec,TMSec} = now(),
|
|
| 546 |
-+ TNow = TSec*1000*1000 + TMSec, |
|
| 547 |
-+%% ?DEBUG("Wait/Hold/cTime/Now: ~p/~p/~p/~p", [Wait, Hold, StateData#state.ctime,TNow]),
|
|
| 548 |
-+ cancel_timer(StateData#state.timer), |
|
| 549 |
-+ Timer = erlang:start_timer(?MAX_INACTIVITY, self(), []), |
|
| 550 |
-+ if |
|
| 551 |
-+ (Hold > 0) and |
|
| 552 |
-+ (StateData#state.output == "") and |
|
| 553 |
-+ ((TNow - StateData#state.ctime) < (Wait*1000*1000)) and |
|
| 554 |
-+ (StateData#state.rid == RID) -> |
|
| 555 |
-+ Output = StateData#state.output, |
|
| 556 |
-+ ReqList = StateData#state.req_list, |
|
| 557 |
-+ Reply = {ok, keep_on_hold};
|
|
| 558 |
-+ true -> |
|
| 559 |
-+ case StateData#state.output of |
|
| 560 |
-+ [[]| OutPacket] -> |
|
| 561 |
-+ Reply = {ok, OutPacket};
|
|
| 562 |
-+ _ -> |
|
| 563 |
-+ Reply = {ok, StateData#state.output}
|
|
| 564 |
-+ end, |
|
| 565 |
-+ %% save request |
|
| 566 |
-+ ReqList = [#hbr{rid=RID,
|
|
| 567 |
-+ key=StateData#state.key, |
|
| 568 |
-+ in=StateData#state.input, |
|
| 569 |
-+ out=StateData#state.output |
|
| 570 |
-+ } | |
|
| 571 |
-+ [El || El <- StateData#state.req_list, |
|
| 572 |
-+ El#hbr.rid /= RID ] |
|
| 573 |
-+ ], |
|
| 574 |
-+ Output = "" |
|
| 575 |
-+ end, |
|
| 576 |
-+ {reply, Reply, StateName, StateData#state{output = Output,
|
|
| 577 |
-+ timer = Timer, |
|
| 578 |
-+ req_list = ReqList}}; |
|
| 579 |
-+ |
|
| 580 |
-+handle_sync_event(_Event, _From, StateName, StateData) -> |
|
| 581 |
-+ Reply = ok, |
|
| 582 |
-+ {reply, Reply, StateName, StateData}.
|
|
| 583 |
-+ |
|
| 584 |
-+code_change(_OldVsn, StateName, StateData, _Extra) -> |
|
| 585 |
-+ {ok, StateName, StateData}.
|
|
| 586 |
-+ |
|
| 587 |
-+%%---------------------------------------------------------------------- |
|
| 588 |
-+%% Func: handle_info/3 |
|
| 589 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 590 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 591 |
-+%% {stop, Reason, NewStateData}
|
|
| 592 |
-+%%---------------------------------------------------------------------- |
|
| 593 |
-+handle_info({timeout, Timer, _}, _StateName,
|
|
| 594 |
-+ #state{timer = Timer} = StateData) ->
|
|
| 595 |
-+ ?DEBUG("ding dong", []),
|
|
| 596 |
-+ {stop, normal, StateData};
|
|
| 597 |
-+ |
|
| 598 |
-+handle_info(_, StateName, StateData) -> |
|
| 599 |
-+ {next_state, StateName, StateData}.
|
|
| 600 |
-+ |
|
| 601 |
-+%%---------------------------------------------------------------------- |
|
| 602 |
-+%% Func: terminate/3 |
|
| 603 |
-+%% Purpose: Shutdown the fsm |
|
| 604 |
-+%% Returns: any |
|
| 605 |
-+%%---------------------------------------------------------------------- |
|
| 606 |
-+terminate(_Reason, _StateName, StateData) -> |
|
| 607 |
-+ ?DEBUG("terminate: deleting session ~s", [StateData#state.id]),
|
|
| 608 |
-+ mnesia:transaction( |
|
| 609 |
-+ fun() -> |
|
| 610 |
-+ mnesia:delete({http_bind, StateData#state.id})
|
|
| 611 |
-+ end), |
|
| 612 |
-+ case StateData#state.waiting_input of |
|
| 613 |
-+ false -> |
|
| 614 |
-+ case StateData#state.last_receiver of |
|
| 615 |
-+ undefined -> ok; |
|
| 616 |
-+ Receiver -> Receiver ! {tcp_closed, {http_bind, self()}}
|
|
| 617 |
-+ end; |
|
| 618 |
-+ {Receiver, _Tag} -> Receiver ! {tcp_closed, {http_bind, self()}}
|
|
| 619 |
-+ end, |
|
| 620 |
-+ ok. |
|
| 621 |
-+ |
|
| 622 |
-+%%%---------------------------------------------------------------------- |
|
| 623 |
-+%%% Internal functions |
|
| 624 |
-+%%%---------------------------------------------------------------------- |
|
| 625 |
-+ |
|
| 626 |
-+ |
|
| 627 |
-+http_put(ID, RID, Key, NewKey, Hold, Packet) -> |
|
| 628 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 629 |
-+ [] -> |
|
| 630 |
-+ {error, not_exists};
|
|
| 631 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 632 |
-+ gen_fsm:sync_send_all_state_event( |
|
| 633 |
-+ FsmRef, {http_put, RID, Key, NewKey, Hold, Packet})
|
|
| 634 |
-+ end. |
|
| 635 |
-+ |
|
| 636 |
-+http_get(ID,RID) -> |
|
| 637 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 638 |
-+ [] -> |
|
| 639 |
-+ {error, not_exists};
|
|
| 640 |
-+ [#http_bind{pid = FsmRef, wait = Wait, hold = Hold}] ->
|
|
| 641 |
-+ gen_fsm:sync_send_all_state_event(FsmRef, {http_get, RID, Wait, Hold})
|
|
| 642 |
-+ end. |
|
| 643 |
-+ |
|
| 644 |
-+ |
|
| 645 |
-+parse_request(Data) -> |
|
| 646 |
-+ ?DEBUG("--- incoming data --- ~n~s~n --- END incoming data END --- ",[Data]),
|
|
| 647 |
-+ case xml_stream:parse_element(Data) of |
|
| 648 |
-+ El when element(1, El) == xmlelement -> |
|
| 649 |
-+ {xmlelement, Name, Attrs, Els} = El,
|
|
| 650 |
-+ ID = xml:get_attr_s("sid",Attrs),
|
|
| 651 |
-+ {RID,_X} = string:to_integer(xml:get_attr_s("rid",Attrs)),
|
|
| 652 |
-+ Key = xml:get_attr_s("key",Attrs),
|
|
| 653 |
-+ NewKey = xml:get_attr_s("newkey",Attrs),
|
|
| 654 |
-+ Xmlns = xml:get_attr_s("xmlns",Attrs),
|
|
| 655 |
-+ Packet = [xml:element_to_string(xml:remove_tag_attr("xmlns",E)) || E <- Els],
|
|
| 656 |
-+ ?DEBUG(" --- incoming packet --- ~n~s~n --- END incoming packet END --- ", [Packet]),
|
|
| 657 |
-+ if |
|
| 658 |
-+ Name /= "body" -> |
|
| 659 |
-+ {error, bad_request};
|
|
| 660 |
-+ Xmlns /= "http://jabber.org/protocol/httpbind" -> |
|
| 661 |
-+ {error, bad_request};
|
|
| 662 |
-+ true -> |
|
| 663 |
-+ {ok, ID, RID, Key, NewKey, Attrs, Packet}
|
|
| 664 |
-+ end; |
|
| 665 |
-+ {error, _Reason} ->
|
|
| 666 |
-+ {error, bad_request}
|
|
| 667 |
-+ end. |
|
| 668 |
-+ |
|
| 669 |
-+cancel_timer(Timer) -> |
|
| 670 |
-+ erlang:cancel_timer(Timer), |
|
| 671 |
-+ receive |
|
| 672 |
-+ {timeout, Timer, _} ->
|
|
| 673 |
-+ ok |
|
| 674 |
-+ after 0 -> |
|
| 675 |
-+ ok |
|
| 676 |
-+ end. |
|
| 677 |
-+ |
|
| 678 |
-+hex(Bin) when binary(Bin) -> hex(binary_to_list(Bin)); |
|
| 679 |
-+hex([]) -> ""; |
|
| 680 |
-+hex([H|T]) -> |
|
| 681 |
-+ [A,B] = if |
|
| 682 |
-+ H == 0 -> "00"; |
|
| 683 |
-+ H < 16 -> [$0,element(H,{$1,$2,$3,$4,$5,$6,$7,$8,$9,$a,$b,$c,$d,$e,$f})];
|
|
| 684 |
-+ true -> erlang:integer_to_list(H,16) |
|
| 685 |
-+ end, |
|
| 686 |
-+ [A,B|hex(T)]. |
|
| 687 |
-Index: src/web/ejabberd_web.erl |
|
| 688 |
-=================================================================== |
|
| 689 |
---- src/web/ejabberd_web.erl (Revision 565) |
|
| 690 |
-+++ src/web/ejabberd_web.erl (Arbeitskopie) |
|
| 691 |
-@@ -49,7 +49,7 @@ |
|
| 692 |
- {"value", Value}])).
|
|
| 693 |
- |
|
| 694 |
- |
|
| 695 |
--process_get({_, true},
|
|
| 696 |
-+process_get({_, _, true},
|
|
| 697 |
- #request{auth = Auth,
|
|
| 698 |
- path = ["admin", "server", SHost | RPath], |
|
| 699 |
- q = Query, |
|
| 700 |
-@@ -94,7 +94,7 @@ |
|
| 701 |
- {404, [], make_xhtml([?XC("h1", "Not found")])}
|
|
| 702 |
- end; |
|
| 703 |
- |
|
| 704 |
--process_get({_, true},
|
|
| 705 |
-+process_get({_, _, true},
|
|
| 706 |
- #request{auth = Auth,
|
|
| 707 |
- path = ["admin" | RPath], |
|
| 708 |
- q = Query, |
|
| 709 |
-@@ -133,12 +133,19 @@ |
|
| 710 |
- [{xmlcdata, "401 Unauthorized"}]}])}
|
|
| 711 |
- end; |
|
| 712 |
- |
|
| 713 |
--process_get({true, _},
|
|
| 714 |
-+process_get({true, _, _},
|
|
| 715 |
- #request{path = ["http-poll" | RPath],
|
|
| 716 |
- q = _Query, |
|
| 717 |
- lang = _Lang} = Request) -> |
|
| 718 |
- ejabberd_http_poll:process_request(Request#request{path = RPath});
|
|
| 719 |
- |
|
| 720 |
-+process_get({_, true, _},
|
|
| 721 |
-+ #request{us = _US,
|
|
| 722 |
-+ path = ["http-bind" | RPath], |
|
| 723 |
-+ q = _Query, |
|
| 724 |
-+ lang = _Lang} = Request) -> |
|
| 725 |
-+ ejabberd_http_bind:process_request(Request#request{path = RPath});
|
|
| 726 |
-+ |
|
| 727 |
- process_get(_, _Request) -> |
|
| 728 |
- {404, [], make_xhtml([?XC("h1", "Not found")])}.
|
|
| 729 |
- |
|
| 730 |
-Index: src/web/ejabberd_http.erl |
|
| 731 |
-=================================================================== |
|
| 732 |
---- src/web/ejabberd_http.erl (Revision 565) |
|
| 733 |
-+++ src/web/ejabberd_http.erl (Arbeitskopie) |
|
| 734 |
-@@ -30,6 +30,7 @@ |
|
| 735 |
- request_keepalive, |
|
| 736 |
- request_content_length, |
|
| 737 |
- request_lang = "en", |
|
| 738 |
-+ use_http_bind = false, |
|
| 739 |
- use_http_poll = false, |
|
| 740 |
- use_web_admin = false, |
|
| 741 |
- end_of_request = false, |
|
| 742 |
-@@ -70,15 +71,17 @@ |
|
| 743 |
- _ -> |
|
| 744 |
- ok |
|
| 745 |
- end, |
|
| 746 |
-+ UseHTTPBind = lists:member(http_bind, Opts), |
|
| 747 |
- UseHTTPPoll = lists:member(http_poll, Opts), |
|
| 748 |
- UseWebAdmin = lists:member(web_admin, Opts), |
|
| 749 |
-- ?DEBUG("S: ~p~n", [{UseHTTPPoll, UseWebAdmin}]),
|
|
| 750 |
-+ ?DEBUG("S: ~p~n", [{UseHTTPPoll, UseHTTPBind, UseWebAdmin}]),
|
|
| 751 |
- ?INFO_MSG("started: ~p", [{SockMod1, Socket1}]),
|
|
| 752 |
- {ok, proc_lib:spawn_link(ejabberd_http,
|
|
| 753 |
- receive_headers, |
|
| 754 |
- [#state{sockmod = SockMod1,
|
|
| 755 |
- socket = Socket1, |
|
| 756 |
- use_http_poll = UseHTTPPoll, |
|
| 757 |
-+ use_http_bind = UseHTTPBind, |
|
| 758 |
- use_web_admin = UseWebAdmin}])}. |
|
| 759 |
- |
|
| 760 |
- |
|
| 761 |
-@@ -185,6 +188,7 @@ |
|
| 762 |
- #state{sockmod = SockMod,
|
|
| 763 |
- socket = Socket, |
|
| 764 |
- use_http_poll = State#state.use_http_poll, |
|
| 765 |
-+ use_http_bind = State#state.use_http_bind, |
|
| 766 |
- use_web_admin = State#state.use_web_admin}; |
|
| 767 |
- _ -> |
|
| 768 |
- #state{end_of_request = true}
|
|
| 769 |
-@@ -200,6 +204,7 @@ |
|
| 770 |
- request_auth = Auth, |
|
| 771 |
- request_lang = Lang, |
|
| 772 |
- use_http_poll = UseHTTPPoll, |
|
| 773 |
-+ use_http_bind = UseHTTPBind, |
|
| 774 |
- use_web_admin = UseWebAdmin} = State) -> |
|
| 775 |
- case (catch url_decode_q_split(Path)) of |
|
| 776 |
- {'EXIT', _} ->
|
|
| 777 |
-@@ -217,7 +222,7 @@ |
|
| 778 |
- q = LQuery, |
|
| 779 |
- auth = Auth, |
|
| 780 |
- lang = Lang}, |
|
| 781 |
-- case ejabberd_web:process_get({UseHTTPPoll, UseWebAdmin},
|
|
| 782 |
-+ case ejabberd_web:process_get({UseHTTPPoll, UseHTTPBind, UseWebAdmin},
|
|
| 783 |
- Request) of |
|
| 784 |
- El when element(1, El) == xmlelement -> |
|
| 785 |
- make_xhtml_output(State, 200, [], El); |
|
| 786 |
-@@ -240,6 +245,7 @@ |
|
| 787 |
- sockmod = SockMod, |
|
| 788 |
- socket = Socket, |
|
| 789 |
- use_http_poll = UseHTTPPoll, |
|
| 790 |
-+ use_http_bind = UseHTTPBind, |
|
| 791 |
- use_web_admin = UseWebAdmin} = State) |
|
| 792 |
- when is_integer(Len) -> |
|
| 793 |
- case SockMod of |
|
| 794 |
-@@ -267,7 +273,7 @@ |
|
| 795 |
- auth = Auth, |
|
| 796 |
- data = Data, |
|
| 797 |
- lang = Lang}, |
|
| 798 |
-- case ejabberd_web:process_get({UseHTTPPoll, UseWebAdmin},
|
|
| 799 |
-+ case ejabberd_web:process_get({UseHTTPPoll, UseHTTPBind, UseWebAdmin},
|
|
| 800 |
- Request) of |
|
| 801 |
- El when element(1, El) == xmlelement -> |
|
| 802 |
- make_xhtml_output(State, 200, [], El); |
|
| 803 |
-Index: src/xml.erl |
|
| 804 |
-=================================================================== |
|
| 805 |
---- src/xml.erl (Revision 565) |
|
| 806 |
-+++ src/xml.erl (Arbeitskopie) |
|
| 807 |
-@@ -18,6 +18,7 @@ |
|
| 808 |
- get_tag_attr/2, get_tag_attr_s/2, |
|
| 809 |
- get_subtag/2, |
|
| 810 |
- get_path_s/2, |
|
| 811 |
-+ remove_tag_attr/2, |
|
| 812 |
- replace_tag_attr/3]). |
|
| 813 |
- |
|
| 814 |
- %element_to_string(El) -> |
|
| 815 |
-@@ -224,6 +225,14 @@ |
|
| 816 |
- get_path_s(El, [cdata]) -> |
|
| 817 |
- get_tag_cdata(El). |
|
| 818 |
- |
|
| 819 |
-+remove_tag_attr(Attr, El) -> |
|
| 820 |
-+ case El of |
|
| 821 |
-+ {xmlelement, Name, Attrs, Els} ->
|
|
| 822 |
-+ Attrs1 = lists:keydelete(Attr, 1, Attrs), |
|
| 823 |
-+ {xmlelement, Name, Attrs1, Els};
|
|
| 824 |
-+ _ -> |
|
| 825 |
-+ El |
|
| 826 |
-+ end. |
|
| 827 |
- |
|
| 828 |
- replace_tag_attr(Attr, Value, {xmlelement, Name, Attrs, Els}) ->
|
|
| 829 |
- Attrs1 = lists:keydelete(Attr, 1, Attrs), |
|
| 830 |
-Index: src/ejabberd_sup.erl |
|
| 831 |
-=================================================================== |
|
| 832 |
---- src/ejabberd_sup.erl (Revision 565) |
|
| 833 |
-+++ src/ejabberd_sup.erl (Arbeitskopie) |
|
| 834 |
-@@ -123,6 +123,14 @@ |
|
| 835 |
- infinity, |
|
| 836 |
- supervisor, |
|
| 837 |
- [ejabberd_tmp_sup]}, |
|
| 838 |
-+ HTTPBindSupervisor = |
|
| 839 |
-+ {ejabberd_http_bind_sup,
|
|
| 840 |
-+ {ejabberd_tmp_sup, start_link,
|
|
| 841 |
-+ [ejabberd_http_bind_sup, ejabberd_http_bind]}, |
|
| 842 |
-+ permanent, |
|
| 843 |
-+ infinity, |
|
| 844 |
-+ supervisor, |
|
| 845 |
-+ [ejabberd_tmp_sup]}, |
|
| 846 |
- IQSupervisor = |
|
| 847 |
- {ejabberd_iq_sup,
|
|
| 848 |
- {ejabberd_tmp_sup, start_link,
|
|
| 849 |
-@@ -145,6 +153,7 @@ |
|
| 850 |
- ServiceSupervisor, |
|
| 851 |
- HTTPSupervisor, |
|
| 852 |
- HTTPPollSupervisor, |
|
| 853 |
-+ HTTPBindSupervisor, |
|
| 854 |
- IQSupervisor, |
|
| 855 |
- Listener]}}. |
| ... | ... |
@@ -1,11 +0,0 @@ |
| 1 |
-diff -Naur ejabberd-1.1.1.orig/src/odbc/ejabberd_odbc.erl ejabberd-1.1.1/src/odbc/ejabberd_odbc.erl |
|
| 2 |
---- ejabberd-1.1.1.orig/src/odbc/ejabberd_odbc.erl 2006-05-07 19:05:12.549917750 +0400 |
|
| 3 |
-+++ ejabberd-1.1.1/src/odbc/ejabberd_odbc.erl 2006-05-07 19:06:11.337591750 +0400 |
|
| 4 |
-@@ -281,6 +281,7 @@ |
|
| 5 |
- case mysql_conn:start(Server, ?MYSQL_PORT, Username, Password, DB, NoLogFun) of |
|
| 6 |
- {ok, Ref} ->
|
|
| 7 |
- erlang:monitor(process, Ref), |
|
| 8 |
-+ catch mysql_conn:fetch(Ref, "SET NAMES 'utf8';", self()), |
|
| 9 |
- {ok, #state{db_ref = Ref, db_type = mysql}};
|
|
| 10 |
- {error, Reason} ->
|
|
| 11 |
- ?ERROR_MSG("MySQL connection failed: ~p~n", [Reason]),
|
| ... | ... |
@@ -1,406 +0,0 @@ |
| 1 |
-* modified files |
|
| 2 |
- |
|
| 3 |
- |
|
| 4 |
---- jlib.hrl |
|
| 5 |
-+++ jlib.hrl |
|
| 6 |
-@@ -34,6 +34,7 @@ |
|
| 7 |
- -define(NS_PUBSUB_OWNER, "http://jabber.org/protocol/pubsub#owner"). |
|
| 8 |
- -define(NS_PUBSUB_NMI, "http://jabber.org/protocol/pubsub#node-meta-info"). |
|
| 9 |
- -define(NS_COMMANDS, "http://jabber.org/protocol/commands"). |
|
| 10 |
-+-define(NS_BYTESTREAMS, "http://jabber.org/protocol/bytestreams"). |
|
| 11 |
- |
|
| 12 |
- -define(NS_EJABBERD_CONFIG, "ejabberd:config"). |
|
| 13 |
- |
|
| 14 |
- |
|
| 15 |
- |
|
| 16 |
- |
|
| 17 |
-* added files |
|
| 18 |
- |
|
| 19 |
---- /dev/null |
|
| 20 |
-+++ mod_proxy65.erl |
|
| 21 |
-@@ -0,0 +1,189 @@ |
|
| 22 |
-+%%%---------------------------------------------------------------------- |
|
| 23 |
-+%%% File : mod_proxy65.erl |
|
| 24 |
-+%%% Author : Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 25 |
-+%%% Purpose : Handle Jabber communications for JEP-0065 proxy |
|
| 26 |
-+%%% Created : 27 Dec 2005 by Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 27 |
-+%%% Id : $Id: ejabberd_c2s.erl 440 2005-11-22 18:00:56Z alexey $ |
|
| 28 |
-+%%%---------------------------------------------------------------------- |
|
| 29 |
-+ |
|
| 30 |
-+-module(mod_proxy65). |
|
| 31 |
-+-author('henoch@dtek.chalmers.se').
|
|
| 32 |
-+-vsn('$Revision$ ').
|
|
| 33 |
-+ |
|
| 34 |
-+-behaviour(gen_mod). |
|
| 35 |
-+ |
|
| 36 |
-+-export([start/2, |
|
| 37 |
-+ init/1, |
|
| 38 |
-+ stop/1]). |
|
| 39 |
-+ |
|
| 40 |
-+-include("ejabberd.hrl").
|
|
| 41 |
-+-include("jlib.hrl").
|
|
| 42 |
-+ |
|
| 43 |
-+-record(proxy65_connection, {cookie, firstpid = none, secondpid = none}).
|
|
| 44 |
-+ |
|
| 45 |
-+-record(proxy65_options, {host, access, streamhosts}).
|
|
| 46 |
-+ |
|
| 47 |
-+-define(PROCNAME, ejabberd_mod_proxy65). |
|
| 48 |
-+ |
|
| 49 |
-+start(Host, Opts) -> |
|
| 50 |
-+ mnesia:create_table(proxy65_connection, |
|
| 51 |
-+ [{ram_copies, [node()]},
|
|
| 52 |
-+ {attributes, record_info(fields, proxy65_connection)}]),
|
|
| 53 |
-+ MyHost = gen_mod:get_opt(host, Opts, "proxy." ++ Host), |
|
| 54 |
-+ Access = gen_mod:get_opt(access, Opts, all), |
|
| 55 |
-+ Streamhosts = gen_mod:get_opt(streamhosts, Opts, [{Host, 7777}]),
|
|
| 56 |
-+ |
|
| 57 |
-+ register(gen_mod:get_module_proc(Host, ?PROCNAME), |
|
| 58 |
-+ spawn(?MODULE, init, [#proxy65_options{host = MyHost, access = Access,
|
|
| 59 |
-+ streamhosts = Streamhosts}])). |
|
| 60 |
-+ |
|
| 61 |
-+ |
|
| 62 |
-+stop(Host) -> |
|
| 63 |
-+ Proc = gen_mod:get_module_proc(Host, ?PROCNAME), |
|
| 64 |
-+ Proc ! stop, |
|
| 65 |
-+ {wait, Proc}.
|
|
| 66 |
-+ |
|
| 67 |
-+init(#proxy65_options{host = Host} = Opts) ->
|
|
| 68 |
-+ ejabberd_router:register_route(Host), |
|
| 69 |
-+ loop(Opts). |
|
| 70 |
-+ |
|
| 71 |
-+loop(#proxy65_options{host = Host} = Opts) ->
|
|
| 72 |
-+ receive |
|
| 73 |
-+ {route, From, To, Packet} ->
|
|
| 74 |
-+ case catch do_route(Opts, From, To, Packet) of |
|
| 75 |
-+ {'EXIT', Reason} ->
|
|
| 76 |
-+ ?ERROR_MSG("~p", [Reason]);
|
|
| 77 |
-+ _ -> |
|
| 78 |
-+ ok |
|
| 79 |
-+ end, |
|
| 80 |
-+ loop(Opts); |
|
| 81 |
-+ stop -> |
|
| 82 |
-+ ejabberd_router:unregister_route(Host), |
|
| 83 |
-+ ok; |
|
| 84 |
-+ _ -> |
|
| 85 |
-+ loop(Opts) |
|
| 86 |
-+ end. |
|
| 87 |
-+ |
|
| 88 |
-+do_route(#proxy65_options{host = Host, access = Access} = Opts,
|
|
| 89 |
-+ From, To, Packet) -> |
|
| 90 |
-+ case acl:match_rule(Host, Access, From) of |
|
| 91 |
-+ allow -> |
|
| 92 |
-+ do_route1(Opts, From, To, Packet); |
|
| 93 |
-+ _ -> |
|
| 94 |
-+ {xmlelement, _Name, Attrs, _Els} = Packet,
|
|
| 95 |
-+ Lang = xml:get_attr_s("xml:lang", Attrs),
|
|
| 96 |
-+ ErrText = "Access denied by service policy", |
|
| 97 |
-+ Err = jlib:make_error_reply(Packet, |
|
| 98 |
-+ ?ERRT_FORBIDDEN(Lang, ErrText)), |
|
| 99 |
-+ ejabberd_router:route(To, From, Err) |
|
| 100 |
-+ end. |
|
| 101 |
-+ |
|
| 102 |
-+do_route1(#proxy65_options{host = Host, streamhosts = Streamhosts}, From, To, Packet) ->
|
|
| 103 |
-+ {xmlelement, Name, _Attrs, _Els} = Packet,
|
|
| 104 |
-+ case Name of |
|
| 105 |
-+ "iq" -> |
|
| 106 |
-+ case jlib:iq_query_info(Packet) of |
|
| 107 |
-+ #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
|
|
| 108 |
-+ lang = Lang, sub_el = SubEl} = IQ -> |
|
| 109 |
-+ Node = xml:get_tag_attr_s("node", SubEl),
|
|
| 110 |
-+ if Node == [] -> |
|
| 111 |
-+ Res = IQ#iq{type = result,
|
|
| 112 |
-+ sub_el = [{xmlelement, "query",
|
|
| 113 |
-+ [{"xmlns", XMLNS}],
|
|
| 114 |
-+ [{xmlelement, "identity",
|
|
| 115 |
-+ [{"category", "proxy"},
|
|
| 116 |
-+ {"type", "bytestreams"},
|
|
| 117 |
-+ {"name", translate:translate(Lang, "SOCKS5 bytestreams proxy")}],
|
|
| 118 |
-+ []}, |
|
| 119 |
-+ {xmlelement, "feature",
|
|
| 120 |
-+ [{"var", ?NS_BYTESTREAMS}], []}]}]};
|
|
| 121 |
-+ true -> |
|
| 122 |
-+ Res = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND) |
|
| 123 |
-+ end; |
|
| 124 |
-+ #iq{type = get, xmlns = ?NS_DISCO_ITEMS = XMLNS} = IQ ->
|
|
| 125 |
-+ Res = IQ#iq{type = result,
|
|
| 126 |
-+ sub_el = [{xmlelement, "query",
|
|
| 127 |
-+ [{"xmlns", XMLNS}], []}]};
|
|
| 128 |
-+ #iq{type = get, xmlns = ?NS_VERSION} = IQ ->
|
|
| 129 |
-+ OSType = case os:type() of |
|
| 130 |
-+ {Osfamily, Osname} ->
|
|
| 131 |
-+ atom_to_list(Osfamily) ++ "/" ++ |
|
| 132 |
-+ atom_to_list(Osname); |
|
| 133 |
-+ Osfamily -> |
|
| 134 |
-+ atom_to_list(Osfamily) |
|
| 135 |
-+ end, |
|
| 136 |
-+ OSVersion = case os:version() of |
|
| 137 |
-+ {Major, Minor, Release} ->
|
|
| 138 |
-+ lists:flatten( |
|
| 139 |
-+ io_lib:format("~w.~w.~w",
|
|
| 140 |
-+ [Major, Minor, Release])); |
|
| 141 |
-+ VersionString -> |
|
| 142 |
-+ VersionString |
|
| 143 |
-+ end, |
|
| 144 |
-+ OS = OSType ++ " " ++ OSVersion, |
|
| 145 |
-+ Res = IQ#iq{type = result,
|
|
| 146 |
-+ sub_el = [{xmlelement, "query",
|
|
| 147 |
-+ [{"xmlns", ?NS_VERSION}],
|
|
| 148 |
-+ [{xmlelement, "name", [],
|
|
| 149 |
-+ [{xmlcdata, "ejabberd mod_proxy65 (unofficial)"}]},
|
|
| 150 |
-+ {xmlelement, "version", [],
|
|
| 151 |
-+ [{xmlcdata, "0.1"}]},
|
|
| 152 |
-+ {xmlelement, "os", [],
|
|
| 153 |
-+ [{xmlcdata, OS}]}
|
|
| 154 |
-+ ]}]}; |
|
| 155 |
-+ #iq{type = get, xmlns = ?NS_BYTESTREAMS = XMLNS} = IQ ->
|
|
| 156 |
-+ Res = IQ#iq{type = result,
|
|
| 157 |
-+ sub_el = [{xmlelement, "query",
|
|
| 158 |
-+ [{"xmlns", XMLNS}],
|
|
| 159 |
-+ return_streamhosts(Host, Streamhosts)}]}; |
|
| 160 |
-+ #iq{type = set, xmlns = ?NS_BYTESTREAMS} = IQ ->
|
|
| 161 |
-+ Res = activate(Packet, From, To, IQ); |
|
| 162 |
-+ _ -> |
|
| 163 |
-+ Res = jlib:make_error_reply(Packet, ?ERR_FEATURE_NOT_IMPLEMENTED) |
|
| 164 |
-+ end, |
|
| 165 |
-+ case Res of |
|
| 166 |
-+ #iq{} ->
|
|
| 167 |
-+ ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); |
|
| 168 |
-+ _ -> |
|
| 169 |
-+ ejabberd_router:route(To, From, Res) |
|
| 170 |
-+ end; |
|
| 171 |
-+ _ -> |
|
| 172 |
-+ ejabberd_router:route(To, From, jlib:make_error_reply(Packet, ?ERR_FEATURE_NOT_IMPLEMENTED)) |
|
| 173 |
-+ end. |
|
| 174 |
-+ |
|
| 175 |
-+return_streamhosts(_JID, []) -> |
|
| 176 |
-+ []; |
|
| 177 |
-+return_streamhosts(JID, [{Host, Port} | Streamhosts]) ->
|
|
| 178 |
-+ %% This is not tail-recursive, but it doesn't matter. |
|
| 179 |
-+ [{xmlelement, "streamhost",
|
|
| 180 |
-+ [{"jid", JID},
|
|
| 181 |
-+ {"host", Host},
|
|
| 182 |
-+ {"port", integer_to_list(Port)}],
|
|
| 183 |
-+ []} | return_streamhosts(JID, Streamhosts)]. |
|
| 184 |
-+ |
|
| 185 |
-+activate(Packet, From, _To, #iq{sub_el = SubEl} = IQ) ->
|
|
| 186 |
-+ case SubEl of |
|
| 187 |
-+ {xmlelement, "query", Attrs, _SubEls} ->
|
|
| 188 |
-+ Sid = xml:get_attr_s("sid", Attrs),
|
|
| 189 |
-+ ActivateTag = xml:get_subtag(SubEl, "activate"), |
|
| 190 |
-+ if ActivateTag /= false -> |
|
| 191 |
-+ TargetJID = jlib:string_to_jid(xml:get_tag_cdata(ActivateTag)); |
|
| 192 |
-+ true -> |
|
| 193 |
-+ TargetJID = false |
|
| 194 |
-+ end, |
|
| 195 |
-+ |
|
| 196 |
-+ if Sid /= [], TargetJID /= false, TargetJID /= error -> |
|
| 197 |
-+ case proxy65_listener:activate(From, TargetJID, Sid) of |
|
| 198 |
-+ ok -> |
|
| 199 |
-+ ?INFO_MSG("Activated connection between ~s and ~s",
|
|
| 200 |
-+ [jlib:jid_to_string(From), TargetJID]), |
|
| 201 |
-+ IQ#iq{type = result, sub_el = []};
|
|
| 202 |
-+ _ -> |
|
| 203 |
-+ jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR) |
|
| 204 |
-+ end; |
|
| 205 |
-+ true -> |
|
| 206 |
-+ jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST) |
|
| 207 |
-+ end; |
|
| 208 |
-+ _ -> |
|
| 209 |
-+ jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST) |
|
| 210 |
-+ end. |
|
| 211 |
---- /dev/null |
|
| 212 |
-+++ proxy65_listener.erl |
|
| 213 |
-@@ -0,0 +1,192 @@ |
|
| 214 |
-+%%%---------------------------------------------------------------------- |
|
| 215 |
-+%%% File : proxy65_listener.erl |
|
| 216 |
-+%%% Author : Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 217 |
-+%%% Purpose : Handle SOCKS5 connections for JEP-0065 proxy |
|
| 218 |
-+%%% Created : 27 Dec 2005 by Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 219 |
-+%%% Id : $Id: ejabberd_c2s.erl 440 2005-11-22 18:00:56Z alexey $ |
|
| 220 |
-+%%%---------------------------------------------------------------------- |
|
| 221 |
-+ |
|
| 222 |
-+-module(proxy65_listener). |
|
| 223 |
-+-author('henoch@dtek.chalmers.se').
|
|
| 224 |
-+-vsn('$Revision$ ').
|
|
| 225 |
-+ |
|
| 226 |
-+-export([start/2, handle_connection/2, activate/3]). |
|
| 227 |
-+ |
|
| 228 |
-+-include("ejabberd.hrl").
|
|
| 229 |
-+-include("jlib.hrl").
|
|
| 230 |
-+ |
|
| 231 |
-+-record(proxy65_connection, {cookie, firstpid = none, secondpid = none}).
|
|
| 232 |
-+ |
|
| 233 |
-+start({SockMod, Socket}, Opts) ->
|
|
| 234 |
-+ {ok, proc_lib:spawn(?MODULE, handle_connection, [{SockMod, Socket}, Opts])}.
|
|
| 235 |
-+ |
|
| 236 |
-+read_bytes(_SockOpts, 0, Data) -> |
|
| 237 |
-+ lists:flatten(Data); |
|
| 238 |
-+read_bytes({SockMod, Socket} = SockOpts, N, Data) ->
|
|
| 239 |
-+ Timeout = 1000, |
|
| 240 |
-+ case SockMod:recv(Socket, N, Timeout) of |
|
| 241 |
-+ {error, closed} ->
|
|
| 242 |
-+ %% On closed connection, return everything we have, |
|
| 243 |
-+ %% but not if we have nothing. |
|
| 244 |
-+ if Data == [] -> |
|
| 245 |
-+ erlang:error(closed); |
|
| 246 |
-+ true -> |
|
| 247 |
-+ lists:flatten(Data) |
|
| 248 |
-+ end; |
|
| 249 |
-+ {ok, MoreData} ->
|
|
| 250 |
-+ ?DEBUG("read ~p", [MoreData]),
|
|
| 251 |
-+ DataList = binary_to_list(MoreData), |
|
| 252 |
-+ read_bytes(SockOpts, N - length(DataList), [Data, DataList]) |
|
| 253 |
-+ end. |
|
| 254 |
-+ |
|
| 255 |
-+handle_connection({SockMod, Socket}, Opts) ->
|
|
| 256 |
-+ ?DEBUG("in handle_connection", []),
|
|
| 257 |
-+ case catch handle_auth({SockMod, Socket}, Opts) of
|
|
| 258 |
-+ {'EXIT', Reason} ->
|
|
| 259 |
-+ ?ERROR_MSG("~p abnormal termination:~n\t~p~n",
|
|
| 260 |
-+ [?MODULE, Reason]), |
|
| 261 |
-+ SockMod:close(Socket); |
|
| 262 |
-+ _ -> |
|
| 263 |
-+ ok |
|
| 264 |
-+ end. |
|
| 265 |
-+ |
|
| 266 |
-+handle_auth({SockMod, Socket} = SockOpts, Opts) ->
|
|
| 267 |
-+ ?DEBUG("in handle_auth", []),
|
|
| 268 |
-+ %% SOCKS protocol stuff... |
|
| 269 |
-+ [5, NAuthMethods] = read_bytes(SockOpts, 2, []), |
|
| 270 |
-+ AuthMethods = read_bytes(SockOpts, NAuthMethods, []), |
|
| 271 |
-+ SupportsNoAuth = lists:member(0, AuthMethods), |
|
| 272 |
-+ |
|
| 273 |
-+ %% Must support no authentication, otherwise crash |
|
| 274 |
-+ true = SupportsNoAuth, |
|
| 275 |
-+ |
|
| 276 |
-+ SockMod:send(Socket, [5, 0]), |
|
| 277 |
-+ |
|
| 278 |
-+ %% And done. |
|
| 279 |
-+ handle_connect(SockOpts, Opts). |
|
| 280 |
-+ |
|
| 281 |
-+handle_connect({SockMod, Socket} = SockOpts, Opts) ->
|
|
| 282 |
-+ ?DEBUG("in handle_connect", []),
|
|
| 283 |
-+ %% Expect a CONNECT command and nothing else |
|
| 284 |
-+ [5, 1, _, 3, AddressLength] = read_bytes(SockOpts, 5, []), |
|
| 285 |
-+ Cookie = read_bytes(SockOpts, AddressLength, []), |
|
| 286 |
-+ [0, 0] = read_bytes(SockOpts, 2, []), |
|
| 287 |
-+ |
|
| 288 |
-+ %% Make sure no more than two connections claim the same cookie. |
|
| 289 |
-+ F = fun() -> |
|
| 290 |
-+ case mnesia:read({proxy65_connection, Cookie}) of
|
|
| 291 |
-+ [] -> |
|
| 292 |
-+ mnesia:write(#proxy65_connection{cookie = Cookie,
|
|
| 293 |
-+ firstpid = self()}), |
|
| 294 |
-+ ok; |
|
| 295 |
-+ [#proxy65_connection{secondpid = none} = C] ->
|
|
| 296 |
-+ mnesia:write(C#proxy65_connection{secondpid = self()}),
|
|
| 297 |
-+ ok |
|
| 298 |
-+ end |
|
| 299 |
-+ end, |
|
| 300 |
-+ |
|
| 301 |
-+ case mnesia:transaction(F) of |
|
| 302 |
-+ {atomic, ok} ->
|
|
| 303 |
-+ SockMod:send(Socket, [5, 0, 0, 3, AddressLength, Cookie, 0, 0]), |
|
| 304 |
-+ wait_for_activation(SockOpts, Opts); |
|
| 305 |
-+ Error -> |
|
| 306 |
-+ %% conflict. send "general SOCKS server failure". |
|
| 307 |
-+ SockMod:send(Socket, [5, 1, 0, 3, AddressLength, Cookie, 0, 0]), |
|
| 308 |
-+ erlang:error({badconnect, Error})
|
|
| 309 |
-+ end. |
|
| 310 |
-+ |
|
| 311 |
-+wait_for_activation(SockOpts, Opts) -> |
|
| 312 |
-+ ?DEBUG("in wait_for_activation", []),
|
|
| 313 |
-+ receive |
|
| 314 |
-+ {get_socket, ReplyTo} ->
|
|
| 315 |
-+ ReplyTo ! SockOpts, |
|
| 316 |
-+ wait_for_activation(SockOpts, Opts); |
|
| 317 |
-+ {activate, TargetSocket, Initiator, Target} ->
|
|
| 318 |
-+ ?DEBUG("activated", []),
|
|
| 319 |
-+ |
|
| 320 |
-+ %% We have no way of knowing which connection belongs to |
|
| 321 |
-+ %% which participant, so give both the maximum traffic |
|
| 322 |
-+ %% allowed to either. |
|
| 323 |
-+ Shapers = case lists:keysearch(shaper, 1, Opts) of |
|
| 324 |
-+ {value, {_, S}} -> S;
|
|
| 325 |
-+ _ -> none |
|
| 326 |
-+ end, |
|
| 327 |
-+ ?DEBUG("we have shapers: ~p", [Shapers]),
|
|
| 328 |
-+ Shaper1 = acl:match_rule(global, Shapers, jlib:string_to_jid(Initiator)), |
|
| 329 |
-+ Shaper2 = acl:match_rule(global, Shapers, jlib:string_to_jid(Target)), |
|
| 330 |
-+ if Shaper1 == none; Shaper2 == none -> |
|
| 331 |
-+ MaxShaper = none; |
|
| 332 |
-+ true -> |
|
| 333 |
-+ ShaperValue1 = ejabberd_config:get_global_option({shaper, Shaper1}),
|
|
| 334 |
-+ ShaperValue2 = ejabberd_config:get_global_option({shaper, Shaper2}),
|
|
| 335 |
-+ |
|
| 336 |
-+ if ShaperValue1 > ShaperValue2 -> |
|
| 337 |
-+ MaxShaper = Shaper1; |
|
| 338 |
-+ true -> |
|
| 339 |
-+ MaxShaper = Shaper2 |
|
| 340 |
-+ end, |
|
| 341 |
-+ ?DEBUG("shapers have values ~p and ~p~nusing ~p", [ShaperValue1, ShaperValue2, MaxShaper]),
|
|
| 342 |
-+ ok |
|
| 343 |
-+ end, |
|
| 344 |
-+ |
|
| 345 |
-+ transfer_data(SockOpts, TargetSocket, shaper:new(MaxShaper)) |
|
| 346 |
-+ end. |
|
| 347 |
-+ |
|
| 348 |
-+transfer_data({SockMod, Socket} = SockOpts, {TargetSockMod, TargetSocket} = TargetSockOpts,
|
|
| 349 |
-+ Shaper) -> |
|
| 350 |
-+ case SockMod:recv(Socket, 0, infinity) of |
|
| 351 |
-+ {ok, Data} ->
|
|
| 352 |
-+ if Data /= <<>> -> |
|
| 353 |
-+ NewShaper = case Shaper of |
|
| 354 |
-+ none -> none; |
|
| 355 |
-+ _ -> |
|
| 356 |
-+ shaper:update(Shaper, size(Data)) |
|
| 357 |
-+ end, |
|
| 358 |
-+ ok = TargetSockMod:send(TargetSocket, Data); |
|
| 359 |
-+ true -> |
|
| 360 |
-+ NewShaper = Shaper |
|
| 361 |
-+ end, |
|
| 362 |
-+ transfer_data(SockOpts, TargetSockOpts, NewShaper); |
|
| 363 |
-+ {error, _} ->
|
|
| 364 |
-+ TargetSockMod:shutdown(TargetSocket, read_write) |
|
| 365 |
-+ end. |
|
| 366 |
-+ |
|
| 367 |
-+get_socket(PID) -> |
|
| 368 |
-+ PID ! {get_socket, self()},
|
|
| 369 |
-+ receive |
|
| 370 |
-+ {_SockMod, _Socket} = SockOpts ->
|
|
| 371 |
-+ SockOpts |
|
| 372 |
-+ end. |
|
| 373 |
-+ |
|
| 374 |
-+%% If any argument is a jid record, convert it to normalized string form... |
|
| 375 |
-+activate(#jid{} = Initiator, Target, SessionID) ->
|
|
| 376 |
-+ NormalizedInitiator = jlib:jid_to_string(jlib:make_jid(jlib:jid_tolower(Initiator))), |
|
| 377 |
-+ activate(NormalizedInitiator, Target, SessionID); |
|
| 378 |
-+activate(Initiator, #jid{} = Target, SessionID) ->
|
|
| 379 |
-+ NormalizedTarget = jlib:jid_to_string(jlib:make_jid(jlib:jid_tolower(Target))), |
|
| 380 |
-+ activate(Initiator, NormalizedTarget, SessionID); |
|
| 381 |
-+%% ...and get on with the activation. |
|
| 382 |
-+activate(Initiator, Target, SessionID) -> |
|
| 383 |
-+ Cookie = sha:sha(SessionID ++ Initiator ++ Target), |
|
| 384 |
-+ F = fun() -> |
|
| 385 |
-+ case mnesia:read({proxy65_connection, Cookie}) of
|
|
| 386 |
-+ [#proxy65_connection{firstpid = FirstPID,
|
|
| 387 |
-+ secondpid = SecondPID}] |
|
| 388 |
-+ when is_pid(FirstPID), is_pid(SecondPID) -> |
|
| 389 |
-+ mnesia:delete({proxy65_connection, Cookie}),
|
|
| 390 |
-+ {FirstPID, SecondPID};
|
|
| 391 |
-+ _ -> |
|
| 392 |
-+ error |
|
| 393 |
-+ end |
|
| 394 |
-+ end, |
|
| 395 |
-+ case mnesia:transaction(F) of |
|
| 396 |
-+ {atomic, {FirstPID, SecondPID}} ->
|
|
| 397 |
-+ FirstSocket = get_socket(FirstPID), |
|
| 398 |
-+ SecondSocket = get_socket(SecondPID), |
|
| 399 |
-+ FirstPID ! {activate, SecondSocket, Initiator, Target},
|
|
| 400 |
-+ SecondPID ! {activate, FirstSocket, Initiator, Target},
|
|
| 401 |
-+ ok; |
|
| 402 |
-+ Error -> |
|
| 403 |
-+ ?ERROR_MSG("Proxy activation failed: ~p", [Error]),
|
|
| 404 |
-+ error |
|
| 405 |
-+ end. |
|
| 406 |
- |
| ... | ... |
@@ -1,17 +0,0 @@ |
| 1 |
-# Copyright 1999-2005 Gentoo Foundation |
|
| 2 |
-# Distributed under the terms of the GNU General Public License v2 |
|
| 3 |
-# $Header: $ |
|
| 4 |
- |
|
| 5 |
-# Name of your ejabberd node. Used by ejabberdctl to determine which |
|
| 6 |
-# node to communicate with. Default is "ejabberd@`hostname -s`". |
|
| 7 |
-#EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 8 |
- |
|
| 9 |
-# Max number of open network connections. Default is 1024. Increasing |
|
| 10 |
-# this will slightly increase memory usage. |
|
| 11 |
-#ERL_MAX_PORTS=1024 |
|
| 12 |
- |
|
| 13 |
-# Return memory to the system after using it, instead of keeping it |
|
| 14 |
-# allocated for future use. Decreases the memory required by ejabberd, |
|
| 15 |
-# but makes it run slower. Default is unset, set to any value to |
|
| 16 |
-# activate. |
|
| 17 |
-#ERL_FULLSWEEP_AFTER=0 |
| ... | ... |
@@ -1,60 +0,0 @@ |
| 1 |
-#!/sbin/runscript |
|
| 2 |
-# Copyright 1999-2005 Gentoo Foundation |
|
| 3 |
-# Distributed under the terms of the GNU General Public License v2 |
|
| 4 |
-# $Header: $ |
|
| 5 |
- |
|
| 6 |
-opts="${opts} reload"
|
|
| 7 |
- |
|
| 8 |
-depend() {
|
|
| 9 |
- use dns |
|
| 10 |
- need net |
|
| 11 |
- provide jabber-server |
|
| 12 |
-} |
|
| 13 |
- |
|
| 14 |
-checkconfig() {
|
|
| 15 |
- if [ ! -e /etc/jabber/ejabberd.cfg ] ; then |
|
| 16 |
- eerror "You need an /etc/jabber/ejabberd.cfg file to run ejabberd" |
|
| 17 |
- return 1 |
|
| 18 |
- fi |
|
| 19 |
-} |
|
| 20 |
- |
|
| 21 |
-start() {
|
|
| 22 |
- checkconfig || return 1 |
|
| 23 |
- ebegin "Starting eJabberd" |
|
| 24 |
- start-stop-daemon --start --quiet --chuid jabber:jabber \ |
|
| 25 |
- --exec /usr/bin/env HOME=/var/run/jabber /usr/bin/ejabberd -- -noshell -detached |
|
| 26 |
- eend $? |
|
| 27 |
-} |
|
| 28 |
- |
|
| 29 |
-stop() {
|
|
| 30 |
- ebegin "Stopping eJabberd" |
|
| 31 |
- if [ -z "$EJABBERD_NODE" ]; |
|
| 32 |
- then |
|
| 33 |
- EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 34 |
- fi |
|
| 35 |
- /usr/bin/ejabberdctl $EJABBERD_NODE stop |
|
| 36 |
- eend $? |
|
| 37 |
-} |
|
| 38 |
- |
|
| 39 |
-# Work around a bug in /sbin/runscript.sh - it won't run our custom |
|
| 40 |
-# restart() unless it finds these two strings in the file. |
|
| 41 |
-# svc_start svc_stop |
|
| 42 |
-restart() {
|
|
| 43 |
- ebegin "Restarting eJabberd" |
|
| 44 |
- if [ -z "$EJABBERD_NODE" ]; |
|
| 45 |
- then |
|
| 46 |
- EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 47 |
- fi |
|
| 48 |
- /usr/bin/ejabberdctl $EJABBERD_NODE restart |
|
| 49 |
- eend $? |
|
| 50 |
-} |
|
| 51 |
- |
|
| 52 |
-reload() {
|
|
| 53 |
- ebegin "Reloading eJabberd" |
|
| 54 |
- if [ -z "$EJABBERD_NODE" ]; |
|
| 55 |
- then |
|
| 56 |
- EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 57 |
- fi |
|
| 58 |
- /usr/bin/ejabberdctl $EJABBERD_NODE reopen-log |
|
| 59 |
- eend $? |
|
| 60 |
-} |
| ... | ... |
@@ -1,934 +0,0 @@ |
| 1 |
-Index: src/ejabberd.cfg.example |
|
| 2 |
-=================================================================== |
|
| 3 |
---- src/ejabberd.cfg.example (Revision 565) |
|
| 4 |
-+++ src/ejabberd.cfg.example (Arbeitskopie) |
|
| 5 |
-@@ -124,7 +124,7 @@ |
|
| 6 |
- {5269, ejabberd_s2s_in, [{shaper, s2s_shaper},
|
|
| 7 |
- {max_stanza_size, 131072}
|
|
| 8 |
- ]}, |
|
| 9 |
-- {5280, ejabberd_http, [http_poll, web_admin]},
|
|
| 10 |
-+ {5280, ejabberd_http, [http_poll, http_bind, web_admin]},
|
|
| 11 |
- {8888, ejabberd_service, [{access, all},
|
|
| 12 |
- {hosts, ["icq.localhost", "sms.localhost"],
|
|
| 13 |
- [{password, "secret"}]}]}
|
|
| 14 |
-Index: src/web/Makefile.in |
|
| 15 |
-=================================================================== |
|
| 16 |
---- src/web/Makefile.in (Revision 565) |
|
| 17 |
-+++ src/web/Makefile.in (Arbeitskopie) |
|
| 18 |
-@@ -15,7 +15,8 @@ |
|
| 19 |
- $(OUTDIR)/ejabberd_http.beam \ |
|
| 20 |
- $(OUTDIR)/ejabberd_web.beam \ |
|
| 21 |
- $(OUTDIR)/ejabberd_web_admin.beam \ |
|
| 22 |
-- $(OUTDIR)/ejabberd_http_poll.beam |
|
| 23 |
-+ $(OUTDIR)/ejabberd_http_poll.beam \ |
|
| 24 |
-+ $(OUTDIR)/ejabberd_http_bind.beam |
|
| 25 |
- |
|
| 26 |
- all: $(OBJS) |
|
| 27 |
- |
|
| 28 |
-Index: src/web/ejabberd_http_bind.erl |
|
| 29 |
-=================================================================== |
|
| 30 |
---- src/web/ejabberd_http_bind.erl (Revision 0) |
|
| 31 |
-+++ src/web/ejabberd_http_bind.erl (Revision 0) |
|
| 32 |
-@@ -0,0 +1,731 @@ |
|
| 33 |
-+%%%---------------------------------------------------------------------- |
|
| 34 |
-+%%% File : ejabberd_http_bind.erl |
|
| 35 |
-+%%% Author : Stefan Strigler <steve@zeank.in-berlin.de> |
|
| 36 |
-+%%% Purpose : HTTP Binding support (JEP-0124) |
|
| 37 |
-+%%% Created : 21 Sep 2005 by Stefan Strigler <steve@zeank.in-berlin.de> |
|
| 38 |
-+%%% Id : $Id: ejabberd_http_bind.erl,v 1.2 2006/01/16 10:47:50 zeank Exp $ |
|
| 39 |
-+%%%---------------------------------------------------------------------- |
|
| 40 |
-+ |
|
| 41 |
-+-module(ejabberd_http_bind). |
|
| 42 |
-+-author('steve@zeank.in-berlin.de').
|
|
| 43 |
-+-vsn('Revision: 1.3').
|
|
| 44 |
-+ |
|
| 45 |
-+-behaviour(gen_fsm). |
|
| 46 |
-+ |
|
| 47 |
-+%% External exports |
|
| 48 |
-+-export([start_link/2, |
|
| 49 |
-+ init/1, |
|
| 50 |
-+ handle_event/3, |
|
| 51 |
-+ handle_sync_event/4, |
|
| 52 |
-+ code_change/4, |
|
| 53 |
-+ handle_info/3, |
|
| 54 |
-+ terminate/3, |
|
| 55 |
-+ send/2, |
|
| 56 |
-+ setopts/2, |
|
| 57 |
-+ controlling_process/2, |
|
| 58 |
-+ close/1, |
|
| 59 |
-+ process_request/1]). |
|
| 60 |
-+ |
|
| 61 |
-+%%-define(ejabberd_debug, true). |
|
| 62 |
-+ |
|
| 63 |
-+-include("ejabberd.hrl").
|
|
| 64 |
-+-include("jlib.hrl").
|
|
| 65 |
-+-include("ejabberd_http.hrl").
|
|
| 66 |
-+ |
|
| 67 |
-+-record(http_bind, {id, pid, hold, wait}).
|
|
| 68 |
-+ |
|
| 69 |
-+%% http binding request |
|
| 70 |
-+-record(hbr, {rid,
|
|
| 71 |
-+ key, |
|
| 72 |
-+ in, |
|
| 73 |
-+ out}). |
|
| 74 |
-+ |
|
| 75 |
-+-record(state, {id,
|
|
| 76 |
-+ rid = error, |
|
| 77 |
-+ key, |
|
| 78 |
-+ output = "", |
|
| 79 |
-+ input = "", |
|
| 80 |
-+ waiting_input = false, |
|
| 81 |
-+ last_receiver, |
|
| 82 |
-+ last_poll, |
|
| 83 |
-+ ctime = 0, |
|
| 84 |
-+ timer, |
|
| 85 |
-+ req_list = [] % list of requests |
|
| 86 |
-+ }). |
|
| 87 |
-+ |
|
| 88 |
-+ |
|
| 89 |
-+%-define(DBGFSM, true). |
|
| 90 |
-+ |
|
| 91 |
-+-ifdef(DBGFSM). |
|
| 92 |
-+-define(FSMOPTS, [{debug, [trace]}]).
|
|
| 93 |
-+-else. |
|
| 94 |
-+-define(FSMOPTS, []). |
|
| 95 |
-+-endif. |
|
| 96 |
-+ |
|
| 97 |
-+-define(MAX_REQUESTS, 2). % number of simultaneous requests |
|
| 98 |
-+-define(MIN_POLLING, "2"). % don't poll faster than that or we will shoot you |
|
| 99 |
-+-define(MAX_WAIT, 60). % max num of secs to keep a request on hold |
|
| 100 |
-+-define(MAX_INACTIVITY, 30000). % msecs to wait before terminating idle sessions |
|
| 101 |
-+-define(CT, {"Content-Type", "text/xml; charset=utf-8"}).
|
|
| 102 |
-+-define(BAD_REQUEST, ?CT). |
|
| 103 |
-+ |
|
| 104 |
-+ |
|
| 105 |
-+%%%---------------------------------------------------------------------- |
|
| 106 |
-+%%% API |
|
| 107 |
-+%%%---------------------------------------------------------------------- |
|
| 108 |
-+start(ID, Key) -> |
|
| 109 |
-+ mnesia:create_table(http_bind, |
|
| 110 |
-+ [{ram_copies, [node()]},
|
|
| 111 |
-+ {attributes, record_info(fields, http_bind)}]),
|
|
| 112 |
-+ supervisor:start_child(ejabberd_http_bind_sup, [ID, Key]). |
|
| 113 |
-+ |
|
| 114 |
-+start_link(ID, Key) -> |
|
| 115 |
-+ gen_fsm:start_link(?MODULE, [ID, Key], ?FSMOPTS). |
|
| 116 |
-+ |
|
| 117 |
-+send({http_bind, FsmRef}, Packet) ->
|
|
| 118 |
-+ gen_fsm:sync_send_all_state_event(FsmRef, {send, Packet}).
|
|
| 119 |
-+ |
|
| 120 |
-+setopts({http_bind, FsmRef}, Opts) ->
|
|
| 121 |
-+ case lists:member({active, once}, Opts) of
|
|
| 122 |
-+ true -> |
|
| 123 |
-+ gen_fsm:sync_send_all_state_event(FsmRef, activate); |
|
| 124 |
-+ _ -> |
|
| 125 |
-+ ok |
|
| 126 |
-+ end. |
|
| 127 |
-+ |
|
| 128 |
-+controlling_process(_Socket, _Pid) -> |
|
| 129 |
-+ ok. |
|
| 130 |
-+ |
|
| 131 |
-+close({http_bind, FsmRef}) ->
|
|
| 132 |
-+ catch gen_fsm:sync_send_all_state_event(FsmRef, close). |
|
| 133 |
-+ |
|
| 134 |
-+ |
|
| 135 |
-+process_request(#request{path = [],
|
|
| 136 |
-+ data = Data}) -> |
|
| 137 |
-+ case catch parse_request(Data) of |
|
| 138 |
-+ {ok, ID1, RID, Key, NewKey, Attrs, Packet} ->
|
|
| 139 |
-+ XmppDomain = xml:get_attr_s("to",Attrs),
|
|
| 140 |
-+ if |
|
| 141 |
-+ (ID1 == "") and (XmppDomain == "") -> |
|
| 142 |
-+ {200, [?CT], "<body type='terminate' "
|
|
| 143 |
-+ "condition='improper-addressing' " |
|
| 144 |
-+ "xmlns='http://jabber.org/protocol/httpbind'/>"}; |
|
| 145 |
-+ true -> |
|
| 146 |
-+ ID = if |
|
| 147 |
-+ (ID1 == "") -> |
|
| 148 |
-+ %% create new session |
|
| 149 |
-+ NewID = sha:sha(term_to_binary({now(), make_ref()})),
|
|
| 150 |
-+ {ok, Pid} = start(NewID, Key),
|
|
| 151 |
-+ Wait = case |
|
| 152 |
-+ string:to_integer(xml:get_attr_s("wait",Attrs))
|
|
| 153 |
-+ of |
|
| 154 |
-+ {error, _} ->
|
|
| 155 |
-+ ?MAX_WAIT; |
|
| 156 |
-+ {CWait, _} ->
|
|
| 157 |
-+ if |
|
| 158 |
-+ (CWait > ?MAX_WAIT) -> |
|
| 159 |
-+ ?MAX_WAIT; |
|
| 160 |
-+ true -> |
|
| 161 |
-+ CWait |
|
| 162 |
-+ end |
|
| 163 |
-+ end, |
|
| 164 |
-+ Hold = case |
|
| 165 |
-+ string:to_integer( |
|
| 166 |
-+ xml:get_attr_s("hold",Attrs))
|
|
| 167 |
-+ of |
|
| 168 |
-+ {error, _} ->
|
|
| 169 |
-+ (?MAX_REQUESTS - 1); |
|
| 170 |
-+ {CHold, _} ->
|
|
| 171 |
-+ if |
|
| 172 |
-+ (CHold > (?MAX_REQUESTS - 1)) -> |
|
| 173 |
-+ (?MAX_REQUESTS - 1); |
|
| 174 |
-+ true -> |
|
| 175 |
-+ CHold |
|
| 176 |
-+ end |
|
| 177 |
-+ end, |
|
| 178 |
-+ mnesia:transaction( |
|
| 179 |
-+ fun() -> |
|
| 180 |
-+ mnesia:write(#http_bind{id = NewID,
|
|
| 181 |
-+ pid = Pid, |
|
| 182 |
-+ wait = Wait, |
|
| 183 |
-+ hold = Hold}) |
|
| 184 |
-+ end), |
|
| 185 |
-+ InPacket = if |
|
| 186 |
-+ (XmppDomain /= "") -> |
|
| 187 |
-+ ["<stream:stream to='", |
|
| 188 |
-+ XmppDomain, |
|
| 189 |
-+ "' xmlns='jabber:client' " |
|
| 190 |
-+ "xmlns:stream='http://etherx.jabber.org/streams'>"]; |
|
| 191 |
-+ true -> |
|
| 192 |
-+ "" |
|
| 193 |
-+ end, |
|
| 194 |
-+ NewID; |
|
| 195 |
-+ true -> |
|
| 196 |
-+ %% old session |
|
| 197 |
-+ Type = xml:get_attr_s("type",Attrs),
|
|
| 198 |
-+ Wait = ?MAX_WAIT, |
|
| 199 |
-+ Hold = (?MAX_REQUESTS - 1), |
|
| 200 |
-+ if |
|
| 201 |
-+ (Type == "terminate") -> |
|
| 202 |
-+ %% terminate session |
|
| 203 |
-+ InPacket = Packet ++ "</stream:stream>"; |
|
| 204 |
-+ true -> |
|
| 205 |
-+ InPacket = Packet |
|
| 206 |
-+ end, |
|
| 207 |
-+ ID1 |
|
| 208 |
-+ end, |
|
| 209 |
-+%% ?DEBUG("~n InPacket: ~s ~n", [InPacket]),
|
|
| 210 |
-+ case http_put(ID, RID, Key, NewKey, Hold, InPacket) of |
|
| 211 |
-+ {error, not_exists} ->
|
|
| 212 |
-+ ?DEBUG("no session associated with sid: ~p", [ID]),
|
|
| 213 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 214 |
-+ {error, bad_key} ->
|
|
| 215 |
-+ ?DEBUG("bad key: ~s", Key),
|
|
| 216 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 217 |
-+ [] -> |
|
| 218 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 219 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 220 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop), |
|
| 221 |
-+ {404, [?BAD_REQUEST], ""}
|
|
| 222 |
-+ end; |
|
| 223 |
-+ {error, polling_too_frequently} ->
|
|
| 224 |
-+ ?DEBUG("polling too frequently: ~p", [ID]),
|
|
| 225 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 226 |
-+ [] -> %% unlikely! (?) |
|
| 227 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 228 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 229 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop), |
|
| 230 |
-+ {403, [?BAD_REQUEST], ""}
|
|
| 231 |
-+ end; |
|
| 232 |
-+ {repeat, OutPacket} ->
|
|
| 233 |
-+ ?DEBUG("http_put said 'repeat!' ...~nOutPacket: ~p",
|
|
| 234 |
-+ [OutPacket]), |
|
| 235 |
-+ send_outpacket(ID, OutPacket); |
|
| 236 |
-+ ok -> |
|
| 237 |
-+ receive_loop(ID,ID1,RID,Wait,Hold,Attrs) |
|
| 238 |
-+ end |
|
| 239 |
-+ end; |
|
| 240 |
-+ _ -> |
|
| 241 |
-+ {400, [?BAD_REQUEST], ""}
|
|
| 242 |
-+ end; |
|
| 243 |
-+process_request(_Request) -> |
|
| 244 |
-+ {400, [], {xmlelement, "h1", [],
|
|
| 245 |
-+ [{xmlcdata, "400 Bad Request"}]}}.
|
|
| 246 |
-+ |
|
| 247 |
-+receive_loop(ID,ID1,RID,Wait,Hold,Attrs) -> |
|
| 248 |
-+ receive |
|
| 249 |
-+ after 100 -> ok |
|
| 250 |
-+ end, |
|
| 251 |
-+ prepare_response(ID,ID1,RID,Wait,Hold,Attrs). |
|
| 252 |
-+ |
|
| 253 |
-+prepare_response(ID,ID1,RID,Wait,Hold,Attrs) -> |
|
| 254 |
-+ case http_get(ID,RID) of |
|
| 255 |
-+ {error, not_exists} ->
|
|
| 256 |
-+ ?DEBUG("no session associated with sid: ~s", ID),
|
|
| 257 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 258 |
-+ {ok, keep_on_hold} ->
|
|
| 259 |
-+ receive_loop(ID,ID1,RID,Wait,Hold,Attrs); |
|
| 260 |
-+ {ok, cancel} ->
|
|
| 261 |
-+ %% actually it would be better if we could completely |
|
| 262 |
-+ %% cancel this request, but then we would have to hack |
|
| 263 |
-+ %% ejabberd_http and I'm too lazy now |
|
| 264 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 265 |
-+ {ok, OutPacket} ->
|
|
| 266 |
-+ ?DEBUG("OutPacket: ~s", [OutPacket]),
|
|
| 267 |
-+ if |
|
| 268 |
-+ ID == ID1 -> |
|
| 269 |
-+ send_outpacket(ID, OutPacket); |
|
| 270 |
-+ true -> |
|
| 271 |
-+ To = xml:get_attr_s("to",Attrs),
|
|
| 272 |
-+ case xml_stream:parse_element( |
|
| 273 |
-+ OutPacket++"</stream:stream>") of |
|
| 274 |
-+ El when element(1, El) == xmlelement -> |
|
| 275 |
-+ {xmlelement, _, OutAttrs, _} = El,
|
|
| 276 |
-+ AuthID = xml:get_attr_s("id", OutAttrs),
|
|
| 277 |
-+ StreamError = false; |
|
| 278 |
-+ {error, _} ->
|
|
| 279 |
-+ AuthID = "", |
|
| 280 |
-+ StreamError = true |
|
| 281 |
-+ end, |
|
| 282 |
-+ if |
|
| 283 |
-+ To == "" -> |
|
| 284 |
-+ {200, [?CT], "<body type='terminate' "
|
|
| 285 |
-+ "condition='improper-addressing' " |
|
| 286 |
-+ "xmlns='http://jabber.org/protocol/httpbind'/>"}; |
|
| 287 |
-+ StreamError == true -> |
|
| 288 |
-+ {200, [?CT], "<body type='terminate' "
|
|
| 289 |
-+ "condition='host-unknown' " |
|
| 290 |
-+ "xmlns='http://jabber.org/protocol/httpbind'/>"}; |
|
| 291 |
-+ true -> |
|
| 292 |
-+ {200, [?CT],
|
|
| 293 |
-+ xml:element_to_string( |
|
| 294 |
-+ {xmlelement,"body",
|
|
| 295 |
-+ [{"xmlns",
|
|
| 296 |
-+ "http://jabber.org/protocol/httpbind"}, |
|
| 297 |
-+ {"sid",ID},
|
|
| 298 |
-+ {"wait", integer_to_list(Wait)},
|
|
| 299 |
-+ {"requests", integer_to_list(Hold+1)},
|
|
| 300 |
-+ {"inactivity",
|
|
| 301 |
-+ integer_to_list(trunc(?MAX_INACTIVITY/1000))}, |
|
| 302 |
-+ {"polling", ?MIN_POLLING},
|
|
| 303 |
-+ {"authid", AuthID}
|
|
| 304 |
-+ ],[]})} |
|
| 305 |
-+ end |
|
| 306 |
-+ end |
|
| 307 |
-+ end. |
|
| 308 |
-+ |
|
| 309 |
-+send_outpacket(ID, OutPacket) -> |
|
| 310 |
-+ case OutPacket of |
|
| 311 |
-+ "" -> |
|
| 312 |
-+ {200, [?CT], "<body xmlns='http://jabber.org/protocol/httpbind'/>"};
|
|
| 313 |
-+ "</stream:stream>" -> |
|
| 314 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 315 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 316 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop) |
|
| 317 |
-+ end, |
|
| 318 |
-+ {200, [?CT], "<body xmlns='http://jabber.org/protocol/httpbind'/>"};
|
|
| 319 |
-+ _ -> |
|
| 320 |
-+ case xml_stream:parse_element("<body>"
|
|
| 321 |
-+ ++ OutPacket |
|
| 322 |
-+ ++ "</body>") |
|
| 323 |
-+ of |
|
| 324 |
-+ El when element(1, El) == xmlelement -> |
|
| 325 |
-+ {xmlelement, _, _, OEls} = El,
|
|
| 326 |
-+ TypedEls = [xml:replace_tag_attr("xmlns",
|
|
| 327 |
-+ "jabber:client",OEl) || |
|
| 328 |
-+ OEl <- OEls], |
|
| 329 |
-+ ?DEBUG(" --- outgoing data --- ~n~s~n --- END --- ~n",
|
|
| 330 |
-+ [xml:element_to_string( |
|
| 331 |
-+ {xmlelement,"body",
|
|
| 332 |
-+ [{"xmlns",
|
|
| 333 |
-+ "http://jabber.org/protocol/httpbind"}], |
|
| 334 |
-+ TypedEls})] |
|
| 335 |
-+ ), |
|
| 336 |
-+ {200, [?CT],
|
|
| 337 |
-+ xml:element_to_string( |
|
| 338 |
-+ {xmlelement,"body",
|
|
| 339 |
-+ [{"xmlns",
|
|
| 340 |
-+ "http://jabber.org/protocol/httpbind"}], |
|
| 341 |
-+ TypedEls})}; |
|
| 342 |
-+ {error, _E} ->
|
|
| 343 |
-+ ?DEBUG("parse error: ~p", [_E]),
|
|
| 344 |
-+ StreamErrCond = case xml_stream:parse_element( |
|
| 345 |
-+ "<stream:stream>"++OutPacket) of |
|
| 346 |
-+ El when element(1, El) == xmlelement -> |
|
| 347 |
-+ {xmlelement, _Tag, _Attr, Els} = El,
|
|
| 348 |
-+ [{xmlelement, SE, _, Cond} | _] = Els,
|
|
| 349 |
-+ if |
|
| 350 |
-+ SE == "stream:error" -> |
|
| 351 |
-+ Cond; |
|
| 352 |
-+ true -> |
|
| 353 |
-+ null |
|
| 354 |
-+ end; |
|
| 355 |
-+ {error, _E} ->
|
|
| 356 |
-+ null |
|
| 357 |
-+ end, |
|
| 358 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 359 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 360 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop); |
|
| 361 |
-+ _ -> |
|
| 362 |
-+ err %% hu? |
|
| 363 |
-+ end, |
|
| 364 |
-+ case StreamErrCond of |
|
| 365 |
-+ null -> |
|
| 366 |
-+ {200, [?CT],
|
|
| 367 |
-+ "<body type='terminate' " |
|
| 368 |
-+ "condition='internal-server-error' " |
|
| 369 |
-+ "xmlns='http://jabber.org/protocol/httpbind'/>"}; |
|
| 370 |
-+ _ -> |
|
| 371 |
-+ {200, [?CT],
|
|
| 372 |
-+ "<body type='terminate' " |
|
| 373 |
-+ "condition='remote-stream-error' " |
|
| 374 |
-+ "xmlns='http://jabber.org/protocol/httpbind'>" ++ |
|
| 375 |
-+ elements_to_string(StreamErrCond) ++ |
|
| 376 |
-+ "</body>"} |
|
| 377 |
-+ end |
|
| 378 |
-+ end |
|
| 379 |
-+ end. |
|
| 380 |
-+ |
|
| 381 |
-+%%%---------------------------------------------------------------------- |
|
| 382 |
-+%%% Callback functions from gen_fsm |
|
| 383 |
-+%%%---------------------------------------------------------------------- |
|
| 384 |
-+ |
|
| 385 |
-+%%---------------------------------------------------------------------- |
|
| 386 |
-+%% Func: init/1 |
|
| 387 |
-+%% Returns: {ok, StateName, StateData} |
|
|
| 388 |
-+%% {ok, StateName, StateData, Timeout} |
|
|
| 389 |
-+%% ignore | |
|
| 390 |
-+%% {stop, StopReason}
|
|
| 391 |
-+%%---------------------------------------------------------------------- |
|
| 392 |
-+init([ID, Key]) -> |
|
| 393 |
-+ ?INFO_MSG("started: ~p", [{ID, Key}]),
|
|
| 394 |
-+ Opts = [], % TODO |
|
| 395 |
-+ {ok, C2SPid} = ejabberd_c2s:start({?MODULE, {http_bind, self()}}, Opts),
|
|
| 396 |
-+ ejabberd_c2s:become_controller(C2SPid), |
|
| 397 |
-+ Timer = erlang:start_timer(?MAX_INACTIVITY, self(), []), |
|
| 398 |
-+ {ok, loop, #state{id = ID,
|
|
| 399 |
-+ key = Key, |
|
| 400 |
-+ timer = Timer}}. |
|
| 401 |
-+ |
|
| 402 |
-+%%---------------------------------------------------------------------- |
|
| 403 |
-+%% Func: StateName/2 |
|
| 404 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 405 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 406 |
-+%% {stop, Reason, NewStateData}
|
|
| 407 |
-+%%---------------------------------------------------------------------- |
|
| 408 |
-+ |
|
| 409 |
-+ |
|
| 410 |
-+%%---------------------------------------------------------------------- |
|
| 411 |
-+%% Func: StateName/3 |
|
| 412 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 413 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 414 |
-+%% {reply, Reply, NextStateName, NextStateData} |
|
|
| 415 |
-+%% {reply, Reply, NextStateName, NextStateData, Timeout} |
|
|
| 416 |
-+%% {stop, Reason, NewStateData} |
|
|
| 417 |
-+%% {stop, Reason, Reply, NewStateData}
|
|
| 418 |
-+%%---------------------------------------------------------------------- |
|
| 419 |
-+%state_name(Event, From, StateData) -> |
|
| 420 |
-+% Reply = ok, |
|
| 421 |
-+% {reply, Reply, state_name, StateData}.
|
|
| 422 |
-+ |
|
| 423 |
-+%%---------------------------------------------------------------------- |
|
| 424 |
-+%% Func: handle_event/3 |
|
| 425 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 426 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 427 |
-+%% {stop, Reason, NewStateData}
|
|
| 428 |
-+%%---------------------------------------------------------------------- |
|
| 429 |
-+handle_event(_Event, StateName, StateData) -> |
|
| 430 |
-+ {next_state, StateName, StateData}.
|
|
| 431 |
-+ |
|
| 432 |
-+%%---------------------------------------------------------------------- |
|
| 433 |
-+%% Func: handle_sync_event/4 |
|
| 434 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 435 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 436 |
-+%% {reply, Reply, NextStateName, NextStateData} |
|
|
| 437 |
-+%% {reply, Reply, NextStateName, NextStateData, Timeout} |
|
|
| 438 |
-+%% {stop, Reason, NewStateData} |
|
|
| 439 |
-+%% {stop, Reason, Reply, NewStateData}
|
|
| 440 |
-+%%---------------------------------------------------------------------- |
|
| 441 |
-+handle_sync_event({send, Packet}, _From, StateName, StateData) ->
|
|
| 442 |
-+ Output = [StateData#state.output | Packet], |
|
| 443 |
-+ Reply = ok, |
|
| 444 |
-+ {reply, Reply, StateName, StateData#state{output = Output}};
|
|
| 445 |
-+ |
|
| 446 |
-+handle_sync_event(activate, From, StateName, StateData) -> |
|
| 447 |
-+ case StateData#state.input of |
|
| 448 |
-+ "" -> |
|
| 449 |
-+ {reply, ok, StateName, StateData#state{
|
|
| 450 |
-+ waiting_input = From}}; |
|
| 451 |
-+ Input -> |
|
| 452 |
-+ From ! {tcp, {http_bind, self()}, list_to_binary(Input)},
|
|
| 453 |
-+ {reply, ok, StateName, StateData#state{
|
|
| 454 |
-+ input = "", |
|
| 455 |
-+ waiting_input = false, |
|
| 456 |
-+ last_receiver = From}} |
|
| 457 |
-+ end; |
|
| 458 |
-+ |
|
| 459 |
-+handle_sync_event(stop, _From, _StateName, StateData) -> |
|
| 460 |
-+ Reply = ok, |
|
| 461 |
-+ {stop, normal, Reply, StateData};
|
|
| 462 |
-+ |
|
| 463 |
-+handle_sync_event({http_put, RID, Key, NewKey, Hold, Packet},
|
|
| 464 |
-+ _From, StateName, StateData) -> |
|
| 465 |
-+ %% check if RID valid |
|
| 466 |
-+ RidAllow = case RID of |
|
| 467 |
-+ error -> |
|
| 468 |
-+ false; |
|
| 469 |
-+ _ -> |
|
| 470 |
-+ case StateData#state.rid of |
|
| 471 |
-+ error -> |
|
| 472 |
-+ %% first request - nothing saved so far |
|
| 473 |
-+ true; |
|
| 474 |
-+ OldRID -> |
|
| 475 |
-+ ?DEBUG("state.rid/cur rid: ~p/~p",
|
|
| 476 |
-+ [OldRID, RID]), |
|
| 477 |
-+ if |
|
| 478 |
-+ (OldRID < RID) and |
|
| 479 |
-+ (RID =< (OldRID + Hold + 1)) -> |
|
| 480 |
-+ true; |
|
| 481 |
-+ (RID =< OldRID) and |
|
| 482 |
-+ (RID > OldRID - Hold - 1) -> |
|
| 483 |
-+ repeat; |
|
| 484 |
-+ true -> |
|
| 485 |
-+ false |
|
| 486 |
-+ end |
|
| 487 |
-+ end |
|
| 488 |
-+ end, |
|
| 489 |
-+ %% check if key valid |
|
| 490 |
-+ KeyAllow = case RidAllow of |
|
| 491 |
-+ repeat -> |
|
| 492 |
-+ true; |
|
| 493 |
-+ false -> |
|
| 494 |
-+ false; |
|
| 495 |
-+ true -> |
|
| 496 |
-+ case StateData#state.key of |
|
| 497 |
-+ "" -> |
|
| 498 |
-+ true; |
|
| 499 |
-+ OldKey -> |
|
| 500 |
-+ NextKey = httpd_util:to_lower( |
|
| 501 |
-+ hex(binary_to_list( |
|
| 502 |
-+ crypto:sha(Key)))), |
|
| 503 |
-+ ?DEBUG("Key/OldKey/NextKey: ~s/~s/~s",
|
|
| 504 |
-+ [Key, OldKey, NextKey]), |
|
| 505 |
-+ if |
|
| 506 |
-+ OldKey == NextKey -> |
|
| 507 |
-+ true; |
|
| 508 |
-+ true -> |
|
| 509 |
-+ ?DEBUG("wrong key: ~s",[Key]),
|
|
| 510 |
-+ false |
|
| 511 |
-+ end |
|
| 512 |
-+ end |
|
| 513 |
-+ end, |
|
| 514 |
-+ {_,TSec,TMSec} = now(),
|
|
| 515 |
-+ TNow = TSec*1000*1000 + TMSec, |
|
| 516 |
-+ LastPoll = if |
|
| 517 |
-+ Packet == "" -> |
|
| 518 |
-+ TNow; |
|
| 519 |
-+ true -> |
|
| 520 |
-+ 0 |
|
| 521 |
-+ end, |
|
| 522 |
-+ {MinPoll, _} = string:to_integer(?MIN_POLLING),
|
|
| 523 |
-+ if |
|
| 524 |
-+ (Packet == "") and |
|
| 525 |
-+ (TNow - StateData#state.last_poll < MinPoll*1000*1000) -> |
|
| 526 |
-+ Reply = {error, polling_too_frequently},
|
|
| 527 |
-+ {reply, Reply, StateName, StateData};
|
|
| 528 |
-+ KeyAllow -> |
|
| 529 |
-+ case RidAllow of |
|
| 530 |
-+ false -> |
|
| 531 |
-+ Reply = {error, not_exists},
|
|
| 532 |
-+ {reply, Reply, StateName, StateData};
|
|
| 533 |
-+ repeat -> |
|
| 534 |
-+ ?DEBUG("REPEATING ~p", [RID]),
|
|
| 535 |
-+ [Out | _XS] = [El#hbr.out || |
|
| 536 |
-+ El <- StateData#state.req_list, |
|
| 537 |
-+ El#hbr.rid == RID], |
|
| 538 |
-+ case Out of |
|
| 539 |
-+ [[] | OutPacket] -> |
|
| 540 |
-+ Reply = {repeat, OutPacket};
|
|
| 541 |
-+ _ -> |
|
| 542 |
-+ Reply = {repeat, Out}
|
|
| 543 |
-+ end, |
|
| 544 |
-+ {reply, Reply, StateName,
|
|
| 545 |
-+ StateData#state{input = "cancel", last_poll = LastPoll}};
|
|
| 546 |
-+ true -> |
|
| 547 |
-+ SaveKey = if |
|
| 548 |
-+ NewKey == "" -> |
|
| 549 |
-+ Key; |
|
| 550 |
-+ true -> |
|
| 551 |
-+ NewKey |
|
| 552 |
-+ end, |
|
| 553 |
-+ ?DEBUG(" -- SaveKey: ~s~n", [SaveKey]),
|
|
| 554 |
-+ |
|
| 555 |
-+ %% save request |
|
| 556 |
-+ ReqList = [#hbr{rid=RID,
|
|
| 557 |
-+ key=StateData#state.key, |
|
| 558 |
-+ in=StateData#state.input, |
|
| 559 |
-+ out=StateData#state.output |
|
| 560 |
-+ } | |
|
| 561 |
-+ [El || El <- StateData#state.req_list, |
|
| 562 |
-+ El#hbr.rid < RID, |
|
| 563 |
-+ El#hbr.rid > (RID - 1 - Hold)] |
|
| 564 |
-+ ], |
|
| 565 |
-+%% ?DEBUG("reqlist: ~p", [ReqList]),
|
|
| 566 |
-+ case StateData#state.waiting_input of |
|
| 567 |
-+ false -> |
|
| 568 |
-+ cancel_timer(StateData#state.timer), |
|
| 569 |
-+ Timer = erlang:start_timer( |
|
| 570 |
-+ ?MAX_INACTIVITY, self(), []), |
|
| 571 |
-+ Input = Packet ++ [StateData#state.input], |
|
| 572 |
-+ Reply = ok, |
|
| 573 |
-+ {reply, Reply, StateName,
|
|
| 574 |
-+ StateData#state{input = Input,
|
|
| 575 |
-+ rid = RID, |
|
| 576 |
-+ key = SaveKey, |
|
| 577 |
-+ ctime = TNow, |
|
| 578 |
-+ timer = Timer, |
|
| 579 |
-+ last_poll = LastPoll, |
|
| 580 |
-+ req_list = ReqList |
|
| 581 |
-+ }}; |
|
| 582 |
-+ {Receiver, _Tag} ->
|
|
| 583 |
-+ Receiver ! {tcp, {http_bind, self()},
|
|
| 584 |
-+ list_to_binary(Packet)}, |
|
| 585 |
-+ cancel_timer(StateData#state.timer), |
|
| 586 |
-+ Timer = erlang:start_timer( |
|
| 587 |
-+ ?MAX_INACTIVITY, self(), []), |
|
| 588 |
-+ Reply = ok, |
|
| 589 |
-+ {reply, Reply, StateName,
|
|
| 590 |
-+ StateData#state{waiting_input = false,
|
|
| 591 |
-+ last_receiver = Receiver, |
|
| 592 |
-+ input = "", |
|
| 593 |
-+ rid = RID, |
|
| 594 |
-+ key = SaveKey, |
|
| 595 |
-+ ctime = TNow, |
|
| 596 |
-+ timer = Timer, |
|
| 597 |
-+ last_poll = LastPoll, |
|
| 598 |
-+ req_list = ReqList |
|
| 599 |
-+ }} |
|
| 600 |
-+ end |
|
| 601 |
-+ end; |
|
| 602 |
-+ true -> |
|
| 603 |
-+ Reply = {error, bad_key},
|
|
| 604 |
-+ {reply, Reply, StateName, StateData}
|
|
| 605 |
-+ end; |
|
| 606 |
-+ |
|
| 607 |
-+handle_sync_event({http_get, RID, Wait, Hold}, _From, StateName, StateData) ->
|
|
| 608 |
-+ {_,TSec,TMSec} = now(),
|
|
| 609 |
-+ TNow = TSec*1000*1000 + TMSec, |
|
| 610 |
-+ cancel_timer(StateData#state.timer), |
|
| 611 |
-+ Timer = erlang:start_timer(?MAX_INACTIVITY, self(), []), |
|
| 612 |
-+ if |
|
| 613 |
-+ (Hold > 0) and |
|
| 614 |
-+ (StateData#state.output == "") and |
|
| 615 |
-+ ((TNow - StateData#state.ctime) < (Wait*1000*1000)) and |
|
| 616 |
-+ (StateData#state.rid == RID) and |
|
| 617 |
-+ (StateData#state.input /= "cancel") -> |
|
| 618 |
-+ Output = StateData#state.output, |
|
| 619 |
-+ ReqList = StateData#state.req_list, |
|
| 620 |
-+ Reply = {ok, keep_on_hold};
|
|
| 621 |
-+ (StateData#state.input == "cancel") -> |
|
| 622 |
-+ Output = StateData#state.output, |
|
| 623 |
-+ ReqList = StateData#state.req_list, |
|
| 624 |
-+ Reply = {ok, cancel};
|
|
| 625 |
-+ true -> |
|
| 626 |
-+ case StateData#state.output of |
|
| 627 |
-+ [[]| OutPacket] -> |
|
| 628 |
-+ Reply = {ok, OutPacket};
|
|
| 629 |
-+ _ -> |
|
| 630 |
-+ Reply = {ok, StateData#state.output}
|
|
| 631 |
-+ end, |
|
| 632 |
-+ %% save request |
|
| 633 |
-+ ReqList = [#hbr{rid=RID,
|
|
| 634 |
-+ key=StateData#state.key, |
|
| 635 |
-+ in=StateData#state.input, |
|
| 636 |
-+ out=StateData#state.output |
|
| 637 |
-+ } | |
|
| 638 |
-+ [El || El <- StateData#state.req_list, |
|
| 639 |
-+ El#hbr.rid /= RID ] |
|
| 640 |
-+ ], |
|
| 641 |
-+ Output = "" |
|
| 642 |
-+ end, |
|
| 643 |
-+ {reply, Reply, StateName, StateData#state{
|
|
| 644 |
-+ input = "", |
|
| 645 |
-+ output = Output, |
|
| 646 |
-+ timer = Timer, |
|
| 647 |
-+ req_list = ReqList}}; |
|
| 648 |
-+ |
|
| 649 |
-+handle_sync_event(_Event, _From, StateName, StateData) -> |
|
| 650 |
-+ Reply = ok, |
|
| 651 |
-+ {reply, Reply, StateName, StateData}.
|
|
| 652 |
-+ |
|
| 653 |
-+code_change(_OldVsn, StateName, StateData, _Extra) -> |
|
| 654 |
-+ {ok, StateName, StateData}.
|
|
| 655 |
-+ |
|
| 656 |
-+%%---------------------------------------------------------------------- |
|
| 657 |
-+%% Func: handle_info/3 |
|
| 658 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 659 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 660 |
-+%% {stop, Reason, NewStateData}
|
|
| 661 |
-+%%---------------------------------------------------------------------- |
|
| 662 |
-+handle_info({timeout, Timer, _}, _StateName,
|
|
| 663 |
-+ #state{timer = Timer} = StateData) ->
|
|
| 664 |
-+ ?DEBUG("ding dong", []),
|
|
| 665 |
-+ {stop, normal, StateData};
|
|
| 666 |
-+ |
|
| 667 |
-+handle_info(_, StateName, StateData) -> |
|
| 668 |
-+ {next_state, StateName, StateData}.
|
|
| 669 |
-+ |
|
| 670 |
-+%%---------------------------------------------------------------------- |
|
| 671 |
-+%% Func: terminate/3 |
|
| 672 |
-+%% Purpose: Shutdown the fsm |
|
| 673 |
-+%% Returns: any |
|
| 674 |
-+%%---------------------------------------------------------------------- |
|
| 675 |
-+terminate(_Reason, _StateName, StateData) -> |
|
| 676 |
-+ ?DEBUG("terminate: deleting session ~s", [StateData#state.id]),
|
|
| 677 |
-+ mnesia:transaction( |
|
| 678 |
-+ fun() -> |
|
| 679 |
-+ mnesia:delete({http_bind, StateData#state.id})
|
|
| 680 |
-+ end), |
|
| 681 |
-+ case StateData#state.waiting_input of |
|
| 682 |
-+ false -> |
|
| 683 |
-+ case StateData#state.last_receiver of |
|
| 684 |
-+ undefined -> ok; |
|
| 685 |
-+ Receiver -> Receiver ! {tcp_closed, {http_bind, self()}}
|
|
| 686 |
-+ end; |
|
| 687 |
-+ {Receiver, _Tag} -> Receiver ! {tcp_closed, {http_bind, self()}}
|
|
| 688 |
-+ end, |
|
| 689 |
-+ ok. |
|
| 690 |
-+ |
|
| 691 |
-+%%%---------------------------------------------------------------------- |
|
| 692 |
-+%%% Internal functions |
|
| 693 |
-+%%%---------------------------------------------------------------------- |
|
| 694 |
-+ |
|
| 695 |
-+ |
|
| 696 |
-+http_put(ID, RID, Key, NewKey, Hold, Packet) -> |
|
| 697 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 698 |
-+ [] -> |
|
| 699 |
-+ {error, not_exists};
|
|
| 700 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 701 |
-+ gen_fsm:sync_send_all_state_event( |
|
| 702 |
-+ FsmRef, {http_put, RID, Key, NewKey, Hold, Packet})
|
|
| 703 |
-+ end. |
|
| 704 |
-+ |
|
| 705 |
-+http_get(ID,RID) -> |
|
| 706 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 707 |
-+ [] -> |
|
| 708 |
-+ {error, not_exists};
|
|
| 709 |
-+ [#http_bind{pid = FsmRef, wait = Wait, hold = Hold}] ->
|
|
| 710 |
-+ gen_fsm:sync_send_all_state_event(FsmRef, |
|
| 711 |
-+ {http_get, RID, Wait, Hold})
|
|
| 712 |
-+ end. |
|
| 713 |
-+ |
|
| 714 |
-+ |
|
| 715 |
-+parse_request(Data) -> |
|
| 716 |
-+ ?DEBUG("--- incoming data --- ~n~s~n --- END --- ",
|
|
| 717 |
-+ [Data]), |
|
| 718 |
-+ case xml_stream:parse_element(Data) of |
|
| 719 |
-+ El when element(1, El) == xmlelement -> |
|
| 720 |
-+ {xmlelement, Name, Attrs, Els} = El,
|
|
| 721 |
-+ ID = xml:get_attr_s("sid",Attrs),
|
|
| 722 |
-+ {RID,_X} = string:to_integer(xml:get_attr_s("rid",Attrs)),
|
|
| 723 |
-+ Key = xml:get_attr_s("key",Attrs),
|
|
| 724 |
-+ NewKey = xml:get_attr_s("newkey",Attrs),
|
|
| 725 |
-+ Xmlns = xml:get_attr_s("xmlns",Attrs),
|
|
| 726 |
-+ Packet = [xml:element_to_string( |
|
| 727 |
-+ xml:remove_tag_attr("xmlns",E)) ||
|
|
| 728 |
-+ E <- Els], |
|
| 729 |
-+ if |
|
| 730 |
-+ Name /= "body" -> |
|
| 731 |
-+ {error, bad_request};
|
|
| 732 |
-+ Xmlns /= "http://jabber.org/protocol/httpbind" -> |
|
| 733 |
-+ {error, bad_request};
|
|
| 734 |
-+ true -> |
|
| 735 |
-+ {ok, ID, RID, Key, NewKey, Attrs, Packet}
|
|
| 736 |
-+ end; |
|
| 737 |
-+ {error, _Reason} ->
|
|
| 738 |
-+ {error, bad_request}
|
|
| 739 |
-+ end. |
|
| 740 |
-+ |
|
| 741 |
-+cancel_timer(Timer) -> |
|
| 742 |
-+ erlang:cancel_timer(Timer), |
|
| 743 |
-+ receive |
|
| 744 |
-+ {timeout, Timer, _} ->
|
|
| 745 |
-+ ok |
|
| 746 |
-+ after 0 -> |
|
| 747 |
-+ ok |
|
| 748 |
-+ end. |
|
| 749 |
-+ |
|
| 750 |
-+hex(Bin) when binary(Bin) -> hex(binary_to_list(Bin)); |
|
| 751 |
-+hex([]) -> ""; |
|
| 752 |
-+hex([H|T]) -> |
|
| 753 |
-+ [A,B] = if |
|
| 754 |
-+ H == 0 -> "00"; |
|
| 755 |
-+ H < 16 -> [$0,element(H,{$1,$2,$3,$4,$5,$6,$7,$8,$9,$a,$b,$c,$d,$e,$f})];
|
|
| 756 |
-+ true -> erlang:integer_to_list(H,16) |
|
| 757 |
-+ end, |
|
| 758 |
-+ [A,B|hex(T)]. |
|
| 759 |
-+ |
|
| 760 |
-+elements_to_string([]) -> |
|
| 761 |
-+ []; |
|
| 762 |
-+elements_to_string([El | Els]) -> |
|
| 763 |
-+ xml:element_to_string(El) ++ elements_to_string(Els). |
|
| 764 |
-Index: src/web/ejabberd_web.erl |
|
| 765 |
-=================================================================== |
|
| 766 |
---- src/web/ejabberd_web.erl (Revision 565) |
|
| 767 |
-+++ src/web/ejabberd_web.erl (Arbeitskopie) |
|
| 768 |
-@@ -49,7 +49,7 @@ |
|
| 769 |
- {"value", Value}])).
|
|
| 770 |
- |
|
| 771 |
- |
|
| 772 |
--process_get({_, true},
|
|
| 773 |
-+process_get({_, _, true},
|
|
| 774 |
- #request{auth = Auth,
|
|
| 775 |
- path = ["admin", "server", SHost | RPath], |
|
| 776 |
- q = Query, |
|
| 777 |
-@@ -94,7 +94,7 @@ |
|
| 778 |
- {404, [], make_xhtml([?XC("h1", "Not found")])}
|
|
| 779 |
- end; |
|
| 780 |
- |
|
| 781 |
--process_get({_, true},
|
|
| 782 |
-+process_get({_, _, true},
|
|
| 783 |
- #request{auth = Auth,
|
|
| 784 |
- path = ["admin" | RPath], |
|
| 785 |
- q = Query, |
|
| 786 |
-@@ -133,12 +133,19 @@ |
|
| 787 |
- [{xmlcdata, "401 Unauthorized"}]}])}
|
|
| 788 |
- end; |
|
| 789 |
- |
|
| 790 |
--process_get({true, _},
|
|
| 791 |
-+process_get({true, _, _},
|
|
| 792 |
- #request{path = ["http-poll" | RPath],
|
|
| 793 |
- q = _Query, |
|
| 794 |
- lang = _Lang} = Request) -> |
|
| 795 |
- ejabberd_http_poll:process_request(Request#request{path = RPath});
|
|
| 796 |
- |
|
| 797 |
-+process_get({_, true, _},
|
|
| 798 |
-+ #request{us = _US,
|
|
| 799 |
-+ path = ["http-bind" | RPath], |
|
| 800 |
-+ q = _Query, |
|
| 801 |
-+ lang = _Lang} = Request) -> |
|
| 802 |
-+ ejabberd_http_bind:process_request(Request#request{path = RPath});
|
|
| 803 |
-+ |
|
| 804 |
- process_get(_, _Request) -> |
|
| 805 |
- {404, [], make_xhtml([?XC("h1", "Not found")])}.
|
|
| 806 |
- |
|
| 807 |
-Index: src/web/ejabberd_http.erl |
|
| 808 |
-=================================================================== |
|
| 809 |
---- src/web/ejabberd_http.erl (Revision 565) |
|
| 810 |
-+++ src/web/ejabberd_http.erl (Arbeitskopie) |
|
| 811 |
-@@ -30,6 +30,7 @@ |
|
| 812 |
- request_keepalive, |
|
| 813 |
- request_content_length, |
|
| 814 |
- request_lang = "en", |
|
| 815 |
-+ use_http_bind = false, |
|
| 816 |
- use_http_poll = false, |
|
| 817 |
- use_web_admin = false, |
|
| 818 |
- end_of_request = false, |
|
| 819 |
-@@ -70,15 +71,17 @@ |
|
| 820 |
- _ -> |
|
| 821 |
- ok |
|
| 822 |
- end, |
|
| 823 |
-+ UseHTTPBind = lists:member(http_bind, Opts), |
|
| 824 |
- UseHTTPPoll = lists:member(http_poll, Opts), |
|
| 825 |
- UseWebAdmin = lists:member(web_admin, Opts), |
|
| 826 |
-- ?DEBUG("S: ~p~n", [{UseHTTPPoll, UseWebAdmin}]),
|
|
| 827 |
-+ ?DEBUG("S: ~p~n", [{UseHTTPPoll, UseHTTPBind, UseWebAdmin}]),
|
|
| 828 |
- ?INFO_MSG("started: ~p", [{SockMod1, Socket1}]),
|
|
| 829 |
- {ok, proc_lib:spawn_link(ejabberd_http,
|
|
| 830 |
- receive_headers, |
|
| 831 |
- [#state{sockmod = SockMod1,
|
|
| 832 |
- socket = Socket1, |
|
| 833 |
- use_http_poll = UseHTTPPoll, |
|
| 834 |
-+ use_http_bind = UseHTTPBind, |
|
| 835 |
- use_web_admin = UseWebAdmin}])}. |
|
| 836 |
- |
|
| 837 |
- |
|
| 838 |
-@@ -185,6 +188,7 @@ |
|
| 839 |
- #state{sockmod = SockMod,
|
|
| 840 |
- socket = Socket, |
|
| 841 |
- use_http_poll = State#state.use_http_poll, |
|
| 842 |
-+ use_http_bind = State#state.use_http_bind, |
|
| 843 |
- use_web_admin = State#state.use_web_admin}; |
|
| 844 |
- _ -> |
|
| 845 |
- #state{end_of_request = true}
|
|
| 846 |
-@@ -200,6 +204,7 @@ |
|
| 847 |
- request_auth = Auth, |
|
| 848 |
- request_lang = Lang, |
|
| 849 |
- use_http_poll = UseHTTPPoll, |
|
| 850 |
-+ use_http_bind = UseHTTPBind, |
|
| 851 |
- use_web_admin = UseWebAdmin} = State) -> |
|
| 852 |
- case (catch url_decode_q_split(Path)) of |
|
| 853 |
- {'EXIT', _} ->
|
|
| 854 |
-@@ -217,7 +222,7 @@ |
|
| 855 |
- q = LQuery, |
|
| 856 |
- auth = Auth, |
|
| 857 |
- lang = Lang}, |
|
| 858 |
-- case ejabberd_web:process_get({UseHTTPPoll, UseWebAdmin},
|
|
| 859 |
-+ case ejabberd_web:process_get({UseHTTPPoll, UseHTTPBind, UseWebAdmin},
|
|
| 860 |
- Request) of |
|
| 861 |
- El when element(1, El) == xmlelement -> |
|
| 862 |
- make_xhtml_output(State, 200, [], El); |
|
| 863 |
-@@ -240,6 +245,7 @@ |
|
| 864 |
- sockmod = SockMod, |
|
| 865 |
- socket = Socket, |
|
| 866 |
- use_http_poll = UseHTTPPoll, |
|
| 867 |
-+ use_http_bind = UseHTTPBind, |
|
| 868 |
- use_web_admin = UseWebAdmin} = State) |
|
| 869 |
- when is_integer(Len) -> |
|
| 870 |
- case SockMod of |
|
| 871 |
-@@ -267,7 +273,7 @@ |
|
| 872 |
- auth = Auth, |
|
| 873 |
- data = Data, |
|
| 874 |
- lang = Lang}, |
|
| 875 |
-- case ejabberd_web:process_get({UseHTTPPoll, UseWebAdmin},
|
|
| 876 |
-+ case ejabberd_web:process_get({UseHTTPPoll, UseHTTPBind, UseWebAdmin},
|
|
| 877 |
- Request) of |
|
| 878 |
- El when element(1, El) == xmlelement -> |
|
| 879 |
- make_xhtml_output(State, 200, [], El); |
|
| 880 |
-Index: src/xml.erl |
|
| 881 |
-=================================================================== |
|
| 882 |
---- src/xml.erl (Revision 565) |
|
| 883 |
-+++ src/xml.erl (Arbeitskopie) |
|
| 884 |
-@@ -18,6 +18,7 @@ |
|
| 885 |
- get_tag_attr/2, get_tag_attr_s/2, |
|
| 886 |
- get_subtag/2, |
|
| 887 |
- get_path_s/2, |
|
| 888 |
-+ remove_tag_attr/2, |
|
| 889 |
- replace_tag_attr/3]). |
|
| 890 |
- |
|
| 891 |
- %element_to_string(El) -> |
|
| 892 |
-@@ -224,6 +225,14 @@ |
|
| 893 |
- get_path_s(El, [cdata]) -> |
|
| 894 |
- get_tag_cdata(El). |
|
| 895 |
- |
|
| 896 |
-+remove_tag_attr(Attr, El) -> |
|
| 897 |
-+ case El of |
|
| 898 |
-+ {xmlelement, Name, Attrs, Els} ->
|
|
| 899 |
-+ Attrs1 = lists:keydelete(Attr, 1, Attrs), |
|
| 900 |
-+ {xmlelement, Name, Attrs1, Els};
|
|
| 901 |
-+ _ -> |
|
| 902 |
-+ El |
|
| 903 |
-+ end. |
|
| 904 |
- |
|
| 905 |
- replace_tag_attr(Attr, Value, {xmlelement, Name, Attrs, Els}) ->
|
|
| 906 |
- Attrs1 = lists:keydelete(Attr, 1, Attrs), |
|
| 907 |
- |
|
| 908 |
-Index: src/ejabberd_sup.erl |
|
| 909 |
-=================================================================== |
|
| 910 |
---- src/ejabberd_sup.erl (Revision 565) |
|
| 911 |
-+++ src/ejabberd_sup.erl (Arbeitskopie) |
|
| 912 |
-@@ -123,6 +123,14 @@ |
|
| 913 |
- infinity, |
|
| 914 |
- supervisor, |
|
| 915 |
- [ejabberd_tmp_sup]}, |
|
| 916 |
-+ HTTPBindSupervisor = |
|
| 917 |
-+ {ejabberd_http_bind_sup,
|
|
| 918 |
-+ {ejabberd_tmp_sup, start_link,
|
|
| 919 |
-+ [ejabberd_http_bind_sup, ejabberd_http_bind]}, |
|
| 920 |
-+ permanent, |
|
| 921 |
-+ infinity, |
|
| 922 |
-+ supervisor, |
|
| 923 |
-+ [ejabberd_tmp_sup]}, |
|
| 924 |
- IQSupervisor = |
|
| 925 |
- {ejabberd_iq_sup,
|
|
| 926 |
- {ejabberd_tmp_sup, start_link,
|
|
| 927 |
-@@ -145,6 +153,7 @@ |
|
| 928 |
- ServiceSupervisor, |
|
| 929 |
- HTTPSupervisor, |
|
| 930 |
- HTTPPollSupervisor, |
|
| 931 |
-+ HTTPBindSupervisor, |
|
| 932 |
- IQSupervisor, |
|
| 933 |
- Listener]}}. |
|
| 934 |
- |
| ... | ... |
@@ -1,11 +0,0 @@ |
| 1 |
---- mod_irc/mod_irc.erl.orig 2006-11-19 14:40:02.463429250 +0100 |
|
| 2 |
-+++ mod_irc/mod_irc.erl 2006-11-19 14:40:25.888893250 +0100 |
|
| 3 |
-@@ -27,7 +27,7 @@ |
|
| 4 |
- -include("ejabberd.hrl").
|
|
| 5 |
- -include("jlib.hrl").
|
|
| 6 |
- |
|
| 7 |
---define(DEFAULT_IRC_ENCODING, "koi8-r"). |
|
| 8 |
-+-define(DEFAULT_IRC_ENCODING, "utf-8"). |
|
| 9 |
- |
|
| 10 |
- -record(irc_connection, {jid_server_host, pid}).
|
|
| 11 |
- -record(irc_custom, {us_host, data}).
|
| ... | ... |
@@ -1,11 +0,0 @@ |
| 1 |
-diff -Naur ejabberd-1.1.1.orig/src/odbc/ejabberd_odbc.erl ejabberd-1.1.1/src/odbc/ejabberd_odbc.erl |
|
| 2 |
---- ejabberd-1.1.1.orig/src/odbc/ejabberd_odbc.erl 2006-05-07 19:05:12.549917750 +0400 |
|
| 3 |
-+++ ejabberd-1.1.1/src/odbc/ejabberd_odbc.erl 2006-05-07 19:06:11.337591750 +0400 |
|
| 4 |
-@@ -281,6 +281,7 @@ |
|
| 5 |
- case mysql_conn:start(Server, ?MYSQL_PORT, Username, Password, DB, NoLogFun) of |
|
| 6 |
- {ok, Ref} ->
|
|
| 7 |
- erlang:monitor(process, Ref), |
|
| 8 |
-+ catch mysql_conn:fetch(Ref, "SET NAMES 'utf8';", self()), |
|
| 9 |
- {ok, #state{db_ref = Ref, db_type = mysql}};
|
|
| 10 |
- {error, Reason} ->
|
|
| 11 |
- ?ERROR_MSG("MySQL connection failed: ~p~n", [Reason]),
|
| ... | ... |
@@ -1,406 +0,0 @@ |
| 1 |
-* modified files |
|
| 2 |
- |
|
| 3 |
- |
|
| 4 |
---- jlib.hrl |
|
| 5 |
-+++ jlib.hrl |
|
| 6 |
-@@ -34,6 +34,7 @@ |
|
| 7 |
- -define(NS_PUBSUB_OWNER, "http://jabber.org/protocol/pubsub#owner"). |
|
| 8 |
- -define(NS_PUBSUB_NMI, "http://jabber.org/protocol/pubsub#node-meta-info"). |
|
| 9 |
- -define(NS_COMMANDS, "http://jabber.org/protocol/commands"). |
|
| 10 |
-+-define(NS_BYTESTREAMS, "http://jabber.org/protocol/bytestreams"). |
|
| 11 |
- |
|
| 12 |
- -define(NS_EJABBERD_CONFIG, "ejabberd:config"). |
|
| 13 |
- |
|
| 14 |
- |
|
| 15 |
- |
|
| 16 |
- |
|
| 17 |
-* added files |
|
| 18 |
- |
|
| 19 |
---- /dev/null |
|
| 20 |
-+++ mod_proxy65.erl |
|
| 21 |
-@@ -0,0 +1,189 @@ |
|
| 22 |
-+%%%---------------------------------------------------------------------- |
|
| 23 |
-+%%% File : mod_proxy65.erl |
|
| 24 |
-+%%% Author : Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 25 |
-+%%% Purpose : Handle Jabber communications for JEP-0065 proxy |
|
| 26 |
-+%%% Created : 27 Dec 2005 by Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 27 |
-+%%% Id : $Id: ejabberd_c2s.erl 440 2005-11-22 18:00:56Z alexey $ |
|
| 28 |
-+%%%---------------------------------------------------------------------- |
|
| 29 |
-+ |
|
| 30 |
-+-module(mod_proxy65). |
|
| 31 |
-+-author('henoch@dtek.chalmers.se').
|
|
| 32 |
-+-vsn('$Revision$ ').
|
|
| 33 |
-+ |
|
| 34 |
-+-behaviour(gen_mod). |
|
| 35 |
-+ |
|
| 36 |
-+-export([start/2, |
|
| 37 |
-+ init/1, |
|
| 38 |
-+ stop/1]). |
|
| 39 |
-+ |
|
| 40 |
-+-include("ejabberd.hrl").
|
|
| 41 |
-+-include("jlib.hrl").
|
|
| 42 |
-+ |
|
| 43 |
-+-record(proxy65_connection, {cookie, firstpid = none, secondpid = none}).
|
|
| 44 |
-+ |
|
| 45 |
-+-record(proxy65_options, {host, access, streamhosts}).
|
|
| 46 |
-+ |
|
| 47 |
-+-define(PROCNAME, ejabberd_mod_proxy65). |
|
| 48 |
-+ |
|
| 49 |
-+start(Host, Opts) -> |
|
| 50 |
-+ mnesia:create_table(proxy65_connection, |
|
| 51 |
-+ [{ram_copies, [node()]},
|
|
| 52 |
-+ {attributes, record_info(fields, proxy65_connection)}]),
|
|
| 53 |
-+ MyHost = gen_mod:get_opt(host, Opts, "proxy." ++ Host), |
|
| 54 |
-+ Access = gen_mod:get_opt(access, Opts, all), |
|
| 55 |
-+ Streamhosts = gen_mod:get_opt(streamhosts, Opts, [{Host, 7777}]),
|
|
| 56 |
-+ |
|
| 57 |
-+ register(gen_mod:get_module_proc(Host, ?PROCNAME), |
|
| 58 |
-+ spawn(?MODULE, init, [#proxy65_options{host = MyHost, access = Access,
|
|
| 59 |
-+ streamhosts = Streamhosts}])). |
|
| 60 |
-+ |
|
| 61 |
-+ |
|
| 62 |
-+stop(Host) -> |
|
| 63 |
-+ Proc = gen_mod:get_module_proc(Host, ?PROCNAME), |
|
| 64 |
-+ Proc ! stop, |
|
| 65 |
-+ {wait, Proc}.
|
|
| 66 |
-+ |
|
| 67 |
-+init(#proxy65_options{host = Host} = Opts) ->
|
|
| 68 |
-+ ejabberd_router:register_route(Host), |
|
| 69 |
-+ loop(Opts). |
|
| 70 |
-+ |
|
| 71 |
-+loop(#proxy65_options{host = Host} = Opts) ->
|
|
| 72 |
-+ receive |
|
| 73 |
-+ {route, From, To, Packet} ->
|
|
| 74 |
-+ case catch do_route(Opts, From, To, Packet) of |
|
| 75 |
-+ {'EXIT', Reason} ->
|
|
| 76 |
-+ ?ERROR_MSG("~p", [Reason]);
|
|
| 77 |
-+ _ -> |
|
| 78 |
-+ ok |
|
| 79 |
-+ end, |
|
| 80 |
-+ loop(Opts); |
|
| 81 |
-+ stop -> |
|
| 82 |
-+ ejabberd_router:unregister_route(Host), |
|
| 83 |
-+ ok; |
|
| 84 |
-+ _ -> |
|
| 85 |
-+ loop(Opts) |
|
| 86 |
-+ end. |
|
| 87 |
-+ |
|
| 88 |
-+do_route(#proxy65_options{host = Host, access = Access} = Opts,
|
|
| 89 |
-+ From, To, Packet) -> |
|
| 90 |
-+ case acl:match_rule(Host, Access, From) of |
|
| 91 |
-+ allow -> |
|
| 92 |
-+ do_route1(Opts, From, To, Packet); |
|
| 93 |
-+ _ -> |
|
| 94 |
-+ {xmlelement, _Name, Attrs, _Els} = Packet,
|
|
| 95 |
-+ Lang = xml:get_attr_s("xml:lang", Attrs),
|
|
| 96 |
-+ ErrText = "Access denied by service policy", |
|
| 97 |
-+ Err = jlib:make_error_reply(Packet, |
|
| 98 |
-+ ?ERRT_FORBIDDEN(Lang, ErrText)), |
|
| 99 |
-+ ejabberd_router:route(To, From, Err) |
|
| 100 |
-+ end. |
|
| 101 |
-+ |
|
| 102 |
-+do_route1(#proxy65_options{host = Host, streamhosts = Streamhosts}, From, To, Packet) ->
|
|
| 103 |
-+ {xmlelement, Name, _Attrs, _Els} = Packet,
|
|
| 104 |
-+ case Name of |
|
| 105 |
-+ "iq" -> |
|
| 106 |
-+ case jlib:iq_query_info(Packet) of |
|
| 107 |
-+ #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
|
|
| 108 |
-+ lang = Lang, sub_el = SubEl} = IQ -> |
|
| 109 |
-+ Node = xml:get_tag_attr_s("node", SubEl),
|
|
| 110 |
-+ if Node == [] -> |
|
| 111 |
-+ Res = IQ#iq{type = result,
|
|
| 112 |
-+ sub_el = [{xmlelement, "query",
|
|
| 113 |
-+ [{"xmlns", XMLNS}],
|
|
| 114 |
-+ [{xmlelement, "identity",
|
|
| 115 |
-+ [{"category", "proxy"},
|
|
| 116 |
-+ {"type", "bytestreams"},
|
|
| 117 |
-+ {"name", translate:translate(Lang, "SOCKS5 bytestreams proxy")}],
|
|
| 118 |
-+ []}, |
|
| 119 |
-+ {xmlelement, "feature",
|
|
| 120 |
-+ [{"var", ?NS_BYTESTREAMS}], []}]}]};
|
|
| 121 |
-+ true -> |
|
| 122 |
-+ Res = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND) |
|
| 123 |
-+ end; |
|
| 124 |
-+ #iq{type = get, xmlns = ?NS_DISCO_ITEMS = XMLNS} = IQ ->
|
|
| 125 |
-+ Res = IQ#iq{type = result,
|
|
| 126 |
-+ sub_el = [{xmlelement, "query",
|
|
| 127 |
-+ [{"xmlns", XMLNS}], []}]};
|
|
| 128 |
-+ #iq{type = get, xmlns = ?NS_VERSION} = IQ ->
|
|
| 129 |
-+ OSType = case os:type() of |
|
| 130 |
-+ {Osfamily, Osname} ->
|
|
| 131 |
-+ atom_to_list(Osfamily) ++ "/" ++ |
|
| 132 |
-+ atom_to_list(Osname); |
|
| 133 |
-+ Osfamily -> |
|
| 134 |
-+ atom_to_list(Osfamily) |
|
| 135 |
-+ end, |
|
| 136 |
-+ OSVersion = case os:version() of |
|
| 137 |
-+ {Major, Minor, Release} ->
|
|
| 138 |
-+ lists:flatten( |
|
| 139 |
-+ io_lib:format("~w.~w.~w",
|
|
| 140 |
-+ [Major, Minor, Release])); |
|
| 141 |
-+ VersionString -> |
|
| 142 |
-+ VersionString |
|
| 143 |
-+ end, |
|
| 144 |
-+ OS = OSType ++ " " ++ OSVersion, |
|
| 145 |
-+ Res = IQ#iq{type = result,
|
|
| 146 |
-+ sub_el = [{xmlelement, "query",
|
|
| 147 |
-+ [{"xmlns", ?NS_VERSION}],
|
|
| 148 |
-+ [{xmlelement, "name", [],
|
|
| 149 |
-+ [{xmlcdata, "ejabberd mod_proxy65 (unofficial)"}]},
|
|
| 150 |
-+ {xmlelement, "version", [],
|
|
| 151 |
-+ [{xmlcdata, "0.1"}]},
|
|
| 152 |
-+ {xmlelement, "os", [],
|
|
| 153 |
-+ [{xmlcdata, OS}]}
|
|
| 154 |
-+ ]}]}; |
|
| 155 |
-+ #iq{type = get, xmlns = ?NS_BYTESTREAMS = XMLNS} = IQ ->
|
|
| 156 |
-+ Res = IQ#iq{type = result,
|
|
| 157 |
-+ sub_el = [{xmlelement, "query",
|
|
| 158 |
-+ [{"xmlns", XMLNS}],
|
|
| 159 |
-+ return_streamhosts(Host, Streamhosts)}]}; |
|
| 160 |
-+ #iq{type = set, xmlns = ?NS_BYTESTREAMS} = IQ ->
|
|
| 161 |
-+ Res = activate(Packet, From, To, IQ); |
|
| 162 |
-+ _ -> |
|
| 163 |
-+ Res = jlib:make_error_reply(Packet, ?ERR_FEATURE_NOT_IMPLEMENTED) |
|
| 164 |
-+ end, |
|
| 165 |
-+ case Res of |
|
| 166 |
-+ #iq{} ->
|
|
| 167 |
-+ ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); |
|
| 168 |
-+ _ -> |
|
| 169 |
-+ ejabberd_router:route(To, From, Res) |
|
| 170 |
-+ end; |
|
| 171 |
-+ _ -> |
|
| 172 |
-+ ejabberd_router:route(To, From, jlib:make_error_reply(Packet, ?ERR_FEATURE_NOT_IMPLEMENTED)) |
|
| 173 |
-+ end. |
|
| 174 |
-+ |
|
| 175 |
-+return_streamhosts(_JID, []) -> |
|
| 176 |
-+ []; |
|
| 177 |
-+return_streamhosts(JID, [{Host, Port} | Streamhosts]) ->
|
|
| 178 |
-+ %% This is not tail-recursive, but it doesn't matter. |
|
| 179 |
-+ [{xmlelement, "streamhost",
|
|
| 180 |
-+ [{"jid", JID},
|
|
| 181 |
-+ {"host", Host},
|
|
| 182 |
-+ {"port", integer_to_list(Port)}],
|
|
| 183 |
-+ []} | return_streamhosts(JID, Streamhosts)]. |
|
| 184 |
-+ |
|
| 185 |
-+activate(Packet, From, _To, #iq{sub_el = SubEl} = IQ) ->
|
|
| 186 |
-+ case SubEl of |
|
| 187 |
-+ {xmlelement, "query", Attrs, _SubEls} ->
|
|
| 188 |
-+ Sid = xml:get_attr_s("sid", Attrs),
|
|
| 189 |
-+ ActivateTag = xml:get_subtag(SubEl, "activate"), |
|
| 190 |
-+ if ActivateTag /= false -> |
|
| 191 |
-+ TargetJID = jlib:string_to_jid(xml:get_tag_cdata(ActivateTag)); |
|
| 192 |
-+ true -> |
|
| 193 |
-+ TargetJID = false |
|
| 194 |
-+ end, |
|
| 195 |
-+ |
|
| 196 |
-+ if Sid /= [], TargetJID /= false, TargetJID /= error -> |
|
| 197 |
-+ case proxy65_listener:activate(From, TargetJID, Sid) of |
|
| 198 |
-+ ok -> |
|
| 199 |
-+ ?INFO_MSG("Activated connection between ~s and ~s",
|
|
| 200 |
-+ [jlib:jid_to_string(From), TargetJID]), |
|
| 201 |
-+ IQ#iq{type = result, sub_el = []};
|
|
| 202 |
-+ _ -> |
|
| 203 |
-+ jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR) |
|
| 204 |
-+ end; |
|
| 205 |
-+ true -> |
|
| 206 |
-+ jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST) |
|
| 207 |
-+ end; |
|
| 208 |
-+ _ -> |
|
| 209 |
-+ jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST) |
|
| 210 |
-+ end. |
|
| 211 |
---- /dev/null |
|
| 212 |
-+++ proxy65_listener.erl |
|
| 213 |
-@@ -0,0 +1,192 @@ |
|
| 214 |
-+%%%---------------------------------------------------------------------- |
|
| 215 |
-+%%% File : proxy65_listener.erl |
|
| 216 |
-+%%% Author : Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 217 |
-+%%% Purpose : Handle SOCKS5 connections for JEP-0065 proxy |
|
| 218 |
-+%%% Created : 27 Dec 2005 by Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 219 |
-+%%% Id : $Id: ejabberd_c2s.erl 440 2005-11-22 18:00:56Z alexey $ |
|
| 220 |
-+%%%---------------------------------------------------------------------- |
|
| 221 |
-+ |
|
| 222 |
-+-module(proxy65_listener). |
|
| 223 |
-+-author('henoch@dtek.chalmers.se').
|
|
| 224 |
-+-vsn('$Revision$ ').
|
|
| 225 |
-+ |
|
| 226 |
-+-export([start/2, handle_connection/2, activate/3]). |
|
| 227 |
-+ |
|
| 228 |
-+-include("ejabberd.hrl").
|
|
| 229 |
-+-include("jlib.hrl").
|
|
| 230 |
-+ |
|
| 231 |
-+-record(proxy65_connection, {cookie, firstpid = none, secondpid = none}).
|
|
| 232 |
-+ |
|
| 233 |
-+start({SockMod, Socket}, Opts) ->
|
|
| 234 |
-+ {ok, proc_lib:spawn(?MODULE, handle_connection, [{SockMod, Socket}, Opts])}.
|
|
| 235 |
-+ |
|
| 236 |
-+read_bytes(_SockOpts, 0, Data) -> |
|
| 237 |
-+ lists:flatten(Data); |
|
| 238 |
-+read_bytes({SockMod, Socket} = SockOpts, N, Data) ->
|
|
| 239 |
-+ Timeout = 1000, |
|
| 240 |
-+ case SockMod:recv(Socket, N, Timeout) of |
|
| 241 |
-+ {error, closed} ->
|
|
| 242 |
-+ %% On closed connection, return everything we have, |
|
| 243 |
-+ %% but not if we have nothing. |
|
| 244 |
-+ if Data == [] -> |
|
| 245 |
-+ erlang:error(closed); |
|
| 246 |
-+ true -> |
|
| 247 |
-+ lists:flatten(Data) |
|
| 248 |
-+ end; |
|
| 249 |
-+ {ok, MoreData} ->
|
|
| 250 |
-+ ?DEBUG("read ~p", [MoreData]),
|
|
| 251 |
-+ DataList = binary_to_list(MoreData), |
|
| 252 |
-+ read_bytes(SockOpts, N - length(DataList), [Data, DataList]) |
|
| 253 |
-+ end. |
|
| 254 |
-+ |
|
| 255 |
-+handle_connection({SockMod, Socket}, Opts) ->
|
|
| 256 |
-+ ?DEBUG("in handle_connection", []),
|
|
| 257 |
-+ case catch handle_auth({SockMod, Socket}, Opts) of
|
|
| 258 |
-+ {'EXIT', Reason} ->
|
|
| 259 |
-+ ?ERROR_MSG("~p abnormal termination:~n\t~p~n",
|
|
| 260 |
-+ [?MODULE, Reason]), |
|
| 261 |
-+ SockMod:close(Socket); |
|
| 262 |
-+ _ -> |
|
| 263 |
-+ ok |
|
| 264 |
-+ end. |
|
| 265 |
-+ |
|
| 266 |
-+handle_auth({SockMod, Socket} = SockOpts, Opts) ->
|
|
| 267 |
-+ ?DEBUG("in handle_auth", []),
|
|
| 268 |
-+ %% SOCKS protocol stuff... |
|
| 269 |
-+ [5, NAuthMethods] = read_bytes(SockOpts, 2, []), |
|
| 270 |
-+ AuthMethods = read_bytes(SockOpts, NAuthMethods, []), |
|
| 271 |
-+ SupportsNoAuth = lists:member(0, AuthMethods), |
|
| 272 |
-+ |
|
| 273 |
-+ %% Must support no authentication, otherwise crash |
|
| 274 |
-+ true = SupportsNoAuth, |
|
| 275 |
-+ |
|
| 276 |
-+ SockMod:send(Socket, [5, 0]), |
|
| 277 |
-+ |
|
| 278 |
-+ %% And done. |
|
| 279 |
-+ handle_connect(SockOpts, Opts). |
|
| 280 |
-+ |
|
| 281 |
-+handle_connect({SockMod, Socket} = SockOpts, Opts) ->
|
|
| 282 |
-+ ?DEBUG("in handle_connect", []),
|
|
| 283 |
-+ %% Expect a CONNECT command and nothing else |
|
| 284 |
-+ [5, 1, _, 3, AddressLength] = read_bytes(SockOpts, 5, []), |
|
| 285 |
-+ Cookie = read_bytes(SockOpts, AddressLength, []), |
|
| 286 |
-+ [0, 0] = read_bytes(SockOpts, 2, []), |
|
| 287 |
-+ |
|
| 288 |
-+ %% Make sure no more than two connections claim the same cookie. |
|
| 289 |
-+ F = fun() -> |
|
| 290 |
-+ case mnesia:read({proxy65_connection, Cookie}) of
|
|
| 291 |
-+ [] -> |
|
| 292 |
-+ mnesia:write(#proxy65_connection{cookie = Cookie,
|
|
| 293 |
-+ firstpid = self()}), |
|
| 294 |
-+ ok; |
|
| 295 |
-+ [#proxy65_connection{secondpid = none} = C] ->
|
|
| 296 |
-+ mnesia:write(C#proxy65_connection{secondpid = self()}),
|
|
| 297 |
-+ ok |
|
| 298 |
-+ end |
|
| 299 |
-+ end, |
|
| 300 |
-+ |
|
| 301 |
-+ case mnesia:transaction(F) of |
|
| 302 |
-+ {atomic, ok} ->
|
|
| 303 |
-+ SockMod:send(Socket, [5, 0, 0, 3, AddressLength, Cookie, 0, 0]), |
|
| 304 |
-+ wait_for_activation(SockOpts, Opts); |
|
| 305 |
-+ Error -> |
|
| 306 |
-+ %% conflict. send "general SOCKS server failure". |
|
| 307 |
-+ SockMod:send(Socket, [5, 1, 0, 3, AddressLength, Cookie, 0, 0]), |
|
| 308 |
-+ erlang:error({badconnect, Error})
|
|
| 309 |
-+ end. |
|
| 310 |
-+ |
|
| 311 |
-+wait_for_activation(SockOpts, Opts) -> |
|
| 312 |
-+ ?DEBUG("in wait_for_activation", []),
|
|
| 313 |
-+ receive |
|
| 314 |
-+ {get_socket, ReplyTo} ->
|
|
| 315 |
-+ ReplyTo ! SockOpts, |
|
| 316 |
-+ wait_for_activation(SockOpts, Opts); |
|
| 317 |
-+ {activate, TargetSocket, Initiator, Target} ->
|
|
| 318 |
-+ ?DEBUG("activated", []),
|
|
| 319 |
-+ |
|
| 320 |
-+ %% We have no way of knowing which connection belongs to |
|
| 321 |
-+ %% which participant, so give both the maximum traffic |
|
| 322 |
-+ %% allowed to either. |
|
| 323 |
-+ Shapers = case lists:keysearch(shaper, 1, Opts) of |
|
| 324 |
-+ {value, {_, S}} -> S;
|
|
| 325 |
-+ _ -> none |
|
| 326 |
-+ end, |
|
| 327 |
-+ ?DEBUG("we have shapers: ~p", [Shapers]),
|
|
| 328 |
-+ Shaper1 = acl:match_rule(global, Shapers, jlib:string_to_jid(Initiator)), |
|
| 329 |
-+ Shaper2 = acl:match_rule(global, Shapers, jlib:string_to_jid(Target)), |
|
| 330 |
-+ if Shaper1 == none; Shaper2 == none -> |
|
| 331 |
-+ MaxShaper = none; |
|
| 332 |
-+ true -> |
|
| 333 |
-+ ShaperValue1 = ejabberd_config:get_global_option({shaper, Shaper1}),
|
|
| 334 |
-+ ShaperValue2 = ejabberd_config:get_global_option({shaper, Shaper2}),
|
|
| 335 |
-+ |
|
| 336 |
-+ if ShaperValue1 > ShaperValue2 -> |
|
| 337 |
-+ MaxShaper = Shaper1; |
|
| 338 |
-+ true -> |
|
| 339 |
-+ MaxShaper = Shaper2 |
|
| 340 |
-+ end, |
|
| 341 |
-+ ?DEBUG("shapers have values ~p and ~p~nusing ~p", [ShaperValue1, ShaperValue2, MaxShaper]),
|
|
| 342 |
-+ ok |
|
| 343 |
-+ end, |
|
| 344 |
-+ |
|
| 345 |
-+ transfer_data(SockOpts, TargetSocket, shaper:new(MaxShaper)) |
|
| 346 |
-+ end. |
|
| 347 |
-+ |
|
| 348 |
-+transfer_data({SockMod, Socket} = SockOpts, {TargetSockMod, TargetSocket} = TargetSockOpts,
|
|
| 349 |
-+ Shaper) -> |
|
| 350 |
-+ case SockMod:recv(Socket, 0, infinity) of |
|
| 351 |
-+ {ok, Data} ->
|
|
| 352 |
-+ if Data /= <<>> -> |
|
| 353 |
-+ NewShaper = case Shaper of |
|
| 354 |
-+ none -> none; |
|
| 355 |
-+ _ -> |
|
| 356 |
-+ shaper:update(Shaper, size(Data)) |
|
| 357 |
-+ end, |
|
| 358 |
-+ ok = TargetSockMod:send(TargetSocket, Data); |
|
| 359 |
-+ true -> |
|
| 360 |
-+ NewShaper = Shaper |
|
| 361 |
-+ end, |
|
| 362 |
-+ transfer_data(SockOpts, TargetSockOpts, NewShaper); |
|
| 363 |
-+ {error, _} ->
|
|
| 364 |
-+ TargetSockMod:shutdown(TargetSocket, read_write) |
|
| 365 |
-+ end. |
|
| 366 |
-+ |
|
| 367 |
-+get_socket(PID) -> |
|
| 368 |
-+ PID ! {get_socket, self()},
|
|
| 369 |
-+ receive |
|
| 370 |
-+ {_SockMod, _Socket} = SockOpts ->
|
|
| 371 |
-+ SockOpts |
|
| 372 |
-+ end. |
|
| 373 |
-+ |
|
| 374 |
-+%% If any argument is a jid record, convert it to normalized string form... |
|
| 375 |
-+activate(#jid{} = Initiator, Target, SessionID) ->
|
|
| 376 |
-+ NormalizedInitiator = jlib:jid_to_string(jlib:make_jid(jlib:jid_tolower(Initiator))), |
|
| 377 |
-+ activate(NormalizedInitiator, Target, SessionID); |
|
| 378 |
-+activate(Initiator, #jid{} = Target, SessionID) ->
|
|
| 379 |
-+ NormalizedTarget = jlib:jid_to_string(jlib:make_jid(jlib:jid_tolower(Target))), |
|
| 380 |
-+ activate(Initiator, NormalizedTarget, SessionID); |
|
| 381 |
-+%% ...and get on with the activation. |
|
| 382 |
-+activate(Initiator, Target, SessionID) -> |
|
| 383 |
-+ Cookie = sha:sha(SessionID ++ Initiator ++ Target), |
|
| 384 |
-+ F = fun() -> |
|
| 385 |
-+ case mnesia:read({proxy65_connection, Cookie}) of
|
|
| 386 |
-+ [#proxy65_connection{firstpid = FirstPID,
|
|
| 387 |
-+ secondpid = SecondPID}] |
|
| 388 |
-+ when is_pid(FirstPID), is_pid(SecondPID) -> |
|
| 389 |
-+ mnesia:delete({proxy65_connection, Cookie}),
|
|
| 390 |
-+ {FirstPID, SecondPID};
|
|
| 391 |
-+ _ -> |
|
| 392 |
-+ error |
|
| 393 |
-+ end |
|
| 394 |
-+ end, |
|
| 395 |
-+ case mnesia:transaction(F) of |
|
| 396 |
-+ {atomic, {FirstPID, SecondPID}} ->
|
|
| 397 |
-+ FirstSocket = get_socket(FirstPID), |
|
| 398 |
-+ SecondSocket = get_socket(SecondPID), |
|
| 399 |
-+ FirstPID ! {activate, SecondSocket, Initiator, Target},
|
|
| 400 |
-+ SecondPID ! {activate, FirstSocket, Initiator, Target},
|
|
| 401 |
-+ ok; |
|
| 402 |
-+ Error -> |
|
| 403 |
-+ ?ERROR_MSG("Proxy activation failed: ~p", [Error]),
|
|
| 404 |
-+ error |
|
| 405 |
-+ end. |
|
| 406 |
- |
| ... | ... |
@@ -1,17 +0,0 @@ |
| 1 |
-# Copyright 1999-2005 Gentoo Foundation |
|
| 2 |
-# Distributed under the terms of the GNU General Public License v2 |
|
| 3 |
-# $Header: $ |
|
| 4 |
- |
|
| 5 |
-# Name of your ejabberd node. Used by ejabberdctl to determine which |
|
| 6 |
-# node to communicate with. Default is "ejabberd@`hostname -s`". |
|
| 7 |
-#EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 8 |
- |
|
| 9 |
-# Max number of open network connections. Default is 1024. Increasing |
|
| 10 |
-# this will slightly increase memory usage. |
|
| 11 |
-#ERL_MAX_PORTS=1024 |
|
| 12 |
- |
|
| 13 |
-# Return memory to the system after using it, instead of keeping it |
|
| 14 |
-# allocated for future use. Decreases the memory required by ejabberd, |
|
| 15 |
-# but makes it run slower. Default is unset, set to any value to |
|
| 16 |
-# activate. |
|
| 17 |
-#ERL_FULLSWEEP_AFTER=0 |
| ... | ... |
@@ -1,60 +0,0 @@ |
| 1 |
-#!/sbin/runscript |
|
| 2 |
-# Copyright 1999-2005 Gentoo Foundation |
|
| 3 |
-# Distributed under the terms of the GNU General Public License v2 |
|
| 4 |
-# $Header: $ |
|
| 5 |
- |
|
| 6 |
-opts="${opts} reload"
|
|
| 7 |
- |
|
| 8 |
-depend() {
|
|
| 9 |
- use dns |
|
| 10 |
- need net |
|
| 11 |
- provide jabber-server |
|
| 12 |
-} |
|
| 13 |
- |
|
| 14 |
-checkconfig() {
|
|
| 15 |
- if [ ! -e /etc/jabber/ejabberd.cfg ] ; then |
|
| 16 |
- eerror "You need an /etc/jabber/ejabberd.cfg file to run ejabberd" |
|
| 17 |
- return 1 |
|
| 18 |
- fi |
|
| 19 |
-} |
|
| 20 |
- |
|
| 21 |
-start() {
|
|
| 22 |
- checkconfig || return 1 |
|
| 23 |
- ebegin "Starting eJabberd" |
|
| 24 |
- start-stop-daemon --start --quiet --chuid jabber:jabber \ |
|
| 25 |
- --exec /usr/bin/env HOME=/var/run/jabber /usr/bin/ejabberd -- -noshell -detached |
|
| 26 |
- eend $? |
|
| 27 |
-} |
|
| 28 |
- |
|
| 29 |
-stop() {
|
|
| 30 |
- ebegin "Stopping eJabberd" |
|
| 31 |
- if [ -z "$EJABBERD_NODE" ]; |
|
| 32 |
- then |
|
| 33 |
- EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 34 |
- fi |
|
| 35 |
- /usr/bin/ejabberdctl $EJABBERD_NODE stop |
|
| 36 |
- eend $? |
|
| 37 |
-} |
|
| 38 |
- |
|
| 39 |
-# Work around a bug in /sbin/runscript.sh - it won't run our custom |
|
| 40 |
-# restart() unless it finds these two strings in the file. |
|
| 41 |
-# svc_start svc_stop |
|
| 42 |
-restart() {
|
|
| 43 |
- ebegin "Restarting eJabberd" |
|
| 44 |
- if [ -z "$EJABBERD_NODE" ]; |
|
| 45 |
- then |
|
| 46 |
- EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 47 |
- fi |
|
| 48 |
- /usr/bin/ejabberdctl $EJABBERD_NODE restart |
|
| 49 |
- eend $? |
|
| 50 |
-} |
|
| 51 |
- |
|
| 52 |
-reload() {
|
|
| 53 |
- ebegin "Reloading eJabberd" |
|
| 54 |
- if [ -z "$EJABBERD_NODE" ]; |
|
| 55 |
- then |
|
| 56 |
- EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 57 |
- fi |
|
| 58 |
- /usr/bin/ejabberdctl $EJABBERD_NODE reopen-log |
|
| 59 |
- eend $? |
|
| 60 |
-} |
| ... | ... |
@@ -1,934 +0,0 @@ |
| 1 |
-Index: src/ejabberd.cfg.example |
|
| 2 |
-=================================================================== |
|
| 3 |
---- src/ejabberd.cfg.example (Revision 565) |
|
| 4 |
-+++ src/ejabberd.cfg.example (Arbeitskopie) |
|
| 5 |
-@@ -124,7 +124,7 @@ |
|
| 6 |
- {5269, ejabberd_s2s_in, [{shaper, s2s_shaper},
|
|
| 7 |
- {max_stanza_size, 131072}
|
|
| 8 |
- ]}, |
|
| 9 |
-- {5280, ejabberd_http, [http_poll, web_admin]},
|
|
| 10 |
-+ {5280, ejabberd_http, [http_poll, http_bind, web_admin]},
|
|
| 11 |
- {8888, ejabberd_service, [{access, all},
|
|
| 12 |
- {hosts, ["icq.localhost", "sms.localhost"],
|
|
| 13 |
- [{password, "secret"}]}]}
|
|
| 14 |
-Index: src/web/Makefile.in |
|
| 15 |
-=================================================================== |
|
| 16 |
---- src/web/Makefile.in (Revision 565) |
|
| 17 |
-+++ src/web/Makefile.in (Arbeitskopie) |
|
| 18 |
-@@ -15,7 +15,8 @@ |
|
| 19 |
- $(OUTDIR)/ejabberd_http.beam \ |
|
| 20 |
- $(OUTDIR)/ejabberd_web.beam \ |
|
| 21 |
- $(OUTDIR)/ejabberd_web_admin.beam \ |
|
| 22 |
-- $(OUTDIR)/ejabberd_http_poll.beam |
|
| 23 |
-+ $(OUTDIR)/ejabberd_http_poll.beam \ |
|
| 24 |
-+ $(OUTDIR)/ejabberd_http_bind.beam |
|
| 25 |
- |
|
| 26 |
- all: $(OBJS) |
|
| 27 |
- |
|
| 28 |
-Index: src/web/ejabberd_http_bind.erl |
|
| 29 |
-=================================================================== |
|
| 30 |
---- src/web/ejabberd_http_bind.erl (Revision 0) |
|
| 31 |
-+++ src/web/ejabberd_http_bind.erl (Revision 0) |
|
| 32 |
-@@ -0,0 +1,731 @@ |
|
| 33 |
-+%%%---------------------------------------------------------------------- |
|
| 34 |
-+%%% File : ejabberd_http_bind.erl |
|
| 35 |
-+%%% Author : Stefan Strigler <steve@zeank.in-berlin.de> |
|
| 36 |
-+%%% Purpose : HTTP Binding support (JEP-0124) |
|
| 37 |
-+%%% Created : 21 Sep 2005 by Stefan Strigler <steve@zeank.in-berlin.de> |
|
| 38 |
-+%%% Id : $Id: ejabberd_http_bind.erl,v 1.2 2006/01/16 10:47:50 zeank Exp $ |
|
| 39 |
-+%%%---------------------------------------------------------------------- |
|
| 40 |
-+ |
|
| 41 |
-+-module(ejabberd_http_bind). |
|
| 42 |
-+-author('steve@zeank.in-berlin.de').
|
|
| 43 |
-+-vsn('Revision: 1.3').
|
|
| 44 |
-+ |
|
| 45 |
-+-behaviour(gen_fsm). |
|
| 46 |
-+ |
|
| 47 |
-+%% External exports |
|
| 48 |
-+-export([start_link/2, |
|
| 49 |
-+ init/1, |
|
| 50 |
-+ handle_event/3, |
|
| 51 |
-+ handle_sync_event/4, |
|
| 52 |
-+ code_change/4, |
|
| 53 |
-+ handle_info/3, |
|
| 54 |
-+ terminate/3, |
|
| 55 |
-+ send/2, |
|
| 56 |
-+ setopts/2, |
|
| 57 |
-+ controlling_process/2, |
|
| 58 |
-+ close/1, |
|
| 59 |
-+ process_request/1]). |
|
| 60 |
-+ |
|
| 61 |
-+%%-define(ejabberd_debug, true). |
|
| 62 |
-+ |
|
| 63 |
-+-include("ejabberd.hrl").
|
|
| 64 |
-+-include("jlib.hrl").
|
|
| 65 |
-+-include("ejabberd_http.hrl").
|
|
| 66 |
-+ |
|
| 67 |
-+-record(http_bind, {id, pid, hold, wait}).
|
|
| 68 |
-+ |
|
| 69 |
-+%% http binding request |
|
| 70 |
-+-record(hbr, {rid,
|
|
| 71 |
-+ key, |
|
| 72 |
-+ in, |
|
| 73 |
-+ out}). |
|
| 74 |
-+ |
|
| 75 |
-+-record(state, {id,
|
|
| 76 |
-+ rid = error, |
|
| 77 |
-+ key, |
|
| 78 |
-+ output = "", |
|
| 79 |
-+ input = "", |
|
| 80 |
-+ waiting_input = false, |
|
| 81 |
-+ last_receiver, |
|
| 82 |
-+ last_poll, |
|
| 83 |
-+ ctime = 0, |
|
| 84 |
-+ timer, |
|
| 85 |
-+ req_list = [] % list of requests |
|
| 86 |
-+ }). |
|
| 87 |
-+ |
|
| 88 |
-+ |
|
| 89 |
-+%-define(DBGFSM, true). |
|
| 90 |
-+ |
|
| 91 |
-+-ifdef(DBGFSM). |
|
| 92 |
-+-define(FSMOPTS, [{debug, [trace]}]).
|
|
| 93 |
-+-else. |
|
| 94 |
-+-define(FSMOPTS, []). |
|
| 95 |
-+-endif. |
|
| 96 |
-+ |
|
| 97 |
-+-define(MAX_REQUESTS, 2). % number of simultaneous requests |
|
| 98 |
-+-define(MIN_POLLING, "2"). % don't poll faster than that or we will shoot you |
|
| 99 |
-+-define(MAX_WAIT, 60). % max num of secs to keep a request on hold |
|
| 100 |
-+-define(MAX_INACTIVITY, 30000). % msecs to wait before terminating idle sessions |
|
| 101 |
-+-define(CT, {"Content-Type", "text/xml; charset=utf-8"}).
|
|
| 102 |
-+-define(BAD_REQUEST, ?CT). |
|
| 103 |
-+ |
|
| 104 |
-+ |
|
| 105 |
-+%%%---------------------------------------------------------------------- |
|
| 106 |
-+%%% API |
|
| 107 |
-+%%%---------------------------------------------------------------------- |
|
| 108 |
-+start(ID, Key) -> |
|
| 109 |
-+ mnesia:create_table(http_bind, |
|
| 110 |
-+ [{ram_copies, [node()]},
|
|
| 111 |
-+ {attributes, record_info(fields, http_bind)}]),
|
|
| 112 |
-+ supervisor:start_child(ejabberd_http_bind_sup, [ID, Key]). |
|
| 113 |
-+ |
|
| 114 |
-+start_link(ID, Key) -> |
|
| 115 |
-+ gen_fsm:start_link(?MODULE, [ID, Key], ?FSMOPTS). |
|
| 116 |
-+ |
|
| 117 |
-+send({http_bind, FsmRef}, Packet) ->
|
|
| 118 |
-+ gen_fsm:sync_send_all_state_event(FsmRef, {send, Packet}).
|
|
| 119 |
-+ |
|
| 120 |
-+setopts({http_bind, FsmRef}, Opts) ->
|
|
| 121 |
-+ case lists:member({active, once}, Opts) of
|
|
| 122 |
-+ true -> |
|
| 123 |
-+ gen_fsm:sync_send_all_state_event(FsmRef, activate); |
|
| 124 |
-+ _ -> |
|
| 125 |
-+ ok |
|
| 126 |
-+ end. |
|
| 127 |
-+ |
|
| 128 |
-+controlling_process(_Socket, _Pid) -> |
|
| 129 |
-+ ok. |
|
| 130 |
-+ |
|
| 131 |
-+close({http_bind, FsmRef}) ->
|
|
| 132 |
-+ catch gen_fsm:sync_send_all_state_event(FsmRef, close). |
|
| 133 |
-+ |
|
| 134 |
-+ |
|
| 135 |
-+process_request(#request{path = [],
|
|
| 136 |
-+ data = Data}) -> |
|
| 137 |
-+ case catch parse_request(Data) of |
|
| 138 |
-+ {ok, ID1, RID, Key, NewKey, Attrs, Packet} ->
|
|
| 139 |
-+ XmppDomain = xml:get_attr_s("to",Attrs),
|
|
| 140 |
-+ if |
|
| 141 |
-+ (ID1 == "") and (XmppDomain == "") -> |
|
| 142 |
-+ {200, [?CT], "<body type='terminate' "
|
|
| 143 |
-+ "condition='improper-addressing' " |
|
| 144 |
-+ "xmlns='http://jabber.org/protocol/httpbind'/>"}; |
|
| 145 |
-+ true -> |
|
| 146 |
-+ ID = if |
|
| 147 |
-+ (ID1 == "") -> |
|
| 148 |
-+ %% create new session |
|
| 149 |
-+ NewID = sha:sha(term_to_binary({now(), make_ref()})),
|
|
| 150 |
-+ {ok, Pid} = start(NewID, Key),
|
|
| 151 |
-+ Wait = case |
|
| 152 |
-+ string:to_integer(xml:get_attr_s("wait",Attrs))
|
|
| 153 |
-+ of |
|
| 154 |
-+ {error, _} ->
|
|
| 155 |
-+ ?MAX_WAIT; |
|
| 156 |
-+ {CWait, _} ->
|
|
| 157 |
-+ if |
|
| 158 |
-+ (CWait > ?MAX_WAIT) -> |
|
| 159 |
-+ ?MAX_WAIT; |
|
| 160 |
-+ true -> |
|
| 161 |
-+ CWait |
|
| 162 |
-+ end |
|
| 163 |
-+ end, |
|
| 164 |
-+ Hold = case |
|
| 165 |
-+ string:to_integer( |
|
| 166 |
-+ xml:get_attr_s("hold",Attrs))
|
|
| 167 |
-+ of |
|
| 168 |
-+ {error, _} ->
|
|
| 169 |
-+ (?MAX_REQUESTS - 1); |
|
| 170 |
-+ {CHold, _} ->
|
|
| 171 |
-+ if |
|
| 172 |
-+ (CHold > (?MAX_REQUESTS - 1)) -> |
|
| 173 |
-+ (?MAX_REQUESTS - 1); |
|
| 174 |
-+ true -> |
|
| 175 |
-+ CHold |
|
| 176 |
-+ end |
|
| 177 |
-+ end, |
|
| 178 |
-+ mnesia:transaction( |
|
| 179 |
-+ fun() -> |
|
| 180 |
-+ mnesia:write(#http_bind{id = NewID,
|
|
| 181 |
-+ pid = Pid, |
|
| 182 |
-+ wait = Wait, |
|
| 183 |
-+ hold = Hold}) |
|
| 184 |
-+ end), |
|
| 185 |
-+ InPacket = if |
|
| 186 |
-+ (XmppDomain /= "") -> |
|
| 187 |
-+ ["<stream:stream to='", |
|
| 188 |
-+ XmppDomain, |
|
| 189 |
-+ "' xmlns='jabber:client' " |
|
| 190 |
-+ "xmlns:stream='http://etherx.jabber.org/streams'>"]; |
|
| 191 |
-+ true -> |
|
| 192 |
-+ "" |
|
| 193 |
-+ end, |
|
| 194 |
-+ NewID; |
|
| 195 |
-+ true -> |
|
| 196 |
-+ %% old session |
|
| 197 |
-+ Type = xml:get_attr_s("type",Attrs),
|
|
| 198 |
-+ Wait = ?MAX_WAIT, |
|
| 199 |
-+ Hold = (?MAX_REQUESTS - 1), |
|
| 200 |
-+ if |
|
| 201 |
-+ (Type == "terminate") -> |
|
| 202 |
-+ %% terminate session |
|
| 203 |
-+ InPacket = Packet ++ "</stream:stream>"; |
|
| 204 |
-+ true -> |
|
| 205 |
-+ InPacket = Packet |
|
| 206 |
-+ end, |
|
| 207 |
-+ ID1 |
|
| 208 |
-+ end, |
|
| 209 |
-+%% ?DEBUG("~n InPacket: ~s ~n", [InPacket]),
|
|
| 210 |
-+ case http_put(ID, RID, Key, NewKey, Hold, InPacket) of |
|
| 211 |
-+ {error, not_exists} ->
|
|
| 212 |
-+ ?DEBUG("no session associated with sid: ~p", [ID]),
|
|
| 213 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 214 |
-+ {error, bad_key} ->
|
|
| 215 |
-+ ?DEBUG("bad key: ~s", Key),
|
|
| 216 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 217 |
-+ [] -> |
|
| 218 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 219 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 220 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop), |
|
| 221 |
-+ {404, [?BAD_REQUEST], ""}
|
|
| 222 |
-+ end; |
|
| 223 |
-+ {error, polling_too_frequently} ->
|
|
| 224 |
-+ ?DEBUG("polling too frequently: ~p", [ID]),
|
|
| 225 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 226 |
-+ [] -> %% unlikely! (?) |
|
| 227 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 228 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 229 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop), |
|
| 230 |
-+ {403, [?BAD_REQUEST], ""}
|
|
| 231 |
-+ end; |
|
| 232 |
-+ {repeat, OutPacket} ->
|
|
| 233 |
-+ ?DEBUG("http_put said 'repeat!' ...~nOutPacket: ~p",
|
|
| 234 |
-+ [OutPacket]), |
|
| 235 |
-+ send_outpacket(ID, OutPacket); |
|
| 236 |
-+ ok -> |
|
| 237 |
-+ receive_loop(ID,ID1,RID,Wait,Hold,Attrs) |
|
| 238 |
-+ end |
|
| 239 |
-+ end; |
|
| 240 |
-+ _ -> |
|
| 241 |
-+ {400, [?BAD_REQUEST], ""}
|
|
| 242 |
-+ end; |
|
| 243 |
-+process_request(_Request) -> |
|
| 244 |
-+ {400, [], {xmlelement, "h1", [],
|
|
| 245 |
-+ [{xmlcdata, "400 Bad Request"}]}}.
|
|
| 246 |
-+ |
|
| 247 |
-+receive_loop(ID,ID1,RID,Wait,Hold,Attrs) -> |
|
| 248 |
-+ receive |
|
| 249 |
-+ after 100 -> ok |
|
| 250 |
-+ end, |
|
| 251 |
-+ prepare_response(ID,ID1,RID,Wait,Hold,Attrs). |
|
| 252 |
-+ |
|
| 253 |
-+prepare_response(ID,ID1,RID,Wait,Hold,Attrs) -> |
|
| 254 |
-+ case http_get(ID,RID) of |
|
| 255 |
-+ {error, not_exists} ->
|
|
| 256 |
-+ ?DEBUG("no session associated with sid: ~s", ID),
|
|
| 257 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 258 |
-+ {ok, keep_on_hold} ->
|
|
| 259 |
-+ receive_loop(ID,ID1,RID,Wait,Hold,Attrs); |
|
| 260 |
-+ {ok, cancel} ->
|
|
| 261 |
-+ %% actually it would be better if we could completely |
|
| 262 |
-+ %% cancel this request, but then we would have to hack |
|
| 263 |
-+ %% ejabberd_http and I'm too lazy now |
|
| 264 |
-+ {404, [?BAD_REQUEST], ""};
|
|
| 265 |
-+ {ok, OutPacket} ->
|
|
| 266 |
-+ ?DEBUG("OutPacket: ~s", [OutPacket]),
|
|
| 267 |
-+ if |
|
| 268 |
-+ ID == ID1 -> |
|
| 269 |
-+ send_outpacket(ID, OutPacket); |
|
| 270 |
-+ true -> |
|
| 271 |
-+ To = xml:get_attr_s("to",Attrs),
|
|
| 272 |
-+ case xml_stream:parse_element( |
|
| 273 |
-+ OutPacket++"</stream:stream>") of |
|
| 274 |
-+ El when element(1, El) == xmlelement -> |
|
| 275 |
-+ {xmlelement, _, OutAttrs, _} = El,
|
|
| 276 |
-+ AuthID = xml:get_attr_s("id", OutAttrs),
|
|
| 277 |
-+ StreamError = false; |
|
| 278 |
-+ {error, _} ->
|
|
| 279 |
-+ AuthID = "", |
|
| 280 |
-+ StreamError = true |
|
| 281 |
-+ end, |
|
| 282 |
-+ if |
|
| 283 |
-+ To == "" -> |
|
| 284 |
-+ {200, [?CT], "<body type='terminate' "
|
|
| 285 |
-+ "condition='improper-addressing' " |
|
| 286 |
-+ "xmlns='http://jabber.org/protocol/httpbind'/>"}; |
|
| 287 |
-+ StreamError == true -> |
|
| 288 |
-+ {200, [?CT], "<body type='terminate' "
|
|
| 289 |
-+ "condition='host-unknown' " |
|
| 290 |
-+ "xmlns='http://jabber.org/protocol/httpbind'/>"}; |
|
| 291 |
-+ true -> |
|
| 292 |
-+ {200, [?CT],
|
|
| 293 |
-+ xml:element_to_string( |
|
| 294 |
-+ {xmlelement,"body",
|
|
| 295 |
-+ [{"xmlns",
|
|
| 296 |
-+ "http://jabber.org/protocol/httpbind"}, |
|
| 297 |
-+ {"sid",ID},
|
|
| 298 |
-+ {"wait", integer_to_list(Wait)},
|
|
| 299 |
-+ {"requests", integer_to_list(Hold+1)},
|
|
| 300 |
-+ {"inactivity",
|
|
| 301 |
-+ integer_to_list(trunc(?MAX_INACTIVITY/1000))}, |
|
| 302 |
-+ {"polling", ?MIN_POLLING},
|
|
| 303 |
-+ {"authid", AuthID}
|
|
| 304 |
-+ ],[]})} |
|
| 305 |
-+ end |
|
| 306 |
-+ end |
|
| 307 |
-+ end. |
|
| 308 |
-+ |
|
| 309 |
-+send_outpacket(ID, OutPacket) -> |
|
| 310 |
-+ case OutPacket of |
|
| 311 |
-+ "" -> |
|
| 312 |
-+ {200, [?CT], "<body xmlns='http://jabber.org/protocol/httpbind'/>"};
|
|
| 313 |
-+ "</stream:stream>" -> |
|
| 314 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 315 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 316 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop) |
|
| 317 |
-+ end, |
|
| 318 |
-+ {200, [?CT], "<body xmlns='http://jabber.org/protocol/httpbind'/>"};
|
|
| 319 |
-+ _ -> |
|
| 320 |
-+ case xml_stream:parse_element("<body>"
|
|
| 321 |
-+ ++ OutPacket |
|
| 322 |
-+ ++ "</body>") |
|
| 323 |
-+ of |
|
| 324 |
-+ El when element(1, El) == xmlelement -> |
|
| 325 |
-+ {xmlelement, _, _, OEls} = El,
|
|
| 326 |
-+ TypedEls = [xml:replace_tag_attr("xmlns",
|
|
| 327 |
-+ "jabber:client",OEl) || |
|
| 328 |
-+ OEl <- OEls], |
|
| 329 |
-+ ?DEBUG(" --- outgoing data --- ~n~s~n --- END --- ~n",
|
|
| 330 |
-+ [xml:element_to_string( |
|
| 331 |
-+ {xmlelement,"body",
|
|
| 332 |
-+ [{"xmlns",
|
|
| 333 |
-+ "http://jabber.org/protocol/httpbind"}], |
|
| 334 |
-+ TypedEls})] |
|
| 335 |
-+ ), |
|
| 336 |
-+ {200, [?CT],
|
|
| 337 |
-+ xml:element_to_string( |
|
| 338 |
-+ {xmlelement,"body",
|
|
| 339 |
-+ [{"xmlns",
|
|
| 340 |
-+ "http://jabber.org/protocol/httpbind"}], |
|
| 341 |
-+ TypedEls})}; |
|
| 342 |
-+ {error, _E} ->
|
|
| 343 |
-+ ?DEBUG("parse error: ~p", [_E]),
|
|
| 344 |
-+ StreamErrCond = case xml_stream:parse_element( |
|
| 345 |
-+ "<stream:stream>"++OutPacket) of |
|
| 346 |
-+ El when element(1, El) == xmlelement -> |
|
| 347 |
-+ {xmlelement, _Tag, _Attr, Els} = El,
|
|
| 348 |
-+ [{xmlelement, SE, _, Cond} | _] = Els,
|
|
| 349 |
-+ if |
|
| 350 |
-+ SE == "stream:error" -> |
|
| 351 |
-+ Cond; |
|
| 352 |
-+ true -> |
|
| 353 |
-+ null |
|
| 354 |
-+ end; |
|
| 355 |
-+ {error, _E} ->
|
|
| 356 |
-+ null |
|
| 357 |
-+ end, |
|
| 358 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 359 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 360 |
-+ gen_fsm:sync_send_all_state_event(FsmRef,stop); |
|
| 361 |
-+ _ -> |
|
| 362 |
-+ err %% hu? |
|
| 363 |
-+ end, |
|
| 364 |
-+ case StreamErrCond of |
|
| 365 |
-+ null -> |
|
| 366 |
-+ {200, [?CT],
|
|
| 367 |
-+ "<body type='terminate' " |
|
| 368 |
-+ "condition='internal-server-error' " |
|
| 369 |
-+ "xmlns='http://jabber.org/protocol/httpbind'/>"}; |
|
| 370 |
-+ _ -> |
|
| 371 |
-+ {200, [?CT],
|
|
| 372 |
-+ "<body type='terminate' " |
|
| 373 |
-+ "condition='remote-stream-error' " |
|
| 374 |
-+ "xmlns='http://jabber.org/protocol/httpbind'>" ++ |
|
| 375 |
-+ elements_to_string(StreamErrCond) ++ |
|
| 376 |
-+ "</body>"} |
|
| 377 |
-+ end |
|
| 378 |
-+ end |
|
| 379 |
-+ end. |
|
| 380 |
-+ |
|
| 381 |
-+%%%---------------------------------------------------------------------- |
|
| 382 |
-+%%% Callback functions from gen_fsm |
|
| 383 |
-+%%%---------------------------------------------------------------------- |
|
| 384 |
-+ |
|
| 385 |
-+%%---------------------------------------------------------------------- |
|
| 386 |
-+%% Func: init/1 |
|
| 387 |
-+%% Returns: {ok, StateName, StateData} |
|
|
| 388 |
-+%% {ok, StateName, StateData, Timeout} |
|
|
| 389 |
-+%% ignore | |
|
| 390 |
-+%% {stop, StopReason}
|
|
| 391 |
-+%%---------------------------------------------------------------------- |
|
| 392 |
-+init([ID, Key]) -> |
|
| 393 |
-+ ?INFO_MSG("started: ~p", [{ID, Key}]),
|
|
| 394 |
-+ Opts = [], % TODO |
|
| 395 |
-+ {ok, C2SPid} = ejabberd_c2s:start({?MODULE, {http_bind, self()}}, Opts),
|
|
| 396 |
-+ ejabberd_c2s:become_controller(C2SPid), |
|
| 397 |
-+ Timer = erlang:start_timer(?MAX_INACTIVITY, self(), []), |
|
| 398 |
-+ {ok, loop, #state{id = ID,
|
|
| 399 |
-+ key = Key, |
|
| 400 |
-+ timer = Timer}}. |
|
| 401 |
-+ |
|
| 402 |
-+%%---------------------------------------------------------------------- |
|
| 403 |
-+%% Func: StateName/2 |
|
| 404 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 405 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 406 |
-+%% {stop, Reason, NewStateData}
|
|
| 407 |
-+%%---------------------------------------------------------------------- |
|
| 408 |
-+ |
|
| 409 |
-+ |
|
| 410 |
-+%%---------------------------------------------------------------------- |
|
| 411 |
-+%% Func: StateName/3 |
|
| 412 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 413 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 414 |
-+%% {reply, Reply, NextStateName, NextStateData} |
|
|
| 415 |
-+%% {reply, Reply, NextStateName, NextStateData, Timeout} |
|
|
| 416 |
-+%% {stop, Reason, NewStateData} |
|
|
| 417 |
-+%% {stop, Reason, Reply, NewStateData}
|
|
| 418 |
-+%%---------------------------------------------------------------------- |
|
| 419 |
-+%state_name(Event, From, StateData) -> |
|
| 420 |
-+% Reply = ok, |
|
| 421 |
-+% {reply, Reply, state_name, StateData}.
|
|
| 422 |
-+ |
|
| 423 |
-+%%---------------------------------------------------------------------- |
|
| 424 |
-+%% Func: handle_event/3 |
|
| 425 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 426 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 427 |
-+%% {stop, Reason, NewStateData}
|
|
| 428 |
-+%%---------------------------------------------------------------------- |
|
| 429 |
-+handle_event(_Event, StateName, StateData) -> |
|
| 430 |
-+ {next_state, StateName, StateData}.
|
|
| 431 |
-+ |
|
| 432 |
-+%%---------------------------------------------------------------------- |
|
| 433 |
-+%% Func: handle_sync_event/4 |
|
| 434 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 435 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 436 |
-+%% {reply, Reply, NextStateName, NextStateData} |
|
|
| 437 |
-+%% {reply, Reply, NextStateName, NextStateData, Timeout} |
|
|
| 438 |
-+%% {stop, Reason, NewStateData} |
|
|
| 439 |
-+%% {stop, Reason, Reply, NewStateData}
|
|
| 440 |
-+%%---------------------------------------------------------------------- |
|
| 441 |
-+handle_sync_event({send, Packet}, _From, StateName, StateData) ->
|
|
| 442 |
-+ Output = [StateData#state.output | Packet], |
|
| 443 |
-+ Reply = ok, |
|
| 444 |
-+ {reply, Reply, StateName, StateData#state{output = Output}};
|
|
| 445 |
-+ |
|
| 446 |
-+handle_sync_event(activate, From, StateName, StateData) -> |
|
| 447 |
-+ case StateData#state.input of |
|
| 448 |
-+ "" -> |
|
| 449 |
-+ {reply, ok, StateName, StateData#state{
|
|
| 450 |
-+ waiting_input = From}}; |
|
| 451 |
-+ Input -> |
|
| 452 |
-+ From ! {tcp, {http_bind, self()}, list_to_binary(Input)},
|
|
| 453 |
-+ {reply, ok, StateName, StateData#state{
|
|
| 454 |
-+ input = "", |
|
| 455 |
-+ waiting_input = false, |
|
| 456 |
-+ last_receiver = From}} |
|
| 457 |
-+ end; |
|
| 458 |
-+ |
|
| 459 |
-+handle_sync_event(stop, _From, _StateName, StateData) -> |
|
| 460 |
-+ Reply = ok, |
|
| 461 |
-+ {stop, normal, Reply, StateData};
|
|
| 462 |
-+ |
|
| 463 |
-+handle_sync_event({http_put, RID, Key, NewKey, Hold, Packet},
|
|
| 464 |
-+ _From, StateName, StateData) -> |
|
| 465 |
-+ %% check if RID valid |
|
| 466 |
-+ RidAllow = case RID of |
|
| 467 |
-+ error -> |
|
| 468 |
-+ false; |
|
| 469 |
-+ _ -> |
|
| 470 |
-+ case StateData#state.rid of |
|
| 471 |
-+ error -> |
|
| 472 |
-+ %% first request - nothing saved so far |
|
| 473 |
-+ true; |
|
| 474 |
-+ OldRID -> |
|
| 475 |
-+ ?DEBUG("state.rid/cur rid: ~p/~p",
|
|
| 476 |
-+ [OldRID, RID]), |
|
| 477 |
-+ if |
|
| 478 |
-+ (OldRID < RID) and |
|
| 479 |
-+ (RID =< (OldRID + Hold + 1)) -> |
|
| 480 |
-+ true; |
|
| 481 |
-+ (RID =< OldRID) and |
|
| 482 |
-+ (RID > OldRID - Hold - 1) -> |
|
| 483 |
-+ repeat; |
|
| 484 |
-+ true -> |
|
| 485 |
-+ false |
|
| 486 |
-+ end |
|
| 487 |
-+ end |
|
| 488 |
-+ end, |
|
| 489 |
-+ %% check if key valid |
|
| 490 |
-+ KeyAllow = case RidAllow of |
|
| 491 |
-+ repeat -> |
|
| 492 |
-+ true; |
|
| 493 |
-+ false -> |
|
| 494 |
-+ false; |
|
| 495 |
-+ true -> |
|
| 496 |
-+ case StateData#state.key of |
|
| 497 |
-+ "" -> |
|
| 498 |
-+ true; |
|
| 499 |
-+ OldKey -> |
|
| 500 |
-+ NextKey = httpd_util:to_lower( |
|
| 501 |
-+ hex(binary_to_list( |
|
| 502 |
-+ crypto:sha(Key)))), |
|
| 503 |
-+ ?DEBUG("Key/OldKey/NextKey: ~s/~s/~s",
|
|
| 504 |
-+ [Key, OldKey, NextKey]), |
|
| 505 |
-+ if |
|
| 506 |
-+ OldKey == NextKey -> |
|
| 507 |
-+ true; |
|
| 508 |
-+ true -> |
|
| 509 |
-+ ?DEBUG("wrong key: ~s",[Key]),
|
|
| 510 |
-+ false |
|
| 511 |
-+ end |
|
| 512 |
-+ end |
|
| 513 |
-+ end, |
|
| 514 |
-+ {_,TSec,TMSec} = now(),
|
|
| 515 |
-+ TNow = TSec*1000*1000 + TMSec, |
|
| 516 |
-+ LastPoll = if |
|
| 517 |
-+ Packet == "" -> |
|
| 518 |
-+ TNow; |
|
| 519 |
-+ true -> |
|
| 520 |
-+ 0 |
|
| 521 |
-+ end, |
|
| 522 |
-+ {MinPoll, _} = string:to_integer(?MIN_POLLING),
|
|
| 523 |
-+ if |
|
| 524 |
-+ (Packet == "") and |
|
| 525 |
-+ (TNow - StateData#state.last_poll < MinPoll*1000*1000) -> |
|
| 526 |
-+ Reply = {error, polling_too_frequently},
|
|
| 527 |
-+ {reply, Reply, StateName, StateData};
|
|
| 528 |
-+ KeyAllow -> |
|
| 529 |
-+ case RidAllow of |
|
| 530 |
-+ false -> |
|
| 531 |
-+ Reply = {error, not_exists},
|
|
| 532 |
-+ {reply, Reply, StateName, StateData};
|
|
| 533 |
-+ repeat -> |
|
| 534 |
-+ ?DEBUG("REPEATING ~p", [RID]),
|
|
| 535 |
-+ [Out | _XS] = [El#hbr.out || |
|
| 536 |
-+ El <- StateData#state.req_list, |
|
| 537 |
-+ El#hbr.rid == RID], |
|
| 538 |
-+ case Out of |
|
| 539 |
-+ [[] | OutPacket] -> |
|
| 540 |
-+ Reply = {repeat, OutPacket};
|
|
| 541 |
-+ _ -> |
|
| 542 |
-+ Reply = {repeat, Out}
|
|
| 543 |
-+ end, |
|
| 544 |
-+ {reply, Reply, StateName,
|
|
| 545 |
-+ StateData#state{input = "cancel", last_poll = LastPoll}};
|
|
| 546 |
-+ true -> |
|
| 547 |
-+ SaveKey = if |
|
| 548 |
-+ NewKey == "" -> |
|
| 549 |
-+ Key; |
|
| 550 |
-+ true -> |
|
| 551 |
-+ NewKey |
|
| 552 |
-+ end, |
|
| 553 |
-+ ?DEBUG(" -- SaveKey: ~s~n", [SaveKey]),
|
|
| 554 |
-+ |
|
| 555 |
-+ %% save request |
|
| 556 |
-+ ReqList = [#hbr{rid=RID,
|
|
| 557 |
-+ key=StateData#state.key, |
|
| 558 |
-+ in=StateData#state.input, |
|
| 559 |
-+ out=StateData#state.output |
|
| 560 |
-+ } | |
|
| 561 |
-+ [El || El <- StateData#state.req_list, |
|
| 562 |
-+ El#hbr.rid < RID, |
|
| 563 |
-+ El#hbr.rid > (RID - 1 - Hold)] |
|
| 564 |
-+ ], |
|
| 565 |
-+%% ?DEBUG("reqlist: ~p", [ReqList]),
|
|
| 566 |
-+ case StateData#state.waiting_input of |
|
| 567 |
-+ false -> |
|
| 568 |
-+ cancel_timer(StateData#state.timer), |
|
| 569 |
-+ Timer = erlang:start_timer( |
|
| 570 |
-+ ?MAX_INACTIVITY, self(), []), |
|
| 571 |
-+ Input = Packet ++ [StateData#state.input], |
|
| 572 |
-+ Reply = ok, |
|
| 573 |
-+ {reply, Reply, StateName,
|
|
| 574 |
-+ StateData#state{input = Input,
|
|
| 575 |
-+ rid = RID, |
|
| 576 |
-+ key = SaveKey, |
|
| 577 |
-+ ctime = TNow, |
|
| 578 |
-+ timer = Timer, |
|
| 579 |
-+ last_poll = LastPoll, |
|
| 580 |
-+ req_list = ReqList |
|
| 581 |
-+ }}; |
|
| 582 |
-+ {Receiver, _Tag} ->
|
|
| 583 |
-+ Receiver ! {tcp, {http_bind, self()},
|
|
| 584 |
-+ list_to_binary(Packet)}, |
|
| 585 |
-+ cancel_timer(StateData#state.timer), |
|
| 586 |
-+ Timer = erlang:start_timer( |
|
| 587 |
-+ ?MAX_INACTIVITY, self(), []), |
|
| 588 |
-+ Reply = ok, |
|
| 589 |
-+ {reply, Reply, StateName,
|
|
| 590 |
-+ StateData#state{waiting_input = false,
|
|
| 591 |
-+ last_receiver = Receiver, |
|
| 592 |
-+ input = "", |
|
| 593 |
-+ rid = RID, |
|
| 594 |
-+ key = SaveKey, |
|
| 595 |
-+ ctime = TNow, |
|
| 596 |
-+ timer = Timer, |
|
| 597 |
-+ last_poll = LastPoll, |
|
| 598 |
-+ req_list = ReqList |
|
| 599 |
-+ }} |
|
| 600 |
-+ end |
|
| 601 |
-+ end; |
|
| 602 |
-+ true -> |
|
| 603 |
-+ Reply = {error, bad_key},
|
|
| 604 |
-+ {reply, Reply, StateName, StateData}
|
|
| 605 |
-+ end; |
|
| 606 |
-+ |
|
| 607 |
-+handle_sync_event({http_get, RID, Wait, Hold}, _From, StateName, StateData) ->
|
|
| 608 |
-+ {_,TSec,TMSec} = now(),
|
|
| 609 |
-+ TNow = TSec*1000*1000 + TMSec, |
|
| 610 |
-+ cancel_timer(StateData#state.timer), |
|
| 611 |
-+ Timer = erlang:start_timer(?MAX_INACTIVITY, self(), []), |
|
| 612 |
-+ if |
|
| 613 |
-+ (Hold > 0) and |
|
| 614 |
-+ (StateData#state.output == "") and |
|
| 615 |
-+ ((TNow - StateData#state.ctime) < (Wait*1000*1000)) and |
|
| 616 |
-+ (StateData#state.rid == RID) and |
|
| 617 |
-+ (StateData#state.input /= "cancel") -> |
|
| 618 |
-+ Output = StateData#state.output, |
|
| 619 |
-+ ReqList = StateData#state.req_list, |
|
| 620 |
-+ Reply = {ok, keep_on_hold};
|
|
| 621 |
-+ (StateData#state.input == "cancel") -> |
|
| 622 |
-+ Output = StateData#state.output, |
|
| 623 |
-+ ReqList = StateData#state.req_list, |
|
| 624 |
-+ Reply = {ok, cancel};
|
|
| 625 |
-+ true -> |
|
| 626 |
-+ case StateData#state.output of |
|
| 627 |
-+ [[]| OutPacket] -> |
|
| 628 |
-+ Reply = {ok, OutPacket};
|
|
| 629 |
-+ _ -> |
|
| 630 |
-+ Reply = {ok, StateData#state.output}
|
|
| 631 |
-+ end, |
|
| 632 |
-+ %% save request |
|
| 633 |
-+ ReqList = [#hbr{rid=RID,
|
|
| 634 |
-+ key=StateData#state.key, |
|
| 635 |
-+ in=StateData#state.input, |
|
| 636 |
-+ out=StateData#state.output |
|
| 637 |
-+ } | |
|
| 638 |
-+ [El || El <- StateData#state.req_list, |
|
| 639 |
-+ El#hbr.rid /= RID ] |
|
| 640 |
-+ ], |
|
| 641 |
-+ Output = "" |
|
| 642 |
-+ end, |
|
| 643 |
-+ {reply, Reply, StateName, StateData#state{
|
|
| 644 |
-+ input = "", |
|
| 645 |
-+ output = Output, |
|
| 646 |
-+ timer = Timer, |
|
| 647 |
-+ req_list = ReqList}}; |
|
| 648 |
-+ |
|
| 649 |
-+handle_sync_event(_Event, _From, StateName, StateData) -> |
|
| 650 |
-+ Reply = ok, |
|
| 651 |
-+ {reply, Reply, StateName, StateData}.
|
|
| 652 |
-+ |
|
| 653 |
-+code_change(_OldVsn, StateName, StateData, _Extra) -> |
|
| 654 |
-+ {ok, StateName, StateData}.
|
|
| 655 |
-+ |
|
| 656 |
-+%%---------------------------------------------------------------------- |
|
| 657 |
-+%% Func: handle_info/3 |
|
| 658 |
-+%% Returns: {next_state, NextStateName, NextStateData} |
|
|
| 659 |
-+%% {next_state, NextStateName, NextStateData, Timeout} |
|
|
| 660 |
-+%% {stop, Reason, NewStateData}
|
|
| 661 |
-+%%---------------------------------------------------------------------- |
|
| 662 |
-+handle_info({timeout, Timer, _}, _StateName,
|
|
| 663 |
-+ #state{timer = Timer} = StateData) ->
|
|
| 664 |
-+ ?DEBUG("ding dong", []),
|
|
| 665 |
-+ {stop, normal, StateData};
|
|
| 666 |
-+ |
|
| 667 |
-+handle_info(_, StateName, StateData) -> |
|
| 668 |
-+ {next_state, StateName, StateData}.
|
|
| 669 |
-+ |
|
| 670 |
-+%%---------------------------------------------------------------------- |
|
| 671 |
-+%% Func: terminate/3 |
|
| 672 |
-+%% Purpose: Shutdown the fsm |
|
| 673 |
-+%% Returns: any |
|
| 674 |
-+%%---------------------------------------------------------------------- |
|
| 675 |
-+terminate(_Reason, _StateName, StateData) -> |
|
| 676 |
-+ ?DEBUG("terminate: deleting session ~s", [StateData#state.id]),
|
|
| 677 |
-+ mnesia:transaction( |
|
| 678 |
-+ fun() -> |
|
| 679 |
-+ mnesia:delete({http_bind, StateData#state.id})
|
|
| 680 |
-+ end), |
|
| 681 |
-+ case StateData#state.waiting_input of |
|
| 682 |
-+ false -> |
|
| 683 |
-+ case StateData#state.last_receiver of |
|
| 684 |
-+ undefined -> ok; |
|
| 685 |
-+ Receiver -> Receiver ! {tcp_closed, {http_bind, self()}}
|
|
| 686 |
-+ end; |
|
| 687 |
-+ {Receiver, _Tag} -> Receiver ! {tcp_closed, {http_bind, self()}}
|
|
| 688 |
-+ end, |
|
| 689 |
-+ ok. |
|
| 690 |
-+ |
|
| 691 |
-+%%%---------------------------------------------------------------------- |
|
| 692 |
-+%%% Internal functions |
|
| 693 |
-+%%%---------------------------------------------------------------------- |
|
| 694 |
-+ |
|
| 695 |
-+ |
|
| 696 |
-+http_put(ID, RID, Key, NewKey, Hold, Packet) -> |
|
| 697 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 698 |
-+ [] -> |
|
| 699 |
-+ {error, not_exists};
|
|
| 700 |
-+ [#http_bind{pid = FsmRef}] ->
|
|
| 701 |
-+ gen_fsm:sync_send_all_state_event( |
|
| 702 |
-+ FsmRef, {http_put, RID, Key, NewKey, Hold, Packet})
|
|
| 703 |
-+ end. |
|
| 704 |
-+ |
|
| 705 |
-+http_get(ID,RID) -> |
|
| 706 |
-+ case mnesia:dirty_read({http_bind, ID}) of
|
|
| 707 |
-+ [] -> |
|
| 708 |
-+ {error, not_exists};
|
|
| 709 |
-+ [#http_bind{pid = FsmRef, wait = Wait, hold = Hold}] ->
|
|
| 710 |
-+ gen_fsm:sync_send_all_state_event(FsmRef, |
|
| 711 |
-+ {http_get, RID, Wait, Hold})
|
|
| 712 |
-+ end. |
|
| 713 |
-+ |
|
| 714 |
-+ |
|
| 715 |
-+parse_request(Data) -> |
|
| 716 |
-+ ?DEBUG("--- incoming data --- ~n~s~n --- END --- ",
|
|
| 717 |
-+ [Data]), |
|
| 718 |
-+ case xml_stream:parse_element(Data) of |
|
| 719 |
-+ El when element(1, El) == xmlelement -> |
|
| 720 |
-+ {xmlelement, Name, Attrs, Els} = El,
|
|
| 721 |
-+ ID = xml:get_attr_s("sid",Attrs),
|
|
| 722 |
-+ {RID,_X} = string:to_integer(xml:get_attr_s("rid",Attrs)),
|
|
| 723 |
-+ Key = xml:get_attr_s("key",Attrs),
|
|
| 724 |
-+ NewKey = xml:get_attr_s("newkey",Attrs),
|
|
| 725 |
-+ Xmlns = xml:get_attr_s("xmlns",Attrs),
|
|
| 726 |
-+ Packet = [xml:element_to_string( |
|
| 727 |
-+ xml:remove_tag_attr("xmlns",E)) ||
|
|
| 728 |
-+ E <- Els], |
|
| 729 |
-+ if |
|
| 730 |
-+ Name /= "body" -> |
|
| 731 |
-+ {error, bad_request};
|
|
| 732 |
-+ Xmlns /= "http://jabber.org/protocol/httpbind" -> |
|
| 733 |
-+ {error, bad_request};
|
|
| 734 |
-+ true -> |
|
| 735 |
-+ {ok, ID, RID, Key, NewKey, Attrs, Packet}
|
|
| 736 |
-+ end; |
|
| 737 |
-+ {error, _Reason} ->
|
|
| 738 |
-+ {error, bad_request}
|
|
| 739 |
-+ end. |
|
| 740 |
-+ |
|
| 741 |
-+cancel_timer(Timer) -> |
|
| 742 |
-+ erlang:cancel_timer(Timer), |
|
| 743 |
-+ receive |
|
| 744 |
-+ {timeout, Timer, _} ->
|
|
| 745 |
-+ ok |
|
| 746 |
-+ after 0 -> |
|
| 747 |
-+ ok |
|
| 748 |
-+ end. |
|
| 749 |
-+ |
|
| 750 |
-+hex(Bin) when binary(Bin) -> hex(binary_to_list(Bin)); |
|
| 751 |
-+hex([]) -> ""; |
|
| 752 |
-+hex([H|T]) -> |
|
| 753 |
-+ [A,B] = if |
|
| 754 |
-+ H == 0 -> "00"; |
|
| 755 |
-+ H < 16 -> [$0,element(H,{$1,$2,$3,$4,$5,$6,$7,$8,$9,$a,$b,$c,$d,$e,$f})];
|
|
| 756 |
-+ true -> erlang:integer_to_list(H,16) |
|
| 757 |
-+ end, |
|
| 758 |
-+ [A,B|hex(T)]. |
|
| 759 |
-+ |
|
| 760 |
-+elements_to_string([]) -> |
|
| 761 |
-+ []; |
|
| 762 |
-+elements_to_string([El | Els]) -> |
|
| 763 |
-+ xml:element_to_string(El) ++ elements_to_string(Els). |
|
| 764 |
-Index: src/web/ejabberd_web.erl |
|
| 765 |
-=================================================================== |
|
| 766 |
---- src/web/ejabberd_web.erl (Revision 565) |
|
| 767 |
-+++ src/web/ejabberd_web.erl (Arbeitskopie) |
|
| 768 |
-@@ -49,7 +49,7 @@ |
|
| 769 |
- {"value", Value}])).
|
|
| 770 |
- |
|
| 771 |
- |
|
| 772 |
--process_get({_, true},
|
|
| 773 |
-+process_get({_, _, true},
|
|
| 774 |
- #request{auth = Auth,
|
|
| 775 |
- path = ["admin", "server", SHost | RPath], |
|
| 776 |
- q = Query, |
|
| 777 |
-@@ -94,7 +94,7 @@ |
|
| 778 |
- {404, [], make_xhtml([?XC("h1", "Not found")])}
|
|
| 779 |
- end; |
|
| 780 |
- |
|
| 781 |
--process_get({_, true},
|
|
| 782 |
-+process_get({_, _, true},
|
|
| 783 |
- #request{auth = Auth,
|
|
| 784 |
- path = ["admin" | RPath], |
|
| 785 |
- q = Query, |
|
| 786 |
-@@ -133,12 +133,19 @@ |
|
| 787 |
- [{xmlcdata, "401 Unauthorized"}]}])}
|
|
| 788 |
- end; |
|
| 789 |
- |
|
| 790 |
--process_get({true, _},
|
|
| 791 |
-+process_get({true, _, _},
|
|
| 792 |
- #request{path = ["http-poll" | RPath],
|
|
| 793 |
- q = _Query, |
|
| 794 |
- lang = _Lang} = Request) -> |
|
| 795 |
- ejabberd_http_poll:process_request(Request#request{path = RPath});
|
|
| 796 |
- |
|
| 797 |
-+process_get({_, true, _},
|
|
| 798 |
-+ #request{us = _US,
|
|
| 799 |
-+ path = ["http-bind" | RPath], |
|
| 800 |
-+ q = _Query, |
|
| 801 |
-+ lang = _Lang} = Request) -> |
|
| 802 |
-+ ejabberd_http_bind:process_request(Request#request{path = RPath});
|
|
| 803 |
-+ |
|
| 804 |
- process_get(_, _Request) -> |
|
| 805 |
- {404, [], make_xhtml([?XC("h1", "Not found")])}.
|
|
| 806 |
- |
|
| 807 |
-Index: src/web/ejabberd_http.erl |
|
| 808 |
-=================================================================== |
|
| 809 |
---- src/web/ejabberd_http.erl (Revision 565) |
|
| 810 |
-+++ src/web/ejabberd_http.erl (Arbeitskopie) |
|
| 811 |
-@@ -30,6 +30,7 @@ |
|
| 812 |
- request_keepalive, |
|
| 813 |
- request_content_length, |
|
| 814 |
- request_lang = "en", |
|
| 815 |
-+ use_http_bind = false, |
|
| 816 |
- use_http_poll = false, |
|
| 817 |
- use_web_admin = false, |
|
| 818 |
- end_of_request = false, |
|
| 819 |
-@@ -70,15 +71,17 @@ |
|
| 820 |
- _ -> |
|
| 821 |
- ok |
|
| 822 |
- end, |
|
| 823 |
-+ UseHTTPBind = lists:member(http_bind, Opts), |
|
| 824 |
- UseHTTPPoll = lists:member(http_poll, Opts), |
|
| 825 |
- UseWebAdmin = lists:member(web_admin, Opts), |
|
| 826 |
-- ?DEBUG("S: ~p~n", [{UseHTTPPoll, UseWebAdmin}]),
|
|
| 827 |
-+ ?DEBUG("S: ~p~n", [{UseHTTPPoll, UseHTTPBind, UseWebAdmin}]),
|
|
| 828 |
- ?INFO_MSG("started: ~p", [{SockMod1, Socket1}]),
|
|
| 829 |
- {ok, proc_lib:spawn_link(ejabberd_http,
|
|
| 830 |
- receive_headers, |
|
| 831 |
- [#state{sockmod = SockMod1,
|
|
| 832 |
- socket = Socket1, |
|
| 833 |
- use_http_poll = UseHTTPPoll, |
|
| 834 |
-+ use_http_bind = UseHTTPBind, |
|
| 835 |
- use_web_admin = UseWebAdmin}])}. |
|
| 836 |
- |
|
| 837 |
- |
|
| 838 |
-@@ -185,6 +188,7 @@ |
|
| 839 |
- #state{sockmod = SockMod,
|
|
| 840 |
- socket = Socket, |
|
| 841 |
- use_http_poll = State#state.use_http_poll, |
|
| 842 |
-+ use_http_bind = State#state.use_http_bind, |
|
| 843 |
- use_web_admin = State#state.use_web_admin}; |
|
| 844 |
- _ -> |
|
| 845 |
- #state{end_of_request = true}
|
|
| 846 |
-@@ -200,6 +204,7 @@ |
|
| 847 |
- request_auth = Auth, |
|
| 848 |
- request_lang = Lang, |
|
| 849 |
- use_http_poll = UseHTTPPoll, |
|
| 850 |
-+ use_http_bind = UseHTTPBind, |
|
| 851 |
- use_web_admin = UseWebAdmin} = State) -> |
|
| 852 |
- case (catch url_decode_q_split(Path)) of |
|
| 853 |
- {'EXIT', _} ->
|
|
| 854 |
-@@ -217,7 +222,7 @@ |
|
| 855 |
- q = LQuery, |
|
| 856 |
- auth = Auth, |
|
| 857 |
- lang = Lang}, |
|
| 858 |
-- case ejabberd_web:process_get({UseHTTPPoll, UseWebAdmin},
|
|
| 859 |
-+ case ejabberd_web:process_get({UseHTTPPoll, UseHTTPBind, UseWebAdmin},
|
|
| 860 |
- Request) of |
|
| 861 |
- El when element(1, El) == xmlelement -> |
|
| 862 |
- make_xhtml_output(State, 200, [], El); |
|
| 863 |
-@@ -240,6 +245,7 @@ |
|
| 864 |
- sockmod = SockMod, |
|
| 865 |
- socket = Socket, |
|
| 866 |
- use_http_poll = UseHTTPPoll, |
|
| 867 |
-+ use_http_bind = UseHTTPBind, |
|
| 868 |
- use_web_admin = UseWebAdmin} = State) |
|
| 869 |
- when is_integer(Len) -> |
|
| 870 |
- case SockMod of |
|
| 871 |
-@@ -267,7 +273,7 @@ |
|
| 872 |
- auth = Auth, |
|
| 873 |
- data = Data, |
|
| 874 |
- lang = Lang}, |
|
| 875 |
-- case ejabberd_web:process_get({UseHTTPPoll, UseWebAdmin},
|
|
| 876 |
-+ case ejabberd_web:process_get({UseHTTPPoll, UseHTTPBind, UseWebAdmin},
|
|
| 877 |
- Request) of |
|
| 878 |
- El when element(1, El) == xmlelement -> |
|
| 879 |
- make_xhtml_output(State, 200, [], El); |
|
| 880 |
-Index: src/xml.erl |
|
| 881 |
-=================================================================== |
|
| 882 |
---- src/xml.erl (Revision 565) |
|
| 883 |
-+++ src/xml.erl (Arbeitskopie) |
|
| 884 |
-@@ -18,6 +18,7 @@ |
|
| 885 |
- get_tag_attr/2, get_tag_attr_s/2, |
|
| 886 |
- get_subtag/2, |
|
| 887 |
- get_path_s/2, |
|
| 888 |
-+ remove_tag_attr/2, |
|
| 889 |
- replace_tag_attr/3]). |
|
| 890 |
- |
|
| 891 |
- %element_to_string(El) -> |
|
| 892 |
-@@ -224,6 +225,14 @@ |
|
| 893 |
- get_path_s(El, [cdata]) -> |
|
| 894 |
- get_tag_cdata(El). |
|
| 895 |
- |
|
| 896 |
-+remove_tag_attr(Attr, El) -> |
|
| 897 |
-+ case El of |
|
| 898 |
-+ {xmlelement, Name, Attrs, Els} ->
|
|
| 899 |
-+ Attrs1 = lists:keydelete(Attr, 1, Attrs), |
|
| 900 |
-+ {xmlelement, Name, Attrs1, Els};
|
|
| 901 |
-+ _ -> |
|
| 902 |
-+ El |
|
| 903 |
-+ end. |
|
| 904 |
- |
|
| 905 |
- replace_tag_attr(Attr, Value, {xmlelement, Name, Attrs, Els}) ->
|
|
| 906 |
- Attrs1 = lists:keydelete(Attr, 1, Attrs), |
|
| 907 |
- |
|
| 908 |
-Index: src/ejabberd_sup.erl |
|
| 909 |
-=================================================================== |
|
| 910 |
---- src/ejabberd_sup.erl (Revision 565) |
|
| 911 |
-+++ src/ejabberd_sup.erl (Arbeitskopie) |
|
| 912 |
-@@ -123,6 +123,14 @@ |
|
| 913 |
- infinity, |
|
| 914 |
- supervisor, |
|
| 915 |
- [ejabberd_tmp_sup]}, |
|
| 916 |
-+ HTTPBindSupervisor = |
|
| 917 |
-+ {ejabberd_http_bind_sup,
|
|
| 918 |
-+ {ejabberd_tmp_sup, start_link,
|
|
| 919 |
-+ [ejabberd_http_bind_sup, ejabberd_http_bind]}, |
|
| 920 |
-+ permanent, |
|
| 921 |
-+ infinity, |
|
| 922 |
-+ supervisor, |
|
| 923 |
-+ [ejabberd_tmp_sup]}, |
|
| 924 |
- IQSupervisor = |
|
| 925 |
- {ejabberd_iq_sup,
|
|
| 926 |
- {ejabberd_tmp_sup, start_link,
|
|
| 927 |
-@@ -145,6 +153,7 @@ |
|
| 928 |
- ServiceSupervisor, |
|
| 929 |
- HTTPSupervisor, |
|
| 930 |
- HTTPPollSupervisor, |
|
| 931 |
-+ HTTPBindSupervisor, |
|
| 932 |
- IQSupervisor, |
|
| 933 |
- Listener]}}. |
|
| 934 |
- |
| ... | ... |
@@ -1,11 +0,0 @@ |
| 1 |
---- mod_irc/mod_irc.erl.orig 2006-11-19 14:40:02.463429250 +0100 |
|
| 2 |
-+++ mod_irc/mod_irc.erl 2006-11-19 14:40:25.888893250 +0100 |
|
| 3 |
-@@ -27,7 +27,7 @@ |
|
| 4 |
- -include("ejabberd.hrl").
|
|
| 5 |
- -include("jlib.hrl").
|
|
| 6 |
- |
|
| 7 |
---define(DEFAULT_IRC_ENCODING, "koi8-r"). |
|
| 8 |
-+-define(DEFAULT_IRC_ENCODING, "utf-8"). |
|
| 9 |
- |
|
| 10 |
- -record(irc_connection, {jid_server_host, pid}).
|
|
| 11 |
- -record(irc_custom, {us_host, data}).
|
| ... | ... |
@@ -1,12 +0,0 @@ |
| 1 |
-diff -Naur ejabberd-1.1.1.orig/src/odbc/ejabberd_odbc.erl ejabberd-1.1.1/src/odbc/ejabberd_odbc.erl |
|
| 2 |
---- ejabberd-1.1.1.orig/src/odbc/ejabberd_odbc.erl 2006-05-07 19:05:12.549917750 +0400 |
|
| 3 |
-+++ ejabberd-1.1.1/src/odbc/ejabberd_odbc.erl 2006-05-07 19:06:11.337591750 +0400 |
|
| 4 |
-@@ -272,7 +272,6 @@ |
|
| 5 |
- case mysql_conn:start(Server, ?MYSQL_PORT, Username, Password, DB, NoLogFun) of |
|
| 6 |
- {ok, Ref} ->
|
|
| 7 |
- erlang:monitor(process, Ref), |
|
| 8 |
-+ catch mysql_conn:fetch(Ref, "SET NAMES 'utf8';", self()), |
|
| 9 |
- {ok, #state{db_ref = Ref, db_type = mysql}};
|
|
| 10 |
- {error, Reason} ->
|
|
| 11 |
- ?ERROR_MSG("MySQL connection failed: ~p~n", [Reason]),
|
|
| 12 |
- |
| ... | ... |
@@ -1,406 +0,0 @@ |
| 1 |
-* modified files |
|
| 2 |
- |
|
| 3 |
- |
|
| 4 |
---- jlib.hrl |
|
| 5 |
-+++ jlib.hrl |
|
| 6 |
-@@ -34,6 +34,7 @@ |
|
| 7 |
- -define(NS_PUBSUB_OWNER, "http://jabber.org/protocol/pubsub#owner"). |
|
| 8 |
- -define(NS_PUBSUB_NMI, "http://jabber.org/protocol/pubsub#node-meta-info"). |
|
| 9 |
- -define(NS_COMMANDS, "http://jabber.org/protocol/commands"). |
|
| 10 |
-+-define(NS_BYTESTREAMS, "http://jabber.org/protocol/bytestreams"). |
|
| 11 |
- |
|
| 12 |
- -define(NS_EJABBERD_CONFIG, "ejabberd:config"). |
|
| 13 |
- |
|
| 14 |
- |
|
| 15 |
- |
|
| 16 |
- |
|
| 17 |
-* added files |
|
| 18 |
- |
|
| 19 |
---- /dev/null |
|
| 20 |
-+++ mod_proxy65.erl |
|
| 21 |
-@@ -0,0 +1,189 @@ |
|
| 22 |
-+%%%---------------------------------------------------------------------- |
|
| 23 |
-+%%% File : mod_proxy65.erl |
|
| 24 |
-+%%% Author : Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 25 |
-+%%% Purpose : Handle Jabber communications for JEP-0065 proxy |
|
| 26 |
-+%%% Created : 27 Dec 2005 by Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 27 |
-+%%% Id : $Id: ejabberd_c2s.erl 440 2005-11-22 18:00:56Z alexey $ |
|
| 28 |
-+%%%---------------------------------------------------------------------- |
|
| 29 |
-+ |
|
| 30 |
-+-module(mod_proxy65). |
|
| 31 |
-+-author('henoch@dtek.chalmers.se').
|
|
| 32 |
-+-vsn('$Revision$ ').
|
|
| 33 |
-+ |
|
| 34 |
-+-behaviour(gen_mod). |
|
| 35 |
-+ |
|
| 36 |
-+-export([start/2, |
|
| 37 |
-+ init/1, |
|
| 38 |
-+ stop/1]). |
|
| 39 |
-+ |
|
| 40 |
-+-include("ejabberd.hrl").
|
|
| 41 |
-+-include("jlib.hrl").
|
|
| 42 |
-+ |
|
| 43 |
-+-record(proxy65_connection, {cookie, firstpid = none, secondpid = none}).
|
|
| 44 |
-+ |
|
| 45 |
-+-record(proxy65_options, {host, access, streamhosts}).
|
|
| 46 |
-+ |
|
| 47 |
-+-define(PROCNAME, ejabberd_mod_proxy65). |
|
| 48 |
-+ |
|
| 49 |
-+start(Host, Opts) -> |
|
| 50 |
-+ mnesia:create_table(proxy65_connection, |
|
| 51 |
-+ [{ram_copies, [node()]},
|
|
| 52 |
-+ {attributes, record_info(fields, proxy65_connection)}]),
|
|
| 53 |
-+ MyHost = gen_mod:get_opt(host, Opts, "proxy." ++ Host), |
|
| 54 |
-+ Access = gen_mod:get_opt(access, Opts, all), |
|
| 55 |
-+ Streamhosts = gen_mod:get_opt(streamhosts, Opts, [{Host, 7777}]),
|
|
| 56 |
-+ |
|
| 57 |
-+ register(gen_mod:get_module_proc(Host, ?PROCNAME), |
|
| 58 |
-+ spawn(?MODULE, init, [#proxy65_options{host = MyHost, access = Access,
|
|
| 59 |
-+ streamhosts = Streamhosts}])). |
|
| 60 |
-+ |
|
| 61 |
-+ |
|
| 62 |
-+stop(Host) -> |
|
| 63 |
-+ Proc = gen_mod:get_module_proc(Host, ?PROCNAME), |
|
| 64 |
-+ Proc ! stop, |
|
| 65 |
-+ {wait, Proc}.
|
|
| 66 |
-+ |
|
| 67 |
-+init(#proxy65_options{host = Host} = Opts) ->
|
|
| 68 |
-+ ejabberd_router:register_route(Host), |
|
| 69 |
-+ loop(Opts). |
|
| 70 |
-+ |
|
| 71 |
-+loop(#proxy65_options{host = Host} = Opts) ->
|
|
| 72 |
-+ receive |
|
| 73 |
-+ {route, From, To, Packet} ->
|
|
| 74 |
-+ case catch do_route(Opts, From, To, Packet) of |
|
| 75 |
-+ {'EXIT', Reason} ->
|
|
| 76 |
-+ ?ERROR_MSG("~p", [Reason]);
|
|
| 77 |
-+ _ -> |
|
| 78 |
-+ ok |
|
| 79 |
-+ end, |
|
| 80 |
-+ loop(Opts); |
|
| 81 |
-+ stop -> |
|
| 82 |
-+ ejabberd_router:unregister_route(Host), |
|
| 83 |
-+ ok; |
|
| 84 |
-+ _ -> |
|
| 85 |
-+ loop(Opts) |
|
| 86 |
-+ end. |
|
| 87 |
-+ |
|
| 88 |
-+do_route(#proxy65_options{host = Host, access = Access} = Opts,
|
|
| 89 |
-+ From, To, Packet) -> |
|
| 90 |
-+ case acl:match_rule(Host, Access, From) of |
|
| 91 |
-+ allow -> |
|
| 92 |
-+ do_route1(Opts, From, To, Packet); |
|
| 93 |
-+ _ -> |
|
| 94 |
-+ {xmlelement, _Name, Attrs, _Els} = Packet,
|
|
| 95 |
-+ Lang = xml:get_attr_s("xml:lang", Attrs),
|
|
| 96 |
-+ ErrText = "Access denied by service policy", |
|
| 97 |
-+ Err = jlib:make_error_reply(Packet, |
|
| 98 |
-+ ?ERRT_FORBIDDEN(Lang, ErrText)), |
|
| 99 |
-+ ejabberd_router:route(To, From, Err) |
|
| 100 |
-+ end. |
|
| 101 |
-+ |
|
| 102 |
-+do_route1(#proxy65_options{host = Host, streamhosts = Streamhosts}, From, To, Packet) ->
|
|
| 103 |
-+ {xmlelement, Name, _Attrs, _Els} = Packet,
|
|
| 104 |
-+ case Name of |
|
| 105 |
-+ "iq" -> |
|
| 106 |
-+ case jlib:iq_query_info(Packet) of |
|
| 107 |
-+ #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
|
|
| 108 |
-+ lang = Lang, sub_el = SubEl} = IQ -> |
|
| 109 |
-+ Node = xml:get_tag_attr_s("node", SubEl),
|
|
| 110 |
-+ if Node == [] -> |
|
| 111 |
-+ Res = IQ#iq{type = result,
|
|
| 112 |
-+ sub_el = [{xmlelement, "query",
|
|
| 113 |
-+ [{"xmlns", XMLNS}],
|
|
| 114 |
-+ [{xmlelement, "identity",
|
|
| 115 |
-+ [{"category", "proxy"},
|
|
| 116 |
-+ {"type", "bytestreams"},
|
|
| 117 |
-+ {"name", translate:translate(Lang, "SOCKS5 bytestreams proxy")}],
|
|
| 118 |
-+ []}, |
|
| 119 |
-+ {xmlelement, "feature",
|
|
| 120 |
-+ [{"var", ?NS_BYTESTREAMS}], []}]}]};
|
|
| 121 |
-+ true -> |
|
| 122 |
-+ Res = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND) |
|
| 123 |
-+ end; |
|
| 124 |
-+ #iq{type = get, xmlns = ?NS_DISCO_ITEMS = XMLNS} = IQ ->
|
|
| 125 |
-+ Res = IQ#iq{type = result,
|
|
| 126 |
-+ sub_el = [{xmlelement, "query",
|
|
| 127 |
-+ [{"xmlns", XMLNS}], []}]};
|
|
| 128 |
-+ #iq{type = get, xmlns = ?NS_VERSION} = IQ ->
|
|
| 129 |
-+ OSType = case os:type() of |
|
| 130 |
-+ {Osfamily, Osname} ->
|
|
| 131 |
-+ atom_to_list(Osfamily) ++ "/" ++ |
|
| 132 |
-+ atom_to_list(Osname); |
|
| 133 |
-+ Osfamily -> |
|
| 134 |
-+ atom_to_list(Osfamily) |
|
| 135 |
-+ end, |
|
| 136 |
-+ OSVersion = case os:version() of |
|
| 137 |
-+ {Major, Minor, Release} ->
|
|
| 138 |
-+ lists:flatten( |
|
| 139 |
-+ io_lib:format("~w.~w.~w",
|
|
| 140 |
-+ [Major, Minor, Release])); |
|
| 141 |
-+ VersionString -> |
|
| 142 |
-+ VersionString |
|
| 143 |
-+ end, |
|
| 144 |
-+ OS = OSType ++ " " ++ OSVersion, |
|
| 145 |
-+ Res = IQ#iq{type = result,
|
|
| 146 |
-+ sub_el = [{xmlelement, "query",
|
|
| 147 |
-+ [{"xmlns", ?NS_VERSION}],
|
|
| 148 |
-+ [{xmlelement, "name", [],
|
|
| 149 |
-+ [{xmlcdata, "ejabberd mod_proxy65 (unofficial)"}]},
|
|
| 150 |
-+ {xmlelement, "version", [],
|
|
| 151 |
-+ [{xmlcdata, "0.1"}]},
|
|
| 152 |
-+ {xmlelement, "os", [],
|
|
| 153 |
-+ [{xmlcdata, OS}]}
|
|
| 154 |
-+ ]}]}; |
|
| 155 |
-+ #iq{type = get, xmlns = ?NS_BYTESTREAMS = XMLNS} = IQ ->
|
|
| 156 |
-+ Res = IQ#iq{type = result,
|
|
| 157 |
-+ sub_el = [{xmlelement, "query",
|
|
| 158 |
-+ [{"xmlns", XMLNS}],
|
|
| 159 |
-+ return_streamhosts(Host, Streamhosts)}]}; |
|
| 160 |
-+ #iq{type = set, xmlns = ?NS_BYTESTREAMS} = IQ ->
|
|
| 161 |
-+ Res = activate(Packet, From, To, IQ); |
|
| 162 |
-+ _ -> |
|
| 163 |
-+ Res = jlib:make_error_reply(Packet, ?ERR_FEATURE_NOT_IMPLEMENTED) |
|
| 164 |
-+ end, |
|
| 165 |
-+ case Res of |
|
| 166 |
-+ #iq{} ->
|
|
| 167 |
-+ ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); |
|
| 168 |
-+ _ -> |
|
| 169 |
-+ ejabberd_router:route(To, From, Res) |
|
| 170 |
-+ end; |
|
| 171 |
-+ _ -> |
|
| 172 |
-+ ejabberd_router:route(To, From, jlib:make_error_reply(Packet, ?ERR_FEATURE_NOT_IMPLEMENTED)) |
|
| 173 |
-+ end. |
|
| 174 |
-+ |
|
| 175 |
-+return_streamhosts(_JID, []) -> |
|
| 176 |
-+ []; |
|
| 177 |
-+return_streamhosts(JID, [{Host, Port} | Streamhosts]) ->
|
|
| 178 |
-+ %% This is not tail-recursive, but it doesn't matter. |
|
| 179 |
-+ [{xmlelement, "streamhost",
|
|
| 180 |
-+ [{"jid", JID},
|
|
| 181 |
-+ {"host", Host},
|
|
| 182 |
-+ {"port", integer_to_list(Port)}],
|
|
| 183 |
-+ []} | return_streamhosts(JID, Streamhosts)]. |
|
| 184 |
-+ |
|
| 185 |
-+activate(Packet, From, _To, #iq{sub_el = SubEl} = IQ) ->
|
|
| 186 |
-+ case SubEl of |
|
| 187 |
-+ {xmlelement, "query", Attrs, _SubEls} ->
|
|
| 188 |
-+ Sid = xml:get_attr_s("sid", Attrs),
|
|
| 189 |
-+ ActivateTag = xml:get_subtag(SubEl, "activate"), |
|
| 190 |
-+ if ActivateTag /= false -> |
|
| 191 |
-+ TargetJID = jlib:string_to_jid(xml:get_tag_cdata(ActivateTag)); |
|
| 192 |
-+ true -> |
|
| 193 |
-+ TargetJID = false |
|
| 194 |
-+ end, |
|
| 195 |
-+ |
|
| 196 |
-+ if Sid /= [], TargetJID /= false, TargetJID /= error -> |
|
| 197 |
-+ case proxy65_listener:activate(From, TargetJID, Sid) of |
|
| 198 |
-+ ok -> |
|
| 199 |
-+ ?INFO_MSG("Activated connection between ~s and ~s",
|
|
| 200 |
-+ [jlib:jid_to_string(From), TargetJID]), |
|
| 201 |
-+ IQ#iq{type = result, sub_el = []};
|
|
| 202 |
-+ _ -> |
|
| 203 |
-+ jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR) |
|
| 204 |
-+ end; |
|
| 205 |
-+ true -> |
|
| 206 |
-+ jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST) |
|
| 207 |
-+ end; |
|
| 208 |
-+ _ -> |
|
| 209 |
-+ jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST) |
|
| 210 |
-+ end. |
|
| 211 |
---- /dev/null |
|
| 212 |
-+++ proxy65_listener.erl |
|
| 213 |
-@@ -0,0 +1,192 @@ |
|
| 214 |
-+%%%---------------------------------------------------------------------- |
|
| 215 |
-+%%% File : proxy65_listener.erl |
|
| 216 |
-+%%% Author : Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 217 |
-+%%% Purpose : Handle SOCKS5 connections for JEP-0065 proxy |
|
| 218 |
-+%%% Created : 27 Dec 2005 by Magnus Henoch <henoch@dtek.chalmers.se> |
|
| 219 |
-+%%% Id : $Id: ejabberd_c2s.erl 440 2005-11-22 18:00:56Z alexey $ |
|
| 220 |
-+%%%---------------------------------------------------------------------- |
|
| 221 |
-+ |
|
| 222 |
-+-module(proxy65_listener). |
|
| 223 |
-+-author('henoch@dtek.chalmers.se').
|
|
| 224 |
-+-vsn('$Revision$ ').
|
|
| 225 |
-+ |
|
| 226 |
-+-export([start/2, handle_connection/2, activate/3]). |
|
| 227 |
-+ |
|
| 228 |
-+-include("ejabberd.hrl").
|
|
| 229 |
-+-include("jlib.hrl").
|
|
| 230 |
-+ |
|
| 231 |
-+-record(proxy65_connection, {cookie, firstpid = none, secondpid = none}).
|
|
| 232 |
-+ |
|
| 233 |
-+start({SockMod, Socket}, Opts) ->
|
|
| 234 |
-+ {ok, proc_lib:spawn(?MODULE, handle_connection, [{SockMod, Socket}, Opts])}.
|
|
| 235 |
-+ |
|
| 236 |
-+read_bytes(_SockOpts, 0, Data) -> |
|
| 237 |
-+ lists:flatten(Data); |
|
| 238 |
-+read_bytes({SockMod, Socket} = SockOpts, N, Data) ->
|
|
| 239 |
-+ Timeout = 1000, |
|
| 240 |
-+ case SockMod:recv(Socket, N, Timeout) of |
|
| 241 |
-+ {error, closed} ->
|
|
| 242 |
-+ %% On closed connection, return everything we have, |
|
| 243 |
-+ %% but not if we have nothing. |
|
| 244 |
-+ if Data == [] -> |
|
| 245 |
-+ erlang:error(closed); |
|
| 246 |
-+ true -> |
|
| 247 |
-+ lists:flatten(Data) |
|
| 248 |
-+ end; |
|
| 249 |
-+ {ok, MoreData} ->
|
|
| 250 |
-+ ?DEBUG("read ~p", [MoreData]),
|
|
| 251 |
-+ DataList = binary_to_list(MoreData), |
|
| 252 |
-+ read_bytes(SockOpts, N - length(DataList), [Data, DataList]) |
|
| 253 |
-+ end. |
|
| 254 |
-+ |
|
| 255 |
-+handle_connection({SockMod, Socket}, Opts) ->
|
|
| 256 |
-+ ?DEBUG("in handle_connection", []),
|
|
| 257 |
-+ case catch handle_auth({SockMod, Socket}, Opts) of
|
|
| 258 |
-+ {'EXIT', Reason} ->
|
|
| 259 |
-+ ?ERROR_MSG("~p abnormal termination:~n\t~p~n",
|
|
| 260 |
-+ [?MODULE, Reason]), |
|
| 261 |
-+ SockMod:close(Socket); |
|
| 262 |
-+ _ -> |
|
| 263 |
-+ ok |
|
| 264 |
-+ end. |
|
| 265 |
-+ |
|
| 266 |
-+handle_auth({SockMod, Socket} = SockOpts, Opts) ->
|
|
| 267 |
-+ ?DEBUG("in handle_auth", []),
|
|
| 268 |
-+ %% SOCKS protocol stuff... |
|
| 269 |
-+ [5, NAuthMethods] = read_bytes(SockOpts, 2, []), |
|
| 270 |
-+ AuthMethods = read_bytes(SockOpts, NAuthMethods, []), |
|
| 271 |
-+ SupportsNoAuth = lists:member(0, AuthMethods), |
|
| 272 |
-+ |
|
| 273 |
-+ %% Must support no authentication, otherwise crash |
|
| 274 |
-+ true = SupportsNoAuth, |
|
| 275 |
-+ |
|
| 276 |
-+ SockMod:send(Socket, [5, 0]), |
|
| 277 |
-+ |
|
| 278 |
-+ %% And done. |
|
| 279 |
-+ handle_connect(SockOpts, Opts). |
|
| 280 |
-+ |
|
| 281 |
-+handle_connect({SockMod, Socket} = SockOpts, Opts) ->
|
|
| 282 |
-+ ?DEBUG("in handle_connect", []),
|
|
| 283 |
-+ %% Expect a CONNECT command and nothing else |
|
| 284 |
-+ [5, 1, _, 3, AddressLength] = read_bytes(SockOpts, 5, []), |
|
| 285 |
-+ Cookie = read_bytes(SockOpts, AddressLength, []), |
|
| 286 |
-+ [0, 0] = read_bytes(SockOpts, 2, []), |
|
| 287 |
-+ |
|
| 288 |
-+ %% Make sure no more than two connections claim the same cookie. |
|
| 289 |
-+ F = fun() -> |
|
| 290 |
-+ case mnesia:read({proxy65_connection, Cookie}) of
|
|
| 291 |
-+ [] -> |
|
| 292 |
-+ mnesia:write(#proxy65_connection{cookie = Cookie,
|
|
| 293 |
-+ firstpid = self()}), |
|
| 294 |
-+ ok; |
|
| 295 |
-+ [#proxy65_connection{secondpid = none} = C] ->
|
|
| 296 |
-+ mnesia:write(C#proxy65_connection{secondpid = self()}),
|
|
| 297 |
-+ ok |
|
| 298 |
-+ end |
|
| 299 |
-+ end, |
|
| 300 |
-+ |
|
| 301 |
-+ case mnesia:transaction(F) of |
|
| 302 |
-+ {atomic, ok} ->
|
|
| 303 |
-+ SockMod:send(Socket, [5, 0, 0, 3, AddressLength, Cookie, 0, 0]), |
|
| 304 |
-+ wait_for_activation(SockOpts, Opts); |
|
| 305 |
-+ Error -> |
|
| 306 |
-+ %% conflict. send "general SOCKS server failure". |
|
| 307 |
-+ SockMod:send(Socket, [5, 1, 0, 3, AddressLength, Cookie, 0, 0]), |
|
| 308 |
-+ erlang:error({badconnect, Error})
|
|
| 309 |
-+ end. |
|
| 310 |
-+ |
|
| 311 |
-+wait_for_activation(SockOpts, Opts) -> |
|
| 312 |
-+ ?DEBUG("in wait_for_activation", []),
|
|
| 313 |
-+ receive |
|
| 314 |
-+ {get_socket, ReplyTo} ->
|
|
| 315 |
-+ ReplyTo ! SockOpts, |
|
| 316 |
-+ wait_for_activation(SockOpts, Opts); |
|
| 317 |
-+ {activate, TargetSocket, Initiator, Target} ->
|
|
| 318 |
-+ ?DEBUG("activated", []),
|
|
| 319 |
-+ |
|
| 320 |
-+ %% We have no way of knowing which connection belongs to |
|
| 321 |
-+ %% which participant, so give both the maximum traffic |
|
| 322 |
-+ %% allowed to either. |
|
| 323 |
-+ Shapers = case lists:keysearch(shaper, 1, Opts) of |
|
| 324 |
-+ {value, {_, S}} -> S;
|
|
| 325 |
-+ _ -> none |
|
| 326 |
-+ end, |
|
| 327 |
-+ ?DEBUG("we have shapers: ~p", [Shapers]),
|
|
| 328 |
-+ Shaper1 = acl:match_rule(global, Shapers, jlib:string_to_jid(Initiator)), |
|
| 329 |
-+ Shaper2 = acl:match_rule(global, Shapers, jlib:string_to_jid(Target)), |
|
| 330 |
-+ if Shaper1 == none; Shaper2 == none -> |
|
| 331 |
-+ MaxShaper = none; |
|
| 332 |
-+ true -> |
|
| 333 |
-+ ShaperValue1 = ejabberd_config:get_global_option({shaper, Shaper1}),
|
|
| 334 |
-+ ShaperValue2 = ejabberd_config:get_global_option({shaper, Shaper2}),
|
|
| 335 |
-+ |
|
| 336 |
-+ if ShaperValue1 > ShaperValue2 -> |
|
| 337 |
-+ MaxShaper = Shaper1; |
|
| 338 |
-+ true -> |
|
| 339 |
-+ MaxShaper = Shaper2 |
|
| 340 |
-+ end, |
|
| 341 |
-+ ?DEBUG("shapers have values ~p and ~p~nusing ~p", [ShaperValue1, ShaperValue2, MaxShaper]),
|
|
| 342 |
-+ ok |
|
| 343 |
-+ end, |
|
| 344 |
-+ |
|
| 345 |
-+ transfer_data(SockOpts, TargetSocket, shaper:new(MaxShaper)) |
|
| 346 |
-+ end. |
|
| 347 |
-+ |
|
| 348 |
-+transfer_data({SockMod, Socket} = SockOpts, {TargetSockMod, TargetSocket} = TargetSockOpts,
|
|
| 349 |
-+ Shaper) -> |
|
| 350 |
-+ case SockMod:recv(Socket, 0, infinity) of |
|
| 351 |
-+ {ok, Data} ->
|
|
| 352 |
-+ if Data /= <<>> -> |
|
| 353 |
-+ NewShaper = case Shaper of |
|
| 354 |
-+ none -> none; |
|
| 355 |
-+ _ -> |
|
| 356 |
-+ shaper:update(Shaper, size(Data)) |
|
| 357 |
-+ end, |
|
| 358 |
-+ ok = TargetSockMod:send(TargetSocket, Data); |
|
| 359 |
-+ true -> |
|
| 360 |
-+ NewShaper = Shaper |
|
| 361 |
-+ end, |
|
| 362 |
-+ transfer_data(SockOpts, TargetSockOpts, NewShaper); |
|
| 363 |
-+ {error, _} ->
|
|
| 364 |
-+ TargetSockMod:shutdown(TargetSocket, read_write) |
|
| 365 |
-+ end. |
|
| 366 |
-+ |
|
| 367 |
-+get_socket(PID) -> |
|
| 368 |
-+ PID ! {get_socket, self()},
|
|
| 369 |
-+ receive |
|
| 370 |
-+ {_SockMod, _Socket} = SockOpts ->
|
|
| 371 |
-+ SockOpts |
|
| 372 |
-+ end. |
|
| 373 |
-+ |
|
| 374 |
-+%% If any argument is a jid record, convert it to normalized string form... |
|
| 375 |
-+activate(#jid{} = Initiator, Target, SessionID) ->
|
|
| 376 |
-+ NormalizedInitiator = jlib:jid_to_string(jlib:make_jid(jlib:jid_tolower(Initiator))), |
|
| 377 |
-+ activate(NormalizedInitiator, Target, SessionID); |
|
| 378 |
-+activate(Initiator, #jid{} = Target, SessionID) ->
|
|
| 379 |
-+ NormalizedTarget = jlib:jid_to_string(jlib:make_jid(jlib:jid_tolower(Target))), |
|
| 380 |
-+ activate(Initiator, NormalizedTarget, SessionID); |
|
| 381 |
-+%% ...and get on with the activation. |
|
| 382 |
-+activate(Initiator, Target, SessionID) -> |
|
| 383 |
-+ Cookie = sha:sha(SessionID ++ Initiator ++ Target), |
|
| 384 |
-+ F = fun() -> |
|
| 385 |
-+ case mnesia:read({proxy65_connection, Cookie}) of
|
|
| 386 |
-+ [#proxy65_connection{firstpid = FirstPID,
|
|
| 387 |
-+ secondpid = SecondPID}] |
|
| 388 |
-+ when is_pid(FirstPID), is_pid(SecondPID) -> |
|
| 389 |
-+ mnesia:delete({proxy65_connection, Cookie}),
|
|
| 390 |
-+ {FirstPID, SecondPID};
|
|
| 391 |
-+ _ -> |
|
| 392 |
-+ error |
|
| 393 |
-+ end |
|
| 394 |
-+ end, |
|
| 395 |
-+ case mnesia:transaction(F) of |
|
| 396 |
-+ {atomic, {FirstPID, SecondPID}} ->
|
|
| 397 |
-+ FirstSocket = get_socket(FirstPID), |
|
| 398 |
-+ SecondSocket = get_socket(SecondPID), |
|
| 399 |
-+ FirstPID ! {activate, SecondSocket, Initiator, Target},
|
|
| 400 |
-+ SecondPID ! {activate, FirstSocket, Initiator, Target},
|
|
| 401 |
-+ ok; |
|
| 402 |
-+ Error -> |
|
| 403 |
-+ ?ERROR_MSG("Proxy activation failed: ~p", [Error]),
|
|
| 404 |
-+ error |
|
| 405 |
-+ end. |
|
| 406 |
- |
| ... | ... |
@@ -1,17 +0,0 @@ |
| 1 |
-# Copyright 1999-2005 Gentoo Foundation |
|
| 2 |
-# Distributed under the terms of the GNU General Public License v2 |
|
| 3 |
-# $Header: $ |
|
| 4 |
- |
|
| 5 |
-# Name of your ejabberd node. Used by ejabberdctl to determine which |
|
| 6 |
-# node to communicate with. Default is "ejabberd@`hostname -s`". |
|
| 7 |
-#EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 8 |
- |
|
| 9 |
-# Max number of open network connections. Default is 1024. Increasing |
|
| 10 |
-# this will slightly increase memory usage. |
|
| 11 |
-#ERL_MAX_PORTS=1024 |
|
| 12 |
- |
|
| 13 |
-# Return memory to the system after using it, instead of keeping it |
|
| 14 |
-# allocated for future use. Decreases the memory required by ejabberd, |
|
| 15 |
-# but makes it run slower. Default is unset, set to any value to |
|
| 16 |
-# activate. |
|
| 17 |
-#ERL_FULLSWEEP_AFTER=0 |
| ... | ... |
@@ -1,60 +0,0 @@ |
| 1 |
-#!/sbin/runscript |
|
| 2 |
-# Copyright 1999-2005 Gentoo Foundation |
|
| 3 |
-# Distributed under the terms of the GNU General Public License v2 |
|
| 4 |
-# $Header: $ |
|
| 5 |
- |
|
| 6 |
-opts="${opts} reload"
|
|
| 7 |
- |
|
| 8 |
-depend() {
|
|
| 9 |
- use dns |
|
| 10 |
- need net |
|
| 11 |
- provide jabber-server |
|
| 12 |
-} |
|
| 13 |
- |
|
| 14 |
-checkconfig() {
|
|
| 15 |
- if [ ! -e /etc/jabber/ejabberd.cfg ] ; then |
|
| 16 |
- eerror "You need an /etc/jabber/ejabberd.cfg file to run ejabberd" |
|
| 17 |
- return 1 |
|
| 18 |
- fi |
|
| 19 |
-} |
|
| 20 |
- |
|
| 21 |
-start() {
|
|
| 22 |
- checkconfig || return 1 |
|
| 23 |
- ebegin "Starting eJabberd" |
|
| 24 |
- start-stop-daemon --start --quiet --chuid jabber:jabber \ |
|
| 25 |
- --exec /usr/bin/env HOME=/var/run/jabber /usr/bin/ejabberd -- -noshell -detached |
|
| 26 |
- eend $? |
|
| 27 |
-} |
|
| 28 |
- |
|
| 29 |
-stop() {
|
|
| 30 |
- ebegin "Stopping eJabberd" |
|
| 31 |
- if [ -z "$EJABBERD_NODE" ]; |
|
| 32 |
- then |
|
| 33 |
- EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 34 |
- fi |
|
| 35 |
- /usr/bin/ejabberdctl $EJABBERD_NODE stop |
|
| 36 |
- eend $? |
|
| 37 |
-} |
|
| 38 |
- |
|
| 39 |
-# Work around a bug in /sbin/runscript.sh - it won't run our custom |
|
| 40 |
-# restart() unless it finds these two strings in the file. |
|
| 41 |
-# svc_start svc_stop |
|
| 42 |
-restart() {
|
|
| 43 |
- ebegin "Restarting eJabberd" |
|
| 44 |
- if [ -z "$EJABBERD_NODE" ]; |
|
| 45 |
- then |
|
| 46 |
- EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 47 |
- fi |
|
| 48 |
- /usr/bin/ejabberdctl $EJABBERD_NODE restart |
|
| 49 |
- eend $? |
|
| 50 |
-} |
|
| 51 |
- |
|
| 52 |
-reload() {
|
|
| 53 |
- ebegin "Reloading eJabberd" |
|
| 54 |
- if [ -z "$EJABBERD_NODE" ]; |
|
| 55 |
- then |
|
| 56 |
- EJABBERD_NODE="ejabberd@`hostname -s`" |
|
| 57 |
- fi |
|
| 58 |
- /usr/bin/ejabberdctl $EJABBERD_NODE reopen-log |
|
| 59 |
- eend $? |
|
| 60 |
-} |
| ... | ... |
@@ -1 +0,0 @@ |
| 1 |
-{file, resolv, "/etc/resolv.conf"}.
|
| ... | ... |
@@ -1,10 +0,0 @@ |
| 1 |
-<?xml version="1.0" encoding="UTF-8"?> |
|
| 2 |
-<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd"> |
|
| 3 |
- |
|
| 4 |
-<pkgmetadata> |
|
| 5 |
-<herd>net-im</herd> |
|
| 6 |
-<maintainer> |
|
| 7 |
- <email>lars@breakmygentoo.net</email> |
|
| 8 |
-</maintainer> |
|
| 9 |
-<longdescription> Free and Open Source distributed fault-tolerant Jabber server. It's mostly written in Erlang, and works on many platforms.</longdescription> |
|
| 10 |
-</pkgmetadata> |
|
| 11 | 0 |