25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-24 16:23:40 +01:00

* src/mod_irc/: Added configuration interface

* src/mod_configure.erl: Use jabber:iq:data instead of
jabberdata
* src/mod_disco.erl: Likewise

SVN Revision: 82
This commit is contained in:
Alexey Shchepin 2003-02-23 20:13:39 +00:00
parent 764a4288ce
commit 499a1117dc
6 changed files with 281 additions and 59 deletions

View File

@ -1,3 +1,11 @@
2003-02-23 Alexey Shchepin <alexey@sevcom.net>
* src/mod_irc/: Added configuration interface
* src/mod_configure.erl: Use jabber:iq:data instead of
jabber:x:data
* src/mod_disco.erl: Likewise
2003-02-22 Alexey Shchepin <alexey@sevcom.net> 2003-02-22 Alexey Shchepin <alexey@sevcom.net>
* src/mod_configure.erl: Backup management support * src/mod_configure.erl: Backup management support

View File

@ -1,7 +1,7 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% File : mod_configure.erl %%% File : mod_configure.erl
%%% Author : Alexey Shchepin <alexey@sevcom.net> %%% Author : Alexey Shchepin <alexey@sevcom.net>
%%% Purpose : Support for online configuration of ejabberd via x:data %%% Purpose : Support for online configuration of ejabberd
%%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@sevcom.net> %%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
%%% Id : $Id$ %%% Id : $Id$
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
@ -23,15 +23,15 @@
start(Opts) -> start(Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_XDATA, gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_IQDATA,
?MODULE, process_local_iq, IQDisc), ?MODULE, process_local_iq, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_XDATA, gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_IQDATA,
?MODULE, process_sm_iq, IQDisc), ?MODULE, process_sm_iq, IQDisc),
ok. ok.
stop() -> stop() ->
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_XDATA), gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_IQDATA),
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_XDATA). gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_IQDATA).
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->

View File

