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 |