diff options
author | Bertrand Jacquin <beber@meleeweb.net> | 2006-09-28 21:56:03 +0200 |
---|---|---|
committer | Bertrand Jacquin <beber@meleeweb.net> | 2006-09-28 21:56:03 +0200 |
commit | 7d299f1efeecd3cb69d6ce76a9486dbb26971a19 (patch) | |
tree | a184b2cb2994d65a818a0a4f72498b13869bd6e6 | |
parent | ejabberd: more patch for new release (diff) | |
download | portage-7d299f1efeecd3cb69d6ce76a9486dbb26971a19.tar.xz |
ejabberd: add patch from http://bugs.gentoo.org/show_bug.cgi?id=137724 and http://bugs.gentoo.org/show_bug.cgi?id=145373
-rw-r--r-- | net-im/ejabberd/Manifest | 23 | ||||
-rw-r--r-- | net-im/ejabberd/ejabberd-1.1.2-r1.ebuild | 213 | ||||
-rw-r--r-- | net-im/ejabberd/files/digest-ejabberd-1.1.2-r1 | 9 | ||||
-rw-r--r-- | net-im/ejabberd/files/ejabberd-1.1.2-mod-proxy.patch | 423 | ||||
-rw-r--r-- | net-im/ejabberd/files/ejabberd-1.1.2-statsdx-web.patch | 318 | ||||
-rw-r--r-- | net-im/ejabberd/files/ejabberd-1.1.2-statsdx.patch | 742 | ||||
-rw-r--r-- | net-im/ejabberd/files/ejabberd-1.1.2.initd | 59 |
7 files changed, 1787 insertions, 0 deletions
diff --git a/net-im/ejabberd/Manifest b/net-im/ejabberd/Manifest index 917c7870..99f645d0 100644 --- a/net-im/ejabberd/Manifest +++ b/net-im/ejabberd/Manifest @@ -1,3 +1,19 @@ +AUX ejabberd-1.1.2-mod-proxy.patch 14771 RMD160 4a3d817fd103aebfb8e76fc9f23396b57da5f473 SHA1 023ab0fe368bd6de78ad21a977b1d5a09818cab3 SHA256 3c130d4d76fcc6e51014c4ef7db2939d3d6ee911f59fe17bd580ca914a07d6e3 +MD5 c9f267fcc007f5a0a92834fc63d9cb3e files/ejabberd-1.1.2-mod-proxy.patch 14771 +RMD160 4a3d817fd103aebfb8e76fc9f23396b57da5f473 files/ejabberd-1.1.2-mod-proxy.patch 14771 +SHA256 3c130d4d76fcc6e51014c4ef7db2939d3d6ee911f59fe17bd580ca914a07d6e3 files/ejabberd-1.1.2-mod-proxy.patch 14771 +AUX ejabberd-1.1.2-statsdx-web.patch 9287 RMD160 e98789d5b29f6fcb55c383e551239378c8ce3eb6 SHA1 4e35a28d7692ae3d36bd0c5590b482c9f8266309 SHA256 4036facbe4bd712784e5964b1e422b1f3f60aeff8ec1058b3358c45535b4e8d9 +MD5 ae2346c4c0a0540b3236a80a2bf12451 files/ejabberd-1.1.2-statsdx-web.patch 9287 +RMD160 e98789d5b29f6fcb55c383e551239378c8ce3eb6 files/ejabberd-1.1.2-statsdx-web.patch 9287 +SHA256 4036facbe4bd712784e5964b1e422b1f3f60aeff8ec1058b3358c45535b4e8d9 files/ejabberd-1.1.2-statsdx-web.patch 9287 +AUX ejabberd-1.1.2-statsdx.patch 24201 RMD160 e04d36746649e435a68c32f2705a27fc9107009e SHA1 6d621b54addfcdb047ec7b4314573ec4aa161ef9 SHA256 27dfeaa59ab901c9c08d7dca9fc667252cec64fa08d8e43adaa7e72f961f864f +MD5 a5fc80bf820a7d5ef93354895bd2928a files/ejabberd-1.1.2-statsdx.patch 24201 +RMD160 e04d36746649e435a68c32f2705a27fc9107009e files/ejabberd-1.1.2-statsdx.patch 24201 +SHA256 27dfeaa59ab901c9c08d7dca9fc667252cec64fa08d8e43adaa7e72f961f864f files/ejabberd-1.1.2-statsdx.patch 24201 +AUX ejabberd-1.1.2.initd 1405 RMD160 104068f4a53db32a713c7e12c3e5eaa6f0ed6545 SHA1 0ff5afe2a0994f36168a2df319c0dfaf9813aa81 SHA256 2d1aa6e50eaa090b2e5897fd5d72112a3848811f6886041fdb8903f85ea18daf +MD5 df620170a91b83b4a45c79d2d736dd22 files/ejabberd-1.1.2.initd 1405 +RMD160 104068f4a53db32a713c7e12c3e5eaa6f0ed6545 files/ejabberd-1.1.2.initd 1405 +SHA256 2d1aa6e50eaa090b2e5897fd5d72112a3848811f6886041fdb8903f85ea18daf files/ejabberd-1.1.2.initd 1405 AUX mod_archive.erl 29560 RMD160 6c628ca4f1d82cd826c2a4d11c87d6b3344f3f24 SHA1 b934e9a9ed1ab7dc700b589177dc9425aa535a6f SHA256 b46976ca86a43cb13ed71009a5fadf7a2ca231e51da83150cdff0d646fbed00f MD5 c3c630a783edc22b0d81646f2c2eb829 files/mod_archive.erl 29560 RMD160 6c628ca4f1d82cd826c2a4d11c87d6b3344f3f24 files/mod_archive.erl 29560 @@ -14,6 +30,10 @@ EBUILD ejabberd-1.1.1-r1.ebuild 3886 RMD160 688617ec68dd542758b695d18d57c6d123c5 MD5 151e7780af1a89705e11cdae74358821 ejabberd-1.1.1-r1.ebuild 3886 RMD160 688617ec68dd542758b695d18d57c6d123c5e2f7 ejabberd-1.1.1-r1.ebuild 3886 SHA256 04236fb5a30476d6b05bbfc8be4e0eb4abad407194204fa8729f3481c0e4bd53 ejabberd-1.1.1-r1.ebuild 3886 +EBUILD ejabberd-1.1.2-r1.ebuild 5727 RMD160 32735f6451a7204f3018b7abd7ad593743104a51 SHA1 2eaca4da4fc79219ee6307ffd3191608068d695c SHA256 e7e6687d67bcb5d9731738ecf8e92034bbacd00ef22256ad2738d58ff3ebdfbc +MD5 502ee5bd89b264cd8a5be6d37cb79b87 ejabberd-1.1.2-r1.ebuild 5727 +RMD160 32735f6451a7204f3018b7abd7ad593743104a51 ejabberd-1.1.2-r1.ebuild 5727 +SHA256 e7e6687d67bcb5d9731738ecf8e92034bbacd00ef22256ad2738d58ff3ebdfbc ejabberd-1.1.2-r1.ebuild 5727 EBUILD ejabberd-1.1.2.ebuild 3886 RMD160 688617ec68dd542758b695d18d57c6d123c5e2f7 SHA1 42051242370093ccff3ecd35fcfa4bda4140ddd3 SHA256 04236fb5a30476d6b05bbfc8be4e0eb4abad407194204fa8729f3481c0e4bd53 MD5 151e7780af1a89705e11cdae74358821 ejabberd-1.1.2.ebuild 3886 RMD160 688617ec68dd542758b695d18d57c6d123c5e2f7 ejabberd-1.1.2.ebuild 3886 @@ -24,3 +44,6 @@ SHA256 f57333e151bec1d584876aade6dc4fec76e8deffdd240d7aa2d2ec947d6dbba8 files/di MD5 f10adb4f04e5543f5410c8a2e1081c96 files/digest-ejabberd-1.1.2 723 RMD160 7eeb128a9c425adfe020101bef8a0278e1bd0211 files/digest-ejabberd-1.1.2 723 SHA256 811fc4d85d4bcd926bdce37a5ecade163afb5b14663d747842375c8ffdc5100d files/digest-ejabberd-1.1.2 723 +MD5 f10adb4f04e5543f5410c8a2e1081c96 files/digest-ejabberd-1.1.2-r1 723 +RMD160 7eeb128a9c425adfe020101bef8a0278e1bd0211 files/digest-ejabberd-1.1.2-r1 723 +SHA256 811fc4d85d4bcd926bdce37a5ecade163afb5b14663d747842375c8ffdc5100d files/digest-ejabberd-1.1.2-r1 723 diff --git a/net-im/ejabberd/ejabberd-1.1.2-r1.ebuild b/net-im/ejabberd/ejabberd-1.1.2-r1.ebuild new file mode 100644 index 00000000..85f7e1cb --- /dev/null +++ b/net-im/ejabberd/ejabberd-1.1.2-r1.ebuild @@ -0,0 +1,213 @@ +# Copyright 1999-2006 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +inherit eutils multilib ssl-cert versionator autotools + +JABBER_ETC="/etc/jabber" +JABBER_RUN="/var/run/jabber" +JABBER_SPOOL="/var/spool/jabber" +JABBER_LOG="/var/log/jabber" + +E_MYSQL_V="5" +E_MYSQL_N="mysql" +E_MYSQL=${E_MYSQL_N}-${E_MYSQL_V} + +E_PGSQL_V="0.0.1" +E_PGSQL_N="pgsql-cvs" +E_PGSQL=${E_PGSQL_N}-${E_PGSQL_V} + +DESCRIPTION="The Erlang Jabber Daemon" +HOMEPAGE="http://ejabberd.jabber.ru/" +SRC_URI="http://process-one.net/en/projects/${PN}/download/${PV}/${P}.tar.gz + pam? ( http://beber.meleeweb.net/jabber/check_pam.diff.gz ) + mod_presence? ( http://www.goryachev.org/jabber/mod_presence-0.0.3.tar.gz )" +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="x86 ~amd64" +IUSE="${IUSE} mod_archive mod_irc mod_muc mod_pubsub mod_presence mod_proxy statsdx ldap odbc pam web mysql postgres" + +DEPEND="${RDEPEND} + >=net-im/jabber-base-0.01 + >=dev-libs/expat-1.95 + >=dev-lang/erlang-10.2.0 + odbc? ( dev-db/unixODBC ) + ldap? ( =net-nds/openldap-2* ) + postgres? ( =dev-erl/${E_PGSQL} ) + mysql? ( =dev-erl/${E_MYSQL} ) + pam? ( sys-libs/pam)" +RDEPEND="postgres? ( dev-db/postgresql ) + mysql? ( dev-db/mysql )" + +RESTRICT="nomirror" + +PROVIDE="virtual/jabber-server" +S=${WORKDIR}/${P}/src + +src_unpack() { + unpack ${A} + cd ${S} + + MYSQL_P=$(best_version dev-db/mysql) + MYSQL_PV=${MYSQL_P/dev-db\/mysql-/} + + # + # If we have to work with MySQL 4.1 or greater, ejabberd's native + # MySQL-driver has to be patched to query "SET NAMES 'utf8'" on connecting + # the database. + # + if use mysql && \ + (( \ + [ $(get_major_version ${MYSQL_PV}) -eq 4 ] && \ + [ $(get_major_version $(get_after_major_version ${MYSQL_PV})) -ge 1] \ + ) \ + || \ + [ $(get_major_version ${MYSQL_PV}) -ge 5 ] \ + ); then + epatch ${FILESDIR}/${P}-mysql-connect-utf8.patch + fi + + if use statsdx; then + epatch ${FILESDIR}/${P}-statsdx.patch + epatch ${FILESDIR}/${P}-statsdx-web.patch + fi + + if use mod_proxy; then + epatch ${FILESDIR}/${P}-mod-proxy.patch + fi + + if use mod_presence; then + epatch ${WORKDIR}/mod_presence/mod_presence.diff + cp -r ${WORKDIR}/mod_presence/pixmaps . + fi + + if use pam; then + patch -p0 < ${WORKDIR}/check_pam.diff + fi + + if use mod_archive; then + cp ${FILESDIR}/mod_archive.erl . + fi +} + +src_compile() { + local myconf + + if ! use mysql && ! use postgres && ! use odbc; then + myconf="--disable-odbc" + else + myconf="--enable-odbc" + fi + + eautoconf + econf ${myconf} \ + --enable-roster-gateway-workaround \ + $(use_enable mod_irc) \ + $(use_enable ldap eldap) \ + $(use_enable mod_muc) \ + $(use_enable mod_pubsub) \ + $(use_enable ssl tls) \ + $(use_enable web) \ + $(use_enable odbc) \ + $(use_enable mod_presence) \ + || die "econf failed" + + emake || die "compiling ejabberd core failed" +} + +src_install() { + make \ + DESTDIR=${D} \ + EJABBERDDIR=${D}/usr/$(get_libdir)/erlang/lib/${P} \ + ETCDIR=${D}${JABBER_ETC} \ + LOGDIR=${D}${JABBER_LOG} \ + install \ + || die "install failed" + + insinto /usr/share/doc/${PF} + use postgres && doins odbc/pg.sql + use mysql && doins odbc/mysql.sql + cd ${S}/.. + dodoc doc/release_notes_${PV}.txt + dohtml doc/*.{html,png} + + use postgres && { + pa="-pa /usr/$(get_libdir)/erlang/lib/${E_PGSQL}/ebin" + } + + use mysql && { + pa=${pa}" -pa /usr/$(get_libdir)/erlang/lib/${E_MYSQL}/ebin" + } + + # + # Create /usr/bin/ejabberd + # + cat <<EOF > ${T}/ejabberd +#!/bin/bash + +erl -pa /usr/$(get_libdir)/erlang/lib/${P}/ebin \\ + ${pa} \\ + -sname ejabberd \\ + -s ejabberd \\ + -ejabberd config \"${JABBER_ETC}/ejabberd.cfg\" \\ + log_path \"${JABBER_LOG}/ejabberd.log\" \\ + -kernel inetrc \"${JABBER_ETC}/inetrc\" \\ + -sasl sasl_error_logger \{file,\"${JABBER_LOG}/sasl.log\"\} \\ + -mnesia dir \"${JABBER_SPOOL}\" \\ + \$@ +EOF + + # + # Create /usr/bin/ejabberdctl + # + cat <<EOF > ${T}/ejabberdctl +#!/bin/sh + +exec env HOME=${JABBER_RUN} \\ + erl -pa /usr/$(get_libdir)/erlang/lib/${P}/ebin \\ + ${pa} \\ + -noinput \\ + -sname ejabberdctl \\ + -s ejabberd_ctl \\ + -extra \$@ +EOF + + dobin ${T}/ejabberdctl + dobin ${T}/ejabberd + + newinitd ${FILESDIR}/${P}.initd ${PN} + newconfd ${FILESDIR}/${P}.confd ${PN} + + insinto ${JABBER_ETC} + if use ssl; then + docert ssl + rm -f ${D}${JABBER_ETC}/ssl.{crt,csr,key} + fowners jabber:jabber ${JABBER_ETC}/ssl.pem + fi + doins ${FILESDIR}/inetrc +} + +pkg_postinst() { + if [ ! -e ${JABBER_ETC}/ejabberd.cfg ] + then + einfo "Configuration file has been installed in ${JABBER_ETC}/ejabberd.cfg." + einfo "Edit it according to your needs. For configuration instructions," + einfo "please see /usr/share/doc/${PF}/html/guide.html" + fi + if use ssl ; then + einfo "A script to generate a ssl key has been installed in" + einfo "${JABBER_ETC}/self-cert.sh . Use it and change the config file to" + einfo "point to the full path" + fi + if ! use web ; then + einfo "The web USE flag is off, this will disable the web admin interface," + einfo "if this was not the intention then add web to your USE flags." + fi + + if use modproxy ; then + einfo "mod_proxy enabled ! http://www.jabber.ru/bugzilla/show_bug.cgi?id=25" + fi + if use statsdx ; then + einfo "Advanced stats enabled ! http://ejabberd.jabber.ru/mod_statsdx" + fi +} diff --git a/net-im/ejabberd/files/digest-ejabberd-1.1.2-r1 b/net-im/ejabberd/files/digest-ejabberd-1.1.2-r1 new file mode 100644 index 00000000..2e59e9e3 --- /dev/null +++ b/net-im/ejabberd/files/digest-ejabberd-1.1.2-r1 @@ -0,0 +1,9 @@ +MD5 6b78cb824b35a7f651ab33790cf841c7 check_pam.diff.gz 3865 +RMD160 86d6ff263d216c63662ef1078f947f9f7a6c1fce check_pam.diff.gz 3865 +SHA256 c474adefeefd6e2d18fff531dc4c2f3c149ba003dbd606655656a95ca72ee62a check_pam.diff.gz 3865 +MD5 5b947e19e18a6b554bf31d1c95176eb6 ejabberd-1.1.2.tar.gz 836240 +RMD160 e763752e6c5fb46c51b71e265ab2ceda6d043a0d ejabberd-1.1.2.tar.gz 836240 +SHA256 029129a6bcb5d15dbccc5aa756f61c52692eb6882ec7aad0193aa940b6a20bb6 ejabberd-1.1.2.tar.gz 836240 +MD5 fa9a979f5e3530a2b3143416934d989b mod_presence-0.0.3.tar.gz 51392 +RMD160 adb6444dcef2fead52c1510fc247f7af20aa62c7 mod_presence-0.0.3.tar.gz 51392 +SHA256 5fc2a97576f33965d07bb1f803a8fe48647479da37cd58333aea6a7e48ebc4a1 mod_presence-0.0.3.tar.gz 51392 diff --git a/net-im/ejabberd/files/ejabberd-1.1.2-mod-proxy.patch b/net-im/ejabberd/files/ejabberd-1.1.2-mod-proxy.patch new file mode 100644 index 00000000..1981aee1 --- /dev/null +++ b/net-im/ejabberd/files/ejabberd-1.1.2-mod-proxy.patch @@ -0,0 +1,423 @@ +diff -Naur ejabberd-1.1.1/src/ejabberd.cfg.example ejabberd-1.1.1-r1/src/ejabberd.cfg.example +--- ejabberd-1.1.1/src/ejabberd.cfg.example 2006-04-22 15:50:30.000000000 +0200 ++++ ejabberd-1.1.1-r1/src/ejabberd.cfg.example 2006-06-23 09:38:17.000000000 +0200 +@@ -125,6 +125,7 @@ + {max_stanza_size, 131072} + ]}, + {5280, ejabberd_http, [http_poll, web_admin]}, ++ %{7777, proxy65_listener, [{shaper, c2s_shaper}]}, + {8888, ejabberd_service, [{access, all}, + {hosts, ["icq.localhost", "sms.localhost"], + [{password, "secret"}]}]} +@@ -171,6 +172,11 @@ + {mod_pubsub, []}, + {mod_time, []}, + {mod_last, []}, ++ %% Simple configuration (hostname:7777) ++ %%{mod_proxy65, []}, ++ %% Several possible hostnames ++ %%{mod_proxy65, [{access, all}, ++ %% {streamhosts, [{"example.com", 7777}, {"192.168.0.42", 7777}]}]}, + {mod_version, []} + ]}. + +diff -Naur ejabberd-1.1.1/src/jlib.hrl ejabberd-1.1.1-r1/src/jlib.hrl +--- ejabberd-1.1.1/src/jlib.hrl 2006-01-20 17:21:39.000000000 +0100 ++++ ejabberd-1.1.1-r1/src/jlib.hrl 2006-06-23 09:38:17.000000000 +0200 +@@ -34,6 +34,7 @@ + -define(NS_PUBSUB_OWNER, "http://jabber.org/protocol/pubsub#owner"). + -define(NS_PUBSUB_NMI, "http://jabber.org/protocol/pubsub#node-meta-info"). + -define(NS_COMMANDS, "http://jabber.org/protocol/commands"). ++-define(NS_BYTESTREAMS, "http://jabber.org/protocol/bytestreams"). + + -define(NS_EJABBERD_CONFIG, "ejabberd:config"). + +diff -Naur ejabberd-1.1.1/src/mod_proxy65.erl ejabberd-1.1.1-r1/src/mod_proxy65.erl +--- ejabberd-1.1.1/src/mod_proxy65.erl 1970-01-01 01:00:00.000000000 +0100 ++++ ejabberd-1.1.1-r1/src/mod_proxy65.erl 2006-06-23 09:38:17.000000000 +0200 +@@ -0,0 +1,189 @@ ++%%%---------------------------------------------------------------------- ++%%% File : mod_proxy65.erl ++%%% Author : Magnus Henoch <henoch@dtek.chalmers.se> ++%%% Purpose : Handle Jabber communications for JEP-0065 proxy ++%%% Created : 27 Dec 2005 by Magnus Henoch <henoch@dtek.chalmers.se> ++%%% Id : $Id: ejabberd_c2s.erl 440 2005-11-22 18:00:56Z alexey $ ++%%%---------------------------------------------------------------------- ++ ++-module(mod_proxy65). ++-author('henoch@dtek.chalmers.se'). ++-vsn('$Revision$ '). ++ ++-behaviour(gen_mod). ++ ++-export([start/2, ++ init/1, ++ stop/1]). ++ ++-include("ejabberd.hrl"). ++-include("jlib.hrl"). ++ ++-record(proxy65_connection, {cookie, firstpid = none, secondpid = none}). ++ ++-record(proxy65_options, {host, access, streamhosts}). ++ ++-define(PROCNAME, ejabberd_mod_proxy65). ++ ++start(Host, Opts) -> ++ mnesia:create_table(proxy65_connection, ++ [{ram_copies, [node()]}, ++ {attributes, record_info(fields, proxy65_connection)}]), ++ MyHost = gen_mod:get_opt(host, Opts, "proxy." ++ Host), ++ Access = gen_mod:get_opt(access, Opts, all), ++ Streamhosts = gen_mod:get_opt(streamhosts, Opts, [{Host, 7777}]), ++ ++ register(gen_mod:get_module_proc(Host, ?PROCNAME), ++ spawn(?MODULE, init, [#proxy65_options{host = MyHost, access = Access, ++ streamhosts = Streamhosts}])). ++ ++ ++stop(Host) -> ++ Proc = gen_mod:get_module_proc(Host, ?PROCNAME), ++ Proc ! stop, ++ {wait, Proc}. ++ ++init(#proxy65_options{host = Host} = Opts) -> ++ ejabberd_router:register_route(Host), ++ loop(Opts). ++ ++loop(#proxy65_options{host = Host} = Opts) -> ++ receive ++ {route, From, To, Packet} -> ++ case catch do_route(Opts, From, To, Packet) of ++ {'EXIT', Reason} -> ++ ?ERROR_MSG("~p", [Reason]); ++ _ -> ++ ok ++ end, ++ loop(Opts); ++ stop -> ++ ejabberd_router:unregister_route(Host), ++ ok; ++ _ -> ++ loop(Opts) ++ end. ++ ++do_route(#proxy65_options{host = Host, access = Access} = Opts, ++ From, To, Packet) -> ++ case acl:match_rule(Host, Access, From) of ++ allow -> ++ do_route1(Opts, From, To, Packet); ++ _ -> ++ {xmlelement, _Name, Attrs, _Els} = Packet, ++ Lang = xml:get_attr_s("xml:lang", Attrs), ++ ErrText = "Access denied by service policy", ++ Err = jlib:make_error_reply(Packet, ++ ?ERRT_FORBIDDEN(Lang, ErrText)), ++ ejabberd_router:route(To, From, Err) ++ end. ++ ++do_route1(#proxy65_options{host = Host, streamhosts = Streamhosts}, From, To, Packet) -> ++ {xmlelement, Name, _Attrs, _Els} = Packet, ++ case Name of ++ "iq" -> ++ case jlib:iq_query_info(Packet) of ++ #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS, ++ lang = Lang, sub_el = SubEl} = IQ -> ++ Node = xml:get_tag_attr_s("node", SubEl), ++ if Node == [] -> ++ Res = IQ#iq{type = result, ++ sub_el = [{xmlelement, "query", ++ [{"xmlns", XMLNS}], ++ [{xmlelement, "identity", ++ [{"category", "proxy"}, ++ {"type", "bytestreams"}, ++ {"name", translate:translate(Lang, "SOCKS5 bytestreams proxy")}], ++ []}, ++ {xmlelement, "feature", ++ [{"var", ?NS_BYTESTREAMS}], []}]}]}; ++ true -> ++ Res = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND) ++ end; ++ #iq{type = get, xmlns = ?NS_DISCO_ITEMS = XMLNS} = IQ -> ++ Res = IQ#iq{type = result, ++ sub_el = [{xmlelement, "query", ++ [{"xmlns", XMLNS}], []}]}; ++ #iq{type = get, xmlns = ?NS_VERSION} = IQ -> ++ OSType = case os:type() of ++ {Osfamily, Osname} -> ++ atom_to_list(Osfamily) ++ "/" ++ ++ atom_to_list(Osname); ++ Osfamily -> ++ atom_to_list(Osfamily) ++ end, ++ OSVersion = case os:version() of ++ {Major, Minor, Release} -> ++ lists:flatten( ++ io_lib:format("~w.~w.~w", ++ [Major, Minor, Release])); ++ VersionString -> ++ VersionString ++ end, ++ OS = OSType ++ " " ++ OSVersion, ++ Res = IQ#iq{type = result, ++ sub_el = [{xmlelement, "query", ++ [{"xmlns", ?NS_VERSION}], ++ [{xmlelement, "name", [], ++ [{xmlcdata, "ejabberd mod_proxy65 (unofficial)"}]}, ++ {xmlelement, "version", [], ++ [{xmlcdata, "0.1"}]}, ++ {xmlelement, "os", [], ++ [{xmlcdata, OS}]} ++ ]}]}; ++ #iq{type = get, xmlns = ?NS_BYTESTREAMS = XMLNS} = IQ -> ++ Res = IQ#iq{type = result, ++ sub_el = [{xmlelement, "query", ++ [{"xmlns", XMLNS}], ++ return_streamhosts(Host, Streamhosts)}]}; ++ #iq{type = set, xmlns = ?NS_BYTESTREAMS} = IQ -> ++ Res = activate(Packet, From, To, IQ); ++ _ -> ++ Res = jlib:make_error_reply(Packet, ?ERR_FEATURE_NOT_IMPLEMENTED) ++ end, ++ case Res of ++ #iq{} -> ++ ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); ++ _ -> ++ ejabberd_router:route(To, From, Res) ++ end; ++ _ -> ++ ejabberd_router:route(To, From, jlib:make_error_reply(Packet, ?ERR_FEATURE_NOT_IMPLEMENTED)) ++ end. ++ ++return_streamhosts(_JID, []) -> ++ []; ++return_streamhosts(JID, [{Host, Port} | Streamhosts]) -> ++ %% This is not tail-recursive, but it doesn't matter. ++ [{xmlelement, "streamhost", ++ [{"jid", JID}, ++ {"host", Host}, ++ {"port", integer_to_list(Port)}], ++ []} | return_streamhosts(JID, Streamhosts)]. ++ ++activate(Packet, From, _To, #iq{sub_el = SubEl} = IQ) -> ++ case SubEl of ++ {xmlelement, "query", Attrs, _SubEls} -> ++ Sid = xml:get_attr_s("sid", Attrs), ++ ActivateTag = xml:get_subtag(SubEl, "activate"), ++ if ActivateTag /= false -> ++ TargetJID = jlib:string_to_jid(xml:get_tag_cdata(ActivateTag)); ++ true -> ++ TargetJID = false ++ end, ++ ++ if Sid /= [], TargetJID /= false, TargetJID /= error -> ++ case proxy65_listener:activate(From, TargetJID, Sid) of ++ ok -> ++ ?INFO_MSG("Activated connection between ~s and ~s", ++ [jlib:jid_to_string(From), TargetJID]), ++ IQ#iq{type = result, sub_el = []}; ++ _ -> ++ jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR) ++ end; ++ true -> ++ jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST) ++ end; ++ _ -> ++ jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST) ++ end. +diff -Naur ejabberd-1.1.1/src/proxy65_listener.erl ejabberd-1.1.1-r1/src/proxy65_listener.erl +--- ejabberd-1.1.1/src/proxy65_listener.erl 1970-01-01 01:00:00.000000000 +0100 ++++ ejabberd-1.1.1-r1/src/proxy65_listener.erl 2006-06-23 09:38:17.000000000 +0200 +@@ -0,0 +1,192 @@ ++%%%---------------------------------------------------------------------- ++%%% File : proxy65_listener.erl ++%%% Author : Magnus Henoch <henoch@dtek.chalmers.se> ++%%% Purpose : Handle SOCKS5 connections for JEP-0065 proxy ++%%% Created : 27 Dec 2005 by Magnus Henoch <henoch@dtek.chalmers.se> ++%%% Id : $Id: ejabberd_c2s.erl 440 2005-11-22 18:00:56Z alexey $ ++%%%---------------------------------------------------------------------- ++ ++-module(proxy65_listener). ++-author('henoch@dtek.chalmers.se'). ++-vsn('$Revision$ '). ++ ++-export([start/2, handle_connection/2, activate/3]). ++ ++-include("ejabberd.hrl"). ++-include("jlib.hrl"). ++ ++-record(proxy65_connection, {cookie, firstpid = none, secondpid = none}). ++ ++start({SockMod, Socket}, Opts) -> ++ {ok, proc_lib:spawn(?MODULE, handle_connection, [{SockMod, Socket}, Opts])}. ++ ++read_bytes(_SockOpts, 0, Data) -> ++ lists:flatten(Data); ++read_bytes({SockMod, Socket} = SockOpts, N, Data) -> ++ Timeout = 1000, ++ case SockMod:recv(Socket, N, Timeout) of ++ {error, closed} -> ++ %% On closed connection, return everything we have, ++ %% but not if we have nothing. ++ if Data == [] -> ++ erlang:error(closed); ++ true -> ++ lists:flatten(Data) ++ end; ++ {ok, MoreData} -> ++ ?DEBUG("read ~p", [MoreData]), ++ DataList = binary_to_list(MoreData), ++ read_bytes(SockOpts, N - length(DataList), [Data, DataList]) ++ end. ++ ++handle_connection({SockMod, Socket}, Opts) -> ++ ?DEBUG("in handle_connection", []), ++ case catch handle_auth({SockMod, Socket}, Opts) of ++ {'EXIT', Reason} -> ++ ?ERROR_MSG("~p abnormal termination:~n\t~p~n", ++ [?MODULE, Reason]), ++ SockMod:close(Socket); ++ _ -> ++ ok ++ end. ++ ++handle_auth({SockMod, Socket} = SockOpts, Opts) -> ++ ?DEBUG("in handle_auth", []), ++ %% SOCKS protocol stuff... ++ [5, NAuthMethods] = read_bytes(SockOpts, 2, []), ++ AuthMethods = read_bytes(SockOpts, NAuthMethods, []), ++ SupportsNoAuth = lists:member(0, AuthMethods), ++ ++ %% Must support no authentication, otherwise crash ++ true = SupportsNoAuth, ++ ++ SockMod:send(Socket, [5, 0]), ++ ++ %% And done. ++ handle_connect(SockOpts, Opts). ++ ++handle_connect({SockMod, Socket} = SockOpts, Opts) -> ++ ?DEBUG("in handle_connect", []), ++ %% Expect a CONNECT command and nothing else ++ [5, 1, _, 3, AddressLength] = read_bytes(SockOpts, 5, []), ++ Cookie = read_bytes(SockOpts, AddressLength, []), ++ [0, 0] = read_bytes(SockOpts, 2, []), ++ ++ %% Make sure no more than two connections claim the same cookie. ++ F = fun() -> ++ case mnesia:read({proxy65_connection, Cookie}) of ++ [] -> ++ mnesia:write(#proxy65_connection{cookie = Cookie, ++ firstpid = self()}), ++ ok; ++ [#proxy65_connection{secondpid = none} = C] -> ++ mnesia:write(C#proxy65_connection{secondpid = self()}), ++ ok ++ end ++ end, ++ ++ case mnesia:transaction(F) of ++ {atomic, ok} -> ++ SockMod:send(Socket, [5, 0, 0, 3, AddressLength, Cookie, 0, 0]), ++ wait_for_activation(SockOpts, Opts); ++ Error -> ++ %% conflict. send "general SOCKS server failure". ++ SockMod:send(Socket, [5, 1, 0, 3, AddressLength, Cookie, 0, 0]), ++ erlang:error({badconnect, Error}) ++ end. ++ ++wait_for_activation(SockOpts, Opts) -> ++ ?DEBUG("in wait_for_activation", []), ++ receive ++ {get_socket, ReplyTo} -> ++ ReplyTo ! SockOpts, ++ wait_for_activation(SockOpts, Opts); ++ {activate, TargetSocket, Initiator, Target} -> ++ ?DEBUG("activated", []), ++ ++ %% We have no way of knowing which connection belongs to ++ %% which participant, so give both the maximum traffic ++ %% allowed to either. ++ Shapers = case lists:keysearch(shaper, 1, Opts) of ++ {value, {_, S}} -> S; ++ _ -> none ++ end, ++ ?DEBUG("we have shapers: ~p", [Shapers]), ++ Shaper1 = acl:match_rule(global, Shapers, jlib:string_to_jid(Initiator)), ++ Shaper2 = acl:match_rule(global, Shapers, jlib:string_to_jid(Target)), ++ if Shaper1 == none; Shaper2 == none -> ++ MaxShaper = none; ++ true -> ++ ShaperValue1 = ejabberd_config:get_global_option({shaper, Shaper1}), ++ ShaperValue2 = ejabberd_config:get_global_option({shaper, Shaper2}), ++ ++ if ShaperValue1 > ShaperValue2 -> ++ MaxShaper = Shaper1; ++ true -> ++ MaxShaper = Shaper2 ++ end, ++ ?DEBUG("shapers have values ~p and ~p~nusing ~p", [ShaperValue1, ShaperValue2, MaxShaper]), ++ ok ++ end, ++ ++ transfer_data(SockOpts, TargetSocket, shaper:new(MaxShaper)) ++ end. ++ ++transfer_data({SockMod, Socket} = SockOpts, {TargetSockMod, TargetSocket} = TargetSockOpts, ++ Shaper) -> ++ case SockMod:recv(Socket, 0, infinity) of ++ {ok, Data} -> ++ if Data /= <<>> -> ++ NewShaper = case Shaper of ++ none -> none; ++ _ -> ++ shaper:update(Shaper, size(Data)) ++ end, ++ ok = TargetSockMod:send(TargetSocket, Data); ++ true -> ++ NewShaper = Shaper ++ end, ++ transfer_data(SockOpts, TargetSockOpts, NewShaper); ++ {error, _} -> ++ TargetSockMod:shutdown(TargetSocket, read_write) ++ end. ++ ++get_socket(PID) -> ++ PID ! {get_socket, self()}, ++ receive ++ {_SockMod, _Socket} = SockOpts -> ++ SockOpts ++ end. ++ ++%% If any argument is a jid record, convert it to normalized string form... ++activate(#jid{} = Initiator, Target, SessionID) -> ++ NormalizedInitiator = jlib:jid_to_string(jlib:make_jid(jlib:jid_tolower(Initiator))), ++ activate(NormalizedInitiator, Target, SessionID); ++activate(Initiator, #jid{} = Target, SessionID) -> ++ NormalizedTarget = jlib:jid_to_string(jlib:make_jid(jlib:jid_tolower(Target))), ++ activate(Initiator, NormalizedTarget, SessionID); ++%% ...and get on with the activation. ++activate(Initiator, Target, SessionID) -> ++ Cookie = sha:sha(SessionID ++ Initiator ++ Target), ++ F = fun() -> ++ case mnesia:read({proxy65_connection, Cookie}) of ++ [#proxy65_connection{firstpid = FirstPID, ++ secondpid = SecondPID}] ++ when is_pid(FirstPID), is_pid(SecondPID) -> ++ mnesia:delete({proxy65_connection, Cookie}), ++ {FirstPID, SecondPID}; ++ _ -> ++ error ++ end ++ end, ++ case mnesia:transaction(F) of ++ {atomic, {FirstPID, SecondPID}} -> ++ FirstSocket = get_socket(FirstPID), ++ SecondSocket = get_socket(SecondPID), ++ FirstPID ! {activate, SecondSocket, Initiator, Target}, ++ SecondPID ! {activate, FirstSocket, Initiator, Target}, ++ ok; ++ Error -> ++ ?ERROR_MSG("Proxy activation failed: ~p", [Error]), ++ error ++ end. diff --git a/net-im/ejabberd/files/ejabberd-1.1.2-statsdx-web.patch b/net-im/ejabberd/files/ejabberd-1.1.2-statsdx-web.patch new file mode 100644 index 00000000..2182fb04 --- /dev/null +++ b/net-im/ejabberd/files/ejabberd-1.1.2-statsdx-web.patch @@ -0,0 +1,318 @@ +--- ejabberd-1.1.1/src/web/ejabberd_web_admin.erl 2006-04-03 16:14:35.000000000 +0200 ++++ ejabberd-1.1.1-r1/src/web/ejabberd_web_admin.erl 2006-06-23 09:32:54.000000000 +0200 +@@ -905,7 +905,10 @@ + path = ["stats"], + q = Query, + lang = Lang} = Request) -> +- Res = get_stats(Host, Lang), ++ Res = case whereis(ejabberd_mod_statsdx) of ++ undefined -> get_stats(Host, Lang); ++ _ -> get_statsdx(Host, Lang) ++ end, + make_xhtml([?XCT("h1", "Statistics")] ++ Res, Host, Lang); + + process_admin(Host, +@@ -1397,6 +1400,165 @@ + ])]. + + ++get_statsdx(global, Lang) -> ++ [ ++ ?XC("h3", "Accounts"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "registeredusers") ++ ]) ++ ]), ++ ?XC("h3", "Roster"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "totalrosteritems"), ++ do_stat(global, Lang, "meanitemsinroster") ++ ]) ++ ]), ++ ?XC("h3", "Users"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "authusers"), ++ do_stat(global, Lang, "onlineusers"), ++ do_stat(global, Lang, "offlinemsg"), ++ do_stat(global, Lang, "vcards") ++ ]) ++ ]), ++ ?XC("h3", "MUC"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "totalmucrooms"), ++ do_stat(global, Lang, "permmucrooms"), ++ do_stat(global, Lang, "regmucrooms") ++ ]) ++ ]), ++ ?XC("h3", "Pub/Sub"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "regpubsubnodes") ++ ]) ++ ]), ++ ?XC("h3", "IRC"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "ircconns") ++ ]) ++ ]), ++ ?XC("h3", "Ratios"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ ]) ++ ]), ++ ?XC("h3", "Sessions: " ++ get_stat_n("client")), ++ ?XAE("table", [], ++ [?XE("tbody", ++ do_stat_table(global, Lang, "client", server) ++ ) ++ ]), ++ ?XC("h3", "Sessions: " ++ get_stat_n("os")), ++ ?XAE("table", [], ++ [?XE("tbody", ++ do_stat_table(global, Lang, "os", server) ++ ) ++ ]), ++ ?XC("h3", "Sessions: " ++ get_stat_n("client") ++ "/" ++ get_stat_n("os")), ++ ?XAE("table", [], ++ [?XE("tbody", ++ do_stat_table(global, Lang, "client_os", server) ++ ) ++ ]), ++ ?XC("h3", "Sessions: " ++ get_stat_n("languages")), ++ ?XAE("table", [], ++ [?XE("tbody", ++ do_stat_table(global, Lang, "languages", server) ++ ) ++ ]) ++ ]; ++ ++get_statsdx(Host, Lang) -> ++ [ ++ ?XC("h2", Host), ++ ?XC("h3", "Accounts"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "registeredusers", Host) ++ ]) ++ ]), ++ ?XC("h3", "Roster"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "totalrosteritems", Host), ++ do_stat(global, Lang, "meanitemsinroster", Host) ++ ]) ++ ]), ++ ?XC("h3", "Users"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "authusers", Host), ++ do_stat(global, Lang, "onlineusers", Host), ++ do_stat(global, Lang, "offlinemsg", Host), ++ do_stat(global, Lang, "vcards", Host) ++ ]) ++ ]), ++ ?XC("h3", "Connections"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "s2sconnections", Host) ++ ]) ++ ]), ++ ?XC("h3", "MUC"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "totalmucrooms", Host), ++ do_stat(global, Lang, "permmucrooms", Host), ++ do_stat(global, Lang, "regmucrooms", Host) ++ ]) ++ ]), ++ ?XC("h3", "IRC"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "ircconns", Host) ++ ]) ++ ]), ++ %?XC("h3", "Pub/Sub"), ++ %?XAE("table", [], ++ % [?XE("tbody", [ ++ % do_stat(global, Lang, "regpubsubnodes", Host) ++ % ]) ++ %]), ++ ?XC("h3", "Ratios"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ ]) ++ ]), ++ ?XC("h3", "Sessions: " ++ get_stat_n("client")), ++ ?XAE("table", [], ++ [?XE("tbody", ++ do_stat_table(global, Lang, "client", Host) ++ ) ++ ]), ++ ?XC("h3", "Sessions: " ++ get_stat_n("os")), ++ ?XAE("table", [], ++ [?XE("tbody", ++ do_stat_table(global, Lang, "os", Host) ++ ) ++ ]), ++ ?XC("h3", "Sessions: " ++ get_stat_n("client") ++ "/" ++ get_stat_n("os")), ++ ?XAE("table", [], ++ [?XE("tbody", ++ do_stat_table(global, Lang, "client_os", Host) ++ ) ++ ]), ++ ?XC("h3", "Sessions: " ++ get_stat_n("languages")), ++ ?XAE("table", [], ++ [?XE("tbody", ++ do_stat_table(global, Lang, "languages", Host) ++ ) ++ ]) ++ ]. ++ ++ ++ + list_online_users(Host, _Lang) -> + Users = [{S, U} || {U, S, R} <- ejabberd_sm:get_vh_session_list(Host)], + SUsers = lists:usort(Users), +@@ -2015,6 +2177,12 @@ + ]; + + get_node(global, Node, ["stats"], Query, Lang) -> ++ Res = case whereis(ejabberd_mod_statsdx) of ++ undefined -> get_node(global, Node, ["statslight"], Query, Lang); ++ _ -> get_node(global, Node, ["statsdx"], Query, Lang) ++ end; ++ ++get_node(global, Node, ["statslight"], Query, Lang) -> + UpTime = rpc:call(Node, erlang, statistics, [wall_clock]), + UpTimeS = io_lib:format("~.3f", [element(1, UpTime)/1000]), + CPUTime = rpc:call(Node, erlang, statistics, [runtime]), +@@ -2089,9 +2257,124 @@ + ?XCT("h3", "Script check"), ?C(atom_to_list(Check))]) + ]; + ++get_node(global, Node, ["statsdx"], Query, Lang) -> ++ TransactionsCommited = ++ rpc:call(Node, mnesia, system_info, [transaction_commits]), ++ TransactionsAborted = ++ rpc:call(Node, mnesia, system_info, [transaction_failures]), ++ TransactionsRestarted = ++ rpc:call(Node, mnesia, system_info, [transaction_restarts]), ++ TransactionsLogged = ++ rpc:call(Node, mnesia, system_info, [transaction_log_writes]), ++ ++ [?XC("h1", io_lib:format(?T("~p statistics"), [Node])), ++ ?XC("h3", "Connections"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(global, Lang, "authusers"), ++ do_stat(Node, Lang, "httppollusers"), ++ do_stat(Node, Lang, "s2sconnections"), ++ do_stat(Node, Lang, "s2sservers") ++ ]) ++ ]), ++ ?XC("h3", "Erlang"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(Node, Lang, "operatingsystem"), ++ do_stat(Node, Lang, "erlangmachine"), ++ do_stat(Node, Lang, "erlangmachinetarget"), ++ do_stat(Node, Lang, "maxprocallowed"), ++ do_stat(Node, Lang, "procqueue"), ++ do_stat(Node, Lang, "totalerlproc") ++ ]) ++ ]), ++ ?XC("h3", "Times"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(Node, Lang, "uptime"), ++ do_stat(Node, Lang, "uptimehuman"), ++ do_stat(Node, Lang, "lastrestart"), ++ do_stat(Node, Lang, "cputime") ++ ]) ++ ]), ++ ?XC("h3", "CPU"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ do_stat(Node, Lang, "cpu_avg1"), ++ do_stat(Node, Lang, "cpu_avg5"), ++ do_stat(Node, Lang, "cpu_avg15"), ++ do_stat(Node, Lang, "cpu_nprocs")%, ++ %do_stat(Node, Lang, "cpu_util_user"), ++ %do_stat(Node, Lang, "cpu_nice_user"), ++ %do_stat(Node, Lang, "cpu_kernel"), ++ %do_stat(Node, Lang, "cpu_idle"), ++ %do_stat(Node, Lang, "cpu_wait") ++ ]) ++ ]), ++ %?XC("h3", "RAM"), ++ %?XAE("table", [], ++ % [?XE("tbody", [ ++ %do_stat(Node, Lang, "memsup_system"), ++ %do_stat(Node, Lang, "memsup_free"), ++ %do_stat(Node, Lang, "reductions") ++ % ]) ++ % ]), ++ ?XC("h3", "Database"), ++ ?XAE("table", [], ++ [?XE("tbody", [ ++ ?XE("tr", [?XCT("td", "Transactions commited"), ++ ?XAC("td", [{"class", "alignright"}], ++ integer_to_list(TransactionsCommited))]), ++ ?XE("tr", [?XCT("td", "Transactions aborted"), ++ ?XAC("td", [{"class", "alignright"}], ++ integer_to_list(TransactionsAborted))]), ++ ?XE("tr", [?XCT("td", "Transactions restarted"), ++ ?XAC("td", [{"class", "alignright"}], ++ integer_to_list(TransactionsRestarted))]), ++ ?XE("tr", [?XCT("td", "Transactions logged"), ++ ?XAC("td", [{"class", "alignright"}], ++ integer_to_list(TransactionsLogged))]) ++ ]) ++ ])]; ++ + get_node(Host, Node, NPath, Query, Lang) -> + [?XCT("h1", "Not Found")]. + ++do_table_element(Lang, L, N) -> ++ ?XE("tr", [ ++ ?XCT("td", L), ++ ?XAC("td", [{"class", "alignright"}], ++ N) ++ ]). ++ ++do_stat_table(global, Lang, Stat, Host) -> ++ Os = mod_statsdx:get(global, [Stat, Host]), ++ lists:map( ++ fun({L, N}) -> ++ do_table_element(Lang, L, io_lib:format("~p", [N])) ++ end, ++ Os ++ ). ++ ++do_stat(Node, Lang, Stat) -> ++ ?XE("tr", [ ++ ?XCT("td", get_stat_n(Stat)), ++ ?XAC("td", [{"class", "alignright"}], ++ get_stat_v(Node, [Stat]))]). ++ ++do_stat(Node, Lang, Stat, Host) -> ++ %[Res] = get_stat_v(Node, [Stat, Host]), ++ %do_table_element(Lang, get_stat_n(Stat), Res). ++ do_table_element(Lang, get_stat_n(Stat), get_stat_v(Node, [Stat, Host])). ++ ++% Get a stat name ++get_stat_n(Stat) -> ++ mod_statsdx:get(foo, [Stat, title]). ++% Get a stat value ++get_stat_v(Node, Stat) -> get_stat_v2(mod_statsdx:get(Node, Stat)). ++get_stat_v2(Value) when is_list(Value) -> Value; ++get_stat_v2(Value) when is_float(Value) -> io_lib:format("~.4f", [Value]); ++get_stat_v2(Value) -> io_lib:format("~p", [Value]). + + node_parse_query(Node, Query) -> + case lists:keysearch("restart", 1, Query) of diff --git a/net-im/ejabberd/files/ejabberd-1.1.2-statsdx.patch b/net-im/ejabberd/files/ejabberd-1.1.2-statsdx.patch new file mode 100644 index 00000000..38383542 --- /dev/null +++ b/net-im/ejabberd/files/ejabberd-1.1.2-statsdx.patch @@ -0,0 +1,742 @@ +diff -Naur ejabberd-1.1.1/src/mod_statsdx.erl ejabberd-1.1.1-r1/src/mod_statsdx.erl +--- ejabberd-1.1.1/src/mod_statsdx.erl 1970-01-01 01:00:00.000000000 +0100 ++++ ejabberd-1.1.1-r1/src/mod_statsdx.erl 2006-05-12 23:14:17.000000000 +0200 +@@ -0,0 +1,738 @@ ++%%%---------------------------------------------------------------------- ++%%% File : mod_statsdx.erl ++%%% Author : Badlop <badlop@ono.com> ++%%% Purpose : Calculates and gathers statistics actively ++%%% Created : ++%%% Id : 0.2.3 ++%%%---------------------------------------------------------------------- ++ ++%%% INSTALL: ++%%% 1 Copy this file to ejabberd/src/mod_statsdx.erl ++%%% 2 Recompile ejabberd ++%%% 3 Add to ejabberd.cfg, 'modules' section the basic configuration: ++%%% {mod_statsdx, []}, ++ ++%%% CONFIGURE: ++%%% hooks: Set to 'false' to remove hooks and related statistics if you don't need them (default: true) ++ ++%%% EXAMPLE CONFIGURATION: ++%%% {mod_statsdx, [{hooks, false}]}, ++ ++%%% FEATURE REQUESTS: ++%%% - fix the problem with plain/ssl/tlsusers, it crashes ejabberd ++%%% - traffic: send bytes per second, received bps ++%%% - connections to a transport ++%%% - traffic: send presence per second, received mps ++%%% - Number of SASL c2s connections ++%%% - improve to work in distributed server ++ ++-module(mod_statsdx). ++-author(''). ++-vsn(''). ++ ++-behaviour(gen_mod). ++ ++-export([start/2, loop/0, stop/1, get/2, ++ remove_user/2, user_send_packet/3, user_receive_packet/4, ++ user_login/1, user_logout/4]). ++ ++-include("ejabberd.hrl"). ++-include("jlib.hrl"). ++-include("mod_roster.hrl"). ++ ++-define(PROCNAME, ejabberd_mod_statsdx). ++-define(T(Text), translate:translate("Lang", Text)). ++ ++%% ------------------- ++%% Module control ++%% ------------------- ++ ++start(Host, Opts) -> ++ Hooks = gen_mod:get_opt(hooks, Opts, true), ++ % Default value for the counters ++ CD = case Hooks of ++ true -> 0; ++ false -> "disabled" ++ end, ++ case whereis(?PROCNAME) of ++ undefined -> ++ application:start(os_mon), ++ ets:new(stats, [named_table, public]), ++ ets:insert(stats, {{user_login, server}, CD}), ++ ets:insert(stats, {{user_logout, server}, CD}), ++ ets:insert(stats, {{remove_user, server}, CD}), ++ lists:foreach( ++ fun(E) -> ets:insert(stats, {{client, server, E}, CD}) end, ++ list_elem(clients, id) ++ ), ++ lists:foreach( ++ fun(E) -> ets:insert(stats, {{os, server, E}, CD}) end, ++ list_elem(oss, id) ++ ), ++ register(?PROCNAME, spawn(?MODULE, loop, [])); ++ _ -> ++ ok ++ end, ++ ets:insert(stats, {{user_login, Host}, CD}), ++ ets:insert(stats, {{user_logout, Host}, CD}), ++ ets:insert(stats, {{remove_user, Host}, CD}), ++ ets:insert(stats, {{send, Host, iq, in}, CD}), ++ ets:insert(stats, {{send, Host, iq, out}, CD}), ++ ets:insert(stats, {{send, Host, message, in}, CD}), ++ ets:insert(stats, {{send, Host, message, out}, CD}), ++ ets:insert(stats, {{send, Host, presence, in}, CD}), ++ ets:insert(stats, {{send, Host, presence, out}, CD}), ++ ets:insert(stats, {{recv, Host, iq, in}, CD}), ++ ets:insert(stats, {{recv, Host, iq, out}, CD}), ++ ets:insert(stats, {{recv, Host, message, in}, CD}), ++ ets:insert(stats, {{recv, Host, message, out}, CD}), ++ ets:insert(stats, {{recv, Host, presence, in}, CD}), ++ ets:insert(stats, {{recv, Host, presence, out}, CD}), ++ lists:foreach( ++ fun(E) -> ets:insert(stats, {{client, Host, E}, CD}) end, ++ list_elem(clients, id) ++ ), ++ lists:foreach( ++ fun(E) -> ets:insert(stats, {{os, Host, E}, CD}) end, ++ list_elem(oss, id) ++ ), ++ case Hooks of ++ true -> ++ ejabberd_hooks:add(user_send_packet, Host, ?MODULE, user_send_packet, 90), ++ ejabberd_hooks:add(user_receive_packet, Host, ?MODULE, user_receive_packet, 90), ++ ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 90), ++ ejabberd_hooks:add(user_available_hook, Host, ?MODULE, user_login, 90), ++ ejabberd_hooks:add(unset_presence_hook, Host, ?MODULE, user_logout, 90); ++ false -> ++ ok ++ end. ++ ++loop() -> ++ receive ++ stop -> ok ++ end. ++ ++stop(Host) -> ++ ejabberd_hooks:delete(user_send_packet, Host, ?MODULE, user_send_packet, 60), ++ ejabberd_hooks:delete(user_receive_packet, Host, ?MODULE, user_receive_packet, 60), ++ ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 60), ++ ets:delete(stats), ++ case whereis(?PROCNAME) of ++ undefined -> ok; ++ _ -> ++ ?PROCNAME ! stop ++ end. ++ ++ ++remove_user(_User, Server) -> ++ ets:update_counter(stats, {remove_user, Server}, 1), ++ ets:update_counter(stats, {remove_user, server}, 1). ++ ++user_send_packet(FromJID, ToJID, NewEl) -> ++ Host = FromJID#jid.lserver, ++ HostTo = ToJID#jid.lserver, ++ {xmlelement, Type, _, _} = NewEl, ++ Type2 = case Type of ++ "iq" -> iq; ++ "message" -> message; ++ "presence" -> presence ++ end, ++ Dest = case is_host(HostTo, Host) of ++ true -> in; ++ false -> out ++ end, ++ ets:update_counter(stats, {send, Host, Type2, Dest}, 1), ++ ++ % Registrarse para tramitar Host/mod_stats2file ++ case list_to_atom(ToJID#jid.lresource) of ++ ?MODULE -> received_response(FromJID, ToJID, NewEl); ++ _ -> ok ++ end. ++ ++user_receive_packet(_JID, From, To, FixedPacket) -> ++ HostFrom = From#jid.lserver, ++ Host = To#jid.lserver, ++ {xmlelement, Type, _, _} = FixedPacket, ++ Type2 = case Type of ++ "iq" -> iq; ++ "message" -> message; ++ "presence" -> presence ++ end, ++ Dest = case is_host(HostFrom, Host) of ++ true -> in; ++ false -> out ++ end, ++ ets:update_counter(stats, {recv, Host, Type2, Dest}, 1). ++ ++ ++%% ------------------- ++%% get(* ++%% ------------------- ++ ++%gett(Arg) -> get(node(), [Arg, title]). ++getl(Args) -> get(node(), [Args]). ++getl(Args, Host) -> get(node(), [Args, Host]). ++ ++%get(_Node, ["", title]) -> ""; ++ ++get(global, A) -> get(node(), A); ++ ++get(_, [{"reductions", _}, title]) -> "Reductions (per minute)"; ++get(_, [{"reductions", I}]) -> calc_avg(element(2, statistics(reductions)), I); %+++ ++ ++get(_, ["cpu_avg1", title]) -> "Average system load (1 min)"; ++get(N, ["cpu_avg1"]) -> rpc:call(N, cpu_sup, avg1, [])/256; ++get(_, ["cpu_avg5", title]) -> "Average system load (5 min)"; ++get(N, ["cpu_avg5"]) -> rpc:call(N, cpu_sup, avg1, [])/256; ++get(_, ["cpu_avg15", title]) -> "Average system load (15 min)"; ++get(N, ["cpu_avg15"]) -> rpc:call(N, cpu_sup, avg15, [])/256; ++get(_, ["cpu_nprocs", title]) -> "Number of UNIX processes running on this machine"; ++get(N, ["cpu_nprocs"]) -> rpc:call(N, cpu_sup, nprocs, []); ++get(_, ["cpu_util", title]) -> "CPU utilization"; ++get(N, ["cpu_util"]) -> rpc:call(N, cpu_sup, util, []); ++ ++get(_, [{"cpu_util_user", _}, title]) -> "CPU utilization - user"; ++get(_, [{"cpu_util_nice_user", _}, title]) -> "CPU utilization - nice_user"; ++get(_, [{"cpu_util_kernel", _}, title]) -> "CPU utilization - kernel"; ++get(_, [{"cpu_util_wait", _}, title]) -> "CPU utilization - wait"; ++get(_, [{"cpu_util_idle", _}, title]) -> "CPU utilization - idle"; ++get(_, [{"cpu_util_user", U}]) -> [{user, Us}, _, _] = element(2, U), Us; ++get(_, [{"cpu_util_nice_user", U}]) -> [_, {nice_user, NU}, _] = element(2, U), NU; ++get(_, [{"cpu_util_kernel", U}]) -> [_, _, {kernel, K}] = element(2, U), K; ++get(_, [{"cpu_util_wait", U}]) -> ++ case element(3, U) of ++ [{wait, W}, {idle, _}] -> W; % Solaris ++ [{idle, _}] -> 0 ++ end; ++get(_, [{"cpu_util_idle", U}]) -> ++ case element(3, U) of ++ [{wait, _}, {idle, I}] -> I; % Solaris ++ [{idle, I}] -> I ++ end; ++ ++get(_, [{"client", Id}, title]) -> atom_to_list(Id); ++get(_, [{"client", Id}, Host]) -> [{_, C}] = ets:lookup(stats, {client, Host, Id}), C; ++get(_, ["client", title]) -> "Client"; ++get(N, ["client", Host]) -> ++ lists:map( ++ fun(Id) -> ++ [Id_string] = io_lib:format("~p", [Id]), ++ {Id_string, get(N, [{"client", Id}, Host])} ++ end, ++ lists:usort(list_elem(clients, id)) ++ ); ++ ++get(_, [{"os", Id}, title]) -> atom_to_list(Id); ++get(_, [{"os", Id}, list]) -> lists:usort(list_elem(oss, Id)); ++get(_, [{"os", Id}, Host]) -> [{_, C}] = ets:lookup(stats, {os, Host, Id}), C; ++get(_, ["os", title]) -> "Operating System"; ++get(N, ["os", Host]) -> ++ lists:map( ++ fun(Id) -> ++ [Id_string] = io_lib:format("~p", [Id]), ++ {Id_string, get(N, [{"os", Id}, Host])} ++ end, ++ lists:usort(list_elem(oss, id)) ++ ); ++ ++get(_, [{"memsup_system", _}, title]) -> "Memory physical (bytes)"; ++get(_, [{"memsup_system", M}]) -> [_, _, {system_total_memory, R}] = M, R; ++get(_, [{"memsup_free", _}, title]) -> "Memory free (bytes)"; ++get(_, [{"memsup_free", M}]) -> [_, {free_memory, R}, _] = M, R; ++ ++get(_, [{"user_login", _}, title]) -> "Logins (per minute)"; ++get(_, [{"user_login", I}, Host]) -> get_stat({user_login, Host}, I); ++get(_, [{"user_logout", _}, title]) -> "Logouts (per minute)"; ++get(_, [{"user_logout", I}, Host]) -> get_stat({user_logout, Host}, I); ++get(_, [{"remove_user", _}, title]) -> "Accounts deleted (per minute)"; ++get(_, [{"remove_user", I}, Host]) -> get_stat({remove_user, Host}, I); ++get(_, [{Table, Type, Dest, _}, title]) -> filename:flatten([Table, Type, Dest]); ++get(_, [{Table, Type, Dest, I}, Host]) -> get_stat({Table, Host, Type, Dest}, I); ++ ++get(_, ["localtime", title]) -> "Local time"; ++get(N, ["localtime"]) -> ++ localtime_to_string(rpc:call(N, erlang, localtime, [])); ++ ++get(_, ["vhost", title]) -> "Virtual host"; ++get(_, ["vhost", Host]) -> Host; ++ ++get(_, ["totalerlproc", title]) -> "Total Erlang processes running"; ++get(N, ["totalerlproc"]) -> rpc:call(N, erlang, system_info, [process_count]); ++get(_, ["operatingsystem", title]) -> "Operating System"; ++get(N, ["operatingsystem"]) -> {rpc:call(N, os, type, []), rpc:call(N, os, version, [])}; ++get(_, ["erlangmachine", title]) -> "Erlang machine"; ++get(N, ["erlangmachine"]) -> rpc:call(N, erlang, system_info, [system_version]); ++get(_, ["erlangmachinetarget", title]) -> "Erlang machine target"; ++get(N, ["erlangmachinetarget"]) -> rpc:call(N, erlang, system_info, [system_architecture]); ++get(_, ["maxprocallowed", title]) -> "Maximum processes allowed"; ++get(N, ["maxprocallowed"]) -> rpc:call(N, erlang, system_info, [process_limit]); ++get(_, ["procqueue", title]) -> "Number of processes on the running queue"; ++get(N, ["procqueue"]) -> rpc:call(N, erlang, statistics, [run_queue]); ++get(_, ["uptimehuman", title]) -> "Uptime"; ++get(N, ["uptimehuman"]) -> ++ io_lib:format("~w days ~w hours ~w minutes ~p seconds", ms_to_time(get(N, ["uptime"]))); ++get(_, ["lastrestart", title]) -> "Last restart"; ++get(N, ["lastrestart"]) -> ++ Now = calendar:datetime_to_gregorian_seconds(rpc:call(N, erlang, localtime, [])), ++ UptimeMS = get(N, ["uptime"]), ++ Last_restartS = trunc(Now - (UptimeMS/1000)), ++ Last_restart = calendar:gregorian_seconds_to_datetime(Last_restartS), ++ localtime_to_string(Last_restart); ++ ++get(_, ["plainusers", title]) -> "Plain users"; ++get(_, ["plainusers"]) -> {R, _, _} = get_connectiontype(), R; ++get(_, ["tlsusers", title]) -> "TLS users"; ++get(_, ["tlsusers"]) -> {_, R, _} = get_connectiontype(), R; ++get(_, ["sslusers", title]) -> "SSL users"; ++get(_, ["sslusers"]) -> {_, _, R} = get_connectiontype(), R; ++get(_, ["registeredusers", title]) -> "Registered users"; ++get(N, ["registeredusers"]) -> rpc:call(N, mnesia, table_info, [passwd, size]); ++get(_, ["registeredusers", Host]) -> length(ejabberd_auth:get_vh_registered_users(Host)); ++get(_, ["authusers", title]) -> "Authenticated users"; ++get(N, ["authusers"]) -> rpc:call(N, mnesia, table_info, [session, size]); ++get(_, ["authusers", Host]) -> get_authusers(Host); ++get(_, ["onlineusers", title]) -> "Online users"; ++get(N, ["onlineusers"]) -> rpc:call(N, mnesia, table_info, [presence, size]); ++get(_, ["onlineusers", Host]) -> length(ejabberd_sm:get_vh_session_list(Host)); ++get(_, ["httppollusers", title]) -> "HTTP-Poll users (aprox)"; ++get(N, ["httppollusers"]) -> rpc:call(N, mnesia, table_info, [http_poll, size]); ++ ++get(_, ["s2sconnections", title]) -> "Outgoing S2S connections"; ++get(_, ["s2sconnections"]) -> length(get_S2SConns()); ++get(_, ["s2sconnections", Host]) -> get_s2sconnections(Host); ++get(_, ["s2sservers", title]) -> "Outgoing S2S servers"; ++get(_, ["s2sservers"]) -> length(lists:usort([element(2, C) || C <- get_S2SConns()])); ++ ++get(_, ["offlinemsg", title]) -> "Offline messages"; ++get(N, ["offlinemsg"]) -> rpc:call(N, mnesia, table_info, [offline_msg, size]); ++get(_, ["offlinemsg", Host]) -> get_offlinemsg(Host); ++get(_, ["totalrosteritems", title]) -> "Total roster items"; ++get(N, ["totalrosteritems"]) -> rpc:call(N, mnesia, table_info, [roster, size]); ++get(_, ["totalrosteritems", Host]) -> get_totalrosteritems(Host); ++ ++get(_, ["meanitemsinroster", title]) -> "Mean items in roster"; ++get(_, ["meanitemsinroster"]) -> get_meanitemsinroster(); ++get(_, ["meanitemsinroster", Host]) -> get_meanitemsinroster(Host); ++ ++get(_, ["totalmucrooms", title]) -> "Total MUC rooms"; ++get(_, ["totalmucrooms"]) -> ets:info(muc_online_room, size); ++get(_, ["totalmucrooms", Host]) -> get_totalmucrooms(Host); ++get(_, ["permmucrooms", title]) -> "Permanent MUC rooms"; ++get(N, ["permmucrooms"]) -> rpc:call(N, mnesia, table_info, [muc_room, size]); ++get(_, ["permmucrooms", Host]) -> get_permmucrooms(Host); ++get(_, ["regmucrooms", title]) -> "Users registered at MUC service"; ++get(N, ["regmucrooms"]) -> rpc:call(N, mnesia, table_info, [muc_registered, size]); ++get(_, ["regmucrooms", Host]) -> get_regmucrooms(Host); ++get(_, ["regpubsubnodes", title]) -> "Registered nodes at Pub/Sub"; ++get(N, ["regpubsubnodes"]) -> rpc:call(N, mnesia, table_info, [pubsub_node, size]); ++get(_, ["vcards", title]) -> "Total vCards published"; ++get(N, ["vcards"]) -> rpc:call(N, mnesia, table_info, [vcard, size]); ++get(_, ["vcards", Host]) -> get_vcards(Host); ++ ++get(_, ["ircconns", title]) -> "IRC connections"; ++get(_, ["ircconns"]) -> ets:info(irc_connection, size); ++get(_, ["ircconns", Host]) -> get_irccons(Host); ++get(_, ["uptime", title]) -> "Uptime"; ++get(N, ["uptime"]) -> element(1, rpc:call(N, erlang, statistics, [wall_clock])); ++get(_, ["cputime", title]) -> "CPU Time"; ++get(N, ["cputime"]) -> element(1, rpc:call(N, erlang, statistics, [runtime])); ++ ++get(_, ["languages", title]) -> "Languages"; ++get(_, ["languages", Server]) -> get_languages(Server); ++ ++get(_, ["client_os", title]) -> "Client/OS"; ++get(_, ["client_os", Server]) -> get_client_os(Server); ++ ++get(N, A) -> ++ io:format(" ----- node: '~p', A: '~p'~n", [N, A]), ++ "666". ++ ++%% ------------------- ++%% get_* ++%% ------------------- ++ ++get_S2SConns() -> ejabberd_s2s:dirty_get_connections(). ++ ++get_tls_drv() -> ++ R = lists:filter( ++ fun(P) -> ++ case erlang:port_info(P, name) of ++ {name, "tls_drv"} -> true; ++ _ -> false ++ end ++ end, erlang:ports()), ++ length(R). ++ ++get_connections(Port) -> ++ R = lists:filter( ++ fun(P) -> ++ case inet:port(P) of ++ {ok, Port} -> true; ++ _ -> false ++ end ++ end, erlang:ports()), ++ length(R). ++ ++get_totalrosteritems(Host) -> ++ F = fun() -> ++ F2 = fun(R, {H, A}) -> ++ {_LUser, LServer, _LJID} = R#roster.usj, ++ A2 = case LServer of ++ H -> A+1; ++ _ -> A ++ end, ++ {H, A2} ++ end, ++ mnesia:foldl(F2, {Host, 0}, roster) ++ end, ++ {atomic, {Host, Res}} = mnesia:transaction(F), ++ Res. ++ ++% Copied from ejabberd_sm.erl ++-record(session, {sid, usr, us, priority}). ++ ++get_authusers(Host) -> ++ F = fun() -> ++ F2 = fun(R, {H, A}) -> ++ {_LUser, LServer, _LResource} = R#session.usr, ++ A2 = case LServer of ++ H -> A+1; ++ _ -> A ++ end, ++ {H, A2} ++ end, ++ mnesia:foldl(F2, {Host, 0}, session) ++ end, ++ {atomic, {Host, Res}} = mnesia:transaction(F), ++ Res. ++ ++-record(offline_msg, {us, timestamp, expire, from, to, packet}). ++ ++get_offlinemsg(Host) -> ++ F = fun() -> ++ F2 = fun(R, {H, A}) -> ++ {_LUser, LServer} = R#offline_msg.us, ++ A2 = case LServer of ++ H -> A+1; ++ _ -> A ++ end, ++ {H, A2} ++ end, ++ mnesia:foldl(F2, {Host, 0}, offline_msg) ++ end, ++ {atomic, {Host, Res}} = mnesia:transaction(F), ++ Res. ++ ++-record(vcard, {us, vcard}). ++ ++get_vcards(Host) -> ++ F = fun() -> ++ F2 = fun(R, {H, A}) -> ++ {_LUser, LServer} = R#vcard.us, ++ A2 = case LServer of ++ H -> A+1; ++ _ -> A ++ end, ++ {H, A2} ++ end, ++ mnesia:foldl(F2, {Host, 0}, vcard) ++ end, ++ {atomic, {Host, Res}} = mnesia:transaction(F), ++ Res. ++ ++-record(s2s, {fromto, pid, key}). ++ ++get_s2sconnections(Host) -> ++ F = fun() -> ++ F2 = fun(R, {H, A}) -> ++ {MyServer, _Server} = R#s2s.fromto, ++ A2 = case MyServer of ++ H -> A+1; ++ _ -> A ++ end, ++ {H, A2} ++ end, ++ mnesia:foldl(F2, {Host, 0}, s2s) ++ end, ++ {atomic, {Host, Res}} = mnesia:transaction(F), ++ Res. ++ ++-record(irc_connection, {jid_server_host, pid}). ++ ++get_irccons(Host) -> ++ F2 = fun(R, {H, A}) -> ++ {From, _Server, _Host} = R#irc_connection.jid_server_host, ++ A2 = case From#jid.lserver of ++ H -> A+1; ++ _ -> A ++ end, ++ {H, A2} ++ end, ++ {Host, Res} = ets:foldl(F2, {Host, 0}, irc_connection), ++ Res. ++ ++is_host(Host, Subhost) -> ++ Pos = string:len(Host)-string:len(Subhost)+1, ++ case string:rstr(Host, Subhost) of ++ Pos -> true; ++ _ -> false ++ end. ++ ++-record(muc_online_room, {name_host, pid}). ++ ++get_totalmucrooms(Host) -> ++ F2 = fun(R, {H, A}) -> ++ {_Name, MUCHost} = R#muc_online_room.name_host, ++ A2 = case is_host(MUCHost, H) of ++ true -> A+1; ++ false -> A ++ end, ++ {H, A2} ++ end, ++ {Host, Res} = ets:foldl(F2, {Host, 0}, muc_online_room), ++ Res. ++ ++-record(muc_room, {name_host, opts}). ++ ++get_permmucrooms(Host) -> ++ F = fun() -> ++ F2 = fun(R, {H, A}) -> ++ {_Name, MUCHost} = R#muc_room.name_host, ++ A2 = case is_host(MUCHost, H) of ++ true -> A+1; ++ false -> A ++ end, ++ {H, A2} ++ end, ++ mnesia:foldl(F2, {Host, 0}, muc_room) ++ end, ++ {atomic, {Host, Res}} = mnesia:transaction(F), ++ Res. ++ ++-record(muc_registered, {us_host, nick}). ++ ++get_regmucrooms(Host) -> ++ F = fun() -> ++ F2 = fun(R, {H, A}) -> ++ {_User, MUCHost} = R#muc_registered.us_host, ++ A2 = case is_host(MUCHost, H) of ++ true -> A+1; ++ false -> A ++ end, ++ {H, A2} ++ end, ++ mnesia:foldl(F2, {Host, 0}, muc_registered) ++ end, ++ {atomic, {Host, Res}} = mnesia:transaction(F), ++ Res. ++ ++get_stat(Stat, Ims) -> ++ Res = ets:lookup(stats, Stat), ++ ets:update_counter(stats, Stat, {2,1,0,0}), ++ [{_, C}] = Res, ++ calc_avg(C, Ims). ++ %C. ++ ++calc_avg(Count, TimeMS) -> ++ TimeMIN = TimeMS/(1000*60), ++ Count/TimeMIN. ++ ++%% ------------------- ++%% utilities ++%% ------------------- ++ ++get_connectiontype() -> ++ C2 = get_connections(5222) -1, ++ C3 = get_connections(5223) -1, ++ NUplain = C2 + C3 - get_tls_drv(), ++ NUtls = C2 - NUplain, ++ NUssl = C3, ++ {NUplain, NUtls, NUssl}. ++ ++ms_to_time(T) -> ++ DMS = 24*60*60*1000, ++ HMS = 60*60*1000, ++ MMS = 60*1000, ++ SMS = 1000, ++ D = trunc(T/DMS), ++ H = trunc((T - (D*DMS)) / HMS), ++ M = trunc((T - (D*DMS) - (H*HMS)) / MMS), ++ S = trunc((T - (D*DMS) - (H*HMS) - (M*MMS)) / SMS), ++ [D, H, M, S]. ++ ++ ++% Cuando un usuario conecta, pedirle iq:version a nombre de Host/mod_stats2file ++user_login(U) -> ++ User = U#jid.luser, ++ Host = U#jid.lserver, ++ Resource = U#jid.lresource, ++ ets:update_counter(stats, {user_login, server}, 1), ++ ets:update_counter(stats, {user_login, Host}, 1), ++ request_iqversion(User, Host, Resource). ++ ++% cuando un usuario desconecta, buscar en la tabla su JID/USR y quitarlo ++user_logout(User, Host, Resource, _Status) -> ++ ets:update_counter(stats, {user_logout, server}, 1), ++ ets:update_counter(stats, {user_logout, Host}, 1), ++ ++ JID = jlib:make_jid(User, Host, Resource), ++ case ets:lookup(stats, {session, JID}) of ++ [{_, Client_id, OS_id, Lang}] -> ++ ets:delete(stats, {session, JID}), ++ ets:update_counter(stats, {client, Host, Client_id}, -1), ++ ets:update_counter(stats, {client, server, Client_id}, -1), ++ ets:update_counter(stats, {os, Host, OS_id}, -1), ++ ets:update_counter(stats, {os, server, OS_id}, -1), ++ update_counter_create(stats, {client_os, Host, Client_id, OS_id}, -1), ++ update_counter_create(stats, {client_os, server, Client_id, OS_id}, -1), ++ update_counter_create(stats, {lang, Host, Lang}, -1), ++ update_counter_create(stats, {lang, server, Lang}, -1); ++ [] -> ++ ok ++ end. ++ ++request_iqversion(User, Host, Resource) -> ++ From = jlib:make_jid("", Host, atom_to_list(?MODULE)), ++ FromStr = jlib:jid_to_string(From), ++ To = jlib:make_jid(User, Host, Resource), ++ ToStr = jlib:jid_to_string(To), ++ Packet = {xmlelement,"iq", ++ [{"from",FromStr}, {"to",ToStr}, {"type","get"}, {"xml:lang","es"}], ++ [{xmlcdata,"\n"}, {xmlcdata," "}, {xmlelement, "query", [{"xmlns","jabber:iq:version"}], []}, {xmlcdata,"\n"}]}, ++ ejabberd_local:route(From, To, Packet). ++ ++% cuando el virtualJID recibe una respuesta iqversion, ++% almacenar su JID/USR + client + OS en una tabla ++received_response(From, _To, {xmlelement, "iq", Attrs, Elc}) -> ++ User = From#jid.luser, ++ Host = From#jid.lserver, ++ Resource = From#jid.lresource, ++ ++ "result" = xml:get_attr_s("type", Attrs), ++ Lang = case xml:get_attr_s("xml:lang", Attrs) of ++ [] -> "unknown"; ++ L -> L ++ end, ++ update_counter_create(stats, {lang, Host, Lang}, 1), ++ update_counter_create(stats, {lang, server, Lang}, 1), ++ ++ [El] = xml:remove_cdata(Elc), ++ {xmlelement, _, Attrs2, _Els2} = El, ++ ?NS_VERSION = xml:get_attr_s("xmlns", Attrs2), ++ ++ Client = get_tag_cdata_subtag(El, "name"), ++ %Version = get_tag_cdata_subtag(El, "version"), ++ OS = get_tag_cdata_subtag(El, "os"), ++ {Client_id, OS_id} = identify(Client, OS), ++ ++ ets:update_counter(stats, {client, Host, Client_id}, 1), ++ ets:update_counter(stats, {client, server, Client_id}, 1), ++ ets:update_counter(stats, {os, Host, OS_id}, 1), ++ ets:update_counter(stats, {os, server, OS_id}, 1), ++ update_counter_create(stats, {client_os, Host, Client_id, OS_id}, 1), ++ update_counter_create(stats, {client_os, server, Client_id, OS_id}, 1), ++ ++ JID = jlib:make_jid(User, Host, Resource), ++ ets:insert(stats, {{session, JID}, Client_id, OS_id, Lang}). ++ ++update_counter_create(Table, Element, C) -> ++ case ets:lookup(Table, Element) of ++ [] -> ets:insert(Table, {Element, 1}); ++ _ -> ets:update_counter(Table, Element, C) ++ end. ++ ++get_tag_cdata_subtag(E, T) -> ++ E2 = xml:get_subtag(E, T), ++ case E2 of ++ false -> "unknown"; ++ _ -> xml:get_tag_cdata(E2) ++ end. ++ ++list_elem(Type, id) -> ++ {_, Ids} = lists:unzip(list_elem(Type, full)), ++ Ids; ++list_elem(clients, full) -> ++ [ ++ {"gaim", gaim}, ++ {"Gajim", gajim}, ++ {"Tkabber", tkabber}, ++ {"Psi", psi}, ++ {"Pandion", pandion}, ++ {"Kopete", kopete}, ++ {"Exodus", exodus}, ++ {"libgaim", libgaim}, ++ {"JBother", jbother}, ++ {"iChat", ichat}, ++ {"Miranda", miranda}, ++ {"Trillian", trillian}, ++ {"JAJC", jajc}, ++ {"Coccinella", coccinella}, ++ {"Gabber", gabber}, ++ {"BitlBee", bitlbee}, ++ {"jabber.el", jabberel}, ++ {"unknown", unknown} ++ ]; ++list_elem(oss, full) -> ++ [ ++ {"Linux", linux}, ++ {"Win", windows}, ++ {"Gentoo", linux}, ++ {"Mac", mac}, ++ {"BSD", bsd}, ++ {"SunOS", linux}, ++ {"Ubuntu", linux}, ++ {"unknown", unknown} ++ ]. ++ ++identify(Client, OS) -> ++ Res = {try_match(Client, list_elem(clients, full)), try_match(OS, list_elem(oss, full))}, ++ case Res of ++ {libgaim, mac} -> {adium, mac}; ++ _ -> Res ++ end. ++ ++try_match(_E, []) -> unknown; ++try_match(E, [{Str, Id} | L]) -> ++ case string:str(E, Str) of ++ 0 -> try_match(E, L); ++ _ -> Id ++ end. ++ ++get_client_os(Server) -> ++ CO1 = ets:match(stats, {{client_os, Server, '$1', '$2'}, '$3'}), ++ CO2 = lists:map( ++ fun([Cl, Os, A3]) -> ++ {lists:flatten([atom_to_list(Cl), "/", atom_to_list(Os)]), A3} ++ end, ++ CO1 ++ ), ++ lists:keysort(1, CO2). ++ ++get_languages(Server) -> ++ L1 = ets:match(stats, {{lang, Server, '$1'}, '$2'}), ++ L2 = lists:map( ++ fun([La, C]) -> ++ {La, C} ++ end, ++ L1 ++ ), ++ lists:keysort(1, L2). ++ ++get_meanitemsinroster() -> ++ get_meanitemsinroster2(getl("totalrosteritems"), getl("registeredusers")). ++get_meanitemsinroster(Host) -> ++ get_meanitemsinroster2(getl("totalrosteritems", Host), getl("registeredusers", Host)). ++get_meanitemsinroster2(Items, Users) -> ++ case Users of ++ 0 -> 0; ++ _ -> Items/Users ++ end. ++ ++localtime_to_string({{Y, Mo, D},{H, Mi, S}}) -> ++ lists:concat([H, ":", Mi, ":", S, " ", D, "/", Mo, "/", Y]). ++ ++% cuando toque mostrar estadisticas ++%get_iqversion() -> ++ % contar en la tabla cuantos tienen cliente: *psi* ++ %buscar en la tabla iqversion ++ %ok. diff --git a/net-im/ejabberd/files/ejabberd-1.1.2.initd b/net-im/ejabberd/files/ejabberd-1.1.2.initd new file mode 100644 index 00000000..4291e39a --- /dev/null +++ b/net-im/ejabberd/files/ejabberd-1.1.2.initd @@ -0,0 +1,59 @@ +#!/sbin/runscript +# Copyright 1999-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/net-im/ejabberd/files/ejabberd-1.1.1.initd,v 1.1 2006/06/19 14:07:20 chainsaw Exp $ + +opts="${opts} reload" + +depend() { + use dns + need net + provide jabber-server +} + +checkconfig() { + if [ ! -e /etc/jabber/ejabberd.cfg ] ; then + eerror "You need an /etc/jabber/ejabberd.cfg file to run ejabberd" + return 1 + fi +} + +start() { + checkconfig || return 1 + ebegin "Starting eJabberd" + su jabber -c "HOME=/var/run/jabber /usr/bin/ejabberd -noshell -detached" + eend $? +} + +stop() { + ebegin "Stopping eJabberd" + if [ -z "$EJABBERD_NODE" ]; + then + EJABBERD_NODE="ejabberd@`hostname -s`" + fi + /usr/bin/ejabberdctl $EJABBERD_NODE stop + eend $? +} + +# Work around a bug in /sbin/runscript.sh - it won't run our custom +# restart() unless it finds these two strings in the file. +# svc_start svc_stop +restart() { + ebegin "Restarting eJabberd" + if [ -z "$EJABBERD_NODE" ]; + then + EJABBERD_NODE="ejabberd@`hostname -s`" + fi + /usr/bin/ejabberdctl $EJABBERD_NODE restart + eend $? +} + +reload() { + ebegin "Reloading eJabberd" + if [ -z "$EJABBERD_NODE" ]; + then + EJABBERD_NODE="ejabberd@`hostname -s`" + fi + /usr/bin/ejabberdctl $EJABBERD_NODE reopen-log + eend $? +} |