From e995f72dc459d8c977fb32e75751227e0aa2a2c5 Mon Sep 17 00:00:00 2001 From: Bertrand Jacquin Date: Thu, 28 Sep 2006 22:28:40 +0200 Subject: ejabberd: update patches for mod_presence --- net-im/ejabberd/Manifest | 24 +- net-im/ejabberd/ejabberd-1.1.2-r1.ebuild | 3 +- net-im/ejabberd/files/mod_presence.diff | 633 +++++++++++++++++++++++++++++++ 3 files changed, 647 insertions(+), 13 deletions(-) create mode 100644 net-im/ejabberd/files/mod_presence.diff (limited to 'net-im') 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 ++%%% Purpose : Module for showing presences via web ++%%% Created : 30 Apr 2006 by Igor Goryachev ++%%% 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, ""). ++ ++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")])}. + -- cgit v1.2.3