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

Merge from trunk (r1457 to r1563).

SVN Revision: 1564
This commit is contained in:
Jean-Sébastien Pédron 2008-09-16 14:39:57 +00:00
parent 414948d822
commit 4eaa8e19c9
202 changed files with 46384 additions and 9369 deletions

270
ChangeLog
View File

@ -1,3 +1,31 @@
2008-09-16 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
Merge from trunk (r1457 to r1563).
2008-09-15 Badlop <badlop@process-one.net>
* doc/guide.tex: Fix explanation of mod_muc's anonymous
option. Make clear that an ejabberd_service can only serve a
single external component. Provide Mnesia directory when setting
clustering (thanks to Matthew Reilly)
2008-09-12 Badlop <badlop@process-one.net>
* src/web/ejabberd_http.hrl: Provide Host, Port, Headers and
Transfer Protocol in request (thanks to Eric Cestari)(EJAB-560)
* src/web/ejabberd_http.erl: Likewise
2008-09-02 Badlop <badlop@process-one.net>
* doc/guide.tex: Fix mod_proxy configuration example
* doc/guide.html: Likewise
2008-09-02 Mickael Remond <mremond@process-one.net>
* src/odbc/mssql2000.sql: Script for MSSQL 2000
* src/odbc/mssql2005.sql: Script for MSSQL 2005 (EJAB-535)
* src/odbc/mssql.sql: removed
2008-08-27 Jean-Sébastien Pédron <js.pedron@meetic-corp.com> 2008-08-27 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
* src/mod_roster.erl: Remove a debugging io:format/2. * src/mod_roster.erl: Remove a debugging io:format/2.
@ -5,8 +33,14 @@
* src/mod_caps.erl: handle_cast({disco_response, ...}, ...) now * src/mod_caps.erl: handle_cast({disco_response, ...}, ...) now
receives an #iq record: update the code to handle this. receives an #iq record: update the code to handle this.
* src/mod_vcard.erl: VCard are now stored as #xmlel. Mnesia tables are * src/mod_vcard.erl: VCards are now stored as #xmlel. Mnesia tables
converted during startup. are converted during startup.
2008-08-27 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: send last published events now
supports PEP events from unavailable users nodes (EJAB-698)
* src/ejabberd_c2s.erl: Likewise
2008-08-26 Jean-Sébastien Pédron <js.pedron@meetic-corp.com> 2008-08-26 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
@ -35,6 +69,81 @@
binary instead of an empty string, for consistency's sake. Fix some binary instead of an empty string, for consistency's sake. Fix some
bugs. bugs.
2008-08-26 Badlop <badlop@process-one.net>
* doc/release_notes_2.0.2.txt: Update for final release
* doc/guide.tex: Windows binary installer requires MSVC++ 5
* doc/guide.html: Likewise
2008-08-26 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: get_items bugfix (EJAB-716)
2008-08-25 Christophe Romain <christophe.romain@process-one.net>
* src/mod_privacy_odbc.erl: Prevent case_clause error when
ejabber_odbc:sql_query returns {error, Reason}
* src/mod_vcard_odbc.erl: Likewise
* src/mod_last_odbc.erl: Likewise
* src/mod_offline_odbc.erl: Likewise
2008-08-25 Badlop <badlop@process-one.net>
* src/ejabberd_check.erl: Detect correctly MSSQL and ODBC
configuration (EJAB-710)
2008-08-24 Geoff Cant <gcant@process-one.net>
* src/mod_mud/mod_muc_room.erl: is_visitor/2 fix - use get_role
not get_affiliation
2008-08-22 Badlop <badlop@process-one.net>
* src/ejabberd_router.erl: Fix call to mnesia match_object
2008-08-21 Badlop <badlop@process-one.net>
* doc/guide.tex: Fix names of chatroom to room, user to occupant
* doc/guide.html: Likewise
2008-08-18 Badlop <badlop@process-one.net>
* src/mod_muc/mod_muc_log.erl: MUC log files options: plaintext
format; filename with only room name (EJAB-596)
* doc/guide.tex: Document both options
* doc/guide.html: Likewise
* src/mod_register.erl: Change password using mod_register always
returns success regardless of real result (EJAB-723)
* src/ejabberd_auth.erl: Likewise
* src/ejabberd_auth_external.erl: Likewise
* src/ejabberd_auth_internal.erl: Likewise
* src/ejabberd_auth_odbc.erl: Likewise
2008-08-18 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/node_dispatch.erl: Fix call to unexported function
nodetree_default:get_subnodes/2
2008-08-17 Badlop <badlop@process-one.net>
* contrib/extract_translations/extract_translations.erl: Use
Gettext PO for translators, export to ejabberd MSG (EJAB-648)
* contrib/extract_translations/prepare-translation.sh: Likewise
* doc/guide.tex: Likewise
* doc/guide.html: Likewise
* src/Makefile.in: New option 'make translations'
* src/msgs/ejabberd.pot: Template translation file
* src/msgs/*.po: Generated from old MSG files
* src/msgs/*.msg: Automatic exported from PO files
2008-08-16 Badlop <badlop@process-one.net>
* src/msgs/sv.msg: Fixed formatting typos
* src/gen_mod.erl: Export stop_module_keep_config/2 (EJAB-706)
2008-08-14 Jean-Sébastien Pédron <js.pedron@meetic-corp.com> 2008-08-14 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
* translate.erl (ascii_tolower): Accept 'undefined' as a language and * translate.erl (ascii_tolower): Accept 'undefined' as a language and
@ -49,6 +158,25 @@
src/mod_disco.erl, src/mod_last.erl: Convert to the new #iq record src/mod_disco.erl, src/mod_last.erl: Convert to the new #iq record
from Exmpp. from Exmpp.
2008-08-13 Badlop <badlop@process-one.net>
* doc/guide.tex: Explain that LDAP is read-only storage (thanks to
Evgeniy Khramtsov)
* doc/guide.html: Likewise
2008-08-10 Badlop <badlop@process-one.net>
* src/msgs/eo.msg: Updated (thanks to Andreas van Cranenburgh)
* src/msgs/nl.msg: Updated (thanks to Andreas van Cranenburgh)
* src/msgs/sk.msg: Updated (thanks to Marek Becka)
* src/msgs/sv.msg: Updated (thanks to Thore Alstromer and Heysan)
2008-08-09 Badlop <badlop@process-one.net>
* src/ejabberd_service.erl: Fix XEP-0114 compliance: define xmlns
in header of error response; include in response the JID of served
component not server (thanks to Sergei Golovan)(EJAB-717)
2008-08-06 Jean-Sébastien Pédron <js.pedron@meetic-corp.com> 2008-08-06 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
* src/mod_offline.erl, src/mod_offline_odbc.erl, src/mod_echo.erl, * src/mod_offline.erl, src/mod_offline_odbc.erl, src/mod_echo.erl,
@ -65,11 +193,131 @@
src/mod_echo.erl, src/mod_offline.erl, src/mod_roster.erl, src/mod_echo.erl, src/mod_offline.erl, src/mod_roster.erl,
src/mod_vcard.erl: Update to use the new names used in exmpp_jid. src/mod_vcard.erl: Update to use the new names used in exmpp_jid.
2008-08-04 Jerome Sautret <jerome.sautret@process-one.net>
* src/odbc/ejabberd_odbc.erl: Restart the database connection when
it's lost or it reaches timeout with MySQL. Set transaction isolation level
to SERIALIZABLE when establishing connection to MySQL.
2008-08-01 Badlop <badlop@process-one.net>
* doc/release_notes_2.0.2.txt: Added for ejabberd 2.0.2-beta1
* src/web/ejabberd_http.erl: Temporary solution for check of
packet size when HTTPS (EJAB-611)(EJAB-507)(EJAB-574)
2008-07-31 Badlop <badlop@process-one.net>
* src/msgs/uk.msg: Fix: each string in a single line
* src/msgs/wa.msg: Likewise
* src/msgs/es.msg: Fix typo
* src/msgs/gl.msg: Likewise
* src/msgs/pt-br.msg: Likewise
* src/msgs/zh.msg: Fix some translations (thanks to Zhan Caibao)
* src/msgs/ca.msg: Updated (thanks to Badlop)
* src/msgs/cs.msg: Updated (thanks to Lukas Poliuvk)
* src/msgs/de.msg: Updated (thanks to Nikolaus Polak)
* src/msgs/es.msg: Updated (thanks to Badlop)
* src/msgs/fr.msg: Updated (thanks to Christophe Romain)
* src/msgs/it.msg: Updated (thanks to Luca Brivio)
* src/msgs/ja.msg: Updated (thanks to Tsukasa Hamano)
* src/msgs/no.msg: Updated (thanks to Stian B. Barmen)
* src/msgs/pl.msg: Updated (thanks to Zbyszek Zolkiewski)
* src/msgs/pt-br.msg: Updated (thanks to Otavio Fernandes)
* src/msgs/ru.msg: Updated (thanks to Evgeniy Khramtsov)
* src/msgs/tr.msg: Updated (thanks to Doruk Fisek)
* src/msgs/uk.msg: Updated (thanks to Ruslan Rakhmanin)
* src/msgs/wa.msg: Updated (thanks to Pablo Saratxaga)
* src/msgs/zh.msg: Updated (thanks to Shelley Shyan)
* README: Update location where mnesia, ebin and priv directories
are installed; install headers and doc (EJAB-696)
* doc/guide.tex: Update Process-one name to ProcessOne (EJAB-708)
* doc/guide.html: Likewise
* doc/api/overview.edoc: Likewise
* src/*/*.erl: Likewise
* src/*/*.hrl: Likewise
* src/*/*.c: Likewise
* src/odbc/*.sql: Likewise
2008-07-30 Badlop <badlop@process-one.net>
* src/mod_muc/mod_muc_room.erl: Support Reasons for all
affiliation and role changes (EJAB-306)
* src/gen_mod.erl: When ejabberd is kindly stopped, don't forget
modules configuration (EJAB-706)
* src/ejabberd_app.erl: Likewise
2008-07-28 Badlop <badlop@process-one.net>
* doc/guide.tex: Document how to get error message when ejabberd
crash dumps at start (EJAB-660)
* doc/guide.html: Likewise
2008-07-25 Jean-Sébastien Pédron <js.pedron@meetic-corp.com> 2008-07-25 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
* src/adhoc.erl, src/mod_configure.erl, src/mod_announce.erl, * src/adhoc.erl, src/mod_configure.erl, src/mod_announce.erl,
src/mod_adhoc.erl, src/gen_iq_handler.erl: Convert to exmpp. src/mod_adhoc.erl, src/gen_iq_handler.erl: Convert to exmpp.
2008-07-25 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: Speedup startup with many pubsub
nodes (EJAB-669)
* src/mod_pubsub/nodetree_default.erl: Likewise
2008-07-24 Badlop <badlop@process-one.net>
* doc/guide.tex: Include example PAM configuration file
ejabberd.pam (thanks to Evgeniy Khramtsov)(EJAB-704)
* doc/guide.html: Likewise
* src/mod_proxy65/mod_proxy65_lib.erl: Send protocol compliant
SOCKS5 reply; this breaks support of uncompliant Psi<0.10 (thanks
to Felix Geyer)(EJAB-632)
* src/mod_proxy65/mod_proxy65_stream.erl: Likewise
* src/mod_register.erl: When a registration is blocked due to IP
limitation, return description in error stanza (EJAB-692)
2008-07-24 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: Allow owner to subscribe/get its own
node (EJAB-705)
2008-07-24 Badlop <badlop@process-one.net>
* doc/guide.tex: Document room options allow_visitor_nickchange
and allow_visitor_status (EJAB-624)
* doc/guide.html: Likewise
2008-07-23 Geoff Cant <geoff.cant@process-one.net>
* src/mod_muc/mod_muc_room.erl: new room options,
allow_visitor_presence and allow_visitor_nickchange to
block/enable visitors to broadcast presence updates to the room
(EJAB-624).
* src/mod_muc/mod_muc_room.erl: renaming allow_visitor_presence to
allow_visitor_status and altering effect (when false) to remove
custom status tags in presence broadcasts to muc rooms by
visitors.
2008-07-23 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: remove_user hook removes
subscriptions (EJAB-684), send the last published and not the
first published item (EJAB-675), remove the pubsub/nodes tree,
subscribing to a node sends only last items (EJAB-700)
* src/mod_pubsub/node_pep.erl: added acl and jid match on node
creation permission (EJAB-663)
* src/mod_pubsub/node_default.erl: fix node creation permission
issue for service
* src/mod_pubsub/node_zoo.erl: Likewise
2008-07-22 Jean-Sébastien Pédron <js.pedron@meetic-corp.com> 2008-07-22 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
* src/mod_disco.erl, src/gen_iq_handler.erl: Convert to exmpp. * src/mod_disco.erl, src/gen_iq_handler.erl: Convert to exmpp.
@ -80,6 +328,15 @@
* src/ejabberd_local.erl (process_iq_reply): IQ handler are now always * src/ejabberd_local.erl (process_iq_reply): IQ handler are now always
called with arguments in the new format. called with arguments in the new format.
2008-07-22 Badlop <badlop@process-one.net>
* src/ejabberd_config.erl: If syntax mistake in config file, show
specific error message (EJAB-616)
2008-07-22 Alexey Shchepin <alexey@process-one.net>
* src/odbc/odbc_queries.erl: Fixed a typo
2008-07-21 Jean-Sébastien Pédron <js.pedron@meetic-corp.com> 2008-07-21 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
* src/gen_iq_handler.erl: Prepare gen_iq_handler to pass arguments in * src/gen_iq_handler.erl: Prepare gen_iq_handler to pass arguments in
@ -94,6 +351,15 @@
* src/jlib.erl: Add support for #xmlel to parse_xdata_submit/1 and * src/jlib.erl: Add support for #xmlel to parse_xdata_submit/1 and
friends. This fixes the user search in mod_vcard. friends. This fixes the user search in mod_vcard.
2008-07-03 Jerome Sautret <jerome.sautret@process-one.net>
* src/ejabberd_ctl.erl: Call reopen_log_hook for each virtual host.
2008-07-17 Badlop <badlop@process-one.net>
* src/mod_muc/mod_muc_room.erl: Fix to allow a server admin to add
himself as owner of a room (EJAB-687)
2008-07-17 Jean-Sébastien Pédron <js.pedron@meetic-corp.com> 2008-07-17 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
Merge revisions from 1444 to revision 1457 from trunk. Merge revisions from 1444 to revision 1457 from trunk.

6
README
View File

@ -30,9 +30,11 @@ To install ejabberd, run this command with system administrator rights
sudo make install sudo make install
These commands will: These commands will:
- Install a startup script: /sbin/ejabberdctl
- Install ejabberd in /var/lib/ejabberd/
- Install the configuration files in /etc/ejabberd/ - Install the configuration files in /etc/ejabberd/
- Install ejabberd binary, header and runtime files in /lib/ejabberd/
- Install the administration script: /sbin/ejabberdctl
- Install ejabberd documentation in /share/doc/ejabberd/
- Create a spool directory: /var/lib/ejabberd/
- Create a directory for log files: /var/log/ejabberd/ - Create a directory for log files: /var/log/ejabberd/

View File

@ -1,5 +1,5 @@
% List of ejabberd-modules to add for ejabberd packaging (source archive and installer) % List of ejabberd-modules to add for ejabberd packaging (source archive and installer)
% %
% HTTP-binding: % HTTP-binding:
https://svn.process-one.net/ejabberd-modules/http_bind/tags/ejabberd-2.0.0-beta1 https://svn.process-one.net/ejabberd-modules/http_bind/trunk
https://svn.process-one.net/ejabberd-modules/mod_http_fileserver/tags/ejabberd-2.0.0-beta1 https://svn.process-one.net/ejabberd-modules/mod_http_fileserver/trunk

View File

@ -20,9 +20,14 @@
start() -> start() ->
ets:new(translations, [named_table, public]), ets:new(translations, [named_table, public]),
ets:new(translations_obsolete, [named_table, public]),
ets:new(files, [named_table, public]), ets:new(files, [named_table, public]),
ets:new(vars, [named_table, public]), ets:new(vars, [named_table, public]),
case init:get_plain_arguments() of case init:get_plain_arguments() of
["-srcmsg2po", Dir, File] ->
print_po_header(File),
Status = process(Dir, File, srcmsg2po),
halt(Status);
["-unused", Dir, File] -> ["-unused", Dir, File] ->
Status = process(Dir, File, unused), Status = process(Dir, File, unused),
halt(Status); halt(Status);
@ -51,6 +56,10 @@ process(Dir, File, Used) ->
ets:foldl(fun({Key, _}, _) -> ets:foldl(fun({Key, _}, _) ->
io:format("~p~n", [Key]) io:format("~p~n", [Key])
end, ok, translations); end, ok, translations);
srcmsg2po ->
ets:foldl(fun({Key, Trans}, _) ->
print_translation_obsolete(Key, Trans)
end, ok, translations_obsolete);
_ -> _ ->
ok ok
end, end,
@ -74,26 +83,26 @@ parse_form(Dir, File, Form, Used) ->
{call, {call,
_, _,
{remote, _, {atom, _, translate}, {atom, _, translate}}, {remote, _, {atom, _, translate}, {atom, _, translate}},
[_, {string, _, Str}] [_, {string, Line, Str}]
} -> } ->
process_string(Dir, File, Str, Used); process_string(Dir, File, Line, Str, Used);
{call, {call,
_, _,
{remote, _, {atom, _, translate}, {atom, _, translate}}, {remote, _, {atom, _, translate}, {atom, _, translate}},
[_, {var, _, Name}] [_, {var, _, Name}]
} -> } ->
case ets:lookup(vars, Name) of case ets:lookup(vars, Name) of
[{_Name, Value}] -> [{_Name, Value, Line}] ->
process_string(Dir, File, Value, Used); process_string(Dir, File, Line, Value, Used);
_ -> _ ->
ok ok
end; end;
{match, {match,
_, _,
{var, _, Name}, {var, _, Name},
{string, _, Value} {string, Line, Value}
} -> } ->
ets:insert(vars, {Name, Value}); ets:insert(vars, {Name, Value, Line});
L when is_list(L) -> L when is_list(L) ->
lists:foreach( lists:foreach(
fun(F) -> fun(F) ->
@ -108,12 +117,18 @@ parse_form(Dir, File, Form, Used) ->
ok ok
end. end.
process_string(_Dir, File, Str, Used) -> process_string(_Dir, _File, _Line, "", _Used) ->
ok;
process_string(_Dir, File, Line, Str, Used) ->
case {ets:lookup(translations, Str), Used} of case {ets:lookup(translations, Str), Used} of
{[{_Key, _Trans}], unused} -> {[{_Key, _Trans}], unused} ->
ets:delete(translations, Str); ets:delete(translations, Str);
{[{_Key, _Trans}], used} -> {[{_Key, _Trans}], used} ->
ok; ok;
{[{_Key, Trans}], srcmsg2po} ->
ets:delete(translations_obsolete, Str),
print_translation(File, Line, Str, Trans);
{_, used} -> {_, used} ->
case ets:lookup(files, File) of case ets:lookup(files, File) of
[{_}] -> [{_}] ->
@ -127,6 +142,15 @@ process_string(_Dir, File, Str, Used) ->
_ -> io:format("{~p, \"\"}.~n", [Str]) _ -> io:format("{~p, \"\"}.~n", [Str])
end, end,
ets:insert(translations, {Str, ""}); ets:insert(translations, {Str, ""});
{_, srcmsg2po} ->
case ets:lookup(files, File) of
[{_}] ->
ok;
_ ->
ets:insert(files, {File})
end,
ets:insert(translations, {Str, ""}),
print_translation(File, Line, Str, "");
_ -> _ ->
ok ok
end. end.
@ -140,7 +164,8 @@ load_file(File) ->
"" -> "" ->
ok; ok;
_ -> _ ->
ets:insert(translations, {Orig, Trans}) ets:insert(translations, {Orig, Trans}),
ets:insert(translations_obsolete, {Orig, Trans})
end end
end, Terms); end, Terms);
Err -> Err ->
@ -191,3 +216,77 @@ print_usage() ->
" extract_translations . ./msgs/ru.msg~n" " extract_translations . ./msgs/ru.msg~n"
). ).
%%%
%%% Gettext
%%%
print_po_header(File) ->
MsgProps = get_msg_header_props(File),
{Language, [LastT | AddT]} = prepare_props(MsgProps),
application:load(ejabberd),
{ok, Version} = application:get_key(ejabberd, vsn),
print_po_header(Version, Language, LastT, AddT).
get_msg_header_props(File) ->
{ok, F} = file:open(File, [read]),
Lines = get_msg_header_props(F, []),
file:close(F),
Lines.
get_msg_header_props(F, Lines) ->
String = io:get_line(F, ""),
case io_lib:fread("% ", String) of
{ok, [], RemString} ->
case io_lib:fread("~s", RemString) of
{ok, [Key], Value} when Value /= "\n" ->
%% The first character in Value is a blankspace:
%% And the last characters are 'slash n'
ValueClean = string:substr(Value, 2, string:len(Value)-2),
get_msg_header_props(F, Lines ++ [{Key, ValueClean}]);
_ ->
get_msg_header_props(F, Lines)
end;
_ ->
Lines
end.
prepare_props(MsgProps) ->
Language = proplists:get_value("Language:", MsgProps),
Authors = proplists:get_all_values("Author:", MsgProps),
{Language, Authors}.
print_po_header(Version, Language, LastTranslator, AdditionalTranslatorsList) ->
AdditionalTranslatorsString = build_additional_translators(AdditionalTranslatorsList),
HeaderString =
"msgid \"\"\n"
"msgstr \"\"\n"
"\"Project-Id-Version: " ++ Version ++ "\\n\"\n"
++ "\"X-Language: " ++ Language ++ "\\n\"\n"
"\"Last-Translator: " ++ LastTranslator ++ "\\n\"\n"
++ AdditionalTranslatorsString ++
"\"MIME-Version: 1.0\\n\"\n"
"\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
"\"Content-Transfer-Encoding: 8bit\\n\"\n",
io:format("~s~n", [HeaderString]).
build_additional_translators(List) ->
lists:foldl(
fun(T, Str) ->
Str ++ "\"X-Additional-Translator: " ++ T ++ "\\n\"\n"
end,
"",
List).
print_translation(File, Line, Str, StrT) ->
{ok, StrQ, _} = regexp:gsub(Str, "\"", "\\\""),
{ok, StrTQ, _} = regexp:gsub(StrT, "\"", "\\\""),
io:format("#: ~s:~p~nmsgid \"~s\"~nmsgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
print_translation_obsolete(Str, StrT) ->
File = "unknown.erl",
Line = 1,
{ok, StrQ, _} = regexp:gsub(Str, "\"", "\\\""),
{ok, StrTQ, _} = regexp:gsub(StrT, "\"", "\\\""),
io:format("#: ~s:~p~n#~~ msgid \"~s\"~n#~~ msgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).

View File

@ -8,10 +8,10 @@ prepare_dirs ()
# Where is Erlang binary # Where is Erlang binary
ERL=`which erl` ERL=`which erl`
EJA_DIR=`pwd`/../.. EJA_DIR=`pwd`/..
EXTRACT_DIR=$EJA_DIR/contrib/extract_translations/ EXTRACT_DIR=$EJA_DIR/contrib/extract_translations/
EXTRACT_ERL=extract_translations.erl EXTRACT_ERL=$EXTRACT_DIR/extract_translations.erl
EXTRACT_BEAM=extract_translations.beam EXTRACT_BEAM=$EXTRACT_DIR/extract_translations.beam
SRC_DIR=$EJA_DIR/src SRC_DIR=$EJA_DIR/src
MSGS_DIR=$SRC_DIR/msgs MSGS_DIR=$SRC_DIR/msgs
@ -22,9 +22,7 @@ prepare_dirs ()
if !([[ -x $EXTRACT_BEAM ]]) if !([[ -x $EXTRACT_BEAM ]])
then then
echo -n "Compiling extract_translations.erl: "
sh -c "cd $EXTRACT_DIR; $ERL -compile $EXTRACT_ERL" sh -c "cd $EXTRACT_DIR; $ERL -compile $EXTRACT_ERL"
echo "ok"
fi fi
} }
@ -140,6 +138,116 @@ find_unused_full ()
cd .. cd ..
} }
extract_lang_srcmsg2po ()
{
LANG_CODE=$1
MSGS_PATH=$MSGS_DIR/$LANG_CODE.msg
PO_PATH=$MSGS_DIR/$LANG_CODE.po
$ERL -pa $EXTRACT_DIR -pa $SRC_DIR -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$PO_PATH.1
sed -e 's/ \[\]$/ \"\"/g;' $PO_PATH.1 > $PO_PATH.2
msguniq --sort-by-file $PO_PATH.2 --output-file=$PO_PATH
rm $PO_PATH.*
}
extract_lang_src2pot ()
{
LANG_CODE=ejabberd
MSGS_PATH=$MSGS_DIR/$LANG_CODE.msg
POT_PATH=$MSGS_DIR/$LANG_CODE.pot
echo -n "" >$MSGS_PATH
echo "% Language: Language Name" >>$MSGS_PATH
echo "% Author: Translator name and contact method" >>$MSGS_PATH
echo "" >>$MSGS_PATH
cd $SRC_DIR
$ERL -pa $EXTRACT_DIR -pa $SRC_DIR -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$POT_PATH.1
sed -e 's/ \[\]$/ \"\"/g;' $POT_PATH.1 > $POT_PATH.2
msguniq --sort-by-file $POT_PATH.2 --output-file=$POT_PATH
rm $POT_PATH.*
rm $MSGS_PATH
}
extract_lang_popot2po ()
{
LANG_CODE=$1
PO_PATH=$MSGS_DIR/$LANG_CODE.po
POT_PATH=$MSGS_DIR/ejabberd.pot
msgmerge $PO_PATH $POT_PATH >$PO_PATH.translate 2>/dev/null
mv $PO_PATH.translate $PO_PATH
}
extract_lang_po2msg ()
{
LANG_CODE=$1
PO_PATH=$LANG_CODE.po
MS_PATH=$PO_PATH.ms
MSGID_PATH=$PO_PATH.msgid
MSGSTR_PATH=$PO_PATH.msgstr
MSGS_PATH=$LANG_CODE.msg
cd $MSGS_DIR
# Check PO has correct ~
# Let's convert to C format so we can use msgfmt
PO_TEMP=$LANG_CODE.po.temp
cat $PO_PATH | sed 's/%/perc/g' | sed 's/~/%/g' | sed 's/#:.*/#, c-format/g' >$PO_TEMP
msgfmt $PO_TEMP --check-format
result=$?
rm $PO_TEMP
if [ $result -ne 0 ] ; then
exit 1
fi
msgattrib $PO_PATH --translated --no-fuzzy --no-obsolete --no-location --no-wrap | grep "^msg" | tail --lines=+3 >$MS_PATH
grep "^msgid" $PO_PATH.ms | sed 's/^msgid //g' >$MSGID_PATH
grep "^msgstr" $PO_PATH.ms | sed 's/^msgstr //g' >$MSGSTR_PATH
paste $MSGID_PATH $MSGSTR_PATH --delimiter=, | awk '{print "{" $0 "}."}' | sort -g >$MSGS_PATH
rm $MS_PATH
rm $MSGID_PATH
rm $MSGSTR_PATH
}
extract_lang_updateall ()
{
echo "Generating POT"
extract_lang_src2pot
cd $MSGS_DIR
echo ""
echo -e "File Missing Language Last translator"
echo -e "---- ------- -------- ---------------"
for i in *.msg; do
LANG_CODE=${i%.msg}
echo -n $LANG_CODE | awk '{printf "%-6s", $1 }'
# Convert old MSG file to PO
PO=$LANG_CODE.po
[ -f $PO ] || extract_lang_srcmsg2po $LANG_CODE
extract_lang_popot2po $LANG_CODE
extract_lang_po2msg $LANG_CODE
MISSING=`msgfmt --statistics $PO 2>&1 | awk '{printf "%5s", $4 }'`
echo -n " $MISSING"
LANGUAGE=`grep "Language:" $PO | sed 's/\"X-Language: //g' | sed 's/\\\\n\"//g' | awk '{printf "%-12s", $1}'`
echo -n " $LANGUAGE"
LASTAUTH=`grep "Last-Translator" $PO | sed 's/\"Last-Translator: //g' | sed 's/\\\\n\"//g'`
echo " $LASTAUTH"
done
echo ""
rm messages.mo
cd ..
}
translation_instructions () translation_instructions ()
{ {
echo "" echo ""
@ -158,34 +266,56 @@ translation_instructions ()
echo " $MSGS_PATH" echo " $MSGS_PATH"
} }
prepare_dirs
case "$1" in case "$1" in
-help)
echo "Options:"
echo " -langall"
echo " -lang LANGUAGE_FILE"
echo ""
echo "Example:"
echo " ./prepare-translation.sh -lang es.msg"
exit 0
;;
-lang) -lang)
LANGU=$2 LANGU=$2
prepare_dirs
extract_lang $LANGU extract_lang $LANGU
shift shift
shift shift
;; ;;
-langall) -langall)
prepare_dirs
extract_lang_all extract_lang_all
shift shift
;; ;;
*) -srcmsg2po)
echo "unknown option: '$1 $2'" LANG_CODE=$2
extract_lang_srcmsg2po $LANG_CODE
shift shift
shift shift
;; ;;
esac -popot2po)
LANG_CODE=$2
extract_lang_popot2po $LANG_CODE
shift
shift
;;
-src2pot)
extract_lang_src2pot
shift
;;
-po2msg)
LANG_CODE=$2
extract_lang_po2msg $LANG_CODE
shift
shift
;;
-updateall)
extract_lang_updateall
shift
;;
*)
echo "Options:"
echo " -langall"
echo " -lang LANGUAGE_FILE"
echo " -srcmsg2po LANGUAGE Construct .msg file using source code to PO file"
echo " -src2pot Generate template POT file from source code"
echo " -popot2po LANGUAGE Update PO file with template POT file"
echo " -po2msg LANGUAGE Export PO file to MSG file"
echo " -updateall Generate POT and update all PO"
echo "" echo ""
echo "End." echo "Example:"
echo " ./prepare-translation.sh -lang es.msg"
exit 0
;;
esac

