eigenes ejabberd-ebuild, brauchen wir nicht mehr
Hanno Böck

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,3 +0,0 @@
1
-MD5 ef6fae4a3f9c7f807f21e9cd3dae195b ejabberd-1.1.1.tar.gz 803278
2
-RMD160 b9c0b7ab3fe1f1b2dce52e1460bba04b313ea534 ejabberd-1.1.1.tar.gz 803278
3
-SHA256 52a97275537073066bd352f5718954f6994b272d1efa51187e17edf0c9b11082 ejabberd-1.1.1.tar.gz 803278
... ...
@@ -1,3 +0,0 @@
1
-MD5 5b947e19e18a6b554bf31d1c95176eb6 ejabberd-1.1.2.tar.gz 836240
2
-RMD160 e763752e6c5fb46c51b71e265ab2ceda6d043a0d ejabberd-1.1.2.tar.gz 836240
3
-SHA256 029129a6bcb5d15dbccc5aa756f61c52692eb6882ec7aad0193aa940b6a20bb6 ejabberd-1.1.2.tar.gz 836240
... ...
@@ -1,3 +0,0 @@
1
-MD5 bdb39965a147506fc194d5a28117172a ejabberd-1.1.3.tar.gz 826057
2
-RMD160 99b4c73ae29ef9814f5c572f8e3b3a82d960f5ee ejabberd-1.1.3.tar.gz 826057
3
-SHA256 3b8ac67673fa6c08bc25382d3e99171ebc71d4759899eb5a730e65117256e703 ejabberd-1.1.3.tar.gz 826057
... ...
@@ -1,3 +0,0 @@
1
-MD5 5b947e19e18a6b554bf31d1c95176eb6 ejabberd-1.1.2.tar.gz 836240
2
-RMD160 e763752e6c5fb46c51b71e265ab2ceda6d043a0d ejabberd-1.1.2.tar.gz 836240
3
-SHA256 029129a6bcb5d15dbccc5aa756f61c52692eb6882ec7aad0193aa940b6a20bb6 ejabberd-1.1.2.tar.gz 836240
... ...
@@ -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