@ -125,28 +125,28 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
{iq, ID, result, XMLNS, [{xmlelement, {iq, ID, result, XMLNS, [{xmlelement,
"query", "query",
[{"xmlns", XMLNS}], [{"xmlns", XMLNS}],
[feature_to_xml({?NS_XDATA}) [feature_to_xml({?NS_IQDATA})
] ]
}]}; }]};
["running nodes", ENode, "modules"] -> ?EMPTY_INFO_RESULT; ["running nodes", ENode, "modules"] -> ?EMPTY_INFO_RESULT;
["running nodes", ENode, "modules", _] -> ["running nodes", ENode, "modules", _] ->
{iq, ID, result, XMLNS, {iq, ID, result, XMLNS,
[{xmlelement, "query", [{"xmlns", XMLNS}], [{xmlelement, "query", [{"xmlns", XMLNS}],
[feature_to_xml({?NS_XDATA})]}]}; [feature_to_xml({?NS_IQDATA})]}]};
["running nodes", ENode, "backup"] -> ?EMPTY_INFO_RESULT; ["running nodes", ENode, "backup"] -> ?EMPTY_INFO_RESULT;
["running nodes", ENode, "backup", _] -> ["running nodes", ENode, "backup", _] ->
{iq, ID, result, XMLNS, {iq, ID, result, XMLNS,
[{xmlelement, "query", [{"xmlns", XMLNS}], [{xmlelement, "query", [{"xmlns", XMLNS}],
[feature_to_xml({?NS_XDATA})]}]}; [feature_to_xml({?NS_IQDATA})]}]};
["running nodes", ENode, "import"] -> ?EMPTY_INFO_RESULT; ["running nodes", ENode, "import"] -> ?EMPTY_INFO_RESULT;
["running nodes", ENode, "import", _] -> ["running nodes", ENode, "import", _] ->
{iq, ID, result, XMLNS, {iq, ID, result, XMLNS,
[{xmlelement, "query", [{"xmlns", XMLNS}], [{xmlelement, "query", [{"xmlns", XMLNS}],
[feature_to_xml({?NS_XDATA})]}]}; [feature_to_xml({?NS_IQDATA})]}]};
["config", _] -> ["config", _] ->
{iq, ID, result, XMLNS, {iq, ID, result, XMLNS,
[{xmlelement, "query", [{"xmlns", XMLNS}], [{xmlelement, "query", [{"xmlns", XMLNS}],
[feature_to_xml({?NS_XDATA})]}]}; [feature_to_xml({?NS_IQDATA})]}]};
_ -> _ ->
{iq, ID, error, XMLNS, {iq, ID, error, XMLNS,
[SubEl, {xmlelement, "error", [SubEl, {xmlelement, "error",
@ -443,7 +443,7 @@ process_sm_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
"" -> "" ->
{iq, ID, result, XMLNS, {iq, ID, result, XMLNS,
[{xmlelement, "query", [{"xmlns", XMLNS}], [{xmlelement, "query", [{"xmlns", XMLNS}],
[feature_to_xml({?NS_XDATA})]}]}; [feature_to_xml({?NS_IQDATA})]}]};
_ -> _ ->
{iq, ID, error, XMLNS, {iq, ID, error, XMLNS,
[SubEl, {xmlelement, "error", [SubEl, {xmlelement, "error",

View File

@ -12,15 +12,22 @@
-behaviour(gen_mod). -behaviour(gen_mod).
-export([start/1, init/1, stop/0, closed_conection/2]). -export([start/1, init/1, stop/0, closed_conection/2,
get_user_and_encoding/2]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
-include("namespaces.hrl"). -include("namespaces.hrl").
-define(DEFAULT_IRC_ENCODING, "koi8-r").
-record(irc_connection, {userserver, pid}). -record(irc_connection, {userserver, pid}).
-record(irc_custom, {userserver, data}).
start(Opts) -> start(Opts) ->
iconv:start(), iconv:start(),
mnesia:create_table(irc_custom,
[{disc_copies, [node()]},
{attributes, record_info(fields, irc_custom)}]),
Host = gen_mod:get_opt(host, Opts, "irc." ++ ?MYNAME), Host = gen_mod:get_opt(host, Opts, "irc." ++ ?MYNAME),
register(ejabberd_mod_irc, spawn(?MODULE, init, [Host])). register(ejabberd_mod_irc, spawn(?MODULE, init, [Host])).
@ -60,15 +67,12 @@ do_route(Host, From, To, Packet) ->
Res = {iq, ID, result, XMLNS, Res = {iq, ID, result, XMLNS,
[{xmlelement, "query", [{xmlelement, "query",
[{"xmlns", XMLNS}], [{"xmlns", XMLNS}],
[{xmlelement, "identity", iq_disco()}]},
[{"category", "conference"},
{"type", "irc"},
{"name", "ejabberd"}], []},
{xmlelement, "feature",
[{"var", ?NS_MUC}], []}]}]},
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(Res)); jlib:iq_to_xml(Res));
{iq, ID, Type, ?NS_IQDATA = XMLNS, SubEl} ->
iq_data(From, To, ID, XMLNS, Type, SubEl);
_ -> _ ->
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
Packet, "503", "Service Unavailable"), Packet, "503", "Service Unavailable"),
@ -85,8 +89,11 @@ do_route(Host, From, To, Packet) ->
case ets:lookup(irc_connection, {From, Server}) of case ets:lookup(irc_connection, {From, Server}) of
[] -> [] ->
io:format("open new connection~n"), io:format("open new connection~n"),
{Username, Encoding} = get_user_and_encoding(
From, Server),
{ok, Pid} = mod_irc_connection:start( {ok, Pid} = mod_irc_connection:start(
From, Host, Server), From, Host, Server,
Username, Encoding),
ets:insert( ets:insert(
irc_connection, irc_connection,
#irc_connection{userserver = {From, Server}, #irc_connection{userserver = {From, Server},
@ -137,3 +144,225 @@ stop() ->
closed_conection(From, Server) -> closed_conection(From, Server) ->
ets:delete(irc_connection, {From, Server}). ets:delete(irc_connection, {From, Server}).
iq_disco() ->
[{xmlelement, "identity",
[{"category", "conference"},
{"type", "irc"},
{"name", "ejabberd/mod_irc"}], []},
{xmlelement, "feature",
[{"var", ?NS_MUC}], []},
{xmlelement, "feature",
[{"var", ?NS_IQDATA}], []}].
iq_data(From, To, ID, XMLNS, Type, SubEl) ->
case catch process_iq_data(From, To, ID, XMLNS, Type, SubEl) of
{'EXIT', Reason} ->
?ERROR_MSG("~p", [Reason]);
ResIQ ->
if
ResIQ /= ignore ->
ejabberd_router:route(To, From,
jlib:iq_to_xml(ResIQ));
true ->
ok
end
end.
process_iq_data(From, To, ID, XMLNS, Type, SubEl) ->
Lang = xml:get_tag_attr_s("xml:lang", SubEl),
case Type of
set ->
case xml:get_tag_attr_s("type", SubEl) of
"cancel" ->
{iq, ID, result, XMLNS,
[{xmlelement, "query", [{"xmlns", XMLNS}], []}]};
"submit" ->
XData = jlib:parse_xdata_submit(SubEl),
case XData of
invalid ->
{iq, ID, error, XMLNS,
[SubEl, {xmlelement, "error",
[{"code", "400"}],
[{xmlcdata, "Bad Request"}]}]};
_ ->
Node =
string:tokens(
xml:get_tag_attr_s("node", SubEl),
"/"),
case set_form(From, Node, Lang, XData) of
{result, Res} ->
{iq, ID, result, XMLNS,
[{xmlelement, "query",
[{"xmlns", XMLNS}],
Res
}]};
{error, Code, Desc} ->
{iq, ID, error, XMLNS,
[SubEl, {xmlelement, "error",
[{"code", Code}],
[{xmlcdata, Desc}]}]}
end
end;
_ ->
{iq, ID, error, XMLNS,
[SubEl, {xmlelement, "error",
[{"code", "405"}],
[{xmlcdata, "Not Allowed"}]}]}
end;
get ->
Node =
string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
case get_form(From, Node, Lang) of
{result, Res} ->
{iq, ID, result, XMLNS,
[{xmlelement, "query", [{"xmlns", XMLNS}],
Res
}]};
{error, Code, Desc} ->
{iq, ID, error, XMLNS,
[SubEl, {xmlelement, "error",
[{"code", Code}],
[{xmlcdata, Desc}]}]}
end
end.
get_form(From, [], Lang) ->
{User, Server, _} = From,
{LUser, LServer, _} = jlib:jid_tolower(From),
Customs =
case catch mnesia:dirty_read({irc_custom, {LUser, LServer}}) of
{'EXIT', Reason} ->
{error, "500", "Internal Server Error"};
[] ->
{User, []};
[#irc_custom{data = Data}] ->
{xml:get_attr_s(username, Data),
xml:get_attr_s(encodings, Data)}
end,
case Customs of
{error, _, _} ->
Customs;
{Username, Encodings} ->
{result,
[{xmlelement, "title", [],
[{xmlcdata,
User ++ "@" ++ Server ++ " " ++
translate:translate(Lang, "Configuration")}]},
%{xmlelement, "instructions", [],
% [{xmlcdata,
% translate:translate(
% Lang, "")}]},
{xmlelement, "field", [{"type", "text-single"},
{"label",
translate:translate(
Lang, "IRC Username")},
{"var", "username"}],
[{xmlelement, "value", [], [{xmlcdata, Username}]}]},
{xmlelement, "field", [{"type", "fixed"}],
[{xmlelement, "value", [],
[{xmlcdata,
lists:flatten(
io_lib:format(
translate:translate(
Lang,
"If you want to specify different encodings "
"for IRC servers, fill this list with values "
"in format '{\"irc server\", \"encoding\"}'. "
"By default this service use \"~s\" encoding."),
[?DEFAULT_IRC_ENCODING]))}]}]},
{xmlelement, "field", [{"type", "fixed"}],
[{xmlelement, "value", [],
[{xmlcdata,
translate:translate(
Lang,
"Example: [{\"irc.lucky.net\", \"koi8-r\"}, "
"{\"vendetta.fef.net\", \"iso8859-1\"}]."
)}]}]},
{xmlelement, "field", [{"type", "text-multi"},
{"label",
translate:translate(Lang, "Encodings")},
{"var", "encodings"}],
lists:map(
fun(S) ->
{xmlelement, "value", [], [{xmlcdata, S}]}
end,
string:tokens(
lists:flatten(
io_lib:format("~p.", [Encodings])),
"\n"))
}
]}
end;
get_form(_, _, Lang) ->
{error, "503", "Service Unavailable"}.
set_form(From, [], Lang, XData) ->
{LUser, LServer, _} = jlib:jid_tolower(From),
case {lists:keysearch("username", 1, XData),
lists:keysearch("encodings", 1, XData)} of
{{value, {_, [Username]}}, {value, {_, Strings}}} ->
EncString = lists:foldl(fun(S, Res) ->
Res ++ S ++ "\n"
end, "", Strings),
case erl_scan:string(EncString) of
{ok, Tokens, _} ->
case erl_parse:parse_term(Tokens) of
{ok, Encodings} ->
case mnesia:transaction(
fun() ->
mnesia:write(
#irc_custom{userserver =
{LUser, LServer},
data =
[{username,
Username},
{encodings,
Encodings}]})
end) of
{atomic, _} ->
{result, []};
_ ->
{error, "406", "Not Acceptable"}
end;
_ ->
{error, "406", "Not Acceptable"}
end;
_ ->
{error, "406", "Not Acceptable"}
end;
_ ->
{error, "406", "Not Acceptable"}
end;
set_form(_, _, Lang, XData) ->
{error, "503", "Service Unavailable"}.
get_user_and_encoding(From, IRCServer) ->
{User, Server, _} = From,
{LUser, LServer, _} = jlib:jid_tolower(From),
case catch mnesia:dirty_read({irc_custom, {LUser, LServer}}) of
{'EXIT', Reason} ->
{User, ?DEFAULT_IRC_ENCODING};
[] ->
{User, ?DEFAULT_IRC_ENCODING};
[#irc_custom{data = Data}] ->
{xml:get_attr_s(username, Data),
case xml:get_attr_s(IRCServer, xml:get_attr_s(encodings, Data)) of
"" -> ?DEFAULT_IRC_ENCODING;
E -> E
end}
end.

View File

@ -13,7 +13,7 @@
-behaviour(gen_fsm). -behaviour(gen_fsm).
%% External exports %% External exports
-export([start/3, receiver/2, route_chan/4, route_nick/3]). -export([start/5, receiver/2, route_chan/4, route_nick/3]).
%% gen_fsm callbacks %% gen_fsm callbacks
-export([init/1, -export([init/1,
@ -31,13 +31,11 @@
-define(SETS, gb_sets). -define(SETS, gb_sets).
-record(state, {socket, receiver, queue, -record(state, {socket, encoding, receiver, queue,
user, myname, server, nick, user, myname, server, nick,
channels = dict:new(), channels = dict:new(),
inbuf = "", outbuf = ""}). inbuf = "", outbuf = ""}).
-define(IRC_ENCODING, "koi8-r").
-define(DBGFSM, true). -define(DBGFSM, true).
-ifdef(DBGFSM). -ifdef(DBGFSM).
@ -49,8 +47,8 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% API %%% API
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
start(From, Host, Server) -> start(From, Host, Server, Username, Encoding) ->
gen_fsm:start(?MODULE, [From, Host, Server], ?FSMOPTS). gen_fsm:start(?MODULE, [From, Host, Server, Username, Encoding], ?FSMOPTS).
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% Callback functions from gen_fsm %%% Callback functions from gen_fsm
@ -63,12 +61,12 @@ start(From, Host, Server) ->
%% ignore | %% ignore |
%% {stop, StopReason} %% {stop, StopReason}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
init([From, Host, Server]) -> init([From, Host, Server, Username, Encoding]) ->
gen_fsm:send_event(self(), init), gen_fsm:send_event(self(), init),
{Nick, _, _} = From,
{ok, open_socket, #state{queue = queue:new(), {ok, open_socket, #state{queue = queue:new(),
encoding = Encoding,
user = From, user = From,
nick = Nick, nick = Username,
myname = Host, myname = Host,
server = Server}}. server = Server}}.
@ -84,13 +82,10 @@ open_socket(init, StateData) ->
?DEBUG("connecting to ~s:~p~n", [Addr, Port]), ?DEBUG("connecting to ~s:~p~n", [Addr, Port]),
case gen_tcp:connect(Addr, Port, [binary, {packet, 0}]) of case gen_tcp:connect(Addr, Port, [binary, {packet, 0}]) of
{ok, Socket} -> {ok, Socket} ->
% TODO: send nick, etc... NewStateData = StateData#state{socket = Socket},
%send_text(Socket, io_lib:format(?STREAM_HEADER, send_text(NewStateData,
% [StateData#state.server])), io_lib:format("NICK ~s\r\n", [StateData#state.nick])),
%send_queue(StateData#state.socket, StateData#state.queue), send_text(NewStateData,
send_text(Socket, io_lib:format("NICK ~s\r\n",
[StateData#state.nick])),
send_text(Socket,
io_lib:format( io_lib:format(
"USER ~s ~s ~s :~s\r\n", "USER ~s ~s ~s :~s\r\n",
[StateData#state.nick, [StateData#state.nick,
@ -98,7 +93,7 @@ open_socket(init, StateData) ->
StateData#state.myname, StateData#state.myname,
StateData#state.nick])), StateData#state.nick])),
{next_state, wait_for_registration, {next_state, wait_for_registration,
StateData#state{socket = Socket}}; NewStateData};
{error, Reason} -> {error, Reason} ->
?DEBUG("connect return ~p~n", [Reason]), ?DEBUG("connect return ~p~n", [Reason]),
Text = case Reason of Text = case Reason of
@ -164,7 +159,7 @@ code_change(OldVsn, StateName, StateData, Extra) ->
-define(SEND(S), -define(SEND(S),
if if
StateName == stream_established -> StateName == stream_established ->
send_text(StateData#state.socket, S), send_text(StateData, S),
StateData; StateData;
true -> true ->
StateData#state{outbuf = StateData#state.outbuf ++ S} StateData#state{outbuf = StateData#state.outbuf ++ S}
@ -297,7 +292,7 @@ handle_info({route_nick, Nick, Packet}, StateName, StateData) ->
handle_info({ircstring, [$P, $I, $N, $G, $ | ID]}, StateName, StateData) -> handle_info({ircstring, [$P, $I, $N, $G, $ | ID]}, StateName, StateData) ->
send_text(StateData#state.socket, "PONG " ++ ID ++ "\r\n"), send_text(StateData, "PONG " ++ ID ++ "\r\n"),
{next_state, StateName, StateData}; {next_state, StateName, StateData};
handle_info({ircstring, [$: | String]}, StateName, StateData) -> handle_info({ircstring, [$: | String]}, StateName, StateData) ->
@ -343,7 +338,7 @@ handle_info({ircstring, [$: | String]}, StateName, StateData) ->
"" -> "" ->
NewStateData; NewStateData;
Data -> Data ->
send_text(NewStateData#state.socket, Data), send_text(NewStateData, Data),
NewStateData#state{outbuf = ""} NewStateData#state{outbuf = ""}
end, end,
{next_state, stream_established, NewStateData1}; {next_state, stream_established, NewStateData1};
@ -360,22 +355,13 @@ handle_info({ircstring, String}, StateName, StateData) ->
handle_info({send_text, Text}, StateName, StateData) -> handle_info({send_text, Text}, StateName, StateData) ->
send_text(StateData#state.socket, Text), send_text(StateData, Text),
{next_state, StateName, StateData}; {next_state, StateName, StateData};
handle_info({send_element, El}, StateName, StateData) ->
case StateName of
stream_established ->
send_element(StateData#state.socket, El),
{next_state, StateName, StateData};
_ ->
Q = queue:in(El, StateData#state.queue),
{next_state, StateName, StateData#state{queue = Q}}
end;
handle_info({tcp, Socket, Data}, StateName, StateData) -> handle_info({tcp, Socket, Data}, StateName, StateData) ->
Buf = StateData#state.inbuf ++ binary_to_list(Data), Buf = StateData#state.inbuf ++ binary_to_list(Data),
{ok, Strings} = regexp:split([C || C <- Buf, C /= $\r], "\n"), {ok, Strings} = regexp:split([C || C <- Buf, C /= $\r], "\n"),
io:format("strings=~p~n", [Strings]), io:format("strings=~p~n", [Strings]),
NewBuf = process_lines(Strings), NewBuf = process_lines(StateData#state.encoding, Strings),
{next_state, StateName, StateData#state{inbuf = NewBuf}}; {next_state, StateName, StateData#state{inbuf = NewBuf}};
handle_info({tcp_closed, Socket}, StateName, StateData) -> handle_info({tcp_closed, Socket}, StateName, StateData) ->
gen_fsm:send_event(self(), closed), gen_fsm:send_event(self(), closed),
@ -430,13 +416,11 @@ receiver(Socket, C2SPid, XMLStreamPid) ->
ok ok
end. end.
send_text(Socket, Text) -> send_text(#state{socket = Socket, encoding = Encoding}, Text) ->
CText = iconv:convert("utf-8", ?IRC_ENCODING, lists:flatten(Text)), CText = iconv:convert("utf-8", Encoding, lists:flatten(Text)),
%io:format("IRC OUTu: ~s~nIRC OUTk: ~s~n", [Text, CText]), %io:format("IRC OUTu: ~s~nIRC OUTk: ~s~n", [Text, CText]),
gen_tcp:send(Socket, CText). gen_tcp:send(Socket, CText).
send_element(Socket, El) ->
send_text(Socket, xml:element_to_string(El)).
%send_queue(Socket, Q) -> %send_queue(Socket, Q) ->
% case queue:out(Q) of % case queue:out(Q) of
@ -474,11 +458,11 @@ route_nick(Pid, Nick, Packet) ->
Pid ! {route_nick, Nick, Packet}. Pid ! {route_nick, Nick, Packet}.
process_lines([S]) -> process_lines(Encoding, [S]) ->
S; S;
process_lines([S | Ss]) -> process_lines(Encoding, [S | Ss]) ->
self() ! {ircstring, iconv:convert(?IRC_ENCODING, "utf-8", S)}, self() ! {ircstring, iconv:convert(Encoding, "utf-8", S)},
process_lines(Ss). process_lines(Encoding, Ss).
process_channel_list(StateData, Items) -> process_channel_list(StateData, Items) ->
process_channel_list_find_chan(StateData, Items). process_channel_list_find_chan(StateData, Items).
@ -580,7 +564,7 @@ process_privmsg(StateData, Nick, From, String) ->
process_version(StateData, Nick, From) -> process_version(StateData, Nick, From) ->
[FromUser | _] = string:tokens(From, "!"), [FromUser | _] = string:tokens(From, "!"),
send_text( send_text(
StateData#state.socket, StateData,
io_lib:format("NOTICE ~s :\001VERSION " io_lib:format("NOTICE ~s :\001VERSION "
"ejabberd IRC transport ~s (c) Alexey Shchepin" "ejabberd IRC transport ~s (c) Alexey Shchepin"
"\001\r\n", "\001\r\n",

View File

@ -16,6 +16,7 @@
-define(NS_VERSION, "jabber:iq:version"). -define(NS_VERSION, "jabber:iq:version").
-define(NS_TIME, "jabber:iq:time"). -define(NS_TIME, "jabber:iq:time").
-define(NS_XDATA, "jabber:x:data"). -define(NS_XDATA, "jabber:x:data").
-define(NS_IQDATA, "jabber:iq:data").
-define(NS_DELAY, "jabber:x:delay"). -define(NS_DELAY, "jabber:x:delay").
-define(NS_EVENT, "jabber:x:event"). -define(NS_EVENT, "jabber:x:event").
-define(NS_STATS, "http://jabber.org/protocol/stats"). -define(NS_STATS, "http://jabber.org/protocol/stats").