View File

@ -1,6 +1,6 @@
@author Mickael Remond <mickael.remond@process-one.net> @author Mickael Remond <mickael.remond@process-one.net>
[http://www.process-one.net/] [http://www.process-one.net/]
@copyright 2007 Process-one @copyright 2007 ProcessOne
@version {@vsn}, {@date} {@time} @version {@vsn}, {@date} {@time}
@title ejabberd Development API Documentation @title ejabberd Development API Documentation

View File

@ -272,9 +272,9 @@ Support for virtual hosting.
</LI></UL><P> <A NAME="installing"></A> </P><!--TOC chapter Installing <TT>ejabberd</TT>--> </LI></UL><P> <A NAME="installing"></A> </P><!--TOC chapter Installing <TT>ejabberd</TT>-->
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc4">Chapter&#XA0;2</A>&#XA0;&#XA0;<A HREF="#installing">Installing <TT>ejabberd</TT></A></H1><!--SEC END --><P> <A NAME="installing"></A> </P><P> <A NAME="install.binary"></A> </P><!--TOC section Installing <TT>ejabberd</TT> with Binary Installer--> <H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc4">Chapter&#XA0;2</A>&#XA0;&#XA0;<A HREF="#installing">Installing <TT>ejabberd</TT></A></H1><!--SEC END --><P> <A NAME="installing"></A> </P><P> <A NAME="install.binary"></A> </P><!--TOC section Installing <TT>ejabberd</TT> with Binary Installer-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc5">2.1</A>&#XA0;&#XA0;<A HREF="#install.binary">Installing <TT>ejabberd</TT> with Binary Installer</A></H2><!--SEC END --><P> <A NAME="install.binary"></A> </P><P>Probably the easiest way to install an <TT>ejabberd</TT> instant messaging server <H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc5">2.1</A>&#XA0;&#XA0;<A HREF="#install.binary">Installing <TT>ejabberd</TT> with Binary Installer</A></H2><!--SEC END --><P> <A NAME="install.binary"></A> </P><P>Probably the easiest way to install an <TT>ejabberd</TT> instant messaging server
is using the binary installer published by Process-one. is using the binary installer published by ProcessOne.
The binary installers of released <TT>ejabberd</TT> versions The binary installers of released <TT>ejabberd</TT> versions
are available in the Process-one <TT>ejabberd</TT> downloads page: are available in the ProcessOne <TT>ejabberd</TT> downloads page:
<A HREF="http://www.process-one.net/en/ejabberd/downloads"><TT>http://www.process-one.net/en/ejabberd/downloads</TT></A></P><P>The installer will deploy and configure a full featured <TT>ejabberd</TT> <A HREF="http://www.process-one.net/en/ejabberd/downloads"><TT>http://www.process-one.net/en/ejabberd/downloads</TT></A></P><P>The installer will deploy and configure a full featured <TT>ejabberd</TT>
server and does not require any extra dependencies.</P><P>In *nix systems, remember to set executable the binary installer before starting it. For example: server and does not require any extra dependencies.</P><P>In *nix systems, remember to set executable the binary installer before starting it. For example:
</P><PRE CLASS="verbatim">chmod +x ejabberd-2.0.0_1-linux-x86-installer.bin </P><PRE CLASS="verbatim">chmod +x ejabberd-2.0.0_1-linux-x86-installer.bin
@ -290,7 +290,19 @@ go to the Windows service settings and set ejabberd to be automatically started.
Note that the Windows service is a feature still in development, Note that the Windows service is a feature still in development,
and for example it doesn&#X2019;t read the file ejabberdctl.cfg.</P><P>On a *nix system, if you want ejabberd to be started as daemon at boot time, and for example it doesn&#X2019;t read the file ejabberdctl.cfg.</P><P>On a *nix system, if you want ejabberd to be started as daemon at boot time,
copy <TT>ejabberd.init</TT> from the &#X2019;bin&#X2019; directory to something like <TT>/etc/init.d/ejabberd</TT> copy <TT>ejabberd.init</TT> from the &#X2019;bin&#X2019; directory to something like <TT>/etc/init.d/ejabberd</TT>
(depending on your distribution) and call <TT>/etc/inid.d/ejabberd start</TT> to start it.</P><P>The <TT>ejabberdctl</TT> administration script is included in the <TT>bin</TT> directory. (depending on your distribution) and call <TT>/etc/inid.d/ejabberd start</TT> to start it.</P><P>If <TT>ejabberd</TT> doesn&#X2019;t start correctly in Windows,
try to start it using the shortcut in desktop or start menu.
If the window shows error 14001, the solution is to install:
"Microsoft Visual C++ 2005 SP1 Redistributable Package".
You can download it from
<A HREF="http://www.microsoft.com/">www.microsoft.com</A>.
Then uninstall <TT>ejabberd</TT> and install it again.</P><P>If <TT>ejabberd</TT> doesn&#X2019;t start correctly and a crash dump is generated,
there was a severe problem.
You can try starting <TT>ejabberd</TT> with
the script <TT>bin/live.bat</TT> in Windows,
or with the command <TT>bin/ejabberdctl live</TT> in other Operating Systems.
This way you see the error message provided by Erlang
and can identify what is exactly the problem.</P><P>The <TT>ejabberdctl</TT> administration script is included in the <TT>bin</TT> directory.
Please refer to the section&#XA0;<A HREF="#ejabberdctl">4.1</A> for details about <TT>ejabberdctl</TT>, Please refer to the section&#XA0;<A HREF="#ejabberdctl">4.1</A> for details about <TT>ejabberdctl</TT>,
and configurable options to fine tune the Erlang runtime system.</P><P> <A NAME="install.os"></A> </P><!--TOC section Installing <TT>ejabberd</TT> with Operating System specific packages--> and configurable options to fine tune the Erlang runtime system.</P><P> <A NAME="install.os"></A> </P><!--TOC section Installing <TT>ejabberd</TT> with Operating System specific packages-->
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc6">2.2</A>&#XA0;&#XA0;<A HREF="#install.os">Installing <TT>ejabberd</TT> with Operating System specific packages</A></H2><!--SEC END --><P> <A NAME="install.os"></A> </P><P>Some Operating Systems provide a specific <TT>ejabberd</TT> package adapted to <H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc6">2.2</A>&#XA0;&#XA0;<A HREF="#install.os">Installing <TT>ejabberd</TT> with Operating System specific packages</A></H2><!--SEC END --><P> <A NAME="install.os"></A> </P><P>Some Operating Systems provide a specific <TT>ejabberd</TT> package adapted to
@ -324,7 +336,7 @@ GNU Make
</LI><LI CLASS="li-itemize">GNU Iconv 1.8 or higher, for the IRC Transport (mod_irc). Optional. Not needed on systems with GNU Libc. </LI><LI CLASS="li-itemize">GNU Iconv 1.8 or higher, for the IRC Transport (mod_irc). Optional. Not needed on systems with GNU Libc.
</LI></UL><P> <A NAME="download"></A> </P><!--TOC subsection Download Source Code--> </LI></UL><P> <A NAME="download"></A> </P><!--TOC subsection Download Source Code-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc10">2.4.2</A>&#XA0;&#XA0;<A HREF="#download">Download Source Code</A></H3><!--SEC END --><P> <A NAME="download"></A> <H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc10">2.4.2</A>&#XA0;&#XA0;<A HREF="#download">Download Source Code</A></H3><!--SEC END --><P> <A NAME="download"></A>
</P><P>Released versions of <TT>ejabberd</TT> are available in the Process-one <TT>ejabberd</TT> downloads page: </P><P>Released versions of <TT>ejabberd</TT> are available in the ProcessOne <TT>ejabberd</TT> downloads page:
<A HREF="http://www.process-one.net/en/ejabberd/downloads"><TT>http://www.process-one.net/en/ejabberd/downloads</TT></A></P><P> <A HREF="http://www.process-one.net/en/ejabberd/downloads"><TT>http://www.process-one.net/en/ejabberd/downloads</TT></A></P><P>
Alternatively, the latest development version can be retrieved from the Subversion repository using this command: Alternatively, the latest development version can be retrieved from the Subversion repository using this command:
</P><PRE CLASS="verbatim">svn co http://svn.process-one.net/ejabberd/trunk ejabberd </P><PRE CLASS="verbatim">svn co http://svn.process-one.net/ejabberd/trunk ejabberd
@ -405,7 +417,12 @@ Node ejabberd@localhost is started. Status: started
ejabberd is running ejabberd is running
ejabberdctl stop ejabberdctl stop
</PRE><P>Please refer to the section&#XA0;<A HREF="#ejabberdctl">4.1</A> for details about <TT>ejabberdctl</TT>, </PRE><P>If <TT>ejabberd</TT> doesn&#X2019;t start correctly and a crash dump is generated,
there was a severe problem.
You can try starting <TT>ejabberd</TT> with
the command <TT>ejabberdctl live</TT>
to see the error message provided by Erlang
and can identify what is exactly the problem.</P><P>Please refer to the section&#XA0;<A HREF="#ejabberdctl">4.1</A> for details about <TT>ejabberdctl</TT>,
and configurable options to fine tune the Erlang runtime system.</P><P> <A NAME="bsd"></A> </P><!--TOC subsection Specific Notes for BSD--> and configurable options to fine tune the Erlang runtime system.</P><P> <A NAME="bsd"></A> </P><!--TOC subsection Specific Notes for BSD-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc14">2.4.6</A>&#XA0;&#XA0;<A HREF="#bsd">Specific Notes for BSD</A></H3><!--SEC END --><P> <A NAME="bsd"></A> <H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc14">2.4.6</A>&#XA0;&#XA0;<A HREF="#bsd">Specific Notes for BSD</A></H3><!--SEC END --><P> <A NAME="bsd"></A>
</P><P>The command to compile <TT>ejabberd</TT> in BSD systems is: </P><P>The command to compile <TT>ejabberd</TT> in BSD systems is:
@ -976,8 +993,12 @@ version, you can <TT>kill(1)</TT> <TT>epam</TT> process periodically to reduce i
consumption: <TT>ejabberd</TT> will restart this process immediately. consumption: <TT>ejabberd</TT> will restart this process immediately.
</LI><LI CLASS="li-itemize"><TT>epam</TT> program tries to turn off delays on authentication failures. </LI><LI CLASS="li-itemize"><TT>epam</TT> program tries to turn off delays on authentication failures.
However, some PAM modules ignore this behavior and rely on their own configuration options. However, some PAM modules ignore this behavior and rely on their own configuration options.
The example configuration file <TT>ejabberd.pam</TT> shows how to turn off delays in You can create a configuration file <TT>ejabberd.pam</TT>.
<TT>pam_unix.so</TT> module. It is not a ready to use configuration file: you must use it This example shows how to turn off delays in <TT>pam_unix.so</TT> module:
<PRE CLASS="verbatim">#%PAM-1.0
auth sufficient pam_unix.so likeauth nullok nodelay
account sufficient pam_unix.so
</PRE>That is not a ready to use configuration file: you must use it
as a hint when building your own PAM configuration instead. Note that if you want to disable as a hint when building your own PAM configuration instead. Note that if you want to disable
delays on authentication failures in the PAM configuration file, you have to restrict access delays on authentication failures in the PAM configuration file, you have to restrict access
to this file, so a malicious user can&#X2019;t use your configuration to perform brute-force to this file, so a malicious user can&#X2019;t use your configuration to perform brute-force
@ -1113,7 +1134,7 @@ To define a shaper named &#X2018;<TT>normal</TT>&#X2019; with traffic speed limi
</PRE></LI></UL><P> <A NAME="language"></A> </P><!--TOC subsection Default Language--> </PRE></LI></UL><P> <A NAME="language"></A> </P><!--TOC subsection Default Language-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc27">3.1.7</A>&#XA0;&#XA0;<A HREF="#language">Default Language</A></H3><!--SEC END --><P> <A NAME="language"></A> <H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc27">3.1.7</A>&#XA0;&#XA0;<A HREF="#language">Default Language</A></H3><!--SEC END --><P> <A NAME="language"></A>
</P><P>The option <TT>language</TT> defines the default language of server strings that </P><P>The option <TT>language</TT> defines the default language of server strings that
can be seen by Jabber clients. If a Jabber client do not support can be seen by Jabber clients. If a Jabber client does not support
<TT>xml:lang</TT>, the specified language is used. The default value is <TT>xml:lang</TT>, the specified language is used. The default value is
<TT>en</TT>. In order to take effect there must be a translation file <TT>en</TT>. In order to take effect there must be a translation file
<TT>&lt;language&gt;.msg</TT> in <TT>ejabberd</TT>&#X2019;s <TT>msgs</TT> directory.</P><P>Examples: <TT>&lt;language&gt;.msg</TT> in <TT>ejabberd</TT>&#X2019;s <TT>msgs</TT> directory.</P><P>Examples:
@ -1122,7 +1143,7 @@ To set Russian as default language:
<PRE CLASS="verbatim">{language, "ru"}. <PRE CLASS="verbatim">{language, "ru"}.
</PRE></LI><LI CLASS="li-itemize">To set Spanish as default language: </PRE></LI><LI CLASS="li-itemize">To set Spanish as default language:
<PRE CLASS="verbatim">{language, "es"}. <PRE CLASS="verbatim">{language, "es"}.
</PRE></LI></UL><P> <A NAME="includeconfigfile"></A> </P><!--TOC subsection Include Additional Configuration Files--> </PRE></LI></UL><P>Appendix <A HREF="#i18ni10n">A</A> provides more details about internationalization and localization.</P><P> <A NAME="includeconfigfile"></A> </P><!--TOC subsection Include Additional Configuration Files-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc28">3.1.8</A>&#XA0;&#XA0;<A HREF="#includeconfigfile">Include Additional Configuration Files</A></H3><!--SEC END --><P> <A NAME="includeconfigfile"></A> <H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc28">3.1.8</A>&#XA0;&#XA0;<A HREF="#includeconfigfile">Include Additional Configuration Files</A></H3><!--SEC END --><P> <A NAME="includeconfigfile"></A>
</P><P>The option <TT>include_config_file</TT> in a configuration file instructs <TT>ejabberd</TT> to include other configuration files immediately.</P><P>The basic usage is: </P><P>The option <TT>include_config_file</TT> in a configuration file instructs <TT>ejabberd</TT> to include other configuration files immediately.</P><P>The basic usage is:
</P><PRE CLASS="verbatim">{include_config_file, &lt;filename&gt;}. </P><PRE CLASS="verbatim">{include_config_file, &lt;filename&gt;}.
@ -1422,7 +1443,9 @@ module loaded!</P><P> <A NAME="ldap"></A> </P><!--TOC subsection LDAP-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc35">3.2.5</A>&#XA0;&#XA0;<A HREF="#ldap">LDAP</A></H3><!--SEC END --><P> <A NAME="ldap"></A> <H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc35">3.2.5</A>&#XA0;&#XA0;<A HREF="#ldap">LDAP</A></H3><!--SEC END --><P> <A NAME="ldap"></A>
</P><P><TT>ejabberd</TT> has built-in LDAP support. You can authenticate users against LDAP </P><P><TT>ejabberd</TT> has built-in LDAP support. You can authenticate users against LDAP
server and use LDAP directory as vCard storage. Shared rosters are not supported server and use LDAP directory as vCard storage. Shared rosters are not supported
yet.</P><P> <A NAME="ldapconnection"></A> </P><!--TOC subsubsection Connection--> yet.</P><P>Note that <TT>ejabberd</TT> treats LDAP as a read-only storage:
it is possible to consult data, but not possible to
create accounts, change password or edit vCard that is stored in LDAP.</P><P> <A NAME="ldapconnection"></A> </P><!--TOC subsubsection Connection-->
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#ldapconnection">Connection</A></H4><!--SEC END --><P> <A NAME="ldapconnection"></A> </P><P>Parameters: <H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#ldapconnection">Connection</A></H4><!--SEC END --><P> <A NAME="ldapconnection"></A> </P><P>Parameters:
</P><DL CLASS="description"><DT CLASS="dt-description"> </P><DL CLASS="description"><DT CLASS="dt-description">
<B><TT>ldap_servers</TT></B></DT><DD CLASS="dd-description"> List of IP addresses or DNS names of your <B><TT>ldap_servers</TT></B></DT><DD CLASS="dd-description"> List of IP addresses or DNS names of your
@ -1928,23 +1951,22 @@ connected user was last active on the server, or to query the uptime of the
the processing discipline for Last activity (<TT>jabber:iq:last</TT>) IQ queries (see section&#XA0;<A HREF="#modiqdiscoption">3.3.2</A>). the processing discipline for Last activity (<TT>jabber:iq:last</TT>) IQ queries (see section&#XA0;<A HREF="#modiqdiscoption">3.3.2</A>).
</DD></DL><P> <A NAME="modmuc"></A> </P><!--TOC subsection <TT>mod_muc</TT>--> </DD></DL><P> <A NAME="modmuc"></A> </P><!--TOC subsection <TT>mod_muc</TT>-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc44">3.3.8</A>&#XA0;&#XA0;<A HREF="#modmuc"><TT>mod_muc</TT></A></H3><!--SEC END --><P> <A NAME="modmuc"></A> <H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc44">3.3.8</A>&#XA0;&#XA0;<A HREF="#modmuc"><TT>mod_muc</TT></A></H3><!--SEC END --><P> <A NAME="modmuc"></A>
</P><P>With this module enabled, your server will support Multi-User Chat </P><P>This module provides a Multi-User Chat (<A HREF="http://www.xmpp.org/extensions/xep-0045.html">XEP-0045</A>) service.
(<A HREF="http://www.xmpp.org/extensions/xep-0045.html">XEP-0045</A>). End users will be able to join text conferences.</P><P>Some of the features of Multi-User Chat: Users can discover existing rooms, join or create them.
Occupants of a room can chat in public or have private chats.</P><P>Some of the features of Multi-User Chat:
</P><UL CLASS="itemize"><LI CLASS="li-itemize"> </P><UL CLASS="itemize"><LI CLASS="li-itemize">
Sending private messages to room participants. Sending public and private messages to room occupants.
</LI><LI CLASS="li-itemize">Inviting users. </LI><LI CLASS="li-itemize">Inviting other users to a room.
</LI><LI CLASS="li-itemize">Setting a conference topic. </LI><LI CLASS="li-itemize">Setting a room subject.
</LI><LI CLASS="li-itemize">Creating password protected rooms. </LI><LI CLASS="li-itemize">Creating password protected rooms.
</LI><LI CLASS="li-itemize">Kicking and banning participants. </LI><LI CLASS="li-itemize">Kicking and banning occupants.
</LI></UL><P>The MUC service allows any Jabber ID to register a nickname, </LI></UL><P>The MUC service allows any Jabber ID to register a nickname,
so nobody else can use that nickname in any room in the MUC service. so nobody else can use that nickname in any room in the MUC service.
To register a nickname, open the Service Discovery in your To register a nickname, open the Service Discovery in your
Jabber client and Register in the MUC service.</P><P>The MUC service allows the service administrator to send a message Jabber client and register in the MUC service.</P><P>This module supports clustering and load
to all existing chatrooms.
To do so, send the message to the Jabber ID of the MUC service.</P><P>This module supports clustering and load
balancing. One module can be started per cluster node. Rooms are balancing. One module can be started per cluster node. Rooms are
distributed at creation time on all available MUC module distributed at creation time on all available MUC module
instances. The multi-user chat module is clustered but the room instances. The multi-user chat module is clustered but the rooms
themselves are not clustered nor fault-tolerant: if the node managing a themselves are not clustered nor fault-tolerant: if the node managing a
set of rooms goes down, the rooms disappear and they will be recreated set of rooms goes down, the rooms disappear and they will be recreated
on an available node on first connection attempt.</P><P>Module options: on an available node on first connection attempt.</P><P>Module options:
@ -1956,19 +1978,19 @@ hostname of the virtual host with the prefix &#X2018;<TT>conference.</TT>&#X2019
is replaced at start time with the real virtual host name. is replaced at start time with the real virtual host name.
</DD><DT CLASS="dt-description"><B><TT>access</TT></B></DT><DD CLASS="dd-description"> You can specify who is allowed to use </DD><DT CLASS="dt-description"><B><TT>access</TT></B></DT><DD CLASS="dd-description"> You can specify who is allowed to use
the Multi-User Chat service (by default, everyone is allowed to use it). the Multi-User Chat service. By default everyone is allowed to use it.
</DD><DT CLASS="dt-description"><B><TT>access_create</TT></B></DT><DD CLASS="dd-description"> To configure who is </DD><DT CLASS="dt-description"><B><TT>access_create</TT></B></DT><DD CLASS="dd-description"> To configure who is
allowed to create new rooms at the Multi-User Chat service, this option allowed to create new rooms at the Multi-User Chat service, this option
can be used (by default, everybody is allowed to create rooms). can be used. By default everybody is allowed to create rooms.
</DD><DT CLASS="dt-description"><B><TT>access_persistent</TT></B></DT><DD CLASS="dd-description"> To configure who is </DD><DT CLASS="dt-description"><B><TT>access_persistent</TT></B></DT><DD CLASS="dd-description"> To configure who is
allowed to modify the &#X2019;persistent&#X2019; chatroom option allowed to modify the &#X2019;persistent&#X2019; room option.
(by default, everybody is allowed to modify that option). By default everybody is allowed to modify that option.
</DD><DT CLASS="dt-description"><B><TT>access_admin</TT></B></DT><DD CLASS="dd-description"> This option specifies </DD><DT CLASS="dt-description"><B><TT>access_admin</TT></B></DT><DD CLASS="dd-description"> This option specifies
who is allowed to administrate the Multi-User Chat service (the default who is allowed to administrate the Multi-User Chat service. The default
value is <TT>none</TT>, which means that only the room creator can value is <TT>none</TT>, which means that only the room creator can
administer his room). administer his room.
The administrators can send a normal message to the service JID, The administrators can send a normal message to the service JID,
and it will be shown in every active room as a service message. and it will be shown in all active rooms as a service message.
The administrators can send a groupchat message to the JID of an active room, The administrators can send a groupchat message to the JID of an active room,
and the message will be shown in the room as a service message. and the message will be shown in the room as a service message.
</DD><DT CLASS="dt-description"><B><TT>history_size</TT></B></DT><DD CLASS="dd-description"> A small history of </DD><DT CLASS="dt-description"><B><TT>history_size</TT></B></DT><DD CLASS="dd-description"> A small history of
@ -1978,44 +2000,43 @@ to keep and send to users joining the room. The value is an
integer. Setting the value to <TT>0</TT> disables the history feature integer. Setting the value to <TT>0</TT> disables the history feature
and, as a result, nothing is kept in memory. The default value is and, as a result, nothing is kept in memory. The default value is
<TT>20</TT>. This value is global and thus affects all rooms on the <TT>20</TT>. This value is global and thus affects all rooms on the
server. service.
</DD><DT CLASS="dt-description"><B><TT>max_users</TT></B></DT><DD CLASS="dd-description"> This option defines at </DD><DT CLASS="dt-description"><B><TT>max_users</TT></B></DT><DD CLASS="dd-description"> This option defines at
the server level, the maximum number of users allowed per MUC the service level, the maximum number of users allowed per
room. It can be lowered in each room configuration but cannot be room. It can be lowered in each room configuration but cannot be
increased in individual MUC room configuration. The default value is increased in individual room configuration. The default value is
200. 200.
</DD><DT CLASS="dt-description"><B><TT>max_users_admin_threshold</TT></B></DT><DD CLASS="dd-description"> </DD><DT CLASS="dt-description"><B><TT>max_users_admin_threshold</TT></B></DT><DD CLASS="dd-description">
This option defines the This option defines the
number of MUC admins or owners to allow to enter the room even if number of service admins or room owners allowed to enter the room when
the maximum number of allowed users is reached. The default limits the maximum number of allowed occupants was reached. The default limit
is 5. In most cases this default value is the best setting. is 5.
</DD><DT CLASS="dt-description"><B><TT>max_user_conferences</TT></B></DT><DD CLASS="dd-description"> </DD><DT CLASS="dt-description"><B><TT>max_user_conferences</TT></B></DT><DD CLASS="dd-description">
This option define the maximum This option defines the maximum
number of chat room any given user will be able to join. The default number of rooms that any given user can join. The default value
is 10. This option is used to prevent possible abuses. Note that is 10. This option is used to prevent possible abuses. Note that
this is a soft limits: Some users can sometime join more conferences this is a soft limit: some users can sometimes join more conferences
in cluster configurations. in cluster configurations.
</DD><DT CLASS="dt-description"><B><TT>min_message_interval</TT></B></DT><DD CLASS="dd-description"> </DD><DT CLASS="dt-description"><B><TT>min_message_interval</TT></B></DT><DD CLASS="dd-description">
This option defines the minimum interval between two messages send This option defines the minimum interval between two messages send
by a user in seconds. This option is global and valid for all chat by an occupant in seconds. This option is global and valid for all
rooms. A decimal value can be used. When this option is not defined, rooms. A decimal value can be used. When this option is not defined,
message rate is not limited. This feature can be used to protect a message rate is not limited. This feature can be used to protect a
MUC service from users abuses and limit number of messages that will MUC service from occupant abuses and limit number of messages that will
be broadcasted by the service. A good value for this minimum message be broadcasted by the service. A good value for this minimum message
interval is 0.4 second. If a user tries to send messages faster, an interval is 0.4 second. If an occupant tries to send messages faster, an
error is send back explaining that the message have been discarded error is send back explaining that the message has been discarded
and describing the reason why the message is not acceptable. and describing the reason why the message is not acceptable.
</DD><DT CLASS="dt-description"><B><TT>min_presence_interval</TT></B></DT><DD CLASS="dd-description"> </DD><DT CLASS="dt-description"><B><TT>min_presence_interval</TT></B></DT><DD CLASS="dd-description">
This option defines the This option defines the
minimum of time between presence changes coming from a given user in minimum of time between presence changes coming from a given occupant in
seconds. This option is global and valid for all chat rooms. A seconds. This option is global and valid for all rooms. A
decimal value can be used. When this option is not defined, no decimal value can be used. When this option is not defined, no
restriction is applied. This option can be used to protect a MUC restriction is applied. This option can be used to protect a MUC
service for users abuses, as fastly changing a user presence will service for occupants abuses. If an occupant tries
result in possible large presence packet broadcast. If a user tries
to change its presence more often than the specified interval, the to change its presence more often than the specified interval, the
presence is cached by <TT>ejabberd</TT> and only the last presence is presence is cached by <TT>ejabberd</TT> and only the last presence is
broadcasted to all users in the room after expiration of the broadcasted to all occupants in the room after expiration of the
interval delay. Intermediate presence packets are silently interval delay. Intermediate presence packets are silently
discarded. A good value for this option is 4 seconds. discarded. A good value for this option is 4 seconds.
</DD><DT CLASS="dt-description"><B><TT>default_room_options</TT></B></DT><DD CLASS="dd-description"> </DD><DT CLASS="dt-description"><B><TT>default_room_options</TT></B></DT><DD CLASS="dd-description">
@ -2028,6 +2049,12 @@ The available room options and the default values are:
</DD><DT CLASS="dt-description"><B><TT>{allow_private_messages, true}</TT></B></DT><DD CLASS="dd-description"> Occupants can send private messages to other occupants. </DD><DT CLASS="dt-description"><B><TT>{allow_private_messages, true}</TT></B></DT><DD CLASS="dd-description"> Occupants can send private messages to other occupants.
</DD><DT CLASS="dt-description"><B><TT>{allow_query_users, true}</TT></B></DT><DD CLASS="dd-description"> Occupants can send IQ queries to other occupants. </DD><DT CLASS="dt-description"><B><TT>{allow_query_users, true}</TT></B></DT><DD CLASS="dd-description"> Occupants can send IQ queries to other occupants.
</DD><DT CLASS="dt-description"><B><TT>{allow_user_invites, false}</TT></B></DT><DD CLASS="dd-description"> Allow occupants to send invitations. </DD><DT CLASS="dt-description"><B><TT>{allow_user_invites, false}</TT></B></DT><DD CLASS="dd-description"> Allow occupants to send invitations.
</DD><DT CLASS="dt-description"><B><TT>{allow_visitor_nickchange, true}</TT></B></DT><DD CLASS="dd-description"> Allow visitors to
change nickname.
</DD><DT CLASS="dt-description"><B><TT>{allow_visitor_status, true}</TT></B></DT><DD CLASS="dd-description"> Allow visitors to send
status text in presence updates. If disallowed, the <TT>status</TT>
text is stripped before broadcasting the presence update to all
the room occupants.
</DD><DT CLASS="dt-description"><B><TT>{anonymous, true}</TT></B></DT><DD CLASS="dd-description"> Occupants are allowed to see the real JIDs of other occupants. </DD><DT CLASS="dt-description"><B><TT>{anonymous, true}</TT></B></DT><DD CLASS="dd-description"> Occupants are allowed to see the real JIDs of other occupants.
</DD><DT CLASS="dt-description"><B><TT>{logging, false}</TT></B></DT><DD CLASS="dd-description"> The public messages are logged using <TT>mod_muc_log</TT>. </DD><DT CLASS="dt-description"><B><TT>{logging, false}</TT></B></DT><DD CLASS="dd-description"> The public messages are logged using <TT>mod_muc_log</TT>.
</DD><DT CLASS="dt-description"><B><TT>{max_users, 200}</TT></B></DT><DD CLASS="dd-description"> Maximum number of occupants in the room. </DD><DT CLASS="dt-description"><B><TT>{max_users, 200}</TT></B></DT><DD CLASS="dd-description"> Maximum number of occupants in the room.
@ -2097,8 +2124,8 @@ and the default value of 20 history messages will be send to the users.
{access_admin, muc_admins}]}, {access_admin, muc_admins}]},
... ...
]}. ]}.
</PRE></LI><LI CLASS="li-itemize">In the following example, MUC anti abuse options are used. A </PRE></LI><LI CLASS="li-itemize">In the following example, MUC anti abuse options are used. An
user cannot send more than one message every 0.4 seconds and cannot occupant cannot send more than one message every 0.4 seconds and cannot
change its presence more than once every 4 seconds. No ACLs are change its presence more than once every 4 seconds. No ACLs are
defined, but some user restriction could be added as well:<PRE CLASS="verbatim">{modules, defined, but some user restriction could be added as well:<PRE CLASS="verbatim">{modules,
[ [
@ -2108,7 +2135,7 @@ defined, but some user restriction could be added as well:<PRE CLASS="verbatim">
... ...
]}. ]}.
</PRE></LI><LI CLASS="li-itemize">This example shows how to use <TT>default_room_options</TT> to make sure </PRE></LI><LI CLASS="li-itemize">This example shows how to use <TT>default_room_options</TT> to make sure
newly created chatrooms have by default those options. the newly created rooms have by default those options.
<PRE CLASS="verbatim">{modules, <PRE CLASS="verbatim">{modules,
[ [
... ...
@ -2128,17 +2155,17 @@ newly created chatrooms have by default those options.
]}. ]}.
</PRE></LI></UL><P> <A NAME="modmuclog"></A> </P><!--TOC subsection <TT>mod_muc_log</TT>--> </PRE></LI></UL><P> <A NAME="modmuclog"></A> </P><!--TOC subsection <TT>mod_muc_log</TT>-->
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc45">3.3.9</A>&#XA0;&#XA0;<A HREF="#modmuclog"><TT>mod_muc_log</TT></A></H3><!--SEC END --><P> <A NAME="modmuclog"></A> <H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc45">3.3.9</A>&#XA0;&#XA0;<A HREF="#modmuclog"><TT>mod_muc_log</TT></A></H3><!--SEC END --><P> <A NAME="modmuclog"></A>
</P><P>This module enables optional logging of Multi-User Chat (MUC) conversations to </P><P>This module enables optional logging of Multi-User Chat (MUC) public conversations to
HTML. Once you enable this module, users can join a chatroom using a MUC capable HTML. Once you enable this module, users can join a room using a MUC capable
Jabber client, and if they have enough privileges, they can request the Jabber client, and if they have enough privileges, they can request the
configuration form in which they can set the option to enable chatroom logging.</P><P>Features: configuration form in which they can set the option to enable room logging.</P><P>Features:
</P><UL CLASS="itemize"><LI CLASS="li-itemize"> </P><UL CLASS="itemize"><LI CLASS="li-itemize">
Chatroom details are added on top of each page: room title, JID, Room details are added on top of each page: room title, JID,
author, subject and configuration. author, subject and configuration.
</LI><LI CLASS="li-itemize"> </LI><LI CLASS="li-itemize">
The room JID in the generated HTML is a link to join the chatroom (using The room JID in the generated HTML is a link to join the room (using
<A HREF="http://www.xmpp.org/rfcs/rfc5122.html">XMPP URI</A>). <A HREF="http://www.xmpp.org/rfcs/rfc5122.html">XMPP URI</A>).
</LI><LI CLASS="li-itemize">Subject and chatroom configuration changes are tracked and displayed. </LI><LI CLASS="li-itemize">Subject and room configuration changes are tracked and displayed.
</LI><LI CLASS="li-itemize">Joins, leaves, nick changes, kicks, bans and &#X2018;/me&#X2019; are tracked and </LI><LI CLASS="li-itemize">Joins, leaves, nick changes, kicks, bans and &#X2018;/me&#X2019; are tracked and
displayed, including the reason if available. displayed, including the reason if available.
</LI><LI CLASS="li-itemize">Generated HTML files are XHTML 1.0 Transitional and CSS compliant. </LI><LI CLASS="li-itemize">Generated HTML files are XHTML 1.0 Transitional and CSS compliant.
@ -2151,7 +2178,7 @@ displayed, including the reason if available.
</LI></UL><P>Options: </LI></UL><P>Options:
</P><DL CLASS="description"><DT CLASS="dt-description"> </P><DL CLASS="description"><DT CLASS="dt-description">
<B><TT>access_log</TT></B></DT><DD CLASS="dd-description"> <B><TT>access_log</TT></B></DT><DD CLASS="dd-description">
This option restricts which users are allowed to enable or disable chatroom This option restricts which occupants are allowed to enable or disable room
logging. The default value is <TT>muc_admin</TT>. Note for this default setting logging. The default value is <TT>muc_admin</TT>. Note for this default setting
you need to have an access rule for <TT>muc_admin</TT> in order to take effect. you need to have an access rule for <TT>muc_admin</TT> in order to take effect.
</DD><DT CLASS="dt-description"><B><TT>cssfile</TT></B></DT><DD CLASS="dd-description"> </DD><DT CLASS="dt-description"><B><TT>cssfile</TT></B></DT><DD CLASS="dd-description">
@ -2161,34 +2188,46 @@ file or if they need to use the embedded CSS file. Allowed values are
include the embedded CSS code. With the latter, you can specify the URL of the include the embedded CSS code. With the latter, you can specify the URL of the
custom CSS file (for example: &#X2018;http://example.com/my.css&#X2019;). The default value custom CSS file (for example: &#X2018;http://example.com/my.css&#X2019;). The default value
is <TT>false</TT>. is <TT>false</TT>.
</DD><DT CLASS="dt-description"><B><TT>dirname</TT></B></DT><DD CLASS="dd-description">
Allows to configure the name of the room directory.
Allowed values are <TT>room_jid</TT> and <TT>room_name</TT>.
With the first value, the room directory name will be the full room JID.
With the latter, the room directory name will be only the room name,
not including the MUC service name.
The default value is <TT>room_jid</TT>.
</DD><DT CLASS="dt-description"><B><TT>dirtype</TT></B></DT><DD CLASS="dd-description"> </DD><DT CLASS="dt-description"><B><TT>dirtype</TT></B></DT><DD CLASS="dd-description">
The type of the created directories can be specified with this option. Allowed The type of the created directories can be specified with this option. Allowed
values are <TT>subdirs</TT> and <TT>plain</TT>. With the first value, values are <TT>subdirs</TT> and <TT>plain</TT>. With the first value,
subdirectories are created for each year and month. With the latter, the subdirectories are created for each year and month. With the latter, the
names of the log files contain the full date, and there are no subdirectories. names of the log files contain the full date, and there are no subdirectories.
The default value is <TT>subdirs</TT>. The default value is <TT>subdirs</TT>.
</DD><DT CLASS="dt-description"><B><TT>file_format</TT></B></DT><DD CLASS="dd-description">
Define the format of the log files:
<TT>html</TT> stores in HTML format,
<TT>plaintext</TT> stores in plain text.
The default value is <TT>html</TT>.
</DD><DT CLASS="dt-description"><B><TT>outdir</TT></B></DT><DD CLASS="dd-description"> </DD><DT CLASS="dt-description"><B><TT>outdir</TT></B></DT><DD CLASS="dd-description">
This option sets the full path to the directory in which the HTML files should This option sets the full path to the directory in which the HTML files should
be stored. Make sure the <TT>ejabberd</TT> daemon user has write access on that be stored. Make sure the <TT>ejabberd</TT> daemon user has write access on that
directory. The default value is <TT>"www/muc"</TT>. directory. The default value is <TT>"www/muc"</TT>.
</DD><DT CLASS="dt-description"><B><TT>timezone</TT></B></DT><DD CLASS="dd-description">
The time zone for the logs is configurable with this option. Allowed values
are <TT>local</TT> and <TT>universal</TT>. With the first value, the local time,
as reported to Erlang by the operating system, will be used. With the latter,
GMT/UTC time will be used. The default value is <TT>local</TT>.
</DD><DT CLASS="dt-description"><B><TT>spam_prevention</TT></B></DT><DD CLASS="dd-description"> </DD><DT CLASS="dt-description"><B><TT>spam_prevention</TT></B></DT><DD CLASS="dd-description">
To prevent spam, the <TT>spam_prevention</TT> option adds a special attribute To prevent spam, the <TT>spam_prevention</TT> option adds a special attribute
to links that prevent their indexation by search engines. The default value to links that prevent their indexation by search engines. The default value
is <TT>true</TT>, which mean that nofollow attributes will be added to user is <TT>true</TT>, which mean that nofollow attributes will be added to user
submitted links. submitted links.
</DD><DT CLASS="dt-description"><B><TT>timezone</TT></B></DT><DD CLASS="dd-description">
The time zone for the logs is configurable with this option. Allowed values
are <TT>local</TT> and <TT>universal</TT>. With the first value, the local time,
as reported to Erlang by the operating system, will be used. With the latter,
GMT/UTC time will be used. The default value is <TT>local</TT>.
</DD><DT CLASS="dt-description"><B><TT>top_link</TT></B></DT><DD CLASS="dd-description"> </DD><DT CLASS="dt-description"><B><TT>top_link</TT></B></DT><DD CLASS="dd-description">
With this option you can customize the link on the top right corner of each With this option you can customize the link on the top right corner of each
log file. The syntax of this option is <TT>{"URL", "Text"}</TT>. The default log file. The syntax of this option is <TT>{"URL", "Text"}</TT>. The default
value is <TT>{"/", "Home"}</TT>. value is <TT>{"/", "Home"}</TT>.
</DD></DL><P>Examples: </DD></DL><P>Examples:
</P><UL CLASS="itemize"><LI CLASS="li-itemize"> </P><UL CLASS="itemize"><LI CLASS="li-itemize">
In the first example any chatroom owner can enable logging, and a In the first example any room owner can enable logging, and a
custom CSS file will be used (http://example.com/my.css). Further, the names custom CSS file will be used (http://example.com/my.css). The names
of the log files will contain the full date, and there will be no of the log files will contain the full date, and there will be no
subdirectories. The log files will be stored in /var/www/muclogs, and the subdirectories. The log files will be stored in /var/www/muclogs, and the
time zone will be GMT/UTC. Finally, the top link will be time zone will be GMT/UTC. Finally, the top link will be
@ -2202,6 +2241,7 @@ time zone will be GMT/UTC. Finally, the top link will be
{access_log, muc}, {access_log, muc},
{cssfile, "http://example.com/my.css"}, {cssfile, "http://example.com/my.css"},
{dirtype, plain}, {dirtype, plain},
{dirname, room_jid},
{outdir, "/var/www/muclogs"}, {outdir, "/var/www/muclogs"},
{timezone, universal}, {timezone, universal},
{spam_prevention, true}, {spam_prevention, true},
@ -2211,7 +2251,7 @@ time zone will be GMT/UTC. Finally, the top link will be
]}. ]}.
</PRE></LI><LI CLASS="li-itemize">In the second example only <TT>admin1@example.org</TT> and </PRE></LI><LI CLASS="li-itemize">In the second example only <TT>admin1@example.org</TT> and
<TT>admin2@example.net</TT> can enable logging, and the embedded CSS file will be <TT>admin2@example.net</TT> can enable logging, and the embedded CSS file will be
used. Further, the names of the log files will only contain the day (number), used. The names of the log files will only contain the day (number),
and there will be subdirectories for each year and month. The log files will and there will be subdirectories for each year and month. The log files will
be stored in /var/www/muclogs, and the local time will be used. Finally, the be stored in /var/www/muclogs, and the local time will be used. Finally, the
top link will be the default <CODE>&lt;a href="/"&gt;Home&lt;/a&gt;</CODE>. top link will be the default <CODE>&lt;a href="/"&gt;Home&lt;/a&gt;</CODE>.
@ -2324,8 +2364,8 @@ The simpliest configuration of the module:
{access, proxy65_access, [{allow, proxy_users}, {deny, all}]}. {access, proxy65_access, [{allow, proxy_users}, {deny, all}]}.
{acl, admin, {user, "admin", "example.org"}}. {acl, admin, {user, "admin", "example.org"}}.
{shaper, normal, {maxrate, 10240}}. %% 10 Kbytes/sec {shaper, proxyrate, {maxrate, 10240}}. %% 10 Kbytes/sec
{access, proxy65_shaper, [{none, admin}, {normal, all}]}. {access, proxy65_shaper, [{none, admin}, {proxyrate, proxy_users}]}.
{modules, {modules,
[ [
@ -2652,7 +2692,9 @@ and that all virtual hosts will be searched instead of only the current one:
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc58">3.3.22</A>&#XA0;&#XA0;<A HREF="#modvcardldap"><TT>mod_vcard_ldap</TT></A></H3><!--SEC END --><P> <A NAME="modvcardldap"></A> <H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc58">3.3.22</A>&#XA0;&#XA0;<A HREF="#modvcardldap"><TT>mod_vcard_ldap</TT></A></H3><!--SEC END --><P> <A NAME="modvcardldap"></A>
</P><P><TT>ejabberd</TT> can map LDAP attributes to vCard fields. This behaviour is </P><P><TT>ejabberd</TT> can map LDAP attributes to vCard fields. This behaviour is
implemented in the <TT>mod_vcard_ldap</TT> module. This module does not depend on the implemented in the <TT>mod_vcard_ldap</TT> module. This module does not depend on the
authentication method (see&#XA0;<A HREF="#ldapauth">3.2.5</A>).</P><P>The <TT>mod_vcard_ldap</TT> module has authentication method (see&#XA0;<A HREF="#ldapauth">3.2.5</A>).</P><P>Note that <TT>ejabberd</TT> treats LDAP as a read-only storage:
it is possible to consult data, but not possible to
create accounts, change password or edit vCard that is stored in LDAP.</P><P>The <TT>mod_vcard_ldap</TT> module has
its own optional parameters. The first group of parameters has the same its own optional parameters. The first group of parameters has the same
meaning as the top-level LDAP parameters to set the authentication method: meaning as the top-level LDAP parameters to set the authentication method:
<TT>ldap_servers</TT>, <TT>ldap_port</TT>, <TT>ldap_rootdn</TT>, <TT>ldap_servers</TT>, <TT>ldap_port</TT>, <TT>ldap_rootdn</TT>,
@ -3221,7 +3263,15 @@ so it is important to use it with extremely care.
There are some simple and safe examples in the article There are some simple and safe examples in the article
<A HREF="http://www.ejabberd.im/interconnect-erl-nodes">Interconnecting Erlang Nodes</A></P><P>To exit the shell, close the window or press the keys: control+c control+c.</P><P> <A NAME="i18ni10n"></A> </P><!--TOC chapter Internationalization and Localization--> <A HREF="http://www.ejabberd.im/interconnect-erl-nodes">Interconnecting Erlang Nodes</A></P><P>To exit the shell, close the window or press the keys: control+c control+c.</P><P> <A NAME="i18ni10n"></A> </P><!--TOC chapter Internationalization and Localization-->
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc88">Appendix&#XA0;A</A>&#XA0;&#XA0;<A HREF="#i18ni10n">Internationalization and Localization</A></H1><!--SEC END --><P> <A NAME="i18ni10n"></A> <H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc88">Appendix&#XA0;A</A>&#XA0;&#XA0;<A HREF="#i18ni10n">Internationalization and Localization</A></H1><!--SEC END --><P> <A NAME="i18ni10n"></A>
</P><P>All built-in modules support the <TT>xml:lang</TT> attribute inside IQ queries. </P><P>The source code of <TT>ejabberd</TT> supports localization.
The translators can edit the
<A HREF="http://www.gnu.org/software/gettext/">gettext</A> .po files
using any capable program (KBabel, Lokalize, Poedit...) or a simple text editor.</P><P>Then gettext
is used to extract, update and export those .po files to the .msg format read by <TT>ejabberd</TT>.
To perform those management tasks, in the <TT>src/</TT> directory execute <TT>make translations</TT>.
The translatable strings are extracted from source code to generate the file <TT>ejabberd.pot</TT>.
This file is merged with each .po file to produce updated .po files.
Finally those .po files are exported to .msg files, that have a format easily readable by <TT>ejabberd</TT>.</P><P>All built-in modules support the <TT>xml:lang</TT> attribute inside IQ queries.
Figure&#XA0;<A HREF="#fig:discorus">A.1</A>, for example, shows the reply to the following query: Figure&#XA0;<A HREF="#fig:discorus">A.1</A>, for example, shows the reply to the following query:
</P><PRE CLASS="verbatim">&lt;iq id='5' </P><PRE CLASS="verbatim">&lt;iq id='5'
to='example.org' to='example.org'
@ -3262,7 +3312,7 @@ Alexey Shchepin (<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT
</LI><LI CLASS="li-itemize">Vsevolod Pelipas (<A HREF="xmpp:vsevoload@jabber.ru"><TT>xmpp:vsevoload@jabber.ru</TT></A>) </LI><LI CLASS="li-itemize">Vsevolod Pelipas (<A HREF="xmpp:vsevoload@jabber.ru"><TT>xmpp:vsevoload@jabber.ru</TT></A>)
</LI></UL><P> <A NAME="copyright"></A> </P><!--TOC chapter Copyright Information--> </LI></UL><P> <A NAME="copyright"></A> </P><!--TOC chapter Copyright Information-->
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc91">Appendix&#XA0;D</A>&#XA0;&#XA0;<A HREF="#copyright">Copyright Information</A></H1><!--SEC END --><P> <A NAME="copyright"></A> </P><P>Ejabberd Installation and Operation Guide.<BR> <H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc91">Appendix&#XA0;D</A>&#XA0;&#XA0;<A HREF="#copyright">Copyright Information</A></H1><!--SEC END --><P> <A NAME="copyright"></A> </P><P>Ejabberd Installation and Operation Guide.<BR>
Copyright &#XA9; 2003 &#X2014; 2008 Process-one</P><P>This document is free software; you can redistribute it and/or Copyright &#XA9; 2003 &#X2014; 2008 ProcessOne</P><P>This document is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.</P><P>This document is distributed in the hope that it will be useful, of the License, or (at your option) any later version.</P><P>This document is distributed in the hope that it will be useful,

View File

@ -5,7 +5,7 @@
\usepackage{graphics} \usepackage{graphics}
\usepackage{hevea} \usepackage{hevea}
\usepackage[pdftex,colorlinks,unicode,urlcolor=blue,linkcolor=blue, \usepackage[pdftex,colorlinks,unicode,urlcolor=blue,linkcolor=blue,
pdftitle=Ejabberd\ Installation\ and\ Operation\ Guide,pdfauthor=Process-one,pdfsubject=ejabberd,pdfkeywords=ejabberd, pdftitle=Ejabberd\ Installation\ and\ Operation\ Guide,pdfauthor=ProcessOne,pdfsubject=ejabberd,pdfkeywords=ejabberd,
pdfpagelabels=false]{hyperref} pdfpagelabels=false]{hyperref}
\usepackage{makeidx} \usepackage{makeidx}
%\usepackage{showidx} % Only for verifying the index entries. %\usepackage{showidx} % Only for verifying the index entries.
@ -208,9 +208,9 @@ ejabberd Development Team
\makesection{install.binary}{Installing \ejabberd{} with Binary Installer} \makesection{install.binary}{Installing \ejabberd{} with Binary Installer}
Probably the easiest way to install an \ejabberd{} instant messaging server Probably the easiest way to install an \ejabberd{} instant messaging server
is using the binary installer published by Process-one. is using the binary installer published by ProcessOne.
The binary installers of released \ejabberd{} versions The binary installers of released \ejabberd{} versions
are available in the Process-one \ejabberd{} downloads page: are available in the ProcessOne \ejabberd{} downloads page:
\ahrefurl{http://www.process-one.net/en/ejabberd/downloads} \ahrefurl{http://www.process-one.net/en/ejabberd/downloads}
The installer will deploy and configure a full featured \ejabberd{} The installer will deploy and configure a full featured \ejabberd{}
@ -241,6 +241,22 @@ On a *nix system, if you want ejabberd to be started as daemon at boot time,
copy \term{ejabberd.init} from the 'bin' directory to something like \term{/etc/init.d/ejabberd} copy \term{ejabberd.init} from the 'bin' directory to something like \term{/etc/init.d/ejabberd}
(depending on your distribution) and call \term{/etc/inid.d/ejabberd start} to start it. (depending on your distribution) and call \term{/etc/inid.d/ejabberd start} to start it.
If \term{ejabberd} doesn't start correctly in Windows,
try to start it using the shortcut in desktop or start menu.
If the window shows error 14001, the solution is to install:
"Microsoft Visual C++ 2005 SP1 Redistributable Package".
You can download it from
\footahref{http://www.microsoft.com/}{www.microsoft.com}.
Then uninstall \ejabberd{} and install it again.
If \term{ejabberd} doesn't start correctly and a crash dump is generated,
there was a severe problem.
You can try starting \term{ejabberd} with
the script \term{bin/live.bat} in Windows,
or with the command \term{bin/ejabberdctl live} in other Operating Systems.
This way you see the error message provided by Erlang
and can identify what is exactly the problem.
The \term{ejabberdctl} administration script is included in the \term{bin} directory. The \term{ejabberdctl} administration script is included in the \term{bin} directory.
Please refer to the section~\ref{ejabberdctl} for details about \term{ejabberdctl}, Please refer to the section~\ref{ejabberdctl} for details about \term{ejabberdctl},
and configurable options to fine tune the Erlang runtime system. and configurable options to fine tune the Erlang runtime system.
@ -294,7 +310,7 @@ To compile \ejabberd{} on a `Unix-like' operating system, you need:
\makesubsection{download}{Download Source Code} \makesubsection{download}{Download Source Code}
\ind{install!download} \ind{install!download}
Released versions of \ejabberd{} are available in the Process-one \ejabberd{} downloads page: Released versions of \ejabberd{} are available in the ProcessOne \ejabberd{} downloads page:
\ahrefurl{http://www.process-one.net/en/ejabberd/downloads} \ahrefurl{http://www.process-one.net/en/ejabberd/downloads}
\ind{Subversion repository} \ind{Subversion repository}
@ -415,6 +431,13 @@ ejabberd is running
ejabberdctl stop ejabberdctl stop
\end{verbatim} \end{verbatim}
If \term{ejabberd} doesn't start correctly and a crash dump is generated,
there was a severe problem.
You can try starting \term{ejabberd} with
the command \term{ejabberdctl live}
to see the error message provided by Erlang
and can identify what is exactly the problem.
Please refer to the section~\ref{ejabberdctl} for details about \term{ejabberdctl}, Please refer to the section~\ref{ejabberdctl} for details about \term{ejabberdctl},
and configurable options to fine tune the Erlang runtime system. and configurable options to fine tune the Erlang runtime system.
@ -727,7 +750,7 @@ The available modules, their purpose and the options allowed by each one are:
Handles incoming s2s connections.\\ Handles incoming s2s connections.\\
Options: \texttt{inet6}, \texttt{ip}, \texttt{max\_stanza\_size} Options: \texttt{inet6}, \texttt{ip}, \texttt{max\_stanza\_size}
\titem{\texttt{ejabberd\_service}} \titem{\texttt{ejabberd\_service}}
Interacts with \footahref{http://www.ejabberd.im/tutorials-transports}{external components} Interacts with an \footahref{http://www.ejabberd.im/tutorials-transports}{external component}
(as defined in the Jabber Component Protocol (\xepref{0114}).\\ (as defined in the Jabber Component Protocol (\xepref{0114}).\\
Options: \texttt{access}, \texttt{hosts}, \texttt{inet6}, Options: \texttt{access}, \texttt{hosts}, \texttt{inet6},
\texttt{ip}, \texttt{shaper}, \texttt{service\_check\_from} \texttt{ip}, \texttt{shaper}, \texttt{service\_check\_from}
@ -749,9 +772,10 @@ This is a detailed description of each option allowed by the listening modules:
external components. The option can be either \term{true} or external components. The option can be either \term{true} or
\term{false}. The default value is \term{true} which conforms to \xepref{0114}. \term{false}. The default value is \term{true} which conforms to \xepref{0114}.
\titem{\{hosts, [Hostnames], [HostOptions]\}} \ind{options!hosts} \titem{\{hosts, [Hostnames], [HostOptions]\}} \ind{options!hosts}
This option of \term{ejabberd\_service} allows to define one or more hostnames The external Jabber component that connects to this \term{ejabberd\_service}
of external Jabber components that provide a service. can serve one or more hostnames.
In \term{HostOptions} it is possible to define the password required to those components In \term{HostOptions} you can define options for the component;
currently the only allowed option is the password required to the component
when attempt to connect to ejabberd: \poption{\{password, Secret\}}. when attempt to connect to ejabberd: \poption{\{password, Secret\}}.
Note that you cannot define in a single \term{ejabberd\_service} components of Note that you cannot define in a single \term{ejabberd\_service} components of
different services: add an \term{ejabberd\_service} for each service, different services: add an \term{ejabberd\_service} for each service,
@ -1159,8 +1183,14 @@ version, you can \term{kill(1)} \term{epam} process periodically to reduce its m
consumption: \ejabberd{} will restart this process immediately. consumption: \ejabberd{} will restart this process immediately.
\item \term{epam} program tries to turn off delays on authentication failures. \item \term{epam} program tries to turn off delays on authentication failures.
However, some PAM modules ignore this behavior and rely on their own configuration options. However, some PAM modules ignore this behavior and rely on their own configuration options.
The example configuration file \term{ejabberd.pam} shows how to turn off delays in You can create a configuration file \term{ejabberd.pam}.
\term{pam\_unix.so} module. It is not a ready to use configuration file: you must use it This example shows how to turn off delays in \term{pam\_unix.so} module:
\begin{verbatim}
#%PAM-1.0
auth sufficient pam_unix.so likeauth nullok nodelay
account sufficient pam_unix.so
\end{verbatim}
That is not a ready to use configuration file: you must use it
as a hint when building your own PAM configuration instead. Note that if you want to disable as a hint when building your own PAM configuration instead. Note that if you want to disable
delays on authentication failures in the PAM configuration file, you have to restrict access delays on authentication failures in the PAM configuration file, you have to restrict access
to this file, so a malicious user can't use your configuration to perform brute-force to this file, so a malicious user can't use your configuration to perform brute-force
@ -1371,7 +1401,7 @@ Examples:
\ind{options!language}\ind{language} \ind{options!language}\ind{language}
The option \option{language} defines the default language of server strings that The option \option{language} defines the default language of server strings that
can be seen by \Jabber{} clients. If a \Jabber{} client do not support can be seen by \Jabber{} clients. If a \Jabber{} client does not support
\option{xml:lang}, the specified language is used. The default value is \option{xml:lang}, the specified language is used. The default value is
\term{en}. In order to take effect there must be a translation file \term{en}. In order to take effect there must be a translation file
\term{<language>.msg} in \ejabberd{}'s \term{msgs} directory. \term{<language>.msg} in \ejabberd{}'s \term{msgs} directory.
@ -1388,6 +1418,9 @@ Examples:
\end{verbatim} \end{verbatim}
\end{itemize} \end{itemize}
Appendix \ref{i18ni10n} provides more details about internationalization and localization.
\makesubsection{includeconfigfile}{Include Additional Configuration Files} \makesubsection{includeconfigfile}{Include Additional Configuration Files}
\ind{options!includeconfigfile}\ind{includeconfigfile} \ind{options!includeconfigfile}\ind{includeconfigfile}
@ -1890,6 +1923,11 @@ module loaded!
server and use LDAP directory as vCard storage. Shared rosters are not supported server and use LDAP directory as vCard storage. Shared rosters are not supported
yet. yet.
Note that \ejabberd{} treats LDAP as a read-only storage:
it is possible to consult data, but not possible to
create accounts, change password or edit vCard that is stored in LDAP.
\makesubsubsection{ldapconnection}{Connection} \makesubsubsection{ldapconnection}{Connection}
Parameters: Parameters:
@ -2534,31 +2572,28 @@ Options:
\makesubsection{modmuc}{\modmuc{}} \makesubsection{modmuc}{\modmuc{}}
\ind{modules!\modmuc{}}\ind{protocols!XEP-0045: Multi-User Chat}\ind{conferencing} \ind{modules!\modmuc{}}\ind{protocols!XEP-0045: Multi-User Chat}\ind{conferencing}
With this module enabled, your server will support Multi-User Chat This module provides a Multi-User Chat (\xepref{0045}) service.
(\xepref{0045}). End users will be able to join text conferences. Users can discover existing rooms, join or create them.
Occupants of a room can chat in public or have private chats.
Some of the features of Multi-User Chat: Some of the features of Multi-User Chat:
\begin{itemize} \begin{itemize}
\item Sending private messages to room participants. \item Sending public and private messages to room occupants.
\item Inviting users. \item Inviting other users to a room.
\item Setting a conference topic. \item Setting a room subject.
\item Creating password protected rooms. \item Creating password protected rooms.
\item Kicking and banning participants. \item Kicking and banning occupants.
\end{itemize} \end{itemize}
The MUC service allows any Jabber ID to register a nickname, The MUC service allows any Jabber ID to register a nickname,
so nobody else can use that nickname in any room in the MUC service. so nobody else can use that nickname in any room in the MUC service.
To register a nickname, open the Service Discovery in your To register a nickname, open the Service Discovery in your
Jabber client and Register in the MUC service. Jabber client and register in the MUC service.
The MUC service allows the service administrator to send a message
to all existing chatrooms.
To do so, send the message to the Jabber ID of the MUC service.
This module supports clustering and load This module supports clustering and load
balancing. One module can be started per cluster node. Rooms are balancing. One module can be started per cluster node. Rooms are
distributed at creation time on all available MUC module distributed at creation time on all available MUC module
instances. The multi-user chat module is clustered but the room instances. The multi-user chat module is clustered but the rooms
themselves are not clustered nor fault-tolerant: if the node managing a themselves are not clustered nor fault-tolerant: if the node managing a
set of rooms goes down, the rooms disappear and they will be recreated set of rooms goes down, the rooms disappear and they will be recreated
on an available node on first connection attempt. on an available node on first connection attempt.
@ -2567,19 +2602,19 @@ Module options:
\begin{description} \begin{description}
\hostitem{conference} \hostitem{conference}
\titem{access} \ind{options!access}You can specify who is allowed to use \titem{access} \ind{options!access}You can specify who is allowed to use
the Multi-User Chat service (by default, everyone is allowed to use it). the Multi-User Chat service. By default everyone is allowed to use it.
\titem{access\_create} \ind{options!access\_create}To configure who is \titem{access\_create} \ind{options!access\_create}To configure who is
allowed to create new rooms at the Multi-User Chat service, this option allowed to create new rooms at the Multi-User Chat service, this option
can be used (by default, everybody is allowed to create rooms). can be used. By default everybody is allowed to create rooms.
\titem{access\_persistent} \ind{options!access\_persistent}To configure who is \titem{access\_persistent} \ind{options!access\_persistent}To configure who is
allowed to modify the 'persistent' chatroom option allowed to modify the 'persistent' room option.
(by default, everybody is allowed to modify that option). By default everybody is allowed to modify that option.
\titem{access\_admin} \ind{options!access\_admin}This option specifies \titem{access\_admin} \ind{options!access\_admin}This option specifies
who is allowed to administrate the Multi-User Chat service (the default who is allowed to administrate the Multi-User Chat service. The default
value is \term{none}, which means that only the room creator can value is \term{none}, which means that only the room creator can
administer his room). administer his room.
The administrators can send a normal message to the service JID, The administrators can send a normal message to the service JID,
and it will be shown in every active room as a service message. and it will be shown in all active rooms as a service message.
The administrators can send a groupchat message to the JID of an active room, The administrators can send a groupchat message to the JID of an active room,
and the message will be shown in the room as a service message. and the message will be shown in the room as a service message.
\titem{history\_size} \ind{options!history\_size}A small history of \titem{history\_size} \ind{options!history\_size}A small history of
@ -2589,44 +2624,43 @@ Module options:
integer. Setting the value to \term{0} disables the history feature integer. Setting the value to \term{0} disables the history feature
and, as a result, nothing is kept in memory. The default value is and, as a result, nothing is kept in memory. The default value is
\term{20}. This value is global and thus affects all rooms on the \term{20}. This value is global and thus affects all rooms on the
server. service.
\titem{max\_users} \ind{options!max\_users} This option defines at \titem{max\_users} \ind{options!max\_users} This option defines at
the server level, the maximum number of users allowed per MUC the service level, the maximum number of users allowed per
room. It can be lowered in each room configuration but cannot be room. It can be lowered in each room configuration but cannot be
increased in individual MUC room configuration. The default value is increased in individual room configuration. The default value is
200. 200.
\titem{max\_users\_admin\_threshold} \titem{max\_users\_admin\_threshold}
\ind{options!max\_users\_admin\_threshold} This option defines the \ind{options!max\_users\_admin\_threshold} This option defines the
number of MUC admins or owners to allow to enter the room even if number of service admins or room owners allowed to enter the room when
the maximum number of allowed users is reached. The default limits the maximum number of allowed occupants was reached. The default limit
is 5. In most cases this default value is the best setting. is 5.
\titem{max\_user\_conferences} \titem{max\_user\_conferences}
\ind{options!max\_user\_conferences} This option define the maximum \ind{options!max\_user\_conferences} This option defines the maximum
number of chat room any given user will be able to join. The default number of rooms that any given user can join. The default value
is 10. This option is used to prevent possible abuses. Note that is 10. This option is used to prevent possible abuses. Note that
this is a soft limits: Some users can sometime join more conferences this is a soft limit: some users can sometimes join more conferences
in cluster configurations. in cluster configurations.
\titem{min\_message\_interval} \ind{options!min\_message\_interval} \titem{min\_message\_interval} \ind{options!min\_message\_interval}
This option defines the minimum interval between two messages send This option defines the minimum interval between two messages send
by a user in seconds. This option is global and valid for all chat by an occupant in seconds. This option is global and valid for all
rooms. A decimal value can be used. When this option is not defined, rooms. A decimal value can be used. When this option is not defined,
message rate is not limited. This feature can be used to protect a message rate is not limited. This feature can be used to protect a
MUC service from users abuses and limit number of messages that will MUC service from occupant abuses and limit number of messages that will
be broadcasted by the service. A good value for this minimum message be broadcasted by the service. A good value for this minimum message
interval is 0.4 second. If a user tries to send messages faster, an interval is 0.4 second. If an occupant tries to send messages faster, an
error is send back explaining that the message have been discarded error is send back explaining that the message has been discarded
and describing the reason why the message is not acceptable. and describing the reason why the message is not acceptable.
\titem{min\_presence\_interval} \titem{min\_presence\_interval}
\ind{options!min\_presence\_interval} This option defines the \ind{options!min\_presence\_interval} This option defines the
minimum of time between presence changes coming from a given user in minimum of time between presence changes coming from a given occupant in
seconds. This option is global and valid for all chat rooms. A seconds. This option is global and valid for all rooms. A
decimal value can be used. When this option is not defined, no decimal value can be used. When this option is not defined, no
restriction is applied. This option can be used to protect a MUC restriction is applied. This option can be used to protect a MUC
service for users abuses, as fastly changing a user presence will service for occupants abuses. If an occupant tries
result in possible large presence packet broadcast. If a user tries
to change its presence more often than the specified interval, the to change its presence more often than the specified interval, the
presence is cached by \ejabberd{} and only the last presence is presence is cached by \ejabberd{} and only the last presence is
broadcasted to all users in the room after expiration of the broadcasted to all occupants in the room after expiration of the
interval delay. Intermediate presence packets are silently interval delay. Intermediate presence packets are silently
discarded. A good value for this option is 4 seconds. discarded. A good value for this option is 4 seconds.
\titem{default\_room\_options} \ind{options!default\_room\_options} \titem{default\_room\_options} \ind{options!default\_room\_options}
@ -2639,7 +2673,15 @@ Module options:
\titem{\{allow\_private\_messages, true\}} Occupants can send private messages to other occupants. \titem{\{allow\_private\_messages, true\}} Occupants can send private messages to other occupants.
\titem{\{allow\_query\_users, true\}} Occupants can send IQ queries to other occupants. \titem{\{allow\_query\_users, true\}} Occupants can send IQ queries to other occupants.
\titem{\{allow\_user\_invites, false\}} Allow occupants to send invitations. \titem{\{allow\_user\_invites, false\}} Allow occupants to send invitations.
\titem{\{anonymous, true\}} Occupants are allowed to see the real JIDs of other occupants. \titem{\{allow\_visitor\_nickchange, true\}} Allow visitors to
change nickname.
\titem{\{allow\_visitor\_status, true\}} Allow visitors to send
status text in presence updates. If disallowed, the \term{status}
text is stripped before broadcasting the presence update to all
the room occupants.
\titem{\{anonymous, true\}} The room is anonymous:
occupants don't see the real JIDs of other occupants.
Note that the room moderators can always see the real JIDs of the occupants.
\titem{\{logging, false\}} The public messages are logged using \term{mod\_muc\_log}. \titem{\{logging, false\}} The public messages are logged using \term{mod\_muc\_log}.
\titem{\{max\_users, 200\}} Maximum number of occupants in the room. \titem{\{max\_users, 200\}} Maximum number of occupants in the room.
\titem{\{members\_by\_default, true\}} The occupants that enter the room are participants by default, so they have 'voice'. \titem{\{members\_by\_default, true\}} The occupants that enter the room are participants by default, so they have 'voice'.
@ -2715,8 +2757,8 @@ Examples:
]}. ]}.
\end{verbatim} \end{verbatim}
\item In the following example, MUC anti abuse options are used. A \item In the following example, MUC anti abuse options are used. An
user cannot send more than one message every 0.4 seconds and cannot occupant cannot send more than one message every 0.4 seconds and cannot
change its presence more than once every 4 seconds. No ACLs are change its presence more than once every 4 seconds. No ACLs are
defined, but some user restriction could be added as well: defined, but some user restriction could be added as well:
@ -2731,7 +2773,7 @@ defined, but some user restriction could be added as well:
\end{verbatim} \end{verbatim}
\item This example shows how to use \option{default\_room\_options} to make sure \item This example shows how to use \option{default\_room\_options} to make sure
newly created chatrooms have by default those options. the newly created rooms have by default those options.
\begin{verbatim} \begin{verbatim}
{modules, {modules,
[ [
@ -2756,19 +2798,19 @@ defined, but some user restriction could be added as well:
\makesubsection{modmuclog}{\modmuclog{}} \makesubsection{modmuclog}{\modmuclog{}}
\ind{modules!\modmuclog{}} \ind{modules!\modmuclog{}}
This module enables optional logging of Multi-User Chat (MUC) conversations to This module enables optional logging of Multi-User Chat (MUC) public conversations to
HTML. Once you enable this module, users can join a chatroom using a MUC capable HTML. Once you enable this module, users can join a room using a MUC capable
Jabber client, and if they have enough privileges, they can request the Jabber client, and if they have enough privileges, they can request the
configuration form in which they can set the option to enable chatroom logging. configuration form in which they can set the option to enable room logging.
Features: Features:
\begin{itemize} \begin{itemize}
\item Chatroom details are added on top of each page: room title, JID, \item Room details are added on top of each page: room title, JID,
author, subject and configuration. author, subject and configuration.
\item \ind{protocols!RFC 5122: Internationalized Resource Identifiers (IRIs) and Uniform Resource Identifiers (URIs) for the Extensible Messaging and Presence Protocol (XMPP)} \item \ind{protocols!RFC 5122: Internationalized Resource Identifiers (IRIs) and Uniform Resource Identifiers (URIs) for the Extensible Messaging and Presence Protocol (XMPP)}
The room JID in the generated HTML is a link to join the chatroom (using The room JID in the generated HTML is a link to join the room (using
\footahref{http://www.xmpp.org/rfcs/rfc5122.html}{XMPP URI}). \footahref{http://www.xmpp.org/rfcs/rfc5122.html}{XMPP URI}).
\item Subject and chatroom configuration changes are tracked and displayed. \item Subject and room configuration changes are tracked and displayed.
\item Joins, leaves, nick changes, kicks, bans and `/me' are tracked and \item Joins, leaves, nick changes, kicks, bans and `/me' are tracked and
displayed, including the reason if available. displayed, including the reason if available.
\item Generated HTML files are XHTML 1.0 Transitional and CSS compliant. \item Generated HTML files are XHTML 1.0 Transitional and CSS compliant.
@ -2783,7 +2825,7 @@ Features:
Options: Options:
\begin{description} \begin{description}
\titem{access\_log}\ind{options!access\_log} \titem{access\_log}\ind{options!access\_log}
This option restricts which users are allowed to enable or disable chatroom This option restricts which occupants are allowed to enable or disable room
logging. The default value is \term{muc\_admin}. Note for this default setting logging. The default value is \term{muc\_admin}. Note for this default setting
you need to have an access rule for \term{muc\_admin} in order to take effect. you need to have an access rule for \term{muc\_admin} in order to take effect.
\titem{cssfile}\ind{options!cssfile} \titem{cssfile}\ind{options!cssfile}
@ -2793,26 +2835,38 @@ Options:
include the embedded CSS code. With the latter, you can specify the URL of the include the embedded CSS code. With the latter, you can specify the URL of the
custom CSS file (for example: `http://example.com/my.css'). The default value custom CSS file (for example: `http://example.com/my.css'). The default value
is \term{false}. is \term{false}.
\titem{dirname}\ind{options!dirname}
Allows to configure the name of the room directory.
Allowed values are \term{room\_jid} and \term{room\_name}.
With the first value, the room directory name will be the full room JID.
With the latter, the room directory name will be only the room name,
not including the MUC service name.
The default value is \term{room\_jid}.
\titem{dirtype}\ind{options!dirtype} \titem{dirtype}\ind{options!dirtype}
The type of the created directories can be specified with this option. Allowed The type of the created directories can be specified with this option. Allowed
values are \term{subdirs} and \term{plain}. With the first value, values are \term{subdirs} and \term{plain}. With the first value,
subdirectories are created for each year and month. With the latter, the subdirectories are created for each year and month. With the latter, the
names of the log files contain the full date, and there are no subdirectories. names of the log files contain the full date, and there are no subdirectories.
The default value is \term{subdirs}. The default value is \term{subdirs}.
\titem{file\_format}\ind{options!file\_format}
Define the format of the log files:
\term{html} stores in HTML format,
\term{plaintext} stores in plain text.
The default value is \term{html}.
\titem{outdir}\ind{options!outdir} \titem{outdir}\ind{options!outdir}
This option sets the full path to the directory in which the HTML files should This option sets the full path to the directory in which the HTML files should
be stored. Make sure the \ejabberd{} daemon user has write access on that be stored. Make sure the \ejabberd{} daemon user has write access on that
directory. The default value is \term{"www/muc"}. directory. The default value is \term{"www/muc"}.
\titem{timezone}\ind{options!timezone}
The time zone for the logs is configurable with this option. Allowed values
are \term{local} and \term{universal}. With the first value, the local time,
as reported to Erlang by the operating system, will be used. With the latter,
GMT/UTC time will be used. The default value is \term{local}.
\titem{spam\_prevention}\ind{options!spam\_prevention} \titem{spam\_prevention}\ind{options!spam\_prevention}
To prevent spam, the \term{spam\_prevention} option adds a special attribute To prevent spam, the \term{spam\_prevention} option adds a special attribute
to links that prevent their indexation by search engines. The default value to links that prevent their indexation by search engines. The default value
is \term{true}, which mean that nofollow attributes will be added to user is \term{true}, which mean that nofollow attributes will be added to user
submitted links. submitted links.
\titem{timezone}\ind{options!timezone}
The time zone for the logs is configurable with this option. Allowed values
are \term{local} and \term{universal}. With the first value, the local time,
as reported to Erlang by the operating system, will be used. With the latter,
GMT/UTC time will be used. The default value is \term{local}.
\titem{top\_link}\ind{options!top\_link} \titem{top\_link}\ind{options!top\_link}
With this option you can customize the link on the top right corner of each With this option you can customize the link on the top right corner of each
log file. The syntax of this option is \term{\{"URL", "Text"\}}. The default log file. The syntax of this option is \term{\{"URL", "Text"\}}. The default
@ -2821,8 +2875,8 @@ Options:
Examples: Examples:
\begin{itemize} \begin{itemize}
\item In the first example any chatroom owner can enable logging, and a \item In the first example any room owner can enable logging, and a
custom CSS file will be used (http://example.com/my.css). Further, the names custom CSS file will be used (http://example.com/my.css). The names
of the log files will contain the full date, and there will be no of the log files will contain the full date, and there will be no
subdirectories. The log files will be stored in /var/www/muclogs, and the subdirectories. The log files will be stored in /var/www/muclogs, and the
time zone will be GMT/UTC. Finally, the top link will be time zone will be GMT/UTC. Finally, the top link will be
@ -2837,6 +2891,7 @@ Examples:
{access_log, muc}, {access_log, muc},
{cssfile, "http://example.com/my.css"}, {cssfile, "http://example.com/my.css"},
{dirtype, plain}, {dirtype, plain},
{dirname, room_jid},
{outdir, "/var/www/muclogs"}, {outdir, "/var/www/muclogs"},
{timezone, universal}, {timezone, universal},
{spam_prevention, true}, {spam_prevention, true},
@ -2847,7 +2902,7 @@ Examples:
\end{verbatim} \end{verbatim}
\item In the second example only \jid{admin1@example.org} and \item In the second example only \jid{admin1@example.org} and
\jid{admin2@example.net} can enable logging, and the embedded CSS file will be \jid{admin2@example.net} can enable logging, and the embedded CSS file will be
used. Further, the names of the log files will only contain the day (number), used. The names of the log files will only contain the day (number),
and there will be subdirectories for each year and month. The log files will and there will be subdirectories for each year and month. The log files will
be stored in /var/www/muclogs, and the local time will be used. Finally, the be stored in /var/www/muclogs, and the local time will be used. Finally, the
top link will be the default \verb|<a href="/">Home</a>|. top link will be the default \verb|<a href="/">Home</a>|.
@ -2986,8 +3041,8 @@ Examples:
{access, proxy65_access, [{allow, proxy_users}, {deny, all}]}. {access, proxy65_access, [{allow, proxy_users}, {deny, all}]}.
{acl, admin, {user, "admin", "example.org"}}. {acl, admin, {user, "admin", "example.org"}}.
{shaper, normal, {maxrate, 10240}}. %% 10 Kbytes/sec {shaper, proxyrate, {maxrate, 10240}}. %% 10 Kbytes/sec
{access, proxy65_shaper, [{none, admin}, {normal, all}]}. {access, proxy65_shaper, [{none, admin}, {proxyrate, proxy_users}]}.
{modules, {modules,
[ [
@ -3411,6 +3466,10 @@ Examples:
implemented in the \modvcardldap{} module. This module does not depend on the implemented in the \modvcardldap{} module. This module does not depend on the
authentication method (see~\ref{ldapauth}). authentication method (see~\ref{ldapauth}).
Note that \ejabberd{} treats LDAP as a read-only storage:
it is possible to consult data, but not possible to
create accounts, change password or edit vCard that is stored in LDAP.
The \modvcardldap{} module has The \modvcardldap{} module has
its own optional parameters. The first group of parameters has the same its own optional parameters. The first group of parameters has the same
meaning as the top-level LDAP parameters to set the authentication method: meaning as the top-level LDAP parameters to set the authentication method:
@ -4052,6 +4111,7 @@ following steps:
\begin{verbatim} \begin{verbatim}
erl -sname ejabberd \ erl -sname ejabberd \
-mnesia dir "/var/lib/ejabberd/" \
-mnesia extra_db_nodes "['ejabberd@first']" \ -mnesia extra_db_nodes "['ejabberd@first']" \
-s mnesia -s mnesia
\end{verbatim} \end{verbatim}
@ -4060,6 +4120,11 @@ erl -sname ejabberd \
You can check this by running the command `\verb|mnesia:info().|'. You You can check this by running the command `\verb|mnesia:info().|'. You
should see a lot of remote tables and a line like the following: should see a lot of remote tables and a line like the following:
Note: the Mnesia directory may be different in your system.
To know where does ejabberd expect Mnesia to be installed by default,
call \ref{ejabberdctl} without options and it will show some help,
including the Mnesia database spool dir.
\begin{verbatim} \begin{verbatim}
running db nodes = [ejabberd@first, ejabberd@second] running db nodes = [ejabberd@first, ejabberd@second]
\end{verbatim} \end{verbatim}
@ -4227,6 +4292,18 @@ To exit the shell, close the window or press the keys: control+c control+c.
\makechapter{i18ni10n}{Internationalization and Localization} \makechapter{i18ni10n}{Internationalization and Localization}
\ind{xml:lang}\ind{internationalization}\ind{localization}\ind{i18n}\ind{l10n} \ind{xml:lang}\ind{internationalization}\ind{localization}\ind{i18n}\ind{l10n}
The source code of \ejabberd{} supports localization.
The translators can edit the
\footahref{http://www.gnu.org/software/gettext/}{gettext} .po files
using any capable program (KBabel, Lokalize, Poedit...) or a simple text editor.
Then gettext
is used to extract, update and export those .po files to the .msg format read by \ejabberd{}.
To perform those management tasks, in the \term{src/} directory execute \term{make translations}.
The translatable strings are extracted from source code to generate the file \term{ejabberd.pot}.
This file is merged with each .po file to produce updated .po files.
Finally those .po files are exported to .msg files, that have a format easily readable by \ejabberd{}.
All built-in modules support the \texttt{xml:lang} attribute inside IQ queries. All built-in modules support the \texttt{xml:lang} attribute inside IQ queries.
Figure~\ref{fig:discorus}, for example, shows the reply to the following query: Figure~\ref{fig:discorus}, for example, shows the reply to the following query:
\begin{verbatim} \begin{verbatim}
@ -4284,7 +4361,7 @@ Thanks to all people who contributed to this guide:
\makechapter{copyright}{Copyright Information} \makechapter{copyright}{Copyright Information}
Ejabberd Installation and Operation Guide.\\ Ejabberd Installation and Operation Guide.\\
Copyright \copyright{} 2003 --- 2008 Process-one Copyright \copyright{} 2003 --- 2008 ProcessOne
This document is free software; you can redistribute it and/or This document is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License

View File

@ -0,0 +1,34 @@
Release Notes
ejabberd 2.0.2
28 August 2008
ejabberd 2.0.2 is the second bug fix release for ejabberd 2.0.x branch.
ejabberd 2.0.2 includes many bugfixes and a few improvements.
A complete list of changes can be retrieved from:
http://redir.process-one.net/ejabberd-2.0.2
The new code can be downloaded from ejabberd download page:
http://www.process-one.net/en/ejabberd/
Recent changes include:
- Anti-abuse feature: client blacklist support by IP.
- Guide: new section Securing ejabberd; improved usability.
- LDAP filter optimisation: ability to filter user in ejabberd and not LDAP.
- MUC improvements: room options to restrict visitors; broadcast reasons.
- Privacy rules: fix MySQL storage.
- Pub/Sub and PEP: many improvements in implementation and protocol compliance.
- Proxy65: send valid SOCKS5 reply (removed support for Psi < 0.10).
- Web server embedded: better support for HTTPS.
- Binary installers: SMP on Windows; don't remove config when uninstalling.
Bug reports
You can officially report bugs on ProcessOne support site:
http://support.process-one.net/
END

View File

@ -157,6 +157,9 @@ $(ERLSHLIBS): %.so: %.c
-o $@ \ -o $@ \
$(DYNAMIC_LIB_CFLAGS) $(DYNAMIC_LIB_CFLAGS)
translations:
../contrib/extract_translations/prepare-translation.sh -updateall
install: all install: all
# #
# Configuration files # Configuration files

View File

@ -5,7 +5,7 @@
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 31 Oct 2005 by Magnus Henoch <henoch@dtek.chalmers.se> %%% Created : 31 Oct 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -1,6 +1,6 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 27 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 27 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -6,7 +6,7 @@
%%% Created : 23 Aug 2005 by Magnus Henoch <henoch@dtek.chalmers.se> %%% Created : 23 Aug 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -1,6 +1,6 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -9,7 +9,7 @@
%%% Created : 7 May 2006 by Mickael Remond <mremond@process-one.net> %%% Created : 7 May 2006 by Mickael Remond <mremond@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -152,7 +152,7 @@ stop_modules() ->
Modules -> Modules ->
lists:foreach( lists:foreach(
fun({Module, _Args}) -> fun({Module, _Args}) ->
gen_mod:stop_module(Host, Module) gen_mod:stop_module_keep_config(Host, Module)
end, Modules) end, Modules)
end end
end, ?MYHOSTS). end, ?MYHOSTS).

View File

@ -5,7 +5,7 @@
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -127,9 +127,12 @@ check_password_with_authmodule(User, Server, Password, StreamID, Digest) ->
[AuthMod | _] -> {true, AuthMod} [AuthMod | _] -> {true, AuthMod}
end. end.
%% We do not allow empty password: %% @spec (User::string(), Server::string(), Password::string()) ->
%% ok | {error, ErrorType}
%% where ErrorType = empty_password | not_allowed | invalid_jid
set_password(_User, _Server, "") -> set_password(_User, _Server, "") ->
{error, not_allowed}; %% We do not allow empty password
{error, empty_password};
set_password(User, Server, Password) -> set_password(User, Server, Password) ->
lists:foldl( lists:foldl(
fun(M, {error, _}) -> fun(M, {error, _}) ->
@ -138,8 +141,8 @@ set_password(User, Server, Password) ->
Res Res
end, {error, not_allowed}, auth_modules(Server)). end, {error, not_allowed}, auth_modules(Server)).
%% We do not allow empty password:
try_register(_User, _Server, "") -> try_register(_User, _Server, "") ->
%% We do not allow empty password
{error, not_allowed}; {error, not_allowed};
try_register(User, Server, Password) -> try_register(User, Server, Password) ->
case is_user_exists(User,Server) of case is_user_exists(User,Server) of

View File

@ -5,7 +5,7 @@
%%% Created : 17 Feb 2006 by Mickael Remond <mremond@process-one.net> %%% Created : 17 Feb 2006 by Mickael Remond <mremond@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net> %%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -61,7 +61,10 @@ check_password(User, Server, Password, _StreamID, _Digest) ->
check_password(User, Server, Password). check_password(User, Server, Password).
set_password(User, Server, Password) -> set_password(User, Server, Password) ->
extauth:set_password(User, Server, Password). case extauth:set_password(User, Server, Password) of
true -> ok;
_ -> {error, unknown_problem}
end.
try_register(_User, _Server, _Password) -> try_register(_User, _Server, _Password) ->
{error, not_allowed}. {error, not_allowed}.

View File

@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net> %%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -98,6 +98,8 @@ check_password(User, Server, Password, StreamID, Digest) ->
false false
end. end.
%% @spec (User::string(), Server::string(), Password::string()) ->
%% ok | {error, invalid_jid}
set_password(User, Server, Password) -> set_password(User, Server, Password) ->
LUser = exmpp_stringprep:nodeprep(User), LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server), LServer = exmpp_stringprep:nameprep(Server),
@ -110,7 +112,8 @@ set_password(User, Server, Password) ->
mnesia:write(#passwd{us = US, mnesia:write(#passwd{us = US,
password = Password}) password = Password})
end, end,
mnesia:transaction(F) {atomic, ok} = mnesia:transaction(F),
ok
end. end.
try_register(User, Server, Password) -> try_register(User, Server, Password) ->

View File

@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net> %%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net> %%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -103,13 +103,18 @@ check_password(User, Server, Password, StreamID, Digest) ->
false false
end. end.
%% @spec (User::string(), Server::string(), Password::string()) ->
%% ok | {error, invalid_jid}
set_password(User, Server, Password) -> set_password(User, Server, Password) ->
try try
LUser = exmpp_stringprep:nodeprep(User), LUser = exmpp_stringprep:nodeprep(User),
Username = ejabberd_odbc:escape(LUser), Username = ejabberd_odbc:escape(LUser),
Pass = ejabberd_odbc:escape(Password), Pass = ejabberd_odbc:escape(Password),
LServer = exmpp_stringprep:nameprep(Server), LServer = exmpp_stringprep:nameprep(Server),
catch odbc_queries:set_password_t(LServer, Username, Pass) case catch odbc_queries:set_password_t(LServer, Username, Pass) of
{atomic, ok} -> ok;
Other -> {error, Other}
end
catch catch
_ -> _ ->
{error, invalid_jid} {error, invalid_jid}

View File

@ -5,7 +5,7 @@
%%% Created : 5 Jul 2007 by Evgeniy Khramtsov <xram@jabber.ru> %%% Created : 5 Jul 2007 by Evgeniy Khramtsov <xram@jabber.ru>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -37,6 +37,7 @@
send_element/2, send_element/2,
socket_type/0, socket_type/0,
get_presence/1, get_presence/1,
get_subscribed/1,
get_subscribed_and_online/1]). get_subscribed_and_online/1]).
%% gen_fsm callbacks %% gen_fsm callbacks
@ -201,6 +202,9 @@ init([{SockMod, Socket}, Opts]) ->
%% Return list of all available resources of contacts, %% Return list of all available resources of contacts,
%% in form [{JID, Caps}]. %% in form [{JID, Caps}].
get_subscribed(FsmRef) ->
gen_fsm:sync_send_all_state_event(
FsmRef, get_subscribed, 1000).
get_subscribed_and_online(FsmRef) -> get_subscribed_and_online(FsmRef) ->
gen_fsm:sync_send_all_state_event( gen_fsm:sync_send_all_state_event(
FsmRef, get_subscribed_and_online, 1000). FsmRef, get_subscribed_and_online, 1000).
@ -932,6 +936,20 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
Reply = {User, Resource, atom_to_list(Show), Status}, Reply = {User, Resource, atom_to_list(Show), Status},
fsm_reply(Reply, StateName, StateData); fsm_reply(Reply, StateName, StateData);
handle_sync_event(get_subscribed, _From, StateName, StateData) ->
Subscribed = StateData#state.pres_f,
Online = StateData#state.pres_available,
Pred = fun(User, _Caps) ->
?SETS:is_element(jlib:jid_remove_resource(User),
Subscribed) orelse
?SETS:is_element(User, Subscribed)
end,
SubscribedAndOnline = ?DICT:filter(Pred, Online),
SubscribedWithCaps = ?SETS:fold(fun(User, Acc) ->
[{User, undefined}|Acc]
end, ?DICT:to_list(SubscribedAndOnline), Subscribed),
{reply, SubscribedWithCaps, StateName, StateData};
handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) -> handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) ->
Subscribed = StateData#state.pres_f, Subscribed = StateData#state.pres_f,
Online = StateData#state.pres_available, Online = StateData#state.pres_available,

View File

@ -6,7 +6,7 @@
%%% Created : 2 Nov 2007 by Mickael Remond <mremond@process-one.net> %%% Created : 2 Nov 2007 by Mickael Remond <mremond@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 27 Feb 2008 by Mickael Remond <mremond@process-one.net> %%% Created : 27 Feb 2008 by Mickael Remond <mremond@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -39,19 +39,21 @@
libs() -> libs() ->
ok. ok.
%% Consistency check on ejabberd configuration %% @doc Consistency check on ejabberd configuration
config() -> config() ->
check_database_modules(). check_database_modules().
check_database_modules() -> check_database_modules() ->
[check_database_module(M)||M<-get_db_used()]. [check_database_module(M)||M<-get_db_used()].
check_database_module(odbc) ->
check_modules(odbc, [odbc, odbc_app, odbc_sup, ejabberd_odbc, ejabberd_odbc_sup, odbc_queries]);
check_database_module(mysql) -> check_database_module(mysql) ->
check_modules(mysql, [mysql, mysql_auth, mysql_conn, mysql_recv]); check_modules(mysql, [mysql, mysql_auth, mysql_conn, mysql_recv]);
check_database_module(pgsql) -> check_database_module(pgsql) ->
check_modules(pgsql, [pgsql, pgsql_proto, pgsql_tcp, pgsql_util]). check_modules(pgsql, [pgsql, pgsql_proto, pgsql_tcp, pgsql_util]).
%% Issue a critical error and throw an exit if needing module is %% @doc Issue a critical error and throw an exit if needing module is
%% missing. %% missing.
check_modules(DB, Modules) -> check_modules(DB, Modules) ->
case get_missing_modules(Modules) of case get_missing_modules(Modules) of
@ -63,7 +65,7 @@ check_modules(DB, Modules) ->
end. end.
%% Return the list of undefined modules %% @doc Return the list of undefined modules
get_missing_modules(Modules) -> get_missing_modules(Modules) ->
lists:filter(fun(Module) -> lists:filter(fun(Module) ->
case catch Module:module_info() of case catch Module:module_info() of
@ -73,7 +75,7 @@ get_missing_modules(Modules) ->
end end
end, Modules). end, Modules).
%% Return the list of databases used %% @doc Return the list of databases used
get_db_used() -> get_db_used() ->
%% Retrieve domains with a database configured: %% Retrieve domains with a database configured:
Domains = Domains =
@ -86,14 +88,22 @@ get_db_used() ->
case check_odbc_option( case check_odbc_option(
ejabberd_config:get_local_option( ejabberd_config:get_local_option(
{auth_method, Domain})) of {auth_method, Domain})) of
true -> [element(1, DB)|Acc]; true -> [get_db_type(DB)|Acc];
_ -> Acc _ -> Acc
end end
end, end,
[], Domains), [], Domains),
lists:usort(DBs). lists:usort(DBs).
%% Return true if odbc option is used %% @doc Depending in the DB definition, return which type of DB this is.
%% Note that MSSQL is detected as ODBC.
%% @spec (DB) -> mysql | pgsql | odbc
get_db_type(DB) when is_tuple(DB) ->
element(1, DB);
get_db_type(DB) when is_list(DB) ->
odbc.
%% @doc Return true if odbc option is used
check_odbc_option(odbc) -> check_odbc_option(odbc) ->
true; true;
check_odbc_option(AuthMethods) when is_list(AuthMethods) -> check_odbc_option(AuthMethods) when is_list(AuthMethods) ->

View File

@ -5,7 +5,7 @@
%%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -95,10 +95,14 @@ get_plain_terms_file(File1) ->
case file:consult(File) of case file:consult(File) of
{ok, Terms} -> {ok, Terms} ->
include_config_files(Terms); include_config_files(Terms);
{error, Reason} -> {error, {_LineNumber, erl_parse, _ParseMessage} = Reason} ->
ExitText = lists:flatten(File ++ ": around line " ExitText = lists:flatten(File ++ " approximately in the line "
++ file:format_error(Reason)), ++ file:format_error(Reason)),
?ERROR_MSG("Problem loading ejabberd config file:~n~s", [ExitText]), ?ERROR_MSG("Problem loading ejabberd config file ~n~s", [ExitText]),
exit(ExitText);
{error, Reason} ->
ExitText = lists:flatten(File ++ ": " ++ file:format_error(Reason)),
?ERROR_MSG("Problem loading ejabberd config file ~n~s", [ExitText]),
exit(ExitText) exit(ExitText)
end. end.

View File

@ -1,6 +1,6 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 11 Jan 2004 by Alexey Shchepin <alexey@process-one.net> %%% Created : 11 Jan 2004 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -99,6 +99,9 @@ process(["restart"]) ->
process(["reopen-log"]) -> process(["reopen-log"]) ->
ejabberd_hooks:run(reopen_log_hook, []), ejabberd_hooks:run(reopen_log_hook, []),
lists:foreach(fun(Host) ->
ejabberd_hooks:run(reopen_log_hook, Host, [Host])
end, ?MYHOSTS),
%% TODO: Use the Reopen log API for logger_h ? %% TODO: Use the Reopen log API for logger_h ?
ejabberd_logger_h:reopen_log(), ejabberd_logger_h:reopen_log(),
?STATUS_SUCCESS; ?STATUS_SUCCESS;

View File

@ -1,6 +1,6 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net> %%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 8 Aug 2004 by Alexey Shchepin <alexey@process-one.net> %%% Created : 8 Aug 2004 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 30 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 30 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 23 Oct 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 23 Oct 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -9,7 +9,7 @@
%%% Created : 29 Nov 2006 by Mickael Remond <mremond@process-one.net> %%% Created : 29 Nov 2006 by Mickael Remond <mremond@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 1 Nov 2006 by Alexey Shchepin <alexey@process-one.net> %%% Created : 1 Nov 2006 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 10 Nov 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 10 Nov 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 27 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 27 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -161,7 +161,7 @@ unregister_route(Domain) ->
mnesia:transaction(F); mnesia:transaction(F);
_ -> _ ->
F = fun() -> F = fun() ->
case mnesia:match(#route{domain = LDomain, case mnesia:match_object(#route{domain=LDomain,
pid = Pid, pid = Pid,
_ = '_'}) of _ = '_'}) of
[R] -> [R] ->

