From 28c0fee27b7714b37df7aa30b9c491275f208ac7 Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Mon, 21 Jul 2003 20:01:22 +0000 Subject: [PATCH] * src/mod_vcard.erl: Bugfix * src/mod_roster.erl: Bugfix * src/jlib.hrl: Added iq:privacy namespace * src/mod_irc/mod_irc_connection.erl: Added support for NOTICE and CODEPAGE commands, better support for QUIT and PART commands (thanks to Oleg V. Motienko) SVN Revision: 126 --- ChangeLog | 12 +++ src/jlib.hrl | 1 + src/mod_irc/mod_irc_connection.erl | 113 +++++++++++++++++++++++++++-- src/mod_pubsub/mod_pubsub.erl | 12 ++- src/mod_roster.erl | 26 +++---- src/mod_vcard.erl | 24 +++--- 6 files changed, 153 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 69326c261..69cd1b68f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2003-07-21 Alexey Shchepin + + * src/mod_vcard.erl: Bugfix + + * src/mod_roster.erl: Bugfix + + * src/jlib.hrl: Added iq:privacy namespace + + * src/mod_irc/mod_irc_connection.erl: Added support for NOTICE and + CODEPAGE commands, better support for QUIT and PART commands + (thanks to Oleg V. Motienko) + 2003-07-20 Alexey Shchepin * (all): Reorganized supervision tree diff --git a/src/jlib.hrl b/src/jlib.hrl index a0656a23f..ae82e7fbb 100644 --- a/src/jlib.hrl +++ b/src/jlib.hrl @@ -13,6 +13,7 @@ -define(NS_REGISTER, "jabber:iq:register"). -define(NS_SEARCH, "jabber:iq:search"). -define(NS_ROSTER, "jabber:iq:roster"). +-define(NS_PRIVACY, "jabber:iq:privacy"). -define(NS_PRIVATE, "jabber:iq:private"). -define(NS_VERSION, "jabber:iq:version"). -define(NS_TIME, "jabber:iq:time"). diff --git a/src/mod_irc/mod_irc_connection.erl b/src/mod_irc/mod_irc_connection.erl index ddfd73276..683447fc5 100644 --- a/src/mod_irc/mod_irc_connection.erl +++ b/src/mod_irc/mod_irc_connection.erl @@ -92,6 +92,8 @@ open_socket(init, StateData) -> StateData#state.nick, StateData#state.myname, StateData#state.nick])), + send_text(NewStateData, + io_lib:format("CODEPAGE ~s\r\n", [StateData#state.encoding])), {next_state, wait_for_registration, NewStateData}; {error, Reason} -> @@ -360,12 +362,18 @@ handle_info({ircstring, [$: | String]}, StateName, StateData) -> [From, "PRIVMSG", [$# | Chan] | _] -> process_chanprivmsg(StateData, Chan, From, String), StateData; + [From, "NOTICE", [$# | Chan] | _] -> + process_channotice(StateData, Chan, From, String), + StateData; [From, "PRIVMSG", Nick, ":\001VERSION\001" | _] -> process_version(StateData, Nick, From), StateData; [From, "PRIVMSG", Nick | _] -> process_privmsg(StateData, Nick, From, String), StateData; + [From, "NOTICE", Nick | _] -> + process_notice(StateData, Nick, From, String), + StateData; [From, "TOPIC", [$# | Chan] | _] -> process_topic(StateData, Chan, From, String), StateData; @@ -547,6 +555,7 @@ process_channel_list_user(StateData, Chan, User) -> {User2, Affiliation, Role} = case User1 of [$@ | U2] -> {U2, "admin", "moderator"}; + [$+ | U2] -> {U2, "member", "participant"}; _ -> {User1, "member", "participant"} end, ejabberd_router:route({lists:concat([Chan, "%", StateData#state.server]), @@ -614,6 +623,36 @@ process_chanprivmsg(StateData, Chan, From, String) -> {xmlelement, "message", [{"type", "groupchat"}], [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). + + +process_channotice(StateData, Chan, From, String) -> + [FromUser | _] = string:tokens(From, "!"), + {ok, Msg, _} = regexp:sub(String, ".*NOTICE[^:]*:", ""), + Msg1 = case Msg of + [1, $A, $C, $T, $I, $O, $N, $ | Rest] -> + "/me " ++ Rest; + _ -> + Msg + end, + Msg2 = lists:filter( + fun(C) -> + if (C < 32) and + (C /= 9) and + (C /= 10) and + (C /= 13) -> + false; + true -> true + end + end, Msg1), + ejabberd_router:route({lists:concat([Chan, "%", StateData#state.server]), + StateData#state.myname, FromUser}, + StateData#state.user, + {xmlelement, "message", [{"type", "groupchat"}], + [{xmlelement, "body", [], [{xmlcdata, "NOTICE: " ++ Msg2}]}]}). + + + + process_privmsg(StateData, Nick, From, String) -> [FromUser | _] = string:tokens(From, "!"), {ok, Msg, _} = regexp:sub(String, ".*PRIVMSG[^:]*:", ""), @@ -640,6 +679,34 @@ process_privmsg(StateData, Nick, From, String) -> {xmlelement, "message", [{"type", "chat"}], [{xmlelement, "body", [], [{xmlcdata, Msg2}]}]}). + +process_notice(StateData, Nick, From, String) -> + [FromUser | _] = string:tokens(From, "!"), + {ok, Msg, _} = regexp:sub(String, ".*NOTICE[^:]*:", ""), + Msg1 = case Msg of + [1, $A, $C, $T, $I, $O, $N, $ | Rest] -> + "/me " ++ Rest; + _ -> + Msg + end, + Msg2 = lists:filter( + fun(C) -> + if (C < 32) and + (C /= 9) and + (C /= 10) and + (C /= 13) -> + false; + true -> true + end + end, Msg1), + ejabberd_router:route( + {lists:concat([FromUser, "!", StateData#state.server]), + StateData#state.myname, ""}, + StateData#state.user, + {xmlelement, "message", [{"type", "chat"}], + [{xmlelement, "body", [], [{xmlcdata, "NOTICE: " ++ Msg2}]}]}). + + process_version(StateData, Nick, From) -> [FromUser | _] = string:tokens(From, "!"), send_text( @@ -677,8 +744,16 @@ process_topic(StateData, Chan, From, String) -> Msg1}]}]}). process_part(StateData, Chan, From, String) -> - [FromUser | _] = string:tokens(From, "!"), - %Msg = lists:last(string:tokens(String, ":")), + [FromUser | FromIdent] = string:tokens(From, "!"), + {ok, Msg, _} = regexp:sub(String, ".*PART[^:]*", ""), + ejabberd_router:route({lists:concat([Chan, "%", StateData#state.server]), + StateData#state.myname, FromUser}, + StateData#state.user, + {xmlelement, "message", [{"type", "groupchat"}], + [{xmlelement, "body", [], + [{xmlcdata, "/me has part: " ++ + Msg ++ "(" ++ FromIdent ++ ")" }]}]}), + ejabberd_router:route({lists:concat([Chan, "%", StateData#state.server]), StateData#state.myname, FromUser}, StateData#state.user, @@ -687,7 +762,10 @@ process_part(StateData, Chan, From, String) -> [{xmlelement, "item", [{"affiliation", "member"}, {"role", "none"}], - []}]}]}), + []}]}, + {xmlelement, "status", [], + [{xmlcdata, Msg ++ "(" ++ FromIdent ++ ")"}]}] + }), case catch dict:update(Chan, fun(Ps) -> remove_element(FromUser, Ps) @@ -700,13 +778,22 @@ process_part(StateData, Chan, From, String) -> process_quit(StateData, From, String) -> - [FromUser | _] = string:tokens(From, "!"), - %Msg = lists:last(string:tokens(String, ":")), + [FromUser | FromIdent] = string:tokens(From, "!"), + + {ok, Msg, _} = regexp:sub(String, ".*QUIT[^:]*:", ""), NewChans = dict:map( fun(Chan, Ps) -> case ?SETS:is_member(FromUser, Ps) of true -> + ejabberd_router:route({lists:concat([Chan, "%", StateData#state.server]), + StateData#state.myname, FromUser}, + StateData#state.user, + {xmlelement, "message", [{"type", "groupchat"}], + [{xmlelement, "body", [], + [{xmlcdata, "/me has quit: " ++ + Msg ++ "(" ++ FromIdent ++ ")" }]}]}), + ejabberd_router:route( {lists:concat([Chan, "%", StateData#state.server]), StateData#state.myname, FromUser}, @@ -716,7 +803,10 @@ process_quit(StateData, From, String) -> [{xmlelement, "item", [{"affiliation", "member"}, {"role", "none"}], - []}]}]}), + []}]}, + {xmlelement, "status", [], + [{xmlcdata, Msg ++ "(" ++ FromIdent ++ ")"}]} + ]}), remove_element(FromUser, Ps); _ -> Ps @@ -726,7 +816,7 @@ process_quit(StateData, From, String) -> process_join(StateData, Channel, From, String) -> - [FromUser | _] = string:tokens(From, "!"), + [FromUser | FromIdent] = string:tokens(From, "!"), Chan = lists:subtract(Channel, ":#"), ejabberd_router:route({lists:concat([Chan, "%", StateData#state.server]), StateData#state.myname, FromUser}, @@ -737,6 +827,15 @@ process_join(StateData, Channel, From, String) -> [{"affiliation", "member"}, {"role", "participant"}], []}]}]}), + {ok, Msg, _} = regexp:sub(String, ".*JOIN[^:]*:", ""), + ejabberd_router:route({lists:concat([Chan, "%", StateData#state.server]), + StateData#state.myname, FromUser}, + StateData#state.user, + {xmlelement, "message", [{"type", "groupchat"}], + [{xmlelement, "body", [], + [{xmlcdata, "/me has joined " ++ + Msg ++ "(" ++ FromIdent ++ ")" }]}]}), + case catch dict:update(Chan, fun(Ps) -> ?SETS:add_element(FromUser, Ps) diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl index ce0fb81f0..c10e31224 100644 --- a/src/mod_pubsub/mod_pubsub.erl +++ b/src/mod_pubsub/mod_pubsub.erl @@ -17,7 +17,7 @@ loop/2, stop/0, system_continue/3, - system_terminate/4, + system_terminate/4, system_code_change/4]). -include("ejabberd.hrl"). @@ -454,8 +454,14 @@ create_new_node(Host, Node, Owner) -> case Node of [] -> {LOU, LOS, _} = jlib:jid_tolower(Owner), - NewNode = ["home", LOS, LOU, randoms:get_string()], - create_new_node(Host, NewNode, Owner); + HomeNode = ["home", LOS, LOU], + case create_new_node(Host, HomeNode, Owner) of + {error, _} = Error -> + Error; + _ -> + NewNode = ["home", LOS, LOU, randoms:get_string()], + create_new_node(Host, NewNode, Owner) + end; _ -> LOwner = jlib:jid_tolower(jlib:jid_remove_resource(Owner)), Parent = lists:sublist(Node, length(Node) - 1), diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 9acebe5f4..502c1f3d2 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -41,7 +41,19 @@ start(Opts) -> {attributes, record_info(fields, roster)}]), mnesia:add_table_index(roster, user), gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_ROSTER, - ?MODULE, process_local_iq, IQDisc). + ?MODULE, process_iq, IQDisc). + +process_iq(From, To, IQ) -> + {iq, ID, Type, XMLNS, SubEl} = IQ, + {_, Server, _} = From, + case ?MYNAME of + Server -> + process_local_iq(From, To, IQ); + _ -> + {iq, ID, error, XMLNS, + [SubEl, ?ERR_ITEM_NOT_FOUND]} + end. + process_local_iq(From, To, {iq, _, Type, _, _} = IQ) -> case Type of @@ -53,18 +65,6 @@ process_local_iq(From, To, {iq, _, Type, _, _} = IQ) -> -process_iq(From, To, IQ) -> - {iq, ID, Type, XMLNS, SubEl} = IQ, - {_, Server, _} = From, - case ?MYNAME of - Server -> - process_local_iq(From, To, IQ), - ignore; - _ -> - {iq, ID, error, XMLNS, - [SubEl, ?ERR_ITEM_NOT_FOUND]} - end. - process_iq_get(From, To, {iq, ID, Type, XMLNS, SubEl}) -> {User, _, _} = From, LUser = jlib:tolower(User), diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 3f19d21ca..73fcc5c6a 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -82,17 +82,7 @@ loop() -> process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> case Type of set -> - {User, Server, _} = From, - LUser = jlib:tolower(User), - LServer = jlib:tolower(Server), - case ?MYNAME of - LServer -> - set_vcard(User, SubEl), - {iq, ID, result, XMLNS, []}; - _ -> - {iq, ID, error, XMLNS, - [SubEl, ?ERR_NOT_ALLOWED]} - end; + {iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; get -> {iq, ID, result, XMLNS, [{xmlelement, "vCard", @@ -114,7 +104,17 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> case Type of set -> - {iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; + {User, Server, _} = From, + LUser = jlib:tolower(User), + LServer = jlib:tolower(Server), + case ?MYNAME of + LServer -> + set_vcard(User, SubEl), + {iq, ID, result, XMLNS, []}; + _ -> + {iq, ID, error, XMLNS, + [SubEl, ?ERR_NOT_ALLOWED]} + end; get -> {User, _, _} = To, LUser = jlib:tolower(User),