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 |