Lars Strojny commited on 2007-03-18 16:29:14
Zeige 12 geänderte Dateien mit 1682 Einfügungen und 6 Löschungen.
... | ... |
@@ -51,9 +51,11 @@ DEPEND=">=net-im/jabber-base-0.0 |
51 | 51 |
|
52 | 52 |
RDEPEND=">=dev-python/twisted-1.3.0 |
53 | 53 |
>=dev-python/twisted-words-0.1.0 |
54 |
+ <dev-python/twisted-words-0.4 |
|
54 | 55 |
>=dev-python/twisted-xish-0.1.0 |
55 |
- >=dev-python/twisted-web-0.5.0 |
|
56 |
+ =dev-python/twisted-web-0.5* |
|
56 | 57 |
>=dev-python/nevow-0.4.1 |
58 |
+ <dev-python/nevow-0.8 |
|
57 | 59 |
>=dev-python/imaging-1.1" |
58 | 60 |
|
59 | 61 |
PYTRANSPORT_CONFIG=config_example.xml |
... | ... |
@@ -42,20 +42,49 @@ AUX ejabberd-1.1.2.initd 1260 RMD160 0565503966512228f21079213a8587d7ada7a823 SH |
42 | 42 |
MD5 608e482a70b1cd9a1a78d721edc8d42d files/ejabberd-1.1.2.initd 1260 |
43 | 43 |
RMD160 0565503966512228f21079213a8587d7ada7a823 files/ejabberd-1.1.2.initd 1260 |
44 | 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 622 RMD160 36bf34ba4a584ed19a4f93f709df0cfeb7d0ad7b SHA1 3fd01b6d6782bea7feeb3f784f393c04a7b7022c SHA256 747fbd494d6ebb75d5b73d407be10b0dba10f59a4a46561509c788d72a30ff08 |
|
54 |
+MD5 2b686065c6f72505ae252cdb5c7bebe8 files/ejabberd-1.1.3-mysql-connect-utf8.patch 622 |
|
55 |
+RMD160 36bf34ba4a584ed19a4f93f709df0cfeb7d0ad7b files/ejabberd-1.1.3-mysql-connect-utf8.patch 622 |
|
56 |
+SHA256 747fbd494d6ebb75d5b73d407be10b0dba10f59a4a46561509c788d72a30ff08 files/ejabberd-1.1.3-mysql-connect-utf8.patch 622 |
|
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 |
|
45 | 69 |
AUX inetrc 36 RMD160 4b79020864689ede547969610fde18fe490f5810 SHA1 1e0bae0f7251e2ae3b62ba9d3e5cc86bb5dd271e SHA256 0f383befc4c46134d88ce14d3bd06c404ef6575391f4ac0b5e8c28ba383b28fc |
46 | 70 |
MD5 e088cd52d4316efddc54195dc939cd24 files/inetrc 36 |
47 | 71 |
RMD160 4b79020864689ede547969610fde18fe490f5810 files/inetrc 36 |
48 | 72 |
SHA256 0f383befc4c46134d88ce14d3bd06c404ef6575391f4ac0b5e8c28ba383b28fc files/inetrc 36 |
49 | 73 |
DIST ejabberd-1.1.1.tar.gz 803278 RMD160 b9c0b7ab3fe1f1b2dce52e1460bba04b313ea534 SHA1 4f23d787afe75c7c866decdff6f539195449776e SHA256 52a97275537073066bd352f5718954f6994b272d1efa51187e17edf0c9b11082 |
50 | 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 |
|
51 | 76 |
EBUILD ejabberd-1.1.1.ebuild 5044 RMD160 3c0213f2cd39fdb54505cc0b394b70477b10fbb4 SHA1 491cbd3d3ab8dde27a5280fdbf2783131da4fa7b SHA256 9346b48122eb7812e6beba93e223d0c1d027719877ef7307415edac56b1a1d06 |
52 | 77 |
MD5 2d16ab0045996aa62fdc6867e8c62edb ejabberd-1.1.1.ebuild 5044 |
53 | 78 |
RMD160 3c0213f2cd39fdb54505cc0b394b70477b10fbb4 ejabberd-1.1.1.ebuild 5044 |
54 | 79 |
SHA256 9346b48122eb7812e6beba93e223d0c1d027719877ef7307415edac56b1a1d06 ejabberd-1.1.1.ebuild 5044 |
55 |
-EBUILD ejabberd-1.1.2-r5.ebuild 5070 RMD160 81251f4089f5489a80aae24df07fc5d3229b7121 SHA1 d2d30f92242eab59119b93d2d64951bf796bfcb1 SHA256 103e56d7c532126d7dc746473b81ee75dac4ae9e29fa3210639d3b49553d6a5a |
|
56 |
-MD5 5e30031f8c3d768b9c6e23416ea1f2ab ejabberd-1.1.2-r5.ebuild 5070 |
|
57 |
-RMD160 81251f4089f5489a80aae24df07fc5d3229b7121 ejabberd-1.1.2-r5.ebuild 5070 |
|
58 |
-SHA256 103e56d7c532126d7dc746473b81ee75dac4ae9e29fa3210639d3b49553d6a5a ejabberd-1.1.2-r5.ebuild 5070 |
|
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 5072 RMD160 d1ad865d489b7856ea9b252ac0fc9444fa812cd7 SHA1 695f4b8715050907072e347ea846b59fe673c181 SHA256 ada01971d7d7b5362ad8b9a839a990eb1b2d8013f7c66fdbba502486b02cbbfb |
|
85 |
+MD5 27ae991ce72e44d8838c5e7c9f3a5331 ejabberd-1.1.3-r1.ebuild 5072 |
|
86 |
+RMD160 d1ad865d489b7856ea9b252ac0fc9444fa812cd7 ejabberd-1.1.3-r1.ebuild 5072 |
|
87 |
+SHA256 ada01971d7d7b5362ad8b9a839a990eb1b2d8013f7c66fdbba502486b02cbbfb ejabberd-1.1.3-r1.ebuild 5072 |
|
59 | 88 |
MISC ChangeLog 1674 RMD160 a7cde836a8d747863d148edef3a9d1b7cf781af2 SHA1 529722882cfb1e1135eda10c99d0aa8e753704a3 SHA256 c37aa58a182a91857395f0c53c3299d19cfe4960d5240673c7606f18199d3681 |
60 | 89 |
MD5 678fcb919ef8ac4a080934c500537f8d ChangeLog 1674 |
61 | 90 |
RMD160 a7cde836a8d747863d148edef3a9d1b7cf781af2 ChangeLog 1674 |
... | ... |
@@ -70,3 +99,6 @@ SHA256 d3659c3dbc43cf807fb7309da84ba62393e9257a7a16a3305621ee60f97378a6 files/di |
70 | 99 |
MD5 a38033cd51c7bb84bc09310952063222 files/digest-ejabberd-1.1.2-r5 244 |
71 | 100 |
RMD160 d8117ebc19953eb40137b4ebca37d7577ff9e5b6 files/digest-ejabberd-1.1.2-r5 244 |
72 | 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 |
... | ... |
@@ -0,0 +1,197 @@ |
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 |
+} |
... | ... |
@@ -0,0 +1,934 @@ |
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 |
+ |
... | ... |
@@ -0,0 +1,11 @@ |
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}). |
... | ... |
@@ -0,0 +1,11 @@ |
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]), |
... | ... |
@@ -0,0 +1,406 @@ |
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 |
+ |
... | ... |
@@ -0,0 +1,17 @@ |
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 |
... | ... |
@@ -0,0 +1,60 @@ |
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 |
+} |
|
0 | 61 |