summaryrefslogtreecommitdiff
path: root/net-im
diff options
context:
space:
mode:
authorBertrand Jacquin <beber@meleeweb.net>2006-09-28 22:28:40 +0200
committerBertrand Jacquin <beber@meleeweb.net>2006-09-28 22:28:40 +0200
commite995f72dc459d8c977fb32e75751227e0aa2a2c5 (patch)
tree56fb93591a63546856db2e572ade0a5d661abc97 /net-im
parentejabberd: add patch from http://bugs.gentoo.org/show_bug.cgi?id=137724 and ht... (diff)
downloadportage-e995f72dc459d8c977fb32e75751227e0aa2a2c5.tar.xz
ejabberd: update patches for mod_presence
Diffstat (limited to 'net-im')
-rw-r--r--net-im/ejabberd/Manifest24
-rw-r--r--net-im/ejabberd/ejabberd-1.1.2-r1.ebuild3
-rw-r--r--net-im/ejabberd/files/mod_presence.diff633
3 files changed, 647 insertions, 13 deletions
diff --git a/net-im/ejabberd/Manifest b/net-im/ejabberd/Manifest
index 99f645d0..ac783f6d 100644
--- a/net-im/ejabberd/Manifest
+++ b/net-im/ejabberd/Manifest
@@ -10,18 +10,18 @@ AUX ejabberd-1.1.2-statsdx.patch 24201 RMD160 e04d36746649e435a68c32f2705a27fc91
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 ejabberd-1.1.2.initd 1298 RMD160 ec7b25205026521ec09f8595bbe6ae36c94bc55f SHA1 012122c9e930ec56257a625a4fd3bd28e140afd3 SHA256 69481e6f156e85c69038675283f818fe3fa92d0ab442aaf78831345969aa021a
+MD5 13c4ef3cee491a8529dc8866347f0636 files/ejabberd-1.1.2.initd 1298
+RMD160 ec7b25205026521ec09f8595bbe6ae36c94bc55f files/ejabberd-1.1.2.initd 1298
+SHA256 69481e6f156e85c69038675283f818fe3fa92d0ab442aaf78831345969aa021a files/ejabberd-1.1.2.initd 1298
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
SHA256 b46976ca86a43cb13ed71009a5fadf7a2ca231e51da83150cdff0d646fbed00f files/mod_archive.erl 29560
-AUX mod_presence.diff.gz 46392 RMD160 2cac587223b53a07c4b17cd49047e2e68ee8122e SHA1 bfff32599160dd3a6bc340743bd55fedca2a64ea SHA256 8c3e39fd87b77fb928f801eb4241cdbacc28c8891097a4cee8ea1c962f20f1b2
-MD5 13316805ef6031854a78272e9aeadd27 files/mod_presence.diff.gz 46392
-RMD160 2cac587223b53a07c4b17cd49047e2e68ee8122e files/mod_presence.diff.gz 46392
-SHA256 8c3e39fd87b77fb928f801eb4241cdbacc28c8891097a4cee8ea1c962f20f1b2 files/mod_presence.diff.gz 46392
+AUX mod_presence.diff 24484 RMD160 6b13d9029854cbf8f22e34722428e805385e4b35 SHA1 8583b61d5f3d3108a631505fc7db0b8c37453e91 SHA256 dd03c73b4b900a160c85abe8df64d27934a5d79126566e6347c727517776a0ad
+MD5 acd6e372c151a9df76d8a171a8653139 files/mod_presence.diff 24484
+RMD160 6b13d9029854cbf8f22e34722428e805385e4b35 files/mod_presence.diff 24484
+SHA256 dd03c73b4b900a160c85abe8df64d27934a5d79126566e6347c727517776a0ad files/mod_presence.diff 24484
DIST check_pam.diff.gz 3865 RMD160 86d6ff263d216c63662ef1078f947f9f7a6c1fce SHA1 756d258a27d145c53b0bac7bb2a333102604127b SHA256 c474adefeefd6e2d18fff531dc4c2f3c149ba003dbd606655656a95ca72ee62a
DIST ejabberd-1.1.1.tar.gz 803278 RMD160 b9c0b7ab3fe1f1b2dce52e1460bba04b313ea534 SHA1 4f23d787afe75c7c866decdff6f539195449776e SHA256 52a97275537073066bd352f5718954f6994b272d1efa51187e17edf0c9b11082
DIST ejabberd-1.1.2.tar.gz 836240 RMD160 e763752e6c5fb46c51b71e265ab2ceda6d043a0d SHA1 9e94bdbc10fee5b781405daf43a0b4abc4dee6c1 SHA256 029129a6bcb5d15dbccc5aa756f61c52692eb6882ec7aad0193aa940b6a20bb6
@@ -30,10 +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-r1.ebuild 5726 RMD160 2426f1d8488a7c685efffc470cd3c67e485d3850 SHA1 3f981158b85b92f2ca825dee38f92fa50b4b8dd2 SHA256 c8d73f7922ac2c672024b86bb6bb63c7b5416ece901390b2341ed2f06f58c14c
+MD5 1713684f7f7dbad5c06b18ffc7a06271 ejabberd-1.1.2-r1.ebuild 5726
+RMD160 2426f1d8488a7c685efffc470cd3c67e485d3850 ejabberd-1.1.2-r1.ebuild 5726
+SHA256 c8d73f7922ac2c672024b86bb6bb63c7b5416ece901390b2341ed2f06f58c14c ejabberd-1.1.2-r1.ebuild 5726
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
diff --git a/net-im/ejabberd/ejabberd-1.1.2-r1.ebuild b/net-im/ejabberd/ejabberd-1.1.2-r1.ebuild
index 85f7e1cb..25cb81b6 100644
--- a/net-im/ejabberd/ejabberd-1.1.2-r1.ebuild
+++ b/net-im/ejabberd/ejabberd-1.1.2-r1.ebuild
@@ -77,8 +77,9 @@ src_unpack() {
fi
if use mod_presence; then
- epatch ${WORKDIR}/mod_presence/mod_presence.diff
cp -r ${WORKDIR}/mod_presence/pixmaps .
+ cd ../..
+ epatch ${FILESDIR}/mod_presence.diff
fi
if use pam; then
diff --git a/net-im/ejabberd/files/mod_presence.diff b/net-im/ejabberd/files/mod_presence.diff
new file mode 100644
index 00000000..159cbbb5
--- /dev/null
+++ b/net-im/ejabberd/files/mod_presence.diff
@@ -0,0 +1,633 @@
+diff -ruN ejabberd-1.1.2.orig/src/Makefile.in ejabberd-1.1.2/src/Makefile.in
+--- ejabberd-1.1.2.orig/src/Makefile.in 2006-04-01 20:06:36.000000000 +0400
++++ ejabberd-1.1.2/src/Makefile.in 2006-09-25 19:14:28.000000000 +0400
+@@ -39,6 +39,7 @@
+ PRIVDIR = $(EJABBERDDIR)/priv
+ SODIR = $(PRIVDIR)/lib
+ MSGSDIR = $(PRIVDIR)/msgs
++PIXMAPSDIR = $(PRIVDIR)/pixmaps
+ LOGDIR = $(DESTDIR)@prefix@/var/log/ejabberd
+ ETCDIR = $(DESTDIR)@prefix@/etc/ejabberd
+
+@@ -81,6 +82,8 @@
+ install -m 644 *.so $(SODIR)
+ install -d $(MSGSDIR)
+ install -m 644 msgs/*.msg $(MSGSDIR)
++ install -d $(PIXMAPSDIR)
++ cp -r pixmaps/* $(PIXMAPSDIR)
+ install -d $(ETCDIR)
+ install -b -m 644 ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
+ install -d $(LOGDIR)
+diff -ruN ejabberd-1.1.2.orig/src/mod_presence.erl ejabberd-1.1.2/src/mod_presence.erl
+--- ejabberd-1.1.2.orig/src/mod_presence.erl 1970-01-01 03:00:00.000000000 +0300
++++ ejabberd-1.1.2/src/mod_presence.erl 2006-09-25 19:45:31.000000000 +0400
+@@ -0,0 +1,572 @@
++%%%----------------------------------------------------------------------
++%%% File : mod_presence.erl
++%%% Author : Igor Goryachev <igor@goryachev.org>
++%%% Purpose : Module for showing presences via web
++%%% Created : 30 Apr 2006 by Igor Goryachev <igor@goryachev.org>
++%%% Id : $Id$
++%%%----------------------------------------------------------------------
++
++-module(mod_presence).
++-author('igor@goryachev.org').
++-vsn('$Revision$').
++
++-behaviour(gen_server).
++-behaviour(gen_mod).
++
++%% API
++-export([start_link/2,
++ start/2,
++ stop/1,
++ get_info/2,
++ show_presence/1]).
++
++%% gen_server callbacks
++-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
++ terminate/2, code_change/3]).
++
++-include("ejabberd.hrl").
++-include("jlib.hrl").
++
++-record(presence_registered, {us_host, xml, icon}).
++-record(state, {host, server_host, access}).
++-record(session, {sid, usr, us, priority}).
++-record(presence, {resource, status, priority, text}).
++
++-define(PROCNAME, ejabberd_mod_presence).
++-define(SERVICE_NAME(Host), "presence." ++ Host).
++
++-define(PIXMAPS_DIR, "pixmaps").
++
++
++%%====================================================================
++%% API
++%%====================================================================
++%%--------------------------------------------------------------------
++%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
++%% Description: Starts the server
++%%--------------------------------------------------------------------
++start_link(Host, Opts) ->
++ Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
++ gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
++
++start(Host, Opts) ->
++ Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
++ ChildSpec =
++ {Proc,
++ {?MODULE, start_link, [Host, Opts]},
++ temporary,
++ 1000,
++ worker,
++ [?MODULE]},
++ Dir =
++ case os:getenv("EJABBERD_PIXMAPS_PATH") of
++ false ->
++ case code:priv_dir(ejabberd) of
++ {error, _} ->
++ ?PIXMAPS_DIR;
++ Path ->
++ filename:join([Path, ?PIXMAPS_DIR])
++ end;
++ Path ->
++ Path
++ end,
++ ets:new(pixmaps_dirs, [named_table, public]),
++ ets:insert(pixmaps_dirs, {directory, Dir}),
++ supervisor:start_child(ejabberd_sup, ChildSpec).
++
++stop(Host) ->
++ Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
++ gen_server:call(Proc, stop),
++ supervisor:stop_child(ejabberd_sup, Proc).
++
++%%====================================================================
++%% gen_server callbacks
++%%====================================================================
++
++%%--------------------------------------------------------------------
++%% Function: init(Args) -> {ok, State} |
++%% {ok, State, Timeout} |
++%% ignore |
++%% {stop, Reason}
++%% Description: Initiates the server
++%%--------------------------------------------------------------------
++init([Host, Opts]) ->
++ mnesia:create_table(presence_registered,
++ [{disc_copies, [node()]},
++ {attributes, record_info(fields, presence_registered)}]),
++ MyHost = gen_mod:get_opt(host, Opts, ?SERVICE_NAME(Host)),
++ mnesia:add_table_index(presence_registered, xml),
++ mnesia:add_table_index(presence_registered, icon),
++ Access = gen_mod:get_opt(access, Opts, all),
++ AccessCreate = gen_mod:get_opt(access_create, Opts, all),
++ AccessAdmin = gen_mod:get_opt(access_admin, Opts, none),
++ ejabberd_router:register_route(MyHost),
++ {ok, #state{host = MyHost,
++ server_host = Host,
++ access = {Access, AccessCreate, AccessAdmin}}}.
++
++%%--------------------------------------------------------------------
++%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
++%% {reply, Reply, State, Timeout} |
++%% {noreply, State} |
++%% {noreply, State, Timeout} |
++%% {stop, Reason, Reply, State} |
++%% {stop, Reason, State}
++%% Description: Handling call messages
++%%--------------------------------------------------------------------
++handle_call(stop, _From, State) ->
++ {stop, normal, ok, State}.
++
++%%--------------------------------------------------------------------
++%% Function: handle_cast(Msg, State) -> {noreply, State} |
++%% {noreply, State, Timeout} |
++%% {stop, Reason, State}
++%% Description: Handling cast messages
++%%--------------------------------------------------------------------
++handle_cast(_Msg, State) ->
++ {noreply, State}.
++
++%%--------------------------------------------------------------------
++%% Function: handle_info(Info, State) -> {noreply, State} |
++%% {noreply, State, Timeout} |
++%% {stop, Reason, State}
++%% Description: Handling all non call/cast messages
++%%--------------------------------------------------------------------
++handle_info({route, From, To, Packet},
++ #state{host = Host,
++ server_host = ServerHost,
++ access = Access} = State) ->
++ case catch do_route(Host, ServerHost, Access, From, To, Packet) of
++ {'EXIT', Reason} ->
++ ?ERROR_MSG("~p", [Reason]);
++ _ ->
++ ok
++ end,
++ {noreply, State};
++handle_info(_Info, State) ->
++ {noreply, State}.
++
++%%--------------------------------------------------------------------
++%% Function: terminate(Reason, State) -> void()
++%% Description: This function is called by a gen_server when it is about to
++%% terminate. It should be the opposite of Module:init/1 and do any necessary
++%% cleaning up. When it returns, the gen_server terminates with Reason.
++%% The return value is ignored.
++%%--------------------------------------------------------------------
++terminate(_Reason, State) ->
++ ejabberd_router:unregister_route(State#state.host),
++ ok.
++
++%%--------------------------------------------------------------------
++%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
++%% Description: Convert process state when code is changed
++%%--------------------------------------------------------------------
++code_change(_OldVsn, State, _Extra) ->
++ {ok, State}.
++
++%%--------------------------------------------------------------------
++%%% Internal functions
++%%--------------------------------------------------------------------
++
++do_route(Host, ServerHost, Access, From, To, Packet) ->
++ {AccessRoute, _AccessCreate, _AccessAdmin} = Access,
++ case acl:match_rule(ServerHost, AccessRoute, From) of
++ allow ->
++ do_route1(Host, ServerHost, Access, 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(Host, ServerHost, Access, From, To, Packet) ->
++ {_AccessRoute, AccessCreate, AccessAdmin} = Access,
++ {xmlelement, Name, Attrs, _Els} = Packet,
++ case Name of
++ "iq" ->
++ case jlib:iq_query_info(Packet) of
++ #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
++ sub_el = _SubEl} = IQ ->
++ Res = IQ#iq{type = result,
++ sub_el = [{xmlelement, "query",
++ [{"xmlns", XMLNS}],
++ iq_disco_info()}]},
++ ejabberd_router:route(To,
++ From,
++ jlib:iq_to_xml(Res));
++ #iq{type = get,
++ xmlns = ?NS_DISCO_ITEMS} = IQ ->
++ ok;
++ #iq{type = get,
++ xmlns = ?NS_REGISTER = XMLNS,
++ lang = Lang,
++ sub_el = _SubEl} = IQ ->
++ Res = IQ#iq{type = result,
++ sub_el =
++ [{xmlelement, "query",
++ [{"xmlns", XMLNS}],
++ iq_get_register_info(
++ Host, From, Lang)}]},
++ ejabberd_router:route(To,
++ From,
++ jlib:iq_to_xml(Res));
++ #iq{type = set,
++ xmlns = ?NS_REGISTER = XMLNS,
++ lang = Lang,
++ sub_el = SubEl} = IQ ->
++ case process_iq_register_set(Host, From, SubEl, Lang) of
++ {result, IQRes} ->
++ Res = IQ#iq{type = result,
++ sub_el =
++ [{xmlelement, "query",
++ [{"xmlns", XMLNS}],
++ IQRes}]},
++ ejabberd_router:route(
++ To, From, jlib:iq_to_xml(Res));
++ {error, Error} ->
++ Err = jlib:make_error_reply(
++ Packet, Error),
++ ejabberd_router:route(
++ To, From, Err)
++ end;
++ #iq{type = get,
++ xmlns = ?NS_VCARD = XMLNS,
++ lang = Lang,
++ sub_el = _SubEl} = IQ ->
++ Res = IQ#iq{type = result,
++ sub_el =
++ [{xmlelement, "vCard",
++ [{"xmlns", XMLNS}],
++ iq_get_vcard(Lang)}]},
++ ejabberd_router:route(To,
++ From,
++ jlib:iq_to_xml(Res));
++ #iq{} ->
++ Err = jlib:make_error_reply(
++ Packet,
++ ?ERR_FEATURE_NOT_IMPLEMENTED),
++ ejabberd_router:route(To, From, Err);
++ _ ->
++ ok
++ end;
++ _ ->
++ case xml:get_attr_s("type", Attrs) of
++ "error" ->
++ ok;
++ "result" ->
++ ok;
++ _ ->
++ Err = jlib:make_error_reply(
++ Packet, ?ERR_ITEM_NOT_FOUND),
++ ejabberd_router:route(To, From, Err)
++ end
++ end.
++
++iq_disco_info() ->
++ [{xmlelement, "identity",
++ [{"category", "presence"},
++ {"type", "text"},
++ {"name", "ejabberd/mod_presence"}], []},
++ {xmlelement, "feature", [{"var", ?NS_REGISTER}], []},
++ {xmlelement, "feature", [{"var", ?NS_VCARD}], []}].
++
++-define(XFIELD(Type, Label, Var, Val),
++ {xmlelement, "field", [{"type", Type},
++ {"label", translate:translate(Lang, Label)},
++ {"var", Var}],
++ [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
++
++iq_get_register_info(Host, From, Lang) ->
++ {LUser, LServer, _} = jlib:jid_tolower(From),
++ LUS = {LUser, LServer},
++ {XML, Icon, Registered} =
++ case catch mnesia:dirty_read(presence_registered, {LUS, Host}) of
++ {'EXIT', _Reason} ->
++ {"false", "disabled", []};
++ [] ->
++ {"false", "disabled", []};
++ [#presence_registered{xml = X, icon = I}] ->
++ {X, I, [{xmlelement, "registered", [], []}]}
++ end,
++ Registered ++
++ [{xmlelement, "instructions", [],
++ [{xmlcdata,
++ translate:translate(
++ Lang, "You need an x:data capable client to register presence")}]},
++ {xmlelement, "x",
++ [{"xmlns", ?NS_XDATA}],
++ [{xmlelement, "title", [],
++ [{xmlcdata,
++ translate:translate(
++ Lang, "Presence registration at ") ++ Host}]},
++ {xmlelement, "instructions", [],
++ [{xmlcdata,
++ translate:translate(
++ Lang, "What presence features do you want to register?")}]},
++ {xmlelement, "field", [{"type", "list-single"},
++ {"label", "Icon theme"},
++ {"var", "icon"}],
++ [{xmlelement, "value", [], [{xmlcdata, Icon}]},
++ {xmlelement, "option", [{"label", "disabled"}],
++ [{xmlelement, "value", [], [{xmlcdata, "disabled"}]}]}
++ ] ++ available_themes(xdata)},
++ ?XFIELD("boolean", "Raw XML", "xml", XML)]}].
++
++iq_set_register_info(Host, From, XML, Icon, Lang) ->
++ {LUser, LServer, _} = jlib:jid_tolower(From),
++ LUS = {LUser, LServer},
++ F = fun() ->
++ case XML of
++ "" ->
++ mnesia:delete({presence_registered, {LUS, Host}}),
++ ok;
++ _ ->
++ Allow =
++ case mnesia:select(
++ presence_registered,
++ [{#presence_registered{us_host = '$1',
++ xml = XML,
++ icon = Icon,
++ _ = '_'},
++ [{'==', {element, 2, '$1'}, Host}],
++ ['$_']}]) of
++ [] ->
++ true;
++ [#presence_registered{us_host = {U, _Host}}] ->
++ U == LUS
++ end,
++ if
++ Allow ->
++ mnesia:write(
++ #presence_registered{us_host = {LUS, Host},
++ xml = XML,
++ icon = Icon}),
++ ok;
++ true ->
++ false
++ end
++ end
++ end,
++ case mnesia:transaction(F) of
++ {atomic, ok} ->
++ {result, []};
++ {atomic, false} ->
++ ErrText = "Specified presence is already registered",
++ {error, ?ERRT_CONFLICT(Lang, ErrText)};
++ _ ->
++ {error, ?ERR_INTERNAL_SERVER_ERROR}
++ end.
++
++process_iq_register_set(Host, From, SubEl, Lang) ->
++ {xmlelement, _Name, _Attrs, Els} = SubEl,
++ case xml:get_subtag(SubEl, "remove") of
++ false ->
++ case xml:remove_cdata(Els) of
++ [{xmlelement, "x", _Attrs1, _Els1} = XEl] ->
++ case {xml:get_tag_attr_s("xmlns", XEl),
++ xml:get_tag_attr_s("type", XEl)} of
++ {?NS_XDATA, "cancel"} ->
++ {result, []};
++ {?NS_XDATA, "submit"} ->
++ XData = jlib:parse_xdata_submit(XEl),
++ case XData of
++ invalid ->
++ {error, ?ERR_BAD_REQUEST};
++ _ ->
++ case lists:keysearch("xml", 1, XData) of
++ false ->
++ ErrText = "You must fill in field \"Xml\" in the form",
++ {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)};
++ {value, {_, [XML]}} ->
++ case lists:keysearch("icon", 1, XData) of
++ false ->
++ ErrText = "You must fill in field \"Icon\" in the form",
++ {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)};
++ {value, {_, [Icon]}} ->
++ iq_set_register_info(Host, From, XML, Icon, Lang)
++ end
++ end
++ end;
++ _ ->
++ {error, ?ERR_BAD_REQUEST}
++ end;
++ _ ->
++ {error, ?ERR_BAD_REQUEST}
++ end;
++ _ ->
++ iq_set_register_info(Host, From, "false", "disabled", Lang)
++ end.
++
++iq_get_vcard(Lang) ->
++ [{xmlelement, "FN", [],
++ [{xmlcdata, "ejabberd/mod_presence"}]},
++ {xmlelement, "URL", [],
++ [{xmlcdata,
++ "http://ejabberd.jabberstudio.org/"}]},
++ {xmlelement, "DESC", [],
++ [{xmlcdata, translate:translate(Lang, "ejabberd presence module\n"
++ "Copyright (c) 2006 Igor Goryachev")}]}].
++
++get_info(LUser, LServer) ->
++ LUS = {LUser, LServer},
++ case catch mnesia:dirty_read(presence_registered, {LUS, ?SERVICE_NAME(LServer)}) of
++ {'EXIT', _Reason} ->
++ {false, disabled};
++ [] ->
++ {false, disabled};
++ [#presence_registered{xml = X, icon = I}] ->
++ X1 = case X of
++ "0" -> false;
++ "1" -> true;
++ _ -> list_to_atom(X)
++ end,
++ {X1, list_to_atom(I)}
++ end.
++
++get_status_weight(Status) ->
++ case Status of
++ "chat" -> 0;
++ "available" -> 1;
++ "away" -> 2;
++ "xa" -> 3;
++ "dnd" -> 4;
++ _ -> 9
++ end.
++
++
++get_presences({bare, LUser, LServer}) ->
++ Resources = ejabberd_sm:get_user_resources(LUser, LServer),
++ lists:map(
++ fun(Resource) ->
++ [Session] = mnesia:dirty_index_read(session,
++ {LUser, LServer, Resource},
++ #session.usr),
++ Pid = element(2, Session#session.sid),
++ {_User, _Resource, Status, Text} =
++ rpc:call(node(Pid), ejabberd_c2s, get_presence, [Pid]),
++ Priority = Session#session.priority,
++ #presence{resource = Resource,
++ status = Status,
++ priority = Priority,
++ text = Text}
++ end,
++ Resources);
++get_presences({sorted, LUser, LServer}) ->
++ lists:sort(
++ fun(A, B) ->
++ if
++ A#presence.priority == B#presence.priority ->
++ WA = get_status_weight(A#presence.status),
++ WB = get_status_weight(B#presence.status),
++ WA < WB;
++ true ->
++ A#presence.priority > B#presence.priority
++ end
++ end,
++ get_presences({bare, LUser, LServer}));
++get_presences({xml, LUser, LServer}) ->
++ {xmlelement, "presence",
++ [{"user", LUser}, {"server", LServer}],
++ lists:map(
++ fun(Presence) ->
++ {xmlelement, "resource",
++ [{"name", Presence#presence.resource},
++ {"status", Presence#presence.status},
++ {"priority", integer_to_list(Presence#presence.priority)}],
++ [{xmlcdata, Presence#presence.text}]}
++ end,
++ get_presences({sorted, LUser, LServer}))};
++get_presences({status, LUser, LServer}) ->
++ case get_presences({sorted, LUser, LServer}) of
++ [Highest | _Rest] ->
++ Highest#presence.status;
++ _ ->
++ "unavailable"
++ end;
++get_presences(_) ->
++ [].
++
++-define(XML_HEADER, "<?xml version='1.0' encoding='utf-8'?>").
++
++get_pixmaps_directory() ->
++ [{directory, Path} | _] = ets:lookup(pixmaps_dirs, directory),
++ Path.
++
++available_themes(list) ->
++ case file:list_dir(get_pixmaps_directory()) of
++ {ok, List} ->
++ List;
++ {error, _} ->
++ []
++ end;
++available_themes(xdata) ->
++ lists:map(
++ fun(Theme) ->
++ {xmlelement, "option", [{"label", Theme}],
++ [{xmlelement, "value", [], [{xmlcdata, Theme}]}]}
++ end, available_themes(list));
++available_themes(_) ->
++ [].
++
++-define(XE(Name, Els), {xmlelement, Name, [], Els}).
++-define(C(Text), {xmlcdata, Text}).
++-define(XC(Name, Text), ?XE(Name, [?C(Text)])).
++
++show_presence({xml, LUser, LServer}) ->
++ {XML, _Icon} = get_info(LUser, LServer),
++ case XML of
++ true ->
++ {200, [{"Content-Type", "text/xml; charset=utf-8"}],
++ ?XML_HEADER ++ xml:element_to_string(
++ get_presences({xml, LUser, LServer}))};
++ _ ->
++ {404, [], ejabberd_web:make_xhtml([?XC("h1", "Not found")])}
++ end;
++show_presence({image, LUser, LServer}) ->
++ {_XML, Icon} = get_info(LUser, LServer),
++ case Icon of
++ disabled ->
++ {404, [], ejabberd_web:make_xhtml([?XC("h1", "Not found")])};
++ _ ->
++ show_presence({image_no_check, LUser, LServer, atom_to_list(Icon)})
++ end;
++show_presence({image, LUser, LServer, Theme}) ->
++ {_XML, Icon} = get_info(LUser, LServer),
++ case Icon of
++ disabled ->
++ {404, [], ejabberd_web:make_xhtml([?XC("h1", "Not found")])};
++ _ ->
++ show_presence({image_no_check, LUser, LServer, Theme})
++ end;
++show_presence({image_no_check, LUser, LServer, Theme}) ->
++ case lists:member(Theme, available_themes(list)) of
++ true ->
++ case filelib:wildcard(
++ filename:join([get_pixmaps_directory(), Theme,
++ get_presences(
++ {status, LUser, LServer}) ++ ".{gif,png,jpg}"])) of
++ [First | _Rest] ->
++ CT = case string:substr(First, string:len(First) - 2, 3) of
++ "gif" -> "gif";
++ "png" -> "png";
++ "jpg" -> "jpeg"
++ end,
++ case file:read_file(First) of
++ {ok, Content} ->
++ {200, [{"Content-Type", "image/" ++ CT}],
++ binary_to_list(Content)};
++ _ ->
++ {404, [], ejabberd_web:make_xhtml([?XC("h1", "Not found")])}
++ end;
++ _ ->
++ {404, [], ejabberd_web:make_xhtml([?XC("h1", "Not found")])}
++ end;
++ false ->
++ {404, [], ejabberd_web:make_xhtml([?XC("h1", "Not found")])}
++ end;
++show_presence(_) ->
++ {404, [], ejabberd_web:make_xhtml([?XC("h1", "Not found")])}.
++
+diff -ruN ejabberd-1.1.2.orig/src/web/ejabberd_web.erl ejabberd-1.1.2/src/web/ejabberd_web.erl
+--- ejabberd-1.1.2.orig/src/web/ejabberd_web.erl 2006-02-07 11:42:39.000000000 +0300
++++ ejabberd-1.1.2/src/web/ejabberd_web.erl 2006-09-25 19:18:13.000000000 +0400
+@@ -139,6 +139,33 @@
+ lang = _Lang} = Request) ->
+ ejabberd_http_poll:process_request(Request#request{path = RPath});
+
++process_get({true, _},
++ #request{path = ["presence" | RPath],
++ q = _Query,
++ lang = _Lang} = Request) ->
++ case RPath of
++ [User, Server | Tail] ->
++ LServer = jlib:nameprep(Server),
++ case lists:member(LServer, ?MYHOSTS) of
++ true ->
++ LUser = jlib:nodeprep(User),
++ case Tail of
++ ["xml"] ->
++ mod_presence:show_presence({xml, LUser, LServer});
++ ["image"] ->
++ mod_presence:show_presence({image, LUser, LServer});
++ ["image", Theme] ->
++ mod_presence:show_presence({image, LUser, LServer, Theme});
++ _ ->
++ {404, [], make_xhtml([?XC("h1", "Not found")])}
++ end;
++ false ->
++ {404, [], make_xhtml([?XC("h1", "Not found")])}
++ end;
++ _ ->
++ {404, [], make_xhtml([?XC("h1", "Not found")])}
++ end;
++
+ process_get(_, _Request) ->
+ {404, [], make_xhtml([?XC("h1", "Not found")])}.
+