View File

@ -5,7 +5,7 @@
%%% Created : 7 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 7 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -1,11 +1,11 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% File : ejabberd_service.erl %%% File : ejabberd_service.erl
%%% Author : Alexey Shchepin <alexey@process-one.net> %%% Author : Alexey Shchepin <alexey@process-one.net>
%%% Purpose : External component management %%% Purpose : External component management (XEP-0114)
%%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -147,11 +147,15 @@ init([{SockMod, Socket}, Opts]) ->
%% {stop, Reason, NewStateData} %% {stop, Reason, NewStateData}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
wait_for_stream({xmlstreamstart, #xmlel{ns = NS}}, StateData) -> wait_for_stream({xmlstreamstart, #xmlel{ns = NS, attrs = Attrs}}, StateData) ->
% TODO
case NS of case NS of
?NS_COMPONENT_ACCEPT -> ?NS_COMPONENT_ACCEPT ->
Opening_Reply = exmpp_stream:opening_reply(?MYNAME, %% Note: XEP-0114 requires to check that destination is a Jabber
%% component served by this Jabber server.
%% However several transports don't respect that,
%% so ejabberd doesn't check 'to' attribute (EJAB-717)
To = exmpp_stanza:get_recipient_from_attrs(Attrs),
Opening_Reply = exmpp_stream:opening_reply(xml:crypt(To),
?NS_COMPONENT_ACCEPT, ?NS_COMPONENT_ACCEPT,
{0, 0}, StateData#state.streamid), {0, 0}, StateData#state.streamid),
send_element(StateData, Opening_Reply), send_element(StateData, Opening_Reply),

View File

@ -5,7 +5,7 @@
%%% Created : 24 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 24 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net> %%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 21 Mar 2007 by Alexey Shchepin <alexey@process-one.net> %%% Created : 21 Mar 2007 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 18 Jul 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 18 Jul 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 27 Jan 2006 by Alexey Shchepin <alexey@process-one.net> %%% Created : 27 Jan 2006 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 19 Jan 2006 by Alexey Shchepin <alexey@process-one.net> %%% Created : 19 Jan 2006 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -1,5 +1,5 @@
/* /*
* ejabberd, Copyright (C) 2002-2008 Process-one * ejabberd, Copyright (C) 2002-2008 ProcessOne
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 22 Aug 2005 by Alexey Shchepin <alexey@process-one.net> %%% Created : 22 Aug 2005 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -1,6 +1,6 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -6,7 +6,7 @@
%%% Author: Evgeniy Khramtsov <xramtsov@gmail.com> %%% Author: Evgeniy Khramtsov <xramtsov@gmail.com>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 12 Nov 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% Created : 12 Nov 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 12 Oct 2006 by Mickael Remond <mremond@process-one.net> %%% Created : 12 Oct 2006 by Mickael Remond <mremond@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 30 Jul 2004 by Leif Johansson <leifj@it.su.se> %%% Created : 30 Jul 2004 by Leif Johansson <leifj@it.su.se>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 22 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 22 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 24 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 24 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -30,6 +30,7 @@
-export([start/0, -export([start/0,
start_module/3, start_module/3,
stop_module/2, stop_module/2,
stop_module_keep_config/2,
get_opt/2, get_opt/2,
get_opt/3, get_opt/3,
get_opt_host/3, get_opt_host/3,
@ -72,22 +73,34 @@ start_module(Host, Module, Opts) ->
ok ok
end. end.
%% @doc Stop the module in a host, and forget its configuration.
stop_module(Host, Module) -> stop_module(Host, Module) ->
case stop_module_keep_config(Host, Module) of
error ->
error;
ok ->
del_module_mnesia(Host, Module)
end.
%% @doc Stop the module in a host, but keep its configuration.
%% As the module configuration is kept in the Mnesia local_config table,
%% when ejabberd is restarted the module will be started again.
%% This function is useful when ejabberd is being stopped
%% and it stops all modules.
stop_module_keep_config(Host, Module) ->
case catch Module:stop(Host) of case catch Module:stop(Host) of
{'EXIT', Reason} -> {'EXIT', Reason} ->
?ERROR_MSG("~p", [Reason]); ?ERROR_MSG("~p", [Reason]),
error;
{wait, ProcList} when is_list(ProcList) -> {wait, ProcList} when is_list(ProcList) ->
lists:foreach(fun wait_for_process/1, ProcList), lists:foreach(fun wait_for_process/1, ProcList),
del_module_mnesia(Host, Module),
ets:delete(ejabberd_modules, {Module, Host}), ets:delete(ejabberd_modules, {Module, Host}),
ok; ok;
{wait, Process} -> {wait, Process} ->
wait_for_process(Process), wait_for_process(Process),
del_module_mnesia(Host, Module),
ets:delete(ejabberd_modules, {Module, Host}), ets:delete(ejabberd_modules, {Module, Host}),
ok; ok;
_ -> _ ->
del_module_mnesia(Host, Module),
ets:delete(ejabberd_modules, {Module, Host}), ets:delete(ejabberd_modules, {Module, Host}),
ok ok
end. end.

View File

@ -5,7 +5,7 @@
%%% Created : 10 Apr 2004 by Alexey Shchepin <alexey@process-one.net> %%% Created : 10 Apr 2004 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 2 Feb 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 2 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -1,6 +1,6 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 15 Nov 2005 by Magnus Henoch <henoch@dtek.chalmers.se> %%% Created : 15 Nov 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 11 Aug 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 11 Aug 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 7 Oct 2006 by Magnus Henoch <henoch@dtek.chalmers.se> %%% Created : 7 Oct 2006 by Magnus Henoch <henoch@dtek.chalmers.se>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 26 Oct 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 26 Oct 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 1 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 1 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 15 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 15 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -7,7 +7,7 @@
%%% {mod_ip_blacklist, []} %%% {mod_ip_blacklist, []}
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 16 Feb 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 16 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -1,5 +1,5 @@
/* /*
* ejabberd, Copyright (C) 2002-2008 Process-one * ejabberd, Copyright (C) 2002-2008 ProcessOne
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 15 Feb 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 15 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 15 Feb 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 15 Feb 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 24 Oct 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 24 Oct 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 24 Oct 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 24 Oct 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -111,8 +111,6 @@ process_sm_iq(From, To, IQ) ->
get_last(IQ, LUser, LServer) -> get_last(IQ, LUser, LServer) ->
Username = ejabberd_odbc:escape(LUser), Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_last(LServer, Username) of case catch odbc_queries:get_last(LServer, Username) of
{'EXIT', _Reason} ->
exmpp_iq:error(IQ, 'internal-server-error');
{selected, ["seconds","state"], []} -> {selected, ["seconds","state"], []} ->
exmpp_iq:error(IQ, 'service-unavailable'); exmpp_iq:error(IQ, 'service-unavailable');
{selected, ["seconds","state"], [{STimeStamp, Status}]} -> {selected, ["seconds","state"], [{STimeStamp, Status}]} ->
@ -127,7 +125,9 @@ get_last(IQ, LUser, LServer) ->
exmpp_iq:result(IQ, Response); exmpp_iq:result(IQ, Response);
_ -> _ ->
exmpp_iq:error(IQ, 'internal-server-error') exmpp_iq:error(IQ, 'internal-server-error')
end end;
_ ->
exmpp_iq:error(IQ, 'internal-server-error')
end. end.
on_presence_update(User, Server, _Resource, Status) -> on_presence_update(User, Server, _Resource, Status) ->
@ -147,8 +147,6 @@ store_last_info(User, Server, TimeStamp, Status) ->
get_last_info(LUser, LServer) -> get_last_info(LUser, LServer) ->
Username = ejabberd_odbc:escape(LUser), Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_last(LServer, Username) of case catch odbc_queries:get_last(LServer, Username) of
{'EXIT', _Reason} ->
not_found;
{selected, ["seconds","state"], []} -> {selected, ["seconds","state"], []} ->
not_found; not_found;
{selected, ["seconds","state"], [{STimeStamp, Status}]} -> {selected, ["seconds","state"], [{STimeStamp, Status}]} ->
@ -157,7 +155,9 @@ get_last_info(LUser, LServer) ->
{ok, TimeStamp, Status}; {ok, TimeStamp, Status};
_ -> _ ->
not_found not_found
end end;
_ ->
not_found
end. end.
remove_user(User, Server) -> remove_user(User, Server) ->

View File

@ -5,7 +5,7 @@
%%% Created : 19 Mar 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 19 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 12 Mar 2006 by Alexey Shchepin <alexey@process-one.net> %%% Created : 12 Mar 2006 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -52,6 +52,8 @@
-record(state, {host, -record(state, {host,
out_dir, out_dir,
dir_type, dir_type,
dir_name,
file_format,
css_file, css_file,
access, access,
lang, lang,
@ -113,6 +115,8 @@ check_access_log(Host, From) ->
init([Host, Opts]) -> init([Host, Opts]) ->
OutDir = gen_mod:get_opt(outdir, Opts, "www/muc"), OutDir = gen_mod:get_opt(outdir, Opts, "www/muc"),
DirType = gen_mod:get_opt(dirtype, Opts, subdirs), DirType = gen_mod:get_opt(dirtype, Opts, subdirs),
DirName = gen_mod:get_opt(dirname, Opts, room_jid),
FileFormat = gen_mod:get_opt(file_format, Opts, html), % Allowed values: html|plaintext
CSSFile = gen_mod:get_opt(cssfile, Opts, false), CSSFile = gen_mod:get_opt(cssfile, Opts, false),
AccessLog = gen_mod:get_opt(access_log, Opts, muc_admin), AccessLog = gen_mod:get_opt(access_log, Opts, muc_admin),
Timezone = gen_mod:get_opt(timezone, Opts, local), Timezone = gen_mod:get_opt(timezone, Opts, local),
@ -129,6 +133,8 @@ init([Host, Opts]) ->
{ok, #state{host = Host, {ok, #state{host = Host,
out_dir = OutDir, out_dir = OutDir,
dir_type = DirType, dir_type = DirType,
dir_name = DirName,
file_format = FileFormat,
css_file = CSSFile, css_file = CSSFile,
access = AccessLog, access = AccessLog,
lang = Lang, lang = Lang,
@ -231,10 +237,10 @@ add_to_log2(kickban, {Nick, Reason, Code}, Room, Opts, State) ->
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
%% Core %% Core
build_filename_string(TimeStamp, OutDir, RoomJID, DirType) -> build_filename_string(TimeStamp, OutDir, RoomJID, DirType, DirName, FileFormat) ->
{{Year, Month, Day}, _Time} = TimeStamp, {{Year, Month, Day}, _Time} = TimeStamp,
% Directory and file names %% Directory and file names
{Dir, Filename, Rel} = {Dir, Filename, Rel} =
case DirType of case DirType of
subdirs -> subdirs ->
@ -248,55 +254,75 @@ build_filename_string(TimeStamp, OutDir, RoomJID, DirType) ->
[Year, Month, Day])), [Year, Month, Day])),
{"", Date, "."} {"", Date, "."}
end, end,
Fd = filename:join([OutDir, RoomJID, Dir]),
Fn = filename:join([Fd, Filename ++ ".html"]), RoomString = case DirName of
Fnrel = filename:join([Rel, Dir, Filename ++ ".html"]), room_jid -> RoomJID;
room_name -> get_room_name(RoomJID)
end,
Extension = case FileFormat of
html -> ".html";
plaintext -> ".txt"
end,
Fd = filename:join([OutDir, RoomString, Dir]),
Fn = filename:join([Fd, Filename ++ Extension]),
Fnrel = filename:join([Rel, Dir, Filename ++ Extension]),
{Fd, Fn, Fnrel}. {Fd, Fn, Fnrel}.
% calculate day before get_room_name(RoomJID) ->
JID = jlib:string_to_jid(RoomJID),
JID#jid.user.
%% calculate day before
get_timestamp_daydiff(TimeStamp, Daydiff) -> get_timestamp_daydiff(TimeStamp, Daydiff) ->
{Date1, HMS} = TimeStamp, {Date1, HMS} = TimeStamp,
Date2 = calendar:gregorian_days_to_date( Date2 = calendar:gregorian_days_to_date(
calendar:date_to_gregorian_days(Date1) + Daydiff), calendar:date_to_gregorian_days(Date1) + Daydiff),
{Date2, HMS}. {Date2, HMS}.
% Try to close the previous day log, if it exists %% Try to close the previous day log, if it exists
close_previous_log(Fn, Images_dir) -> close_previous_log(Fn, Images_dir, FileFormat) ->
case file:read_file_info(Fn) of case file:read_file_info(Fn) of
{ok, _} -> {ok, _} ->
{ok, F} = file:open(Fn, [append]), {ok, F} = file:open(Fn, [append]),
%fw(F, "<div class=\"legend\">ejabberd/mod_muc log<span class=\"w3c\">"), write_last_lines(F, Images_dir, FileFormat),
file:close(F);
_ -> ok
end.
write_last_lines(_, _, plaintext) ->
ok;
write_last_lines(F, Images_dir, _FileFormat) ->
%%fw(F, "<div class=\"legend\">ejabberd/mod_muc log<span class=\"w3c\">"),
fw(F, "<div class=\"legend\">"), fw(F, "<div class=\"legend\">"),
fw(F, " <a href=\"http://www.ejabberd.im\"><img style=\"border:0\" src=\"~s/powered-by-ejabberd.png\" alt=\"Powered by ejabberd\"/></a>", [Images_dir]), fw(F, " <a href=\"http://www.ejabberd.im\"><img style=\"border:0\" src=\"~s/powered-by-ejabberd.png\" alt=\"Powered by ejabberd\"/></a>", [Images_dir]),
fw(F, " <a href=\"http://www.erlang.org/\"><img style=\"border:0\" src=\"~s/powered-by-erlang.png\" alt=\"Powered by Erlang\"/></a>", [Images_dir]), fw(F, " <a href=\"http://www.erlang.org/\"><img style=\"border:0\" src=\"~s/powered-by-erlang.png\" alt=\"Powered by Erlang\"/></a>", [Images_dir]),
fw(F, "<span class=\"w3c\">"), fw(F, "<span class=\"w3c\">"),
fw(F, " <a href=\"http://validator.w3.org/check?uri=referer\"><img style=\"border:0;width:88px;height:31px\" src=\"~s/valid-xhtml10.png\" alt=\"Valid XHTML 1.0 Transitional\" /></a>", [Images_dir]), fw(F, " <a href=\"http://validator.w3.org/check?uri=referer\"><img style=\"border:0;width:88px;height:31px\" src=\"~s/valid-xhtml10.png\" alt=\"Valid XHTML 1.0 Transitional\" /></a>", [Images_dir]),
fw(F, " <a href=\"http://jigsaw.w3.org/css-validator/\"><img style=\"border:0;width:88px;height:31px\" src=\"~s/vcss.png\" alt=\"Valid CSS!\"/></a>", [Images_dir]), fw(F, " <a href=\"http://jigsaw.w3.org/css-validator/\"><img style=\"border:0;width:88px;height:31px\" src=\"~s/vcss.png\" alt=\"Valid CSS!\"/></a>", [Images_dir]),
fw(F, "</span></div></body></html>"), fw(F, "</span></div></body></html>").
file:close(F);
_ -> ok
end.
add_message_to_log(Nick1, Message, RoomJID, Opts, State) -> add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
Nick = htmlize(Nick1),
#state{out_dir = OutDir, #state{out_dir = OutDir,
dir_type = DirType, dir_type = DirType,
dir_name = DirName,
file_format = FileFormat,
css_file = CSSFile, css_file = CSSFile,
lang = Lang, lang = Lang,
timezone = Timezone, timezone = Timezone,
spam_prevention = NoFollow, spam_prevention = NoFollow,
top_link = TopLink} = State, top_link = TopLink} = State,
Room = get_room_info(RoomJID, Opts), Room = get_room_info(RoomJID, Opts),
Nick = htmlize(Nick1, FileFormat),
Nick2 = htmlize("<"++Nick1++">", FileFormat),
Now = now(), Now = now(),
TimeStamp = case Timezone of TimeStamp = case Timezone of
local -> calendar:now_to_local_time(Now); local -> calendar:now_to_local_time(Now);
universal -> calendar:now_to_universal_time(Now) universal -> calendar:now_to_universal_time(Now)
end, end,
{Fd, Fn, _Dir} = build_filename_string(TimeStamp, OutDir, Room#room.jid, DirType), {Fd, Fn, _Dir} = build_filename_string(TimeStamp, OutDir, Room#room.jid, DirType, DirName, FileFormat),
{Date, Time} = TimeStamp, {Date, Time} = TimeStamp,
% Open file, create if it does not exist, create parent dirs if needed %% Open file, create if it does not exist, create parent dirs if needed
case file:read_file_info(Fn) of case file:read_file_info(Fn) of
{ok, _} -> {ok, _} ->
{ok, F} = file:open(Fn, [append]); {ok, F} = file:open(Fn, [append]);
@ -308,16 +334,16 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
TimeStampYesterday = get_timestamp_daydiff(TimeStamp, -1), TimeStampYesterday = get_timestamp_daydiff(TimeStamp, -1),
{_FdYesterday, FnYesterday, DatePrev} = {_FdYesterday, FnYesterday, DatePrev} =
build_filename_string( build_filename_string(
TimeStampYesterday, OutDir, Room#room.jid, DirType), TimeStampYesterday, OutDir, Room#room.jid, DirType, DirName, FileFormat),
TimeStampTomorrow = get_timestamp_daydiff(TimeStamp, 1), TimeStampTomorrow = get_timestamp_daydiff(TimeStamp, 1),
{_FdTomorrow, _FnTomorrow, DateNext} = {_FdTomorrow, _FnTomorrow, DateNext} =
build_filename_string( build_filename_string(
TimeStampTomorrow, OutDir, Room#room.jid, DirType), TimeStampTomorrow, OutDir, Room#room.jid, DirType, DirName, FileFormat),
HourOffset = calc_hour_offset(TimeStamp), HourOffset = calc_hour_offset(TimeStamp),
put_header(F, Room, Datestring, CSSFile, Lang, put_header(F, Room, Datestring, CSSFile, Lang,
HourOffset, DatePrev, DateNext, TopLink), HourOffset, DatePrev, DateNext, TopLink, FileFormat),
Images_dir = filename:join([OutDir, "images"]), Images_dir = filename:join([OutDir, "images"]),
file:make_dir(Images_dir), file:make_dir(Images_dir),
@ -326,14 +352,14 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
subdirs -> "../../../images"; subdirs -> "../../../images";
plain -> "../images" plain -> "../images"
end, end,
close_previous_log(FnYesterday, Images_url) close_previous_log(FnYesterday, Images_url, FileFormat)
end, end,
% Build message %% Build message
Text = case Message of Text = case Message of
roomconfig_change -> roomconfig_change ->
RoomConfig = roomconfig_to_string(Room#room.config, Lang), RoomConfig = roomconfig_to_string(Room#room.config, Lang, FileFormat),
put_room_config(F, RoomConfig, Lang), put_room_config(F, RoomConfig, Lang, FileFormat),
io_lib:format("<font class=\"mrcm\">~s</font><br/>", io_lib:format("<font class=\"mrcm\">~s</font><br/>",
[?T("Chatroom configuration modified")]); [?T("Chatroom configuration modified")]);
join -> join ->
@ -344,19 +370,19 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
[Nick, ?T("leaves the room")]); [Nick, ?T("leaves the room")]);
{leave, Reason} -> {leave, Reason} ->
io_lib:format("<font class=\"ml\">~s ~s: ~s</font><br/>", io_lib:format("<font class=\"ml\">~s ~s: ~s</font><br/>",
[Nick, ?T("leaves the room"), htmlize(Reason,NoFollow)]); [Nick, ?T("leaves the room"), htmlize(Reason,NoFollow,FileFormat)]);
{kickban, "301", ""} -> {kickban, "301", ""} ->
io_lib:format("<font class=\"mb\">~s ~s</font><br/>", io_lib:format("<font class=\"mb\">~s ~s</font><br/>",
[Nick, ?T("has been banned")]); [Nick, ?T("has been banned")]);
{kickban, "301", Reason} -> {kickban, "301", Reason} ->
io_lib:format("<font class=\"mb\">~s ~s: ~s</font><br/>", io_lib:format("<font class=\"mb\">~s ~s: ~s</font><br/>",
[Nick, ?T("has been banned"), htmlize(Reason)]); [Nick, ?T("has been banned"), htmlize(Reason,FileFormat)]);
{kickban, "307", ""} -> {kickban, "307", ""} ->
io_lib:format("<font class=\"mk\">~s ~s</font><br/>", io_lib:format("<font class=\"mk\">~s ~s</font><br/>",
[Nick, ?T("has been kicked")]); [Nick, ?T("has been kicked")]);
{kickban, "307", Reason} -> {kickban, "307", Reason} ->
io_lib:format("<font class=\"mk\">~s ~s: ~s</font><br/>", io_lib:format("<font class=\"mk\">~s ~s: ~s</font><br/>",
[Nick, ?T("has been kicked"), htmlize(Reason)]); [Nick, ?T("has been kicked"), htmlize(Reason,FileFormat)]);
{kickban, "321", ""} -> {kickban, "321", ""} ->
io_lib:format("<font class=\"mk\">~s ~s</font><br/>", io_lib:format("<font class=\"mk\">~s ~s</font><br/>",
[Nick, ?T("has been kicked because of an affiliation change")]); [Nick, ?T("has been kicked because of an affiliation change")]);
@ -368,18 +394,18 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
[Nick, ?T("has been kicked because of a system shutdown")]); [Nick, ?T("has been kicked because of a system shutdown")]);
{nickchange, OldNick} -> {nickchange, OldNick} ->
io_lib:format("<font class=\"mnc\">~s ~s ~s</font><br/>", io_lib:format("<font class=\"mnc\">~s ~s ~s</font><br/>",
[htmlize(OldNick), ?T("is now known as"), Nick]); [htmlize(OldNick,FileFormat), ?T("is now known as"), Nick]);
{subject, T} -> {subject, T} ->
io_lib:format("<font class=\"msc\">~s~s~s</font><br/>", io_lib:format("<font class=\"msc\">~s~s~s</font><br/>",
[Nick, ?T(" has set the subject to: "), htmlize(T,NoFollow)]); [Nick, ?T(" has set the subject to: "), htmlize(T,NoFollow,FileFormat)]);
{body, T} -> {body, T} ->
case regexp:first_match(T, "^/me\s") of case regexp:first_match(T, "^/me\s") of
{match, _, _} -> {match, _, _} ->
io_lib:format("<font class=\"mne\">~s ~s</font><br/>", io_lib:format("<font class=\"mne\">~s ~s</font><br/>",
[Nick, string:substr(htmlize(T), 5)]); [Nick, string:substr(htmlize(T,FileFormat), 5)]);
nomatch -> nomatch ->
io_lib:format("<font class=\"mn\">&lt;~s&gt;</font> ~s<br/>", io_lib:format("<font class=\"mn\">~s</font> ~s<br/>",
[Nick, htmlize(T,NoFollow)]) [Nick2, htmlize(T,NoFollow,FileFormat)])
end end
end, end,
{Hour, Minute, Second} = Time, {Hour, Minute, Second} = Time,
@ -388,11 +414,11 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
{_, _, Microsecs} = Now, {_, _, Microsecs} = Now,
STimeUnique = io_lib:format("~s.~w", [STime, Microsecs]), STimeUnique = io_lib:format("~s.~w", [STime, Microsecs]),
% Write message %% Write message
file:write(F, io_lib:format("<a id=\"~s\" name=\"~s\" href=\"#~s\" class=\"ts\">[~s]</a> ~s~n", fw(F, io_lib:format("<a id=\"~s\" name=\"~s\" href=\"#~s\" class=\"ts\">[~s]</a> ",
[STimeUnique, STimeUnique, STimeUnique, STime, Text])), [STimeUnique, STimeUnique, STimeUnique, STime]) ++ Text, FileFormat),
% Close file %% Close file
file:close(F), file:close(F),
ok. ok.
@ -443,10 +469,10 @@ make_dir_rec(Dir) ->
end. end.
% {ok, F1}=file:open("valid-xhtml10.png", [read]). %% {ok, F1}=file:open("valid-xhtml10.png", [read]).
% {ok, F1b}=file:read(F1, 1000000). %% {ok, F1b}=file:read(F1, 1000000).
% c("../../ejabberd/src/jlib.erl"). %% c("../../ejabberd/src/jlib.erl").
% jlib:encode_base64(F1b). %% jlib:encode_base64(F1b).
image_base64("powered-by-erlang.png") -> image_base64("powered-by-erlang.png") ->
"iVBORw0KGgoAAAANSUhEUgAAAGUAAAAfCAYAAAD+xQNoAAADN0lEQVRo3u1a" "iVBORw0KGgoAAAANSUhEUgAAAGUAAAAfCAYAAAD+xQNoAAADN0lEQVRo3u1a"
@ -579,8 +605,7 @@ image_base64("powered-by-ejabberd.png") ->
"AElFTkSuQmCC". "AElFTkSuQmCC".
create_image_files(Images_dir) -> create_image_files(Images_dir) ->
Filenames = [ Filenames = ["powered-by-ejabberd.png",
"powered-by-ejabberd.png",
"powered-by-erlang.png", "powered-by-erlang.png",
"valid-xhtml10.png", "valid-xhtml10.png",
"vcss.png" "vcss.png"
@ -596,10 +621,27 @@ create_image_files(Images_dir) ->
Filenames), Filenames),
ok. ok.
fw(F, S, O) -> io:format(F, S ++ "~n", O). fw(F, S) -> fw(F, S, [], html).
fw(F, S) -> fw(F, S, []).
put_header(F, Room, Date, CSSFile, Lang, Hour_offset, Date_prev, Date_next, Top_link) -> fw(F, S, O) when is_list(O) ->
fw(F, S, O, html);
fw(F, S, FileFormat) when is_atom(FileFormat) ->
fw(F, S, [], FileFormat).
fw(F, S, O, FileFormat) ->
S1 = io_lib:format(S ++ "~n", O),
S2 = case FileFormat of
html ->
S1;
plaintext ->
{ok, Res, _} = regexp:gsub(S1, "<[^>]*>", ""),
Res
end,
io:format(F, S2, []).
put_header(_, _, _, _, _, _, _, _, _, plaintext) ->
ok;
put_header(F, Room, Date, CSSFile, Lang, Hour_offset, Date_prev, Date_next, Top_link, FileFormat) ->
fw(F, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"), fw(F, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"),
fw(F, "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"~s\" lang=\"~s\">", [Lang, Lang]), fw(F, "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"~s\" lang=\"~s\">", [Lang, Lang]),
fw(F, "<head>"), fw(F, "<head>"),
@ -618,8 +660,8 @@ put_header(F, Room, Date, CSSFile, Lang, Hour_offset, Date_prev, Date_next, Top_
{"", ""} -> ok; {"", ""} -> ok;
{SuA, Su} -> fw(F, "<div class=\"roomsubject\">~s~s~s</div>", [SuA, ?T(" has set the subject to: "), Su]) {SuA, Su} -> fw(F, "<div class=\"roomsubject\">~s~s~s</div>", [SuA, ?T(" has set the subject to: "), Su])
end, end,
RoomConfig = roomconfig_to_string(Room#room.config, Lang), RoomConfig = roomconfig_to_string(Room#room.config, Lang, FileFormat),
put_room_config(F, RoomConfig, Lang), put_room_config(F, RoomConfig, Lang, FileFormat),
Time_offset_str = case Hour_offset<0 of Time_offset_str = case Hour_offset<0 of
true -> io_lib:format("~p", [Hour_offset]); true -> io_lib:format("~p", [Hour_offset]);
false -> io_lib:format("+~p", [Hour_offset]) false -> io_lib:format("+~p", [Hour_offset])
@ -669,7 +711,9 @@ put_header_script(F) ->
fw(F, "else {document.getElementById(e).style.display='none';}}"), fw(F, "else {document.getElementById(e).style.display='none';}}"),
fw(F, "</script>"). fw(F, "</script>").
put_room_config(F, RoomConfig, Lang) -> put_room_config(_F, _RoomConfig, _Lang, plaintext) ->
ok;
put_room_config(F, RoomConfig, Lang, _FileFormat) ->
{_, Now2, _} = now(), {_, Now2, _} = now(),
fw(F, "<div class=\"rc\">"), fw(F, "<div class=\"rc\">"),
fw(F, "<div class=\"rct\" onclick=\"sh('a~p');return false;\">~s</div>", [Now2, ?T("Room Configuration")]), fw(F, "<div class=\"rct\" onclick=\"sh('a~p');return false;\">~s</div>", [Now2, ?T("Room Configuration")]),
@ -680,11 +724,18 @@ put_room_config(F, RoomConfig, Lang) ->
%% The default behaviour is to ignore the nofollow spam prevention on links %% The default behaviour is to ignore the nofollow spam prevention on links
%% (NoFollow=false) %% (NoFollow=false)
htmlize(S1) -> htmlize(S1) ->
htmlize(S1, false). htmlize(S1, html).
htmlize(S1, plaintext) ->
S1;
htmlize(S1, FileFormat) ->
htmlize(S1, false, FileFormat).
%% The NoFollow parameter tell if the spam prevention should be applied to the link found %% The NoFollow parameter tell if the spam prevention should be applied to the link found
%% true means 'apply nofollow on links'. %% true means 'apply nofollow on links'.
htmlize(S1, NoFollow) -> htmlize(S1, _NoFollow, plaintext) ->
S1;
htmlize(S1, NoFollow, _FileFormat) ->
S2_list = string:tokens(S1, "\n"), S2_list = string:tokens(S1, "\n"),
lists:foldl( lists:foldl(
fun(Si, Res) -> fun(Si, Res) ->
@ -735,20 +786,20 @@ get_room_info(RoomJID, Opts) ->
config = Opts config = Opts
}. }.
roomconfig_to_string(Options, Lang) -> roomconfig_to_string(Options, Lang, FileFormat) ->
% Get title, if available %% Get title, if available
Title = case lists:keysearch(title, 1, Options) of Title = case lists:keysearch(title, 1, Options) of
{value, Tuple} -> [Tuple]; {value, Tuple} -> [Tuple];
false -> [] false -> []
end, end,
% Remove title from list %% Remove title from list
Os1 = lists:keydelete(title, 1, Options), Os1 = lists:keydelete(title, 1, Options),
% Order list %% Order list
Os2 = lists:sort(Os1), Os2 = lists:sort(Os1),
% Add title to ordered list %% Add title to ordered list
Options2 = Title ++ Os2, Options2 = Title ++ Os2,
lists:foldl( lists:foldl(
@ -765,7 +816,7 @@ roomconfig_to_string(Options, Lang) ->
T -> T ->
case Opt of case Opt of
password -> "<div class=\"rcoe\">" ++ OptText ++ "</div>"; password -> "<div class=\"rcoe\">" ++ OptText ++ "</div>";
title -> "<div class=\"rcot\">" ++ ?T("Room title") ++ ": \"" ++ htmlize(T) ++ "\"</div>"; title -> "<div class=\"rcot\">" ++ ?T("Room title") ++ ": \"" ++ htmlize(T, FileFormat) ++ "\"</div>";
_ -> "\"" ++ T ++ "\"" _ -> "\"" ++ T ++ "\""
end end
end, end,

View File

@ -5,7 +5,7 @@
%%% Created : 19 Mar 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 19 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -63,6 +63,8 @@
allow_change_subj = true, allow_change_subj = true,
allow_query_users = true, allow_query_users = true,
allow_private_messages = true, allow_private_messages = true,
allow_visitor_status = true,
allow_visitor_nickchange = true,
public = true, public = true,
public_list = true, public_list = true,
persistent = false, persistent = false,
@ -886,9 +888,8 @@ process_groupchat_message(From, {xmlelement, "message", Attrs, _Els} = Packet,
%% Check the mod_muc option access_message_nonparticipant and wether this JID %% Check the mod_muc option access_message_nonparticipant and wether this JID
%% is allowed or denied %% is allowed or denied
is_user_allowed_message_nonparticipant(JID, StateData) -> is_user_allowed_message_nonparticipant(JID, StateData) ->
{_AccessRoute, _AccessCreate, AccessAdmin, _AccessPersistent} = StateData#state.access, case get_service_affiliation(JID, StateData) of
case acl:match_rule(StateData#state.server_host, AccessAdmin, JID) of owner ->
allow ->
true; true;
_ -> false _ -> false
end. end.
@ -941,8 +942,22 @@ process_presence(From, Nick, {xmlelement, "presence", Attrs, _Els} = Packet,
true -> true ->
case {is_nick_exists(Nick, StateData), case {is_nick_exists(Nick, StateData),
mod_muc:can_use_nick( mod_muc:can_use_nick(
StateData#state.host, From, Nick)} of StateData#state.host, From, Nick),
{true, _} -> {(StateData#state.config)#config.allow_visitor_nickchange,
is_visitor(From, StateData)}} of
{_, _, {false, true}} ->
ErrText = "Visitors are not allowed to change their nicknames in this room",
Err = jlib:make_error_reply(
Packet,
?ERRT_NOT_ALLOWED(Lang, ErrText)),
ejabberd_router:route(
% TODO: s/Nick/""/
jlib:jid_replace_resource(
StateData#state.jid,
Nick),
From, Err),
StateData;
{true, _, _} ->
Lang = xml:get_attr_s("xml:lang", Attrs), Lang = xml:get_attr_s("xml:lang", Attrs),
ErrText = "Nickname is already in use by another occupant", ErrText = "Nickname is already in use by another occupant",
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
@ -954,7 +969,7 @@ process_presence(From, Nick, {xmlelement, "presence", Attrs, _Els} = Packet,
Nick), % TODO: s/Nick/""/ Nick), % TODO: s/Nick/""/
From, Err), From, Err),
StateData; StateData;
{_, false} -> {_, false, _} ->
ErrText = "Nickname is registered by another person", ErrText = "Nickname is registered by another person",
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
Packet, Packet,
@ -969,9 +984,15 @@ process_presence(From, Nick, {xmlelement, "presence", Attrs, _Els} = Packet,
_ -> _ ->
change_nick(From, Nick, StateData) change_nick(From, Nick, StateData)
end; end;
_ -> _NotNickChange ->
NewState = Stanza = case {(StateData#state.config)#config.allow_visitor_status,
add_user_presence(From, Packet, StateData), is_visitor(From, StateData)} of
{false, true} ->
strip_status(Packet);
_Allowed ->
Packet
end,
NewState = add_user_presence(From, Stanza, StateData),
send_new_presence(From, NewState), send_new_presence(From, NewState),
NewState NewState
end; end;
@ -1243,6 +1264,9 @@ get_default_role(Affiliation, StateData) ->
end end
end. end.
is_visitor(Jid, StateData) ->
get_role(Jid, StateData) =:= visitor.
get_max_users(StateData) -> get_max_users(StateData) ->
MaxUsers = (StateData#state.config)#config.max_users, MaxUsers = (StateData#state.config)#config.max_users,
ServiceMaxUsers = get_service_max_users(StateData), ServiceMaxUsers = get_service_max_users(StateData),
@ -1347,6 +1371,13 @@ filter_presence({xmlelement, "presence", Attrs, Els}) ->
end, Els), end, Els),
{xmlelement, "presence", Attrs, FEls}. {xmlelement, "presence", Attrs, FEls}.
strip_status({xmlelement, "presence", Attrs, Els}) ->
FEls = lists:filter(
fun({xmlelement, "status", _Attrs1, _Els1}) ->
false;
(_) -> true
end, Els),
{xmlelement, "presence", Attrs, FEls}.
add_user_presence(JID, Presence, StateData) -> add_user_presence(JID, Presence, StateData) ->
LJID = jlib:jid_tolower(JID), LJID = jlib:jid_tolower(JID),
@ -1662,6 +1693,9 @@ extract_history([_ | Els], Type) ->
send_update_presence(JID, StateData) -> send_update_presence(JID, StateData) ->
send_update_presence(JID, "", StateData).
send_update_presence(JID, Reason, StateData) ->
LJID = jlib:jid_tolower(JID), LJID = jlib:jid_tolower(JID),
LJIDs = case LJID of LJIDs = case LJID of
{U, S, ""} -> {U, S, ""} ->
@ -1683,10 +1717,13 @@ send_update_presence(JID, StateData) ->
end end
end, end,
lists:foreach(fun(J) -> lists:foreach(fun(J) ->
send_new_presence(J, StateData) send_new_presence(J, Reason, StateData)
end, LJIDs). end, LJIDs).
send_new_presence(NJID, StateData) -> send_new_presence(NJID, StateData) ->
send_new_presence(NJID, "", StateData).
send_new_presence(NJID, Reason, StateData) ->
{ok, #user{jid = RealJID, {ok, #user{jid = RealJID,
nick = Nick, nick = Nick,
role = Role, role = Role,
@ -1708,6 +1745,13 @@ send_new_presence(NJID, StateData) ->
[{"affiliation", SAffiliation}, [{"affiliation", SAffiliation},
{"role", SRole}] {"role", SRole}]
end, end,
ItemEls = case Reason of
"" ->
[];
_ ->
[{xmlelement, "reason", [],
[{xmlcdata, Reason}]}]
end,
Status = case StateData#state.just_created of Status = case StateData#state.just_created of
true -> true ->
[{xmlelement, "status", [{"code", "201"}], []}]; [{xmlelement, "status", [{"code", "201"}], []}];
@ -1717,7 +1761,7 @@ send_new_presence(NJID, StateData) ->
Packet = append_subtags( Packet = append_subtags(
Presence, Presence,
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}], [{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
[{xmlelement, "item", ItemAttrs, []} | Status]}]), [{xmlelement, "item", ItemAttrs, ItemEls} | Status]}]),
ejabberd_router:route( ejabberd_router:route(
jlib:jid_replace_resource(StateData#state.jid, Nick), jlib:jid_replace_resource(StateData#state.jid, Nick),
Info#user.jid, Info#user.jid,
@ -2085,21 +2129,21 @@ process_admin_items_set(UJID, Items, Lang, StateData) ->
set_affiliation_and_reason( set_affiliation_and_reason(
JID, outcast, Reason, JID, outcast, Reason,
set_role(JID, none, SD)); set_role(JID, none, SD));
{JID, affiliation, A, _Reason} when {JID, affiliation, A, Reason} when
(A == admin) or (A == owner) -> (A == admin) or (A == owner) ->
SD1 = set_affiliation(JID, A, SD), SD1 = set_affiliation_and_reason(JID, A, Reason, SD),
SD2 = set_role(JID, moderator, SD1), SD2 = set_role(JID, moderator, SD1),
send_update_presence(JID, SD2), send_update_presence(JID, Reason, SD2),
SD2; SD2;
{JID, affiliation, member, _Reason} -> {JID, affiliation, member, Reason} ->
SD1 = set_affiliation( SD1 = set_affiliation_and_reason(
JID, member, SD), JID, member, Reason, SD),
SD2 = set_role(JID, participant, SD1), SD2 = set_role(JID, participant, SD1),
send_update_presence(JID, SD2), send_update_presence(JID, Reason, SD2),
SD2; SD2;
{JID, role, R, _Reason} -> {JID, role, Role, Reason} ->
SD1 = set_role(JID, R, SD), SD1 = set_role(JID, Role, SD),
catch send_new_presence(JID, SD1), catch send_new_presence(JID, Reason, SD1),
SD1; SD1;
{JID, affiliation, A, _Reason} -> {JID, affiliation, A, _Reason} ->
SD1 = set_affiliation(JID, A, SD), SD1 = set_affiliation(JID, A, SD),
@ -2187,11 +2231,13 @@ find_changed_items(UJID, UAffiliation, URole,
[StrAffiliation]), [StrAffiliation]),
{error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText1)}; {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText1)};
SAffiliation -> SAffiliation ->
ServiceAf = get_service_affiliation(JID, StateData),
CanChangeRA = CanChangeRA =
case can_change_ra( case can_change_ra(
UAffiliation, URole, UAffiliation, URole,
TAffiliation, TRole, TAffiliation, TRole,
affiliation, SAffiliation) of affiliation, SAffiliation,
ServiceAf) of
nothing -> nothing ->
nothing; nothing;
true -> true ->
@ -2242,11 +2288,13 @@ find_changed_items(UJID, UAffiliation, URole,
[StrRole]), [StrRole]),
{error, ?ERRT_BAD_REQUEST(Lang, ErrText1)}; {error, ?ERRT_BAD_REQUEST(Lang, ErrText1)};
SRole -> SRole ->
ServiceAf = get_service_affiliation(JID, StateData),
CanChangeRA = CanChangeRA =
case can_change_ra( case can_change_ra(
UAffiliation, URole, UAffiliation, URole,
TAffiliation, TRole, TAffiliation, TRole,
role, SRole) of role, SRole,
ServiceAf) of
nothing -> nothing ->
nothing; nothing;
true -> true ->
@ -2292,143 +2340,149 @@ find_changed_items(_UJID, _UAffiliation, _URole, _Items,
{error, ?ERR_BAD_REQUEST}. {error, ?ERR_BAD_REQUEST}.
can_change_ra(_FAffiliation, _FRole,
owner, _TRole,
affiliation, owner, owner) ->
%% A room owner tries to add as persistent owner a
%% participant that is already owner because he is MUC admin
true;
can_change_ra(_FAffiliation, _FRole, can_change_ra(_FAffiliation, _FRole,
TAffiliation, _TRole, TAffiliation, _TRole,
affiliation, Value) affiliation, Value, _ServiceAf)
when (TAffiliation == Value) -> when (TAffiliation == Value) ->
nothing; nothing;
can_change_ra(_FAffiliation, _FRole, can_change_ra(_FAffiliation, _FRole,
_TAffiliation, TRole, _TAffiliation, TRole,
role, Value) role, Value, _ServiceAf)
when (TRole == Value) -> when (TRole == Value) ->
nothing; nothing;
can_change_ra(FAffiliation, _FRole, can_change_ra(FAffiliation, _FRole,
outcast, _TRole, outcast, _TRole,
affiliation, none) affiliation, none, _ServiceAf)
when (FAffiliation == owner) or (FAffiliation == admin) -> when (FAffiliation == owner) or (FAffiliation == admin) ->
true; true;
can_change_ra(FAffiliation, _FRole, can_change_ra(FAffiliation, _FRole,
outcast, _TRole, outcast, _TRole,
affiliation, member) affiliation, member, _ServiceAf)
when (FAffiliation == owner) or (FAffiliation == admin) -> when (FAffiliation == owner) or (FAffiliation == admin) ->
true; true;
can_change_ra(owner, _FRole, can_change_ra(owner, _FRole,
outcast, _TRole, outcast, _TRole,
affiliation, admin) -> affiliation, admin, _ServiceAf) ->
true; true;
can_change_ra(owner, _FRole, can_change_ra(owner, _FRole,
outcast, _TRole, outcast, _TRole,
affiliation, owner) -> affiliation, owner, _ServiceAf) ->
true; true;
can_change_ra(FAffiliation, _FRole, can_change_ra(FAffiliation, _FRole,
none, _TRole, none, _TRole,
affiliation, outcast) affiliation, outcast, _ServiceAf)
when (FAffiliation == owner) or (FAffiliation == admin) -> when (FAffiliation == owner) or (FAffiliation == admin) ->
true; true;
can_change_ra(FAffiliation, _FRole, can_change_ra(FAffiliation, _FRole,
none, _TRole, none, _TRole,
affiliation, member) affiliation, member, _ServiceAf)
when (FAffiliation == owner) or (FAffiliation == admin) -> when (FAffiliation == owner) or (FAffiliation == admin) ->
true; true;
can_change_ra(owner, _FRole, can_change_ra(owner, _FRole,
none, _TRole, none, _TRole,
affiliation, admin) -> affiliation, admin, _ServiceAf) ->
true; true;
can_change_ra(owner, _FRole, can_change_ra(owner, _FRole,
none, _TRole, none, _TRole,
affiliation, owner) -> affiliation, owner, _ServiceAf) ->
true; true;
can_change_ra(FAffiliation, _FRole, can_change_ra(FAffiliation, _FRole,
member, _TRole, member, _TRole,
affiliation, outcast) affiliation, outcast, _ServiceAf)
when (FAffiliation == owner) or (FAffiliation == admin) -> when (FAffiliation == owner) or (FAffiliation == admin) ->
true; true;
can_change_ra(FAffiliation, _FRole, can_change_ra(FAffiliation, _FRole,
member, _TRole, member, _TRole,
affiliation, none) affiliation, none, _ServiceAf)
when (FAffiliation == owner) or (FAffiliation == admin) -> when (FAffiliation == owner) or (FAffiliation == admin) ->
true; true;
can_change_ra(owner, _FRole, can_change_ra(owner, _FRole,
member, _TRole, member, _TRole,
affiliation, admin) -> affiliation, admin, _ServiceAf) ->
true; true;
can_change_ra(owner, _FRole, can_change_ra(owner, _FRole,
member, _TRole, member, _TRole,
affiliation, owner) -> affiliation, owner, _ServiceAf) ->
true; true;
can_change_ra(owner, _FRole, can_change_ra(owner, _FRole,
admin, _TRole, admin, _TRole,
affiliation, _Affiliation) -> affiliation, _Affiliation, _ServiceAf) ->
true; true;
can_change_ra(owner, _FRole, can_change_ra(owner, _FRole,
owner, _TRole, owner, _TRole,
affiliation, _Affiliation) -> affiliation, _Affiliation, _ServiceAf) ->
check_owner; check_owner;
can_change_ra(_FAffiliation, _FRole, can_change_ra(_FAffiliation, _FRole,
_TAffiliation, _TRole, _TAffiliation, _TRole,
affiliation, _Value) -> affiliation, _Value, _ServiceAf) ->
false; false;
can_change_ra(_FAffiliation, moderator, can_change_ra(_FAffiliation, moderator,
_TAffiliation, visitor, _TAffiliation, visitor,
role, none) -> role, none, _ServiceAf) ->
true; true;
can_change_ra(_FAffiliation, moderator, can_change_ra(_FAffiliation, moderator,
_TAffiliation, visitor, _TAffiliation, visitor,
role, participant) -> role, participant, _ServiceAf) ->
true; true;
can_change_ra(FAffiliation, _FRole, can_change_ra(FAffiliation, _FRole,
_TAffiliation, visitor, _TAffiliation, visitor,
role, moderator) role, moderator, _ServiceAf)
when (FAffiliation == owner) or (FAffiliation == admin) -> when (FAffiliation == owner) or (FAffiliation == admin) ->
true; true;
can_change_ra(_FAffiliation, moderator, can_change_ra(_FAffiliation, moderator,
_TAffiliation, participant, _TAffiliation, participant,
role, none) -> role, none, _ServiceAf) ->
true; true;
can_change_ra(_FAffiliation, moderator, can_change_ra(_FAffiliation, moderator,
_TAffiliation, participant, _TAffiliation, participant,
role, visitor) -> role, visitor, _ServiceAf) ->
true; true;
can_change_ra(FAffiliation, _FRole, can_change_ra(FAffiliation, _FRole,
_TAffiliation, participant, _TAffiliation, participant,
role, moderator) role, moderator, _ServiceAf)
when (FAffiliation == owner) or (FAffiliation == admin) -> when (FAffiliation == owner) or (FAffiliation == admin) ->
true; true;
can_change_ra(_FAffiliation, _FRole, can_change_ra(_FAffiliation, _FRole,
owner, moderator, owner, moderator,
role, visitor) -> role, visitor, _ServiceAf) ->
false; false;
can_change_ra(owner, _FRole, can_change_ra(owner, _FRole,
_TAffiliation, moderator, _TAffiliation, moderator,
role, visitor) -> role, visitor, _ServiceAf) ->
true; true;
can_change_ra(_FAffiliation, _FRole, can_change_ra(_FAffiliation, _FRole,
admin, moderator, admin, moderator,
role, visitor) -> role, visitor, _ServiceAf) ->
false; false;
can_change_ra(admin, _FRole, can_change_ra(admin, _FRole,
_TAffiliation, moderator, _TAffiliation, moderator,
role, visitor) -> role, visitor, _ServiceAf) ->
true; true;
can_change_ra(_FAffiliation, _FRole, can_change_ra(_FAffiliation, _FRole,
owner, moderator, owner, moderator,
role, participant) -> role, participant, _ServiceAf) ->
false; false;
can_change_ra(owner, _FRole, can_change_ra(owner, _FRole,
_TAffiliation, moderator, _TAffiliation, moderator,
role, participant) -> role, participant, _ServiceAf) ->
true; true;
can_change_ra(_FAffiliation, _FRole, can_change_ra(_FAffiliation, _FRole,
admin, moderator, admin, moderator,
role, participant) -> role, participant, _ServiceAf) ->
false; false;
can_change_ra(admin, _FRole, can_change_ra(admin, _FRole,
_TAffiliation, moderator, _TAffiliation, moderator,
role, participant) -> role, participant, _ServiceAf) ->
true; true;
can_change_ra(_FAffiliation, _FRole, can_change_ra(_FAffiliation, _FRole,
_TAffiliation, _TRole, _TAffiliation, _TRole,
role, _Value) -> role, _Value, _ServiceAf) ->
false. false.
@ -2700,7 +2754,13 @@ get_config(Lang, StateData, From) ->
Config#config.allow_query_users), Config#config.allow_query_users),
?BOOLXFIELD("Allow users to send invites", ?BOOLXFIELD("Allow users to send invites",
"muc#roomconfig_allowinvites", "muc#roomconfig_allowinvites",
Config#config.allow_user_invites) Config#config.allow_user_invites),
?BOOLXFIELD("Allow visitors to send status text in presence updates",
"muc#roomconfig_allowvisitorstatus",
Config#config.allow_visitor_status),
?BOOLXFIELD("Allow visitors to change nickname",
"muc#roomconfig_allowvisitornickchange",
Config#config.allow_visitor_nickchange)
] ++ ] ++
case mod_muc_log:check_access_log( case mod_muc_log:check_access_log(
StateData#state.server_host, From) of StateData#state.server_host, From) of
@ -2773,6 +2833,10 @@ set_xoption([{"allow_query_users", [Val]} | Opts], Config) ->
?SET_BOOL_XOPT(allow_query_users, Val); ?SET_BOOL_XOPT(allow_query_users, Val);
set_xoption([{"allow_private_messages", [Val]} | Opts], Config) -> set_xoption([{"allow_private_messages", [Val]} | Opts], Config) ->
?SET_BOOL_XOPT(allow_private_messages, Val); ?SET_BOOL_XOPT(allow_private_messages, Val);
set_xoption([{"muc#roomconfig_allowvisitorstatus", [Val]} | Opts], Config) ->
?SET_BOOL_XOPT(allow_visitor_status, Val);
set_xoption([{"muc#roomconfig_allowvisitornickchange", [Val]} | Opts], Config) ->
?SET_BOOL_XOPT(allow_visitor_nickchange, Val);
set_xoption([{"muc#roomconfig_publicroom", [Val]} | Opts], Config) -> set_xoption([{"muc#roomconfig_publicroom", [Val]} | Opts], Config) ->
?SET_BOOL_XOPT(public, Val); ?SET_BOOL_XOPT(public, Val);
set_xoption([{"public_list", [Val]} | Opts], Config) -> set_xoption([{"public_list", [Val]} | Opts], Config) ->
@ -2866,6 +2930,8 @@ set_opts([{Opt, Val} | Opts], StateData) ->
allow_change_subj -> StateData#state{config = (StateData#state.config)#config{allow_change_subj = Val}}; allow_change_subj -> StateData#state{config = (StateData#state.config)#config{allow_change_subj = Val}};
allow_query_users -> StateData#state{config = (StateData#state.config)#config{allow_query_users = Val}}; allow_query_users -> StateData#state{config = (StateData#state.config)#config{allow_query_users = Val}};
allow_private_messages -> StateData#state{config = (StateData#state.config)#config{allow_private_messages = Val}}; allow_private_messages -> StateData#state{config = (StateData#state.config)#config{allow_private_messages = Val}};
allow_visitor_nickchange -> StateData#state{config = (StateData#state.config)#config{allow_visitor_nickchange = Val}};
allow_visitor_status -> StateData#state{config = (StateData#state.config)#config{allow_visitor_status = Val}};
public -> StateData#state{config = (StateData#state.config)#config{public = Val}}; public -> StateData#state{config = (StateData#state.config)#config{public = Val}};
public_list -> StateData#state{config = (StateData#state.config)#config{public_list = Val}}; public_list -> StateData#state{config = (StateData#state.config)#config{public_list = Val}};
persistent -> StateData#state{config = (StateData#state.config)#config{persistent = Val}}; persistent -> StateData#state{config = (StateData#state.config)#config{persistent = Val}};
@ -2906,6 +2972,8 @@ make_opts(StateData) ->
?MAKE_CONFIG_OPT(allow_change_subj), ?MAKE_CONFIG_OPT(allow_change_subj),
?MAKE_CONFIG_OPT(allow_query_users), ?MAKE_CONFIG_OPT(allow_query_users),
?MAKE_CONFIG_OPT(allow_private_messages), ?MAKE_CONFIG_OPT(allow_private_messages),
?MAKE_CONFIG_OPT(allow_visitor_status),
?MAKE_CONFIG_OPT(allow_visitor_nickchange),
?MAKE_CONFIG_OPT(public), ?MAKE_CONFIG_OPT(public),
?MAKE_CONFIG_OPT(public_list), ?MAKE_CONFIG_OPT(public_list),
?MAKE_CONFIG_OPT(persistent), ?MAKE_CONFIG_OPT(persistent),

View File

@ -5,7 +5,7 @@
%%% Created : 5 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 5 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 5 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 5 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -118,6 +118,8 @@ loop(Host, MaxOfflineMsgs) ->
case catch odbc_queries:add_spool(Host, Query) of case catch odbc_queries:add_spool(Host, Query) of
{'EXIT', Reason} -> {'EXIT', Reason} ->
?ERROR_MSG("~p~n", [Reason]); ?ERROR_MSG("~p~n", [Reason]);
{error, Reason} ->
?ERROR_MSG("~p~n", [Reason]);
_ -> _ ->
ok ok
end end

View File

@ -5,7 +5,7 @@
%%% Created : 21 Jul 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 21 Jul 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -1,6 +1,6 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 5 Oct 2006 by Alexey Shchepin <alexey@process-one.net> %%% Created : 5 Oct 2006 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -96,16 +96,14 @@ process_iq_get(_, From, _To, #iq{sub_el = SubEl},
process_lists_get(LUser, LServer, Active) -> process_lists_get(LUser, LServer, Active) ->
Default = case catch sql_get_default_privacy_list(LUser, LServer) of Default = case catch sql_get_default_privacy_list(LUser, LServer) of
{'EXIT', _Reason} ->
none;
{selected, ["name"], []} -> {selected, ["name"], []} ->
none; none;
{selected, ["name"], [{DefName}]} -> {selected, ["name"], [{DefName}]} ->
DefName DefName;
_ ->
none
end, end,
case catch sql_get_privacy_list_names(LUser, LServer) of case catch sql_get_privacy_list_names(LUser, LServer) of
{'EXIT', _Reason2} ->
{error, ?ERR_INTERNAL_SERVER_ERROR};
{selected, ["name"], []} -> {selected, ["name"], []} ->
{result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]}; {result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]};
{selected, ["name"], Names} -> {selected, ["name"], Names} ->
@ -132,19 +130,17 @@ process_lists_get(LUser, LServer, Active) ->
end, end,
{result, {result,
[{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}],
ADItems}]} ADItems}]};
_ ->
{error, ?ERR_INTERNAL_SERVER_ERROR}
end. end.
process_list_get(LUser, LServer, {value, Name}) -> process_list_get(LUser, LServer, {value, Name}) ->
case catch sql_get_privacy_list_id(LUser, LServer, Name) of case catch sql_get_privacy_list_id(LUser, LServer, Name) of
{'EXIT', _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR};
{selected, ["id"], []} -> {selected, ["id"], []} ->
{error, ?ERR_ITEM_NOT_FOUND}; {error, ?ERR_ITEM_NOT_FOUND};
{selected, ["id"], [{ID}]} -> {selected, ["id"], [{ID}]} ->
case catch sql_get_privacy_list_data_by_id(ID, LServer) of case catch sql_get_privacy_list_data_by_id(ID, LServer) of
{'EXIT', _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR};
{selected, ["t", "value", "action", "ord", "match_all", {selected, ["t", "value", "action", "ord", "match_all",
"match_iq", "match_message", "match_iq", "match_message",
"match_presence_in", "match_presence_out"], "match_presence_in", "match_presence_out"],
@ -154,8 +150,12 @@ process_list_get(LUser, LServer, {value, Name}) ->
{result, {result,
[{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}],
[{xmlelement, "list", [{xmlelement, "list",
[{"name", Name}], LItems}]}]} [{"name", Name}], LItems}]}]};
end _ ->
{error, ?ERR_INTERNAL_SERVER_ERROR}
end;
_ ->
{error, ?ERR_INTERNAL_SERVER_ERROR}
end; end;
process_list_get(_LUser, _LServer, false) -> process_list_get(_LUser, _LServer, false) ->
@ -294,6 +294,8 @@ process_default_set(LUser, LServer, false) ->
case catch sql_unset_default_privacy_list(LUser, LServer) of case catch sql_unset_default_privacy_list(LUser, LServer) of
{'EXIT', _Reason} -> {'EXIT', _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR}; {error, ?ERR_INTERNAL_SERVER_ERROR};
{error, _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR};
_ -> _ ->
{result, []} {result, []}
end. end.
@ -301,21 +303,21 @@ process_default_set(LUser, LServer, false) ->
process_active_set(LUser, LServer, {value, Name}) -> process_active_set(LUser, LServer, {value, Name}) ->
case catch sql_get_privacy_list_id(LUser, LServer, Name) of case catch sql_get_privacy_list_id(LUser, LServer, Name) of
{'EXIT', _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR};
{selected, ["id"], []} -> {selected, ["id"], []} ->
{error, ?ERR_ITEM_NOT_FOUND}; {error, ?ERR_ITEM_NOT_FOUND};
{selected, ["id"], [{ID}]} -> {selected, ["id"], [{ID}]} ->
case catch sql_get_privacy_list_data_by_id(ID, LServer) of case catch sql_get_privacy_list_data_by_id(ID, LServer) of
{'EXIT', _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR};
{selected, ["t", "value", "action", "ord", "match_all", {selected, ["t", "value", "action", "ord", "match_all",
"match_iq", "match_message", "match_iq", "match_message",
"match_presence_in", "match_presence_out"], "match_presence_in", "match_presence_out"],
RItems} -> RItems} ->
Items = lists:map(fun raw_to_item/1, RItems), Items = lists:map(fun raw_to_item/1, RItems),
{result, [], #userlist{name = Name, list = Items}} {result, [], #userlist{name = Name, list = Items}};
end _ ->
{error, ?ERR_INTERNAL_SERVER_ERROR}
end;
_ ->
{error, ?ERR_INTERNAL_SERVER_ERROR}
end; end;
process_active_set(_LUser, _LServer, false) -> process_active_set(_LUser, _LServer, false) ->
@ -517,21 +519,21 @@ get_user_list(_, User, Server) ->
LServer = jlib:nameprep(Server), LServer = jlib:nameprep(Server),
case catch sql_get_default_privacy_list(LUser, LServer) of case catch sql_get_default_privacy_list(LUser, LServer) of
{'EXIT', _Reason} ->
#userlist{};
{selected, ["name"], []} -> {selected, ["name"], []} ->
#userlist{}; #userlist{};
{selected, ["name"], [{Default}]} -> {selected, ["name"], [{Default}]} ->
case catch sql_get_privacy_list_data(LUser, LServer, Default) of case catch sql_get_privacy_list_data(LUser, LServer, Default) of
{'EXIT', _Reason} ->
#userlist{};
{selected, ["t", "value", "action", "ord", "match_all", {selected, ["t", "value", "action", "ord", "match_all",
"match_iq", "match_message", "match_iq", "match_message",
"match_presence_in", "match_presence_out"], "match_presence_in", "match_presence_out"],
RItems} -> RItems} ->
Items = lists:map(fun raw_to_item/1, RItems), Items = lists:map(fun raw_to_item/1, RItems),
#userlist{name = Default, list = Items} #userlist{name = Default, list = Items};
end _ ->
#userlist{}
end;
_ ->
#userlist{}
end. end.

View File

@ -5,7 +5,7 @@
%%% Created : 16 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% Created : 16 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 5 Oct 2006 by Alexey Shchepin <alexey@process-one.net> %%% Created : 5 Oct 2006 by Alexey Shchepin <alexey@process-one.net>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -2,7 +2,7 @@
%%% RFC 1928 constants. %%% RFC 1928 constants.
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -35,7 +35,7 @@
unpack_request/1, unpack_request/1,
make_init_reply/1, make_init_reply/1,
make_auth_reply/1, make_auth_reply/1,
make_reply/0, make_reply/1,
make_error_reply/1, make_error_reply/1,
make_error_reply/2 make_error_reply/2
]). ]).
@ -73,12 +73,8 @@ make_init_reply(Method) ->
make_auth_reply(true) -> [1, ?SUCCESS]; make_auth_reply(true) -> [1, ?SUCCESS];
make_auth_reply(false) -> [1, ?ERR_NOT_ALLOWED]. make_auth_reply(false) -> [1, ?ERR_NOT_ALLOWED].
%% WARNING: According to SOCKS5 RFC, this reply is _incorrect_, but make_reply(#s5_request{rsv = RSV, sha1 = SHA1}) ->
%% Psi writes junk to the beginning of the file on correct reply. [?VERSION_5, ?SUCCESS, RSV, ?ATYP_DOMAINNAME, length(SHA1), SHA1, 0,0].
%% I'm not sure, but there may be an issue with other clients.
%% Needs more testing.
make_reply() ->
[?VERSION_5, ?SUCCESS, 0, 0, 0, 0].
make_error_reply(Request) -> make_error_reply(Request) ->
make_error_reply(Request, ?ERR_NOT_ALLOWED). make_error_reply(Request, ?ERR_NOT_ALLOWED).

View File

@ -5,7 +5,7 @@
%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -5,7 +5,7 @@
%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%% %%%
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as

View File

@ -4,7 +4,7 @@
%%% Purpose : Bytestream process. %%% Purpose : Bytestream process.
%%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru>
%%% %%%
%%% ejabberd, Copyright (C) 2002-2008 Process-one %%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%% %%%
%%% This program is free software; you can redistribute it and/or %%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as %%% modify it under the terms of the GNU General Public License as
@ -172,7 +172,7 @@ wait_for_request(Packet, #state{socket=Socket} = StateData) ->
case catch mod_proxy65_sm:register_stream(SHA1) of case catch mod_proxy65_sm:register_stream(SHA1) of
{atomic, ok} -> {atomic, ok} ->
inet:setopts(Socket, [{active, false}]), inet:setopts(Socket, [{active, false}]),
gen_tcp:send(Socket, mod_proxy65_lib:make_reply()), gen_tcp:send(Socket, mod_proxy65_lib:make_reply(Request)),
{next_state, wait_for_activation, StateData#state{sha1=SHA1}}; {next_state, wait_for_activation, StateData#state{sha1=SHA1}};
_ -> _ ->
Err = mod_proxy65_lib:make_error_reply(Request), Err = mod_proxy65_lib:make_error_reply(Request),

View File

@ -10,13 +10,13 @@
%%% the License for the specific language governing rights and limitations %%% the License for the specific language governing rights and limitations
%%% under the License. %%% under the License.
%%% %%%
%%% The Initial Developer of the Original Code is Process-one. %%% The Initial Developer of the Original Code is ProcessOne.
%%% Portions created by Process-one are Copyright 2006-2008, Process-one %%% Portions created by ProcessOne are Copyright 2006-2008, ProcessOne
%%% All Rights Reserved.'' %%% All Rights Reserved.''
%%% This software is copyright 2006-2008, Process-one. %%% This software is copyright 2006-2008, ProcessOne.
%%% %%%
%%% %%%
%%% @copyright 2006-2008 Process-one %%% @copyright 2006-2008 ProcessOne
%%% @author Christophe Romain <christophe.romain@process-one.net> %%% @author Christophe Romain <christophe.romain@process-one.net>
%%% [http://www.process-one.net/] %%% [http://www.process-one.net/]
%%% @version {@vsn}, {@date} {@time} %%% @version {@vsn}, {@date} {@time}

Some files were not shown because too many files have changed in this diff Show More