Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e63b4afffd |
@@ -1,38 +0,0 @@
|
||||
#
|
||||
# You can add personal rules in your file .git/info/exclude
|
||||
*.swp
|
||||
*~
|
||||
/contrib/extract_translations/extract_translations.beam
|
||||
/doc/*.aux
|
||||
/doc/*.haux
|
||||
/doc/*.html
|
||||
/doc/*.htoc
|
||||
/doc/*.idx
|
||||
/doc/*.ilg
|
||||
/doc/*.ind
|
||||
/doc/*.log
|
||||
/doc/*.out
|
||||
/doc/*.pdf
|
||||
/doc/*.toc
|
||||
/doc/contributed_modules.tex
|
||||
/doc/version.tex
|
||||
/src/*.beam
|
||||
/src/*.so
|
||||
/src/*.so.dSYM
|
||||
/src/*/*.beam
|
||||
/src/*/Makefile
|
||||
/src/Makefile
|
||||
/src/XmppAddr.asn1db
|
||||
/src/XmppAddr.erl
|
||||
/src/XmppAddr.hrl
|
||||
/src/aclocal.m4
|
||||
/src/autom4te.cache
|
||||
/src/config.log
|
||||
/src/config.status
|
||||
/src/ejabberd.init
|
||||
/src/ejabberdctl.example
|
||||
/src/eldap/ELDAPv3.asn1db
|
||||
/src/eldap/ELDAPv3.erl
|
||||
/src/eldap/ELDAPv3.hrl
|
||||
/src/eldap/eldap_filter_yecc.erl
|
||||
/src/epam
|
||||
@@ -1,54 +0,0 @@
|
||||
ejabberd - High-Performance Enterprise Instant Messaging Server
|
||||
|
||||
Quickstart guide
|
||||
|
||||
|
||||
0. Requirements
|
||||
|
||||
To compile ejabberd you need:
|
||||
- GNU Make
|
||||
- GCC
|
||||
- Libexpat 1.95 or higher
|
||||
- Erlang/OTP R10B-9 or higher. Recommended: R13B04 and R14B04.
|
||||
Avoid R14A and R14B.
|
||||
- OpenSSL 0.9.8 or higher, for STARTTLS, SASL and SSL encryption.
|
||||
- Zlib 1.2.3 or higher, for Stream Compression support
|
||||
(XEP-0138). Optional.
|
||||
- Erlang mysql library. Optional. MySQL authentication/storage.
|
||||
- Erlang pgsql library. Optional. PostgreSQL authentication/storage.
|
||||
- PAM library. Optional. For Pluggable Authentication Modules (PAM).
|
||||
- GNU Iconv 1.8 or higher, for the IRC Transport
|
||||
(mod_irc). Optional. Not needed on systems with GNU Libc.
|
||||
- ImageMagick's Convert program. Optional. For CAPTCHA challenges.
|
||||
- exmpp 0.9.6 or higher. Optional. For import/export XEP-0227 files.
|
||||
|
||||
|
||||
1. Compile and install on *nix systems
|
||||
|
||||
To compile ejabberd, go to the directory src/ and execute the commands:
|
||||
./configure
|
||||
make
|
||||
|
||||
To install ejabberd, run this command with system administrator rights
|
||||
(root user):
|
||||
|
||||
sudo make install
|
||||
|
||||
These commands will:
|
||||
- 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/
|
||||
|
||||
|
||||
2. Start ejabberd
|
||||
|
||||
You can use the ejabberdctl command line administration script to
|
||||
start and stop ejabberd. For example:
|
||||
ejabberdctl start
|
||||
|
||||
|
||||
For detailed information please refer to the
|
||||
ejabberd Installation and Operation Guide
|
||||
@@ -0,0 +1,21 @@
|
||||
admin tool
|
||||
mod_muc logging
|
||||
|
||||
admin interface
|
||||
users management
|
||||
statistics about each user
|
||||
statistics about each connection
|
||||
node management
|
||||
node restart/shutdown
|
||||
statistics about memory usage
|
||||
|
||||
S2S:
|
||||
rewrite S2S key validation
|
||||
check "id" attributes in db:verify packets
|
||||
|
||||
more correctly work with SRV DNS records (priority, weight, etc...)
|
||||
TLS
|
||||
make roster set to work in one transaction
|
||||
add traffic shapers to c2s connection before authentification
|
||||
more traffic shapers
|
||||
SNMP
|
||||
@@ -1,5 +0,0 @@
|
||||
% List of ejabberd-modules to add for ejabberd packaging (source archive and installer)
|
||||
%
|
||||
% HTTP-binding:
|
||||
%https://svn.process-one.net/ejabberd-modules/http_bind/trunk
|
||||
%https://svn.process-one.net/ejabberd-modules/mod_http_fileserver/trunk
|
||||
@@ -1,21 +0,0 @@
|
||||
extract_translations - auxiliary tool that extracts lines to be translated
|
||||
from ejabberd source tree.
|
||||
|
||||
Building:
|
||||
erlc extract_translations.erl
|
||||
|
||||
Invoking 1:
|
||||
erl -noinput -s extract_translations -extra dirname message_file
|
||||
|
||||
where dirname is the directory "src" in ejabberd's source tree root,
|
||||
message_file is a file with translated messages (src/msgs/*.msg).
|
||||
|
||||
Result is a list of messages from source files which aren't contained in
|
||||
message file.
|
||||
|
||||
Invoking 2:
|
||||
erl -noinput -s extract_translations -extra -unused dirname message_file
|
||||
|
||||
Result is a list of messages from message file which aren't in source
|
||||
files anymore.
|
||||
|
||||
@@ -1,294 +0,0 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : extract_translations.erl
|
||||
%%% Author : Sergei Golovan <sgolovan@nes.ru>
|
||||
%%% Purpose : Auxiliary tool for interface/messages translators
|
||||
%%% Created : 23 Apr 2005 by Sergei Golovan <sgolovan@nes.ru>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(extract_translations).
|
||||
-author('sgolovan@nes.ru').
|
||||
|
||||
-export([start/0]).
|
||||
|
||||
-define(STATUS_SUCCESS, 0).
|
||||
-define(STATUS_ERROR, 1).
|
||||
-define(STATUS_USAGE, 2).
|
||||
|
||||
-include_lib("kernel/include/file.hrl").
|
||||
|
||||
|
||||
start() ->
|
||||
ets:new(translations, [named_table, public]),
|
||||
ets:new(translations_obsolete, [named_table, public]),
|
||||
ets:new(files, [named_table, public]),
|
||||
ets:new(vars, [named_table, public]),
|
||||
case init:get_plain_arguments() of
|
||||
["-srcmsg2po", Dir, File] ->
|
||||
print_po_header(File),
|
||||
Status = process(Dir, File, srcmsg2po),
|
||||
halt(Status);
|
||||
["-unused", Dir, File] ->
|
||||
Status = process(Dir, File, unused),
|
||||
halt(Status);
|
||||
[Dir, File] ->
|
||||
Status = process(Dir, File, used),
|
||||
halt(Status);
|
||||
_ ->
|
||||
print_usage(),
|
||||
halt(?STATUS_USAGE)
|
||||
end.
|
||||
|
||||
|
||||
process(Dir, File, Used) ->
|
||||
case load_file(File) of
|
||||
{error, Reason} ->
|
||||
io:format("~s: ~s~n", [File, file:format_error(Reason)]),
|
||||
?STATUS_ERROR;
|
||||
_ ->
|
||||
FileList = find_src_files(Dir),
|
||||
lists:foreach(
|
||||
fun(F) ->
|
||||
parse_file(Dir, F, Used)
|
||||
end, FileList),
|
||||
case Used of
|
||||
unused ->
|
||||
ets:foldl(fun({Key, _}, _) ->
|
||||
io:format("~p~n", [Key])
|
||||
end, ok, translations);
|
||||
srcmsg2po ->
|
||||
ets:foldl(fun({Key, Trans}, _) ->
|
||||
print_translation_obsolete(Key, Trans)
|
||||
end, ok, translations_obsolete);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
?STATUS_SUCCESS
|
||||
end.
|
||||
|
||||
parse_file(Dir, File, Used) ->
|
||||
ets:delete_all_objects(vars),
|
||||
case epp:parse_file(File, [Dir, filename:dirname(File) | code:get_path()], []) of
|
||||
{ok, Forms} ->
|
||||
lists:foreach(
|
||||
fun(F) ->
|
||||
parse_form(Dir, File, F, Used)
|
||||
end, Forms);
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
parse_form(Dir, File, Form, Used) ->
|
||||
case Form of
|
||||
%%{undefined, Something} ->
|
||||
%% io:format("Undefined: ~p~n", [Something]);
|
||||
{call,
|
||||
_,
|
||||
{remote, _, {atom, _, translate}, {atom, _, translate}},
|
||||
[_, {string, Line, Str}]
|
||||
} ->
|
||||
process_string(Dir, File, Line, Str, Used);
|
||||
{call,
|
||||
_,
|
||||
{remote, _, {atom, _, translate}, {atom, _, translate}},
|
||||
[_, {var, _, Name}]
|
||||
} ->
|
||||
case ets:lookup(vars, Name) of
|
||||
[{_Name, Value, Line}] ->
|
||||
process_string(Dir, File, Line, Value, Used);
|
||||
_ ->
|
||||
ok
|
||||
end;
|
||||
{match,
|
||||
_,
|
||||
{var, _, Name},
|
||||
{string, Line, Value}
|
||||
} ->
|
||||
ets:insert(vars, {Name, Value, Line});
|
||||
L when is_list(L) ->
|
||||
lists:foreach(
|
||||
fun(F) ->
|
||||
parse_form(Dir, File, F, Used)
|
||||
end, L);
|
||||
T when is_tuple(T) ->
|
||||
lists:foreach(
|
||||
fun(F) ->
|
||||
parse_form(Dir, File, F, Used)
|
||||
end, tuple_to_list(T));
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
process_string(_Dir, _File, _Line, "", _Used) ->
|
||||
ok;
|
||||
|
||||
process_string(_Dir, File, Line, Str, Used) ->
|
||||
case {ets:lookup(translations, Str), Used} of
|
||||
{[{_Key, _Trans}], unused} ->
|
||||
ets:delete(translations, Str);
|
||||
{[{_Key, _Trans}], used} ->
|
||||
ok;
|
||||
{[{_Key, Trans}], srcmsg2po} ->
|
||||
ets:delete(translations_obsolete, Str),
|
||||
print_translation(File, Line, Str, Trans);
|
||||
{_, used} ->
|
||||
case ets:lookup(files, File) of
|
||||
[{_}] ->
|
||||
ok;
|
||||
_ ->
|
||||
io:format("~n% ~s~n", [File]),
|
||||
ets:insert(files, {File})
|
||||
end,
|
||||
case Str of
|
||||
[] -> ok;
|
||||
_ -> io:format("{~p, \"\"}.~n", [Str])
|
||||
end,
|
||||
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
|
||||
end.
|
||||
|
||||
load_file(File) ->
|
||||
case file:consult(File) of
|
||||
{ok, Terms} ->
|
||||
lists:foreach(
|
||||
fun({Orig, Trans}) ->
|
||||
case Trans of
|
||||
"" ->
|
||||
ok;
|
||||
_ ->
|
||||
ets:insert(translations, {Orig, Trans}),
|
||||
ets:insert(translations_obsolete, {Orig, Trans})
|
||||
end
|
||||
end, Terms);
|
||||
Err ->
|
||||
Err
|
||||
end.
|
||||
|
||||
find_src_files(Dir) ->
|
||||
case file:list_dir(Dir) of
|
||||
{ok, FileList} ->
|
||||
recurse_filelist(
|
||||
lists:map(
|
||||
fun(F) ->
|
||||
filename:join(Dir, F)
|
||||
end, FileList));
|
||||
_ ->
|
||||
[]
|
||||
end.
|
||||
|
||||
recurse_filelist(FileList) ->
|
||||
recurse_filelist(FileList, []).
|
||||
|
||||
recurse_filelist([], Acc) ->
|
||||
lists:reverse(Acc);
|
||||
|
||||
recurse_filelist([H | T], Acc) ->
|
||||
case file:read_file_info(H) of
|
||||
{ok, #file_info{type = directory}} ->
|
||||
recurse_filelist(T, lists:reverse(find_src_files(H)) ++ Acc);
|
||||
{ok, #file_info{type = regular}} ->
|
||||
case string:substr(H, string:len(H) - 3) of
|
||||
".erl" ->
|
||||
recurse_filelist(T, [H | Acc]);
|
||||
".hrl" ->
|
||||
recurse_filelist(T, [H | Acc]);
|
||||
_ ->
|
||||
recurse_filelist(T, Acc)
|
||||
end;
|
||||
_ ->
|
||||
recurse_filelist(T, Acc)
|
||||
end.
|
||||
|
||||
|
||||
print_usage() ->
|
||||
io:format(
|
||||
"Usage: extract_translations [-unused] dir file~n"
|
||||
"~n"
|
||||
"Example:~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) ->
|
||||
StrQ = ejabberd_regexp:greplace(Str, "\\\"", "\\\\\""),
|
||||
StrTQ = ejabberd_regexp:greplace(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,
|
||||
StrQ = ejabberd_regexp:greplace(Str, "\\\"", "\\\\\""),
|
||||
StrTQ = ejabberd_regexp:greplace(StrT, "\\\"", "\\\\\""),
|
||||
io:format("#: ~s:~p~n#~~ msgid \"~s\"~n#~~ msgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
|
||||
|
||||
@@ -1,363 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Frontend for ejabberd's extract_translations.erl
|
||||
# by Badlop
|
||||
|
||||
# How to create template files for a new language:
|
||||
# NEWLANG=zh
|
||||
# cp msgs/ejabberd.pot msgs/$NEWLANG.po
|
||||
# echo \{\"\",\"\"\}. > msgs/$NEWLANG.msg
|
||||
# ../../extract_translations/prepare-translation.sh -updateall
|
||||
|
||||
prepare_dirs ()
|
||||
{
|
||||
# Where is Erlang binary
|
||||
ERL=`which erl`
|
||||
|
||||
EJA_SRC_DIR=$EJA_DIR/src/
|
||||
EJA_MSGS_DIR=$EJA_SRC_DIR/msgs/
|
||||
EXTRACT_DIR=$EJA_DIR/contrib/extract_translations/
|
||||
EXTRACT_ERL=$EXTRACT_DIR/extract_translations.erl
|
||||
EXTRACT_BEAM=$EXTRACT_DIR/extract_translations.beam
|
||||
|
||||
SRC_DIR=$RUN_DIR/src
|
||||
MSGS_DIR=$SRC_DIR/msgs
|
||||
|
||||
if !([[ -n $EJA_DIR ]])
|
||||
then
|
||||
echo "ejabberd dir does not exist: $EJA_DIR"
|
||||
fi
|
||||
|
||||
if !([[ -x $EXTRACT_BEAM ]])
|
||||
then
|
||||
sh -c "cd $EXTRACT_DIR; $ERL -compile $EXTRACT_ERL"
|
||||
fi
|
||||
}
|
||||
|
||||
extract_lang ()
|
||||
{
|
||||
MSGS_FILE=$1
|
||||
MSGS_FILE2=$MSGS_FILE.translate
|
||||
MSGS_PATH=$MSGS_DIR/$MSGS_FILE
|
||||
MSGS_PATH2=$MSGS_DIR/$MSGS_FILE2
|
||||
|
||||
echo -n "Extracting language strings for '$MSGS_FILE':"
|
||||
|
||||
echo -n " new..."
|
||||
cd $SRC_DIR
|
||||
$ERL -pa $EXTRACT_DIR -noinput -noshell -s extract_translations -s init stop -extra . $MSGS_PATH >$MSGS_PATH.new
|
||||
sed -e 's/^% \.\//% /g;' $MSGS_PATH.new > $MSGS_PATH.new2
|
||||
mv $MSGS_PATH.new2 $MSGS_PATH.new
|
||||
|
||||
echo -n " old..."
|
||||
$ERL -pa $EXTRACT_DIR -noinput -noshell -s extract_translations -s init stop -extra -unused . $MSGS_PATH >$MSGS_PATH.unused
|
||||
find_unused_full $MSGS_FILE $MSGS_FILE.unused
|
||||
|
||||
echo "" >$MSGS_PATH2
|
||||
echo " ***** Translation file for ejabberd ***** " >>$MSGS_PATH2
|
||||
echo "" >>$MSGS_PATH2
|
||||
|
||||
echo "" >>$MSGS_PATH2
|
||||
echo " *** New strings: Can you please translate them? *** " >>$MSGS_PATH2
|
||||
cat $MSGS_PATH.new >>$MSGS_PATH2
|
||||
|
||||
echo "" >>$MSGS_PATH2
|
||||
echo "" >>$MSGS_PATH2
|
||||
echo " *** Unused strings: They will be removed automatically *** " >>$MSGS_PATH2
|
||||
cat $MSGS_PATH.unused.full >>$MSGS_PATH2
|
||||
|
||||
echo "" >>$MSGS_PATH2
|
||||
echo "" >>$MSGS_PATH2
|
||||
echo " *** Already translated strings: you can also modify any of them if you want *** " >>$MSGS_PATH2
|
||||
echo "" >>$MSGS_PATH2
|
||||
cat $MSGS_PATH.old_cleaned >>$MSGS_PATH2
|
||||
|
||||
echo " ok"
|
||||
|
||||
rm $MSGS_PATH.new
|
||||
rm $MSGS_PATH.old_cleaned
|
||||
rm $MSGS_PATH.unused.full
|
||||
}
|
||||
|
||||
extract_lang_all ()
|
||||
{
|
||||
cd $MSGS_DIR
|
||||
for i in $( ls *.msg ) ; do
|
||||
extract_lang $i;
|
||||
done
|
||||
|
||||
echo -e "File\tMissing\tLanguage\t\tLast translator"
|
||||
echo -e "----\t-------\t--------\t\t---------------"
|
||||
cd $MSGS_DIR
|
||||
for i in $( ls *.msg ) ; do
|
||||
MISSING=`cat $i.translate | grep "\", \"\"}." | wc -l`
|
||||
LANGUAGE=`grep "X-Language:" $i.translate | sed 's/% Language: //g'`
|
||||
LASTAUTH=`grep "Author:" $i.translate | head -n 1 | sed 's/% Author: //g'`
|
||||
echo -e "$i\t$MISSING\t$LANGUAGE\t$LASTAUTH"
|
||||
done
|
||||
|
||||
cd $MSGS_DIR
|
||||
REVISION=`git describe --always`
|
||||
zip $HOME/ejabberd-langs-$REVISION.zip *.translate;
|
||||
|
||||
rm *.translate
|
||||
}
|
||||
|
||||
find_unused_full ()
|
||||
{
|
||||
DATFILE=$1
|
||||
DATFILEI=$1.old_cleaned
|
||||
DELFILE=$2
|
||||
cd msgs
|
||||
|
||||
DATFILE1=$DATFILE.t1
|
||||
DATFILE2=$DATFILE.t2
|
||||
|
||||
DELFILE1=$DELFILE.t1
|
||||
DELFILE2=$DELFILE.t2
|
||||
DELFILEF=$DATFILE.unused.full
|
||||
echo "" >$DELFILEF
|
||||
|
||||
grep -v "\\\\" $DELFILE >$DELFILE2
|
||||
echo ENDFILEMARK >>$DELFILE2
|
||||
cp $DATFILE $DATFILEI
|
||||
cp $DATFILE $DATFILE2
|
||||
|
||||
cp $DELFILE2 $DELFILE1
|
||||
STRING=`head -1 $DELFILE1`
|
||||
until [[ $STRING == ENDFILEMARK ]]; do
|
||||
cp $DELFILE2 $DELFILE1
|
||||
cp $DATFILE2 $DATFILE1
|
||||
|
||||
STRING=`head -1 $DELFILE1`
|
||||
|
||||
cat $DATFILE1 | grep "$STRING" >>$DELFILEF
|
||||
cat $DATFILE1 | grep -v "$STRING" >$DATFILE2
|
||||
cat $DELFILE1 | grep -v "$STRING" >$DELFILE2
|
||||
done
|
||||
|
||||
mv $DATFILE2 $DATFILEI
|
||||
|
||||
rm -f $MSGS_PATH.t1
|
||||
rm $MSGS_PATH.unused
|
||||
rm -f $MSGS_PATH.unused.t1
|
||||
rm $MSGS_PATH.unused.t2
|
||||
|
||||
cd ..
|
||||
}
|
||||
|
||||
extract_lang_srcmsg2po ()
|
||||
{
|
||||
LANG=$1
|
||||
LANG_CODE=$LANG.$PROJECT
|
||||
MSGS_PATH=$MSGS_DIR/$LANG_CODE.msg
|
||||
PO_PATH=$MSGS_DIR/$LANG_CODE.po
|
||||
|
||||
echo $MSGS_PATH
|
||||
|
||||
$ERL -pa $EXTRACT_DIR -pa $SRC_DIR -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -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=$PROJECT
|
||||
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 -pa $EJA_SRC_DIR -pa /lib/ejabberd/include -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 $EJA_MSGS_DIR --output-file=$POT_PATH
|
||||
msguniq --sort-by-file $POT_PATH.2 --output-file=$POT_PATH
|
||||
|
||||
rm $POT_PATH.*
|
||||
rm $MSGS_PATH
|
||||
|
||||
# If the project is a specific module, not the main ejabberd
|
||||
if [[ $PROJECT != ejabberd ]] ; then
|
||||
# Remove from project.pot the strings that are already present in the general ejabberd
|
||||
EJABBERD_MSG_FILE=$EJA_MSGS_DIR/es.po # This is just some file with translated strings
|
||||
POT_PATH_TEMP=$POT_PATH.temp
|
||||
msgattrib --set-obsolete --only-file=$EJABBERD_MSG_FILE -o $POT_PATH_TEMP $POT_PATH
|
||||
mv $POT_PATH_TEMP $POT_PATH
|
||||
fi
|
||||
}
|
||||
|
||||
extract_lang_popot2po ()
|
||||
{
|
||||
LANG_CODE=$1
|
||||
PO_PATH=$MSGS_DIR/$LANG_CODE.po
|
||||
POT_PATH=$MSGS_DIR/$PROJECT.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 $( ls *.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 "X-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 ()
|
||||
{
|
||||
echo ""
|
||||
echo " A new file has been created for you, with the current, the new and the deprecated strings:"
|
||||
echo " $MSGS_PATH2"
|
||||
echo ""
|
||||
echo " At the end of that file you will find the strings you must update:"
|
||||
echo " - Untranslated strings are like this: {"March", ""}."
|
||||
echo " To translate the string, add the text inside the commas. Example:"
|
||||
echo " {"March", "Marzo"}."
|
||||
echo " - Old strings that are not used: "Woowoa""
|
||||
echo " Search the entire file for those strings and remove them"
|
||||
echo ""
|
||||
echo " Once you have translated all the strings and removed all the old ones,"
|
||||
echo " rename the file to overwrite the previous one:"
|
||||
echo " $MSGS_PATH"
|
||||
}
|
||||
|
||||
EJA_DIR=`pwd`/..
|
||||
RUN_DIR=`pwd`/..
|
||||
PROJECT=ejabberd
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
PARAM=$1
|
||||
shift
|
||||
case $PARAM in
|
||||
--) break ;;
|
||||
-project)
|
||||
PROJECT=$1
|
||||
shift
|
||||
;;
|
||||
-ejadir)
|
||||
EJA_DIR=$1
|
||||
shift
|
||||
;;
|
||||
-rundir)
|
||||
RUN_DIR=$1
|
||||
shift
|
||||
;;
|
||||
-lang)
|
||||
LANGU=$1
|
||||
prepare_dirs
|
||||
extract_lang $LANGU
|
||||
shift
|
||||
;;
|
||||
-langall)
|
||||
prepare_dirs
|
||||
extract_lang_all
|
||||
;;
|
||||
-srcmsg2po)
|
||||
LANG_CODE=$1
|
||||
prepare_dirs
|
||||
extract_lang_srcmsg2po $LANG_CODE
|
||||
shift
|
||||
;;
|
||||
-popot2po)
|
||||
LANG_CODE=$1
|
||||
prepare_dirs
|
||||
extract_lang_popot2po $LANG_CODE
|
||||
shift
|
||||
;;
|
||||
-src2pot)
|
||||
prepare_dirs
|
||||
extract_lang_src2pot
|
||||
;;
|
||||
-po2msg)
|
||||
LANG_CODE=$1
|
||||
prepare_dirs
|
||||
extract_lang_po2msg $LANG_CODE
|
||||
shift
|
||||
;;
|
||||
-updateall)
|
||||
prepare_dirs
|
||||
extract_lang_updateall
|
||||
;;
|
||||
*)
|
||||
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 "Example:"
|
||||
echo " ./prepare-translation.sh -lang es.msg"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -1,62 +0,0 @@
|
||||
# $Id$
|
||||
|
||||
SHELL = /bin/bash
|
||||
|
||||
CONTRIBUTED_MODULES = ""
|
||||
#ifeq ($(shell ls mod_http_bind.tex),mod_http_bind.tex)
|
||||
# CONTRIBUTED_MODULES += "\\n\\setboolean{modhttpbind}{true}"
|
||||
#endif
|
||||
|
||||
|
||||
all: release pdf html
|
||||
|
||||
release:
|
||||
@echo "Notes for the releaser:"
|
||||
@echo "* Do not forget to add a link to the release notes in guide.tex"
|
||||
@echo "* Do not forget to update the version number in src/ejabberd.app!"
|
||||
@echo "* Do not forget to update the features in introduction.tex (including \new{} and \improved{} tags)."
|
||||
@echo "Press any key to continue"
|
||||
##@read foo
|
||||
@echo "% ejabberd version (automatically generated)." > version.tex
|
||||
@echo "\newcommand{\version}{"`sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../src/ejabberd.app`"}" >> version.tex
|
||||
@echo -n "% Contributed modules (automatically generated)." > contributed_modules.tex
|
||||
@echo -e "$(CONTRIBUTED_MODULES)" >> contributed_modules.tex
|
||||
|
||||
html: guide.html dev.html features.html
|
||||
|
||||
pdf: guide.pdf features.pdf
|
||||
|
||||
clean:
|
||||
rm -f *.aux
|
||||
rm -f *.haux
|
||||
rm -f *.htoc
|
||||
rm -f *.idx
|
||||
rm -f *.ilg
|
||||
rm -f *.ind
|
||||
rm -f *.log
|
||||
rm -f *.out
|
||||
rm -f *.pdf
|
||||
rm -f *.toc
|
||||
[ ! -f contributed_modules.tex ] || rm contributed_modules.tex
|
||||
|
||||
distclean: clean
|
||||
rm -f *.html
|
||||
|
||||
guide.html: guide.tex
|
||||
hevea -fix -pedantic guide.tex
|
||||
|
||||
dev.html: dev.tex
|
||||
hevea -fix -pedantic dev.tex
|
||||
|
||||
features.html: features.tex
|
||||
hevea -fix -pedantic features.tex
|
||||
|
||||
guide.pdf: guide.tex
|
||||
pdflatex guide.tex
|
||||
pdflatex guide.tex
|
||||
pdflatex guide.tex
|
||||
makeindex guide.idx
|
||||
pdflatex guide.tex
|
||||
|
||||
features.pdf: features.tex
|
||||
pdflatex features.tex
|
||||
@@ -1,18 +0,0 @@
|
||||
APPNAME = ejabberd
|
||||
VSN = $(shell sed '/vsn/!d;s/\(.*\)"\(.*\)"\(.*\)/\2/' ../../src/ejabberd.app)
|
||||
|
||||
DOCDIR=.
|
||||
SRCDIR=../../src
|
||||
|
||||
.PHONY = all
|
||||
|
||||
all: docs
|
||||
|
||||
clean:
|
||||
rm -f *.html
|
||||
rm edoc-info
|
||||
rm erlang.png
|
||||
|
||||
docs:
|
||||
erl -noshell -run edoc_run application \
|
||||
"'$(APPNAME)'" '"$(SRCDIR)"' '[{dir,"$(DOCDIR)"},{packages, false},{todo,true},{private,true},{def,{vsn,"$(VSN)"}},{stylesheet,"process-one.css"},{overview,"$(DOCDIR)/overview.edoc"}]' -s init stop
|
||||
@@ -1,10 +0,0 @@
|
||||
@author Mickael Remond <mickael.remond@process-one.net>
|
||||
[http://www.process-one.net/]
|
||||
@copyright 2013 ProcessOne
|
||||
@version {@vsn}, {@date} {@time}
|
||||
@title ejabberd Development API Documentation
|
||||
|
||||
@doc
|
||||
== Introduction ==
|
||||
|
||||
TODO: Insert content from Jerome documentation.
|
||||
@@ -1,92 +0,0 @@
|
||||
html, body {
|
||||
font-family: Verdana, sans-serif;
|
||||
color: #000;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #4a5389;
|
||||
border-bottom: solid 1px #000;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
text-align: right;
|
||||
color: #4a5389;
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
color: #900;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 14px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
a[href] {
|
||||
color: #4a5389;
|
||||
}
|
||||
|
||||
a[href]:hover {
|
||||
background-color: #ecefff;
|
||||
}
|
||||
|
||||
p, li, dd {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
|
||||
li:first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
caption {
|
||||
font-style: italic;
|
||||
color: #009;
|
||||
text-align: left;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
table[border="1"] {
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
table[border="1"] td {
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
pre, tt, code {
|
||||
color: #461b7e;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin:1ex 2ex;
|
||||
border:1px dashed lightgrey;
|
||||
background-color:#f9f9f9;
|
||||
padding:0.5ex;
|
||||
}
|
||||
|
||||
pre em {
|
||||
font-style: normal;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dt {
|
||||
margin:0ex 2ex;
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin:0ex 0ex 1ex 4ex;
|
||||
}
|
||||
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
@@ -1,251 +1,162 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Ejabberd 2.1.12 Developers Guide
|
||||
</TITLE>
|
||||
<HEAD><TITLE>Ejabberd Developers Guide</TITLE>
|
||||
|
||||
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<META name="GENERATOR" content="hevea 1.10">
|
||||
<STYLE type="text/css">
|
||||
.li-itemize{margin:1ex 0ex;}
|
||||
.li-enumerate{margin:1ex 0ex;}
|
||||
.dd-description{margin:0ex 0ex 1ex 4ex;}
|
||||
.dt-description{margin:0ex;}
|
||||
.toc{list-style:none;}
|
||||
.thefootnotes{text-align:left;margin:0ex;}
|
||||
.dt-thefootnotes{margin:0em;}
|
||||
.dd-thefootnotes{margin:0em 0em 0em 2em;}
|
||||
.footnoterule{margin:1em auto 1em 0px;width:50%;}
|
||||
.caption{padding-left:2ex; padding-right:2ex; margin-left:auto; margin-right:auto}
|
||||
.title{margin:2ex auto;text-align:center}
|
||||
.center{text-align:center;margin-left:auto;margin-right:auto;}
|
||||
.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
|
||||
.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
|
||||
DIV TABLE{margin-left:inherit;margin-right:inherit;}
|
||||
PRE{text-align:left;margin-left:0ex;margin-right:auto;}
|
||||
BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
|
||||
TD P{margin:0px;}
|
||||
.boxed{border:1px solid black}
|
||||
.textboxed{border:1px solid black}
|
||||
.vbar{border:none;width:2px;background-color:black;}
|
||||
.hbar{border:none;height:2px;width:100%;background-color:black;}
|
||||
.hfill{border:none;height:1px;width:200%;background-color:black;}
|
||||
.vdisplay{border-collapse:separate;border-spacing:2px;width:auto; empty-cells:show; border:2px solid red;}
|
||||
.vdcell{white-space:nowrap;padding:0px;width:auto; border:2px solid green;}
|
||||
.display{border-collapse:separate;border-spacing:2px;width:auto; border:none;}
|
||||
.dcell{white-space:nowrap;padding:0px;width:auto; border:none;}
|
||||
.dcenter{margin:0ex auto;}
|
||||
.vdcenter{border:solid #FF8000 2px; margin:0ex auto;}
|
||||
.minipage{text-align:left; margin-left:0em; margin-right:auto;}
|
||||
.marginpar{border:solid thin black; width:20%; text-align:left;}
|
||||
.marginparleft{float:left; margin-left:0ex; margin-right:1ex;}
|
||||
.marginparright{float:right; margin-left:1ex; margin-right:0ex;}
|
||||
.theorem{text-align:left;margin:1ex auto 1ex 0ex;}
|
||||
.part{margin:2ex auto;text-align:center}
|
||||
</STYLE>
|
||||
<META http-equiv="Content-Type" content="text/html; charset=ISO8859-1">
|
||||
<META name="GENERATOR" content="hevea 1.06">
|
||||
</HEAD>
|
||||
<BODY >
|
||||
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic dev.tex -->
|
||||
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
|
||||
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.12 Developers Guide</H1><H3 CLASS="titlerest">Alexey Shchepin<BR>
|
||||
<A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
|
||||
<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3></TD></TR>
|
||||
</TABLE><DIV CLASS="center">
|
||||
|
||||
<IMG SRC="logo.png" ALT="logo.png">
|
||||
<!--HEVEA command line is: /usr/bin/hevea -charset ISO8859-1 dev.tex -->
|
||||
<!--HTMLHEAD-->
|
||||
<!--ENDHTML-->
|
||||
<!--PREFIX <ARG ></ARG>-->
|
||||
<!--CUT DEF section 1 -->
|
||||
|
||||
|
||||
</DIV><BLOCKQUOTE CLASS="quotation"><I>I can thoroughly recommend ejabberd for ease of setup –
|
||||
Kevin Smith, Current maintainer of the Psi project</I></BLOCKQUOTE><!--TOC section Contents-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR -->Contents</H2><!--SEC END --><UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc1">1  Key Features</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc2">2  Additional Features</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc3">3  How it Works</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc4">3.1  Router</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc5">3.2  Local Router</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc6">3.3  Session Manager</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc7">3.4  S2S Manager</A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc8">4  Authentication</A>
|
||||
<UL CLASS="toc">
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc9">4.0.1  External</A>
|
||||
</LI></UL>
|
||||
|
||||
<H1 ALIGN=center>Ejabberd Developers Guide</H1>
|
||||
|
||||
<H3 ALIGN=center>Alexey Shchepin<BR>
|
||||
<A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
|
||||
<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3>
|
||||
|
||||
<H3 ALIGN=center>September 10, 2003</H3><DIV ALIGN=center>
|
||||
|
||||
<IMG SRC="logo.png">
|
||||
|
||||
|
||||
</DIV><BR>
|
||||
<BR>
|
||||
|
||||
|
||||
<!--TOC section Table of Contents-->
|
||||
|
||||
<H2>Table of Contents</H2><!--SEC END -->
|
||||
|
||||
<UL><LI>
|
||||
<A HREF="#htoc1">1 Introduction</A>
|
||||
<UL><LI>
|
||||
<A HREF="#htoc2">1.1 How it works</A>
|
||||
<UL><LI>
|
||||
<A HREF="#htoc3">1.1.1 Router</A>
|
||||
<LI><A HREF="#htoc4">1.1.2 Local Router</A>
|
||||
<LI><A HREF="#htoc5">1.1.3 Session Manager</A>
|
||||
<LI><A HREF="#htoc6">1.1.4 S2S Manager</A>
|
||||
</UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc10">5  XML Representation</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc11">6  Module <TT>xml</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc12">7  Module <TT>xml_stream</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc13">8  Modules</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc14">8.1  Module gen_iq_handler</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc15">8.2  Services</A>
|
||||
</LI></UL>
|
||||
</LI></UL><P>Introduction
|
||||
<A NAME="intro"></A></P><P><TT>ejabberd</TT> is a free and open source instant messaging server written in <A HREF="http://www.erlang.org/">Erlang/OTP</A>.</P><P><TT>ejabberd</TT> is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.</P><P><TT>ejabberd</TT> is designed to be a rock-solid and feature rich XMPP server.</P><P><TT>ejabberd</TT> is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.</P><!--TOC section Key Features-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc1">1</A>  Key Features</H2><!--SEC END --><P>
|
||||
<A NAME="keyfeatures"></A>
|
||||
</P><P><TT>ejabberd</TT> is:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Cross-platform: <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</LI><LI CLASS="li-itemize">Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</LI><LI CLASS="li-itemize">Fault-tolerant: You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced ‘on the fly’.</LI><LI CLASS="li-itemize">Administrator Friendly: <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Comprehensive documentation.
|
||||
</LI><LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </LI><LI CLASS="li-itemize">Web Administration.
|
||||
</LI><LI CLASS="li-itemize">Shared Roster Groups.
|
||||
</LI><LI CLASS="li-itemize">Command line administration tool. </LI><LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
|
||||
</LI><LI CLASS="li-itemize">Capability to send announce messages.
|
||||
</LI></UL></LI><LI CLASS="li-itemize">Internationalized: <TT>ejabberd</TT> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Translated to 25 languages. </LI><LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
|
||||
</LI></UL></LI><LI CLASS="li-itemize">Open Standards: <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Fully XMPP compliant.
|
||||
</LI><LI CLASS="li-itemize">XML-based protocol.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.ejabberd.im/protocols">Many protocols supported</A>.
|
||||
</LI></UL></LI></UL><!--TOC section Additional Features-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc2">2</A>  Additional Features</H2><!--SEC END --><P>
|
||||
<A NAME="addfeatures"></A>
|
||||
</P><P>Moreover, <TT>ejabberd</TT> comes with a wide range of other state-of-the-art features:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Modular
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Load only the modules you want.
|
||||
</LI><LI CLASS="li-itemize">Extend <TT>ejabberd</TT> with your own custom modules.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Security
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
SASL and STARTTLS for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
|
||||
</LI><LI CLASS="li-itemize">Web Admin accessible via HTTPS secure access.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Databases
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Internal database for fast deployment (Mnesia).
|
||||
</LI><LI CLASS="li-itemize">Native MySQL support.
|
||||
</LI><LI CLASS="li-itemize">Native PostgreSQL support.
|
||||
</LI><LI CLASS="li-itemize">ODBC data storage support.
|
||||
</LI><LI CLASS="li-itemize">Microsoft SQL Server support. </LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Authentication
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Internal Authentication.
|
||||
</LI><LI CLASS="li-itemize">PAM, LDAP and ODBC. </LI><LI CLASS="li-itemize">External Authentication script.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Others
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Support for virtual hosting.
|
||||
</LI><LI CLASS="li-itemize">Compressing XML streams with Stream Compression (<A HREF="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</A>).
|
||||
</LI><LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>).
|
||||
</LI><LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with support for clustering and HTML logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component with support for <A HREF="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</A>.
|
||||
</LI><LI CLASS="li-itemize">Support for web clients: <A HREF="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</A> and <A HREF="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</A> services.
|
||||
</LI><LI CLASS="li-itemize">IRC transport.
|
||||
</LI><LI CLASS="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
|
||||
</LI></UL>
|
||||
</LI></UL><!--TOC section How it Works-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc3">3</A>  How it Works</H2><!--SEC END --><P>
|
||||
<A NAME="howitworks"></A></P><P>A XMPP domain is served by one or more <TT>ejabberd</TT> nodes. These nodes can
|
||||
</UL>
|
||||
<LI><A HREF="#htoc7">2 XML representation</A>
|
||||
<LI><A HREF="#htoc8">3 Module <TT>xml</TT></A>
|
||||
<LI><A HREF="#htoc9">4 <TT>ejabberd</TT> modules</A>
|
||||
<UL><LI>
|
||||
<A HREF="#htoc10">4.1 <CODE>gen_mod</CODE> behaviour</A>
|
||||
<LI><A HREF="#htoc11">4.2 Module <CODE>gen_iq_handler</CODE></A>
|
||||
<LI><A HREF="#htoc12">4.3 Services</A>
|
||||
</UL>
|
||||
</UL>
|
||||
|
||||
<!--TOC section Introduction-->
|
||||
|
||||
<H2><A NAME="htoc1">1</A> Introduction</H2><!--SEC END -->
|
||||
|
||||
<A NAME="sec:intro"></A>
|
||||
<TT>ejabberd</TT> is a Free and Open Source fault-tolerant distributed Jabber
|
||||
server. It is writen mostly in Erlang.<BR>
|
||||
<BR>
|
||||
The main features of <TT>ejabberd</TT> is:
|
||||
<UL><LI>
|
||||
Works on most of popular platforms: *nix (tested on Linux and FreeBSD)
|
||||
and Win32
|
||||
<LI>Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of
|
||||
them will serve one Jabber domain.
|
||||
<LI>Fault-tolerance: You can setup an <TT>ejabberd</TT> cluster so that all the
|
||||
information required for a properly working service will be stored
|
||||
permanently on more than one node. This means that if one of the nodes
|
||||
crashes, then the others will continue working without disruption.
|
||||
You can also add or replace more nodes ``on the fly''.
|
||||
<LI>Built-in <A HREF="http://www.jabber.org/jeps/jep-0045.html">Multi-User
|
||||
Chat</A> service
|
||||
<LI>Built-in IRC transport
|
||||
<LI>Built-in
|
||||
<A HREF="http://www.jabber.org/jeps/jep-0060.html">Publish-Subscribe</A>
|
||||
service
|
||||
<LI>Built-in Jabber Users Directory service based on users vCards
|
||||
<LI>Support for
|
||||
<A HREF="http://www.jabber.org/jeps/jep-0030.html">JEP-0030</A>
|
||||
(Service Discovery).
|
||||
<LI>Support for
|
||||
<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A>
|
||||
(Statistics Gathering).
|
||||
<LI>Support for <TT>xml:lang</TT> attribute in many XML elements
|
||||
</UL>
|
||||
<!--TOC subsection How it works-->
|
||||
|
||||
<H3><A NAME="htoc2">1.1</A> How it works</H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:howitworks"></A>
|
||||
A Jabber domain is served by one or more <TT>ejabberd</TT> nodes. These nodes can
|
||||
be run on different machines that are connected via a network. They all must
|
||||
have the ability to connect to port 4369 of all another nodes, and must have
|
||||
the same magic cookie (see Erlang/OTP documentation, in other words the file
|
||||
<TT>~ejabberd/.erlang.cookie</TT> must be the same on all nodes). This is
|
||||
needed because all nodes exchange information about connected users, S2S
|
||||
connections, registered services, etc…</P><P>Each <TT>ejabberd</TT> node have following modules:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
connections, registered services, etc...<BR>
|
||||
<BR>
|
||||
Each <TT>ejabberd</TT> node have following modules:
|
||||
<UL><LI>
|
||||
router;
|
||||
</LI><LI CLASS="li-itemize">local router.
|
||||
</LI><LI CLASS="li-itemize">session manager;
|
||||
</LI><LI CLASS="li-itemize">S2S manager;
|
||||
</LI></UL><!--TOC subsection Router-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc4">3.1</A>  Router</H3><!--SEC END --><P>This module is the main router of XMPP packets on each node. It routes
|
||||
<LI>local router.
|
||||
<LI>session manager;
|
||||
<LI>S2S manager;
|
||||
</UL>
|
||||
<!--TOC subsubsection Router-->
|
||||
|
||||
<H4><A NAME="htoc3">1.1.1</A> Router</H4><!--SEC END -->
|
||||
|
||||
This module is the main router of Jabber packets on each node. It routes
|
||||
them based on their destinations domains. It has two tables: local and global
|
||||
routes. First, domain of packet destination searched in local table, and if it
|
||||
found, then the packet is routed to appropriate process. If no, then it
|
||||
searches in global table, and is routed to the appropriate <TT>ejabberd</TT> node or
|
||||
process. If it does not exists in either tables, then it sent to the S2S
|
||||
manager.</P><!--TOC subsection Local Router-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc5">3.2</A>  Local Router</H3><!--SEC END --><P>This module routes packets which have a destination domain equal to this server
|
||||
manager.<BR>
|
||||
<BR>
|
||||
<!--TOC subsubsection Local Router-->
|
||||
|
||||
<H4><A NAME="htoc4">1.1.2</A> Local Router</H4><!--SEC END -->
|
||||
|
||||
This module routes packets which have a destination domain equal to this server
|
||||
name. If destination JID has a non-empty user part, then it routed to the
|
||||
session manager, else it is processed depending on it’s content.</P><!--TOC subsection Session Manager-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc6">3.3</A>  Session Manager</H3><!--SEC END --><P>This module routes packets to local users. It searches for what user resource
|
||||
packet must be sent via presence table. If this resource is connected to
|
||||
session manager, else it is processed depending on it's content.<BR>
|
||||
<BR>
|
||||
<!--TOC subsubsection Session Manager-->
|
||||
|
||||
<H4><A NAME="htoc5">1.1.3</A> Session Manager</H4><!--SEC END -->
|
||||
|
||||
This module routes packets to local users. It searches for what user resource
|
||||
packet must be sended via presence table. If this resource is connected to
|
||||
this node, it is routed to C2S process, if it connected via another node, then
|
||||
the packet is sent to session manager on that node.</P><!--TOC subsection S2S Manager-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc7">3.4</A>  S2S Manager</H3><!--SEC END --><P>This module routes packets to other XMPP servers. First, it checks if an
|
||||
the packet is sent to session manager on that node.<BR>
|
||||
<BR>
|
||||
<!--TOC subsubsection S2S Manager-->
|
||||
|
||||
<H4><A NAME="htoc6">1.1.4</A> S2S Manager</H4><!--SEC END -->
|
||||
|
||||
This module routes packets to other Jabber servers. First, it checks if an
|
||||
open S2S connection from the domain of the packet source to the domain of
|
||||
packet destination already exists. If it is open on another node, then it
|
||||
routes the packet to S2S manager on that node, if it is open on this node, then
|
||||
it is routed to the process that serves this connection, and if a connection
|
||||
does not exist, then it is opened and registered.</P><!--TOC section Authentication-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc8">4</A>  Authentication</H2><!--SEC END --><!--TOC subsubsection External-->
|
||||
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A NAME="htoc9">4.0.1</A>  External</H4><!--SEC END --><P>
|
||||
<A NAME="externalauth"></A>
|
||||
</P><P>The external authentication script follows
|
||||
<A HREF="http://www.erlang.org/doc/tutorial/c_portdriver.html">the erlang port driver API</A>.</P><P>That script is supposed to do theses actions, in an infinite loop:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
read from stdin: AABBBBBBBBB.....
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
A: 2 bytes of length data (a short in network byte order)
|
||||
</LI><LI CLASS="li-itemize">B: a string of length found in A that contains operation in plain text
|
||||
operation are as follows:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
auth:User:Server:Password (check if a username/password pair is correct)
|
||||
</LI><LI CLASS="li-itemize">isuser:User:Server (check if it’s a valid user)
|
||||
</LI><LI CLASS="li-itemize">setpass:User:Server:Password (set user’s password)
|
||||
</LI><LI CLASS="li-itemize">tryregister:User:Server:Password (try to register an account)
|
||||
</LI><LI CLASS="li-itemize">removeuser:User:Server (remove this account)
|
||||
</LI><LI CLASS="li-itemize">removeuser3:User:Server:Password (remove this account if the password is correct)
|
||||
</LI></UL>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">write to stdout: AABB
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
A: the number 2 (coded as a short, which is bytes length of following result)
|
||||
</LI><LI CLASS="li-itemize">B: the result code (coded as a short), should be 1 for success/valid, or 0 for failure/invalid
|
||||
</LI></UL>
|
||||
</LI></UL><P>Example python script
|
||||
</P><PRE CLASS="verbatim">#!/usr/bin/python
|
||||
does not exist, then it is opened and registered.<BR>
|
||||
<BR>
|
||||
<!--TOC section XML representation-->
|
||||
|
||||
import sys
|
||||
from struct import *
|
||||
<H2><A NAME="htoc7">2</A> XML representation</H2><!--SEC END -->
|
||||
|
||||
def from_ejabberd():
|
||||
input_length = sys.stdin.read(2)
|
||||
(size,) = unpack('>h', input_length)
|
||||
return sys.stdin.read(size).split(':')
|
||||
|
||||
def to_ejabberd(bool):
|
||||
answer = 0
|
||||
if bool:
|
||||
answer = 1
|
||||
token = pack('>hh', 2, answer)
|
||||
sys.stdout.write(token)
|
||||
sys.stdout.flush()
|
||||
|
||||
def auth(username, server, password):
|
||||
return True
|
||||
|
||||
def isuser(username, server):
|
||||
return True
|
||||
|
||||
def setpass(username, server, password):
|
||||
return True
|
||||
|
||||
while True:
|
||||
data = from_ejabberd()
|
||||
success = False
|
||||
if data[0] == "auth":
|
||||
success = auth(data[1], data[2], data[3])
|
||||
elif data[0] == "isuser":
|
||||
success = isuser(data[1], data[2])
|
||||
elif data[0] == "setpass":
|
||||
success = setpass(data[1], data[2], data[3])
|
||||
to_ejabberd(success)
|
||||
</PRE><!--TOC section XML Representation-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc10">5</A>  XML Representation</H2><!--SEC END --><P>
|
||||
<A NAME="xmlrepr"></A></P><P>Each XML stanza is represented as the following tuple:
|
||||
</P><PRE CLASS="verbatim">XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
||||
<A NAME="sec:xmlrepr"></A>
|
||||
Each XML stanza represented as following tuple:
|
||||
<PRE>
|
||||
XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
||||
Name = string()
|
||||
Attrs = [Attr]
|
||||
Attr = {Key, Val}
|
||||
@@ -253,30 +164,46 @@ while True:
|
||||
Val = string()
|
||||
ElementOrCDATA = XMLElement | CDATA
|
||||
CDATA = {xmlcdata, string()}
|
||||
</PRE><P>E. g. this stanza:
|
||||
</P><PRE CLASS="verbatim"><message to='test@conference.example.org' type='groupchat'>
|
||||
</PRE>E. g. this stanza:
|
||||
<PRE>
|
||||
<message to='test@conference.e.localhost' type='groupchat'>
|
||||
<body>test</body>
|
||||
</message>
|
||||
</PRE><P>is represented as the following structure:
|
||||
</P><PRE CLASS="verbatim">{xmlelement, "message",
|
||||
[{"to", "test@conference.example.org"},
|
||||
</PRE>represented as following structure:
|
||||
<PRE>
|
||||
{xmlelement, "message",
|
||||
[{"to", "test@conference.e.localhost"},
|
||||
{"type", "groupchat"}],
|
||||
[{xmlelement, "body",
|
||||
[],
|
||||
[{xmlcdata, "test"}]}]}}
|
||||
</PRE><!--TOC section Module <TT>xml</TT>-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc11">6</A>  Module <TT>xml</TT></H2><!--SEC END --><P>
|
||||
<A NAME="xmlmod"></A></P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>element_to_string(El) -> string()</CODE>
|
||||
<PRE CLASS="verbatim">El = XMLElement
|
||||
</PRE>Returns string representation of XML stanza <TT>El</TT>.</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>crypt(S) -> string()</CODE>
|
||||
<PRE CLASS="verbatim">S = string()
|
||||
</PRE>
|
||||
<!--TOC section Module <TT>xml</TT>-->
|
||||
|
||||
<H2><A NAME="htoc8">3</A> Module <TT>xml</TT></H2><!--SEC END -->
|
||||
|
||||
<A NAME="sec:xmlmod"></A>
|
||||
<DL COMPACT=compact><DT>
|
||||
<CODE><B>element_to_string(El) -> string()</B></CODE><DD>
|
||||
<PRE>
|
||||
El = XMLElement
|
||||
</PRE>Returns string representation of XML stanza <TT>El</TT>.<BR>
|
||||
<BR>
|
||||
<DT><CODE><B>crypt(S) -> string()</B></CODE><DD>
|
||||
<PRE>
|
||||
S = string()
|
||||
</PRE>Returns string which correspond to <TT>S</TT> with encoded XML special
|
||||
characters.</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>remove_cdata(ECList) -> EList</CODE>
|
||||
<PRE CLASS="verbatim">ECList = [ElementOrCDATA]
|
||||
characters.<BR>
|
||||
<BR>
|
||||
<DT><CODE><B>remove_cdata(ECList) -> EList</B></CODE><DD>
|
||||
<PRE>
|
||||
ECList = [ElementOrCDATA]
|
||||
EList = [XMLElement]
|
||||
</PRE><TT>EList</TT> is a list of all non-CDATA elements of ECList.</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>get_path_s(El, Path) -> Res</CODE>
|
||||
<PRE CLASS="verbatim">El = XMLElement
|
||||
</PRE><TT>EList</TT> is a list of all non-CDATA elements of ECList.<BR>
|
||||
<BR>
|
||||
<DT><CODE><B>get_path_s(El, Path) -> Res</B></CODE><DD>
|
||||
<PRE>
|
||||
El = XMLElement
|
||||
Path = [PathItem]
|
||||
PathItem = PathElem | PathAttr | PathCDATA
|
||||
PathElem = {elem, Name}
|
||||
@@ -285,61 +212,76 @@ PathCDATA = cdata
|
||||
Name = string()
|
||||
Res = string() | XMLElement
|
||||
</PRE>If <TT>Path</TT> is empty, then returns <TT>El</TT>. Else sequentially
|
||||
consider elements of <TT>Path</TT>. Each element is one of:
|
||||
<DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>{elem, Name}</CODE> <TT>Name</TT> is name of subelement of
|
||||
<TT>El</TT>, if such element exists, then this element considered in
|
||||
following steps, else returns empty string.
|
||||
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>{attr, Name}</CODE> If <TT>El</TT> have attribute <TT>Name</TT>, then
|
||||
returns value of this attribute, else returns empty string.
|
||||
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>cdata</CODE> Returns CDATA of <TT>El</TT>.
|
||||
</DD></DL></DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description">TODO:
|
||||
<PRE CLASS="verbatim"> get_cdata/1, get_tag_cdata/1
|
||||
consider elements of <TT>Path</TT>. Each element is one of:
|
||||
<DL COMPACT=compact><DT>
|
||||
<CODE><B>{elem, Name}</B></CODE><DD> <TT>Name</TT> is name of subelement of
|
||||
<TT>El</TT>, if such element exists, then this element considered in
|
||||
following steps, else returns empty string.
|
||||
<DT><CODE><B>{attr, Name}</B></CODE><DD> If <TT>El</TT> have attribute <TT>Name</TT>, then
|
||||
returns value of this attribute, else returns empty string.
|
||||
<DT><CODE><B>cdata</B></CODE><DD> Returns CDATA of <TT>El</TT>.
|
||||
</DL><BR>
|
||||
<BR>
|
||||
<DT><B>TODO:</B><DD>
|
||||
<PRE>
|
||||
get_cdata/1, get_tag_cdata/1
|
||||
get_attr/2, get_attr_s/2
|
||||
get_tag_attr/2, get_tag_attr_s/2
|
||||
get_subtag/2
|
||||
</PRE></DD></DL><!--TOC section Module <TT>xml_stream</TT>-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc12">7</A>  Module <TT>xml_stream</TT></H2><!--SEC END --><P>
|
||||
<A NAME="xmlstreammod"></A></P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>parse_element(Str) -> XMLElement | {error, Err}</CODE>
|
||||
<PRE CLASS="verbatim">Str = string()
|
||||
Err = term()
|
||||
</PRE>Parses <TT>Str</TT> using XML parser, returns either parsed element or error
|
||||
tuple.
|
||||
</DD></DL><!--TOC section Modules-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc13">8</A>  Modules</H2><!--SEC END --><P>
|
||||
<A NAME="emods"></A></P><!--TOC subsection Module gen_iq_handler-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc14">8.1</A>  Module gen_iq_handler</H3><!--SEC END --><P>
|
||||
<A NAME="geniqhandl"></A></P><P>The module <CODE>gen_iq_handler</CODE> allows to easily write handlers for IQ packets
|
||||
of particular XML namespaces that addressed to server or to users bare JIDs.</P><P>In this module the following functions are defined:
|
||||
</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>add_iq_handler(Component, Host, NS, Module, Function, Type)</CODE>
|
||||
<PRE CLASS="verbatim">Component = Module = Function = atom()
|
||||
Host = NS = string()
|
||||
</PRE></DL>
|
||||
<!--TOC section <TT>ejabberd</TT> modules-->
|
||||
|
||||
<H2><A NAME="htoc9">4</A> <TT>ejabberd</TT> modules</H2><!--SEC END -->
|
||||
|
||||
<A NAME="sec:emods"></A>
|
||||
<!--TOC subsection <CODE>gen_mod</CODE> behaviour-->
|
||||
|
||||
<H3><A NAME="htoc10">4.1</A> <CODE>gen_mod</CODE> behaviour</H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:genmod"></A>
|
||||
TBD<BR>
|
||||
<BR>
|
||||
<!--TOC subsection Module <CODE>gen_iq_handler</CODE>-->
|
||||
|
||||
<H3><A NAME="htoc11">4.2</A> Module <CODE>gen_iq_handler</CODE></H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:geniqhandl"></A>
|
||||
The module <CODE>gen_iq_handler</CODE> allows to easily write handlers for IQ packets
|
||||
of particular XML namespaces that addressed to server or to users bare JIDs.<BR>
|
||||
<BR>
|
||||
In this module the following functions are defined:
|
||||
<DL COMPACT=compact><DT>
|
||||
<CODE><B>add_iq_handler(Component, NS, Module, Function, Type)</B></CODE><DD>
|
||||
<PRE>
|
||||
Component = Module = Function = atom()
|
||||
NS = string()
|
||||
Type = no_queue | one_queue | parallel
|
||||
</PRE>Registers function <CODE>Module:Function</CODE> as handler for IQ packets on
|
||||
virtual host <CODE>Host</CODE> that contain child of namespace <CODE>NS</CODE> in
|
||||
<CODE>Component</CODE>. Queueing discipline is <CODE>Type</CODE>. There are at least
|
||||
two components defined:
|
||||
<DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>ejabberd_local</CODE> Handles packets that addressed to server JID;
|
||||
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>ejabberd_sm</CODE> Handles packets that addressed to users bare JIDs.
|
||||
</DD></DL>
|
||||
</DD><DT CLASS="dt-description"></DT><DD CLASS="dd-description"><CODE>remove_iq_handler(Component, Host, NS)</CODE>
|
||||
<PRE CLASS="verbatim">Component = atom()
|
||||
Host = NS = string()
|
||||
</PRE>Removes IQ handler on virtual host <CODE>Host</CODE> for namespace <CODE>NS</CODE> from
|
||||
<CODE>Component</CODE>.
|
||||
</DD></DL><P>Handler function must have the following type:
|
||||
</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
</DT><DD CLASS="dd-description"><CODE>Module:Function(From, To, IQ)</CODE>
|
||||
<PRE CLASS="verbatim">From = To = jid()
|
||||
</PRE></DD></DL><PRE CLASS="verbatim">-module(mod_cputime).
|
||||
</PRE>Registers function <CODE>Module:Function</CODE> as handler for IQ packets that
|
||||
contain child of namespace <CODE>NS</CODE> in <CODE>Component</CODE>. Queueing
|
||||
discipline is <CODE>Type</CODE>. There are at least two components defined:
|
||||
<DL COMPACT=compact><DT>
|
||||
<CODE><B>ejabberd_local</B></CODE><DD> Handles packets that addressed to server JID;
|
||||
<DT><CODE><B>ejabberd_sm</B></CODE><DD> Handles packets that addressed to users bare JIDs.
|
||||
</DL>
|
||||
<DT><CODE><B>remove_iq_handler(Component, NS)</B></CODE><DD>
|
||||
<PRE>
|
||||
Component = atom()
|
||||
NS = string()
|
||||
</PRE>Removes IQ handler for namespace <CODE>NS</CODE> from <CODE>Component</CODE>.
|
||||
</DL>
|
||||
Handler function must have the following type:
|
||||
<DL COMPACT=compact><DT>
|
||||
<CODE><B>Module:Function(From, To, IQ)</B></CODE><DD>
|
||||
<PRE>
|
||||
From = To = jid()
|
||||
</PRE></DL>
|
||||
<PRE>
|
||||
-module(mod_cputime).
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([start/2,
|
||||
stop/1,
|
||||
-export([start/1,
|
||||
stop/0,
|
||||
process_local_iq/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
@@ -347,13 +289,13 @@ Host = NS = string()
|
||||
|
||||
-define(NS_CPUTIME, "ejabberd:cputime").
|
||||
|
||||
start(Host, Opts) ->
|
||||
start(Opts) ->
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_CPUTIME,
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_CPUTIME,
|
||||
?MODULE, process_local_iq, IQDisc).
|
||||
|
||||
stop(Host) ->
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_CPUTIME).
|
||||
stop() ->
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_CPUTIME).
|
||||
|
||||
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
case Type of
|
||||
@@ -368,21 +310,28 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
[{"xmlns", ?NS_CPUTIME}],
|
||||
[{xmlelement, "cputime", [], [{xmlcdata, SCPUTime}]}]}]}
|
||||
end.
|
||||
</PRE><!--TOC subsection Services-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc15">8.2</A>  Services</H3><!--SEC END --><P>
|
||||
<A NAME="services"></A></P><PRE CLASS="verbatim">-module(mod_echo).
|
||||
</PRE>
|
||||
<!--TOC subsection Services-->
|
||||
|
||||
<H3><A NAME="htoc12">4.3</A> Services</H3><!--SEC END -->
|
||||
|
||||
<A NAME="sec:services"></A>
|
||||
TBD<BR>
|
||||
<BR>
|
||||
TODO: use <CODE>proc_lib</CODE>
|
||||
<PRE>
|
||||
-module(mod_echo).
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([start/2, init/1, stop/1]).
|
||||
-export([start/1, init/1, stop/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
start(Host, Opts) ->
|
||||
MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host),
|
||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
spawn(?MODULE, init, [MyHost])).
|
||||
start(Opts) ->
|
||||
Host = gen_mod:get_opt(host, Opts, "echo." ++ ?MYNAME),
|
||||
register(ejabberd_mod_echo, spawn(?MODULE, init, [Host])).
|
||||
|
||||
init(Host) ->
|
||||
ejabberd_router:register_local_route(Host),
|
||||
@@ -394,20 +343,22 @@ loop(Host) ->
|
||||
ejabberd_router:route(To, From, Packet),
|
||||
loop(Host);
|
||||
stop ->
|
||||
ejabberd_router:unregister_route(Host),
|
||||
ejabberd_router:unregister_local_route(Host),
|
||||
ok;
|
||||
_ ->
|
||||
loop(Host)
|
||||
end.
|
||||
|
||||
stop(Host) ->
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
Proc ! stop,
|
||||
{wait, Proc}.
|
||||
</PRE><!--CUT END -->
|
||||
stop() ->
|
||||
ejabberd_mod_echo ! stop,
|
||||
ok.
|
||||
</PRE>
|
||||
<!--HTMLFOOT-->
|
||||
<!--ENDHTML-->
|
||||
<!--FOOTER-->
|
||||
<HR SIZE=2><BLOCKQUOTE CLASS="quote"><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
|
||||
</EM><A HREF="http://hevea.inria.fr/index.html"><EM>H</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>V</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>A</EM></A><EM>.</EM></BLOCKQUOTE></BODY>
|
||||
<HR SIZE=2>
|
||||
<BLOCKQUOTE><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
|
||||
</EM><A HREF="http://pauillac.inria.fr/~maranget/hevea/index.html"><EM>H<FONT SIZE=2><sup>E</sup></FONT>V<FONT SIZE=2><sup>E</sup></FONT>A</EM></A><EM>.
|
||||
</EM></BLOCKQUOTE>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
\documentclass[a4paper,10pt]{article}
|
||||
\documentclass[10pt]{article}
|
||||
|
||||
%% Packages
|
||||
\usepackage{graphics}
|
||||
\usepackage{hevea}
|
||||
\usepackage{makeidx}
|
||||
\usepackage{verbatim}
|
||||
|
||||
%% Index
|
||||
\makeindex
|
||||
% Remove the index anchors from the HTML version to save size and bandwith.
|
||||
\newcommand{\ind}[1]{\begin{latexonly}\index{#1}\end{latexonly}}
|
||||
|
||||
%% Images
|
||||
\newcommand{\logoscale}{0.7}
|
||||
\newcommand{\imgscale}{0.58}
|
||||
\newcommand{\insimg}[1]{\insscaleimg{\imgscale}{#1}}
|
||||
|
||||
\newcommand{\insscaleimg}[2]{
|
||||
\imgsrc{#2}{}
|
||||
\begin{latexonly}
|
||||
@@ -22,86 +16,87 @@
|
||||
\end{latexonly}
|
||||
}
|
||||
|
||||
%% Various
|
||||
\newcommand{\ns}[1]{\texttt{#1}}
|
||||
\newcommand{\ejabberd}{\texttt{ejabberd}}
|
||||
\newcommand{\Jabber}{Jabber}
|
||||
\newcommand{\XMPP}{XMPP}
|
||||
|
||||
%% Modules
|
||||
\newcommand{\module}[1]{\texttt{#1}}
|
||||
\newcommand{\modadhoc}{\module{mod\_adhoc}}
|
||||
\newcommand{\modannounce}{\module{mod\_announce}}
|
||||
\newcommand{\modconfigure}{\module{mod\_configure}}
|
||||
\newcommand{\moddisco}{\module{mod\_disco}}
|
||||
\newcommand{\modecho}{\module{mod\_echo}}
|
||||
\newcommand{\modirc}{\module{mod\_irc}}
|
||||
\newcommand{\modlast}{\module{mod\_last}}
|
||||
\newcommand{\modlastodbc}{\module{mod\_last\_odbc}}
|
||||
\newcommand{\modmuc}{\module{mod\_muc}}
|
||||
\newcommand{\modmuclog}{\module{mod\_muc\_log}}
|
||||
\newcommand{\modoffline}{\module{mod\_offline}}
|
||||
\newcommand{\modofflineodbc}{\module{mod\_offline\_odbc}}
|
||||
\newcommand{\modprivacy}{\module{mod\_privacy}}
|
||||
\newcommand{\modprivate}{\module{mod\_private}}
|
||||
\newcommand{\modpubsub}{\module{mod\_pubsub}}
|
||||
\newcommand{\modregister}{\module{mod\_register}}
|
||||
\newcommand{\modroster}{\module{mod\_roster}}
|
||||
\newcommand{\modrosterodbc}{\module{mod\_roster\_odbc}}
|
||||
\newcommand{\modservicelog}{\module{mod\_service\_log}}
|
||||
\newcommand{\modsharedroster}{\module{mod\_shared\_roster}}
|
||||
\newcommand{\modstats}{\module{mod\_stats}}
|
||||
\newcommand{\modtime}{\module{mod\_time}}
|
||||
\newcommand{\modvcard}{\module{mod\_vcard}}
|
||||
\newcommand{\modvcardldap}{\module{mod\_vcard\_ldap}}
|
||||
\newcommand{\modvcardodbc}{\module{mod\_vcard\_odbc}}
|
||||
\newcommand{\modversion}{\module{mod\_version}}
|
||||
\newcommand{\modregister}{\texttt{mod\_register}}
|
||||
\newcommand{\modroster}{\texttt{mod\_roster}}
|
||||
\newcommand{\modconfigure}{\texttt{mod\_configure}}
|
||||
\newcommand{\moddisco}{\texttt{mod\_disco}}
|
||||
\newcommand{\modstats}{\texttt{mod\_stats}}
|
||||
\newcommand{\modvcard}{\texttt{mod\_vcard}}
|
||||
\newcommand{\modoffline}{\texttt{mod\_offline}}
|
||||
\newcommand{\modecho}{\texttt{mod\_echo}}
|
||||
\newcommand{\modprivate}{\texttt{mod\_private}}
|
||||
\newcommand{\modtime}{\texttt{mod\_time}}
|
||||
\newcommand{\modversion}{\texttt{mod\_version}}
|
||||
c
|
||||
%\setcounter{tocdepth}{3}
|
||||
|
||||
%% Title page
|
||||
\include{version}
|
||||
\title{Ejabberd \version\ Developers Guide}
|
||||
|
||||
\title{Ejabberd Developers Guide}
|
||||
\author{Alexey Shchepin \\
|
||||
\ahrefurl{mailto:alexey@sevcom.net} \\
|
||||
\ahrefurl{xmpp:aleksey@jabber.ru}}
|
||||
|
||||
%% Options
|
||||
\newcommand{\marking}[1]{#1} % Marking disabled
|
||||
\newcommand{\quoting}[2][yozhik]{} % Quotes disabled
|
||||
\newcommand{\new}{\begin{latexonly}\marginpar{\textsc{new}}\end{latexonly}} % Highlight new features
|
||||
\newcommand{\improved}{\begin{latexonly}\marginpar{\textsc{improved}}\end{latexonly}} % Highlight improved features
|
||||
\newcommand{\moreinfo}[1]{} % Hide details
|
||||
|
||||
%% Footnotes
|
||||
\newcommand{\txepref}[2]{\footahref{http://www.xmpp.org/extensions/xep-#1.html}{#2}}
|
||||
\newcommand{\xepref}[1]{\txepref{#1}{XEP-#1}}
|
||||
\date{September 10, 2003}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\label{titlepage}
|
||||
\begin{titlepage}
|
||||
\maketitle{}
|
||||
|
||||
\begin{center}
|
||||
{\insscaleimg{\logoscale}{logo.png}
|
||||
|
||||
{\centering
|
||||
\insscaleimg{\logoscale}{logo.png}
|
||||
\par
|
||||
}
|
||||
\end{center}
|
||||
|
||||
\begin{quotation}\textit{I can thoroughly recommend ejabberd for ease of setup --
|
||||
Kevin Smith, Current maintainer of the Psi project}\end{quotation}
|
||||
|
||||
\end{titlepage}
|
||||
|
||||
%\newpage
|
||||
\tableofcontents{}
|
||||
|
||||
% Input introduction.tex
|
||||
\input{introduction}
|
||||
\newpage
|
||||
\section{Introduction}
|
||||
\label{sec:intro}
|
||||
|
||||
\section{How it Works}
|
||||
\label{howitworks}
|
||||
\ejabberd{} is a Free and Open Source fault-tolerant distributed \Jabber{}
|
||||
server. It is writen mostly in Erlang.
|
||||
|
||||
The main features of \ejabberd{} is:
|
||||
\begin{itemize}
|
||||
\item Works on most of popular platforms: *nix (tested on Linux and FreeBSD)
|
||||
and Win32
|
||||
\item Distributed: You can run \ejabberd{} on a cluster of machines and all of
|
||||
them will serve one Jabber domain.
|
||||
\item Fault-tolerance: You can setup an \ejabberd{} cluster so that all the
|
||||
information required for a properly working service will be stored
|
||||
permanently on more than one node. This means that if one of the nodes
|
||||
crashes, then the others will continue working without disruption.
|
||||
You can also add or replace more nodes ``on the fly''.
|
||||
\item Built-in \footahref{http://www.jabber.org/jeps/jep-0045.html}{Multi-User
|
||||
Chat} service
|
||||
\item Built-in IRC transport
|
||||
\item Built-in
|
||||
\footahref{http://www.jabber.org/jeps/jep-0060.html}{Publish-Subscribe}
|
||||
service
|
||||
\item Built-in Jabber Users Directory service based on users vCards
|
||||
\item Support for
|
||||
\footahref{http://www.jabber.org/jeps/jep-0030.html}{JEP-0030}
|
||||
(Service Discovery).
|
||||
\item Support for
|
||||
\footahref{http://www.jabber.org/jeps/jep-0039.html}{JEP-0039}
|
||||
(Statistics Gathering).
|
||||
\item Support for \ns{xml:lang} attribute in many XML elements
|
||||
\end{itemize}
|
||||
|
||||
|
||||
A \XMPP{} domain is served by one or more \ejabberd{} nodes. These nodes can
|
||||
|
||||
|
||||
|
||||
\subsection{How it works}
|
||||
\label{sec:howitworks}
|
||||
|
||||
|
||||
|
||||
A \Jabber{} domain is served by one or more \ejabberd{} nodes. These nodes can
|
||||
be run on different machines that are connected via a network. They all must
|
||||
have the ability to connect to port 4369 of all another nodes, and must have
|
||||
the same magic cookie (see Erlang/OTP documentation, in other words the file
|
||||
@@ -120,9 +115,9 @@ Each \ejabberd{} node have following modules:
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\subsection{Router}
|
||||
\subsubsection{Router}
|
||||
|
||||
This module is the main router of \XMPP{} packets on each node. It routes
|
||||
This module is the main router of \Jabber{} packets on each node. It routes
|
||||
them based on their destinations domains. It has two tables: local and global
|
||||
routes. First, domain of packet destination searched in local table, and if it
|
||||
found, then the packet is routed to appropriate process. If no, then it
|
||||
@@ -131,24 +126,24 @@ process. If it does not exists in either tables, then it sent to the S2S
|
||||
manager.
|
||||
|
||||
|
||||
\subsection{Local Router}
|
||||
\subsubsection{Local Router}
|
||||
|
||||
This module routes packets which have a destination domain equal to this server
|
||||
name. If destination JID has a non-empty user part, then it routed to the
|
||||
session manager, else it is processed depending on it's content.
|
||||
|
||||
|
||||
\subsection{Session Manager}
|
||||
\subsubsection{Session Manager}
|
||||
|
||||
This module routes packets to local users. It searches for what user resource
|
||||
packet must be sent via presence table. If this resource is connected to
|
||||
packet must be sended via presence table. If this resource is connected to
|
||||
this node, it is routed to C2S process, if it connected via another node, then
|
||||
the packet is sent to session manager on that node.
|
||||
|
||||
|
||||
\subsection{S2S Manager}
|
||||
\subsubsection{S2S Manager}
|
||||
|
||||
This module routes packets to other \XMPP{} servers. First, it checks if an
|
||||
This module routes packets to other \Jabber{} servers. First, it checks if an
|
||||
open S2S connection from the domain of the packet source to the domain of
|
||||
packet destination already exists. If it is open on another node, then it
|
||||
routes the packet to S2S manager on that node, if it is open on this node, then
|
||||
@@ -156,83 +151,12 @@ it is routed to the process that serves this connection, and if a connection
|
||||
does not exist, then it is opened and registered.
|
||||
|
||||
|
||||
\section{Authentication}
|
||||
|
||||
\subsubsection{External}
|
||||
\label{externalauth}
|
||||
\ind{external authentication}
|
||||
|
||||
The external authentication script follows
|
||||
\footahref{http://www.erlang.org/doc/tutorial/c_portdriver.html}{the erlang port driver API}.
|
||||
\section{XML representation}
|
||||
\label{sec:xmlrepr}
|
||||
|
||||
That script is supposed to do theses actions, in an infinite loop:
|
||||
\begin{itemize}
|
||||
\item read from stdin: AABBBBBBBBB.....
|
||||
\begin{itemize}
|
||||
\item A: 2 bytes of length data (a short in network byte order)
|
||||
\item B: a string of length found in A that contains operation in plain text
|
||||
operation are as follows:
|
||||
\begin{itemize}
|
||||
\item auth:User:Server:Password (check if a username/password pair is correct)
|
||||
\item isuser:User:Server (check if it's a valid user)
|
||||
\item setpass:User:Server:Password (set user's password)
|
||||
\item tryregister:User:Server:Password (try to register an account)
|
||||
\item removeuser:User:Server (remove this account)
|
||||
\item removeuser3:User:Server:Password (remove this account if the password is correct)
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\item write to stdout: AABB
|
||||
\begin{itemize}
|
||||
\item A: the number 2 (coded as a short, which is bytes length of following result)
|
||||
\item B: the result code (coded as a short), should be 1 for success/valid, or 0 for failure/invalid
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
Example python script
|
||||
\begin{verbatim}
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
from struct import *
|
||||
|
||||
def from_ejabberd():
|
||||
input_length = sys.stdin.read(2)
|
||||
(size,) = unpack('>h', input_length)
|
||||
return sys.stdin.read(size).split(':')
|
||||
|
||||
def to_ejabberd(bool):
|
||||
answer = 0
|
||||
if bool:
|
||||
answer = 1
|
||||
token = pack('>hh', 2, answer)
|
||||
sys.stdout.write(token)
|
||||
sys.stdout.flush()
|
||||
|
||||
def auth(username, server, password):
|
||||
return True
|
||||
|
||||
def isuser(username, server):
|
||||
return True
|
||||
|
||||
def setpass(username, server, password):
|
||||
return True
|
||||
|
||||
while True:
|
||||
data = from_ejabberd()
|
||||
success = False
|
||||
if data[0] == "auth":
|
||||
success = auth(data[1], data[2], data[3])
|
||||
elif data[0] == "isuser":
|
||||
success = isuser(data[1], data[2])
|
||||
elif data[0] == "setpass":
|
||||
success = setpass(data[1], data[2], data[3])
|
||||
to_ejabberd(success)
|
||||
\end{verbatim}
|
||||
|
||||
\section{XML Representation}
|
||||
\label{xmlrepr}
|
||||
|
||||
Each XML stanza is represented as the following tuple:
|
||||
Each XML stanza represented as following tuple:
|
||||
\begin{verbatim}
|
||||
XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
||||
Name = string()
|
||||
@@ -245,14 +169,14 @@ XMLElement = {xmlelement, Name, Attrs, [ElementOrCDATA]}
|
||||
\end{verbatim}
|
||||
E.\,g. this stanza:
|
||||
\begin{verbatim}
|
||||
<message to='test@conference.example.org' type='groupchat'>
|
||||
<message to='test@conference.e.localhost' type='groupchat'>
|
||||
<body>test</body>
|
||||
</message>
|
||||
\end{verbatim}
|
||||
is represented as the following structure:
|
||||
represented as following structure:
|
||||
\begin{verbatim}
|
||||
{xmlelement, "message",
|
||||
[{"to", "test@conference.example.org"},
|
||||
[{"to", "test@conference.e.localhost"},
|
||||
{"type", "groupchat"}],
|
||||
[{xmlelement, "body",
|
||||
[],
|
||||
@@ -262,23 +186,23 @@ is represented as the following structure:
|
||||
|
||||
|
||||
\section{Module \texttt{xml}}
|
||||
\label{xmlmod}
|
||||
\label{sec:xmlmod}
|
||||
|
||||
\begin{description}
|
||||
\item{\verb|element_to_string(El) -> string()|}
|
||||
\item[\verb|element_to_string(El) -> string()|]
|
||||
\begin{verbatim}
|
||||
El = XMLElement
|
||||
\end{verbatim}
|
||||
Returns string representation of XML stanza \texttt{El}.
|
||||
|
||||
\item{\verb|crypt(S) -> string()|}
|
||||
\item[\verb|crypt(S) -> string()|]
|
||||
\begin{verbatim}
|
||||
S = string()
|
||||
\end{verbatim}
|
||||
Returns string which correspond to \texttt{S} with encoded XML special
|
||||
characters.
|
||||
|
||||
\item{\verb|remove_cdata(ECList) -> EList|}
|
||||
\item[\verb|remove_cdata(ECList) -> EList|]
|
||||
\begin{verbatim}
|
||||
ECList = [ElementOrCDATA]
|
||||
EList = [XMLElement]
|
||||
@@ -287,7 +211,7 @@ EList = [XMLElement]
|
||||
|
||||
|
||||
|
||||
\item{\verb|get_path_s(El, Path) -> Res|}
|
||||
\item[\verb|get_path_s(El, Path) -> Res|]
|
||||
\begin{verbatim}
|
||||
El = XMLElement
|
||||
Path = [PathItem]
|
||||
@@ -301,15 +225,15 @@ Res = string() | XMLElement
|
||||
If \texttt{Path} is empty, then returns \texttt{El}. Else sequentially
|
||||
consider elements of \texttt{Path}. Each element is one of:
|
||||
\begin{description}
|
||||
\item{\verb|{elem, Name}|} \texttt{Name} is name of subelement of
|
||||
\item[\verb|{elem, Name}|] \texttt{Name} is name of subelement of
|
||||
\texttt{El}, if such element exists, then this element considered in
|
||||
following steps, else returns empty string.
|
||||
\item{\verb|{attr, Name}|} If \texttt{El} have attribute \texttt{Name}, then
|
||||
\item[\verb|{attr, Name}|] If \texttt{El} have attribute \texttt{Name}, then
|
||||
returns value of this attribute, else returns empty string.
|
||||
\item{\verb|cdata|} Returns CDATA of \texttt{El}.
|
||||
\item[\verb|cdata|] Returns CDATA of \texttt{El}.
|
||||
\end{description}
|
||||
|
||||
\item{TODO:}
|
||||
\item[TODO:]
|
||||
\begin{verbatim}
|
||||
get_cdata/1, get_tag_cdata/1
|
||||
get_attr/2, get_attr_s/2
|
||||
@@ -319,63 +243,49 @@ Res = string() | XMLElement
|
||||
\end{description}
|
||||
|
||||
|
||||
\section{Module \texttt{xml\_stream}}
|
||||
\label{xmlstreammod}
|
||||
|
||||
\begin{description}
|
||||
\item{\verb!parse_element(Str) -> XMLElement | {error, Err}!}
|
||||
\begin{verbatim}
|
||||
Str = string()
|
||||
Err = term()
|
||||
\end{verbatim}
|
||||
Parses \texttt{Str} using XML parser, returns either parsed element or error
|
||||
tuple.
|
||||
\end{description}
|
||||
|
||||
|
||||
\section{Modules}
|
||||
\label{emods}
|
||||
\section{\ejabberd{} modules}
|
||||
\label{sec:emods}
|
||||
|
||||
|
||||
%\subsection{gen\_mod behaviour}
|
||||
%\label{genmod}
|
||||
\subsection{\verb|gen_mod| behaviour}
|
||||
\label{sec:genmod}
|
||||
|
||||
%TBD
|
||||
TBD
|
||||
|
||||
\subsection{Module gen\_iq\_handler}
|
||||
\label{geniqhandl}
|
||||
\subsection{Module \verb|gen_iq_handler|}
|
||||
\label{sec:geniqhandl}
|
||||
|
||||
The module \verb|gen_iq_handler| allows to easily write handlers for IQ packets
|
||||
of particular XML namespaces that addressed to server or to users bare JIDs.
|
||||
|
||||
In this module the following functions are defined:
|
||||
\begin{description}
|
||||
\item{\verb|add_iq_handler(Component, Host, NS, Module, Function, Type)|}
|
||||
\item[\verb|add_iq_handler(Component, NS, Module, Function, Type)|]
|
||||
\begin{verbatim}
|
||||
Component = Module = Function = atom()
|
||||
Host = NS = string()
|
||||
NS = string()
|
||||
Type = no_queue | one_queue | parallel
|
||||
\end{verbatim}
|
||||
Registers function \verb|Module:Function| as handler for IQ packets on
|
||||
virtual host \verb|Host| that contain child of namespace \verb|NS| in
|
||||
\verb|Component|. Queueing discipline is \verb|Type|. There are at least
|
||||
two components defined:
|
||||
Registers function \verb|Module:Function| as handler for IQ packets that
|
||||
contain child of namespace \verb|NS| in \verb|Component|. Queueing
|
||||
discipline is \verb|Type|. There are at least two components defined:
|
||||
\begin{description}
|
||||
\item{\verb|ejabberd_local|} Handles packets that addressed to server JID;
|
||||
\item{\verb|ejabberd_sm|} Handles packets that addressed to users bare JIDs.
|
||||
\item[\verb|ejabberd_local|] Handles packets that addressed to server JID;
|
||||
\item[\verb|ejabberd_sm|] Handles packets that addressed to users bare JIDs.
|
||||
\end{description}
|
||||
\item{\verb|remove_iq_handler(Component, Host, NS)|}
|
||||
\item[\verb|remove_iq_handler(Component, NS)|]
|
||||
\begin{verbatim}
|
||||
Component = atom()
|
||||
Host = NS = string()
|
||||
NS = string()
|
||||
\end{verbatim}
|
||||
Removes IQ handler on virtual host \verb|Host| for namespace \verb|NS| from
|
||||
\verb|Component|.
|
||||
Removes IQ handler for namespace \verb|NS| from \verb|Component|.
|
||||
\end{description}
|
||||
|
||||
Handler function must have the following type:
|
||||
\begin{description}
|
||||
\item{\verb|Module:Function(From, To, IQ)|}
|
||||
\item[\verb|Module:Function(From, To, IQ)|]
|
||||
\begin{verbatim}
|
||||
From = To = jid()
|
||||
\end{verbatim}
|
||||
@@ -388,8 +298,8 @@ From = To = jid()
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([start/2,
|
||||
stop/1,
|
||||
-export([start/1,
|
||||
stop/0,
|
||||
process_local_iq/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
@@ -397,13 +307,13 @@ From = To = jid()
|
||||
|
||||
-define(NS_CPUTIME, "ejabberd:cputime").
|
||||
|
||||
start(Host, Opts) ->
|
||||
start(Opts) ->
|
||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_CPUTIME,
|
||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_CPUTIME,
|
||||
?MODULE, process_local_iq, IQDisc).
|
||||
|
||||
stop(Host) ->
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_CPUTIME).
|
||||
stop() ->
|
||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_CPUTIME).
|
||||
|
||||
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
case Type of
|
||||
@@ -422,26 +332,25 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
|
||||
|
||||
|
||||
\subsection{Services}
|
||||
\label{services}
|
||||
\label{sec:services}
|
||||
|
||||
%TBD
|
||||
TBD
|
||||
|
||||
|
||||
%TODO: use \verb|proc_lib|
|
||||
TODO: use \verb|proc_lib|
|
||||
\begin{verbatim}
|
||||
-module(mod_echo).
|
||||
|
||||
-behaviour(gen_mod).
|
||||
|
||||
-export([start/2, init/1, stop/1]).
|
||||
-export([start/1, init/1, stop/0]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
start(Host, Opts) ->
|
||||
MyHost = gen_mod:get_opt(host, Opts, "echo." ++ Host),
|
||||
register(gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
spawn(?MODULE, init, [MyHost])).
|
||||
start(Opts) ->
|
||||
Host = gen_mod:get_opt(host, Opts, "echo." ++ ?MYNAME),
|
||||
register(ejabberd_mod_echo, spawn(?MODULE, init, [Host])).
|
||||
|
||||
init(Host) ->
|
||||
ejabberd_router:register_local_route(Host),
|
||||
@@ -453,16 +362,15 @@ loop(Host) ->
|
||||
ejabberd_router:route(To, From, Packet),
|
||||
loop(Host);
|
||||
stop ->
|
||||
ejabberd_router:unregister_route(Host),
|
||||
ejabberd_router:unregister_local_route(Host),
|
||||
ok;
|
||||
_ ->
|
||||
loop(Host)
|
||||
end.
|
||||
|
||||
stop(Host) ->
|
||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||
Proc ! stop,
|
||||
{wait, Proc}.
|
||||
stop() ->
|
||||
ejabberd_mod_echo ! stop,
|
||||
ok.
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 7.8 KiB |
@@ -1,132 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Ejabberd 2.1.12 Feature Sheet
|
||||
</TITLE>
|
||||
|
||||
<META http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<META name="GENERATOR" content="hevea 1.10">
|
||||
<STYLE type="text/css">
|
||||
.li-itemize{margin:1ex 0ex;}
|
||||
.li-enumerate{margin:1ex 0ex;}
|
||||
.dd-description{margin:0ex 0ex 1ex 4ex;}
|
||||
.dt-description{margin:0ex;}
|
||||
.toc{list-style:none;}
|
||||
.thefootnotes{text-align:left;margin:0ex;}
|
||||
.dt-thefootnotes{margin:0em;}
|
||||
.dd-thefootnotes{margin:0em 0em 0em 2em;}
|
||||
.footnoterule{margin:1em auto 1em 0px;width:50%;}
|
||||
.caption{padding-left:2ex; padding-right:2ex; margin-left:auto; margin-right:auto}
|
||||
.title{margin:2ex auto;text-align:center}
|
||||
.center{text-align:center;margin-left:auto;margin-right:auto;}
|
||||
.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
|
||||
.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
|
||||
DIV TABLE{margin-left:inherit;margin-right:inherit;}
|
||||
PRE{text-align:left;margin-left:0ex;margin-right:auto;}
|
||||
BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
|
||||
TD P{margin:0px;}
|
||||
.boxed{border:1px solid black}
|
||||
.textboxed{border:1px solid black}
|
||||
.vbar{border:none;width:2px;background-color:black;}
|
||||
.hbar{border:none;height:2px;width:100%;background-color:black;}
|
||||
.hfill{border:none;height:1px;width:200%;background-color:black;}
|
||||
.vdisplay{border-collapse:separate;border-spacing:2px;width:auto; empty-cells:show; border:2px solid red;}
|
||||
.vdcell{white-space:nowrap;padding:0px;width:auto; border:2px solid green;}
|
||||
.display{border-collapse:separate;border-spacing:2px;width:auto; border:none;}
|
||||
.dcell{white-space:nowrap;padding:0px;width:auto; border:none;}
|
||||
.dcenter{margin:0ex auto;}
|
||||
.vdcenter{border:solid #FF8000 2px; margin:0ex auto;}
|
||||
.minipage{text-align:left; margin-left:0em; margin-right:auto;}
|
||||
.marginpar{border:solid thin black; width:20%; text-align:left;}
|
||||
.marginparleft{float:left; margin-left:0ex; margin-right:1ex;}
|
||||
.marginparright{float:right; margin-left:1ex; margin-right:0ex;}
|
||||
.theorem{text-align:left;margin:1ex auto 1ex 0ex;}
|
||||
.part{margin:2ex auto;text-align:center}
|
||||
SPAN{width:20%; float:right; text-align:left; margin-left:auto;}
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<BODY >
|
||||
<!--HEVEA command line is: /usr/bin/hevea -fix -pedantic features.tex -->
|
||||
<!--CUT DEF section 1 --><P><A NAME="titlepage"></A>
|
||||
|
||||
</P><TABLE CLASS="title"><TR><TD><H1 CLASS="titlemain">Ejabberd 2.1.12 Feature Sheet</H1><H3 CLASS="titlerest">Sander Devrieze<BR>
|
||||
<A HREF="mailto:s.devrieze@pandora.be"><TT>mailto:s.devrieze@pandora.be</TT></A><BR>
|
||||
<A HREF="xmpp:sander@devrieze.dyndns.org"><TT>xmpp:sander@devrieze.dyndns.org</TT></A></H3></TD></TR>
|
||||
</TABLE><DIV CLASS="center">
|
||||
|
||||
<IMG SRC="logo.png" ALT="logo.png">
|
||||
|
||||
|
||||
</DIV><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>I can thoroughly recommend ejabberd for ease of setup –
|
||||
Kevin Smith, Current maintainer of the Psi project</I></FONT></BLOCKQUOTE><P>Introduction
|
||||
<A NAME="intro"></A></P><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>I just tried out ejabberd and was impressed both by ejabberd itself and the language it is written in, Erlang. —
|
||||
Joeri</I></FONT></BLOCKQUOTE><P><TT>ejabberd</TT> is a <B><FONT SIZE=4><FONT COLOR="#001376">free and open source</FONT></FONT></B> instant messaging server written in <A HREF="http://www.erlang.org/">Erlang/OTP</A>.</P><P><TT>ejabberd</TT> is <B><FONT SIZE=4><FONT COLOR="#001376">cross-platform</FONT></FONT></B>, distributed, fault-tolerant, and based on open standards to achieve real-time communication.</P><P><TT>ejabberd</TT> is designed to be a <B><FONT SIZE=4><FONT COLOR="#001376">rock-solid and feature rich</FONT></FONT></B> XMPP server.</P><P><TT>ejabberd</TT> is suitable for small deployments, whether they need to be <B><FONT SIZE=4><FONT COLOR="#001376">scalable</FONT></FONT></B> or not, as well as extremely big deployments.</P><!--TOC section Key Features-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc1"></A>Key Features</H2><!--SEC END --><P>
|
||||
<A NAME="keyfeatures"></A>
|
||||
</P><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>Erlang seems to be tailor-made for writing stable, robust servers. —
|
||||
Peter Saint-André, Executive Director of the Jabber Software Foundation</I></FONT></BLOCKQUOTE><P><TT>ejabberd</TT> is:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
<B><FONT SIZE=4><FONT COLOR="#001376">Cross-platform:</FONT></FONT></B> <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Distributed:</FONT></FONT></B> You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Fault-tolerant:</FONT></FONT></B> You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced ‘on the fly’.</LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Administrator Friendly:</FONT></FONT></B> <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Comprehensive documentation.
|
||||
</LI><LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows. </LI><LI CLASS="li-itemize">Web Administration.
|
||||
</LI><LI CLASS="li-itemize">Shared Roster Groups.
|
||||
</LI><LI CLASS="li-itemize">Command line administration tool. </LI><LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
|
||||
</LI><LI CLASS="li-itemize">Capability to send announce messages.
|
||||
</LI></UL></LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Internationalized:</FONT></FONT></B> <TT>ejabberd</TT> leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Translated to 25 languages. </LI><LI CLASS="li-itemize">Support for <A HREF="http://www.ietf.org/rfc/rfc3490.txt">IDNA</A>.
|
||||
</LI></UL></LI><LI CLASS="li-itemize"><B><FONT SIZE=4><FONT COLOR="#001376">Open Standards:</FONT></FONT></B> <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Fully XMPP compliant.
|
||||
</LI><LI CLASS="li-itemize">XML-based protocol.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.ejabberd.im/protocols">Many protocols supported</A>.
|
||||
</LI></UL></LI></UL><!--TOC section Additional Features-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc2"></A>Additional Features</H2><!--SEC END --><P>
|
||||
<A NAME="addfeatures"></A>
|
||||
</P><BLOCKQUOTE CLASS="quotation"><FONT COLOR="#921700"><I>ejabberd is making inroads to solving the "buggy incomplete server" problem —
|
||||
Justin Karneges, Founder of the Psi and the Delta projects</I></FONT></BLOCKQUOTE><P>Moreover, <TT>ejabberd</TT> comes with a wide range of other state-of-the-art features:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Modular
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Load only the modules you want.
|
||||
</LI><LI CLASS="li-itemize">Extend <TT>ejabberd</TT> with your own custom modules.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Security
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
SASL and STARTTLS for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
|
||||
</LI><LI CLASS="li-itemize">Web Admin accessible via HTTPS secure access.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Databases
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Internal database for fast deployment (Mnesia).
|
||||
</LI><LI CLASS="li-itemize">Native MySQL support.
|
||||
</LI><LI CLASS="li-itemize">Native PostgreSQL support.
|
||||
</LI><LI CLASS="li-itemize">ODBC data storage support.
|
||||
</LI><LI CLASS="li-itemize">Microsoft SQL Server support. </LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Authentication
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Internal Authentication.
|
||||
</LI><LI CLASS="li-itemize">PAM, LDAP and ODBC. </LI><LI CLASS="li-itemize">External Authentication script.
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-itemize">Others
|
||||
<UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Support for virtual hosting.
|
||||
</LI><LI CLASS="li-itemize">Compressing XML streams with Stream Compression (<A HREF="http://www.xmpp.org/extensions/xep-0138.html">XEP-0138</A>).
|
||||
</LI><LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>).
|
||||
</LI><LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0045.html">Multi-User Chat</A> module with support for clustering and HTML logging. </LI><LI CLASS="li-itemize">Users Directory based on users vCards.
|
||||
</LI><LI CLASS="li-itemize"><A HREF="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</A> component with support for <A HREF="http://www.xmpp.org/extensions/xep-0163.html">Personal Eventing via Pubsub</A>.
|
||||
</LI><LI CLASS="li-itemize">Support for web clients: <A HREF="http://www.xmpp.org/extensions/xep-0025.html">HTTP Polling</A> and <A HREF="http://www.xmpp.org/extensions/xep-0206.html">HTTP Binding (BOSH)</A> services.
|
||||
</LI><LI CLASS="li-itemize">IRC transport.
|
||||
</LI><LI CLASS="li-itemize">Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
|
||||
</LI></UL>
|
||||
</LI></UL><!--CUT END -->
|
||||
<!--HTMLFOOT-->
|
||||
<!--ENDHTML-->
|
||||
<!--FOOTER-->
|
||||
<HR SIZE=2><BLOCKQUOTE CLASS="quote"><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
|
||||
</EM><A HREF="http://hevea.inria.fr/index.html"><EM>H</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>V</EM><EM><FONT SIZE=2><sup>E</sup></FONT></EM><EM>A</EM></A><EM>.</EM></BLOCKQUOTE></BODY>
|
||||
</HTML>
|
||||
@@ -1,136 +0,0 @@
|
||||
\documentclass[a4paper,10pt]{article}
|
||||
|
||||
%% Packages
|
||||
\usepackage{epsfig}
|
||||
\usepackage{fancyhdr}
|
||||
\usepackage{graphics}
|
||||
\usepackage{hevea}
|
||||
\usepackage[pdftex,colorlinks,unicode,urlcolor=blue,linkcolor=blue,pdftitle=Ejabberd\
|
||||
Feature\ Sheet,pdfauthor=Sander\
|
||||
Devrieze,pdfsubject=ejabberd,pdfkeywords=ejabberd]{hyperref}
|
||||
\usepackage{verbatim}
|
||||
\usepackage{color}
|
||||
|
||||
%% Index
|
||||
% Remove the index anchors from the HTML version to save size and bandwith.
|
||||
\newcommand{\ind}[1]{\begin{latexonly}\index{#1}\end{latexonly}}
|
||||
|
||||
%% Images
|
||||
\newcommand{\logoscale}{0.7}
|
||||
\newcommand{\imgscale}{0.58}
|
||||
\newcommand{\insimg}[1]{\insscaleimg{\imgscale}{#1}}
|
||||
\newcommand{\insscaleimg}[2]{
|
||||
\imgsrc{#2}{}
|
||||
\begin{latexonly}
|
||||
\scalebox{#1}{\includegraphics{#2}}
|
||||
\end{latexonly}
|
||||
}
|
||||
|
||||
%% Various
|
||||
\newcommand{\bracehack}{\def\{{\char"7B}\def\}{\char"7D}}
|
||||
\newcommand{\titem}[1]{\item[\bracehack\texttt{#1}]}
|
||||
\newcommand{\ns}[1]{\texttt{#1}}
|
||||
\newcommand{\jid}[1]{\texttt{#1}}
|
||||
\newcommand{\option}[1]{\texttt{#1}}
|
||||
\newcommand{\poption}[1]{{\bracehack\texttt{#1}}}
|
||||
\newcommand{\node}[1]{\texttt{#1}}
|
||||
\newcommand{\term}[1]{\texttt{#1}}
|
||||
\newcommand{\shell}[1]{\texttt{#1}}
|
||||
\newcommand{\ejabberd}{\texttt{ejabberd}}
|
||||
\newcommand{\Jabber}{Jabber}
|
||||
|
||||
%% Title page
|
||||
\include{version}
|
||||
\title{Ejabberd \version\ Feature Sheet}
|
||||
\author{Sander Devrieze \\
|
||||
\ahrefurl{mailto:s.devrieze@pandora.be} \\
|
||||
\ahrefurl{xmpp:sander@devrieze.dyndns.org}}
|
||||
|
||||
% Options
|
||||
\newcommand{\marking}[1]{\textbf{\begin{large}\textcolor{ejblue}{#1}\end{large}}} % Marking enabled
|
||||
\newcommand{\quoting}[2][yozhik]{\begin{quotation}\textcolor{#1}{\textit{#2}}\end{quotation}} % Quotes enabled
|
||||
\newcommand{\new}{\marginpar{\textcolor{red}{\textsc{new}}}} % Highlight new features
|
||||
\newcommand{\improved}{\marginpar{\textcolor{orange}{\textsc{improved}}}} % Highlight improved features
|
||||
\setcounter{secnumdepth}{-1} % Disable section numbering
|
||||
|
||||
%% To by-pass errors in the HTML version.
|
||||
\newstyle{SPAN}{width:20\%; float:right; text-align:left; margin-left:auto;}
|
||||
\definecolor{orange} {cmyk}{0.000,0.333,1.000,0.000}
|
||||
|
||||
%% Footnotes
|
||||
\begin{latexonly}
|
||||
\global\parskip=9pt plus 3pt minus 1pt
|
||||
\global\parindent=0pt
|
||||
\gdef\ahrefurl#1{\href{#1}{\texttt{#1}}}
|
||||
\gdef\footahref#1#2{#2\footnote{\href{#1}{\texttt{#1}}}}
|
||||
\end{latexonly}
|
||||
\newcommand{\txepref}[2]{\footahref{http://www.xmpp.org/extensions/xep-#1.html}{#2}}
|
||||
\newcommand{\xepref}[1]{\txepref{#1}{XEP-#1}}
|
||||
|
||||
%% Fancy header
|
||||
\fancyhf{}
|
||||
\pagestyle{fancy}
|
||||
\rhead{\textcolor{ejblue}{The Expandable Jabber/XMPP Daemon.}}
|
||||
\renewcommand{\headrule}{{\color{ejblue}%
|
||||
\hrule width\headwidth height\headrulewidth \vskip-\headrulewidth}}
|
||||
\lhead{\setlength{\unitlength}{-6mm}
|
||||
\begin{picture}(0,0)
|
||||
\put(5.8,3.25){\includegraphics[width=1.3\textwidth]{yozhikheader.png}}
|
||||
\end{picture}}
|
||||
|
||||
% Official ejabberd colours
|
||||
\definecolor{ejblue} {cmyk}{1.000,0.831,0.000,0.537} %RGB: 0,0,118 HTML: 000076
|
||||
\definecolor{ejgreenyellow}{cmyk}{0.079,0.000,0.275,0.102} %RGB: 209,229,159 HTML: d1e59f
|
||||
\definecolor{ejgreendark} {cmyk}{0.131,0.000,0.146,0.220} %RGB: 166,199,162 HTML: a6c7a2
|
||||
\definecolor{ejgreen} {cmyk}{0.077,0.000,0.081,0.078} %RGB: 216,236,215 HTML: d8ecd7
|
||||
\definecolor{ejgreenwhite} {cmyk}{0.044,0.000,0.048,0.020} %RGB: 239,250,238 HTML: effaee
|
||||
\definecolor{yozhik} {cmyk}{0.000,0.837,1.000,0.424} %RGB: 147,0,0 HTML: 930000
|
||||
|
||||
\begin{document}
|
||||
|
||||
\label{titlepage}
|
||||
\begin{titlepage}
|
||||
\maketitle{}
|
||||
|
||||
\thispagestyle{empty}
|
||||
|
||||
\begin{center}
|
||||
{\insscaleimg{\logoscale}{logo.png}
|
||||
\par
|
||||
}
|
||||
\end{center}
|
||||
\quoting{I can thoroughly recommend ejabberd for ease of setup --
|
||||
Kevin Smith, Current maintainer of the Psi project}
|
||||
|
||||
\end{titlepage}
|
||||
|
||||
\newpage
|
||||
% Set the page counter to 2 so that the titlepage and the second page do not
|
||||
% have the same page number. This fixes the PDFLaTeX warning "destination with
|
||||
% the same identifier".
|
||||
\begin{latexonly}
|
||||
\setcounter{page}{2}
|
||||
\pagecolor{ejgreenwhite}
|
||||
\end{latexonly}
|
||||
|
||||
% Input introduction.tex
|
||||
\input{introduction}
|
||||
|
||||
\end{document}
|
||||
|
||||
%% TODO
|
||||
% * illustrations (e.g. screenshot from web interface)
|
||||
% * commented parts
|
||||
% * slides, guide and html version
|
||||
% * cleaning and improving LaTeX code
|
||||
% * key features: something like this (shorter)? (more focussed on Erlang now): "To reach the goal of high
|
||||
% availability, performance and clustering, ejabberd is written in Erlang, a programming language perfectly
|
||||
% suited for this. Besides that, some parts are written in C to also incude the advantages of this language. In
|
||||
% short, ejabberd is a perfect mix of mainly Erlang code, peppered with some C code to get the final touch!"
|
||||
% <picture of a cocktail>
|
||||
% * key features: saying that ejabberd the only XMPP server is that can do real clustering:
|
||||
% http://www.jivesoftware.org/forums/thread.jspa?threadID=14602
|
||||
% "What I find interesting is that *no* XMPP servers truly provide clustering. This includes all the commercial
|
||||
% servers. The one partial exception appears to be ejabberd, which can cluster certain data such as sessions,
|
||||
% but not all services such as MUC."
|
||||
% * try it today: links to migration tutorials
|
||||
@@ -1,133 +0,0 @@
|
||||
\chapter{Introduction}
|
||||
\label{intro}
|
||||
|
||||
%% TODO: improve the feature sheet with a nice table to highlight new features.
|
||||
|
||||
\quoting{I just tried out ejabberd and was impressed both by ejabberd itself and the language it is written in, Erlang. ---
|
||||
Joeri}
|
||||
|
||||
%ejabberd is a free and open source instant messaging server written in Erlang. ejabberd is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication (Jabber/XMPP).
|
||||
|
||||
\ejabberd{} is a \marking{free and open source} instant messaging server written in \footahref{http://www.erlang.org/}{Erlang/OTP}.
|
||||
|
||||
\ejabberd{} is \marking{cross-platform}, distributed, fault-tolerant, and based on open standards to achieve real-time communication.
|
||||
|
||||
\ejabberd{} is designed to be a \marking{rock-solid and feature rich} XMPP server.
|
||||
|
||||
\ejabberd{} is suitable for small deployments, whether they need to be \marking{scalable} or not, as well as extremely big deployments.
|
||||
|
||||
%\subsection{Layout with example deployment (title needs a better name)}
|
||||
%\label{layout}
|
||||
|
||||
%In this section there will be a graphical overview like these:\\
|
||||
%\verb|http://www.tipic.com/var/timp/timp_dep.gif| \\
|
||||
%\verb|http://www.jabber.com/images/jabber_Com_Platform.jpg| \\
|
||||
%\verb|http://www.antepo.com/files/OPN45systemdatasheet.pdf| \\
|
||||
|
||||
%A page full with names of Jabber client that are known to work with ejabberd. \begin{tiny}tiny font\end{tiny}
|
||||
|
||||
%\subsection{Try It Today}
|
||||
%\label{trytoday}
|
||||
|
||||
%(Not sure if I will include/finish this section for the next version.)
|
||||
|
||||
%\begin{itemize}
|
||||
%\item Erlang REPOS
|
||||
%\item Packages in distributions
|
||||
%\item Windows binary
|
||||
%\item source tar.gz
|
||||
%\item Migration from Jabberd14 (and so also Jabberd2 because you can migrate from version 2 back to 14) and Jabber Inc. XCP possible.
|
||||
%\end{itemize}
|
||||
|
||||
\newpage
|
||||
\section{Key Features}
|
||||
\label{keyfeatures}
|
||||
\ind{features!key features}
|
||||
|
||||
\quoting{Erlang seems to be tailor-made for writing stable, robust servers. ---
|
||||
Peter Saint-Andr\'e, Executive Director of the Jabber Software Foundation}
|
||||
|
||||
\ejabberd{} is:
|
||||
\begin{itemize}
|
||||
\item \marking{Cross-platform:} \ejabberd{} runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.
|
||||
|
||||
\item \marking{Distributed:} You can run \ejabberd{} on a cluster of machines and all of them will serve the same \Jabber{} domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.
|
||||
|
||||
\item \marking{Fault-tolerant:} You can deploy an \ejabberd{} cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced `on the fly'.
|
||||
|
||||
\item \marking{Administrator Friendly:} \ejabberd{} is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
|
||||
\begin{itemize}
|
||||
\item Comprehensive documentation.
|
||||
\item Straightforward installers for Linux, Mac OS X, and Windows. %%\improved{}
|
||||
\item Web Administration.
|
||||
\item Shared Roster Groups.
|
||||
\item Command line administration tool. %%\improved{}
|
||||
\item Can integrate with existing authentication mechanisms.
|
||||
\item Capability to send announce messages.
|
||||
\end{itemize}
|
||||
|
||||
\item \marking{Internationalized:} \ejabberd{} leads in internationalization. Hence it is very well suited in a globalized world. Related features are:
|
||||
\begin{itemize}
|
||||
\item Translated to 25 languages. %%\improved{}
|
||||
\item Support for \footahref{http://www.ietf.org/rfc/rfc3490.txt}{IDNA}.
|
||||
\end{itemize}
|
||||
|
||||
\item \marking{Open Standards:} \ejabberd{} is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
|
||||
\begin{itemize}
|
||||
\item Fully XMPP compliant.
|
||||
\item XML-based protocol.
|
||||
\item \footahref{http://www.ejabberd.im/protocols}{Many protocols supported}.
|
||||
\end{itemize}
|
||||
|
||||
\end{itemize}
|
||||
|
||||
\newpage
|
||||
|
||||
\section{Additional Features}
|
||||
\label{addfeatures}
|
||||
\ind{features!additional features}
|
||||
|
||||
\quoting{ejabberd is making inroads to solving the "buggy incomplete server" problem ---
|
||||
Justin Karneges, Founder of the Psi and the Delta projects}
|
||||
|
||||
Moreover, \ejabberd{} comes with a wide range of other state-of-the-art features:
|
||||
\begin{itemize}
|
||||
\item Modular
|
||||
\begin{itemize}
|
||||
\item Load only the modules you want.
|
||||
\item Extend \ejabberd{} with your own custom modules.
|
||||
\end{itemize}
|
||||
\item Security
|
||||
\begin{itemize}
|
||||
\item SASL and STARTTLS for c2s and s2s connections.
|
||||
\item STARTTLS and Dialback s2s connections.
|
||||
\item Web Admin accessible via HTTPS secure access.
|
||||
\end{itemize}
|
||||
\item Databases
|
||||
\begin{itemize}
|
||||
\item Internal database for fast deployment (Mnesia).
|
||||
\item Native MySQL support.
|
||||
\item Native PostgreSQL support.
|
||||
\item ODBC data storage support.
|
||||
\item Microsoft SQL Server support. %%\new{}
|
||||
\end{itemize}
|
||||
\item Authentication
|
||||
\begin{itemize}
|
||||
\item Internal Authentication.
|
||||
\item PAM, LDAP and ODBC. %%\improved{}
|
||||
\item External Authentication script.
|
||||
\end{itemize}
|
||||
\item Others
|
||||
\begin{itemize}
|
||||
\item Support for virtual hosting.
|
||||
\item Compressing XML streams with Stream Compression (\xepref{0138}).
|
||||
\item Statistics via Statistics Gathering (\xepref{0039}).
|
||||
\item IPv6 support both for c2s and s2s connections.
|
||||
\item \txepref{0045}{Multi-User Chat} module with support for clustering and HTML logging. %%\improved{}
|
||||
\item Users Directory based on users vCards.
|
||||
\item \txepref{0060}{Publish-Subscribe} component with support for \txepref{0163}{Personal Eventing via Pubsub}.
|
||||
\item Support for web clients: \txepref{0025}{HTTP Polling} and \txepref{0206}{HTTP Binding (BOSH)} services.
|
||||
\item IRC transport.
|
||||
\item Component support: interface with networks such as AIM, ICQ and MSN installing special tranports.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 21 KiB |
@@ -1,62 +0,0 @@
|
||||
Release notes
|
||||
ejabberd 0.9.1
|
||||
|
||||
This document describes the main changes from [25]ejabberd 0.9.
|
||||
|
||||
The code can be downloaded from the [26]download page.
|
||||
|
||||
For more detailed information, please refer to ejabberd [27]User Guide.
|
||||
|
||||
|
||||
Groupchat (Multi-user chat and IRC) improvements
|
||||
|
||||
The multi-user chat code has been improved to comply with the latest version
|
||||
of Jabber Enhancement Proposal 0045.
|
||||
|
||||
The IRC (Internet Relay Chat) features now support WHOIS and USERINFO
|
||||
requests.
|
||||
|
||||
|
||||
Web interface
|
||||
|
||||
ejabberd modules management features have been added to the web interface.
|
||||
They now allow to start or stop extension module without restarting the
|
||||
ejabberd server.
|
||||
|
||||
|
||||
Publish and subscribe
|
||||
|
||||
It is now possible to a subscribe node with a JabberID that includes a
|
||||
resource.
|
||||
|
||||
|
||||
Translations
|
||||
|
||||
A new script has been included to help translate ejabberd into new languages
|
||||
and maintain existing translations.
|
||||
|
||||
As a result, ejabberd is now translating into 10 languages:
|
||||
* Dutch
|
||||
* English
|
||||
* French
|
||||
* German
|
||||
* Polish
|
||||
* Portuguese
|
||||
* Russian
|
||||
* Spanish
|
||||
* Swedish
|
||||
* Ukrainian
|
||||
|
||||
|
||||
Migration
|
||||
|
||||
No changes have been made to the database. No particular conversion steps
|
||||
are needed. However, you should backup your database before upgrading to a
|
||||
new ejabberd version.
|
||||
|
||||
|
||||
Bugfixes
|
||||
|
||||
This release contains several bugfixes and architectural changes. Please
|
||||
refer to the Changelog file supplied with this release for details of all
|
||||
improvements in the ejabberd code.
|
||||
@@ -1,99 +0,0 @@
|
||||
Release notes
|
||||
ejabberd 0.9.8
|
||||
2005-08-01
|
||||
|
||||
This document describes the main changes in ejabberd 0.9.8. This
|
||||
version prepares the way for the release of ejabberd 1.0, which
|
||||
is due later this year.
|
||||
|
||||
The code can be downloaded from the Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
|
||||
For more detailed information, please refer to ejabberd User Guide
|
||||
on the Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/docs.html
|
||||
|
||||
|
||||
Recent changes include....
|
||||
|
||||
|
||||
Enhanced virtual hosting
|
||||
|
||||
Virtual hosting applies to many more setting options and
|
||||
features and is transparent. Virtual hosting accepts different
|
||||
parameters for different virtual hosts regarding the following
|
||||
features: authentication method, access control lists and access
|
||||
rules, users management, statistics, and shared roster. The web
|
||||
interface gives access to each virtual host's parameters.
|
||||
|
||||
|
||||
Enhanced Publish-Subscribe module
|
||||
|
||||
ejabberd's Publish-Subscribe module integrates enhancements
|
||||
coming from J-EAI, an XMPP-based integration server built on
|
||||
ejabberd. ejabberd thus supports Publish-Subscribe node
|
||||
configuration. It is possible to define nodes that should be
|
||||
persistent, and the number of items to persist. Besides that, it
|
||||
is also possible to define various notification parameters, such
|
||||
as the delivery of the payload with the notifications, and the
|
||||
notification of subscribers when some changes occur on items.
|
||||
Other examples are: the maximum size of the items payload, the
|
||||
subscription approvers, the limitation of the notification to
|
||||
online users only, etc.
|
||||
|
||||
|
||||
Code reorganisation and update
|
||||
|
||||
- The mod_register module has been cleaned up.
|
||||
- ODBC support has been updated and several bugs have been fixed.
|
||||
|
||||
|
||||
Development API
|
||||
|
||||
To ease the work of Jabber/XMPP developers, a filter_packet hook
|
||||
has been added. As a result it is possible to develop plugins to
|
||||
filter or modify packets flowing through ejabberd.
|
||||
|
||||
|
||||
Translations
|
||||
|
||||
- Translations have been updated to support the new Publish-Subscribe features.
|
||||
- A new Brazilian Portuguese translation has been contributed.
|
||||
|
||||
|
||||
Web interface
|
||||
|
||||
- The CSS stylesheet from the web interface is W3C compliant.
|
||||
|
||||
|
||||
Installers
|
||||
|
||||
Installers are provided for Microsoft Windows and Linux/x86. The
|
||||
Linux installer includes Erlang ASN.1 modules for LDAP
|
||||
authentication support.
|
||||
|
||||
|
||||
Bugfixes
|
||||
|
||||
- This release contains several bugfixes and architectural
|
||||
changes. Among other bugfixes include improvements in LDAP
|
||||
authentication. Please refer to the ChangeLog file supplied
|
||||
with this release regarding all improvements in ejabberd.
|
||||
|
||||
|
||||
References
|
||||
|
||||
The ejabberd feature sheet helps comparing with other Jabber/XMPP
|
||||
servers:
|
||||
http://www.process-one.net/en/projects/ejabberd/docs/features.pdf
|
||||
|
||||
Contributed tutorials of interest are:
|
||||
- Migration from Jabberd1.4 to ejabberd:
|
||||
http://ejabberd.jabber.ru/jabberd1-to-ejabberd
|
||||
- Migration from Jabberd2 to ejabberd:
|
||||
http://ejabberd.jabber.ru/jabberd2-to-ejabberd
|
||||
- Transport configuration for connecting to other networks:
|
||||
http://ejabberd.jabber.ru/tutorials-transports
|
||||
|
||||
END
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
Release notes
|
||||
ejabberd 0.9
|
||||
|
||||
This document describes the major new features of and changes to
|
||||
ejabberd 0.9, compared to latest public release ejabber 0.7.5.
|
||||
|
||||
For more detailed information, please refer to ejabberd User
|
||||
Guide.
|
||||
|
||||
|
||||
Virtual Hosting
|
||||
|
||||
ejabberd now can host several domain on the same instance.
|
||||
This option is enabled by using:
|
||||
|
||||
{hosts, ["erlang-projects.org", "erlang-fr.org"]}.
|
||||
|
||||
instead of the previous host directive.
|
||||
|
||||
Note that you are now using a list of hosts. The main one should
|
||||
be the first listed. See migration section further in this release
|
||||
note for details.
|
||||
|
||||
|
||||
Shared Roster
|
||||
|
||||
Shared roster is a new feature that allow the ejabberd
|
||||
administrator to add jabber user that will be present in the
|
||||
roster of every users on the server.
|
||||
Shared roster are enabled by adding:
|
||||
|
||||
{mod_shared_roster, []}
|
||||
|
||||
at the end of your module list in your ejabberd.cfg file.
|
||||
|
||||
|
||||
PostgreSQL (ODBC) support
|
||||
|
||||
This feature is experimental and not yet properly documented. This
|
||||
feature is released for testing purpose.
|
||||
|
||||
You need to have Erlang/OTP R10 to compile with ODBC on various
|
||||
flavour of *nix. You should use Erlang/OTP R10B-4, as this task
|
||||
has became easier with this release. It comes already build in
|
||||
Erlang/OTP Microsoft Windows binary.
|
||||
|
||||
PostgreSQL support is enabled by using the following module in
|
||||
ejabberd.cfg instead of their standard counterpart:
|
||||
|
||||
mod_last_odbc.erl
|
||||
mod_offline_odbc.erl
|
||||
mod_roster_odbc.erl
|
||||
|
||||
The database schema is located in the src/odbc/pq.sql file.
|
||||
|
||||
Look at the src/ejabberd.cfg.example file for more information on
|
||||
how to configure ejabberd with odbc support. You can get support
|
||||
on how to configure ejabberd with a relational database.
|
||||
|
||||
|
||||
Migration from ejabberd 0.7.5
|
||||
|
||||
Migration is pretty straightforward as Mnesia database schema
|
||||
conversions is handled automatically. Remember however that you
|
||||
must backup your ejabberd database before migration.
|
||||
|
||||
Here are the following steps to proceed:
|
||||
|
||||
1. Stop your instance of ejabberd.
|
||||
|
||||
2. In ejabberd.cfg, define the host lists. Change the host
|
||||
directive to the hosts one:
|
||||
Before:
|
||||
{host, "erlang-projects.org"}.
|
||||
After:
|
||||
{hosts, ["erlang-projects.org", "erlang-fr.org"]}.
|
||||
Note that when you restart the server the existing users will be
|
||||
affected to the first virtual host, so the order is important. You
|
||||
should keep the previous hostname as the first virtual host.
|
||||
|
||||
3. Restart ejabberd.
|
||||
|
||||
|
||||
Bugfixes
|
||||
|
||||
This release contains several bugfixes and architectural changes.
|
||||
Please refer to the Changelog file supplied with this release for
|
||||
details of all improvements in the ejabberd code.
|
||||
@@ -1,120 +0,0 @@
|
||||
Release Notes
|
||||
ejabberd 1.0.0
|
||||
14 December 2005
|
||||
|
||||
This document describes the main changes in ejabberd 1.0.0. Unique in this
|
||||
version is the compliancy with the XMPP (eXtensible Messaging and Presence
|
||||
Protocol) standard. ejabberd is the first Open Source Jabber server claiming
|
||||
to fully comply to the XMPP standard.
|
||||
|
||||
ejabberd can be downloaded from the Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
|
||||
Detailed information can be found in the ejabberd Feature Sheet and User
|
||||
Guide which are available on the Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/docs.html
|
||||
|
||||
|
||||
Recent changes include:
|
||||
|
||||
|
||||
Server-to-server Encryption for Enhanced Security
|
||||
|
||||
- Support for STARTTLS and SASL EXTERNAL to secure server-to-server traffic
|
||||
has been added.
|
||||
- Also, STARTTLS and Dialback has been implemented for server-to-server (s2s)
|
||||
connections. Detailed information about these new features can be found on
|
||||
http://ejabberd.jabber.ru/s2s-encryption
|
||||
- commonName and dNSName fields matching were introduced to ease the process
|
||||
of retrieving certificates.
|
||||
- Different certificates can be defined for each virtual host.
|
||||
|
||||
ODBC Support
|
||||
|
||||
- ODBC support has been improved to allow production use of ejabberd with
|
||||
relational databases.
|
||||
- Support for vCard storage in ODBC has been added.
|
||||
- ejd2odbc.erl is a tool to convert an installation from Erlang's database
|
||||
Mnesia to an ODBC compatible relational database.
|
||||
|
||||
Native PostgreSQL Support
|
||||
|
||||
- Native PostgreSQL support gives you a better performance when you use
|
||||
PostgreSQL.
|
||||
|
||||
Shared Roster groups
|
||||
|
||||
- Shared Roster groups support has been enhanced. New is the ability to add
|
||||
all registered users to everyone's roster. Detailed information about this
|
||||
new feature can be found on http://ejabberd.jabber.ru/shared-roster-all
|
||||
|
||||
Web Interface
|
||||
|
||||
- The web interface internal code has been modified for better integration
|
||||
and compliancy with J-EAI, an ejabberd-based Enterprise Application
|
||||
Integration platform.
|
||||
- More XHTML 1.0 Transitional compliancy work was done.
|
||||
|
||||
Transports
|
||||
|
||||
- A transport workaround can be enabled during compilation. To do this, you
|
||||
can pass the "--enable-roster-gateway-workaround" option to the configure
|
||||
script. (./configure --enable-roster-gateway-workaround)
|
||||
This option allows transports to add items with subscription "to" in the
|
||||
roster by sending <presence type='subscribed'/> stanza to user. This option
|
||||
is only needed for JIT ICQ transport.
|
||||
Warning: by enabling this option, ejabberd will not be fully XMPP compliant
|
||||
anymore.
|
||||
|
||||
Documentation and Internationalization
|
||||
|
||||
- Documentation has been extended to cover more topics.
|
||||
- Translations have been updated.
|
||||
|
||||
Bugfixes
|
||||
|
||||
- This release contains several bugfixes.
|
||||
- Among other bugfixes include improvements to the client-to-server (c2s)
|
||||
connection management module.
|
||||
- Please refer to the ChangeLog file supplied
|
||||
with this release regarding all improvements in ejabberd.
|
||||
|
||||
|
||||
Installation Notes
|
||||
|
||||
|
||||
Supported Erlang Version
|
||||
|
||||
- You need at least Erlang/OTP R9C to run ejabberd 1.0.0.
|
||||
|
||||
Installation
|
||||
|
||||
Installers are provided for Microsoft Windows and Linux/x86.
|
||||
Installers can be retrieved from:
|
||||
http://www.process-one.net/en/projects/ejabberd/download.html
|
||||
|
||||
Migration Notes
|
||||
|
||||
- Before any migration, ejabberd system and database must be properly
|
||||
backed up.
|
||||
- When upgrading an ODBC-based installation, you will need to change the
|
||||
relational database schema. The following SQL commands must be run on the
|
||||
database:
|
||||
CREATE SEQUENCE spool_seq_seq;
|
||||
ALTER TABLE spool ADD COLUMN seq integer;
|
||||
ALTER TABLE spool ALTER COLUMN seq SET DEFAULT nextval('spool_seq_seq');
|
||||
UPDATE spool SET seq = DEFAULT;
|
||||
ALTER TABLE spool ALTER COLUMN seq SET NOT NULL;
|
||||
|
||||
References
|
||||
|
||||
Contributed tutorials of interest are:
|
||||
- Migration from Jabberd1.4 to ejabberd:
|
||||
http://ejabberd.jabber.ru/jabberd1-to-ejabberd
|
||||
- Migration from Jabberd2 to ejabberd:
|
||||
http://ejabberd.jabber.ru/jabberd2-to-ejabberd
|
||||
- Transport configuration for connecting to other networks:
|
||||
http://ejabberd.jabber.ru/tutorials-transports
|
||||
|
||||
END
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
Release Notes
|
||||
ejabberd 1.1.0
|
||||
24 April 2006
|
||||
|
||||
This document describes the main changes in ejabberd 1.1.0. This version
|
||||
introduce new features including support for new Jabber Enhancement
|
||||
Proposals and several performance improvements enabling deployments on an
|
||||
even larger scale than already possible.
|
||||
|
||||
ejabberd can be downloaded from the Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
|
||||
Detailed information can be found in the ejabberd Feature Sheet and User
|
||||
Guide which are available on the Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/docs.html
|
||||
|
||||
A complete list of changes is available from:
|
||||
http://support.process-one.net/secure/ReleaseNote.jspa?projectId=10011&styleName=Html&version=10025
|
||||
|
||||
|
||||
Recent changes include:
|
||||
|
||||
|
||||
New Jabber Enhancement Proposal support:
|
||||
|
||||
- JEP-0050: Ad-Hoc Commands.
|
||||
- JEP-0138: Stream Compression.
|
||||
- JEP-0175: SASL anonymous.
|
||||
|
||||
Anonymous login
|
||||
|
||||
- SASL anonymous.
|
||||
- Anonymous login for clients that do not yet support SASL Anonymous.
|
||||
|
||||
Relational database Support
|
||||
|
||||
- MySQL is now fully supported through ODBC and in native mode.
|
||||
- Various improvements to the native database interfaces.
|
||||
- The migration tool can use relational databases.
|
||||
|
||||
Multi-User Chat improvements
|
||||
|
||||
- Logging of room discussion to text file is now supported.
|
||||
- Better reconfiguration support.
|
||||
- Security oriented fixes.
|
||||
- Several improvements and updates to latest JEP-0045.
|
||||
|
||||
Performance scalability improvements for large clusters
|
||||
|
||||
- Improved session synchronisation management between cluster nodes.
|
||||
- Internal architecture has been reworked to use generalize Erlang/OTP
|
||||
framework usage.
|
||||
- Speed improvement on logger.
|
||||
- TCP/IP packet reception change for better network throttling and
|
||||
regulation.
|
||||
As a result, these improvements will reduce load on large scale deployments.
|
||||
|
||||
XMPP Protocol related improvements
|
||||
|
||||
- XML stanza size can be limited.
|
||||
- Messages are send to all resources with the same highest priority.
|
||||
|
||||
Documentation and Internationalization
|
||||
|
||||
- Documentation has been extended to cover more topics.
|
||||
- Translations have been updated.
|
||||
|
||||
Web interface
|
||||
|
||||
- XHTML 1.0 compliance.
|
||||
|
||||
Bugfixes
|
||||
|
||||
- This release contains many bugfixes on various areas such as Publish-Subscribe, build
|
||||
chain, installers, IRC gateway, ejabberdctl, amongst others.
|
||||
- Please refer to the ChangeLog file supplied with this release regarding
|
||||
all improvements in ejabberd.
|
||||
|
||||
|
||||
|
||||
Installation Notes
|
||||
|
||||
Supported Erlang Version
|
||||
|
||||
- You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.0.
|
||||
|
||||
Installation
|
||||
|
||||
Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC.
|
||||
Installers can be retrieved from:
|
||||
http://www.process-one.net/en/projects/ejabberd/download.html
|
||||
|
||||
Migration Notes
|
||||
|
||||
- Before any migration, ejabberd system and database must be properly
|
||||
backed up.
|
||||
- The database schema has not been changed comparing to version 1.0.0 and
|
||||
consequently it does not require any migration.
|
||||
|
||||
|
||||
References
|
||||
|
||||
Contributed tutorials and documents of interest are:
|
||||
- Migration from Jabberd1.4, Jabberd2 and WPJabber to ejabberd:
|
||||
http://ejabberd.jabber.ru/migrate-to-ejabberd
|
||||
- Transport configuration for connecting to other networks:
|
||||
http://ejabberd.jabber.ru/tutorials-transports
|
||||
- Using ejabberd with MySQL native driver:
|
||||
http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver
|
||||
- Anonymous User Support:
|
||||
http://support.process-one.net/doc/display/MESSENGER/Anonymous+users+support
|
||||
- Frequently Asked Questions:
|
||||
http://ejabberd.jabber.ru/faq
|
||||
|
||||
END
|
||||
@@ -1,119 +0,0 @@
|
||||
Release Notes
|
||||
ejabberd 1.1.1
|
||||
28 April 2006
|
||||
|
||||
This document describes the main changes in ejabberd 1.1.x. This version
|
||||
introduce new features including support for new Jabber Enhancement
|
||||
Proposals and several performance improvements enabling deployments on an
|
||||
even larger scale than already possible.
|
||||
|
||||
This release fix a security issue introduced in ejabberd 1.1.0. In SASL
|
||||
mode, anonymous login was enabled as a default. Upgrading ejabberd 1.1.0 to
|
||||
ejabberd 1.1.1 is highly recommended.
|
||||
|
||||
ejabberd can be downloaded from the Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
|
||||
Detailed information can be found in the ejabberd Feature Sheet and User
|
||||
Guide which are available on the Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/docs.html
|
||||
|
||||
A complete list of changes is available from:
|
||||
http://support.process-one.net/secure/ReleaseNote.jspa?projectId=10011&styleName=Html&version=10025
|
||||
|
||||
|
||||
Recent changes include:
|
||||
|
||||
|
||||
New Jabber Enhancement Proposal support:
|
||||
|
||||
- JEP-0050: Ad-Hoc Commands.
|
||||
- JEP-0138: Stream Compression.
|
||||
- JEP-0175: SASL anonymous.
|
||||
|
||||
Anonymous login
|
||||
|
||||
- SASL anonymous.
|
||||
- Anonymous login for clients that do not yet support SASL Anonymous.
|
||||
|
||||
Relational database Support
|
||||
|
||||
- MySQL is now fully supported through ODBC and in native mode.
|
||||
- Various improvements to the native database interfaces.
|
||||
- The migration tool can use relational databases.
|
||||
|
||||
Multi-User Chat improvements
|
||||
|
||||
- Logging of room discussion to text file is now supported.
|
||||
- Better reconfiguration support.
|
||||
- Security oriented fixes.
|
||||
- Several improvements and updates to latest JEP-0045.
|
||||
|
||||
Performance scalability improvements for large clusters
|
||||
|
||||
- Improved session synchronisation management between cluster nodes.
|
||||
- Internal architecture has been reworked to use generalize Erlang/OTP
|
||||
framework usage.
|
||||
- Speed improvement on logger.
|
||||
- TCP/IP packet reception change for better network throttling and
|
||||
regulation.
|
||||
As a result, these improvements will reduce load on large scale deployments.
|
||||
|
||||
XMPP Protocol related improvements
|
||||
|
||||
- XML stanza size can be limited.
|
||||
- Messages are send to all resources with the same highest priority.
|
||||
|
||||
Documentation and Internationalization
|
||||
|
||||
- Documentation has been extended to cover more topics.
|
||||
- Translations have been updated.
|
||||
|
||||
Web interface
|
||||
|
||||
- XHTML 1.0 compliance.
|
||||
|
||||
Bugfixes
|
||||
|
||||
- This release contains many bugfixes on various areas such as Publish-Subscribe, build
|
||||
chain, installers, IRC gateway, ejabberdctl, amongst others.
|
||||
- Please refer to the ChangeLog file supplied with this release regarding
|
||||
all improvements in ejabberd.
|
||||
|
||||
|
||||
|
||||
Installation Notes
|
||||
|
||||
Supported Erlang Version
|
||||
|
||||
- You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.0.
|
||||
|
||||
Installation
|
||||
|
||||
Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC.
|
||||
Installers can be retrieved from:
|
||||
http://www.process-one.net/en/projects/ejabberd/download.html
|
||||
|
||||
Migration Notes
|
||||
|
||||
- Before any migration, ejabberd system and database must be properly
|
||||
backed up.
|
||||
- The database schema has not been changed comparing to version 1.0.0 and
|
||||
consequently it does not require any migration.
|
||||
|
||||
|
||||
References
|
||||
|
||||
Contributed tutorials and documents of interest are:
|
||||
- Migration from Jabberd1.4, Jabberd2 and WPJabber to ejabberd:
|
||||
http://ejabberd.jabber.ru/migrate-to-ejabberd
|
||||
- Transport configuration for connecting to other networks:
|
||||
http://ejabberd.jabber.ru/tutorials-transports
|
||||
- Using ejabberd with MySQL native driver:
|
||||
http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver
|
||||
- Anonymous User Support:
|
||||
http://support.process-one.net/doc/display/MESSENGER/Anonymous+users+support
|
||||
- Frequently Asked Questions:
|
||||
http://ejabberd.jabber.ru/faq
|
||||
|
||||
END
|
||||
@@ -1,119 +0,0 @@
|
||||
Release Notes
|
||||
ejabberd 1.1.2
|
||||
27 September 2006
|
||||
|
||||
This document describes the main changes in ejabberd 1.1.2.
|
||||
|
||||
This version is a major improvement over ejabberd 1.1.1, improving the
|
||||
overall behaviour of the server in many areas. Users of ejabberd 1.1.1
|
||||
should upgrade to this new release for improved robustness and compliance.
|
||||
|
||||
ejabberd can be downloaded from the Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
|
||||
Detailed information can be found in the Feature Sheet and in the
|
||||
Installation and Operation Guide which are both available on the
|
||||
Process-one website:
|
||||
http://www.process-one.net/en/projects/ejabberd/docs.html
|
||||
|
||||
ejabberd includes 44 improvements. A complete list of changes can be
|
||||
retrieved from:
|
||||
http://redir.process-one.net/ejabberd-1.1.2
|
||||
|
||||
|
||||
Recent changes include:
|
||||
|
||||
LDAP Improvements
|
||||
|
||||
- Major improvements have been made on the LDAP module. It is now more
|
||||
flexible and more robust.
|
||||
|
||||
HTTP Polling Fixes
|
||||
|
||||
- The HTTP polling modules have been fixed and improved: the connections are
|
||||
closed properly and polled messages cannot be lost anymore.
|
||||
|
||||
Roster Management Improvement
|
||||
|
||||
- Roster management improvements increase reliability, especially in cases
|
||||
where users are on different servers.
|
||||
- Shared rosters are more reliable.
|
||||
|
||||
Improved Robustness
|
||||
|
||||
- It is now possible to limit the number of opened connections for a single
|
||||
user.
|
||||
|
||||
Relational databases
|
||||
|
||||
- Database support: Microsoft SQL Server is now officially supported in ODBC
|
||||
mode.
|
||||
|
||||
Publish-Subscribe Improvement
|
||||
|
||||
- Restricting node creation with a dedicated ACL rule is now possible.
|
||||
|
||||
Localization
|
||||
|
||||
- A Czech translation has been added.
|
||||
- Translations have been updated.
|
||||
|
||||
Binary Installer
|
||||
|
||||
- New binary installer for Windows including all requirements.
|
||||
- Improved installers for Linux and MacOSX (PowerPC)
|
||||
|
||||
XMPP Compliancy
|
||||
|
||||
- Some protocol compliance fix have been added, after the Portland XMPP
|
||||
Interop Meeting in July.
|
||||
|
||||
Miscelanous
|
||||
|
||||
- MUC have been improved (logging rendering).
|
||||
- The command line tool ejabberdctl has been improved.
|
||||
- The build chain has been improved, including MacOSX support.
|
||||
- The documentation has been improved and updated to describe the new
|
||||
features.
|
||||
|
||||
Bugfixes
|
||||
|
||||
- Anonymous login bugfixes.
|
||||
- Please refer to the ChangeLog file supplied with this release regarding
|
||||
all improvements in ejabberd.
|
||||
|
||||
|
||||
Installation Notes
|
||||
|
||||
Supported Erlang Version
|
||||
|
||||
- You need at least Erlang/OTP R9C-2 to run ejabberd 1.1.2.
|
||||
- The recommanded version is Erlang/OTP R10B-10.
|
||||
- Erlang/OTP R11B has not yet been fully certified for ejabberd.
|
||||
|
||||
Installation
|
||||
|
||||
Installers are provided for Microsoft Windows, Linux/x86 and MacOSX/PPC.
|
||||
They can be retrieved from:
|
||||
http://www.process-one.net/en/projects/ejabberd/download.html
|
||||
|
||||
Migration Notes
|
||||
|
||||
- Before any migration, ejabberd system and database must be properly
|
||||
backed up.
|
||||
- The relational database schema has changed between version 1.1.1 and
|
||||
1.1.2. An "askmessage" column needs to be added in the "rosterusers" table
|
||||
to perform the migration.
|
||||
|
||||
|
||||
References
|
||||
|
||||
Contributed tutorials and documents of interest are:
|
||||
- Migration from other XMPP servers to ejabberd:
|
||||
http://ejabberd.jabber.ru/migrate-to-ejabberd
|
||||
- Transport configuration for connecting to other networks:
|
||||
http://ejabberd.jabber.ru/tutorials-transports
|
||||
- Frequently Asked Questions:
|
||||
http://ejabberd.jabber.ru/faq
|
||||
|
||||
END
|
||||
@@ -1,14 +0,0 @@
|
||||
Release Notes
|
||||
ejabberd 1.1.3
|
||||
2 February 2007
|
||||
|
||||
ejabberd 1.1.3 is a security fix release for ejabberd roster ODBC
|
||||
module.
|
||||
|
||||
The upgrade is only necessary if you are using ejabberd with the
|
||||
mod_roster_odbc.
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
|
||||
END
|
||||
@@ -1,31 +0,0 @@
|
||||
Release Notes
|
||||
ejabberd 1.1.4
|
||||
3 september 2007
|
||||
|
||||
ejabberd 1.1.4 is a bugfix release for ejabberd 1.1.x branch.
|
||||
|
||||
ejabberd 1.1.4 includes 10 improvements. A complete list of changes
|
||||
can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-1.1.4
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
|
||||
|
||||
Recent changes include:
|
||||
|
||||
- Better LDAP support.
|
||||
- Support for UTF-8 with MySQL 5.
|
||||
- Roster migration script bugfixes.
|
||||
- Performance improvements on user removal.
|
||||
- Traffic shapers bugfix.
|
||||
- Configuration: host value is now case insensitive.
|
||||
- Build: ejabberd.cfg file is not overwritten with 'make install' command.
|
||||
|
||||
|
||||
Bugs report
|
||||
|
||||
You can officially report bugs on Process-one support site:
|
||||
http://support.process-one.net/
|
||||
|
||||
END
|
||||
@@ -1,208 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.0.0
|
||||
21 February 2008
|
||||
|
||||
ejabberd 2.0.0 is a major new version for ejabberd adding plenty of
|
||||
new features, performance and scalability improvements and
|
||||
architectural changes.
|
||||
|
||||
ejabberd 2.0.0 includes more than 200 improvements over ejabberd
|
||||
1.1.x. A complete list of changes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.0.0
|
||||
|
||||
The new code can be downloaded from ejabberd downloads page:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
Recent changes include:
|
||||
|
||||
|
||||
* Clustering and Architecture
|
||||
|
||||
- New front-end and back-end cluster architecture for better
|
||||
scalability and robustness. Back-end nodes are able to run a fully
|
||||
fault-tolerant XMPP router and services, but you can now deploy
|
||||
many front-end nodes to share the load without needing to synchronize
|
||||
any state with the back-ends.
|
||||
- All components now run in cluster mode (For example, Multi-User chat
|
||||
service and file transfer proxy).
|
||||
- New load balancing algorithm to support Multi-User chat and gateways
|
||||
clustering. More generally it supports any external component load
|
||||
balancing.
|
||||
- ejabberd watchdog to receive warning on suspicious resources consumption.
|
||||
- Traffic shapers are now supported on components. This protect
|
||||
ejabberd from components and gateways abuses.
|
||||
|
||||
|
||||
* Publish and Subscribe
|
||||
|
||||
- Complete rewrite of the PubSub module. The new PubSub module is
|
||||
plugin-based, allowing developers to create new nodes type. Any
|
||||
application can be plugged to ejabberd and can provide rich presence
|
||||
as a pubsub plugin.
|
||||
- Personal Eventing via Pubsub support (XEP-0163). This module is
|
||||
implemented as a PubSub service. It supports user mood (XEP-107),
|
||||
User Tune (XEP-118), user location (XEP-0080) or user avatar
|
||||
(XEP-0084) for example.
|
||||
|
||||
|
||||
* Server to Server (s2s)
|
||||
|
||||
- More robust code with connection timeout implementation.
|
||||
- Support for multiple s2s connections per domain.
|
||||
- s2s whitelist and blacklist support.
|
||||
- s2s retrial interval.
|
||||
|
||||
|
||||
* LDAP
|
||||
|
||||
- Many enterprise-class enhancements such as better behaviour under
|
||||
heavy load.
|
||||
- Support for LDAP servers pool.
|
||||
- Simplified use of virtual hosting with LDAP with domain substitution
|
||||
in config.
|
||||
- Ability to match on several userid attributes.
|
||||
|
||||
|
||||
* Multi-User Chat
|
||||
|
||||
- Clustering and load balancing support.
|
||||
- Ability to define default room configuration in ejabberd config file.
|
||||
- Many anti abuse features have been added:
|
||||
. New ACL to limit the creation of persistent room to authorized users.
|
||||
. Ability to define the maximum number of users per room.
|
||||
. Limitation of the rate of message and presence packets.
|
||||
. Limitation of the maximum number of room a user can join at the same time.
|
||||
|
||||
|
||||
* File Transfer
|
||||
|
||||
- XEP-0065 - Proxy65 file transfer proxy. The proxy can run in
|
||||
cluster mode.
|
||||
|
||||
|
||||
* Authentication
|
||||
|
||||
- PAM (Pluggable Authentication Modules) support on *nix systems.
|
||||
- External Authentication protocol is now fully documented.
|
||||
|
||||
|
||||
* Web Client Support
|
||||
|
||||
- XEP-0124 - BOSH support: BOSH (Bidirectional-streams Over
|
||||
Synchronous HTTP) was formerly known as "HTTP binding". It provides
|
||||
an efficient alternative to HTTP polling for scalable Web based chat
|
||||
solutions.
|
||||
- HTTP module can now serve static documents (with
|
||||
mod_http_fileserver). It is needed for high-performance Web 2.0 chat
|
||||
/ IM application. System administrators can now avoid using a proxy
|
||||
(like Apache) that handles much less simultaneous than ejabberd HTTP
|
||||
module.
|
||||
- Added limitations enforcement on HTTP poll and HTTP bind modules
|
||||
(bandwidth, packet size).
|
||||
|
||||
|
||||
* System Administration
|
||||
|
||||
- XEP-0133 - Service administration support. System administrators can
|
||||
now perform lot of ejabberd related admin tasks from their XMPP
|
||||
client, through adhoc commands.
|
||||
- Dynamic log levels: Improved logging with more log levels. You can
|
||||
now change the loglevel at run time. No performance penalty is
|
||||
involved when less verbose levels are used.
|
||||
- The ejabberdctl command-line administration script now can start
|
||||
and stop ejabberd. It also includes other useful options.
|
||||
|
||||
|
||||
* Localization
|
||||
|
||||
- ejabberd is now translated to 24 languages: Catalan, Chinese, Czech,
|
||||
Dutch, English, Esperanto, French, Galician, German, Italian, Japanese,
|
||||
Norwegian, Polish, Portuguese, Portuguese (Brazil), Russian, Slovak,
|
||||
Spanish, Swedish, Thai, Turkish, Ukrainian, Vietnamese, Walloon.
|
||||
|
||||
|
||||
* Build and Installer
|
||||
|
||||
- Many launch script improvements.
|
||||
- New translations. The binary installer is now available in Chinese,
|
||||
Dutch, English, French, German, Spanish, Russian.
|
||||
- Makefile now implements uninstall command.
|
||||
- Full MacOSX compliance in Makefile.
|
||||
- Configure script is clever at finding libraries in unusual places.
|
||||
|
||||
|
||||
* Development API
|
||||
|
||||
- Several hooks have been added for module developers (most notably
|
||||
presence related hooks).
|
||||
- HTTP request handler to write HTTP based plugins.
|
||||
- Manage connections IP address.
|
||||
|
||||
|
||||
* Bugfixes
|
||||
|
||||
- ejabberd 2.0.0 also fixes numerous small bugs :) Read the full
|
||||
changelog for details.
|
||||
|
||||
|
||||
|
||||
Important Note:
|
||||
|
||||
- Since this release, ejabberd requires Erlang R10B-5 or higher.
|
||||
R11B-5 is the recommended version. R12 is not yet officially
|
||||
supported, and is not recommended for production servers.
|
||||
|
||||
|
||||
|
||||
Upgrading From ejabberd 1.x:
|
||||
|
||||
- If you upgrade from a version older than 1.1.4, please check the
|
||||
Release Notes of the intermediate versions for additional
|
||||
information about database or configuration changes.
|
||||
|
||||
- The database schemas didn't change since ejabberd 1.1.4. Of course,
|
||||
you are encouraged to make a database backup of your SQL database,
|
||||
or your Mnesia spool directory before upgrading ejabberd.
|
||||
|
||||
- The ejabberdctl command line administration script is improved in
|
||||
ejabberd 2.0.0, and now it can start and stop ejabberd. If you
|
||||
already wrote your own start script for ejabberd 1.x, you can
|
||||
continue using it, or try ejabberdctl. For your convenience, the
|
||||
ejabberd Guide describes all the ejabberd and Erlang options used by
|
||||
ejabberdctl.
|
||||
|
||||
- The example ejabberd.cfg file has been reorganized, but its format
|
||||
and syntax rules are the same. So, you can continue using your
|
||||
ejabberd.cfg file from 1.x if you want. The most important changes
|
||||
are described now.
|
||||
|
||||
- The 'ssl' option is no longer available in the listening ports. For
|
||||
legacy SSL encryption use the option 'tls'. For STARTTLS encryption
|
||||
as defined in RFC 3920 XMPP-CORE use the option 'starttls'. Check
|
||||
the ejabberd Guide for more information about configuring listening
|
||||
ports.
|
||||
|
||||
- The options 'welcome_message' and 'registration_watchers' are now
|
||||
options of the module mod_register. Check in the ejabberd Guide how
|
||||
to configure that module.
|
||||
|
||||
- To enable PEP support in mod_pubsub, you need to enable it in the
|
||||
mod_pubsub configuration, and also enable the new module
|
||||
mod_caps. Check the section about mod_pubsub in the ejabberd Guide.
|
||||
|
||||
- Other new features and improvements also require changes in the
|
||||
ejabberd.cfg, like mod_http_bind, mod_http_fileserver, mod_proxy65,
|
||||
loglevel, pam_service, and watchdog_admins. Search for those words
|
||||
in the ejabberd Guide and the example ejabberd.cfg.
|
||||
|
||||
|
||||
|
||||
Bug Reports
|
||||
|
||||
You can officially report bugs on Process-one support site:
|
||||
https://support.process-one.net/
|
||||
|
||||
|
||||
END
|
||||
@@ -1,30 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.0.1
|
||||
20 May 2008
|
||||
|
||||
ejabberd 2.0.1 is a bugfix release for ejabberd 2.0.x branch.
|
||||
|
||||
ejabberd 2.0.1 includes 10 improvements and 32 bugfixes.
|
||||
A complete list of changes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.0.1
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/projects/ejabberd/
|
||||
|
||||
|
||||
Recent changes include:
|
||||
|
||||
- Erlang R12 support.
|
||||
- Better LDAP handling.
|
||||
- PubSub bugfixes.
|
||||
- Documentation improvements.
|
||||
- inband registration limitation per IP.
|
||||
- s2s improvements.
|
||||
|
||||
Bugs report
|
||||
|
||||
You can officially report bugs on Process-one support site:
|
||||
http://support.process-one.net/
|
||||
|
||||
END
|
||||
@@ -1,34 +0,0 @@
|
||||
|
||||
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
|
||||
@@ -1,35 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.0.3
|
||||
14 January 2009
|
||||
|
||||
ejabberd 2.0.3 is the third bugfix release for ejabberd 2.0.x branch.
|
||||
|
||||
ejabberd 2.0.3 includes several bugfixes and a few improvements.
|
||||
A complete list of changes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.0.3
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
Recent changes include:
|
||||
|
||||
- Do not ask certificate for client (c2s)
|
||||
- Check digest-uri in SASL digest authentication
|
||||
- Use send timeout to avoid locking on gen_tcp:send
|
||||
- Fix ejabberd reconnection to database
|
||||
- HTTP-Bind: handle wrong order of packets
|
||||
- MUC: Improve traffic regulation management
|
||||
- PubSub: Several bugfixes and improvements for best coverage of XEP-0060 v1.12
|
||||
- Shared Roster Groups: push immediately membership changes
|
||||
- Rotate also sasl.log on "reopen-log" command
|
||||
- Binary Windows installer: better detect "Error running Post Install Script"
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
|
||||
END
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.0.4
|
||||
|
||||
ejabberd 2.0.4 is the fourth bugfix release for ejabberd 2.0.x branch.
|
||||
|
||||
ejabberd 2.0.4 includes several bugfixes.
|
||||
A detailed list of changes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.0.4
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
The changes are:
|
||||
|
||||
- Ensure ID attribute in roster push is unique
|
||||
- Authentication: Fix Anonymous auth when enabled with broken ODBC
|
||||
- Authentication: Unquote correctly backslash in DIGEST-MD5 SASL responses
|
||||
- Authentication: Cancel presence subscriptions on account deletion
|
||||
- LDAP: Close a connection on tcp_error
|
||||
- LDAP: Implemented queue for pending queries
|
||||
- LDAP: On failure of LDAP connection, waiting is done on pending queue
|
||||
- MUC: Owner of a password protected room must also provide the password
|
||||
- MUC: Prevent XSS in MUC logs by linkifying only a few known protocols
|
||||
- Privacy rules: Items are now processed in the specified order
|
||||
- Privacy rules: Fix to correctly block subscription requests
|
||||
- Proxy65: If ip option is not defined, take an IP address of a local hostname
|
||||
- PubSub: Add roster subscription handling; send PEP events to all resources
|
||||
- PubSub: Allow node creation without configure item
|
||||
- PubSub: Requesting items on a node which exists, but empty returns an error
|
||||
- PEP: Fix sending notifications to other domains and s2s
|
||||
- S2S: Fix problem with encrypted connection to Gtalk and recent Openfire
|
||||
- S2S: Workaround to get DNS SRV lookup to work on Windows machine
|
||||
- Shared Roster Groups: Fix to not resend authorization request
|
||||
- WebAdmin: Fix encryption problem for ejabberd_http after timeout
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
|
||||
END
|
||||
@@ -1,33 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.0.5
|
||||
|
||||
ejabberd 2.0.5 is the fifth bugfix release in ejabberd 2.0.x branch.
|
||||
|
||||
ejabberd 2.0.5 includes three bugfixes.
|
||||
More details of those fixes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.0.5
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
The changes are:
|
||||
|
||||
- Fix two problems introduced in ejabberd 2.0.4: subscription request
|
||||
produced many authorization requests with some clients and
|
||||
transports; and subscription requests were not stored for later
|
||||
delivery when receiver was offline.
|
||||
|
||||
- Fix warning in expat_erl.c about implicit declaration of x_fix_buff
|
||||
|
||||
- HTTP-Bind (BOSH): Fix a missing stream:error in the returned
|
||||
remote-stream-error stanza
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
|
||||
END
|
||||
@@ -1,281 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.0
|
||||
|
||||
ejabberd 2.1.0 is a major new version for ejabberd adding many
|
||||
new features, performance and scalability improvements.
|
||||
|
||||
ejabberd 2.1.0 includes many new features, improvements and bug fixes.
|
||||
A complete list of changes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.1.0
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
New features and improvements:
|
||||
|
||||
* Anti-abuse
|
||||
- Captcha support (XEP-0158). The example script uses ImageMagick.
|
||||
- New option: registration_timeout to limit registrations by time
|
||||
- Use send timeout to avoid locking on gen_tcp:send
|
||||
- mod_ip_blacklist: client blacklist support by IP
|
||||
|
||||
* API
|
||||
- ejabberd_http provides Host, Port, Headers and Protocol in HTTP requests
|
||||
- Export function to create MUC room
|
||||
- New events: s2s_send_packet and s2s_receive_packet
|
||||
- New event: webadmin_user_parse_query when POST in web admin user page
|
||||
- Support distributed hooks over the cluster
|
||||
|
||||
* Authentification
|
||||
- Extauth responses: log strange responses and add timeout
|
||||
|
||||
* Binary Installer
|
||||
- Includes exmpp library to support import/export XML files
|
||||
|
||||
* Caps
|
||||
- Remove useless caps tables entries
|
||||
- mod_caps must handle correctly external contacts with several resources
|
||||
- Complain if mod_caps disabled and mod_pubsub has PEP plugin enabled
|
||||
|
||||
* Clustering and Architecture
|
||||
|
||||
* Configuration
|
||||
- Added option access_max_user_messages for mod_offline
|
||||
- Added option backlog for ejabberd_listener to increase TCP backlog
|
||||
- Added option define_macro and use_macro
|
||||
- Added option include_config_file to include additional configuration files
|
||||
- Added option max_fsm_queue
|
||||
- Added option outgoing_s2s_options to define IP address families and timeout
|
||||
- Added option registration_timeout to ejabberd.cfg.example
|
||||
- Added option s2s_dns_options to define DNS timeout and retries
|
||||
- Added option ERL_OPTIONS to ejabberdctl.cfg
|
||||
- Added option FIREWALL_WINDOW to ejabberdctl.cfg
|
||||
- Added option EJABBERD_PID_PATH to ejabberdctl.cfg
|
||||
- Deleted option user_max_messages of mod_offline
|
||||
- Check certfiles are readable on server start and listener start
|
||||
- Config file management mix file reading and sanity check
|
||||
- Include example PAM configuration file: ejabberd.pam
|
||||
- New ejabberd listener: ejabberd_stun
|
||||
- Support to bind the same port to multiple interfaces
|
||||
- New syntax to specify the IP address and IPv6 in listeners
|
||||
configuration. The old options {ip,{1,2,3,4}} and inet6 are
|
||||
supported even if they aren't documented.
|
||||
- New syntax to specify the network protocol: tcp or udp
|
||||
- Report error at startup if a listener module isn't available
|
||||
- Only listen in a port when actually ready to serve requests
|
||||
- In default config, only local accounts can create rooms and PubSub nodes
|
||||
|
||||
* Core architecture
|
||||
- More verbose error reporting for xml:element_to_string
|
||||
- Deliver messages when first presence is Invisible
|
||||
- Better log message when config file is not found
|
||||
- Include original timestamp on delayed presences
|
||||
|
||||
* Crypto
|
||||
- Do not ask certificate for client (c2s)
|
||||
- SSL code remove from ejabberd in favor of TLS
|
||||
- Support Zlib compression after STARTTLS encryption
|
||||
- tls v1 client hello
|
||||
|
||||
* Documentation
|
||||
- Document possible default MUC room options
|
||||
- Document service_check_from in the Guide
|
||||
- Document s2s_default_policy and s2s_host in the Guide
|
||||
- new command and guide instructions to change node name in a Mnesia database
|
||||
|
||||
* ejabberd commands
|
||||
- ejabberd commands: separate command definition and calling interface
|
||||
- access_commands restricts who can execute what commands and arguments
|
||||
- ejabberdctl script now displays help and categorization of commands
|
||||
|
||||
* HTTP Binding and HTTP Polling
|
||||
- HTTP-Bind: module optimization and clean-up
|
||||
- HTTP-Bind: allow configuration of max_inactivity timeout
|
||||
- HTTP-Poll: turn session timeout into a config file parameter
|
||||
|
||||
* Jingle
|
||||
- STUN server that facilitates the client-to-client negotiation process
|
||||
|
||||
* LDAP
|
||||
- Faster reconnection to LDAP servers
|
||||
- LDAP filter optimisation: Add ability to filter user in ejabberd and not LDAP
|
||||
- LDAP differentiates failed auth and unavailable auth service
|
||||
- Improve LDAP logging
|
||||
- LDAPS support using TLS.
|
||||
|
||||
* Localization
|
||||
- Use Gettext PO for translators, export to ejabberd MSG
|
||||
- Support translation files for additional projects
|
||||
- Most translations are updated to latest code
|
||||
- New translation to Greek language
|
||||
|
||||
* Multi-User Chat (MUC)
|
||||
- Allow admins to send messages to rooms
|
||||
- Allow to store room description
|
||||
- Captcha support in MUC: the admin of a room can configure it to
|
||||
require participants to fill a captcha to join the room.
|
||||
- Limit number of characters in Room ID, Name and Description
|
||||
- Prevent unvoiced occupants from changing nick
|
||||
- Support Result Set Management (XEP-0059) for listing rooms
|
||||
- Support for decline of invitation to MUC room
|
||||
- mod_muc_log options: plaintext format; filename with only room name
|
||||
|
||||
* Performance
|
||||
- Run roster_get_jid_info only if privacy list has subscription or group item
|
||||
- Significant PubSub performance improvements
|
||||
|
||||
* Publish-Subscribe
|
||||
- Add nodetree filtering/authorization
|
||||
- Add subscription option support for collection nodes
|
||||
- Allow Multiple Subscriptions
|
||||
- Check option of the nodetree instead of checking configuration
|
||||
- Implement whitelist authorize and roster access model
|
||||
- Implicit item deletion is not notified when deleting node
|
||||
- Make PubSub x-data configuration form handles list value
|
||||
- Make default node name convention XEP-compatible, document usage of hierarchy
|
||||
- Node names are used verbatim, without separating by slash, unless a
|
||||
node plugin uses its own separator
|
||||
- Send authorization update event (XEP-0060, 8.6)
|
||||
- Support of collection node subscription options
|
||||
- Support ODBC storage. Experimental, needs more testing.
|
||||
|
||||
* Relational databases:
|
||||
- Added MSSQL 2000 and 2005
|
||||
- Privacy rules storage in MySQL
|
||||
- Implement reliable ODBC transaction nesting
|
||||
|
||||
* Source Package
|
||||
- Default installation directories changed. Please see the upgrade notes below.
|
||||
- Allow more environment variable overrides in ejabberdctl
|
||||
- ChangeLog is not edited manually anymore; it's generated automatically.
|
||||
- Install the ejabberd Guide
|
||||
- Install the ejabberd include files
|
||||
- New option for the 'configure' script: --enable-user which installs
|
||||
ejabberd granting permission to manage it to a regular system user;
|
||||
no need to use root account to.
|
||||
- Only try to install epam if pam was enabled in configure script
|
||||
- Spool, config and log dirs: owner writes, group reads, others do nothing.
|
||||
- Provides an example ejabberd.init file
|
||||
|
||||
* S2S
|
||||
- Option to define s2s outgoing behaviour: IPv4, IPv6 and timeout
|
||||
- DNS timeout and retries, configurable with s2s_dns_options.
|
||||
|
||||
* Shared rosters
|
||||
- When a member is added/removed to group, send roster upgrade to group members
|
||||
|
||||
* Users management
|
||||
- When account is deleted, cancel presence subscription for all roster items
|
||||
|
||||
* XEP Support
|
||||
- Added XEP-0059 Result Set Management (for listing rooms)
|
||||
- Added XEP-0082 Date Time
|
||||
- Added XEP-0085 Chat State Notifications
|
||||
- Added XEP-0157 Contact Addresses for XMPP Services
|
||||
- Added XEP-0158 CAPTCHA Forms (in MUC rooms)
|
||||
- Added STUN server, for XEP-0176: Jingle ICE-UDP Transport Method
|
||||
- Added XEP-0199 XMPP Ping
|
||||
- Added XEP-0202 Entity Time
|
||||
- Added XEP-0203 Delayed Delivery
|
||||
- Added XEP-0227 Portable Import/Export Format for XMPP-IM Servers
|
||||
- Added XEP-0237 Roster Versioning
|
||||
|
||||
* Web Admin
|
||||
- Display the connection method of user sessions
|
||||
- Cross link of ejabberd users in the list of users and rosters
|
||||
- Improved the browsing menu: don't disappear when browsing a host or node
|
||||
- Include Last-Modified HTTP header in responses to allow caching
|
||||
- Make some Input areas multiline: options of listening ports and modules
|
||||
- Support PUT and DELETE methods in ejabberd_http
|
||||
- WebAdmin serves Guide and links to related sections
|
||||
|
||||
* Web plugins
|
||||
- mod_http_fileserver: new option directory_indices, and improve logging
|
||||
|
||||
|
||||
Important Notes:
|
||||
|
||||
- ejabberd 2.1.0 requires Erlang R10B-9 or higher.
|
||||
R12B-5 is the recommended version. Support for R13B is experimental.
|
||||
|
||||
|
||||
Upgrading From ejabberd 1.x.x:
|
||||
|
||||
- Check the Release Notes of the intermediate versions for additional
|
||||
information about database or configuration changes.
|
||||
|
||||
|
||||
Upgrading From ejabberd 2.0.x:
|
||||
|
||||
- The database schemas have three changes since ejabberd 2.0.x.
|
||||
Check the database creation SQL files and update your database.
|
||||
1) New table roster_version to support roster versioning.
|
||||
2) Six new tables for optional pubsub ODBC storage.
|
||||
3) Some tables in the MySQL database have a new created_at column.
|
||||
|
||||
- As usual, it is recommended to backup the Mnesia spool directory and
|
||||
your SQL database (if used) before upgrading ejabberd.
|
||||
|
||||
- Between ejabberd 2.0.0 and 2.0.5, mod_pubsub used "default" as the
|
||||
default node plugin. But in 2.1.0 this is renamed to "hometree".
|
||||
You have to edit your ejabberd config file and replace those names.
|
||||
If you used ejabberd 2.0.5 or older, the database will be updated
|
||||
automatically. But if you were using ejabberd from SVN, you must
|
||||
manually run ejabberdctl with the command: rename_default_nodeplugin.
|
||||
Running this command on already updated database does nothing.
|
||||
|
||||
- The listener options 'ip' and 'inet6' are not documented anymore
|
||||
but they are supported and you can continue using them.
|
||||
There is a new syntax to define IP address and IP version.
|
||||
As usual, check the ejabberd Guide for more information.
|
||||
|
||||
- The log file sasl.log is now called erlang.log
|
||||
|
||||
- ejabberdctl commands now have _ characters instead of -.
|
||||
For backwards compatibility, it is still supported -.
|
||||
|
||||
- mod_offline has a new option: access_max_user_messages.
|
||||
The old option user_max_messages is no longer supported.
|
||||
|
||||
- If you upgrade from ejabberd trunk SVN, you must execute this:
|
||||
$ ejabberdctl rename_default_nodeplugin
|
||||
|
||||
- Default installation directories changed a bit:
|
||||
* The Mnesia spool files that were previously stored in
|
||||
/var/lib/ejabberd/db/NODENAME/*
|
||||
are now stored in
|
||||
/var/lib/ejabberd/*
|
||||
* The directories
|
||||
/var/lib/ejabberd/ebin
|
||||
/var/lib/ejabberd/priv
|
||||
and their content is now installed as
|
||||
/lib/ejabberd/ebin
|
||||
/lib/ejabberd/priv
|
||||
* There is a new directory with Erlang header files:
|
||||
/lib/ejabberd/include
|
||||
* There is a new directory for ejabberd documentation,
|
||||
which includes the Admin Guide and the release notes::
|
||||
/share/doc/ejabberd
|
||||
|
||||
- How to upgrade from previous version to ejabberd 2.1.0:
|
||||
1. Stop the old instance of ejabberd.
|
||||
2. Run 'make install' of new ejabberd 2.1.0 to create the new directories.
|
||||
3. Copy the content of your old directory:
|
||||
/var/lib/ejabberd/db/NODENAME/
|
||||
to the new location:
|
||||
/var/lib/ejabberd/
|
||||
so you will have the files like this:
|
||||
/var/lib/ejabberd/acl.DCD ...
|
||||
4. You can backup the content of those directories and delete them:
|
||||
/var/lib/ejabberd/ebin
|
||||
/var/lib/ejabberd/priv
|
||||
/var/lib/ejabberd/db
|
||||
5. Now try to start your new ejabberd 2.1.0.
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
@@ -1,47 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.1
|
||||
|
||||
ejabberd 2.1.1 is the first bugfix release in ejabberd 2.1.x branch.
|
||||
|
||||
ejabberd 2.1.1 includes several important bugfixes.
|
||||
More details of those fixes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.1.1
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
The changes are:
|
||||
|
||||
* Core
|
||||
- Call ejabberd_router:route/3 instead of sending a message
|
||||
- Can't connect if starttls_required and zlib are set
|
||||
- Routes vCard request to the occupant full JID, but should to bare JID
|
||||
- S2S: fix allow_host/2 on subdomains. added hook s2s_allow_host
|
||||
|
||||
* MUC
|
||||
- Support converting one-to-one chat to MUC
|
||||
- Add support for serving a Unique Room Name
|
||||
|
||||
* Publish Subscribe
|
||||
- Receive same last published PEP items at reconnect if several resources online
|
||||
- Typo in mod_pubsub_odbc breaks Service Discovery and more
|
||||
|
||||
* Web
|
||||
- Fix memory and port leak when TLS is enabled in HTTP
|
||||
- WebAdmin doesn't report correct last activity with postgresql backend
|
||||
- Option to define custom HTTP headers in mod_http_fileserver
|
||||
- Show informative webpage when browsing the HTTP-Poll page
|
||||
|
||||
* Other
|
||||
- Change captcha.sh to not depend on bash
|
||||
- Generate main XML file also when exporting only a vhost
|
||||
- Fix last newline in ejabberdctl result
|
||||
- Guide: fix -setcookie, mod_pubsub_odbc host, content_types
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.10
|
||||
|
||||
ejabberd 2.1.10 includes a few bugfixes and improvements.
|
||||
|
||||
Read more details about the changes in:
|
||||
http://redir.process-one.net/ejabberd-2.1.10
|
||||
|
||||
Download the source code and installers from:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
The major changes are:
|
||||
|
||||
* Erlang/OTP compatibility
|
||||
- Support Erlang/OTP R15B regexp and drivers (EJAB-1521)
|
||||
- Fix modules update in R14B04 and higher
|
||||
- Fix modules update of stripped beams (EJAB-1520)
|
||||
|
||||
* XMPP Core
|
||||
- Fix presence problem in C2S after first unavailable (EJAB-1466)
|
||||
- Fix bug on S2S shaper when TLS is used
|
||||
- Prevent overload of incoming S2S connections
|
||||
|
||||
* XEPs
|
||||
- BOSH: Get rid of useless mnesia transaction (EJAB-1502)
|
||||
- MUC: Don't reveal invitee resource when room informs invitor
|
||||
- Privacy: Activate "Blocked Contacts" to current c2s connection (EJAB-1519)
|
||||
- Privacy: Always allow packets from user's server and bare jid (EJAB-1441)
|
||||
- Pubsub: Add hooks for node creation/deletion (EJAB-1470)
|
||||
- Shared Rosters: support groupname@vhost in Displayed Groups (EJAB-506)
|
||||
- Vcard: Fix error when lowercasing some search results (EJAB-1490)
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
@@ -1,58 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.11
|
||||
|
||||
ejabberd 2.1.11 includes a few bugfixes and improvements.
|
||||
|
||||
Read more details about the changes in:
|
||||
http://redir.process-one.net/ejabberd-2.1.11
|
||||
|
||||
Download the source code and installers from:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
The major changes are:
|
||||
|
||||
* HTTP service
|
||||
- Fix ejabberd_http:get_line
|
||||
- Don't use binary:match to extract lines from binaries
|
||||
- Parse and encode https header names like native http parser does
|
||||
- Parse correctly https request split into multiple packets
|
||||
- Properly handle HEAD request in mod_http_bind (EJAB-1538)
|
||||
- New option default_host for handling requests with ambiguous Host (EJAB-1261)
|
||||
|
||||
* ODBC
|
||||
- New ODBC support for mod_announce
|
||||
- New ODBC support for mod_blocking
|
||||
- New ODBC support for mod_irc
|
||||
- New ODBC support for mod_muc
|
||||
- New ODBC support for mod_shared_roster
|
||||
- New ODBC support for mod_vcard_xupdate
|
||||
- Add ODBC exporting function for privacy table
|
||||
- Work also with some unicode strings in PgSQL (EJAB-1490)
|
||||
- Replace a single quote with double quotes in an ODBC escape
|
||||
|
||||
* SSL
|
||||
- Make sure that res is initialized in all cases
|
||||
- Parse correctly https request split into multiple packets (EJAB-1537)
|
||||
- Added missed tls:recv_data/2
|
||||
- Don't ignore Length parameter in tls:recv
|
||||
- Avoid quadratic behavior in reading SSL data
|
||||
- Dix http_bind webserver TLS fail on Chrome (EJAB-1530)
|
||||
|
||||
* Miscelanea
|
||||
- Assume we have only one CPU when an auto-detection fails (EJAB-1516)
|
||||
- Auth: Relax digest-uri handling (EJAB-1529)
|
||||
- Caps: Cache caps timestamp before the IQ-request is done
|
||||
- IRC: Use of MUC password
|
||||
- Private: misc errors cases fixes
|
||||
- Pubsub: return user affiliation for a specified node (EJAB-1294)
|
||||
- Shared Roster: Foreign items were not pushed (EJAB-1509)
|
||||
- Shared Roster LDAP: user substitution in ldap_rfilter (EJAB-1555)
|
||||
- Windows: Fix makefile rules for building DLLs
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
@@ -1,67 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.12
|
||||
|
||||
ejabberd 2.1.12 includes a many bugfixes and a few improvements.
|
||||
|
||||
Read more details about the changes in:
|
||||
http://redir.process-one.net/ejabberd-2.1.12
|
||||
|
||||
Download the source code and installers from:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
The changes are:
|
||||
|
||||
* Core ejabberd
|
||||
- Make terms serialization faster
|
||||
- Reduce size of XML stream state
|
||||
|
||||
* Administration
|
||||
- Add SCRAM and remove MD5 support to ejabberd commands auth verification
|
||||
- Added command to list all the vhosts registered in an ejabberd node
|
||||
- Added export2odbc command, copied from mod_admin_extra.erl
|
||||
- Fix ejabberdctl number of arguments error report with R15
|
||||
- Check node name is available before starting ejabberd (EJAB-1572)
|
||||
- Fix ejabberd_xmlrpc commands authentication with SCRAM
|
||||
- Fix mod_offline:store_offline_msg argument (EJAB-1581)
|
||||
- Log IP address when auth attempt fails
|
||||
- Make sure update_info returns atoms only (EJAB-1595)
|
||||
- On shutdown, first stop listeners, then modules
|
||||
|
||||
* Encryption
|
||||
- Detect OpenSSL version at runtime, not at compile time
|
||||
- Fixed signedness issue in tls_drv GET_DESCRYPTED_INPUT (EJAB-1591)
|
||||
- Enable DHE key exchange in TLS driver
|
||||
- Enable ECDHE key exchange in TSL driver
|
||||
- Disable old and unsecure ciphers in TLS driver
|
||||
- Disable SSL 2.0 in TLS driver
|
||||
|
||||
* HTTP-Bind
|
||||
- Do not trigger item-not-found errors in mod_http_bind
|
||||
- Repeated http-bind request should abort only requests with same rid
|
||||
- Receiving missing request shouldn't close waiting out-ouf-order request
|
||||
|
||||
* XMPP
|
||||
- Allow multiple fqdn values in configuration (EJAB-1578)
|
||||
- Fix get_subscription_lists/4
|
||||
- Fix account registration
|
||||
- Send announce Message stanzas as Headline type instead of Normal
|
||||
|
||||
* Other
|
||||
- Guide: Fix file name of Name Service Switch
|
||||
- Guide: Document the db_type modules option (EJAB-1560)
|
||||
- LDAP: Fix broken JPEG photo (EJAB-1526)
|
||||
- LDAP: Fix compatibility with Erlang R16A (EJAB-1612)
|
||||
- MUC: Fix angle brackets handle in plaintext log (EJAB-1610)
|
||||
- MUC: Fix MUC start when Mnesia tables don't exist yet
|
||||
- MUC: New mod_muc_log option file_permissions (EJAB-1588)
|
||||
- ODBC: Merge SQL and Mnesia code into one module (EJAB-1560)
|
||||
- Translation: New Hebrew
|
||||
- Translation: Update Slovak
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
@@ -1,51 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.2
|
||||
|
||||
ejabberd 2.1.2 is the second bugfix release in ejabberd 2.1.x branch.
|
||||
|
||||
ejabberd 2.1.2 includes several bugfixes.
|
||||
More details of those fixes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.1.2
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
The major changes are:
|
||||
|
||||
* Core
|
||||
- Close sessions that were half connected
|
||||
- Fix SASL PLAIN authentication message for RFC4616 compliance
|
||||
- Fix support for old Erlang/OTP R10 and R11
|
||||
- Return proper error (not 'conflict') when register is forbidden by ACL
|
||||
- When ejabberd stops, send stream close to clients
|
||||
|
||||
* ejabberdctl
|
||||
- Check for EGID in ejabberdctl command
|
||||
- Command to stop ejabberd informing users, with grace period
|
||||
- If there's a problem in config file, display config lines and stop node
|
||||
|
||||
* MUC
|
||||
- Kick occupants with reason when room is stopped due to MUC shutdown
|
||||
- Write in room log when a room is created, destroyed, started, stopped
|
||||
|
||||
* PubSub and PEP
|
||||
- Don't call gen_server on internal event (improves performance and scalability)
|
||||
- Fix duplicate SHIM header in Pubsub message
|
||||
- Notification messages of Pubsub node config change contained a SHIM header
|
||||
- SubID SHIM header missing in Pubsub message with multiple
|
||||
subscriptions on the same node
|
||||
- PEP: last published item not sent from unavailable users when the
|
||||
subscription is implicit (XEP-0115)
|
||||
- pep_mapping not working due to Node type mismatch
|
||||
|
||||
* WebAdmin
|
||||
- If big offline message queue, show only subset on WebAdmin
|
||||
- Support in user list page of WebAdmin when mod_offline is disabled
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
@@ -1,91 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.3
|
||||
|
||||
ejabberd 2.1.3 is the third release in ejabberd 2.1.x branch.
|
||||
|
||||
ejabberd 2.1.3 includes many bugfixes, and some improvements.
|
||||
More details of those fixes can be retrieved from:
|
||||
http://redir.process-one.net/ejabberd-2.1.3
|
||||
|
||||
The new code can be downloaded from ejabberd download page:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
This is the full list of changes:
|
||||
|
||||
* Client connections
|
||||
- Avoid 'invalid' value in iq record
|
||||
- Avoid resending stream:error stanzas on terminate (EJAB-1180)
|
||||
- Close also legacy sessions that were half connected (EJAB-1165)
|
||||
- iq_query_info/1 now returns 'invalid' if XMLNS is invalid
|
||||
- New ejabberd_c2s option support: max_fsm_queue
|
||||
- Rewrite mnesia counter functions to use dirty_update_counter (EJAB-1177)
|
||||
- Run user_receive_packet also when sending offline messages (EJAB-1193)
|
||||
- Use p1_fsm behaviour in c2s FSM (EJAB-1173)
|
||||
|
||||
* Clustering
|
||||
- Fix cluster race condition in route read
|
||||
- New command to set master Mnesia node
|
||||
- Use mnesia:async_dirty when cleaning table from failed node
|
||||
|
||||
* Documentation
|
||||
- Add quotes in documentation of some erl arguments (EJAB-1191)
|
||||
- Add option access_from (EJAB-1187)
|
||||
- Add option max_fsm_queue (EJAB-1185)
|
||||
- Fix documentation installation, no need for executable permission (EJAB-1170)
|
||||
- Fix typo in EJABBERD_BIN_PATH (EJAB-891)
|
||||
- Fix typos in example config comments (EJAB-1192)
|
||||
|
||||
* ejabberdctl
|
||||
- Support concurrent connections with bound connection names
|
||||
- Add support for Jot in ctl and TTY in debug
|
||||
- Support help command names with old - characters
|
||||
- Fix to really use the variable ERL_PROCESSES
|
||||
|
||||
* Erlang compatibility
|
||||
- Don't call queue:filter/2 to keep compatibility with older Erlang versions
|
||||
- Use alternative of file:read_line/1 to not require R13B02
|
||||
|
||||
* HTTP
|
||||
- Add new debugging hook to the http receiving process
|
||||
- Allow a request_handler to serve a file in root of HTTP
|
||||
|
||||
* HTTP-Bind (BOSH)
|
||||
- Cross-domain HTTP-Bind support (EJAB-1168)
|
||||
- Hibernate http-bind process after handling a request
|
||||
- Reduce verbosity of HTTP Binding log messages
|
||||
|
||||
* LDAP
|
||||
- Document ldap_dn_filter, fetch only needed attributes in search (EJAB-1204)
|
||||
- Use "%u" pattern as default for ldap_uids (EJAB-1203)
|
||||
|
||||
* Localization
|
||||
- Fix German translation (EJAB-1195)
|
||||
- Fix Russian translation
|
||||
|
||||
* ODBC
|
||||
- Fix MSSQL support, which was broken (EJAB-1201)
|
||||
- Improved SQL reconnect behaviour
|
||||
|
||||
* Pubsub, PEP and Caps
|
||||
- Add extended stanza addressing 'replyto' on PEP (EJAB-1198)
|
||||
- Add pubsub#purge_offline (EJAB-1186)
|
||||
- Fix pubsub#title option (EJAB-1190)
|
||||
- Fix remove_user for node subscriptions (EJAB-1172)
|
||||
- Optimizations in mod_caps
|
||||
|
||||
* Other
|
||||
- mod_register: Add new acl access_from, default is to deny
|
||||
- mod_sic: new module for the experimental XEP-0279 Server IP Check (EJAB-1205)
|
||||
- PIEFXIS: Catch errors when exporting to PIEFXIS file (EJAB-1178)
|
||||
- Proxy65: new option "hostname" (EJAB-838)
|
||||
- Roster: Fix resending authorization problem
|
||||
- Shared Roster Groups: get contacts nickname from vcard (EJAB-114)
|
||||
- S2S: Improved s2s connections clean up (EJAB-1202)
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
@@ -1,80 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.4
|
||||
|
||||
ejabberd 2.1.4 is the fourth release in ejabberd 2.1.x branch,
|
||||
and includes many small bugfixes and improvements.
|
||||
|
||||
Read more details about the changes in:
|
||||
http://redir.process-one.net/ejabberd-2.1.4
|
||||
|
||||
Download the source code and installers from:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
This is the full list of changes:
|
||||
|
||||
* Authentication
|
||||
- Extauth: Optionally cache extauth users in mnesia (EJAB-641)
|
||||
- LDAP: Allow inband password change (EJAB-199)
|
||||
- LDAP: Extensible match support (EJAB-722)
|
||||
- LDAP: New option ldap_tls_verify is added (EJAB-1229)
|
||||
- PAM: New option pam_userinfotype to provide username or JID (EJAB-652)
|
||||
|
||||
* HTTP
|
||||
- Add xml default content type
|
||||
- Don't show HTTP request in logs, because reveals password (EJAB-1231)
|
||||
- Move HTTP session timeout log from warning level to info
|
||||
- New Access rule webadmin_view for read-only
|
||||
|
||||
* HTTP-Bind (BOSH)
|
||||
- Change max inactivity from 30 to 120 seconds
|
||||
- Export functions to facilitate prebinding methods
|
||||
- Use dirty_delete when removing the session
|
||||
- Remove an unneeded delay of 100 milliseconds
|
||||
|
||||
* Pubsub, PEP and Caps
|
||||
- Enforce pubsub#presence_based_delivery (EJAB-1221)
|
||||
- Enforce pubsub#show_values subscription option (EJAB-1096)
|
||||
- Fix error code when unsubscribing from a non-existent node
|
||||
- Fix to send node notifications (EJAB-1225)
|
||||
- Full support for XEP-0115 v1.5 (EJAB-1223)(EJAB-1189)
|
||||
- Make last_item_cache feature to be cluster aware
|
||||
- Prevent orphaned pubsub node (EJAB-1233)
|
||||
- Send created node notifications
|
||||
|
||||
* Other
|
||||
- Bounce messages when closing c2s session
|
||||
- Bugfixes when handling Service Discovery to contacts (EJAB-1207)
|
||||
- Compilation of ejabberd_debug.erl is now optional
|
||||
- Don't send error stanza as reply to error stanza (EJAB-930)
|
||||
- Don't store blocked messages in offline queue
|
||||
- Reduce verbosity of log when captcha_cmd is checked but not configured
|
||||
- Use a standard method to get a random seed (EJAB-1229)
|
||||
- Commands: new update_list and update to update modified modules (EJAB-1237)
|
||||
- Localization: Updated most translations
|
||||
- MUC: Refactor code to reduce calls to get_affiliation and get_role
|
||||
- ODBC: Add created_at column also to PostgreSQL schema
|
||||
- Vcard: Automatic vcard avatar addition in presence
|
||||
|
||||
|
||||
Upgrading From previous ejabberd releases:
|
||||
|
||||
- If you use PostgreSQL, maybe you want to add the column created_at
|
||||
to several tables. This is only a suggestion; ejabberd doesn't use
|
||||
that column. Add it to your existing database executing those SQL
|
||||
statements:
|
||||
|
||||
ALTER TABLE users ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now();
|
||||
ALTER TABLE rosterusers ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now();
|
||||
ALTER TABLE spool ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now();
|
||||
ALTER TABLE vcard ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now();
|
||||
ALTER TABLE privacy_list ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now();
|
||||
ALTER TABLE privacy_storage ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT now();
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.5
|
||||
|
||||
ejabberd 2.1.5 is the fifth release in ejabberd 2.1.x branch,
|
||||
and includes several minor bugfixes and a few improvements.
|
||||
|
||||
Read more details about the changes in:
|
||||
http://redir.process-one.net/ejabberd-2.1.4
|
||||
|
||||
Download the source code and installers from:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
This is the full list of changes:
|
||||
|
||||
* Authentication
|
||||
- Extauth: Support parallel script running (EJAB-1280)
|
||||
- mod_register: Return Registered element when account exists
|
||||
|
||||
* ejabberdctl
|
||||
- Fix print of command result that contains ~
|
||||
- Fix problem when FIREWALL_WINDOW options for erl kernel were used
|
||||
- Fix typo in update_list command (EJAB-1237)
|
||||
- Some systems delete the lock dir; in such case don't use flock at all
|
||||
- The command Update now returns meaningful message and exit-status (EJAB-1237)
|
||||
|
||||
* HTTP-Bind (BOSH)
|
||||
- Don't say v1.2 in the Bind HTTP page
|
||||
- New optional BOSH connection attribute process-delay (EJAB-1257)
|
||||
|
||||
* MUC
|
||||
- Document the mod_muc option captcha_protected
|
||||
- Now admins are able to see private rooms in disco (EJAB-1269)
|
||||
- Show some more room options in the log file
|
||||
|
||||
* ODBC
|
||||
- Correct handling of SQL boolean types (EJAB-1275)
|
||||
- Discard too old queued requests (the caller has already got a timeout)
|
||||
- Fixes wrong SQL escaping when --enable-full-xml is set
|
||||
- Use ets insead of asking supervisor in ejabberd_odbc_sup:get_pids/1
|
||||
|
||||
* Pubsub, PEP and Caps
|
||||
- Enforce disco features results (EJAB-1033, EJAB-1228, EJAB-1238)
|
||||
- Support all the hash functions required by Caps XEP-0115
|
||||
|
||||
* Requirements
|
||||
- Fixed support for Erlang R12; which doesn't support: true andalso ok
|
||||
- Support OTP R14A by using public_key library instead of old ssl (EJAB-953)
|
||||
- Requirement of OpenSSL increased from 0.9.6 to 0.9.8
|
||||
- OpenSSL is now required, not optional
|
||||
|
||||
* Other
|
||||
- Don't ask for client certificate when using tls (EJAB-1267)
|
||||
- Fix typo in --enable-transient_supervisors
|
||||
- Fix privacy check when serving local Last (EJAB-1271)
|
||||
- Inform client that SSL session caching is disabled
|
||||
- New configure option: --enable-nif
|
||||
- Use driver allocator in C files for reflecting memory in erlang:memory(system)
|
||||
- Debug: New p1_prof compiled with: make debugtools=true
|
||||
- Debug: Added functions to collect stats about queues, memory, reductions etc
|
||||
- HTTP: Log error if request has ambiguous Host header (EJAB-1261)
|
||||
- Logs: When logging s2s out connection attempt or success, log if TLS is used
|
||||
- Shared Rosters: When account is deleted, delete also member of stored rosters
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
@@ -1,67 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.6
|
||||
|
||||
ejabberd 2.1.6 is the sixth release in ejabberd 2.1.x branch,
|
||||
and includes a lot of bugfixes and improvements.
|
||||
|
||||
Read more details about the changes in:
|
||||
http://redir.process-one.net/ejabberd-2.1.6
|
||||
|
||||
Download the source code and installers from:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
Some of the changes are:
|
||||
|
||||
* Account register
|
||||
- mod_register: New ip_access option restricts which IPs can register (EJAB-915)
|
||||
- mod_register: Default configuration allows registrations only from localhost
|
||||
- mod_register: New password_strength for entropy check (EJAB-1326)
|
||||
- mod_register: New captcha_protected option to require CAPTCHA (EJAB-1262)
|
||||
- mod_register_web: New module, with CAPTCHA support (EJAB-471)
|
||||
|
||||
* BOSH
|
||||
- Don't loop when there is nothing after a stream start (EJAB-1358)
|
||||
- Fix http-bind supervisor to support multiple vhosts (EJAB-1321)
|
||||
- Support to restart http-bind (EJAB-1318)
|
||||
- Support for X-Forwarded-For HTTP header (EJAB-1356)
|
||||
|
||||
* Erlang/OTP compatibility
|
||||
- R11: Fix detection of Erlang R11 and older (EJAB-1287)
|
||||
- R12B5: Fix compatibility in ejabberd_http_bind.erl (EJAB-1343)
|
||||
- R14A: Make xml.c correctly compile (EJAB-1288)
|
||||
- R14A, R14B: Disapprove the use of R14A and R14B due to the rwlock bug
|
||||
- R14B: Use pg2 from this version in systems with older ones (EJAB-1349)
|
||||
|
||||
* Listeners
|
||||
- Bind listener ports early and start accepting connections later
|
||||
- Fix a leak of ejabberd_receiver processes
|
||||
- Speed up ejabberd_s2s:is_service/2, allow_host/2 (EJAB-1319)
|
||||
- S2S: New option to require encryption (EJAB-495)
|
||||
- S2S: New option to reject connection if untrusted certificate (EJAB-464)
|
||||
- S2S: Include From attribute in the stream header of outgoing S2S connections
|
||||
- S2S: Fix domain_certfile tlsopts modifications for S2S connections (EJAB-1086)
|
||||
|
||||
* Pubsub/PEP/Caps
|
||||
- Fix pubsub cross domain eventing (EJAB-1340)
|
||||
- Use one_queue IQ discipline by default
|
||||
- Implement lifetime for broken hashes
|
||||
- New CAPS processing
|
||||
|
||||
* ODBC
|
||||
- Increase maximum restart strategy to handle some SQL timeouts
|
||||
- Support PostgreSQL 9.0 (EJAB-1359)
|
||||
- Use MEDIUMTEXT type for vcard avatars in MySQL schema (EJAB-1252)
|
||||
|
||||
* Miscellanea:
|
||||
- mod_shared_roster_ldap: New Shared Roster Groups using LDAP information
|
||||
- mod_privacy: Fix to allow block by group and subscription again
|
||||
- Support timezone West of UTC (EJAB-1301)
|
||||
- Support to change loglevel per module at runtime (EJAB-225)
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
@@ -1,97 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.7
|
||||
|
||||
ejabberd 2.1.7 is the eighth release in ejabberd 2.1.x branch,
|
||||
and includes a lot of bugfixes and improvements.
|
||||
|
||||
Read more details about the changes in:
|
||||
http://redir.process-one.net/ejabberd-2.1.7
|
||||
|
||||
Download the source code and installers from:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
The changes are:
|
||||
|
||||
* BOSH and Web
|
||||
- Clarify error message when BOSH query is sent to non-running module
|
||||
- Keep the order of stanzas when BOSH sends several (EJAB-1374)
|
||||
- Show configuration for HTTPS http_bind
|
||||
- Support as read-only HTTP method not only GET, also HEAD
|
||||
- The responses to HEAD must have empty Body
|
||||
|
||||
* CAPTCHA
|
||||
- If the port number isn't listener, then specify the protocol (EJAB-1418)
|
||||
- New CAPTCHA limit
|
||||
- New CAPTCHA whitelist support
|
||||
- Only check system at startup if option is enabled
|
||||
- Provide HTTPS URL in CAPTCHA form when listener has 'tls' option (EJAB-1406)
|
||||
- Show captcha_limit option in the example config
|
||||
- Support more captcha_host value formats (EJAB-1418)
|
||||
- Throw error when captcha fails at server start, not later at runtime
|
||||
- captcha_host must have the port number to get protocol (EJAB-1418)
|
||||
|
||||
* Core ejabberd
|
||||
- Disable all entity expansions (EJAB-1451)
|
||||
- Do not accept XML with undefined prefixes (EJAB-680)
|
||||
- Make jlib:ip_to_list safe to use
|
||||
- Make sure 'closed' event is correctly processed on every state
|
||||
- New route_iq/5 accepting Timeout (EJAB-1398)
|
||||
- Take into consideration internal queue length when sorting processes queues
|
||||
- Use route instead of send_element to go through standard workflow
|
||||
|
||||
* Erlang/OTP compatibility
|
||||
- Remove Type and Spec, backport list comprehensions, so R12B-5 can compile
|
||||
- Tweak pg2_backport.erl to work with Erlang older than R13A (EJAB-1349)
|
||||
|
||||
* ODBC
|
||||
- Don't let presence-in privacy rule block a presence subscription (EJAB-255)
|
||||
- Escape user input in mod_privacy_odbc (EJAB-1442)
|
||||
- Try to improve support for roster_version in MSSQL (EJAB-1437)
|
||||
|
||||
* Pubsub/PEP/Caps
|
||||
- Apply filtered notification to PEP last items (EJAB-1456)
|
||||
- Fix empty pubsub payload check
|
||||
- Owner can delete any items from its own node (EJAB-1445)
|
||||
- Pubsub node maxitem forced to 0 if non persistent node (EJAB-1434)
|
||||
- Reorganize the push_item function, and handle version not_found (EJAB-1420)
|
||||
|
||||
* Scripts
|
||||
- ejabberd.init: Several fixes and improvements
|
||||
- ejabberdctl: Escape output from ctlexec() to erl script (EJAB-1399)
|
||||
- ejabberdctl: Fix bashism and mimic master branch (EJAB-1404)
|
||||
- ejabberdctl: Fix space between INET_DIST_INTERFACE (EJAB-1416)
|
||||
- ejabberdctl: New DIST_USE_INTERFACE restricts IP of erlang listen (EJAB-1404)
|
||||
- ejabberdctl: New ERL_EPMD_ADDRESS that works since Erlang/OTP R14B03
|
||||
- extauth: Fix delayed response of timeout was reused for next login (EJAB-1385)
|
||||
- extauth: Forward old messages to newly spawned extauth process (EJAB-1385)
|
||||
- extauth: If script crashes, ejabberd should restart it (EJAB-1428)
|
||||
|
||||
* XEP support
|
||||
- mod_blocking: New XEP-0191 Simple Communications Blocking (EJAB-695)
|
||||
- No need to inform that XEP-0237 is optional; clarified in XEP version 1.2
|
||||
|
||||
* Miscellanea:
|
||||
- If a module start fails during server start, stop erlang (EJAB-1446)
|
||||
- New Indonesian translation (EJAB-1407)
|
||||
- LDAP: Note that ejabberd works with CGP LDAP server
|
||||
- S2S: Handle Tigase's unexpected version=1.0 (EJAB-1379)
|
||||
- mod_irc: Send presence unavailable to the departing occupant (EJAB-1417)
|
||||
- mod_last: Allow user to query his own Last activity
|
||||
- mod_muc: Do not decrease MUC admin's role/affiliation
|
||||
- mod_muc: Send jid attribute when occupant is banned (EJAB-1432)
|
||||
- mod_offline: Change c2s state before offline messages resending
|
||||
- mod_ping: Use iqdisc no_queue by default (EJAB-1435)
|
||||
- mod_pres_counter: Prevent subscription flood (EJAB-1388)
|
||||
- mod_register Access now also controls account unregistrations
|
||||
- mod_register: Clarify more the expected content of welcome_message option
|
||||
- mod_shared_roster: Fix support for anonymous accounts in @all@ (EJAB-1264)
|
||||
- mod_shared_roster: New @online@ directive (EJAB-1391)
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.8
|
||||
|
||||
ejabberd 2.1.8 is the ninth release in ejabberd 2.1.x branch,
|
||||
and includes a PubSub regression bugfix.
|
||||
|
||||
Download the source code and installers from:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
The change is:
|
||||
|
||||
- Fix issue on PubSub preventing publication of items (EJAB-1457)
|
||||
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
@@ -1,56 +0,0 @@
|
||||
|
||||
Release Notes
|
||||
ejabberd 2.1.9
|
||||
|
||||
ejabberd 2.1.9 is the eighth release in ejabberd 2.1.x branch,
|
||||
and includes a lot of bugfixes and improvements.
|
||||
|
||||
Read more details about the changes in:
|
||||
http://redir.process-one.net/ejabberd-2.1.9
|
||||
|
||||
Download the source code and installers from:
|
||||
http://www.process-one.net/en/ejabberd/
|
||||
|
||||
|
||||
The changes are:
|
||||
|
||||
* Core ejabberd
|
||||
- Decrease CPU usage caused by tls:send with large data
|
||||
- Escape iolist correctly when NIFs are disabled (EJAB-1462)
|
||||
- Fix code to satisfy Dialyzer warnings
|
||||
- Fix compilation in Windows
|
||||
- Replace calls of OTP's Binary, since they would require R14
|
||||
|
||||
* LDAP
|
||||
- Document ldap_tls_cacertfile and ldap_tls_depth options (EJAB-1299)
|
||||
- Log an error when an LDAP filter is incorrect (EJAB-1395)
|
||||
- New options: ldap_tls_cacertfile and ldap_tls_depth (EJAB-1299)
|
||||
- New option: ldap_deref_aliases (EJAB-639)
|
||||
- Match ldap_uidattr_format case-insensitively (EJAB-1449)
|
||||
|
||||
* MUC
|
||||
- Support for multiple entry with same nick to MUC rooms (EJAB-305)
|
||||
- Support voice request and approvement
|
||||
- New room option: allow_private_messages_from_visitors
|
||||
- New room options: allow_voice_requests and voice_request_min_interval
|
||||
- Include status 110 in presence to new occupant (EJAB-740)
|
||||
- Fix mod_muc_log crash when first log entry is room destroy (EJAB-1499)
|
||||
- Many fixes and improvements in mod_muc
|
||||
|
||||
* Pubsub
|
||||
- Enable pubsub#deliver_notification checking (EJAB-1453)
|
||||
- Fix Denial of Service when user sends malformed publish stanza (EJAB-1498)
|
||||
|
||||
* ODBC
|
||||
- Fix ODBC account counting (EJAB-1491)
|
||||
- Optimized mod_roster_odbc:get_roster
|
||||
|
||||
* Miscellanea:
|
||||
- New SASL SCRAM-SHA-1 authentication mechanism (EJAB-1196)
|
||||
- New option: resource_conflict (EJAB-650)
|
||||
|
||||
|
||||
Bug reports
|
||||
|
||||
You can officially report bugs on ProcessOne support site:
|
||||
http://support.process-one.net/
|
||||
@@ -1,2 +0,0 @@
|
||||
% ejabberd version (automatically generated).
|
||||
\newcommand{\version}{13.03-beta1}
|
||||
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 157 KiB |
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/perl
|
||||
#!/usr/local/bin/perl
|
||||
|
||||
use Unix::Syslog qw(:macros :subs);
|
||||
|
||||
@@ -18,7 +18,7 @@ while(1)
|
||||
my $len = unpack "n",$buf;
|
||||
my $nread = sysread STDIN,$buf,$len;
|
||||
|
||||
my ($op,$user,$host,$password) = split /:/,$buf;
|
||||
my ($op,$user,$password) = split /:/,$buf;
|
||||
#$user =~ s/\./\//og;
|
||||
my $jid = "$user\@$domain";
|
||||
my $result;
|
||||
@@ -42,22 +42,6 @@ while(1)
|
||||
# password is null. Return 1 if the user $user\@$domain exitst.
|
||||
$result = 1;
|
||||
},last SWITCH;
|
||||
|
||||
$op eq 'tryregister' and do
|
||||
{
|
||||
$result = 1;
|
||||
},last SWITCH;
|
||||
|
||||
$op eq 'removeuser' and do
|
||||
{
|
||||
# password is null. Return 1 if the user $user\@$domain exitst.
|
||||
$result = 1;
|
||||
},last SWITCH;
|
||||
|
||||
$op eq 'removeuser3' and do
|
||||
{
|
||||
$result = 1;
|
||||
},last SWITCH;
|
||||
};
|
||||
my $out = pack "nn",2,$result ? 1 : 0;
|
||||
syswrite STDOUT,$out;
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
<!-- aim-transport.xml -->
|
||||
|
||||
<jabber>
|
||||
|
||||
<!--
|
||||
You need to add elogger and rlogger entries when using ejabberd.
|
||||
In this case the transport will do the logging.
|
||||
-->
|
||||
|
||||
<log id='elogger'>
|
||||
<host/>
|
||||
<logtype/>
|
||||
<format>%d: [%t] (%h): %s</format>
|
||||
<file>/var/log/jabber/aim-transport-error.log</file>
|
||||
</log>
|
||||
|
||||
<log id='rlogger'>
|
||||
<host/>
|
||||
<logtype>record</logtype>
|
||||
<format>%d %h %s</format>
|
||||
<file>/var/log/jabber/aim-transport-record.log</file>
|
||||
</log>
|
||||
|
||||
<!--
|
||||
ejabberd do not provide XDB services.
|
||||
xdb_file.so is loaded in to handle all XDB requests.
|
||||
-->
|
||||
|
||||
<xdb id="xdb">
|
||||
<host/>
|
||||
<load>
|
||||
<xdb_file>/usr/local/lib/jabber/libjabberdxdbfile.so</xdb_file> <!-- This file is part of jabberd-1.4.x. -->
|
||||
</load>
|
||||
<xdb_file xmlns="jabber:config:xdb_file">
|
||||
<spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
|
||||
</xdb_file>
|
||||
</xdb>
|
||||
|
||||
<!--
|
||||
Make sure that all host names here are resolveable via DNS if you
|
||||
want the transport to be available to the public.
|
||||
-->
|
||||
|
||||
<service id='aim.SERVER.COM'>
|
||||
<!-- aim-transport configuration. -->
|
||||
<aimtrans xmlns='jabber:config:aimtrans'>
|
||||
<vCard>
|
||||
<FN>AIM/ICQ Transport</FN>
|
||||
<DESC>This is the AIM/ICQ Transport.</DESC>
|
||||
<MAIL>EMAIL@ADDRESS.COM</MAIL>
|
||||
<URL>http://aim-transport.jabberstudio.org/</URL>
|
||||
</vCard>
|
||||
<charset>cp1252</charset>
|
||||
</aimtrans>
|
||||
<!-- aim-transport module. -->
|
||||
<load>
|
||||
<aim_transport>/usr/local/lib/jabber/aim-transport.so</aim_transport>
|
||||
</load>
|
||||
</service>
|
||||
|
||||
<!--
|
||||
The settings below have to match the settings you made
|
||||
in your ejabberd.cfg configuration file.
|
||||
-->
|
||||
|
||||
<service id="icq-linker">
|
||||
<uplink/>
|
||||
<connect>
|
||||
<ip>127.0.0.1</ip>
|
||||
<port>5233</port>
|
||||
<secret>SECRET</secret>
|
||||
</connect>
|
||||
</service>
|
||||
|
||||
<pidfile>/var/run/jabber/aim-transport.pid</pidfile>
|
||||
|
||||
</jabber>
|
||||
@@ -1,136 +0,0 @@
|
||||
<!-- ile.xml -->
|
||||
|
||||
<config>
|
||||
<jabber>
|
||||
<server>127.0.0.1</server>
|
||||
<port>5238</port>
|
||||
<secret>SECRET</secret>
|
||||
<service>ile.SERVER.COM</service>
|
||||
<connectsleep>7</connectsleep> <!-- seconds to wait if we get disconnected -->
|
||||
<language>en</language>
|
||||
<vCard>
|
||||
<FN>I Love Email</FN>
|
||||
<DESC>With this service you can receive email notifications.
|
||||
|
||||
Security warning: Be careful when using this. Your password will travel in clear from your client to your jabber server if you don't use SSL and it will probably travel in clear from the jabber server to your email server. Use with care. This shouldn't be an issue in your Intranet, but it is if you use an ILE installed in a foreign jabber server.</DESC>
|
||||
<MAIL>EMAIL@ADDRESS.COM</MAIL>
|
||||
<URL>http://ile.jabberstudio.org/</URL>
|
||||
</vCard>
|
||||
</jabber>
|
||||
|
||||
<debug>
|
||||
<file>/var/log/jabber/ile.log</file>
|
||||
<level>1</level> <!-- man Net::Jabber::Debug -->
|
||||
</debug>
|
||||
|
||||
<mail>
|
||||
<checkinterval>10</checkinterval> <!-- in minutes -->
|
||||
<timeout>20</timeout> <!-- timeout for IMAP/POP connection, in seconds -->
|
||||
</mail>
|
||||
|
||||
<files>
|
||||
<users>/var/spool/jabber/ile.SERVER.COM/users.db</users>
|
||||
<passwords>/var/spool/jabber/ile.SERVER.COM/passwords.db</passwords>
|
||||
<hosts>/var/spool/jabber/ile.SERVER.COM/hosts.db</hosts>
|
||||
<types>/var/spool/jabber/ile.SERVER.COM/types.db</types>
|
||||
<notifyxa>/var/spool/jabber/ile.SERVER.COM/notifyxa.db</notifyxa>
|
||||
<notifydnd>/var/spool/jabber/ile.SERVER.COM/notifydnd.db</notifydnd>
|
||||
<urls>/var/spool/jabber/ile.SERVER.COM/urls.db</urls>
|
||||
</files>
|
||||
|
||||
<form>
|
||||
<en>
|
||||
<instructions>Please fill in the fields,according to your email account settings and notification preferences</instructions>
|
||||
<title>ILE: Email notification service</title>
|
||||
<email_options>Email account settings</email_options>
|
||||
<user>Username</user>
|
||||
<pass>Password</pass>
|
||||
<host>Hostname</host>
|
||||
<type>Type</type>
|
||||
<newmail>You have received NUM email messages since last time I checked, which was CHECKINTERVAL minutes ago.</newmail>
|
||||
<errorcheck>There was an error while trying to check mail for ACCOUNT.</errorcheck>
|
||||
<notify_options>Notification Options</notify_options>
|
||||
<notifyxa>Notify even when Xtended Away (XA)</notifyxa>
|
||||
<notifydnd>Notify even when Do Not Disturb (DND)</notifydnd>
|
||||
<webmail_url>Webmail URL</webmail_url>
|
||||
<webmail_login>Login to ACCOUNT</webmail_login>
|
||||
<iledesc>ILE: an email notifier component: http://ile.jabberstudio.org</iledesc>
|
||||
</en>
|
||||
|
||||
<es>
|
||||
<instructions>Por favor, rellene los campos del formulario.</instructions>
|
||||
<title>ILE: Servicio de notificación de correo</title>
|
||||
<email_options>Configuración de la cuenta de correo</email_options>
|
||||
<user>Usuario</user>
|
||||
<pass>Clave</pass>
|
||||
<host>Host</host>
|
||||
<type>Tipo</type>
|
||||
<newmail>Ha recibido NUM email(s) desde la última comprobación que fue hace CHECKINTERVAL minutos</newmail>
|
||||
<errorcheck>Ha habido un error en la comprobación del correo para la cuenta ACCOUNT.</errorcheck>
|
||||
<notify_options>Opciones de notificación</notify_options>
|
||||
<notifyxa>Notificar incluso si muy ausente (XA)</notifyxa>
|
||||
<notifydnd>Notificar incluso si no molestar (DND)</notifydnd>
|
||||
<webmail_url>Webmail URL</webmail_url>
|
||||
<webmail_login>Leer correo de ACCOUNT</webmail_login>
|
||||
<iledesc>ILE: un notificador de nuevo email - http://ile.jabberstudio.org</iledesc>
|
||||
</es>
|
||||
|
||||
<ca>
|
||||
<instructions>Ompli els camps del formulari.</instructions>
|
||||
<title>ILE: Servei de notificació de nou email</title>
|
||||
<email_options>Dades del compte de mail</email_options>
|
||||
<user>Usuari</user>
|
||||
<pass>Clau</pass>
|
||||
<host>Host</host>
|
||||
<type>Tipus</type>
|
||||
<newmail>Ha rebut NUM email(s) des de la última comprobació que va ser fa CHECKINTERVAL minuts.</newmail>
|
||||
<errorcheck>S'ha produit un error en la comprobació del correu per al compte ACCOUNT.</errorcheck>
|
||||
<notify_options>Opcions de notificació</notify_options>
|
||||
<notifyxa>Notificar si molt absent (XA)</notifyxa>
|
||||
<notifydnd>Notificar si no molestar (DND)</notifydnd>
|
||||
<webmail_url>Webmail URL</webmail_url>
|
||||
<webmail_login>Llegir correu de ACCOUNT</webmail_login>
|
||||
<iledesc>ILE: un notificador de nou email - http://ile.jabberstudio.org</iledesc>
|
||||
</ca>
|
||||
|
||||
<ro>
|
||||
<!-- Contributed by Adrian Rappa -->
|
||||
<instructions>Va rog completati urmatoarele campuri</instructions>
|
||||
<title>I Love Email: new email notification service</title>
|
||||
<email_options>Email account settings</email_options>
|
||||
<user>Nume utilizator</user>
|
||||
<pass>Parola</pass>
|
||||
<host>Nume gazda</host>
|
||||
<type>Tip</type>
|
||||
<newmail>Ati primit NUM mesaj(e) de la ultima verificare, care a fost acum CHECKINTERVAL minute.</newmail>
|
||||
<errorcheck>A fost eroare in timp ce incercam sa verific posta pentru ACCOUNT.</errorcheck>
|
||||
<notify_options>Notification Options</notify_options>
|
||||
<notifyxa>Notify even when Xtended Away (XA)</notifyxa>
|
||||
<notifydnd>Notify even when Do Not Disturb (DND)</notifydnd>
|
||||
<webmail_url>Webmail URL</webmail_url>
|
||||
<webmail_login>Login to ACCOUNT</webmail_login>
|
||||
<iledesc>ILE: an email notifier component: http://ile.jabberstudio.org</iledesc>
|
||||
</ro>
|
||||
|
||||
<nl>
|
||||
<!-- Contributed by Sander Devrieze -->
|
||||
<instructions>Vul volgende velden in.</instructions>
|
||||
<title>ILE: Dienst voor e-mailnotificaties</title>
|
||||
<email_options>Instellingen van e-mailaccount</email_options>
|
||||
<user>Gebruikersnaam</user>
|
||||
<pass>Wachtwoord</pass>
|
||||
<host>Inkomende mailserver</host>
|
||||
<type>Type verbinding</type>
|
||||
<newmail>U hebt NUM berichten ontvangen sinds CHECKINTERVAL minuten geleden.</newmail>
|
||||
<errorcheck>Fout tijdens controle op nieuwe e-mails bij ACCOUNT. ILE zal deze account niet meer opnieuw controleren tot u uw registratiegegevens wijzigt of opnieuw aanmeldt.</errorcheck>
|
||||
<notify_options>Notificatie-instellingen</notify_options>
|
||||
<notifyxa>Notificeer ook in de status Niet Beschikbaar (XA)</notifyxa>
|
||||
<notifydnd>Notificeer ook in de status Niet Storen (DND)</notifydnd>
|
||||
<webmail_url>URL van webmail</webmail_url>
|
||||
<webmail_login>Aanmelden op ACCOUNT</webmail_login>
|
||||
<iledesc>ILE: een dienst om e-mailnotificaties te ontvangen: http://ile.jabberstudio.org</iledesc>
|
||||
</nl>
|
||||
|
||||
</form>
|
||||
|
||||
</config>
|
||||
@@ -1,149 +0,0 @@
|
||||
<jggtrans>
|
||||
|
||||
<service jid="gg.SERVER.COM"/>
|
||||
|
||||
<!-- This connects the jabber-gg-transport process to ejabberd. -->
|
||||
<connect id="gglinker">
|
||||
<ip>127.0.0.1</ip>
|
||||
<port>5237</port>
|
||||
<secret>SECRET</secret>
|
||||
</connect>
|
||||
|
||||
<register>
|
||||
<!-- This tag contains the message displayed to users at registration time.
|
||||
You can use <p/> and/or <br/> to break lines. Multiple spaces and newlines
|
||||
are converted to just one, so formatting of config file doesn't really matter. -->
|
||||
<instructions>
|
||||
Fill in your GG number (after "username")
|
||||
and password to register on the transport.
|
||||
<p/>To change your information in the GaduGadu directory you need to fill in the other fields.
|
||||
<p/>To remove registration you need to leave the form blank.
|
||||
</instructions>
|
||||
</register>
|
||||
|
||||
<search>
|
||||
<!-- This tag contains the message displayed to users at search time. -->
|
||||
<instructions>
|
||||
To search people:<br/>
|
||||
First fill in surname or family name, nickname, city, birthyear or range of birthyears (eg. 1950-1960)
|
||||
and gender (you may fill in more fields at once).<br/>
|
||||
or<br/>
|
||||
Fill in phone number<br/>
|
||||
or<br/>
|
||||
Fill in the GG number of the person you are searching.
|
||||
</instructions>
|
||||
</search>
|
||||
|
||||
<gateway>
|
||||
<!-- This is message, that may be displayed to user when adding gg contact. -->
|
||||
<desc>Please fill in the GaduGadu number of the person you want to add.</desc>
|
||||
<!-- And this is the prompt for GG number. -->
|
||||
<prompt>GG Nummer</prompt>
|
||||
</gateway>
|
||||
|
||||
<vCard>
|
||||
<FN>Gadu-Gadu Transport</FN>
|
||||
<DESC>This is the Gadu-Gadu Transport.</DESC>
|
||||
<EMAIL>EMAIL@ADDRESS.COM</EMAIL>
|
||||
<URL>http://www.jabberstudio.org/projects/jabber-gg-transport/</URL>
|
||||
</vCard>
|
||||
|
||||
<!-- Default user locale (language).
|
||||
Empty means system locale setting,
|
||||
no (or commented-out) <default_locale> tag means no translations. -->
|
||||
<!-- <default_locale>pl_PL</default_locale> -->
|
||||
|
||||
<!-- Logger configuration.
|
||||
You may configure one logger of type "syslog" and/or one of type "file".
|
||||
You may also not configure logging at all. -->
|
||||
<log type="syslog" facility="local0"/>
|
||||
<log type="file">/var/log/jabber/jabber-gg-transport.log</log>
|
||||
|
||||
<!-- Uncomment this, if you want proxy to be used for Gadu-Gadu connection. -->
|
||||
<!--
|
||||
<proxy>
|
||||
<ip>127.0.0.1</ip>
|
||||
<port>8080</port>
|
||||
</proxy>
|
||||
-->
|
||||
|
||||
<!-- You can change these values according to your needs. -->
|
||||
<conn_timeout>60</conn_timeout>
|
||||
<ping_interval>10</ping_interval>
|
||||
|
||||
<!-- Gadu-Gadu server doesn't seem to answer pings anymore :-(
|
||||
So let's give it 10 year :-) -->
|
||||
<pong_timeout>315360000</pong_timeout>
|
||||
|
||||
<!-- This time after disconnection from Gadu-Gadu server the transport
|
||||
will try to connect again. -->
|
||||
<reconnect>300</reconnect>
|
||||
|
||||
<!-- How long to wait before restart, after jabber server connection is broken
|
||||
negative value means, that jggtrans should terminate. -->
|
||||
<restart_timeout>60</restart_timeout>
|
||||
|
||||
<!-- Delay between the unavailable presence is received from user and loggin out
|
||||
from Gadu-Gadu - for nice <presence type="invisible"/> support. -->
|
||||
<disconnect_delay>5</disconnect_delay>
|
||||
|
||||
<!-- list of Gadu-Gadu servers to use.
|
||||
<hub/> means "use GG hub to find server"
|
||||
<server/> tag should contain server address and may contain "port"
|
||||
attribute with port number. When TLS is available (supported by libgadu)
|
||||
it will be used unless "tls" attribute is set to "no". Please notice,
|
||||
that not all servers will accept TLS connections.
|
||||
Servers (including hub) are tried in order as they appear in <servers/>
|
||||
element.
|
||||
A reasonable default server list is hardcoded in jggtrans.
|
||||
-->
|
||||
<!--
|
||||
<servers>
|
||||
<hub/>
|
||||
<server port="443">217.17.41.90</server>
|
||||
<server tls="no">217.17.41.85</server>
|
||||
<server tls="no">217.17.41.88</server>
|
||||
</servers>
|
||||
-->
|
||||
|
||||
<!-- Spool directory. This is the place, where user info will be stored. -->
|
||||
<!-- Be careful about permissions - users' Gadu-Gadu passwords are stored there. -->
|
||||
<spool>/var/spool/jabber/gg.SERVER.COM/</spool>
|
||||
|
||||
<!-- Where to store pid file. This tag is optional. -->
|
||||
<pidfile>/var/run/jabber/jabber-gg-transport.pid</pidfile>
|
||||
|
||||
<!-- jid allowed to do some administrative task (eg. discovering online users).
|
||||
May be used multiple times. -->
|
||||
<admin>GG_TRANSPORT_ADMIN@SERVER.COM</admin>
|
||||
|
||||
<!-- ACL gives detailed access control to the transport. -->
|
||||
<acl>
|
||||
<!-- Example entries: -->
|
||||
|
||||
<allow who="admin@SERVER.COM" what="iq/query?xmlns=http://jabber.org/protocol/stats"/>
|
||||
<!-- will allow statistics gathering to admin@SERVER.COM -->
|
||||
|
||||
<deny who="*" what="iq/query?xmlns=http://jabber.org/protocol/stats"/>
|
||||
<!-- will deny statistics gathering for anybody else -->
|
||||
|
||||
<!-- <allow who="*@SERVER.COM"/> -->
|
||||
<!-- will allow anything else to users from "SERVER.COM" -->
|
||||
|
||||
<!-- <deny what="iq/query?xmlns=jabber:x:register"/> -->
|
||||
<!-- will deny registration for all other users -->
|
||||
|
||||
<!-- <allow what="presence"/> -->
|
||||
<!-- allow presence from anybody -->
|
||||
|
||||
<!-- <allow what="iq"/> -->
|
||||
<!-- allow iq from anybody -->
|
||||
|
||||
<!-- <allow what="message"/> -->
|
||||
<!-- allow message from anybody -->
|
||||
|
||||
<!-- <deny/> -->
|
||||
<!-- will deny anything else -->
|
||||
</acl>
|
||||
|
||||
</jggtrans>
|
||||
@@ -1,128 +0,0 @@
|
||||
<!-- jit.xml -->
|
||||
|
||||
<jabber>
|
||||
|
||||
<!--
|
||||
You need to add elogger and rlogger entries here when using ejabberd.
|
||||
In this case the transport will do the logging.
|
||||
-->
|
||||
|
||||
<log id='elogger'>
|
||||
<host/>
|
||||
<logtype/>
|
||||
<file>/var/log/jabber/jit-error</file> <!-- WPJabber logs with date. -->
|
||||
</log>
|
||||
|
||||
<log id='rlogger'>
|
||||
<host/>
|
||||
<logtype>record</logtype>
|
||||
<file>/var/log/jabber/jit-record</file> <!-- WPJabber logs with date. -->
|
||||
</log>
|
||||
|
||||
<!--
|
||||
ejabberd do not provide XDB services.
|
||||
xdb_file-jit.so (the renamed xdb_file.so from WPJabber) is
|
||||
loaded in to handle all XDB requests.
|
||||
Read also the documentation in xdb_file/README from the JIT package.
|
||||
-->
|
||||
|
||||
<xdb id="xdb">
|
||||
<host/>
|
||||
<load>
|
||||
<xdb_file>/usr/local/lib/jabber/xdb_file.so</xdb_file> <!-- The xdb_file.so from WPJabber/JIT. -->
|
||||
</load>
|
||||
<xdb_file xmlns="jabber:config:xdb_file">
|
||||
<spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
|
||||
</xdb_file>
|
||||
</xdb>
|
||||
|
||||
<!--
|
||||
Make sure that all host names here are resolveable via DNS if you
|
||||
want the transport to be available to the public.
|
||||
-->
|
||||
|
||||
<service id="icq.SERVER.COM">
|
||||
<!--
|
||||
Replace SERVER.COM with the same as above to enable sms.
|
||||
-->
|
||||
<host>sms.icq.SERVER.COM</host>
|
||||
<!-- JIT configuration. -->
|
||||
<icqtrans xmlns="jabber:config:icqtrans">
|
||||
<sms>
|
||||
<host>sms.icq.SERVER.COM</host>
|
||||
<!-- Status of virtual "sms-contacts". -->
|
||||
<show>away</show>
|
||||
<status/>
|
||||
</sms>
|
||||
<instructions>Fill in your UIN and password.</instructions>
|
||||
<search>Search ICQ users.</search>
|
||||
<vCard>
|
||||
<FN>ICQ Transport (JIT)</FN>
|
||||
<DESC>This is the Jabber ICQ Transport.</DESC>
|
||||
<MAIL>EMAIL@ADDRESS.COM</MAIL>
|
||||
<URL>http://jit.jabberstudio.org/</URL>
|
||||
</vCard>
|
||||
<!-- Hashtable for users. -->
|
||||
<prime>3907</prime>
|
||||
<!-- Send messages from ICQ as chat to Jabber clients. -->
|
||||
<chat/>
|
||||
<!-- Enable this for ICQ web presence. -->
|
||||
<web/>
|
||||
<!--
|
||||
If you don't want jabber:x:data forms
|
||||
in reg and search uncomment this tag
|
||||
(Not recomended).
|
||||
-->
|
||||
<no_xdata/>
|
||||
<!--
|
||||
This tag is necessary when using ejabberd.
|
||||
In this way JIT will have its own contact list.
|
||||
-->
|
||||
<own_roster/>
|
||||
<!--
|
||||
When present, this tag will tell JIT not to try to
|
||||
get the user's roster (which will take a bit of time
|
||||
to fail in scenarios described above).
|
||||
-->
|
||||
<no_jabber_roster/>
|
||||
<!-- File with stats. -->
|
||||
<user_count_file>/var/spool/jabber/jit-count</user_count_file>
|
||||
<!--
|
||||
Interval beetween checking sessions: ping, messages, acks.
|
||||
-->
|
||||
<session_check>5</session_check>
|
||||
<!-- Reconnect retries. -->
|
||||
<reconnects>5</reconnects>
|
||||
<!--
|
||||
Time in sec when session can be inactive, 0=disabled.
|
||||
-->
|
||||
<session_timeout>18000</session_timeout>
|
||||
<charset>windows-1252</charset>
|
||||
<server>
|
||||
<host port="5190">login.icq.com</host>
|
||||
</server>
|
||||
</icqtrans>
|
||||
<!-- JIT module. -->
|
||||
<load>
|
||||
<icqtrans>/usr/local/lib/jabber/jit.so</icqtrans>
|
||||
</load>
|
||||
</service>
|
||||
|
||||
<!--
|
||||
The settings below have to match the settings you made
|
||||
in your ejabberd.cfg configuration file.
|
||||
-->
|
||||
|
||||
<service id="icq-linker">
|
||||
<host>SERVER.COM</host>
|
||||
<uplink/>
|
||||
<connect>
|
||||
<ip>127.0.0.1</ip>
|
||||
<port>5234</port>
|
||||
<secret>SECRET</secret>
|
||||
</connect>
|
||||
</service>
|
||||
|
||||
<pidfile>/var/run/jabber/jit.pid</pidfile>
|
||||
|
||||
</jabber>
|
||||
@@ -1,118 +0,0 @@
|
||||
<!-- msn-transport.xml -->
|
||||
|
||||
<jabber>
|
||||
|
||||
<!--
|
||||
You need to add elogger and rlogger entries here when using ejabberd.
|
||||
In this case the transport will do the logging.
|
||||
-->
|
||||
|
||||
<log id='elogger'>
|
||||
<host/>
|
||||
<logtype/>
|
||||
<format>%d: [%t] (%h): %s</format>
|
||||
<file>/var/log/jabber/msn-transport-error.log</file>
|
||||
</log>
|
||||
|
||||
<log id='rlogger'>
|
||||
<host/>
|
||||
<logtype>record</logtype>
|
||||
<format>%d %h %s</format>
|
||||
<file>/var/log/jabber/msn-transport-record.log</file>
|
||||
</log>
|
||||
|
||||
<!--
|
||||
ejabberd do not provide XDB services.
|
||||
xdb_file.so is loaded in to handle all XDB requests.
|
||||
-->
|
||||
|
||||
<xdb id="xdb">
|
||||
<host/>
|
||||
<load>
|
||||
<xdb_file>/usr/local/lib/jabber/libjabberdxdbfile.so</xdb_file>
|
||||
</load>
|
||||
<xdb_file xmlns="jabber:config:xdb_file">
|
||||
<spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
|
||||
</xdb_file>
|
||||
</xdb>
|
||||
|
||||
<!--
|
||||
Make sure that all host names here are resolveable via DNS if you
|
||||
want the transport to be available to the public.
|
||||
-->
|
||||
|
||||
<service id="msn.SERVER.COM">
|
||||
<!-- msn-transport configuration. -->
|
||||
<msntrans xmlns="jabber:config:msntrans">
|
||||
<instructions>Fill in your MSN account and password (eg: user1@hotmail.com). A nickname is optional.</instructions>
|
||||
<vCard>
|
||||
<FN>MSN Transport</FN>
|
||||
<DESC>This is the MSN Transport.</DESC>
|
||||
<EMAIL>EMAIL@ADDRESS.COM</EMAIL>
|
||||
<URL>http://msn-transport.jabberstudio.org/</URL>
|
||||
</vCard>
|
||||
<!--
|
||||
Conference support allows you to create groupchat rooms on the
|
||||
msn-transport and invite MSN users to join.
|
||||
-->
|
||||
<conference id="conference.msn.SERVER.COM">
|
||||
<!--
|
||||
This will make MSN transport invite you to a special groupchat
|
||||
room when more then one user joins a normal one-on-one session.
|
||||
Joining this room will make MSN transport "switch" the session
|
||||
into groupchat mode. If you ignore it, MSN transport will
|
||||
continue to send the messages as one-on-one chats.
|
||||
-->
|
||||
<invite>More than one user entered this chat session. Enter this room to switch to groupchat modus.</invite>
|
||||
<notice>
|
||||
<join> is available</join>
|
||||
<leave> has leaved the room</leave>
|
||||
</notice>
|
||||
</conference>
|
||||
<!-- Enable Hotmail inbox notification. -->
|
||||
<headlines/>
|
||||
<!--
|
||||
Enable fancy friendly names
|
||||
If the user enters a nickname upon registration, and the user has
|
||||
a status message, their MSN friendly name will be "nickname - status message".
|
||||
|
||||
If the user does not enter a nickname on registration, but they do have
|
||||
a status message, their friendly name will just be their status message.
|
||||
|
||||
If the user did enter a nickname on registration, but they have a blank status message,
|
||||
then their friendly name will just be the registered nickname.
|
||||
|
||||
If the user did not enter a nickname on registration, and they have a blank status message,
|
||||
their nickname will just be the username portion of their JID.
|
||||
|
||||
If the above chosen friendly name is too long, then it will be truncated and "..." placed
|
||||
at the end. MSN only supports friendly names of 128 characters, so this is unavoidable.
|
||||
|
||||
If this is disabled, then the registered nick is always sent as the MSN friendly name,
|
||||
or if that is blank, the username portion of their JID is sent instead.
|
||||
-->
|
||||
<fancy_friendly/>
|
||||
</msntrans>
|
||||
<!-- msn-transport module. -->
|
||||
<load>
|
||||
<msntrans>/usr/local/lib/jabber/msn-transport.so</msntrans>
|
||||
</load>
|
||||
</service>
|
||||
|
||||
<!--
|
||||
The settings below have to match the settings you made
|
||||
in your ejabberd.cfg configuration file.
|
||||
-->
|
||||
|
||||
<service id="msn-linker">
|
||||
<uplink/>
|
||||
<connect>
|
||||
<ip>127.0.0.1</ip>
|
||||
<port>5235</port>
|
||||
<secret>SECRET</secret>
|
||||
</connect>
|
||||
</service>
|
||||
|
||||
<pidfile>/var/run/jabber/msn-transport.pid</pidfile>
|
||||
|
||||
</jabber>
|
||||
@@ -1,86 +0,0 @@
|
||||
<!-- yahoo-transport-2.xml -->
|
||||
|
||||
<jabber>
|
||||
|
||||
<!--
|
||||
You need to add the elogger entry here when using ejabberd.
|
||||
In this case the transport will do the logging.
|
||||
-->
|
||||
|
||||
<log id='elogger'>
|
||||
<host/>
|
||||
<logtype/>
|
||||
<format>%d: [%t] (%h): %s</format>
|
||||
<file>/var/log/jabber/yahoo-transport-2-error.log</file>
|
||||
<stderr/>
|
||||
</log>
|
||||
|
||||
<!--
|
||||
ejabberd do not provide XDB services.
|
||||
xdb_file.so is loaded in to handle all XDB requests.
|
||||
-->
|
||||
|
||||
<xdb id="xdb">
|
||||
<host/>
|
||||
<load>
|
||||
<xdb_file>/usr/local/lib/jabber/libjabberdxdbfile.so</xdb_file>
|
||||
</load>
|
||||
<xdb_file xmlns="jabber:config:xdb_file">
|
||||
<spool><jabberd:cmdline flag='s'>/var/spool/jabber</jabberd:cmdline></spool>
|
||||
</xdb_file>
|
||||
</xdb>
|
||||
|
||||
<!--
|
||||
Make sure that all host names here are resolveable via DNS if you
|
||||
want the transport to be available to the public.
|
||||
-->
|
||||
|
||||
<service id="yahoo.SERVER.COM">
|
||||
<!-- yahoo-transport-2 configuration. -->
|
||||
<config xmlns="jabber:config:yahoo">
|
||||
<vCard>
|
||||
<NAME>Yahoo! Transport</NAME>
|
||||
<FN>vCard not implemented in current version</FN>
|
||||
<DESC>This is the Yahoo! transport.</DESC>
|
||||
<MAIL>EMAIL@ADDRESS.COM</MAIL>
|
||||
<URL>http://yahoo-transport-2.jabberstudio.org/</URL>
|
||||
</vCard>
|
||||
<instructions>Fill in your YAHOO! Messenger username and password to register on this transport.</instructions>
|
||||
<server>scs.msg.yahoo.com</server>
|
||||
<port>5050</port>
|
||||
<!--
|
||||
The character map. This provides character set translation from UTF-8
|
||||
to the indicated character map. See the man page for 'iconv' for available
|
||||
character maps on your platform. CP1252 is the standard Windows character
|
||||
set.
|
||||
-->
|
||||
<charmap>CP1252</charmap>
|
||||
<!--
|
||||
When this element exists, the transport will send new mail notifications as
|
||||
well as a count of unread messages when the user initially logs in.
|
||||
-->
|
||||
<newmail/>
|
||||
</config>
|
||||
<!-- yahoo-transport-2 module. -->
|
||||
<load>
|
||||
<yahoo_transport>/usr/local/lib/jabber/yahoo-transport-2.so</yahoo_transport>
|
||||
</load>
|
||||
</service>
|
||||
|
||||
<!--
|
||||
The settings below have to match the settings you made
|
||||
in your ejabberd.cfg configuration file.
|
||||
-->
|
||||
|
||||
<service id="yahoo-linker">
|
||||
<uplink/>
|
||||
<connect>
|
||||
<ip>127.0.0.1</ip>
|
||||
<port>5236</port>
|
||||
<secret>SECRET</secret>
|
||||
</connect>
|
||||
</service>
|
||||
|
||||
<pidfile>/var/run/jabber/yahoo-transport-2.pid</pidfile>
|
||||
|
||||
</jabber>
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/bin/sh
|
||||
#########################################################
|
||||
#
|
||||
# aim-transport -- script to start aim-transport.
|
||||
#
|
||||
#########################################################
|
||||
|
||||
DAEMON=/usr/local/sbin/jabberd-aim-transport
|
||||
CONF=/etc/jabber/aim-transport.xml
|
||||
NAME=jabberd-aim-transport
|
||||
HOME=/etc/jabber/
|
||||
USER=ejabberd
|
||||
|
||||
#########################################################
|
||||
|
||||
if [ "`/usr/bin/whoami`" != "$USER" ]; then
|
||||
|
||||
echo "You need to be" $USER "user to run this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
debug)
|
||||
test -f $DAEMON -a -f $CONF || exit 0
|
||||
echo "Starting $NAME in debugging mode."
|
||||
$DAEMON -D -H $HOME -c $CONF &
|
||||
;;
|
||||
start)
|
||||
test -f $DAEMON -a -f $CONF || exit 0
|
||||
echo "Starting $NAME."
|
||||
$DAEMON -H $HOME -c $CONF &
|
||||
;;
|
||||
stop)
|
||||
echo "Stopping $NAME."
|
||||
killall $NAME &
|
||||
;;
|
||||
restart|reload)
|
||||
$0 stop
|
||||
sleep 3
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {debug|start|stop|restart}"
|
||||
exit 1
|
||||
esac
|
||||
@@ -1,43 +0,0 @@
|
||||
#!/bin/sh
|
||||
#########################################################
|
||||
#
|
||||
# ile -- script to start ILE.
|
||||
#
|
||||
#########################################################
|
||||
|
||||
DAEMON=/usr/local/sbin/ile.pl
|
||||
NAME=ile.pl
|
||||
CONF=/etc/jabber/ile.xml
|
||||
USER=ejabberd
|
||||
|
||||
#########################################################
|
||||
|
||||
if [ "`/usr/bin/whoami`" != "$USER" ]; then
|
||||
|
||||
echo "You need to be" $USER "user to run this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
debug)
|
||||
echo "Not implemented yet. Starting in normal mode"
|
||||
$0 start
|
||||
;;
|
||||
start)
|
||||
test -f $DAEMON || exit 0
|
||||
echo "Starting $NAME."
|
||||
$DAEMON $CONF &
|
||||
;;
|
||||
stop)
|
||||
echo "Stopping $NAME."
|
||||
killall $NAME &
|
||||
;;
|
||||
restart|reload)
|
||||
$0 stop
|
||||
sleep 3
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {debug|start|stop|status|restart}"
|
||||
exit 1
|
||||
esac
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/bin/sh
|
||||
#########################################################
|
||||
#
|
||||
# jabber-gg-transport -- script to start jabber-gg-transport.
|
||||
#
|
||||
#########################################################
|
||||
|
||||
DAEMON=/usr/local/sbin/jggtrans
|
||||
CONF=/etc/jabber/jabber-gg-transport.xml
|
||||
NAME=jggtrans
|
||||
HOME=/etc/jabber/
|
||||
USER=ejabberd
|
||||
|
||||
#########################################################
|
||||
|
||||
if [ "`/usr/bin/whoami`" != "$USER" ]; then
|
||||
|
||||
echo "You need to be" $USER "user to run this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
debug)
|
||||
test -f $DAEMON -a -f $CONF || exit 0
|
||||
echo "Starting $NAME in debugging mode."
|
||||
$DAEMON -D -H $HOME -c $CONF &
|
||||
;;
|
||||
start)
|
||||
test -f $DAEMON -a -f $CONF || exit 0
|
||||
echo "Starting $NAME."
|
||||
$DAEMON $CONF &
|
||||
;;
|
||||
stop)
|
||||
echo "Stopping $NAME."
|
||||
killall $NAME &
|
||||
rm /var/run/jabber/jabber-gg-transport.pid
|
||||
;;
|
||||
|
||||
restart|reload)
|
||||
$0 stop
|
||||
sleep 3
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {debug|start|stop|restart}"
|
||||
exit 1
|
||||
esac
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/bin/sh
|
||||
#########################################################
|
||||
#
|
||||
# jit -- script to start JIT.
|
||||
#
|
||||
#########################################################
|
||||
|
||||
DAEMON=/usr/local/sbin/wpjabber-jit
|
||||
CONF=/etc/jabber/jit.xml
|
||||
NAME=wpjabber-jit
|
||||
HOME=/etc/jabber/
|
||||
USER=ejabberd
|
||||
|
||||
#########################################################
|
||||
|
||||
if [ "`/usr/bin/whoami`" != "$USER" ]; then
|
||||
|
||||
echo "You need to be" $USER "user to run this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
debug)
|
||||
test -f $DAEMON -a -f $CONF || exit 0
|
||||
echo "Starting $NAME in debugging mode."
|
||||
$DAEMON -D -H $HOME -c $CONF &
|
||||
;;
|
||||
start)
|
||||
test -f $DAEMON -a -f $CONF || exit 0
|
||||
echo "Starting $NAME."
|
||||
$DAEMON -H $HOME -c $CONF &
|
||||
;;
|
||||
stop)
|
||||
echo "Stopping $NAME."
|
||||
killall $NAME &
|
||||
;;
|
||||
restart|reload)
|
||||
$0 stop
|
||||
sleep 3
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {debug|start|stop|restart}"
|
||||
exit 1
|
||||
esac
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/bin/sh
|
||||
#########################################################
|
||||
#
|
||||
# msn-transport -- script to start MSN Transport.
|
||||
#
|
||||
#########################################################
|
||||
|
||||
DAEMON=/usr/local/sbin/jabberd-msn-transport
|
||||
CONF=/etc/jabber/msn-transport.xml
|
||||
NAME=jabberd-msn-transport
|
||||
HOME=/etc/jabber/
|
||||
USER=ejabberd
|
||||
|
||||
#########################################################
|
||||
|
||||
if [ "`/usr/bin/whoami`" != "$USER" ]; then
|
||||
|
||||
echo "You need to be" $USER "user to run this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
strace)
|
||||
test -f $DAEMON -a -f $CONF || exit 0
|
||||
echo "Starting $NAME in strace mode."
|
||||
strace -o /opt/ejabberd/var/log/jabber/strace.log $DAEMON -H $HOME -c $CONF &
|
||||
;;
|
||||
debug)
|
||||
test -f $DAEMON -a -f $CONF || exit 0
|
||||
echo "Starting $NAME in debugging mode."
|
||||
$DAEMON -D -H $HOME -c $CONF &
|
||||
;;
|
||||
start)
|
||||
test -f $DAEMON -a -f $CONF || exit 0
|
||||
echo "Starting $NAME."
|
||||
$DAEMON -H $HOME -c $CONF &
|
||||
;;
|
||||
stop)
|
||||
echo "Stopping $NAME."
|
||||
killall $NAME &
|
||||
;;
|
||||
restart|reload)
|
||||
$0 stop
|
||||
sleep 3
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {debug|start|stop|restart}"
|
||||
exit 1
|
||||
esac
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/bin/sh
|
||||
##############################################################
|
||||
#
|
||||
# yahoo-transport-2 -- script to start Yahoo-transport-2.
|
||||
#
|
||||
#############################################################
|
||||
|
||||
DAEMON=/usr/local/sbin/jabberd-yahoo-transport-2
|
||||
CONF=/etc/jabber/yahoo-transport-2.xml
|
||||
NAME=jabberd-yahoo-transport-2
|
||||
HOME=/etc/jabber/
|
||||
USER=ejabberd
|
||||
|
||||
#############################################################
|
||||
|
||||
if [ "`/usr/bin/whoami`" != "$USER" ]; then
|
||||
|
||||
echo "You need to be" $USER "user to run this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
debug)
|
||||
test -f $DAEMON -a -f $CONF || exit 0
|
||||
echo "Starting $NAME in debugging mode."
|
||||
$DAEMON -D -H $HOME -c $CONF &
|
||||
;;
|
||||
start)
|
||||
test -f $DAEMON -a -f $CONF || exit 0
|
||||
echo "Starting $NAME."
|
||||
$DAEMON -H $HOME -c $CONF &
|
||||
;;
|
||||
stop)
|
||||
echo "Stopping $NAME."
|
||||
killall $NAME &
|
||||
;;
|
||||
restart|reload)
|
||||
$0 stop
|
||||
sleep 3
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {debug|start|stop|restart}"
|
||||
exit 1
|
||||
esac
|
||||
@@ -0,0 +1 @@
|
||||
*.beam
|
||||
@@ -12,145 +12,25 @@ ERLANG_CFLAGS= @ERLANG_CFLAGS@
|
||||
EXPAT_LIBS = @EXPAT_LIBS@
|
||||
ERLANG_LIBS = @ERLANG_LIBS@
|
||||
|
||||
ASN_FLAGS = -bber_bin +der +compact_bit_string +optimize +noobj
|
||||
|
||||
INSTALLUSER=@INSTALLUSER@
|
||||
# if no user was enabled, don't set privileges or ownership
|
||||
ifeq ($(INSTALLUSER),)
|
||||
O_USER=
|
||||
G_USER=
|
||||
CHOWN_COMMAND=echo
|
||||
CHOWN_OUTPUT=/dev/null
|
||||
INIT_USER=root
|
||||
else
|
||||
O_USER=-o $(INSTALLUSER)
|
||||
G_USER=-g $(INSTALLUSER)
|
||||
CHOWN_COMMAND=chown
|
||||
CHOWN_OUTPUT=&1
|
||||
INIT_USER=$(INSTALLUSER)
|
||||
endif
|
||||
|
||||
EFLAGS += @ERLANG_SSLVER@ -pa .
|
||||
ERLANG_CFLAGS += @ERLANG_SSLVER@
|
||||
|
||||
# make debug=true to compile Erlang module with debug informations.
|
||||
ifdef debug
|
||||
EFLAGS+=+debug_info
|
||||
endif
|
||||
|
||||
DEBUGTOOLS = p1_prof.erl
|
||||
ifdef debugtools
|
||||
SOURCES+=$(DEBUGTOOLS)
|
||||
endif
|
||||
|
||||
ifeq (@hipe@, true)
|
||||
EFLAGS+=+native
|
||||
endif
|
||||
|
||||
ifeq (@roster_gateway_workaround@, true)
|
||||
EFLAGS+=-DROSTER_GATEWAY_WORKAROUND
|
||||
endif
|
||||
|
||||
ifeq (@full_xml@, true)
|
||||
EFLAGS+=-DFULL_XML_SUPPORT
|
||||
endif
|
||||
|
||||
ifeq (@nif@, true)
|
||||
EFLAGS+=-DNIF
|
||||
ERLSHLIBS=xml.so
|
||||
endif
|
||||
|
||||
ifeq (@transient_supervisors@, false)
|
||||
EFLAGS+=-DNO_TRANSIENT_SUPERVISORS
|
||||
endif
|
||||
|
||||
ifeq (@md2@, true)
|
||||
EFLAGS+=-DHAVE_MD2
|
||||
ERLANG_CFLAGS += -DHAVE_MD2
|
||||
endif
|
||||
|
||||
INSTALL_EPAM=
|
||||
ifeq (@pam@, pam)
|
||||
INSTALL_EPAM=install -m 750 $(O_USER) epam $(PBINDIR)
|
||||
endif
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
SUBDIRS = @mod_irc@ @mod_pubsub@ @mod_muc@ @mod_proxy65@ @eldap@ @pam@ @web@ mysql pgsql stringprep stun @tls@ @odbc@ @ejabberd_zlib@
|
||||
ERLSHLIBS += expat_erl.so
|
||||
ERLBEHAVS = cyrsasl.erl gen_mod.erl p1_fsm.erl ejabberd_auth.erl
|
||||
SOURCES_ALL = $(wildcard *.erl)
|
||||
SOURCES_MISC = $(ERLBEHAVS) $(DEBUGTOOLS)
|
||||
SOURCES += $(filter-out $(SOURCES_MISC),$(SOURCES_ALL))
|
||||
ERLBEHAVBEAMS = $(ERLBEHAVS:.erl=.beam)
|
||||
BEAMS = $(SOURCES:.erl=.beam)
|
||||
SUBDIRS = @mod_irc@ @mod_pubsub@ @mod_muc@ @eldap@ @web@ stringprep @tls@
|
||||
ERLSHLIBS = expat_erl.so
|
||||
|
||||
DESTDIR =
|
||||
|
||||
# /etc/ejabberd/
|
||||
ETCDIR = $(DESTDIR)@sysconfdir@/ejabberd
|
||||
|
||||
# /sbin/
|
||||
SBINDIR = $(DESTDIR)@sbindir@
|
||||
|
||||
# /lib/ejabberd/
|
||||
EJABBERDDIR = $(DESTDIR)@libdir@/ejabberd
|
||||
|
||||
# /share/doc/ejabberd
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
datarootdir = @datarootdir@
|
||||
DOCDIR = $(DESTDIR)@docdir@
|
||||
|
||||
# /usr/lib/ejabberd/ebin/
|
||||
EJABBERDDIR = $(DESTDIR)/var/lib/ejabberd
|
||||
BEAMDIR = $(EJABBERDDIR)/ebin
|
||||
|
||||
# /usr/lib/ejabberd/include/
|
||||
INCLUDEDIR = $(EJABBERDDIR)/include
|
||||
|
||||
# /usr/lib/ejabberd/priv/
|
||||
PRIVDIR = $(EJABBERDDIR)/priv
|
||||
|
||||
# /usr/lib/ejabberd/priv/bin
|
||||
PBINDIR = $(PRIVDIR)/bin
|
||||
|
||||
# /usr/lib/ejabberd/priv/lib
|
||||
SODIR = $(PRIVDIR)/lib
|
||||
|
||||
# /usr/lib/ejabberd/priv/msgs
|
||||
MSGSDIR = $(PRIVDIR)/msgs
|
||||
|
||||
# /var/lib/ejabberd/
|
||||
SPOOLDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
|
||||
|
||||
# /var/lock/ejabberdctl
|
||||
CTLLOCKDIR = $(DESTDIR)@localstatedir@/lock/ejabberdctl
|
||||
|
||||
# /var/lib/ejabberd/.erlang.cookie
|
||||
COOKIEFILE = $(SPOOLDIR)/.erlang.cookie
|
||||
|
||||
# /var/log/ejabberd/
|
||||
LOGDIR = $(DESTDIR)@localstatedir@/log/ejabberd
|
||||
|
||||
# Assume Linux-style dynamic library flags
|
||||
DYNAMIC_LIB_CFLAGS = -fpic -shared
|
||||
ifeq ($(shell uname),Darwin)
|
||||
DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
|
||||
endif
|
||||
ifeq ($(shell uname),SunOs)
|
||||
DYNAMIC_LIB_CFLAGS = -KPIC -G -z text
|
||||
endif
|
||||
LOGDIR = $(DESTDIR)/var/log/ejabberd
|
||||
ETCDIR = $(DESTDIR)/etc/ejabberd
|
||||
|
||||
all: $(ERLSHLIBS) compile-beam all-recursive
|
||||
|
||||
compile-beam: XmppAddr.hrl $(ERLBEHAVBEAMS) $(BEAMS)
|
||||
|
||||
$(BEAMS): $(ERLBEHAVBEAMS)
|
||||
|
||||
all-recursive: $(ERLBEHAVBEAMS)
|
||||
|
||||
%.beam: %.erl
|
||||
@ERLC@ -W $(EFLAGS) $<
|
||||
compile-beam:
|
||||
@ERL@ -s make all report -noinput -s erlang halt
|
||||
|
||||
|
||||
all-recursive install-recursive uninstall-recursive \
|
||||
@@ -163,154 +43,37 @@ mostlyclean-recursive maintainer-clean-recursive:
|
||||
done
|
||||
|
||||
|
||||
%.hrl: %.asn1
|
||||
@ERLC@ $(ASN_FLAGS) $<
|
||||
@ERLC@ -W $(EFLAGS) $*.erl
|
||||
|
||||
$(ERLSHLIBS): %.so: %.c
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) \
|
||||
$(subst ../,,$(subst .so,.c,$@)) \
|
||||
$(EXPAT_LIBS) \
|
||||
$(EXPAT_CFLAGS) \
|
||||
$(ERLANG_LIBS) \
|
||||
$(ERLANG_CFLAGS) \
|
||||
-o $@ \
|
||||
$(DYNAMIC_LIB_CFLAGS)
|
||||
|
||||
translations:
|
||||
../contrib/extract_translations/prepare-translation.sh -updateall
|
||||
gcc -Wall $(CFLAGS) $(LDFLAGS) $(LIBS) \
|
||||
$(subst ../,,$(subst .so,.c,$@)) \
|
||||
$(EXPAT_LIBS) $(EXPAT_CFLAGS) \
|
||||
$(ERLANG_LIBS) $(ERLANG_CFLAGS) \
|
||||
-o $@ -fpic -shared
|
||||
|
||||
install: all
|
||||
#
|
||||
# Configuration files
|
||||
install -d -m 750 $(G_USER) $(ETCDIR)
|
||||
[ -f $(ETCDIR)/ejabberd.cfg ] \
|
||||
&& install -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg-new \
|
||||
|| install -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
|
||||
sed -e "s*@rootdir@*@prefix@*" \
|
||||
-e "s*@installuser@*@INSTALLUSER@*" \
|
||||
-e "s*@LIBDIR@*@libdir@*" \
|
||||
-e "s*@SYSCONFDIR@*@sysconfdir@*" \
|
||||
-e "s*@LOCALSTATEDIR@*@localstatedir@*" \
|
||||
-e "s*@DOCDIR@*@docdir@*" \
|
||||
-e "s*@erl@*@ERL@*" ejabberdctl.template \
|
||||
> ejabberdctl.example
|
||||
[ -f $(ETCDIR)/ejabberdctl.cfg ] \
|
||||
&& install -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg-new \
|
||||
|| install -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg
|
||||
install -b -m 644 $(G_USER) inetrc $(ETCDIR)/inetrc
|
||||
#
|
||||
# Administration script
|
||||
[ -d $(SBINDIR) ] || install -d -m 755 $(SBINDIR)
|
||||
install -m 550 $(G_USER) ejabberdctl.example $(SBINDIR)/ejabberdctl
|
||||
#
|
||||
# Init script
|
||||
sed -e "s*@ctlscriptpath@*$(SBINDIR)*" \
|
||||
-e "s*@installuser@*$(INIT_USER)*" ejabberd.init.template \
|
||||
> ejabberd.init
|
||||
chmod 755 ejabberd.init
|
||||
#
|
||||
# Binary Erlang files
|
||||
install -d $(BEAMDIR)
|
||||
install -m 644 *.app $(BEAMDIR)
|
||||
install -m 644 *.beam $(BEAMDIR)
|
||||
rm -f $(BEAMDIR)/configure.beam
|
||||
#
|
||||
# ejabberd header files
|
||||
install -d $(INCLUDEDIR)
|
||||
install -m 644 *.hrl $(INCLUDEDIR)
|
||||
install -d $(INCLUDEDIR)/eldap/
|
||||
install -m 644 eldap/*.hrl $(INCLUDEDIR)/eldap/
|
||||
install -d $(INCLUDEDIR)/mod_muc/
|
||||
install -m 644 mod_muc/*.hrl $(INCLUDEDIR)/mod_muc/
|
||||
install -d $(INCLUDEDIR)/mod_proxy65/
|
||||
install -m 644 mod_proxy65/*.hrl $(INCLUDEDIR)/mod_proxy65/
|
||||
install -d $(INCLUDEDIR)/mod_pubsub/
|
||||
install -m 644 mod_pubsub/*.hrl $(INCLUDEDIR)/mod_pubsub/
|
||||
install -d $(INCLUDEDIR)/web/
|
||||
install -m 644 web/*.hrl $(INCLUDEDIR)/web/
|
||||
#
|
||||
# Binary C programs
|
||||
install -d $(PBINDIR)
|
||||
install -m 750 $(O_USER) ../tools/captcha.sh $(PBINDIR)
|
||||
$(INSTALL_EPAM)
|
||||
#
|
||||
# Binary system libraries
|
||||
install -m 644 *.app $(BEAMDIR)
|
||||
install -d $(SODIR)
|
||||
install -m 644 *.so $(SODIR)
|
||||
#
|
||||
# Translated strings
|
||||
install -d $(MSGSDIR)
|
||||
install -m 644 msgs/*.msg $(MSGSDIR)
|
||||
#
|
||||
# Spool directory
|
||||
install -d -m 750 $(O_USER) $(SPOOLDIR)
|
||||
$(CHOWN_COMMAND) -R @INSTALLUSER@ $(SPOOLDIR) >$(CHOWN_OUTPUT)
|
||||
chmod -R 750 $(SPOOLDIR)
|
||||
[ ! -f $(COOKIEFILE) ] || { $(CHOWN_COMMAND) @INSTALLUSER@ $(COOKIEFILE) >$(CHOWN_OUTPUT) ; chmod 400 $(COOKIEFILE) ; }
|
||||
#
|
||||
# ejabberdctl lock directory
|
||||
install -d -m 750 $(O_USER) $(CTLLOCKDIR)
|
||||
$(CHOWN_COMMAND) -R @INSTALLUSER@ $(CTLLOCKDIR) >$(CHOWN_OUTPUT)
|
||||
chmod -R 750 $(CTLLOCKDIR)
|
||||
#
|
||||
# Log directory
|
||||
install -d -m 750 $(O_USER) $(LOGDIR)
|
||||
$(CHOWN_COMMAND) -R @INSTALLUSER@ $(LOGDIR) >$(CHOWN_OUTPUT)
|
||||
chmod -R 750 $(LOGDIR)
|
||||
#
|
||||
# Documentation
|
||||
install -d $(DOCDIR)
|
||||
install -m 644 ../doc/dev.html $(DOCDIR)
|
||||
install -m 644 ../doc/guide.html $(DOCDIR)
|
||||
install -m 644 ../doc/*.png $(DOCDIR)
|
||||
install -m 644 ../doc/*.txt $(DOCDIR)
|
||||
[ -f ../doc/guide.pdf ] \
|
||||
&& install -m 644 ../doc/guide.pdf $(DOCDIR) \
|
||||
|| echo "No ../doc/guide.pdf was built"
|
||||
install -m 644 ../COPYING $(DOCDIR)
|
||||
|
||||
uninstall: uninstall-binary
|
||||
|
||||
uninstall-binary:
|
||||
rm -f $(SBINDIR)/ejabberdctl
|
||||
rm -fr $(DOCDIR)
|
||||
rm -f $(BEAMDIR)/*.beam
|
||||
rm -f $(BEAMDIR)/*.app
|
||||
rm -fr $(BEAMDIR)
|
||||
rm -f $(INCLUDEDIR)/*.hrl
|
||||
rm -fr $(INCLUDEDIR)
|
||||
rm -fr $(PBINDIR)
|
||||
rm -f $(SODIR)/*.so
|
||||
rm -fr $(SODIR)
|
||||
rm -f $(MSGSDIR)/*.msgs
|
||||
rm -fr $(MSGSDIR)
|
||||
rm -fr $(PRIVDIR)
|
||||
rm -fr $(EJABBERDDIR)
|
||||
|
||||
uninstall-all: uninstall-binary
|
||||
rm -rf $(ETCDIR)
|
||||
rm -rf $(EJABBERDDIR)
|
||||
rm -rf $(SPOOLDIR)
|
||||
rm -rf $(CTLLOCKDIR)
|
||||
rm -rf $(LOGDIR)
|
||||
install -d $(ETCDIR)
|
||||
install -b -m 644 ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
|
||||
install -d $(LOGDIR)
|
||||
|
||||
clean: clean-recursive clean-local
|
||||
|
||||
clean-local:
|
||||
rm -f *.beam $(ERLSHLIBS) epam ejabberdctl.example
|
||||
rm -f XmppAddr.asn1db XmppAddr.erl XmppAddr.hrl
|
||||
rm -f *.beam $(ERLSHLIBS)
|
||||
|
||||
distclean: distclean-recursive clean-local
|
||||
rm -f config.status
|
||||
rm -f config.log
|
||||
rm -f Makefile
|
||||
[ ! -f ../ChangeLog ] || rm -f ../ChangeLog
|
||||
|
||||
TAGS:
|
||||
etags *.erl
|
||||
|
||||
Makefile: Makefile.in
|
||||
|
||||
dialyzer: $(BEAMS)
|
||||
@dialyzer -c .
|
||||
|
||||
@@ -8,8 +8,8 @@ EREL=$(REL)\ejabberd-$(EJABBERD_VERSION)
|
||||
EBIN_DIR=$(EREL)\ebin
|
||||
SRC_DIR=$(EREL)\src
|
||||
PRIV_DIR=$(EREL)\priv
|
||||
SO_DIR=$(EREL)
|
||||
MSGS_DIR=$(EREL)\msgs
|
||||
SO_DIR=$(PRIV_DIR)\lib
|
||||
MSGS_DIR=$(PRIV_DIR)\msgs
|
||||
WIN32_DIR=$(EREL)\win32
|
||||
DOC_DIR=$(EREL)\doc
|
||||
|
||||
@@ -35,12 +35,13 @@ release : build release_clean
|
||||
copy *.beam $(EBIN_DIR)
|
||||
@erase $(EBIN_DIR)\configure.beam
|
||||
copy *.app $(EBIN_DIR)
|
||||
mkdir $(PRIV_DIR)
|
||||
mkdir $(SO_DIR)
|
||||
copy *.dll $(SO_DIR)
|
||||
mkdir $(MSGS_DIR)
|
||||
copy msgs\*.msg $(MSGS_DIR)
|
||||
mkdir $(WIN32_DIR)
|
||||
copy win32\ejabberd.cfg $(EREL)
|
||||
copy win32\inetrc $(EREL)
|
||||
copy $(SYSTEMROOT)\system32\libeay32.dll $(EREL)
|
||||
copy $(SYSTEMROOT)\system32\ssleay32.dll $(EREL)
|
||||
copy win32\ejabberd.ico $(WIN32_DIR)
|
||||
@@ -59,29 +60,15 @@ release : build release_clean
|
||||
copy mod_muc\*.erl $(SRC_DIR)\mod_muc
|
||||
mkdir $(SRC_DIR)\mod_pubsub
|
||||
copy mod_pubsub\*.erl $(SRC_DIR)\mod_pubsub
|
||||
mkdir $(SRC_DIR)\mod_proxy65
|
||||
copy mod_proxy65\*.erl $(SRC_DIR)\mod_proxy65
|
||||
copy mod_proxy65\*.hrl $(SRC_DIR)\mod_proxy65
|
||||
mkdir $(SRC_DIR)\stringprep
|
||||
copy stringprep\*.erl $(SRC_DIR)\stringprep
|
||||
copy stringprep\*.c $(SRC_DIR)\stringprep
|
||||
copy stringprep\*.tcl $(SRC_DIR)\stringprep
|
||||
mkdir $(SRC_DIR)\stun
|
||||
copy stun\*.erl $(SRC_DIR)\stun
|
||||
copy stun\*.hrl $(SRC_DIR)\stun
|
||||
mkdir $(SRC_DIR)\tls
|
||||
copy tls\*.erl $(SRC_DIR)\tls
|
||||
copy tls\*.c $(SRC_DIR)\tls
|
||||
mkdir $(SRC_DIR)\ejabberd_zlib
|
||||
copy ejabberd_zlib\*.erl $(SRC_DIR)\ejabberd_zlib
|
||||
copy ejabberd_zlib\*.c $(SRC_DIR)\ejabberd_zlib
|
||||
mkdir $(SRC_DIR)\web
|
||||
copy web\*.erl $(SRC_DIR)\web
|
||||
mkdir $(SRC_DIR)\odbc
|
||||
copy odbc\*.erl $(SRC_DIR)\odbc
|
||||
copy odbc\*.sql $(EREL)
|
||||
mkdir $(DOC_DIR)
|
||||
copy ..\doc\*.txt $(DOC_DIR)
|
||||
copy ..\doc\*.html $(DOC_DIR)
|
||||
copy ..\doc\*.png $(DOC_DIR)
|
||||
|
||||
@@ -100,28 +87,17 @@ all-recursive :
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\mod_pubsub
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\mod_proxy65
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\stringprep
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\stun
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\tls
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\ejabberd_zlib
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\web
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..\odbc
|
||||
nmake -nologo -f Makefile.win32
|
||||
cd ..
|
||||
|
||||
compile-beam : XmppAddr.hrl
|
||||
compile-beam :
|
||||
erl -s make all report -noinput -s erlang halt
|
||||
|
||||
XmppAddr.hrl : XmppAddr.asn1
|
||||
erlc -bber_bin +der +compact_bit_string +optimize +noobj XmppAddr.asn1
|
||||
|
||||
CLEAN : clean-recursive clean-local
|
||||
|
||||
clean-local :
|
||||
@@ -130,9 +106,6 @@ clean-local :
|
||||
-@erase expat_erl.exp
|
||||
-@erase expat_erl.lib
|
||||
-@erase *.beam
|
||||
-@erase XmppAddr.asn1db
|
||||
-@erase XmppAddr.erl
|
||||
-@erase XmppAddr.hrl
|
||||
|
||||
clean-recursive :
|
||||
cd eldap
|
||||
@@ -143,20 +116,12 @@ clean-recursive :
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\mod_pubsub
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\mod_proxy65
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\stringprep
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\stun
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\tls
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\ejabberd_zlib
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\web
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..\odbc
|
||||
nmake -nologo -f Makefile.win32 clean
|
||||
cd ..
|
||||
|
||||
distclean : release_clean clean
|
||||
@@ -170,7 +135,8 @@ LD=link.exe
|
||||
LD_FLAGS=-release -nologo -incremental:no -dll "$(EI_DIR)\lib\ei_md.lib" "$(EI_DIR)\lib\erl_interface_md.lib" "$(EXPAT_LIB)" MSVCRT.LIB kernel32.lib advapi32.lib gdi32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib
|
||||
|
||||
$(DLL) : $(OBJECT)
|
||||
$(LD) $(LD_FLAGS) -out:$@ $<
|
||||
$(LD) $(LD_FLAGS) -out:$(DLL) $(OBJECT)
|
||||
|
||||
$(OBJECT) : $(SOURCE)
|
||||
$(CC) $(CC_FLAGS) -c -Fo$@ $<
|
||||
$(CC) $(CC_FLAGS) -c -Fo$(OBJECT) $(SOURCE)
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
XmppAddr { iso(1) identified-organization(3)
|
||||
dod(6) internet(1) security(5) mechanisms(5) pkix(7)
|
||||
id-on(8) id-on-xmppAddr(5) }
|
||||
|
||||
DEFINITIONS EXPLICIT TAGS ::=
|
||||
BEGIN
|
||||
|
||||
id-on-xmppAddr OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
|
||||
dod(6) internet(1) security(5) mechanisms(5) pkix(7)
|
||||
id-on(8) 5 }
|
||||
|
||||
XmppAddr ::= UTF8String
|
||||
|
||||
END
|
||||
@@ -1,288 +1,150 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : acl.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose : ACL support
|
||||
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(acl).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
-export([start/0, to_record/3, add/3, add_list/3,
|
||||
match_rule/3, match_acl/3]).
|
||||
-export([start/0,
|
||||
to_record/2,
|
||||
add/2,
|
||||
add_list/2,
|
||||
match_rule/2,
|
||||
% for debugging only
|
||||
match_acl/2]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-record(acl, {aclname, aclspec}).
|
||||
|
||||
-type regexp() :: binary().
|
||||
-type glob() :: binary().
|
||||
-type aclname() :: {atom(), binary() | global}.
|
||||
-type aclspec() :: all | none |
|
||||
{user, binary()} |
|
||||
{user, binary(), binary()} |
|
||||
{server, binary()} |
|
||||
{resource, binary()} |
|
||||
{user_regexp, regexp()} |
|
||||
{shared_group, binary()} |
|
||||
{shared_group, binary(), binary()} |
|
||||
{user_regexp, regexp(), binary()} |
|
||||
{server_regexp, regexp()} |
|
||||
{resource_regexp, regexp()} |
|
||||
{node_regexp, regexp(), regexp()} |
|
||||
{user_glob, glob()} |
|
||||
{user_glob, glob(), binary()} |
|
||||
{server_glob, glob()} |
|
||||
{resource_glob, glob()} |
|
||||
{node_glob, glob(), glob()}.
|
||||
|
||||
-type acl() :: #acl{aclname :: aclname(),
|
||||
aclspec :: aclspec()}.
|
||||
|
||||
-export_type([acl/0]).
|
||||
|
||||
start() ->
|
||||
mnesia:create_table(acl,
|
||||
[{disc_copies, [node()]}, {type, bag},
|
||||
[{disc_copies, [node()]},
|
||||
{type, bag},
|
||||
{attributes, record_info(fields, acl)}]),
|
||||
mnesia:add_table_copy(acl, node(), ram_copies),
|
||||
update_table(),
|
||||
ok.
|
||||
|
||||
-spec to_record(binary(), atom(), aclspec()) -> acl().
|
||||
to_record(ACLName, ACLSpec) ->
|
||||
#acl{aclname = ACLName, aclspec = ACLSpec}.
|
||||
|
||||
to_record(Host, ACLName, ACLSpec) ->
|
||||
#acl{aclname = {ACLName, Host},
|
||||
aclspec = normalize_spec(ACLSpec)}.
|
||||
|
||||
-spec add(binary(), aclname(), aclspec()) -> {atomic, ok} | {aborted, any()}.
|
||||
|
||||
add(Host, ACLName, ACLSpec) ->
|
||||
F = fun () ->
|
||||
mnesia:write(#acl{aclname = {ACLName, Host},
|
||||
aclspec = normalize_spec(ACLSpec)})
|
||||
add(ACLName, ACLSpec) ->
|
||||
F = fun() ->
|
||||
mnesia:write(#acl{aclname = ACLName, aclspec = ACLSpec})
|
||||
end,
|
||||
mnesia:transaction(F).
|
||||
|
||||
-spec add_list(binary(), [acl()], boolean()) -> false | ok.
|
||||
|
||||
add_list(Host, ACLs, Clear) ->
|
||||
F = fun () ->
|
||||
if Clear ->
|
||||
Ks = mnesia:select(acl,
|
||||
[{{acl, {'$1', Host}, '$2'}, [],
|
||||
['$1']}]),
|
||||
lists:foreach(fun (K) -> mnesia:delete({acl, {K, Host}})
|
||||
end,
|
||||
Ks);
|
||||
true -> ok
|
||||
add_list(ACLs, Clear) ->
|
||||
F = fun() ->
|
||||
if
|
||||
Clear ->
|
||||
Ks = mnesia:all_keys(acl),
|
||||
lists:foreach(fun(K) ->
|
||||
mnesia:delete({acl, K})
|
||||
end, Ks);
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
lists:foreach(fun (ACL) ->
|
||||
lists:foreach(fun(ACL) ->
|
||||
case ACL of
|
||||
#acl{aclname = ACLName,
|
||||
aclspec = ACLSpec} ->
|
||||
mnesia:write(#acl{aclname =
|
||||
{ACLName,
|
||||
Host},
|
||||
aclspec =
|
||||
normalize_spec(ACLSpec)})
|
||||
#acl{} ->
|
||||
mnesia:write(ACL)
|
||||
end
|
||||
end,
|
||||
ACLs)
|
||||
end, ACLs)
|
||||
end,
|
||||
case mnesia:transaction(F) of
|
||||
{atomic, _} -> ok;
|
||||
_ -> false
|
||||
{atomic, _} ->
|
||||
ok;
|
||||
_ ->
|
||||
false
|
||||
end.
|
||||
|
||||
normalize(A) -> jlib:nodeprep(iolist_to_binary(A)).
|
||||
|
||||
normalize_spec({A, B}) -> {A, normalize(B)};
|
||||
normalize_spec({A, B, C}) ->
|
||||
{A, normalize(B), normalize(C)};
|
||||
normalize_spec(all) -> all;
|
||||
normalize_spec(none) -> none.
|
||||
|
||||
-spec match_rule(global | binary(), atom(), jid() | ljid()) -> any().
|
||||
|
||||
match_rule(global, Rule, JID) ->
|
||||
match_rule(Rule, JID) ->
|
||||
case Rule of
|
||||
all -> allow;
|
||||
none -> deny;
|
||||
_ ->
|
||||
case ejabberd_config:get_global_option(
|
||||
{access, Rule, global}, fun(V) -> V end)
|
||||
of
|
||||
undefined -> deny;
|
||||
GACLs -> match_acls(GACLs, JID, global)
|
||||
end
|
||||
end;
|
||||
match_rule(Host, Rule, JID) ->
|
||||
case Rule of
|
||||
all -> allow;
|
||||
none -> deny;
|
||||
_ ->
|
||||
case ejabberd_config:get_global_option(
|
||||
{access, Rule, global}, fun(V) -> V end)
|
||||
of
|
||||
undefined ->
|
||||
case ejabberd_config:get_global_option(
|
||||
{access, Rule, Host}, fun(V) -> V end)
|
||||
of
|
||||
undefined -> deny;
|
||||
ACLs -> match_acls(ACLs, JID, Host)
|
||||
end;
|
||||
GACLs ->
|
||||
case ejabberd_config:get_global_option(
|
||||
{access, Rule, Host}, fun(V) -> V end)
|
||||
of
|
||||
undefined -> match_acls(GACLs, JID, Host);
|
||||
ACLs ->
|
||||
case lists:reverse(GACLs) of
|
||||
[{allow, all} | Rest] ->
|
||||
match_acls(lists:reverse(Rest) ++
|
||||
ACLs ++ [{allow, all}],
|
||||
JID, Host);
|
||||
_ -> match_acls(GACLs ++ ACLs, JID, Host)
|
||||
end
|
||||
end
|
||||
end
|
||||
all -> allow;
|
||||
none -> deny;
|
||||
_ ->
|
||||
case ejabberd_config:get_global_option({access, Rule}) of
|
||||
undefined ->
|
||||
deny;
|
||||
ACLs ->
|
||||
match_acls(ACLs, JID)
|
||||
end
|
||||
end.
|
||||
|
||||
match_acls([], _, _Host) -> deny;
|
||||
match_acls([{Access, ACL} | ACLs], JID, Host) ->
|
||||
case match_acl(ACL, JID, Host) of
|
||||
true -> Access;
|
||||
_ -> match_acls(ACLs, JID, Host)
|
||||
match_acls([], _) ->
|
||||
deny;
|
||||
match_acls([{Access, ACL} | ACLs], JID) ->
|
||||
case match_acl(ACL, JID) of
|
||||
true ->
|
||||
Access;
|
||||
_ ->
|
||||
match_acls(ACLs, JID)
|
||||
end.
|
||||
|
||||
-spec match_acl(atom(), jid() | ljid(), binary()) -> boolean().
|
||||
|
||||
match_acl(ACL, JID, Host) ->
|
||||
match_acl(ACL, JID) ->
|
||||
case ACL of
|
||||
all -> true;
|
||||
none -> false;
|
||||
_ ->
|
||||
{User, Server, Resource} = jlib:jid_tolower(JID),
|
||||
lists:any(fun (#acl{aclspec = Spec}) ->
|
||||
case Spec of
|
||||
all -> true;
|
||||
{user, U} ->
|
||||
U == User andalso
|
||||
(Host == Server orelse
|
||||
Host == global andalso
|
||||
lists:member(Server, ?MYHOSTS));
|
||||
{user, U, S} -> U == User andalso S == Server;
|
||||
{server, S} -> S == Server;
|
||||
{resource, R} -> R == Resource;
|
||||
{user_regexp, UR} ->
|
||||
(Host == Server orelse
|
||||
Host == global andalso
|
||||
lists:member(Server, ?MYHOSTS))
|
||||
andalso is_regexp_match(User, UR);
|
||||
{shared_group, G} ->
|
||||
Mod = loaded_shared_roster_module(Host),
|
||||
Mod:is_user_in_group({User, Server}, G, Host);
|
||||
{shared_group, G, H} ->
|
||||
Mod = loaded_shared_roster_module(H),
|
||||
Mod:is_user_in_group({User, Server}, G, H);
|
||||
{user_regexp, UR, S} ->
|
||||
S == Server andalso is_regexp_match(User, UR);
|
||||
{server_regexp, SR} ->
|
||||
is_regexp_match(Server, SR);
|
||||
{resource_regexp, RR} ->
|
||||
is_regexp_match(Resource, RR);
|
||||
{node_regexp, UR, SR} ->
|
||||
is_regexp_match(Server, SR) andalso
|
||||
is_regexp_match(User, UR);
|
||||
{user_glob, UR} ->
|
||||
(Host == Server orelse
|
||||
Host == global andalso
|
||||
lists:member(Server, ?MYHOSTS))
|
||||
andalso is_glob_match(User, UR);
|
||||
{user_glob, UR, S} ->
|
||||
S == Server andalso is_glob_match(User, UR);
|
||||
{server_glob, SR} -> is_glob_match(Server, SR);
|
||||
{resource_glob, RR} ->
|
||||
is_glob_match(Resource, RR);
|
||||
{node_glob, UR, SR} ->
|
||||
is_glob_match(Server, SR) andalso
|
||||
is_glob_match(User, UR);
|
||||
WrongSpec ->
|
||||
?ERROR_MSG("Wrong ACL expression: ~p~nCheck your "
|
||||
"config file and reload it with the override_a"
|
||||
"cls option enabled",
|
||||
[WrongSpec]),
|
||||
false
|
||||
end
|
||||
end,
|
||||
ets:lookup(acl, {ACL, global}) ++
|
||||
ets:lookup(acl, {ACL, Host}))
|
||||
all -> true;
|
||||
none -> false;
|
||||
_ ->
|
||||
{User, Server, Resource} = jlib:jid_tolower(JID),
|
||||
lists:any(fun(#acl{aclspec = Spec}) ->
|
||||
case Spec of
|
||||
all ->
|
||||
true;
|
||||
{user, U} ->
|
||||
(U == User) andalso (?MYNAME == Server);
|
||||
{user, U, S} ->
|
||||
(U == User) andalso (S == Server);
|
||||
{server, S} ->
|
||||
S == Server;
|
||||
{user_regexp, UR} ->
|
||||
(?MYNAME == Server) andalso
|
||||
is_regexp_match(User, UR);
|
||||
{user_regexp, UR, S} ->
|
||||
(S == Server) andalso
|
||||
is_regexp_match(User, UR);
|
||||
{server_regexp, SR} ->
|
||||
is_regexp_match(Server, SR);
|
||||
{node_regexp, UR, SR} ->
|
||||
is_regexp_match(Server, SR) andalso
|
||||
is_regexp_match(User, UR);
|
||||
{user_glob, UR} ->
|
||||
(?MYNAME == Server) andalso
|
||||
is_glob_match(User, UR);
|
||||
{user_glob, UR, S} ->
|
||||
(S == Server) andalso
|
||||
is_glob_match(User, UR);
|
||||
{server_glob, SR} ->
|
||||
is_glob_match(Server, SR);
|
||||
{node_glob, UR, SR} ->
|
||||
is_glob_match(Server, SR) andalso
|
||||
is_glob_match(User, UR)
|
||||
end
|
||||
end, ets:lookup(acl, ACL))
|
||||
end.
|
||||
|
||||
is_regexp_match(String, RegExp) ->
|
||||
case ejabberd_regexp:run(String, RegExp) of
|
||||
nomatch -> false;
|
||||
match -> true;
|
||||
{error, ErrDesc} ->
|
||||
?ERROR_MSG("Wrong regexp ~p in ACL: ~p",
|
||||
[RegExp, ErrDesc]),
|
||||
false
|
||||
case regexp:first_match(String, RegExp) of
|
||||
nomatch ->
|
||||
false;
|
||||
{match, _, _} ->
|
||||
true;
|
||||
{error, ErrDesc} ->
|
||||
?ERROR_MSG(
|
||||
"Wrong regexp ~p in ACL: ~p",
|
||||
[RegExp, lists:flatten(regexp:format_error(ErrDesc))]),
|
||||
false
|
||||
end.
|
||||
|
||||
is_glob_match(String, Glob) ->
|
||||
is_regexp_match(String,
|
||||
ejabberd_regexp:sh_to_awk(Glob)).
|
||||
is_regexp_match(String, regexp:sh_to_awk(Glob)).
|
||||
|
||||
loaded_shared_roster_module(Host) ->
|
||||
case gen_mod:is_loaded(Host, mod_shared_roster_ldap) of
|
||||
true -> mod_shared_roster_ldap;
|
||||
false -> mod_shared_roster
|
||||
end.
|
||||
|
||||
update_table() ->
|
||||
Fields = record_info(fields, acl),
|
||||
case mnesia:table_info(acl, attributes) of
|
||||
Fields ->
|
||||
ejabberd_config:convert_table_to_binary(
|
||||
acl, Fields, bag,
|
||||
fun(#acl{aclspec = Spec}) when is_tuple(Spec) ->
|
||||
element(2, Spec);
|
||||
(_) ->
|
||||
'$next'
|
||||
end,
|
||||
fun(#acl{aclname = {ACLName, Host},
|
||||
aclspec = Spec} = R) ->
|
||||
NewHost = if Host == global ->
|
||||
Host;
|
||||
true ->
|
||||
iolist_to_binary(Host)
|
||||
end,
|
||||
R#acl{aclname = {ACLName, NewHost},
|
||||
aclspec = normalize_spec(Spec)}
|
||||
end);
|
||||
_ ->
|
||||
?INFO_MSG("Recreating acl table", []),
|
||||
mnesia:transform_table(acl, ignore, Fields)
|
||||
end.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
AC_DEFUN([AM_WITH_EXPAT],
|
||||
AC_DEFUN(AM_WITH_EXPAT,
|
||||
[ AC_ARG_WITH(expat,
|
||||
[AC_HELP_STRING([--with-expat=PREFIX], [prefix where EXPAT is installed])])
|
||||
[ --with-expat=PREFIX prefix where EXPAT is installed])
|
||||
|
||||
EXPAT_CFLAGS=
|
||||
EXPAT_LIBS=
|
||||
@@ -8,207 +8,90 @@ AC_DEFUN([AM_WITH_EXPAT],
|
||||
EXPAT_CFLAGS="-I$with_expat/include"
|
||||
EXPAT_LIBS="-L$with_expat/lib"
|
||||
fi
|
||||
|
||||
|
||||
AC_CHECK_LIB(expat, XML_ParserCreate,
|
||||
[ EXPAT_LIBS="$EXPAT_LIBS -lexpat"
|
||||
expat_found=yes ],
|
||||
[ expat_found=no ],
|
||||
"$EXPAT_LIBS")
|
||||
if test $expat_found = no; then
|
||||
AC_MSG_ERROR([Could not find development files of Expat library])
|
||||
AC_MSG_ERROR([Could not find the Expat library])
|
||||
fi
|
||||
expat_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $EXPAT_CFLAGS"
|
||||
expat_save_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $EXPAT_CFLAGS"
|
||||
AC_CHECK_HEADERS(expat.h, , expat_found=no)
|
||||
if test $expat_found = no; then
|
||||
AC_MSG_ERROR([Could not find expat.h])
|
||||
fi
|
||||
CFLAGS="$expat_save_CFLAGS"
|
||||
CPPFLAGS="$expat_save_CPPFLAGS"
|
||||
|
||||
AC_SUBST(EXPAT_CFLAGS)
|
||||
AC_SUBST(EXPAT_LIBS)
|
||||
])
|
||||
|
||||
AC_DEFUN([AM_WITH_ZLIB],
|
||||
[ AC_ARG_WITH(zlib,
|
||||
[AC_HELP_STRING([--with-zlib=PREFIX], [prefix where zlib is installed])])
|
||||
|
||||
if test x"$ejabberd_zlib" != x; then
|
||||
ZLIB_CFLAGS=
|
||||
ZLIB_LIBS=
|
||||
if test x"$with_zlib" != x; then
|
||||
ZLIB_CFLAGS="-I$with_zlib/include"
|
||||
ZLIB_LIBS="-L$with_zlib/lib"
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(z, gzgets,
|
||||
[ ZLIB_LIBS="$ZLIB_LIBS -lz"
|
||||
zlib_found=yes ],
|
||||
[ zlib_found=no ],
|
||||
"$ZLIB_LIBS")
|
||||
if test $zlib_found = no; then
|
||||
AC_MSG_ERROR([Could not find development files of zlib library. Install them or disable `ejabberd_zlib' with: --disable-ejabberd_zlib])
|
||||
fi
|
||||
zlib_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $ZLIB_CFLAGS"
|
||||
zlib_save_CPPFLAGS="$CFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS"
|
||||
AC_CHECK_HEADERS(zlib.h, , zlib_found=no)
|
||||
if test $zlib_found = no; then
|
||||
AC_MSG_ERROR([Could not find zlib.h. Install it or disable `ejabberd_zlib' with: --disable-ejabberd_zlib])
|
||||
fi
|
||||
CFLAGS="$zlib_save_CFLAGS"
|
||||
CPPFLAGS="$zlib_save_CPPFLAGS"
|
||||
|
||||
AC_SUBST(ZLIB_CFLAGS)
|
||||
AC_SUBST(ZLIB_LIBS)
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([AM_WITH_PAM],
|
||||
[ AC_ARG_WITH(pam,
|
||||
[AC_HELP_STRING([--with-pam=PREFIX], [prefix where PAM is installed])])
|
||||
if test x"$pam" != x; then
|
||||
PAM_CFLAGS=
|
||||
PAM_LIBS=
|
||||
if test x"$with_pam" != x; then
|
||||
PAM_CFLAGS="-I$with_pam/include"
|
||||
PAM_LIBS="-L$with_pam/lib"
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(pam, pam_start,
|
||||
[ PAM_LIBS="$PAM_LIBS -lpam"
|
||||
pam_found=yes ],
|
||||
[ pam_found=no ],
|
||||
"$PAM_LIBS")
|
||||
if test $pam_found = no; then
|
||||
AC_MSG_ERROR([Could not find development files of PAM library. Install them or disable `pam' with: --disable-pam])
|
||||
fi
|
||||
pam_save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $PAM_CFLAGS"
|
||||
pam_save_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $PAM_CFLAGS"
|
||||
AC_CHECK_HEADERS(security/pam_appl.h, , pam_found=no)
|
||||
if test $pam_found = no; then
|
||||
AC_MSG_ERROR([Could not find security/pam_appl.h. Install it or disable `pam' with: --disable-pam])
|
||||
fi
|
||||
CFLAGS="$pam_save_CFLAGS"
|
||||
CPPFLAGS="$pam_save_CPPFLAGS"
|
||||
|
||||
AC_SUBST(PAM_CFLAGS)
|
||||
AC_SUBST(PAM_LIBS)
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([AM_WITH_ERLANG],
|
||||
AC_DEFUN(AM_WITH_ERLANG,
|
||||
[ AC_ARG_WITH(erlang,
|
||||
[AC_HELP_STRING([--with-erlang=PREFIX], [path to erlc and erl])])
|
||||
[ --with-erlang=PREFIX path to erlc and erl ])
|
||||
|
||||
AC_PATH_TOOL(ERLC, erlc, , $with_erlang:$with_erlang/bin:$PATH)
|
||||
AC_PATH_TOOL(ERL, erl, , $with_erlang:$with_erlang/bin:$PATH)
|
||||
|
||||
if test "z$ERLC" = "z" || test "z$ERL" = "z"; then
|
||||
AC_PATH_TOOL(ERLC, erlc, , $PATH:$with_erlang:$with_erlang/bin)
|
||||
AC_PATH_TOOL(ERL, erl, , $PATH:$with_erlang:$with_erlang/bin)
|
||||
|
||||
if test "z$ERLC" == "z" || test "z$ERL" == "z"; then
|
||||
AC_MSG_ERROR([erlang not found])
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
cat >>conftest.erl <<_EOF
|
||||
|
||||
|
||||
-module(conftest).
|
||||
-author('alexey@sevcom.net').
|
||||
|
||||
|
||||
-export([[start/0]]).
|
||||
|
||||
|
||||
start() ->
|
||||
EIDirS = code:lib_dir("erl_interface") ++ "\n",
|
||||
EILibS = libpath("erl_interface") ++ "\n",
|
||||
RootDirS = code:root_dir() ++ "\n",
|
||||
file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ ssldef() ++ RootDirS)),
|
||||
halt().
|
||||
|
||||
ssldef() ->
|
||||
OTP = (catch erlang:system_info(otp_release)),
|
||||
if
|
||||
OTP >= "R14" -> "-DSSL40\n";
|
||||
OTP >= "R12" -> "-DSSL39\n";
|
||||
true -> "\n"
|
||||
end.
|
||||
|
||||
%% return physical architecture based on OS/Processor
|
||||
archname() ->
|
||||
ArchStr = erlang:system_info(system_architecture),
|
||||
case os:type() of
|
||||
{win32, _} -> "windows";
|
||||
{unix,UnixName} ->
|
||||
Specs = string:tokens(ArchStr,"-"),
|
||||
Cpu = case lists:nth(2,Specs) of
|
||||
"pc" -> "x86";
|
||||
_ -> hd(Specs)
|
||||
end,
|
||||
atom_to_list(UnixName) ++ "-" ++ Cpu;
|
||||
_ -> "generic"
|
||||
end.
|
||||
|
||||
%% Return arch-based library path or a default value if this directory
|
||||
%% does not exist
|
||||
libpath(App) ->
|
||||
PrivDir = code:priv_dir(App),
|
||||
ArchDir = archname(),
|
||||
LibArchDir = filename:join([[PrivDir,"lib",ArchDir]]),
|
||||
case file:list_dir(LibArchDir) of
|
||||
%% Arch lib dir exists: We use it
|
||||
{ok, _List} -> LibArchDir;
|
||||
%% Arch lib dir does not exist: Return the default value
|
||||
%% ({error, enoent}):
|
||||
_Error -> code:lib_dir("erl_interface") ++ "/lib"
|
||||
end.
|
||||
|
||||
EIDirS = code:lib_dir("erl_interface") ++ "\n",
|
||||
RootDirS = code:root_dir() ++ "\n",
|
||||
file:write_file("conftest.out", list_to_binary(EIDirS ++ RootDirS)),
|
||||
halt().
|
||||
|
||||
_EOF
|
||||
|
||||
|
||||
if ! $ERLC conftest.erl; then
|
||||
AC_MSG_ERROR([could not compile sample program])
|
||||
fi
|
||||
|
||||
|
||||
if ! $ERL -s conftest -noshell; then
|
||||
AC_MSG_ERROR([could not run sample program])
|
||||
fi
|
||||
|
||||
|
||||
if ! test -f conftest.out; then
|
||||
AC_MSG_ERROR([erlang program was not properly executed, (conftest.out was not produced)])
|
||||
fi
|
||||
|
||||
# First line
|
||||
|
||||
ERLANG_EI_DIR=`cat conftest.out | head -n 1`
|
||||
# Second line
|
||||
ERLANG_EI_LIB=`cat conftest.out | head -n 2 | tail -n 1`
|
||||
# Third line
|
||||
ERLANG_SSLVER=`cat conftest.out | head -n 3 | tail -n 1`
|
||||
# End line
|
||||
ERLANG_DIR=`cat conftest.out | tail -n 1`
|
||||
|
||||
|
||||
ERLANG_CFLAGS="-I$ERLANG_EI_DIR/include -I$ERLANG_DIR/usr/include"
|
||||
ERLANG_LIBS="-L$ERLANG_EI_LIB -lerl_interface -lei"
|
||||
|
||||
ERLANG_LIBS="-L$ERLANG_EI_DIR/lib -lerl_interface -lei"
|
||||
|
||||
AC_SUBST(ERLANG_CFLAGS)
|
||||
AC_SUBST(ERLANG_LIBS)
|
||||
AC_SUBST(ERLANG_SSLVER)
|
||||
AC_SUBST(ERLC)
|
||||
AC_SUBST(ERL)
|
||||
])
|
||||
|
||||
AC_DEFUN([AC_MOD_ENABLE],
|
||||
|
||||
AC_DEFUN(AC_MOD_ENABLE,
|
||||
[
|
||||
$1=
|
||||
make_$1=
|
||||
AC_MSG_CHECKING([whether build $1])
|
||||
AC_ARG_ENABLE($1,
|
||||
[AC_HELP_STRING([--enable-$1], [enable $1 (default: $2)])],
|
||||
[ --enable-$1 enable $1 (default: $2)],
|
||||
[mr_enable_$1="$enableval"],
|
||||
[mr_enable_$1=$2])
|
||||
if test "$mr_enable_$1" = "yes"; then
|
||||
if test "$mr_enable_$1" = $2; then
|
||||
$1=$1
|
||||
make_$1=$1/Makefile
|
||||
fi
|
||||
@@ -226,7 +109,7 @@ AC_DEFUN([AM_ICONV],
|
||||
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
|
||||
dnl those with the standalone portable GNU libiconv installed).
|
||||
AC_ARG_WITH([libiconv-prefix],
|
||||
[AC_HELP_STRING([--with-libiconv-prefix=PREFIX], [prefix where libiconv is installed])], [
|
||||
[ --with-libiconv-prefix=PREFIX prefix where libiconv is installed], [
|
||||
for dir in `echo "$withval" | tr : ' '`; do
|
||||
if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
|
||||
if test -d $dir/include; then CFLAGS="$CFLAGS -I$dir/include"; fi
|
||||
@@ -275,7 +158,7 @@ AC_DEFUN([AM_ICONV],
|
||||
CFLAGS="$am_save_CFLAGS")
|
||||
LIBS="$am_save_LIBS"
|
||||
fi
|
||||
|
||||
|
||||
])
|
||||
if test "$am_cv_func_iconv" = yes; then
|
||||
AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.])
|
||||
@@ -309,39 +192,31 @@ size_t iconv();
|
||||
])
|
||||
|
||||
dnl <openssl>
|
||||
AC_DEFUN([AM_WITH_OPENSSL],
|
||||
AC_DEFUN(AM_WITH_OPENSSL,
|
||||
[ AC_ARG_WITH(openssl,
|
||||
[AC_HELP_STRING([--with-openssl=PREFIX], [prefix where OPENSSL is installed])])
|
||||
[ --with-openssl=PREFIX prefix where OPENSSL is installed ])
|
||||
unset SSL_LIBS;
|
||||
unset SSL_CFLAGS;
|
||||
have_openssl=no
|
||||
if test x"$tls" != x; then
|
||||
for ssl_prefix in $withval /usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr; do
|
||||
printf "looking for openssl in $ssl_prefix...\n"
|
||||
SSL_CFLAGS="-I$ssl_prefix/include"
|
||||
SSL_CFLAGS="-I$ssl_prefix/include/openssl"
|
||||
SSL_LIBS="-L$ssl_prefix/lib -lcrypto"
|
||||
AC_CHECK_LIB(ssl, SSL_new, [ have_openssl=yes ], [ have_openssl=no ], [ $SSL_LIBS $SSL_CFLAGS ])
|
||||
if test x"$have_openssl" = xyes; then
|
||||
save_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS="-I$ssl_prefix/include $CPPFLAGS"
|
||||
AC_CHECK_HEADERS(openssl/ssl.h, have_openssl_h=yes)
|
||||
CPPFLAGS=$save_CPPFLAGS
|
||||
AC_CHECK_HEADERS($ssl_prefix/include/openssl/ssl.h, have_openssl_h=yes)
|
||||
if test x"$have_openssl_h" = xyes; then
|
||||
have_openssl=yes
|
||||
printf "openssl found in $ssl_prefix\n";
|
||||
SSL_LIBS="-L$ssl_prefix/lib -lssl -lcrypto"
|
||||
CPPFLAGS="-I$ssl_prefix/include $CPPFLAGS"
|
||||
SSL_CFLAGS="-DHAVE_SSL"
|
||||
SSL_CFLAGS="-I$ssl_prefix/include/openssl -DHAVE_SSL"
|
||||
break
|
||||
fi
|
||||
else
|
||||
# Clear this from the autoconf cache, so in the next pass of
|
||||
# this loop with different -L arguments, it will test again.
|
||||
unset ac_cv_lib_ssl_SSL_new
|
||||
fi
|
||||
done
|
||||
if test x${have_openssl} != xyes; then
|
||||
AC_MSG_ERROR([Could not find development files of OpenSSL library. Install them or disable `tls' with: --disable-tls])
|
||||
AC_MSG_ERROR([openssl library cannot be found. Install openssl or disable `tls' module (--disable-tls).])
|
||||
fi
|
||||
AC_SUBST(SSL_LIBS)
|
||||
AC_SUBST(SSL_CFLAGS)
|
||||
@@ -1,160 +0,0 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : adhoc.erl
|
||||
%%% Author : Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%% Purpose : Provide helper functions for ad-hoc commands (XEP-0050)
|
||||
%%% Created : 31 Oct 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(adhoc).
|
||||
|
||||
-author('henoch@dtek.chalmers.se').
|
||||
|
||||
-export([
|
||||
parse_request/1,
|
||||
produce_response/2,
|
||||
produce_response/1
|
||||
]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
-include("adhoc.hrl").
|
||||
|
||||
%% Parse an ad-hoc request. Return either an adhoc_request record or
|
||||
%% an {error, ErrorType} tuple.
|
||||
%%
|
||||
-spec(parse_request/1 ::
|
||||
(
|
||||
IQ :: iq_request())
|
||||
-> adhoc_response()
|
||||
%%
|
||||
| {error, _}
|
||||
).
|
||||
|
||||
parse_request(#iq{type = set, lang = Lang, sub_el = SubEl, xmlns = ?NS_COMMANDS}) ->
|
||||
?DEBUG("entering parse_request...", []),
|
||||
Node = xml:get_tag_attr_s(<<"node">>, SubEl),
|
||||
SessionID = xml:get_tag_attr_s(<<"sessionid">>, SubEl),
|
||||
Action = xml:get_tag_attr_s(<<"action">>, SubEl),
|
||||
XData = find_xdata_el(SubEl),
|
||||
#xmlel{children = AllEls} = SubEl,
|
||||
Others = case XData of
|
||||
false -> AllEls;
|
||||
_ -> lists:delete(XData, AllEls)
|
||||
end,
|
||||
#adhoc_request{
|
||||
lang = Lang,
|
||||
node = Node,
|
||||
sessionid = SessionID,
|
||||
action = Action,
|
||||
xdata = XData,
|
||||
others = Others
|
||||
};
|
||||
parse_request(_) -> {error, ?ERR_BAD_REQUEST}.
|
||||
|
||||
%% Borrowed from mod_vcard.erl
|
||||
find_xdata_el(#xmlel{children = SubEls}) ->
|
||||
find_xdata_el1(SubEls).
|
||||
|
||||
find_xdata_el1([]) -> false;
|
||||
find_xdata_el1([El | Els]) when is_record(El, xmlel) ->
|
||||
case xml:get_tag_attr_s(<<"xmlns">>, El) of
|
||||
?NS_XDATA -> El;
|
||||
_ -> find_xdata_el1(Els)
|
||||
end;
|
||||
find_xdata_el1([_ | Els]) -> find_xdata_el1(Els).
|
||||
|
||||
%% Produce a <command/> node to use as response from an adhoc_response
|
||||
%% record, filling in values for language, node and session id from
|
||||
%% the request.
|
||||
%%
|
||||
-spec(produce_response/2 ::
|
||||
(
|
||||
Adhoc_Request :: adhoc_request(),
|
||||
Adhoc_Response :: adhoc_response())
|
||||
-> Xmlel::xmlel()
|
||||
).
|
||||
|
||||
%% Produce a <command/> node to use as response from an adhoc_response
|
||||
%% record.
|
||||
produce_response(#adhoc_request{lang = Lang, node = Node, sessionid = SessionID},
|
||||
Adhoc_Response) ->
|
||||
produce_response(Adhoc_Response#adhoc_response{
|
||||
lang = Lang, node = Node, sessionid = SessionID
|
||||
}).
|
||||
|
||||
%%
|
||||
-spec(produce_response/1 ::
|
||||
(
|
||||
Adhoc_Response::adhoc_response())
|
||||
-> Xmlel::xmlel()
|
||||
).
|
||||
|
||||
produce_response(
|
||||
#adhoc_response{
|
||||
%lang = _Lang,
|
||||
node = Node,
|
||||
sessionid = ProvidedSessionID,
|
||||
status = Status,
|
||||
defaultaction = DefaultAction,
|
||||
actions = Actions,
|
||||
notes = Notes,
|
||||
elements = Elements
|
||||
}) ->
|
||||
SessionID = if is_binary(ProvidedSessionID),
|
||||
ProvidedSessionID /= <<"">> -> ProvidedSessionID;
|
||||
true -> jlib:now_to_utc_string(now())
|
||||
end,
|
||||
case Actions of
|
||||
[] ->
|
||||
ActionsEls = [];
|
||||
_ ->
|
||||
case DefaultAction of
|
||||
<<"">> -> ActionsElAttrs = [];
|
||||
_ -> ActionsElAttrs = [{<<"execute">>, DefaultAction}]
|
||||
end,
|
||||
ActionsEls = [
|
||||
#xmlel{
|
||||
name = <<"actions">>,
|
||||
attrs = ActionsElAttrs,
|
||||
children = [
|
||||
#xmlel{name = Action, attrs = [], children = []}
|
||||
|| Action <- Actions]
|
||||
}
|
||||
]
|
||||
end,
|
||||
NotesEls = lists:map(fun({Type, Text}) ->
|
||||
#xmlel{
|
||||
name = <<"note">>,
|
||||
attrs = [{<<"type">>, Type}],
|
||||
children = [{xmlcdata, Text}]
|
||||
}
|
||||
end, Notes),
|
||||
#xmlel{
|
||||
name = <<"command">>,
|
||||
attrs = [
|
||||
{<<"xmlns">>, ?NS_COMMANDS},
|
||||
{<<"sessionid">>, SessionID},
|
||||
{<<"node">>, Node},
|
||||
{<<"status">>, iolist_to_binary(atom_to_list(Status))}
|
||||
],
|
||||
children = ActionsEls ++ NotesEls ++ Elements
|
||||
}.
|
||||
@@ -1,45 +0,0 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-record(adhoc_request,
|
||||
{
|
||||
lang = <<"">> :: binary(),
|
||||
node = <<"">> :: binary(),
|
||||
sessionid = <<"">> :: binary(),
|
||||
action = <<"">> :: binary(),
|
||||
xdata = false :: false | xmlel(),
|
||||
others = [] :: [xmlel()]
|
||||
}).
|
||||
|
||||
-record(adhoc_response,
|
||||
{
|
||||
lang = <<"">> :: binary(),
|
||||
node = <<"">> :: binary(),
|
||||
sessionid = <<"">> :: binary(),
|
||||
status :: atom(),
|
||||
defaultaction = <<"">> :: binary(),
|
||||
actions = [] :: [binary()],
|
||||
notes = [] :: [{binary(), binary()}],
|
||||
elements = [] :: [xmlel()]
|
||||
}).
|
||||
|
||||
-type adhoc_request() :: #adhoc_request{}.
|
||||
-type adhoc_response() :: #adhoc_response{}.
|
||||
@@ -1,609 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : cache_tab.erl
|
||||
%%% Author : Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Description : Caching key-value table
|
||||
%%%
|
||||
%%% Created : 29 Aug 2010 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(cache_tab).
|
||||
|
||||
-define(GEN_SERVER, gen_server).
|
||||
|
||||
-behaviour(?GEN_SERVER).
|
||||
|
||||
%% API
|
||||
-export([start_link/4, new/2, delete/1, delete/3, lookup/3,
|
||||
insert/4, info/2, tab2list/1, setopts/2,
|
||||
dirty_lookup/3, dirty_insert/4, dirty_delete/3,
|
||||
all/0, test/0]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
-record(state, {tab = treap:empty(),
|
||||
name,
|
||||
size = 0,
|
||||
owner,
|
||||
max_size,
|
||||
life_time,
|
||||
warn,
|
||||
hits = 0,
|
||||
miss = 0,
|
||||
procs_num,
|
||||
cache_missed,
|
||||
lru,
|
||||
shrink_size}).
|
||||
|
||||
-define(PROCNAME, ?MODULE).
|
||||
-define(CALL_TIMEOUT, 60000).
|
||||
|
||||
%% Defaults
|
||||
-define(MAX_SIZE, 1000).
|
||||
-define(WARN, true).
|
||||
-define(CACHE_MISSED, true).
|
||||
-define(LRU, true).
|
||||
-define(LIFETIME, 600). %% 10 minutes
|
||||
|
||||
%%====================================================================
|
||||
%% API
|
||||
%%====================================================================
|
||||
start_link(Proc, Tab, Opts, Owner) ->
|
||||
?GEN_SERVER:start_link(
|
||||
{local, Proc}, ?MODULE, [Tab, Opts, get_proc_num(), Owner], []).
|
||||
|
||||
new(Tab, Opts) ->
|
||||
Res = lists:flatmap(
|
||||
fun(Proc) ->
|
||||
Spec = {{Tab, Proc},
|
||||
{?MODULE, start_link,
|
||||
[Proc, Tab, Opts, self()]},
|
||||
permanent,
|
||||
brutal_kill,
|
||||
worker,
|
||||
[?MODULE]},
|
||||
case supervisor:start_child(cache_tab_sup, Spec) of
|
||||
{ok, _Pid} ->
|
||||
[ok];
|
||||
R ->
|
||||
[R]
|
||||
end
|
||||
end, get_all_procs(Tab)),
|
||||
case lists:filter(fun(ok) -> false; (_) -> true end, Res) of
|
||||
[] ->
|
||||
ok;
|
||||
Err ->
|
||||
{error, Err}
|
||||
end.
|
||||
|
||||
delete(Tab) ->
|
||||
lists:foreach(
|
||||
fun(Proc) ->
|
||||
supervisor:terminate_child(cache_tab_sup, {Tab, Proc}),
|
||||
supervisor:delete_child(cache_tab_sup, {Tab, Proc})
|
||||
end, get_all_procs(Tab)).
|
||||
|
||||
delete(Tab, Key, F) ->
|
||||
?GEN_SERVER:call(
|
||||
get_proc_by_hash(Tab, Key), {delete, Key, F}, ?CALL_TIMEOUT).
|
||||
|
||||
dirty_delete(Tab, Key, F) ->
|
||||
F(),
|
||||
?GEN_SERVER:call(
|
||||
get_proc_by_hash(Tab, Key), {cache_delete, Key}, ?CALL_TIMEOUT).
|
||||
|
||||
lookup(Tab, Key, F) ->
|
||||
?GEN_SERVER:call(
|
||||
get_proc_by_hash(Tab, Key), {lookup, Key, F}, ?CALL_TIMEOUT).
|
||||
|
||||
dirty_lookup(Tab, Key, F) ->
|
||||
Proc = get_proc_by_hash(Tab, Key),
|
||||
case ?GEN_SERVER:call(Proc, {cache_lookup, Key}, ?CALL_TIMEOUT) of
|
||||
{ok, '$cached_mismatch'} ->
|
||||
error;
|
||||
{ok, Val} ->
|
||||
{ok, Val};
|
||||
_ ->
|
||||
{Result, NewVal} = case F() of
|
||||
{ok, Val} ->
|
||||
{{ok, Val}, Val};
|
||||
_ ->
|
||||
{error, '$cached_mismatch'}
|
||||
end,
|
||||
?GEN_SERVER:call(
|
||||
Proc, {cache_insert, Key, NewVal}, ?CALL_TIMEOUT),
|
||||
Result
|
||||
end.
|
||||
|
||||
insert(Tab, Key, Val, F) ->
|
||||
?GEN_SERVER:call(
|
||||
get_proc_by_hash(Tab, Key), {insert, Key, Val, F}, ?CALL_TIMEOUT).
|
||||
|
||||
dirty_insert(Tab, Key, Val, F) ->
|
||||
F(),
|
||||
?GEN_SERVER:call(
|
||||
get_proc_by_hash(Tab, Key), {cache_insert, Key, Val}, ?CALL_TIMEOUT).
|
||||
|
||||
info(Tab, Info) ->
|
||||
case lists:map(
|
||||
fun(Proc) ->
|
||||
?GEN_SERVER:call(Proc, {info, Info}, ?CALL_TIMEOUT)
|
||||
end, get_all_procs(Tab)) of
|
||||
Res when Info == size ->
|
||||
{ok, lists:sum(Res)};
|
||||
Res when Info == all ->
|
||||
{ok, Res};
|
||||
Res when Info == ratio ->
|
||||
{H, M} = lists:foldl(
|
||||
fun({Hits, Miss}, {HitsAcc, MissAcc}) ->
|
||||
{HitsAcc + Hits, MissAcc + Miss}
|
||||
end, {0, 0}, Res),
|
||||
{ok, [{hits, H}, {miss, M}]};
|
||||
_ ->
|
||||
{error, badarg}
|
||||
end.
|
||||
|
||||
setopts(Tab, Opts) ->
|
||||
lists:foreach(
|
||||
fun(Proc) ->
|
||||
?GEN_SERVER:call(Proc, {setopts, Opts}, ?CALL_TIMEOUT)
|
||||
end, get_all_procs(Tab)).
|
||||
|
||||
tab2list(Tab) ->
|
||||
lists:flatmap(
|
||||
fun(Proc) ->
|
||||
?GEN_SERVER:call(Proc, tab2list, ?CALL_TIMEOUT)
|
||||
end, get_all_procs(Tab)).
|
||||
|
||||
all() ->
|
||||
lists:usort(
|
||||
[Tab || {{Tab, _}, _, _, _} <- supervisor:which_children(cache_tab_sup)]).
|
||||
|
||||
%%====================================================================
|
||||
%% gen_server callbacks
|
||||
%%====================================================================
|
||||
init([Tab, Opts, N, Pid]) ->
|
||||
State = #state{procs_num = N,
|
||||
owner = Pid,
|
||||
name = Tab},
|
||||
{ok, do_setopts(State, Opts)}.
|
||||
|
||||
handle_call({lookup, Key, F}, _From, #state{tab = T} = State) ->
|
||||
CleanPrio = clean_priority(State#state.life_time),
|
||||
case treap:lookup(Key, T) of
|
||||
{ok, Prio, Val} when (State#state.lru == true) or (Prio =< CleanPrio) ->
|
||||
Hits = State#state.hits,
|
||||
NewState = treap_update(Key, Val, State#state{hits = Hits + 1}),
|
||||
case Val of
|
||||
'$cached_mismatch' ->
|
||||
{reply, error, NewState};
|
||||
_ ->
|
||||
{reply, {ok, Val}, NewState}
|
||||
end;
|
||||
_ ->
|
||||
case catch F() of
|
||||
{ok, Val} ->
|
||||
Miss = State#state.miss,
|
||||
NewState = treap_insert(Key, Val, State),
|
||||
{reply, {ok, Val}, NewState#state{miss = Miss + 1}};
|
||||
{'EXIT', Reason} ->
|
||||
print_error(lookup, [Key], Reason, State),
|
||||
{reply, error, State};
|
||||
_ ->
|
||||
Miss = State#state.miss,
|
||||
NewState = State#state{miss = Miss + 1},
|
||||
if State#state.cache_missed ->
|
||||
{reply, error,
|
||||
treap_insert(Key, '$cached_mismatch', NewState)};
|
||||
true ->
|
||||
{reply, error, NewState}
|
||||
end
|
||||
end
|
||||
end;
|
||||
handle_call({cache_lookup, Key}, _From, #state{tab = T} = State) ->
|
||||
CleanPrio = clean_priority(State#state.life_time),
|
||||
case treap:lookup(Key, T) of
|
||||
{ok, Prio, Val} when (State#state.lru == true) or (Prio =< CleanPrio) ->
|
||||
Hits = State#state.hits,
|
||||
NewState = treap_update(Key, Val, State#state{hits = Hits + 1}),
|
||||
{reply, {ok, Val}, NewState};
|
||||
_ ->
|
||||
Miss = State#state.miss,
|
||||
NewState = State#state{miss = Miss + 1},
|
||||
{reply, error, NewState}
|
||||
end;
|
||||
handle_call({insert, Key, Val, F}, _From, #state{tab = T} = State) ->
|
||||
case treap:lookup(Key, T) of
|
||||
{ok, _Prio, Val} ->
|
||||
{reply, ok, treap_update(Key, Val, State)};
|
||||
_ ->
|
||||
case catch F() of
|
||||
{'EXIT', Reason} ->
|
||||
print_error(insert, [Key, Val], Reason, State),
|
||||
{reply, ok, State};
|
||||
_ ->
|
||||
{reply, ok, treap_insert(Key, Val, State)}
|
||||
end
|
||||
end;
|
||||
handle_call({cache_insert, _, '$cached_mismatch'}, _From,
|
||||
#state{cache_missed = false} = State) ->
|
||||
{reply, ok, State};
|
||||
handle_call({cache_insert, Key, Val}, _From, State) ->
|
||||
{reply, ok, treap_insert(Key, Val, State)};
|
||||
handle_call({delete, Key, F}, _From, State) ->
|
||||
NewState = treap_delete(Key, State),
|
||||
case catch F() of
|
||||
{'EXIT', Reason} ->
|
||||
print_error(delete, [Key], Reason, State);
|
||||
_ ->
|
||||
ok
|
||||
end,
|
||||
{reply, ok, NewState};
|
||||
handle_call({cache_delete, Key}, _From, State) ->
|
||||
NewState = treap_delete(Key, State),
|
||||
{reply, ok, NewState};
|
||||
handle_call({info, Info}, _From, State) ->
|
||||
Res = case Info of
|
||||
size ->
|
||||
State#state.size;
|
||||
ratio ->
|
||||
{State#state.hits, State#state.miss};
|
||||
all ->
|
||||
[{max_size, State#state.max_size},
|
||||
{life_time, State#state.life_time},
|
||||
{shrink_size, State#state.shrink_size},
|
||||
{size, State#state.size},
|
||||
{owner, State#state.owner},
|
||||
{hits, State#state.hits},
|
||||
{miss, State#state.miss},
|
||||
{cache_missed, State#state.cache_missed},
|
||||
{lru, State#state.lru},
|
||||
{warn, State#state.warn}];
|
||||
_ ->
|
||||
badarg
|
||||
end,
|
||||
{reply, Res, State};
|
||||
handle_call(tab2list, _From, #state{tab = T} = State) ->
|
||||
Res = treap:fold(
|
||||
fun({Key, _, Val}, Acc) ->
|
||||
[{Key, Val}|Acc]
|
||||
end, [], T),
|
||||
{reply, Res, State};
|
||||
handle_call({setopts, Opts}, _From, State) ->
|
||||
{reply, ok, do_setopts(State, Opts)};
|
||||
handle_call(_Request, _From, State) ->
|
||||
Reply = ok,
|
||||
{reply, Reply, State}.
|
||||
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
terminate(_Reason, _State) ->
|
||||
ok.
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%%% Internal functions
|
||||
%%--------------------------------------------------------------------
|
||||
do_setopts(#state{procs_num = N} = State, Opts) ->
|
||||
MaxSize = case {proplists:get_value(max_size, Opts),
|
||||
State#state.max_size} of
|
||||
{MS, _} when is_integer(MS), MS > 0 ->
|
||||
round(MS/N);
|
||||
{unlimited, _} ->
|
||||
unlimited;
|
||||
{_, undefined} ->
|
||||
round(?MAX_SIZE/N);
|
||||
{_, MS} ->
|
||||
MS
|
||||
end,
|
||||
LifeTime = case {proplists:get_value(life_time, Opts),
|
||||
State#state.life_time} of
|
||||
{LT, _} when is_integer(LT), LT > 0 ->
|
||||
LT*1000*1000;
|
||||
{unlimited, _} ->
|
||||
unlimited;
|
||||
{_, undefined} ->
|
||||
?LIFETIME*1000*1000;
|
||||
{_, LT} ->
|
||||
LT
|
||||
end,
|
||||
ShrinkSize = case {proplists:get_value(shrink_size, Opts),
|
||||
State#state.shrink_size} of
|
||||
{SS, _} when is_integer(SS), SS > 0 ->
|
||||
round(SS/N);
|
||||
_ when is_integer(MaxSize) ->
|
||||
round(MaxSize/2);
|
||||
_ ->
|
||||
unlimited
|
||||
end,
|
||||
Warn = case {proplists:get_value(warn, Opts),
|
||||
State#state.warn} of
|
||||
{true, _} ->
|
||||
true;
|
||||
{false, _} ->
|
||||
false;
|
||||
{_, undefined} ->
|
||||
?WARN;
|
||||
{_, W} ->
|
||||
W
|
||||
end,
|
||||
CacheMissed = case proplists:get_value(
|
||||
cache_missed, Opts, State#state.cache_missed) of
|
||||
false ->
|
||||
false;
|
||||
true ->
|
||||
true;
|
||||
_ ->
|
||||
?CACHE_MISSED
|
||||
end,
|
||||
LRU = case proplists:get_value(
|
||||
lru, Opts, State#state.lru) of
|
||||
false ->
|
||||
false;
|
||||
true ->
|
||||
true;
|
||||
_ ->
|
||||
?LRU
|
||||
end,
|
||||
State#state{max_size = MaxSize,
|
||||
warn = Warn,
|
||||
life_time = LifeTime,
|
||||
cache_missed = CacheMissed,
|
||||
lru = LRU,
|
||||
shrink_size = ShrinkSize}.
|
||||
|
||||
get_proc_num() ->
|
||||
case catch erlang:system_info(logical_processors) of
|
||||
Num when is_integer(Num) ->
|
||||
Num;
|
||||
_ ->
|
||||
1
|
||||
end.
|
||||
|
||||
get_proc_by_hash(Tab, Term) ->
|
||||
N = erlang:phash2(Term, get_proc_num()) + 1,
|
||||
get_proc(Tab, N).
|
||||
|
||||
get_proc(Tab, N) ->
|
||||
list_to_atom(atom_to_list(?PROCNAME) ++ "_" ++
|
||||
atom_to_list(Tab) ++ "_" ++ integer_to_list(N)).
|
||||
|
||||
get_all_procs(Tab) ->
|
||||
[get_proc(Tab, N) || N <- lists:seq(1, get_proc_num())].
|
||||
|
||||
now_priority() ->
|
||||
{MSec, Sec, USec} = now(),
|
||||
-((MSec*1000000 + Sec)*1000000 + USec).
|
||||
|
||||
clean_priority(LifeTime) ->
|
||||
if is_integer(LifeTime) ->
|
||||
now_priority() + LifeTime;
|
||||
true ->
|
||||
unlimited
|
||||
end.
|
||||
|
||||
treap_update(Key, Val, #state{tab = T, lru = LRU} = State) ->
|
||||
if LRU ->
|
||||
Priority = now_priority(),
|
||||
NewT = treap:insert(Key, Priority, Val, T),
|
||||
State#state{tab = NewT};
|
||||
true ->
|
||||
State
|
||||
end.
|
||||
|
||||
treap_insert(Key, Val, State) ->
|
||||
State1 = clean_treap(State),
|
||||
#state{size = Size} = State2 = shrink_treap(State1),
|
||||
T = State2#state.tab,
|
||||
case treap:lookup(Key, T) of
|
||||
{ok, _, Val} ->
|
||||
treap_update(Key, Val, State2);
|
||||
{ok, _, _} ->
|
||||
NewT = treap:insert(Key, now_priority(), Val, T),
|
||||
State2#state{tab = NewT};
|
||||
_ ->
|
||||
NewT = treap:insert(Key, now_priority(), Val, T),
|
||||
State2#state{tab = NewT, size = Size+1}
|
||||
end.
|
||||
|
||||
treap_delete(Key, #state{tab = T, size = Size} = State) ->
|
||||
case treap:lookup(Key, T) of
|
||||
{ok, _, _} ->
|
||||
NewT = treap:delete(Key, T),
|
||||
clean_treap(State#state{tab = NewT, size = Size-1});
|
||||
_ ->
|
||||
State
|
||||
end.
|
||||
|
||||
clean_treap(#state{tab = T, size = Size, life_time = LifeTime} = State) ->
|
||||
if is_integer(LifeTime) ->
|
||||
Priority = now_priority(),
|
||||
{Cleaned, NewT} = clean_treap(T, Priority + LifeTime, 0),
|
||||
State#state{size = Size - Cleaned, tab = NewT};
|
||||
true ->
|
||||
State
|
||||
end.
|
||||
|
||||
clean_treap(Treap, CleanPriority, N) ->
|
||||
case treap:is_empty(Treap) of
|
||||
true ->
|
||||
{N, Treap};
|
||||
false ->
|
||||
{_Key, Priority, _Value} = treap:get_root(Treap),
|
||||
if Priority > CleanPriority ->
|
||||
clean_treap(treap:delete_root(Treap), CleanPriority, N+1);
|
||||
true ->
|
||||
{N, Treap}
|
||||
end
|
||||
end.
|
||||
|
||||
shrink_treap(#state{tab = T,
|
||||
max_size = MaxSize,
|
||||
shrink_size = ShrinkSize,
|
||||
warn = Warn,
|
||||
size = Size} = State) when Size >= MaxSize ->
|
||||
if Warn ->
|
||||
?WARNING_MSG("shrinking table:~n"
|
||||
"** Table: ~p~n"
|
||||
"** Processes Number: ~p~n"
|
||||
"** Max Size: ~p items~n"
|
||||
"** Shrink Size: ~p items~n"
|
||||
"** Life Time: ~p microseconds~n"
|
||||
"** Hits/Miss: ~p/~p~n"
|
||||
"** Owner: ~p~n"
|
||||
"** Cache Missed: ~p~n"
|
||||
"** Instruction: you have to tune cacheing options"
|
||||
" if this message repeats too frequently",
|
||||
[State#state.name, State#state.procs_num,
|
||||
MaxSize, ShrinkSize, State#state.life_time,
|
||||
State#state.hits, State#state.miss,
|
||||
State#state.owner, State#state.cache_missed]);
|
||||
true ->
|
||||
ok
|
||||
end,
|
||||
{Shrinked, NewT} = shrink_treap(T, ShrinkSize, 0),
|
||||
State#state{tab = NewT, size = Size - Shrinked};
|
||||
shrink_treap(State) ->
|
||||
State.
|
||||
|
||||
shrink_treap(T, ShrinkSize, ShrinkSize) ->
|
||||
{ShrinkSize, T};
|
||||
shrink_treap(T, ShrinkSize, N) ->
|
||||
case treap:is_empty(T) of
|
||||
true ->
|
||||
{N, T};
|
||||
false ->
|
||||
shrink_treap(treap:delete_root(T), ShrinkSize, N+1)
|
||||
end.
|
||||
|
||||
print_error(Operation, Args, Reason, State) ->
|
||||
?ERROR_MSG("callback failed:~n"
|
||||
"** Tab: ~p~n"
|
||||
"** Owner: ~p~n"
|
||||
"** Operation: ~p~n"
|
||||
"** Args: ~p~n"
|
||||
"** Reason: ~p",
|
||||
[State#state.name, State#state.owner,
|
||||
Operation, Args, Reason]).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%%% Tests
|
||||
%%--------------------------------------------------------------------
|
||||
-define(lookup, dirty_lookup).
|
||||
-define(delete, dirty_delete).
|
||||
-define(insert, dirty_insert).
|
||||
%%-define(lookup, lookup).
|
||||
%%-define(delete, delete).
|
||||
%%-define(insert, insert).
|
||||
|
||||
test() ->
|
||||
LifeTime = 2,
|
||||
ok = new(test_tbl, [{life_time, LifeTime}, {max_size, unlimited}]),
|
||||
check([]),
|
||||
ok = ?insert(test_tbl, "key", "value", fun() -> ok end),
|
||||
check([{"key", "value"}]),
|
||||
{ok, "value"} = ?lookup(test_tbl, "key", fun() -> error end),
|
||||
check([{"key", "value"}]),
|
||||
io:format("** waiting for ~p seconds to check if LRU works fine...~n",
|
||||
[LifeTime+1]),
|
||||
timer:sleep(timer:seconds(LifeTime+1)),
|
||||
ok = ?insert(test_tbl, "key1", "value1", fun() -> ok end),
|
||||
check([{"key1", "value1"}]),
|
||||
ok = ?delete(test_tbl, "key1", fun() -> ok end),
|
||||
{ok, "value"} = ?lookup(test_tbl, "key", fun() -> {ok, "value"} end),
|
||||
check([{"key", "value"}]),
|
||||
ok = ?delete(test_tbl, "key", fun() -> ok end),
|
||||
check([]),
|
||||
%% io:format("** testing buggy callbacks...~n"),
|
||||
%% delete(test_tbl, "key", fun() -> erlang:error(badarg) end),
|
||||
%% insert(test_tbl, "key", "val", fun() -> erlang:error(badarg) end),
|
||||
%% lookup(test_tbl, "key", fun() -> erlang:error(badarg) end),
|
||||
check([]),
|
||||
delete(test_tbl),
|
||||
test1().
|
||||
|
||||
test1() ->
|
||||
MaxSize = 10,
|
||||
ok = new(test_tbl, [{max_size, MaxSize}, {shrink_size, 1}, {warn, false}]),
|
||||
lists:foreach(
|
||||
fun(N) ->
|
||||
ok = ?insert(test_tbl, N, N, fun() -> ok end)
|
||||
end, lists:seq(1, MaxSize*get_proc_num())),
|
||||
{ok, MaxSize} = info(test_tbl, size),
|
||||
delete(test_tbl),
|
||||
test2().
|
||||
|
||||
test2() ->
|
||||
LifeTime = 2,
|
||||
ok = new(test_tbl, [{life_time, LifeTime},
|
||||
{max_size, unlimited},
|
||||
{lru, false}]),
|
||||
check([]),
|
||||
ok = ?insert(test_tbl, "key", "value", fun() -> ok end),
|
||||
{ok, "value"} = ?lookup(test_tbl, "key", fun() -> error end),
|
||||
check([{"key", "value"}]),
|
||||
io:format("** waiting for ~p seconds to check if non-LRU works fine...~n",
|
||||
[LifeTime+1]),
|
||||
timer:sleep(timer:seconds(LifeTime+1)),
|
||||
error = ?lookup(test_tbl, "key", fun() -> error end),
|
||||
check([{"key", '$cached_mismatch'}]),
|
||||
ok = ?insert(test_tbl, "key", "value1", fun() -> ok end),
|
||||
check([{"key", "value1"}]),
|
||||
delete(test_tbl),
|
||||
io:format("** testing speed, this may take a while...~n"),
|
||||
test3(1000),
|
||||
test3(10000),
|
||||
test3(100000),
|
||||
test3(1000000).
|
||||
|
||||
test3(Iter) ->
|
||||
ok = new(test_tbl, [{max_size, unlimited}, {life_time, unlimited}]),
|
||||
L = lists:seq(1, Iter),
|
||||
T1 = now(),
|
||||
lists:foreach(
|
||||
fun(N) ->
|
||||
ok = ?insert(test_tbl, N, N, fun() -> ok end)
|
||||
end, L),
|
||||
io:format("** average insert (size = ~p): ~p usec~n",
|
||||
[Iter, round(timer:now_diff(now(), T1)/Iter)]),
|
||||
T2 = now(),
|
||||
lists:foreach(
|
||||
fun(N) ->
|
||||
{ok, N} = ?lookup(test_tbl, N, fun() -> ok end)
|
||||
end, L),
|
||||
io:format("** average lookup (size = ~p): ~p usec~n",
|
||||
[Iter, round(timer:now_diff(now(), T2)/Iter)]),
|
||||
{ok, Iter} = info(test_tbl, size),
|
||||
delete(test_tbl).
|
||||
|
||||
check(List) ->
|
||||
Size = length(List),
|
||||
{ok, Size} = info(test_tbl, size),
|
||||
List = tab2list(test_tbl).
|
||||
@@ -1,53 +0,0 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : cache_tab_sup.erl
|
||||
%%% Author : Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%% Description : Cache tables supervisor
|
||||
%%%
|
||||
%%% Created : 30 Aug 2010 by Evgeniy Khramtsov <ekhramtsov@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(cache_tab_sup).
|
||||
|
||||
-behaviour(supervisor).
|
||||
|
||||
%% API
|
||||
-export([start_link/0]).
|
||||
|
||||
%% Supervisor callbacks
|
||||
-export([init/1]).
|
||||
|
||||
-define(SERVER, ?MODULE).
|
||||
|
||||
%%====================================================================
|
||||
%% API functions
|
||||
%%====================================================================
|
||||
start_link() ->
|
||||
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
|
||||
|
||||
%%====================================================================
|
||||
%% Supervisor callbacks
|
||||
%%====================================================================
|
||||
init([]) ->
|
||||
{ok, {{one_for_one,10,1}, []}}.
|
||||
|
||||
%%====================================================================
|
||||
%% Internal functions
|
||||
%%====================================================================
|
||||
@@ -2,16 +2,12 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.53)
|
||||
AC_INIT(ejabberd, m4_esyscmd([grep -o -E "\{vsn,.\".*\"\}" ejabberd.app | cut -d \" -f 2 | tr -d '\n']), [ejabberd@process-one.net], [ejabberd])
|
||||
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
if test "x$GCC" = "xyes"; then
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
fi
|
||||
|
||||
#locating erlang
|
||||
AM_WITH_ERLANG
|
||||
#locating iconv
|
||||
@@ -22,162 +18,25 @@ AM_WITH_EXPAT
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
|
||||
# Check Erlang headers are installed
|
||||
#AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])])
|
||||
|
||||
# Change default prefix
|
||||
AC_PREFIX_DEFAULT(/)
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_MALLOC
|
||||
AC_HEADER_STDC
|
||||
|
||||
AC_MOD_ENABLE(mod_pubsub, yes)
|
||||
AC_MOD_ENABLE(mod_irc, yes)
|
||||
AC_MOD_ENABLE(mod_muc, yes)
|
||||
AC_MOD_ENABLE(mod_proxy65, yes)
|
||||
AC_MOD_ENABLE(mod_pubsub, yes)
|
||||
AC_MOD_ENABLE(eldap, yes)
|
||||
AC_MOD_ENABLE(odbc, no)
|
||||
AC_MOD_ENABLE(tls, yes)
|
||||
AC_MOD_ENABLE(web, yes)
|
||||
|
||||
AC_MOD_ENABLE(ejabberd_zlib, yes)
|
||||
#locating zlib
|
||||
AM_WITH_ZLIB
|
||||
|
||||
AC_MOD_ENABLE(pam, no)
|
||||
#locating PAM
|
||||
AM_WITH_PAM
|
||||
|
||||
AC_ARG_ENABLE(hipe,
|
||||
[AC_HELP_STRING([--enable-hipe], [compile natively with HiPE, not recommended (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) hipe=true ;;
|
||||
no) hipe=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-hipe) ;;
|
||||
esac],[hipe=false])
|
||||
AC_SUBST(hipe)
|
||||
|
||||
AC_ARG_ENABLE(roster_gateway_workaround,
|
||||
[AC_HELP_STRING([--enable-roster-gateway-workaround], [turn on workaround for processing gateway subscriptions (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) roster_gateway_workaround=true ;;
|
||||
no) roster_gateway_workaround=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-roster-gateway-workaround) ;;
|
||||
esac],[roster_gateway_workaround=false])
|
||||
AC_SUBST(roster_gateway_workaround)
|
||||
|
||||
AC_ARG_ENABLE(mssql,
|
||||
[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
|
||||
[case "${enableval}" in
|
||||
yes) db_type=mssql ;;
|
||||
no) db_type=generic ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mssql) ;;
|
||||
esac],[db_type=generic])
|
||||
AC_SUBST(db_type)
|
||||
|
||||
AC_ARG_ENABLE(transient_supervisors,
|
||||
[AC_HELP_STRING([--enable-transient_supervisors], [use Erlang supervision for transient process (default: yes)])],
|
||||
[case "${enableval}" in
|
||||
yes) transient_supervisors=true ;;
|
||||
no) transient_supervisors=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-transient_supervisors) ;;
|
||||
esac],[transient_supervisors=true])
|
||||
AC_SUBST(transient_supervisors)
|
||||
|
||||
AC_ARG_ENABLE(full_xml,
|
||||
[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
|
||||
[case "${enableval}" in
|
||||
yes) full_xml=true ;;
|
||||
no) full_xml=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-full-xml) ;;
|
||||
esac],[full_xml=false])
|
||||
AC_SUBST(full_xml)
|
||||
|
||||
AC_ARG_ENABLE(nif,
|
||||
[AC_HELP_STRING([--enable-nif], [replace some functions with C equivalents. Requires Erlang R13B04 or higher (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) nif=true ;;
|
||||
no) nif=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-nif) ;;
|
||||
esac],[nif=false])
|
||||
AC_SUBST(nif)
|
||||
AC_MOD_ENABLE(tls, yes)
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
$make_mod_irc
|
||||
$make_mod_muc
|
||||
$make_mod_pubsub
|
||||
$make_mod_proxy65
|
||||
$make_eldap
|
||||
$make_pam
|
||||
$make_web
|
||||
mysql/Makefile
|
||||
pgsql/Makefile
|
||||
stringprep/Makefile
|
||||
stun/Makefile
|
||||
$make_tls
|
||||
$make_odbc
|
||||
$make_ejabberd_zlib])
|
||||
$make_tls])
|
||||
#openssl
|
||||
AM_WITH_OPENSSL
|
||||
# If ssl is kerberized it need krb5.h
|
||||
# On RedHat and OpenBSD, krb5.h is in an unsual place:
|
||||
KRB5_INCLUDE="`krb5-config --cflags 2>/dev/null`"
|
||||
if test -n "$KRB5_INCLUDE" ; then
|
||||
CPPFLAGS="$CPPFLAGS $KRB5_INCLUDE"
|
||||
else
|
||||
# For RedHat For BSD
|
||||
for D in /usr/kerberos/include /usr/include/kerberos /usr/include/kerberosV
|
||||
do
|
||||
if test -d $D ; then
|
||||
CPPFLAGS="$CPPFLAGS -I$D"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
AC_CHECK_HEADER(krb5.h,,)
|
||||
|
||||
ENABLEUSER=""
|
||||
AC_ARG_ENABLE(user,
|
||||
[AS_HELP_STRING([--enable-user[[[[=USER]]]]], [allow this system user to start ejabberd (default: no)])],
|
||||
[case "${enableval}" in
|
||||
yes) ENABLEUSER=`whoami` ;;
|
||||
no) ENABLEUSER="" ;;
|
||||
*) ENABLEUSER=$enableval
|
||||
esac],
|
||||
[])
|
||||
if test "$ENABLEUSER" != ""; then
|
||||
echo "allow this system user to start ejabberd: $ENABLEUSER"
|
||||
AC_SUBST([INSTALLUSER], [$ENABLEUSER])
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADER(openssl/md2.h, md2=true, md2=false)
|
||||
AC_SUBST(md2)
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
#AC_DEFINE_UNQUOTED(CPU_VENDOR_OS, "$target")
|
||||
#AC_SUBST(target_os)
|
||||
|
||||
|
||||
case "$target_os" in
|
||||
*darwin10*)
|
||||
echo "Target OS is 'Darwin10'"
|
||||
AC_LANG(Erlang)
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM([],[dnl
|
||||
halt(case erlang:system_info(wordsize) of
|
||||
8 -> 0; 4 -> 1 end)])],
|
||||
[AC_MSG_NOTICE(found 64-bit Erlang)
|
||||
CBIT=-m64],
|
||||
[AC_MSG_NOTICE(found 32-bit Erlang)
|
||||
CBIT=-m32])
|
||||
;;
|
||||
*)
|
||||
echo "Target OS is '$target_os'"
|
||||
CBIT=""
|
||||
;;
|
||||
esac
|
||||
CFLAGS="$CFLAGS $CBIT"
|
||||
LD_SHARED="$LD_SHARED $CBIT"
|
||||
echo "CBIT is set to '$CBIT'"
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -1,31 +1,14 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : configure.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Purpose :
|
||||
%%% Created : 27 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose :
|
||||
%%% Created : 27 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(configure).
|
||||
-author('alexey@process-one.net').
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/0]).
|
||||
|
||||
@@ -44,46 +27,36 @@ start() ->
|
||||
true ->
|
||||
ExpatLib = "EXPAT_LIB = $(EXPAT_DIR)\\StaticLibs\\libexpatMT.lib\n",
|
||||
ExpatFlag = "EXPAT_FLAG = -DXML_STATIC\n",
|
||||
IconvDir = "ICONV_DIR = c:\\sdk\\GnuWin32\n",
|
||||
IconvLib = "ICONV_LIB = $(ICONV_DIR)\\lib\\libiconv.lib\n",
|
||||
ZlibDir = "ZLIB_DIR = c:\\sdk\\GnuWin32\n",
|
||||
ZlibLib = "ZLIB_LIB = $(ZLIB_DIR)\\lib\\zlib.lib\n";
|
||||
IconvDir = "ICONV_DIR = c:\\progra~1\\libiconv-1.9.1-static\n",
|
||||
IconvLib = "ICONV_LIB = $(ICONV_DIR)\\lib\\iconv.lib\n";
|
||||
false ->
|
||||
ExpatLib = "EXPAT_LIB = $(EXPAT_DIR)\\Libs\\libexpat.lib\n",
|
||||
ExpatFlag = "",
|
||||
IconvDir = "ICONV_DIR = c:\\sdk\\GnuWin32\n",
|
||||
IconvLib = "ICONV_LIB = $(ICONV_DIR)\\lib\\libiconv.lib\n",
|
||||
ZlibDir = "ZLIB_DIR = c:\\sdk\\GnuWin32\n",
|
||||
ZlibLib = "ZLIB_LIB = $(ZLIB_DIR)\\lib\\zlib.lib\n"
|
||||
IconvDir = "ICONV_DIR = c:\\progra~1\\libiconv-1.9.1\n",
|
||||
IconvLib = "ICONV_LIB = $(ICONV_DIR)\\lib\\iconv.lib\n"
|
||||
end,
|
||||
|
||||
EVersion = "ERLANG_VERSION = " ++ erlang:system_info(version) ++ "\n",
|
||||
EIDirS = "EI_DIR = " ++ code:lib_dir(erl_interface) ++ "\n",
|
||||
EIDirS = "EI_DIR = " ++ code:lib_dir("erl_interface") ++ "\n",
|
||||
RootDirS = "ERLANG_DIR = " ++ code:root_dir() ++ "\n",
|
||||
%% Load the ejabberd application description so that ?VERSION can read the vsn key
|
||||
application:load(ejabberd),
|
||||
Version = "EJABBERD_VERSION = " ++ binary_to_list(?VERSION) ++ "\n",
|
||||
ExpatDir = "EXPAT_DIR = c:\\sdk\\Expat-2.0.0\n",
|
||||
OpenSSLDir = "OPENSSL_DIR = c:\\sdk\\OpenSSL\n",
|
||||
DBType = "DBTYPE = generic\n", %% 'generic' or 'mssql'
|
||||
Version = "EJABBERD_VERSION = " ++ ?VERSION ++ "\n",
|
||||
ExpatDir = "EXPAT_DIR = c:\\progra~1\\expat-1.95.7\n",
|
||||
OpenSSLDir = "OPENSSL_DIR = c:\\progra~1\\OpenSSL\n",
|
||||
|
||||
SSLDir = "SSLDIR = " ++ code:lib_dir(ssl) ++ "\n",
|
||||
StdLibDir = "STDLIBDIR = " ++ code:lib_dir(stdlib) ++ "\n",
|
||||
SSLDir = "SSLDIR = " ++ code:lib_dir("ssl") ++ "\n",
|
||||
StdLibDir = "STDLIBDIR = " ++ code:lib_dir("stdlib") ++ "\n",
|
||||
|
||||
file:write_file("Makefile.inc",
|
||||
list_to_binary(EVersion ++
|
||||
EIDirS ++
|
||||
list_to_binary(EIDirS ++
|
||||
RootDirS ++
|
||||
Version ++
|
||||
SSLDir ++
|
||||
StdLibDir ++
|
||||
OpenSSLDir ++
|
||||
DBType ++
|
||||
ExpatDir ++
|
||||
ExpatLib ++
|
||||
ExpatFlag ++
|
||||
IconvDir ++
|
||||
IconvLib ++
|
||||
ZlibDir ++
|
||||
ZlibLib)),
|
||||
IconvLib)),
|
||||
halt().
|
||||
|
||||
|
||||
|
||||
@@ -1,217 +1,116 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : cyrsasl.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose : Cyrus SASL-like library
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(cyrsasl).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-author('alexey@process-one.net').
|
||||
-export([start/0,
|
||||
register_mechanism/2,
|
||||
listmech/0,
|
||||
server_new/4,
|
||||
server_start/3,
|
||||
server_step/2]).
|
||||
|
||||
-export([start/0, register_mechanism/3, listmech/1,
|
||||
server_new/7, server_start/3, server_step/2]).
|
||||
-record(sasl_mechanism, {mechanism, module}).
|
||||
-record(sasl_state, {service, myname, realm, mech_mod, mech_state}).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-export([behaviour_info/1]).
|
||||
|
||||
%%
|
||||
-export_type([
|
||||
mechanism/0,
|
||||
mechanisms/0,
|
||||
sasl_mechanism/0
|
||||
]).
|
||||
|
||||
-record(sasl_mechanism,
|
||||
{mechanism = <<"">> :: mechanism() | '$1',
|
||||
module :: atom(),
|
||||
password_type = plain :: password_type() | '$2'}).
|
||||
|
||||
-type(mechanism() :: binary()).
|
||||
-type(mechanisms() :: [mechanism(),...]).
|
||||
-type(password_type() :: plain | digest | scram).
|
||||
-type(props() :: [{username, binary()} |
|
||||
{authzid, binary()} |
|
||||
{auth_module, atom()}]).
|
||||
|
||||
-type(sasl_mechanism() :: #sasl_mechanism{}).
|
||||
|
||||
-record(sasl_state,
|
||||
{
|
||||
service,
|
||||
myname,
|
||||
realm,
|
||||
get_password,
|
||||
check_password,
|
||||
check_password_digest,
|
||||
mech_mod,
|
||||
mech_state
|
||||
}).
|
||||
|
||||
-callback mech_new(binary(), fun(), fun(), fun()) -> any().
|
||||
-callback mech_step(any(), binary()) -> {ok, props()} |
|
||||
{ok, props(), binary()} |
|
||||
{continue, binary(), any()} |
|
||||
{error, binary()} |
|
||||
{error, binary(), binary()}.
|
||||
behaviour_info(callbacks) ->
|
||||
[{mech_new, 0},
|
||||
{mech_step, 2}];
|
||||
behaviour_info(Other) ->
|
||||
undefined.
|
||||
|
||||
start() ->
|
||||
ets:new(sasl_mechanism,
|
||||
[named_table, public,
|
||||
{keypos, #sasl_mechanism.mechanism}]),
|
||||
ets:new(sasl_mechanism, [named_table,
|
||||
public,
|
||||
{keypos, #sasl_mechanism.mechanism}]),
|
||||
cyrsasl_plain:start([]),
|
||||
cyrsasl_digest:start([]),
|
||||
cyrsasl_scram:start([]),
|
||||
cyrsasl_anonymous:start([]),
|
||||
ok.
|
||||
|
||||
%%
|
||||
-spec(register_mechanism/3 ::
|
||||
(
|
||||
Mechanim :: mechanism(),
|
||||
Module :: module(),
|
||||
PasswordType :: password_type())
|
||||
-> any()
|
||||
).
|
||||
register_mechanism(Mechanism, Module) ->
|
||||
ets:insert(sasl_mechanism, #sasl_mechanism{mechanism = Mechanism,
|
||||
module = Module}).
|
||||
|
||||
register_mechanism(Mechanism, Module, PasswordType) ->
|
||||
ets:insert(sasl_mechanism,
|
||||
#sasl_mechanism{mechanism = Mechanism, module = Module,
|
||||
password_type = PasswordType}).
|
||||
|
||||
%%% TODO: use callbacks
|
||||
%%-include("ejabberd.hrl").
|
||||
%%-include("jlib.hrl").
|
||||
%%check_authzid(_State, Props) ->
|
||||
%% AuthzId = xml:get_attr_s(authzid, Props),
|
||||
%% case jlib:string_to_jid(AuthzId) of
|
||||
%% error ->
|
||||
%% {error, "invalid-authzid"};
|
||||
%% JID ->
|
||||
%% LUser = jlib:nodeprep(xml:get_attr_s(username, Props)),
|
||||
%% {U, S, R} = jlib:jid_tolower(JID),
|
||||
%% case R of
|
||||
%% "" ->
|
||||
%% {error, "invalid-authzid"};
|
||||
%% _ ->
|
||||
%% case {LUser, ?MYNAME} of
|
||||
%% {U, S} ->
|
||||
%% ok;
|
||||
%% _ ->
|
||||
%% {error, "invalid-authzid"}
|
||||
%% end
|
||||
%% end
|
||||
%% end.
|
||||
|
||||
check_credentials(_State, Props) ->
|
||||
User = proplists:get_value(username, Props, <<>>),
|
||||
case jlib:nodeprep(User) of
|
||||
error -> {error, <<"not-authorized">>};
|
||||
<<"">> -> {error, <<"not-authorized">>};
|
||||
_LUser -> ok
|
||||
% TODO: use callbacks
|
||||
-include("ejabberd.hrl").
|
||||
-include("jlib.hrl").
|
||||
check_authzid(State, Props) ->
|
||||
AuthzId = xml:get_attr_s(authzid, Props),
|
||||
case jlib:string_to_jid(AuthzId) of
|
||||
error ->
|
||||
{error, "invalid-authzid"};
|
||||
JID ->
|
||||
LUser = jlib:nodeprep(xml:get_attr_s(username, Props)),
|
||||
{U, S, R} = jlib:jid_tolower(JID),
|
||||
case R of
|
||||
"" ->
|
||||
{error, "invalid-authzid"};
|
||||
_ ->
|
||||
case {LUser, ?MYNAME} of
|
||||
{U, S} ->
|
||||
ok;
|
||||
_ ->
|
||||
{error, "invalid-authzid"}
|
||||
end
|
||||
end
|
||||
end.
|
||||
|
||||
-spec(listmech/1 ::
|
||||
(
|
||||
Host ::binary())
|
||||
-> Mechanisms::mechanisms()
|
||||
).
|
||||
check_credentials(State, Props) ->
|
||||
User = xml:get_attr_s(username, Props),
|
||||
case jlib:nodeprep(User) of
|
||||
error ->
|
||||
{error, "not-authorized"};
|
||||
"" ->
|
||||
{error, "not-authorized"};
|
||||
LUser ->
|
||||
ok
|
||||
end.
|
||||
|
||||
listmech(Host) ->
|
||||
Mechs = ets:select(sasl_mechanism,
|
||||
[{#sasl_mechanism{mechanism = '$1',
|
||||
password_type = '$2', _ = '_'},
|
||||
case catch ejabberd_auth:store_type(Host) of
|
||||
external -> [{'==', '$2', plain}];
|
||||
scram -> [{'/=', '$2', digest}];
|
||||
{'EXIT', {undef, [{Module, store_type, []} | _]}} ->
|
||||
?WARNING_MSG("~p doesn't implement the function store_type/0",
|
||||
[Module]),
|
||||
[];
|
||||
_Else -> []
|
||||
end,
|
||||
['$1']}]),
|
||||
filter_anonymous(Host, Mechs).
|
||||
listmech() ->
|
||||
ets:select(sasl_mechanism,
|
||||
[{#sasl_mechanism{mechanism = '$1', _ = '_'}, [], ['$1']}]).
|
||||
|
||||
server_new(Service, ServerFQDN, UserRealm, _SecFlags,
|
||||
GetPassword, CheckPassword, CheckPasswordDigest) ->
|
||||
#sasl_state{service = Service, myname = ServerFQDN,
|
||||
realm = UserRealm, get_password = GetPassword,
|
||||
check_password = CheckPassword,
|
||||
check_password_digest = CheckPasswordDigest}.
|
||||
|
||||
server_new(Service, ServerFQDN, UserRealm, SecFlags) ->
|
||||
#sasl_state{service = Service,
|
||||
myname = ServerFQDN,
|
||||
realm = UserRealm}.
|
||||
|
||||
server_start(State, Mech, ClientIn) ->
|
||||
case lists:member(Mech,
|
||||
listmech(State#sasl_state.myname))
|
||||
of
|
||||
true ->
|
||||
case ets:lookup(sasl_mechanism, Mech) of
|
||||
[#sasl_mechanism{module = Module}] ->
|
||||
{ok, MechState} =
|
||||
Module:mech_new(State#sasl_state.myname,
|
||||
State#sasl_state.get_password,
|
||||
State#sasl_state.check_password,
|
||||
State#sasl_state.check_password_digest),
|
||||
server_step(State#sasl_state{mech_mod = Module,
|
||||
mech_state = MechState},
|
||||
ClientIn);
|
||||
_ -> {error, <<"no-mechanism">>}
|
||||
end;
|
||||
false -> {error, <<"no-mechanism">>}
|
||||
case ets:lookup(sasl_mechanism, Mech) of
|
||||
[#sasl_mechanism{module = Module}] ->
|
||||
{ok, MechState} = Module:mech_new(),
|
||||
server_step(State#sasl_state{mech_mod = Module,
|
||||
mech_state = MechState},
|
||||
ClientIn);
|
||||
_ ->
|
||||
{error, "no-mechanism"}
|
||||
end.
|
||||
|
||||
server_step(State, ClientIn) ->
|
||||
Module = State#sasl_state.mech_mod,
|
||||
MechState = State#sasl_state.mech_state,
|
||||
case Module:mech_step(MechState, ClientIn) of
|
||||
{ok, Props} ->
|
||||
case check_credentials(State, Props) of
|
||||
ok -> {ok, Props};
|
||||
{error, Error} -> {error, Error}
|
||||
end;
|
||||
{ok, Props, ServerOut} ->
|
||||
case check_credentials(State, Props) of
|
||||
ok -> {ok, Props, ServerOut};
|
||||
{error, Error} -> {error, Error}
|
||||
end;
|
||||
{continue, ServerOut, NewMechState} ->
|
||||
{continue, ServerOut, State#sasl_state{mech_state = NewMechState}};
|
||||
{error, Error, Username} ->
|
||||
{error, Error, Username};
|
||||
{error, Error} ->
|
||||
{error, Error}
|
||||
{ok, Props} ->
|
||||
case check_credentials(State, Props) of
|
||||
ok ->
|
||||
{ok, Props};
|
||||
{error, Error} ->
|
||||
{error, Error}
|
||||
end;
|
||||
{continue, ServerOut, NewMechState} ->
|
||||
{continue, ServerOut,
|
||||
State#sasl_state{mech_state = NewMechState}};
|
||||
{error, Error} ->
|
||||
{error, Error}
|
||||
end.
|
||||
|
||||
%% Remove the anonymous mechanism from the list if not enabled for the given
|
||||
%% host
|
||||
%%
|
||||
-spec(filter_anonymous/2 ::
|
||||
(
|
||||
Host :: binary(),
|
||||
Mechs :: mechanisms())
|
||||
-> mechanisms()
|
||||
).
|
||||
|
||||
filter_anonymous(Host, Mechs) ->
|
||||
case ejabberd_auth_anonymous:is_sasl_anonymous_enabled(Host) of
|
||||
true -> Mechs;
|
||||
false -> Mechs -- [<<"ANONYMOUS">>]
|
||||
end.
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : cyrsasl_anonymous.erl
|
||||
%%% Author : Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%% Purpose : ANONYMOUS SASL mechanism
|
||||
%%% See http://www.ietf.org/internet-drafts/draft-ietf-sasl-anon-05.txt
|
||||
%%% Created : 23 Aug 2005 by Magnus Henoch <henoch@dtek.chalmers.se>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(cyrsasl_anonymous).
|
||||
|
||||
-export([start/1, stop/0, mech_new/4, mech_step/2]).
|
||||
|
||||
-behaviour(cyrsasl).
|
||||
|
||||
-record(state, {server = <<"">> :: binary()}).
|
||||
|
||||
start(_Opts) ->
|
||||
cyrsasl:register_mechanism(<<"ANONYMOUS">>, ?MODULE, plain),
|
||||
ok.
|
||||
|
||||
stop() -> ok.
|
||||
|
||||
mech_new(Host, _GetPassword, _CheckPassword, _CheckPasswordDigest) ->
|
||||
{ok, #state{server = Host}}.
|
||||
|
||||
mech_step(#state{server = Server}, _ClientIn) ->
|
||||
User = iolist_to_binary([randoms:get_string() | tuple_to_list(now())]),
|
||||
case ejabberd_auth:is_user_exists(User, Server) of
|
||||
true -> {error, <<"not-authorized">>};
|
||||
false -> {ok, [{username, User}, {auth_module, ejabberd_auth_anonymous}]}
|
||||
end.
|
||||
@@ -3,256 +3,162 @@
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose : DIGEST-MD5 SASL mechanism
|
||||
%%% Created : 11 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(cyrsasl_digest).
|
||||
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/1, stop/0, mech_new/4, mech_step/2, parse/1]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-export([start/1,
|
||||
stop/0,
|
||||
mech_new/0,
|
||||
mech_step/2]).
|
||||
|
||||
-behaviour(cyrsasl).
|
||||
%-behaviour(gen_mod).
|
||||
|
||||
-type get_password_fun() :: fun((binary()) -> {false, any()} |
|
||||
{binary(), atom()}).
|
||||
-record(state, {step, nonce, username, authzid}).
|
||||
|
||||
-type check_password_fun() :: fun((binary(), binary(), binary(),
|
||||
fun((binary()) -> binary())) ->
|
||||
{boolean(), any()} |
|
||||
false).
|
||||
start(Opts) ->
|
||||
case ejabberd_auth:plain_password_required() of
|
||||
true ->
|
||||
ok;
|
||||
false ->
|
||||
cyrsasl:register_mechanism("DIGEST-MD5", ?MODULE),
|
||||
ok
|
||||
end.
|
||||
|
||||
-record(state, {step = 1 :: 1 | 3 | 5,
|
||||
nonce = <<"">> :: binary(),
|
||||
username = <<"">> :: binary(),
|
||||
authzid = <<"">> :: binary(),
|
||||
get_password = fun(_) -> {false, <<>>} end :: get_password_fun(),
|
||||
check_password = fun(_, _, _, _) -> false end :: check_password_fun(),
|
||||
auth_module :: atom(),
|
||||
host = <<"">> :: binary(),
|
||||
hostfqdn = <<"">> :: binary()}).
|
||||
stop() ->
|
||||
ok.
|
||||
|
||||
start(_Opts) ->
|
||||
Fqdn = get_local_fqdn(),
|
||||
?INFO_MSG("FQDN used to check DIGEST-MD5 SASL authentication: ~s",
|
||||
[Fqdn]),
|
||||
cyrsasl:register_mechanism(<<"DIGEST-MD5">>, ?MODULE,
|
||||
digest).
|
||||
|
||||
stop() -> ok.
|
||||
|
||||
mech_new(Host, GetPassword, _CheckPassword,
|
||||
CheckPasswordDigest) ->
|
||||
{ok,
|
||||
#state{step = 1, nonce = randoms:get_string(),
|
||||
host = Host, hostfqdn = get_local_fqdn(),
|
||||
get_password = GetPassword,
|
||||
check_password = CheckPasswordDigest}}.
|
||||
mech_new() ->
|
||||
{ok, #state{step = 1,
|
||||
nonce = randoms:get_string()}}.
|
||||
|
||||
mech_step(#state{step = 1, nonce = Nonce} = State, _) ->
|
||||
{continue,
|
||||
<<"nonce=\"", Nonce/binary,
|
||||
"\",qop=\"auth\",charset=utf-8,algorithm=md5-sess">>,
|
||||
"nonce=\"" ++ Nonce ++
|
||||
"\",qop=\"auth\",charset=utf-8,algorithm=md5-sess",
|
||||
%"\",qop=\"auth,auth-int\",charset=utf-8,algorithm=md5-sess",
|
||||
State#state{step = 3}};
|
||||
mech_step(#state{step = 3, nonce = Nonce} = State,
|
||||
ClientIn) ->
|
||||
mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
|
||||
case parse(ClientIn) of
|
||||
bad -> {error, <<"bad-protocol">>};
|
||||
KeyVals ->
|
||||
DigestURI = proplists:get_value(<<"digest-uri">>, KeyVals, <<>>),
|
||||
%DigestURI = xml:get_attr_s(<<"digest-uri">>, KeyVals),
|
||||
UserName = proplists:get_value(<<"username">>, KeyVals, <<>>),
|
||||
%UserName = xml:get_attr_s(<<"username">>, KeyVals),
|
||||
case is_digesturi_valid(DigestURI, State#state.host,
|
||||
State#state.hostfqdn)
|
||||
of
|
||||
false ->
|
||||
?DEBUG("User login not authorized because digest-uri "
|
||||
"seems invalid: ~p (checking for Host "
|
||||
"~p, FQDN ~p)",
|
||||
[DigestURI, State#state.host, State#state.hostfqdn]),
|
||||
{error, <<"not-authorized">>, UserName};
|
||||
true ->
|
||||
AuthzId = proplists:get_value(<<"authzid">>, KeyVals, <<>>),
|
||||
%AuthzId = xml:get_attr_s(<<"authzid">>, KeyVals),
|
||||
case (State#state.get_password)(UserName) of
|
||||
{false, _} -> {error, <<"not-authorized">>, UserName};
|
||||
{Passwd, AuthModule} ->
|
||||
case (State#state.check_password)(UserName, <<"">>,
|
||||
proplists:get_value(<<"response">>, KeyVals, <<>>),
|
||||
%xml:get_attr_s(<<"response">>, KeyVals),
|
||||
fun (PW) ->
|
||||
response(KeyVals,
|
||||
UserName,
|
||||
PW,
|
||||
Nonce,
|
||||
AuthzId,
|
||||
<<"AUTHENTICATE">>)
|
||||
end)
|
||||
of
|
||||
{true, _} ->
|
||||
RspAuth = response(KeyVals, UserName, Passwd, Nonce,
|
||||
AuthzId, <<"">>),
|
||||
{continue, <<"rspauth=", RspAuth/binary>>,
|
||||
State#state{step = 5, auth_module = AuthModule,
|
||||
bad ->
|
||||
{error, "bad-protocol"};
|
||||
KeyVals ->
|
||||
UserName = xml:get_attr_s("username", KeyVals),
|
||||
AuthzId = xml:get_attr_s("authzid", KeyVals),
|
||||
case ejabberd_auth:get_password(UserName) of
|
||||
false ->
|
||||
{error, "not-authorized"};
|
||||
Passwd ->
|
||||
Response = response(KeyVals, UserName, Passwd,
|
||||
Nonce, AuthzId, "AUTHENTICATE"),
|
||||
case xml:get_attr_s("response", KeyVals) of
|
||||
Response ->
|
||||
RspAuth = response(KeyVals,
|
||||
UserName, Passwd,
|
||||
Nonce, AuthzId, ""),
|
||||
{continue,
|
||||
"rspauth=" ++ RspAuth,
|
||||
State#state{step = 5,
|
||||
username = UserName,
|
||||
authzid = AuthzId}};
|
||||
false -> {error, <<"not-authorized">>, UserName};
|
||||
{false, _} -> {error, <<"not-authorized">>, UserName}
|
||||
end
|
||||
end
|
||||
end
|
||||
_ ->
|
||||
{error, "not-authorized"}
|
||||
end
|
||||
end
|
||||
end;
|
||||
mech_step(#state{step = 5, auth_module = AuthModule,
|
||||
username = UserName, authzid = AuthzId},
|
||||
<<"">>) ->
|
||||
{ok,
|
||||
[{username, UserName}, {authzid, AuthzId},
|
||||
{auth_module, AuthModule}]};
|
||||
mech_step(#state{step = 5,
|
||||
username = UserName,
|
||||
authzid = AuthzId} = State, "") ->
|
||||
{ok, [{username, UserName}, {authzid, AuthzId}]};
|
||||
mech_step(A, B) ->
|
||||
?DEBUG("SASL DIGEST: A ~p B ~p", [A, B]),
|
||||
{error, <<"bad-protocol">>}.
|
||||
io:format("SASL DIGEST: A ~p B ~p", [A,B]),
|
||||
{error, "bad-protocol"}.
|
||||
|
||||
parse(S) -> parse1(binary_to_list(S), "", []).
|
||||
|
||||
parse(S) ->
|
||||
parse1(S, "", []).
|
||||
|
||||
parse1([$= | Cs], S, Ts) ->
|
||||
parse2(Cs, lists:reverse(S), "", Ts);
|
||||
parse1([$, | Cs], [], Ts) -> parse1(Cs, [], Ts);
|
||||
parse1([$\s | Cs], [], Ts) -> parse1(Cs, [], Ts);
|
||||
parse1([C | Cs], S, Ts) -> parse1(Cs, [C | S], Ts);
|
||||
parse1([], [], T) -> lists:reverse(T);
|
||||
parse1([], _S, _T) -> bad.
|
||||
parse1([C | Cs], S, Ts) ->
|
||||
parse1(Cs, [C | S], Ts);
|
||||
parse1([], [], T) ->
|
||||
lists:reverse(T);
|
||||
parse1([], S, T) ->
|
||||
bad.
|
||||
|
||||
parse2([$" | Cs], Key, Val, Ts) ->
|
||||
parse3(Cs, Key, Val, Ts);
|
||||
parse2([C | Cs], Key, Val, Ts) ->
|
||||
parse4(Cs, Key, [C | Val], Ts);
|
||||
parse2([], _, _, _) -> bad.
|
||||
parse2([], _, _, _) ->
|
||||
bad.
|
||||
|
||||
parse3([$" | Cs], Key, Val, Ts) ->
|
||||
parse4(Cs, Key, Val, Ts);
|
||||
parse3([$\\, C | Cs], Key, Val, Ts) ->
|
||||
parse3(Cs, Key, [C | Val], Ts);
|
||||
parse3([C | Cs], Key, Val, Ts) ->
|
||||
parse3(Cs, Key, [C | Val], Ts);
|
||||
parse3([], _, _, _) -> bad.
|
||||
parse3([], _, _, _) ->
|
||||
bad.
|
||||
|
||||
parse4([$, | Cs], Key, Val, Ts) ->
|
||||
parse1(Cs, "", [{list_to_binary(Key), list_to_binary(lists:reverse(Val))} | Ts]);
|
||||
parse4([$\s | Cs], Key, Val, Ts) ->
|
||||
parse4(Cs, Key, Val, Ts);
|
||||
parse1(Cs, "", [{Key, lists:reverse(Val)} | Ts]);
|
||||
parse4([C | Cs], Key, Val, Ts) ->
|
||||
parse4(Cs, Key, [C | Val], Ts);
|
||||
parse4([], Key, Val, Ts) ->
|
||||
%% @doc Check if the digest-uri is valid.
|
||||
%% RFC-2831 allows to provide the IP address in Host,
|
||||
%% however ejabberd doesn't allow that.
|
||||
%% If the service (for example jabber.example.org)
|
||||
%% is provided by several hosts (being one of them server3.example.org),
|
||||
%% then acceptable digest-uris would be:
|
||||
%% xmpp/server3.example.org/jabber.example.org, xmpp/server3.example.org and
|
||||
%% xmpp/jabber.example.org
|
||||
%% The last version is not actually allowed by the RFC, but implemented by popular clients
|
||||
parse1([], "", [{list_to_binary(Key), list_to_binary(lists:reverse(Val))} | Ts]).
|
||||
parse1([], "", [{Key, lists:reverse(Val)} | Ts]).
|
||||
|
||||
is_digesturi_valid(DigestURICase, JabberDomain,
|
||||
JabberFQDN) ->
|
||||
DigestURI = stringprep:tolower(DigestURICase),
|
||||
case catch str:tokens(DigestURI, <<"/">>) of
|
||||
[<<"xmpp">>, Host] ->
|
||||
IsHostFqdn = is_host_fqdn(binary_to_list(Host), binary_to_list(JabberFQDN)),
|
||||
(Host == JabberDomain) or IsHostFqdn;
|
||||
[<<"xmpp">>, Host, ServName] ->
|
||||
IsHostFqdn = is_host_fqdn(binary_to_list(Host), binary_to_list(JabberFQDN)),
|
||||
(ServName == JabberDomain) and IsHostFqdn;
|
||||
_ ->
|
||||
false
|
||||
end.
|
||||
|
||||
is_host_fqdn(Host, [Letter | _Tail] = Fqdn) when not is_list(Letter) ->
|
||||
Host == Fqdn;
|
||||
is_host_fqdn(_Host, []) ->
|
||||
false;
|
||||
is_host_fqdn(Host, [Fqdn | _FqdnTail]) when Host == Fqdn ->
|
||||
true;
|
||||
is_host_fqdn(Host, [Fqdn | FqdnTail]) when Host /= Fqdn ->
|
||||
is_host_fqdn(Host, FqdnTail).
|
||||
|
||||
get_local_fqdn() ->
|
||||
case catch get_local_fqdn2() of
|
||||
Str when is_binary(Str) -> Str;
|
||||
_ ->
|
||||
<<"unknown-fqdn, please configure fqdn "
|
||||
"option in ejabberd.cfg!">>
|
||||
end.
|
||||
|
||||
get_local_fqdn2() ->
|
||||
case ejabberd_config:get_local_option(
|
||||
fqdn, fun iolist_to_binary/1) of
|
||||
ConfiguredFqdn when is_binary(ConfiguredFqdn) ->
|
||||
ConfiguredFqdn;
|
||||
undefined ->
|
||||
{ok, Hostname} = inet:gethostname(),
|
||||
{ok, {hostent, Fqdn, _, _, _, _}} =
|
||||
inet:gethostbyname(Hostname),
|
||||
list_to_binary(Fqdn)
|
||||
end.
|
||||
|
||||
|
||||
digit_to_xchar(D) when (D >= 0) and (D < 10) ->
|
||||
D + 48;
|
||||
digit_to_xchar(D) ->
|
||||
D + 87.
|
||||
|
||||
hex(S) ->
|
||||
sha:to_hexlist(S).
|
||||
hex(S, []).
|
||||
|
||||
proplists_get_bin_value(Key, Pairs, Default) ->
|
||||
case proplists:get_value(Key, Pairs, Default) of
|
||||
L when is_list(L) ->
|
||||
list_to_binary(L);
|
||||
L2 ->
|
||||
L2
|
||||
end.
|
||||
hex([], Res) ->
|
||||
lists:reverse(Res);
|
||||
hex([N | Ns], Res) ->
|
||||
hex(Ns, [digit_to_xchar(N rem 16),
|
||||
digit_to_xchar(N div 16) | Res]).
|
||||
|
||||
response(KeyVals, User, Passwd, Nonce, AuthzId,
|
||||
A2Prefix) ->
|
||||
Realm = proplists_get_bin_value(<<"realm">>, KeyVals, <<>>),
|
||||
CNonce = proplists_get_bin_value(<<"cnonce">>, KeyVals, <<>>),
|
||||
DigestURI = proplists_get_bin_value(<<"digest-uri">>, KeyVals, <<>>),
|
||||
NC = proplists_get_bin_value(<<"nc">>, KeyVals, <<>>),
|
||||
QOP = proplists_get_bin_value(<<"qop">>, KeyVals, <<>>),
|
||||
MD5Hash = crypto:md5(<<User/binary, ":", Realm/binary, ":",
|
||||
Passwd/binary>>),
|
||||
|
||||
response(KeyVals, User, Passwd, Nonce, AuthzId, A2Prefix) ->
|
||||
Realm = xml:get_attr_s("realm", KeyVals),
|
||||
CNonce = xml:get_attr_s("cnonce", KeyVals),
|
||||
DigestURI = xml:get_attr_s("digest-uri", KeyVals),
|
||||
NC = xml:get_attr_s("nc", KeyVals),
|
||||
QOP = xml:get_attr_s("qop", KeyVals),
|
||||
A1 = case AuthzId of
|
||||
<<"">> ->
|
||||
<<MD5Hash/binary, ":", Nonce/binary, ":", CNonce/binary>>;
|
||||
_ ->
|
||||
<<MD5Hash/binary, ":", Nonce/binary, ":", CNonce/binary, ":",
|
||||
AuthzId/binary>>
|
||||
"" ->
|
||||
binary_to_list(
|
||||
crypto:md5(User ++ ":" ++ Realm ++ ":" ++ Passwd)) ++
|
||||
":" ++ Nonce ++ ":" ++ CNonce;
|
||||
_ ->
|
||||
binary_to_list(
|
||||
crypto:md5(User ++ ":" ++ Realm ++ ":" ++ Passwd)) ++
|
||||
":" ++ Nonce ++ ":" ++ CNonce ++ ":" ++ AuthzId
|
||||
end,
|
||||
A2 = case QOP of
|
||||
<<"auth">> ->
|
||||
<<A2Prefix/binary, ":", DigestURI/binary>>;
|
||||
_ ->
|
||||
<<A2Prefix/binary, ":", DigestURI/binary,
|
||||
":00000000000000000000000000000000">>
|
||||
end,
|
||||
T = <<(hex((crypto:md5(A1))))/binary, ":", Nonce/binary,
|
||||
":", NC/binary, ":", CNonce/binary, ":", QOP/binary,
|
||||
":", (hex((crypto:md5(A2))))/binary>>,
|
||||
hex((crypto:md5(T))).
|
||||
case QOP of
|
||||
"auth" ->
|
||||
A2 = A2Prefix ++ ":" ++ DigestURI;
|
||||
_ ->
|
||||
A2 = A2Prefix ++ ":" ++ DigestURI ++
|
||||
":00000000000000000000000000000000"
|
||||
end,
|
||||
T = hex(binary_to_list(crypto:md5(A1))) ++ ":" ++ Nonce ++ ":" ++
|
||||
NC ++ ":" ++ CNonce ++ ":" ++ QOP ++ ":" ++
|
||||
hex(binary_to_list(crypto:md5(A2))),
|
||||
hex(binary_to_list(crypto:md5(T))).
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,90 +1,56 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : cyrsasl_plain.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose : PLAIN SASL mechanism
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(cyrsasl_plain).
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-author('alexey@process-one.net').
|
||||
|
||||
-export([start/1, stop/0, mech_new/4, mech_step/2, parse/1]).
|
||||
-export([start/1, stop/0, mech_new/0, mech_step/2, parse/1]).
|
||||
|
||||
-behaviour(cyrsasl).
|
||||
%-behaviour(gen_mod).
|
||||
|
||||
-record(state, {check_password}).
|
||||
|
||||
start(_Opts) ->
|
||||
cyrsasl:register_mechanism(<<"PLAIN">>, ?MODULE, plain),
|
||||
start(Opts) ->
|
||||
cyrsasl:register_mechanism("PLAIN", ?MODULE),
|
||||
ok.
|
||||
|
||||
stop() -> ok.
|
||||
stop() ->
|
||||
ok.
|
||||
|
||||
mech_new(_Host, _GetPassword, CheckPassword, _CheckPasswordDigest) ->
|
||||
{ok, #state{check_password = CheckPassword}}.
|
||||
mech_new() ->
|
||||
{ok, []}.
|
||||
|
||||
mech_step(State, ClientIn) ->
|
||||
case prepare(ClientIn) of
|
||||
[AuthzId, User, Password] ->
|
||||
case (State#state.check_password)(User, Password) of
|
||||
{true, AuthModule} ->
|
||||
{ok,
|
||||
[{username, User}, {authzid, AuthzId},
|
||||
{auth_module, AuthModule}]};
|
||||
_ -> {error, <<"not-authorized">>, User}
|
||||
end;
|
||||
_ -> {error, <<"bad-protocol">>}
|
||||
end.
|
||||
|
||||
prepare(ClientIn) ->
|
||||
case parse(ClientIn) of
|
||||
[<<"">>, UserMaybeDomain, Password] ->
|
||||
case parse_domain(UserMaybeDomain) of
|
||||
%% <NUL>login@domain<NUL>pwd
|
||||
[User, _Domain] -> [UserMaybeDomain, User, Password];
|
||||
%% <NUL>login<NUL>pwd
|
||||
[User] -> [<<"">>, User, Password]
|
||||
end;
|
||||
%% login@domain<NUL>login<NUL>pwd
|
||||
[AuthzId, User, Password] -> [AuthzId, User, Password];
|
||||
_ -> error
|
||||
[AuthzId, User, Password] ->
|
||||
case ejabberd_auth:check_password(User, Password) of
|
||||
true ->
|
||||
{ok, [{username, User}, {authzid, AuthzId}]};
|
||||
_ ->
|
||||
{error, "bad-auth"}
|
||||
end;
|
||||
_ ->
|
||||
{error, "bad-protocol"}
|
||||
end.
|
||||
|
||||
parse(S) -> parse1(binary_to_list(S), "", []).
|
||||
|
||||
parse(S) ->
|
||||
parse1(S, "", []).
|
||||
|
||||
parse1([0 | Cs], S, T) ->
|
||||
parse1(Cs, "", [list_to_binary(lists:reverse(S)) | T]);
|
||||
parse1([C | Cs], S, T) -> parse1(Cs, [C | S], T);
|
||||
parse1(Cs, "", [lists:reverse(S) | T]);
|
||||
parse1([C | Cs], S, T) ->
|
||||
parse1(Cs, [C | S], T);
|
||||
%parse1([], [], T) ->
|
||||
% lists:reverse(T);
|
||||
parse1([], S, T) ->
|
||||
lists:reverse([list_to_binary(lists:reverse(S)) | T]).
|
||||
lists:reverse([lists:reverse(S) | T]).
|
||||
|
||||
|
||||
|
||||
parse_domain(S) -> parse_domain1(binary_to_list(S), "", []).
|
||||
|
||||
parse_domain1([$@ | Cs], S, T) ->
|
||||
parse_domain1(Cs, "", [list_to_binary(lists:reverse(S)) | T]);
|
||||
parse_domain1([C | Cs], S, T) ->
|
||||
parse_domain1(Cs, [C | S], T);
|
||||
parse_domain1([], S, T) ->
|
||||
lists:reverse([list_to_binary(lists:reverse(S)) | T]).
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : cyrsasl_scram.erl
|
||||
%%% Author : Stephen Röttger <stephen.roettger@googlemail.com>
|
||||
%%% Purpose : SASL SCRAM authentication
|
||||
%%% Created : 7 Aug 2011 by Stephen Röttger <stephen.roettger@googlemail.com>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(cyrsasl_scram).
|
||||
|
||||
-author('stephen.roettger@googlemail.com').
|
||||
|
||||
-export([start/1, stop/0, mech_new/4, mech_step/2]).
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
|
||||
-behaviour(cyrsasl).
|
||||
|
||||
-record(state,
|
||||
{step = 2 :: 2 | 4,
|
||||
stored_key = <<"">> :: binary(),
|
||||
server_key = <<"">> :: binary(),
|
||||
username = <<"">> :: binary(),
|
||||
get_password :: fun(),
|
||||
check_password :: fun(),
|
||||
auth_message = <<"">> :: binary(),
|
||||
client_nonce = <<"">> :: binary(),
|
||||
server_nonce = <<"">> :: binary()}).
|
||||
|
||||
-define(SALT_LENGTH, 16).
|
||||
|
||||
-define(NONCE_LENGTH, 16).
|
||||
|
||||
start(_Opts) ->
|
||||
cyrsasl:register_mechanism(<<"SCRAM-SHA-1">>, ?MODULE,
|
||||
scram).
|
||||
|
||||
stop() -> ok.
|
||||
|
||||
mech_new(_Host, GetPassword, _CheckPassword,
|
||||
_CheckPasswordDigest) ->
|
||||
{ok, #state{step = 2, get_password = GetPassword}}.
|
||||
|
||||
mech_step(#state{step = 2} = State, ClientIn) ->
|
||||
case str:tokens(ClientIn, <<",">>) of
|
||||
[CBind, UserNameAttribute, ClientNonceAttribute]
|
||||
when (CBind == <<"y">>) or (CBind == <<"n">>) ->
|
||||
case parse_attribute(UserNameAttribute) of
|
||||
{error, Reason} -> {error, Reason};
|
||||
{_, EscapedUserName} ->
|
||||
case unescape_username(EscapedUserName) of
|
||||
error -> {error, <<"protocol-error-bad-username">>};
|
||||
UserName ->
|
||||
case parse_attribute(ClientNonceAttribute) of
|
||||
{$r, ClientNonce} ->
|
||||
case (State#state.get_password)(UserName) of
|
||||
{false, _} -> {error, <<"not-authorized">>, UserName};
|
||||
{Ret, _AuthModule} ->
|
||||
{StoredKey, ServerKey, Salt, IterationCount} =
|
||||
if is_tuple(Ret) -> Ret;
|
||||
true ->
|
||||
TempSalt =
|
||||
crypto:rand_bytes(?SALT_LENGTH),
|
||||
SaltedPassword =
|
||||
scram:salted_password(Ret,
|
||||
TempSalt,
|
||||
?SCRAM_DEFAULT_ITERATION_COUNT),
|
||||
{scram:stored_key(scram:client_key(SaltedPassword)),
|
||||
scram:server_key(SaltedPassword),
|
||||
TempSalt,
|
||||
?SCRAM_DEFAULT_ITERATION_COUNT}
|
||||
end,
|
||||
ClientFirstMessageBare =
|
||||
str:substr(ClientIn,
|
||||
str:str(ClientIn, <<"n=">>)),
|
||||
ServerNonce =
|
||||
jlib:encode_base64(crypto:rand_bytes(?NONCE_LENGTH)),
|
||||
ServerFirstMessage =
|
||||
iolist_to_binary(
|
||||
["r=",
|
||||
ClientNonce,
|
||||
ServerNonce,
|
||||
",", "s=",
|
||||
jlib:encode_base64(Salt),
|
||||
",", "i=",
|
||||
integer_to_list(IterationCount)]),
|
||||
{continue, ServerFirstMessage,
|
||||
State#state{step = 4, stored_key = StoredKey,
|
||||
server_key = ServerKey,
|
||||
auth_message =
|
||||
<<ClientFirstMessageBare/binary,
|
||||
",", ServerFirstMessage/binary>>,
|
||||
client_nonce = ClientNonce,
|
||||
server_nonce = ServerNonce,
|
||||
username = UserName}}
|
||||
end;
|
||||
_Else -> {error, <<"not-supported">>}
|
||||
end
|
||||
end
|
||||
end;
|
||||
_Else -> {error, <<"bad-protocol">>}
|
||||
end;
|
||||
mech_step(#state{step = 4} = State, ClientIn) ->
|
||||
case str:tokens(ClientIn, <<",">>) of
|
||||
[GS2ChannelBindingAttribute, NonceAttribute,
|
||||
ClientProofAttribute] ->
|
||||
case parse_attribute(GS2ChannelBindingAttribute) of
|
||||
{$c, CVal} when (CVal == <<"biws">>) or (CVal == <<"eSws">>) ->
|
||||
%% biws is base64 for n,, => channelbinding not supported
|
||||
%% eSws is base64 for y,, => channelbinding supported by client only
|
||||
Nonce = <<(State#state.client_nonce)/binary,
|
||||
(State#state.server_nonce)/binary>>,
|
||||
case parse_attribute(NonceAttribute) of
|
||||
{$r, CompareNonce} when CompareNonce == Nonce ->
|
||||
case parse_attribute(ClientProofAttribute) of
|
||||
{$p, ClientProofB64} ->
|
||||
ClientProof = jlib:decode_base64(ClientProofB64),
|
||||
AuthMessage =
|
||||
iolist_to_binary(
|
||||
[State#state.auth_message,
|
||||
",",
|
||||
str:substr(ClientIn, 1,
|
||||
str:str(ClientIn, <<",p=">>)
|
||||
- 1)]),
|
||||
ClientSignature =
|
||||
scram:client_signature(State#state.stored_key,
|
||||
AuthMessage),
|
||||
ClientKey = scram:client_key(ClientProof,
|
||||
ClientSignature),
|
||||
CompareStoredKey = scram:stored_key(ClientKey),
|
||||
if CompareStoredKey == State#state.stored_key ->
|
||||
ServerSignature =
|
||||
scram:server_signature(State#state.server_key,
|
||||
AuthMessage),
|
||||
{ok, [{username, State#state.username}],
|
||||
<<"v=",
|
||||
(jlib:encode_base64(ServerSignature))/binary>>};
|
||||
true -> {error, <<"bad-auth">>}
|
||||
end;
|
||||
_Else -> {error, <<"bad-protocol">>}
|
||||
end;
|
||||
{$r, _} -> {error, <<"bad-nonce">>};
|
||||
_Else -> {error, <<"bad-protocol">>}
|
||||
end;
|
||||
_Else -> {error, <<"bad-protocol">>}
|
||||
end;
|
||||
_Else -> {error, <<"bad-protocol">>}
|
||||
end.
|
||||
|
||||
parse_attribute(Attribute) ->
|
||||
AttributeLen = byte_size(Attribute),
|
||||
if AttributeLen >= 3 ->
|
||||
AttributeS = binary_to_list(Attribute),
|
||||
SecondChar = lists:nth(2, AttributeS),
|
||||
case is_alpha(lists:nth(1, AttributeS)) of
|
||||
true ->
|
||||
if SecondChar == $= ->
|
||||
String = str:substr(Attribute, 3),
|
||||
{lists:nth(1, AttributeS), String};
|
||||
true -> {error, <<"bad-format second char not equal sign">>}
|
||||
end;
|
||||
_Else -> {error, <<"bad-format first char not a letter">>}
|
||||
end;
|
||||
true -> {error, <<"bad-format attribute too short">>}
|
||||
end.
|
||||
|
||||
unescape_username(<<"">>) -> <<"">>;
|
||||
unescape_username(EscapedUsername) ->
|
||||
Pos = str:str(EscapedUsername, <<"=">>),
|
||||
if Pos == 0 -> EscapedUsername;
|
||||
true ->
|
||||
Start = str:substr(EscapedUsername, 1, Pos - 1),
|
||||
End = str:substr(EscapedUsername, Pos),
|
||||
EndLen = byte_size(End),
|
||||
if EndLen < 3 -> error;
|
||||
true ->
|
||||
case str:substr(End, 1, 3) of
|
||||
<<"=2C">> ->
|
||||
<<Start/binary, ",",
|
||||
(unescape_username(str:substr(End, 4)))/binary>>;
|
||||
<<"=3D">> ->
|
||||
<<Start/binary, "=",
|
||||
(unescape_username(str:substr(End, 4)))/binary>>;
|
||||
_Else -> error
|
||||
end
|
||||
end
|
||||
end.
|
||||
|
||||
is_alpha(Char) when Char >= $a, Char =< $z -> true;
|
||||
is_alpha(Char) when Char >= $A, Char =< $Z -> true;
|
||||
is_alpha(_) -> false.
|
||||
@@ -1,268 +0,0 @@
|
||||
%% Copyright (c) 2007
|
||||
%% Mats Cronqvist <mats.cronqvist@ericsson.com>
|
||||
%% Chris Newcombe <chris.newcombe@gmail.com>
|
||||
%% Jacob Vorreuter <jacob.vorreuter@gmail.com>
|
||||
%%
|
||||
%% Permission is hereby granted, free of charge, to any person
|
||||
%% obtaining a copy of this software and associated documentation
|
||||
%% files (the "Software"), to deal in the Software without
|
||||
%% restriction, including without limitation the rights to use,
|
||||
%% copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
%% copies of the Software, and to permit persons to whom the
|
||||
%% Software is furnished to do so, subject to the following
|
||||
%% conditions:
|
||||
%%
|
||||
%% The above copyright notice and this permission notice shall be
|
||||
%% included in all copies or substantial portions of the Software.
|
||||
%%
|
||||
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
%% OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% File : dynamic_compile.erl
|
||||
%%% Description :
|
||||
%%% Authors : Mats Cronqvist <mats.cronqvist@ericsson.com>
|
||||
%%% Chris Newcombe <chris.newcombe@gmail.com>
|
||||
%%% Jacob Vorreuter <jacob.vorreuter@gmail.com>
|
||||
%%% TODO :
|
||||
%%% - add support for limit include-file depth (and prevent circular references)
|
||||
%%% prevent circular macro expansion set FILE correctly when -module() is found
|
||||
%%% -include_lib support $ENVVAR in include filenames
|
||||
%%% substitute-stringize (??MACRO)
|
||||
%%% -undef/-ifdef/-ifndef/-else/-endif
|
||||
%%% -file(File, Line)
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(dynamic_compile).
|
||||
|
||||
%% API
|
||||
-export([from_string/1, from_string/2]).
|
||||
|
||||
-import(lists, [reverse/1, keyreplace/4]).
|
||||
|
||||
%%====================================================================
|
||||
%% API
|
||||
%%====================================================================
|
||||
%%--------------------------------------------------------------------
|
||||
%% Function:
|
||||
%% Description:
|
||||
%% Returns a binary that can be used with
|
||||
%% code:load_binary(Module, ModuleFilenameForInternalRecords, Binary).
|
||||
%%--------------------------------------------------------------------
|
||||
from_string(CodeStr) ->
|
||||
from_string(CodeStr, []).
|
||||
|
||||
% takes Options as for compile:forms/2
|
||||
from_string(CodeStr, CompileFormsOptions) ->
|
||||
%% Initialise the macro dictionary with the default predefined macros,
|
||||
%% (adapted from epp.erl:predef_macros/1
|
||||
Filename = "compiled_from_string",
|
||||
%%Machine = list_to_atom(erlang:system_info(machine)),
|
||||
Ms0 = dict:new(),
|
||||
% Ms1 = dict:store('FILE', {[], "compiled_from_string"}, Ms0),
|
||||
% Ms2 = dict:store('LINE', {[], 1}, Ms1), % actually we might add special code for this
|
||||
% Ms3 = dict:store('MODULE', {[], undefined}, Ms2),
|
||||
% Ms4 = dict:store('MODULE_STRING', {[], undefined}, Ms3),
|
||||
% Ms5 = dict:store('MACHINE', {[], Machine}, Ms4),
|
||||
% InitMD = dict:store(Machine, {[], true}, Ms5),
|
||||
InitMD = Ms0,
|
||||
|
||||
%% From the docs for compile:forms:
|
||||
%% When encountering an -include or -include_dir directive, the compiler searches for header files in the following directories:
|
||||
%% 1. ".", the current working directory of the file server;
|
||||
%% 2. the base name of the compiled file;
|
||||
%% 3. the directories specified using the i option. The directory specified last is searched first.
|
||||
%% In this case, #2 is meaningless.
|
||||
IncludeSearchPath = ["." | reverse([Dir || {i, Dir} <- CompileFormsOptions])],
|
||||
{RevForms, _OutMacroDict} = scan_and_parse(CodeStr, Filename, 1, [], InitMD, IncludeSearchPath),
|
||||
Forms = reverse(RevForms),
|
||||
|
||||
%% note: 'binary' is forced as an implicit option, whether it is provided or not.
|
||||
case compile:forms(Forms, CompileFormsOptions) of
|
||||
{ok, ModuleName, CompiledCodeBinary} when is_binary(CompiledCodeBinary) ->
|
||||
{ModuleName, CompiledCodeBinary};
|
||||
{ok, ModuleName, CompiledCodeBinary, []} when is_binary(CompiledCodeBinary) -> % empty warnings list
|
||||
{ModuleName, CompiledCodeBinary};
|
||||
{ok, _ModuleName, _CompiledCodeBinary, Warnings} ->
|
||||
throw({?MODULE, warnings, Warnings});
|
||||
Other ->
|
||||
throw({?MODULE, compile_forms, Other})
|
||||
end.
|
||||
|
||||
%%====================================================================
|
||||
%% Internal functions
|
||||
%%====================================================================
|
||||
%%% Code from Mats Cronqvist
|
||||
%%% See http://www.erlang.org/pipermail/erlang-questions/2007-March/025507.html
|
||||
%%%## 'scan_and_parse'
|
||||
%%%
|
||||
%%% basically we call the OTP scanner and parser (erl_scan and
|
||||
%%% erl_parse) line-by-line, but check each scanned line for (or
|
||||
%%% definitions of) macros before parsing.
|
||||
%% returns {ReverseForms, FinalMacroDict}
|
||||
scan_and_parse([], _CurrFilename, _CurrLine, RevForms, MacroDict, _IncludeSearchPath) ->
|
||||
{RevForms, MacroDict};
|
||||
|
||||
scan_and_parse(RemainingText, CurrFilename, CurrLine, RevForms, MacroDict, IncludeSearchPath) ->
|
||||
case scanner(RemainingText, CurrLine, MacroDict) of
|
||||
{tokens, NLine, NRemainingText, Toks} ->
|
||||
{ok, Form} = erl_parse:parse_form(Toks),
|
||||
scan_and_parse(NRemainingText, CurrFilename, NLine, [Form | RevForms], MacroDict, IncludeSearchPath);
|
||||
{macro, NLine, NRemainingText, NMacroDict} ->
|
||||
scan_and_parse(NRemainingText, CurrFilename, NLine, RevForms,NMacroDict, IncludeSearchPath);
|
||||
{include, NLine, NRemainingText, IncludeFilename} ->
|
||||
IncludeFileRemainingTextents = read_include_file(IncludeFilename, IncludeSearchPath),
|
||||
%%io:format("include file ~p contents: ~n~p~nRemainingText = ~p~n", [IncludeFilename,IncludeFileRemainingTextents, RemainingText]),
|
||||
%% Modify the FILE macro to reflect the filename
|
||||
%%IncludeMacroDict = dict:store('FILE', {[],IncludeFilename}, MacroDict),
|
||||
IncludeMacroDict = MacroDict,
|
||||
|
||||
%% Process the header file (inc. any nested header files)
|
||||
{RevIncludeForms, IncludedMacroDict} = scan_and_parse(IncludeFileRemainingTextents, IncludeFilename, 1, [], IncludeMacroDict, IncludeSearchPath),
|
||||
%io:format("include file results = ~p~n", [R]),
|
||||
%% Restore the FILE macro in the NEW MacroDict (so we keep any macros defined in the header file)
|
||||
%%NMacroDict = dict:store('FILE', {[],CurrFilename}, IncludedMacroDict),
|
||||
NMacroDict = IncludedMacroDict,
|
||||
|
||||
%% Continue with the original file
|
||||
scan_and_parse(NRemainingText, CurrFilename, NLine, RevIncludeForms ++ RevForms, NMacroDict, IncludeSearchPath);
|
||||
done ->
|
||||
scan_and_parse([], CurrFilename, CurrLine, RevForms, MacroDict, IncludeSearchPath)
|
||||
end.
|
||||
|
||||
scanner(Text, Line, MacroDict) ->
|
||||
case erl_scan:tokens([],Text,Line) of
|
||||
{done, {ok,Toks,NLine}, LeftOverChars} ->
|
||||
case pre_proc(Toks, MacroDict) of
|
||||
{tokens, NToks} -> {tokens, NLine, LeftOverChars, NToks};
|
||||
{macro, NMacroDict} -> {macro, NLine, LeftOverChars, NMacroDict};
|
||||
{include, Filename} -> {include, NLine, LeftOverChars, Filename}
|
||||
end;
|
||||
{more, _Continuation} ->
|
||||
%% This is supposed to mean "term is not yet complete" (i.e. a '.' has
|
||||
%% not been reached yet).
|
||||
%% However, for some bizarre reason we also get this if there is a comment after the final '.' in a file.
|
||||
%% So we check to see if Text only consists of comments.
|
||||
case is_only_comments(Text) of
|
||||
true ->
|
||||
done;
|
||||
false ->
|
||||
throw({incomplete_term, Text, Line})
|
||||
end
|
||||
end.
|
||||
|
||||
is_only_comments(Text) -> is_only_comments(Text, not_in_comment).
|
||||
|
||||
is_only_comments([], _) -> true;
|
||||
is_only_comments([$ |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment
|
||||
is_only_comments([$\t |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment
|
||||
is_only_comments([$\n |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment
|
||||
is_only_comments([$% |T], not_in_comment) -> is_only_comments(T, in_comment); % found start of a comment
|
||||
is_only_comments(_, not_in_comment) -> false;
|
||||
% found any significant char NOT in a comment
|
||||
is_only_comments([$\n |T], in_comment) -> is_only_comments(T, not_in_comment); % found end of a comment
|
||||
is_only_comments([_ |T], in_comment) -> is_only_comments(T, in_comment). % skipping over in-comment chars
|
||||
|
||||
%%%## 'pre-proc'
|
||||
%%%
|
||||
%%% have to implement a subset of the pre-processor, since epp insists
|
||||
%%% on running on a file.
|
||||
%%% only handles 2 cases;
|
||||
%% -define(MACRO, something).
|
||||
%% -define(MACRO(VAR1,VARN),{stuff,VAR1,more,stuff,VARN,extra,stuff}).
|
||||
pre_proc([{'-',_},{atom,_,define},{'(',_},{_,_,Name}|DefToks],MacroDict) ->
|
||||
false = dict:is_key(Name, MacroDict),
|
||||
case DefToks of
|
||||
[{',',_} | Macro] ->
|
||||
{macro, dict:store(Name, {[], macro_body_def(Macro, [])}, MacroDict)};
|
||||
[{'(',_} | Macro] ->
|
||||
{macro, dict:store(Name, macro_params_body_def(Macro, []), MacroDict)}
|
||||
end;
|
||||
|
||||
pre_proc([{'-',_}, {atom,_,include}, {'(',_}, {string,_,Filename}, {')',_}, {dot,_}], _MacroDict) ->
|
||||
{include, Filename};
|
||||
|
||||
pre_proc(Toks,MacroDict) ->
|
||||
{tokens, subst_macros(Toks, MacroDict)}.
|
||||
|
||||
macro_params_body_def([{')',_},{',',_} | Toks], RevParams) ->
|
||||
{reverse(RevParams), macro_body_def(Toks, [])};
|
||||
macro_params_body_def([{var,_,Param} | Toks], RevParams) ->
|
||||
macro_params_body_def(Toks, [Param | RevParams]);
|
||||
macro_params_body_def([{',',_}, {var,_,Param} | Toks], RevParams) ->
|
||||
macro_params_body_def(Toks, [Param | RevParams]).
|
||||
|
||||
macro_body_def([{')',_}, {dot,_}], RevMacroBodyToks) ->
|
||||
reverse(RevMacroBodyToks);
|
||||
macro_body_def([Tok|Toks], RevMacroBodyToks) ->
|
||||
macro_body_def(Toks, [Tok | RevMacroBodyToks]).
|
||||
|
||||
subst_macros(Toks, MacroDict) ->
|
||||
reverse(subst_macros_rev(Toks, MacroDict, [])).
|
||||
|
||||
%% returns a reversed list of tokes
|
||||
subst_macros_rev([{'?',_}, {_,LineNum,'LINE'} | Toks], MacroDict, RevOutToks) ->
|
||||
%% special-case for ?LINE, to avoid creating a new MacroDict for every line in the source file
|
||||
subst_macros_rev(Toks, MacroDict, [{integer,LineNum,LineNum}] ++ RevOutToks);
|
||||
|
||||
subst_macros_rev([{'?',_}, {_,_,Name}, {'(',_} = Paren | Toks], MacroDict, RevOutToks) ->
|
||||
case dict:fetch(Name, MacroDict) of
|
||||
{[], MacroValue} ->
|
||||
%% This macro does not have any vars, so ignore the fact that the invocation is followed by "(...stuff"
|
||||
%% Recursively expand any macro calls inside this macro's value
|
||||
%% TODO: avoid infinite expansion due to circular references (even indirect ones)
|
||||
RevExpandedOtherMacrosToks = subst_macros_rev(MacroValue, MacroDict, []),
|
||||
subst_macros_rev([Paren|Toks], MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks);
|
||||
ParamsAndBody ->
|
||||
%% This macro does have vars.
|
||||
%% Collect all of the passe arguments, in an ordered list
|
||||
{NToks, Arguments} = subst_macros_get_args(Toks, []),
|
||||
%% Expand the varibles
|
||||
ExpandedParamsToks = subst_macros_subst_args_for_vars(ParamsAndBody, Arguments),
|
||||
%% Recursively expand any macro calls inside this macro's value
|
||||
%% TODO: avoid infinite expansion due to circular references (even indirect ones)
|
||||
RevExpandedOtherMacrosToks = subst_macros_rev(ExpandedParamsToks, MacroDict, []),
|
||||
subst_macros_rev(NToks, MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks)
|
||||
end;
|
||||
|
||||
subst_macros_rev([{'?',_}, {_,_,Name} | Toks], MacroDict, RevOutToks) ->
|
||||
%% This macro invocation does not have arguments.
|
||||
%% Therefore the definition should not have parameters
|
||||
{[], MacroValue} = dict:fetch(Name, MacroDict),
|
||||
|
||||
%% Recursively expand any macro calls inside this macro's value
|
||||
%% TODO: avoid infinite expansion due to circular references (even indirect ones)
|
||||
RevExpandedOtherMacrosToks = subst_macros_rev(MacroValue, MacroDict, []),
|
||||
subst_macros_rev(Toks, MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks);
|
||||
|
||||
subst_macros_rev([Tok|Toks], MacroDict, RevOutToks) ->
|
||||
subst_macros_rev(Toks, MacroDict, [Tok|RevOutToks]);
|
||||
subst_macros_rev([], _MacroDict, RevOutToks) -> RevOutToks.
|
||||
|
||||
subst_macros_get_args([{')',_} | Toks], RevArgs) ->
|
||||
{Toks, reverse(RevArgs)};
|
||||
subst_macros_get_args([{',',_}, {var,_,ArgName} | Toks], RevArgs) ->
|
||||
subst_macros_get_args(Toks, [ArgName| RevArgs]);
|
||||
subst_macros_get_args([{var,_,ArgName} | Toks], RevArgs) ->
|
||||
subst_macros_get_args(Toks, [ArgName | RevArgs]).
|
||||
|
||||
subst_macros_subst_args_for_vars({[], BodyToks}, []) ->
|
||||
BodyToks;
|
||||
subst_macros_subst_args_for_vars({[Param | Params], BodyToks}, [Arg|Args]) ->
|
||||
NBodyToks = keyreplace(Param, 3, BodyToks, {var,1,Arg}),
|
||||
subst_macros_subst_args_for_vars({Params, NBodyToks}, Args).
|
||||
|
||||
read_include_file(Filename, IncludeSearchPath) ->
|
||||
case file:path_open(IncludeSearchPath, Filename, [read, raw, binary]) of
|
||||
{ok, IoDevice, FullName} ->
|
||||
{ok, Data} = file:read(IoDevice, filelib:file_size(FullName)),
|
||||
file:close(IoDevice),
|
||||
binary_to_list(Data);
|
||||
{error, Reason} ->
|
||||
throw({failed_to_read_include_file, Reason, Filename, IncludeSearchPath})
|
||||
end.
|
||||
@@ -1,126 +1,51 @@
|
||||
%% $Id$
|
||||
% $Id$
|
||||
|
||||
{application, ejabberd,
|
||||
[{description, "ejabberd"},
|
||||
{vsn, "13.03-beta1"},
|
||||
{vsn, "0.1-alpha"},
|
||||
{modules, [acl,
|
||||
adhoc,
|
||||
configure,
|
||||
cyrsasl_anonymous,
|
||||
cyrsasl,
|
||||
cyrsasl_digest,
|
||||
cyrsasl_plain,
|
||||
cyrsasl_scram,
|
||||
ejabberd_admin,
|
||||
ejabberd_app,
|
||||
ejabberd_auth_anonymous,
|
||||
ejabberd_auth,
|
||||
ejabberd_auth_external,
|
||||
ejabberd_auth_internal,
|
||||
ejabberd_auth_ldap,
|
||||
ejabberd_auth_odbc,
|
||||
ejabberd_auth_pam,
|
||||
ejabberd,
|
||||
ejabberd_app,
|
||||
ejabberd_auth,
|
||||
ejabberd_c2s,
|
||||
ejabberd_c2s_config,
|
||||
ejabberd_config,
|
||||
ejabberd_ctl,
|
||||
ejabberd_frontend_socket,
|
||||
ejabberd_hooks,
|
||||
ejabberd_http,
|
||||
ejabberd_http_bind,
|
||||
ejabberd_http_poll,
|
||||
ejabberd_listener,
|
||||
ejabberd_local,
|
||||
ejabberd_logger_h,
|
||||
ejabberd_loglevel,
|
||||
ejabberd_node_groups,
|
||||
ejabberd_rdbms,
|
||||
ejabberd_receiver,
|
||||
ejabberd_local,
|
||||
ejabberd_router,
|
||||
ejabberd_s2s,
|
||||
ejabberd_s2s_in,
|
||||
ejabberd_s2s_out,
|
||||
ejabberd_service,
|
||||
ejabberd_sm,
|
||||
ejabberd_socket,
|
||||
ejabberd_sup,
|
||||
ejabberd_system_monitor,
|
||||
ejabberd_tmp_sup,
|
||||
ejabberd_update,
|
||||
ejabberd_web_admin,
|
||||
ejabberd_web,
|
||||
ejabberd_zlib,
|
||||
ejd2odbc,
|
||||
eldap,
|
||||
eldap_filter,
|
||||
eldap_pool,
|
||||
eldap_utils,
|
||||
'ELDAPv3',
|
||||
extauth,
|
||||
gen_iq_handler,
|
||||
gen_mod,
|
||||
gen_pubsub_node,
|
||||
gen_pubsub_nodetree,
|
||||
iconv,
|
||||
idna,
|
||||
jd2ejd,
|
||||
jlib,
|
||||
mod_adhoc,
|
||||
mod_announce,
|
||||
mod_caps,
|
||||
mod_configure2,
|
||||
mod_configure,
|
||||
mod_disco,
|
||||
mod_echo,
|
||||
mod_http_bind,
|
||||
mod_http_fileserver,
|
||||
mod_irc,
|
||||
mod_irc_connection,
|
||||
mod_last,
|
||||
mod_muc,
|
||||
mod_muc_log,
|
||||
mod_muc_room,
|
||||
mod_offline,
|
||||
mod_privacy,
|
||||
mod_private,
|
||||
mod_proxy65,
|
||||
mod_proxy65_lib,
|
||||
mod_proxy65_service,
|
||||
mod_proxy65_sm,
|
||||
mod_proxy65_stream,
|
||||
mod_pubsub,
|
||||
mod_register,
|
||||
mod_roster,
|
||||
mod_service_log,
|
||||
mod_shared_roster,
|
||||
mod_stats,
|
||||
mod_time,
|
||||
mod_vcard,
|
||||
mod_vcard_ldap,
|
||||
mod_version,
|
||||
node_buddy,
|
||||
node_club,
|
||||
node_default,
|
||||
node_dispatch,
|
||||
node_pep,
|
||||
node_private,
|
||||
node_public,
|
||||
nodetree_default,
|
||||
nodetree_virtual,
|
||||
p1_fsm,
|
||||
p1_mnesia,
|
||||
p1_prof,
|
||||
randoms,
|
||||
sha,
|
||||
shaper,
|
||||
stringprep,
|
||||
stringprep_sup,
|
||||
tls,
|
||||
translate,
|
||||
xml,
|
||||
xml_stream,
|
||||
'XmppAddr'
|
||||
xml_stream
|
||||
]},
|
||||
{registered, [ejabberd,
|
||||
ejabberd_sup,
|
||||
@@ -148,7 +73,7 @@
|
||||
{mod, {ejabberd_app, []}}]}.
|
||||
|
||||
|
||||
%% Local Variables:
|
||||
%% mode: erlang
|
||||
%% End:
|
||||
%% vim: set filetype=erlang tabstop=8:
|
||||
|
||||
% Local Variables:
|
||||
% mode: erlang
|
||||
% End:
|
||||
|
||||
@@ -1,610 +1,151 @@
|
||||
%%%
|
||||
%%% ejabberd configuration file
|
||||
%%%
|
||||
%%%'
|
||||
% $Id$
|
||||
|
||||
%%% The parameters used in this configuration file are explained in more detail
|
||||
%%% in the ejabberd Installation and Operation Guide.
|
||||
%%% Please consult the Guide in case of doubts, it is included with
|
||||
%%% your copy of ejabberd, and is also available online at
|
||||
%%% http://www.process-one.net/en/ejabberd/docs/
|
||||
|
||||
%%% This configuration file contains Erlang terms.
|
||||
%%% In case you want to understand the syntax, here are the concepts:
|
||||
%%%
|
||||
%%% - The character to comment a line is %
|
||||
%%%
|
||||
%%% - Each term ends in a dot, for example:
|
||||
%%% override_global.
|
||||
%%%
|
||||
%%% - A tuple has a fixed definition, its elements are
|
||||
%%% enclosed in {}, and separated with commas:
|
||||
%%% {loglevel, 4}.
|
||||
%%%
|
||||
%%% - A list can have as many elements as you want,
|
||||
%%% and is enclosed in [], for example:
|
||||
%%% [http_poll, web_admin, tls]
|
||||
%%%
|
||||
%%% - A keyword of ejabberd is a word in lowercase.
|
||||
%%% Strings are enclosed in "" and can contain spaces, dots, ...
|
||||
%%% {language, "en"}.
|
||||
%%% {ldap_rootdn, "dc=example,dc=com"}.
|
||||
%%%
|
||||
%%% - This term includes a tuple, a keyword, a list, and two strings:
|
||||
%%% {hosts, ["jabber.example.net", "im.example.com"]}.
|
||||
%%%
|
||||
%override_acls.
|
||||
|
||||
|
||||
%%%. =======================
|
||||
%%%' OVERRIDE STORED OPTIONS
|
||||
% Users that have admin access. Add line like one of the following after you
|
||||
% will be successfully registered on server to get admin access:
|
||||
%{acl, admin, {user, "aleksey"}}.
|
||||
%{acl, admin, {user, "ermine"}}.
|
||||
|
||||
%%
|
||||
%% Override the old values stored in the database.
|
||||
%%
|
||||
% Blocked users:
|
||||
%{acl, blocked, {user, "test"}}.
|
||||
|
||||
%%
|
||||
%% Override global options (shared by all ejabberd nodes in a cluster).
|
||||
%%
|
||||
%%override_global.
|
||||
|
||||
%%
|
||||
%% Override local options (specific for this particular ejabberd node).
|
||||
%%
|
||||
%%override_local.
|
||||
|
||||
%%
|
||||
%% Remove the Access Control Lists before new ones are added.
|
||||
%%
|
||||
%%override_acls.
|
||||
|
||||
|
||||
%%%. =========
|
||||
%%%' DEBUGGING
|
||||
|
||||
%%
|
||||
%% loglevel: Verbosity of log files generated by ejabberd.
|
||||
%% 0: No ejabberd log at all (not recommended)
|
||||
%% 1: Critical
|
||||
%% 2: Error
|
||||
%% 3: Warning
|
||||
%% 4: Info
|
||||
%% 5: Debug
|
||||
%%
|
||||
{loglevel, 4}.
|
||||
|
||||
%%
|
||||
%% watchdog_admins: Only useful for developers: if an ejabberd process
|
||||
%% consumes a lot of memory, send live notifications to these XMPP
|
||||
%% accounts.
|
||||
%%
|
||||
%%{watchdog_admins, ["bob@example.com"]}.
|
||||
|
||||
|
||||
%%%. ================
|
||||
%%%' SERVED HOSTNAMES
|
||||
|
||||
%%
|
||||
%% hosts: Domains served by ejabberd.
|
||||
%% You can define one or several, for example:
|
||||
%% {hosts, ["example.net", "example.com", "example.org"]}.
|
||||
%%
|
||||
{hosts, ["localhost"]}.
|
||||
|
||||
%%
|
||||
%% route_subdomains: Delegate subdomains to other XMPP servers.
|
||||
%% For example, if this ejabberd serves example.org and you want
|
||||
%% to allow communication with an XMPP server called im.example.org.
|
||||
%%
|
||||
%%{route_subdomains, s2s}.
|
||||
|
||||
|
||||
%%%. ===============
|
||||
%%%' LISTENING PORTS
|
||||
|
||||
%%
|
||||
%% listen: The ports ejabberd will listen on, which service each is handled
|
||||
%% by and what options to start it with.
|
||||
%%
|
||||
{listen,
|
||||
[
|
||||
|
||||
{5222, ejabberd_c2s, [
|
||||
|
||||
%%
|
||||
%% If TLS is compiled in and you installed a SSL
|
||||
%% certificate, specify the full path to the
|
||||
%% file and uncomment this line:
|
||||
%%
|
||||
%%{certfile, "/path/to/ssl.pem"}, starttls,
|
||||
|
||||
{access, c2s},
|
||||
{shaper, c2s_shaper},
|
||||
{max_stanza_size, 65536}
|
||||
]},
|
||||
|
||||
%%
|
||||
%% To enable the old SSL connection method on port 5223:
|
||||
%%
|
||||
%%{5223, ejabberd_c2s, [
|
||||
%% {access, c2s},
|
||||
%% {shaper, c2s_shaper},
|
||||
%% {certfile, "/path/to/ssl.pem"}, tls,
|
||||
%% {max_stanza_size, 65536}
|
||||
%% ]},
|
||||
|
||||
{5269, ejabberd_s2s_in, [
|
||||
{shaper, s2s_shaper},
|
||||
{max_stanza_size, 131072}
|
||||
]},
|
||||
|
||||
%%
|
||||
%% ejabberd_service: Interact with external components (transports, ...)
|
||||
%%
|
||||
%%{8888, ejabberd_service, [
|
||||
%% {access, all},
|
||||
%% {shaper_rule, fast},
|
||||
%% {ip, {127, 0, 0, 1}},
|
||||
%% {hosts, ["icq.example.org", "sms.example.org"],
|
||||
%% [{password, "secret"}]
|
||||
%% }
|
||||
%% ]},
|
||||
|
||||
%%
|
||||
%% ejabberd_stun: Handles STUN Binding requests
|
||||
%%
|
||||
%%{{3478, udp}, ejabberd_stun, []},
|
||||
|
||||
{5280, ejabberd_http, [
|
||||
%%{request_handlers,
|
||||
%% [
|
||||
%% {["pub", "archive"], mod_http_fileserver}
|
||||
%% ]},
|
||||
captcha,
|
||||
http_bind,
|
||||
http_poll,
|
||||
%%register,
|
||||
web_admin
|
||||
]}
|
||||
|
||||
]}.
|
||||
|
||||
%%
|
||||
%% s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections.
|
||||
%% Allowed values are: false optional required required_trusted
|
||||
%% You must specify a certificate file.
|
||||
%%
|
||||
%%{s2s_use_starttls, optional}.
|
||||
|
||||
%%
|
||||
%% s2s_certfile: Specify a certificate file.
|
||||
%%
|
||||
%%{s2s_certfile, "/path/to/ssl.pem"}.
|
||||
|
||||
%%
|
||||
%% domain_certfile: Specify a different certificate for each served hostname.
|
||||
%%
|
||||
%%{domain_certfile, "example.org", "/path/to/example_org.pem"}.
|
||||
%%{domain_certfile, "example.com", "/path/to/example_com.pem"}.
|
||||
|
||||
%%
|
||||
%% S2S whitelist or blacklist
|
||||
%%
|
||||
%% Default s2s policy for undefined hosts.
|
||||
%%
|
||||
%%{s2s_default_policy, allow}.
|
||||
|
||||
%%
|
||||
%% Allow or deny communication with specific servers.
|
||||
%%
|
||||
%%{{s2s_host, "goodhost.org"}, allow}.
|
||||
%%{{s2s_host, "badhost.org"}, deny}.
|
||||
|
||||
%%
|
||||
%% Outgoing S2S options
|
||||
%%
|
||||
%% Preferred address families (which to try first) and connect timeout
|
||||
%% in milliseconds.
|
||||
%%
|
||||
%%{outgoing_s2s_options, [ipv4, ipv6], 10000}.
|
||||
|
||||
|
||||
%%%. ==============
|
||||
%%%' AUTHENTICATION
|
||||
|
||||
%%
|
||||
%% auth_method: Method used to authenticate the users.
|
||||
%% The default method is the internal.
|
||||
%% If you want to use a different method,
|
||||
%% comment this line and enable the correct ones.
|
||||
%%
|
||||
{auth_method, internal}.
|
||||
%%
|
||||
%% Store the plain passwords or hashed for SCRAM:
|
||||
%%{auth_password_format, plain}.
|
||||
%%{auth_password_format, scram}.
|
||||
%%
|
||||
%% Define the FQDN if ejabberd doesn't detect it:
|
||||
%%{fqdn, "server3.example.com"}.
|
||||
|
||||
%%
|
||||
%% Authentication using external script
|
||||
%% Make sure the script is executable by ejabberd.
|
||||
%%
|
||||
%%{auth_method, external}.
|
||||
%%{extauth_program, "/path/to/authentication/script"}.
|
||||
|
||||
%%
|
||||
%% Authentication using ODBC
|
||||
%% Remember to setup a database in the next section.
|
||||
%%
|
||||
%%{auth_method, odbc}.
|
||||
|
||||
%%
|
||||
%% Authentication using PAM
|
||||
%%
|
||||
%%{auth_method, pam}.
|
||||
%%{pam_service, "pamservicename"}.
|
||||
|
||||
%%
|
||||
%% Authentication using LDAP
|
||||
%%
|
||||
%%{auth_method, ldap}.
|
||||
%%
|
||||
%% List of LDAP servers:
|
||||
%%{ldap_servers, ["localhost"]}.
|
||||
%%
|
||||
%% Encryption of connection to LDAP servers:
|
||||
%%{ldap_encrypt, none}.
|
||||
%%{ldap_encrypt, tls}.
|
||||
%%
|
||||
%% Port to connect to on LDAP servers:
|
||||
%%{ldap_port, 389}.
|
||||
%%{ldap_port, 636}.
|
||||
%%
|
||||
%% LDAP manager:
|
||||
%%{ldap_rootdn, "dc=example,dc=com"}.
|
||||
%%
|
||||
%% Password of LDAP manager:
|
||||
%%{ldap_password, "******"}.
|
||||
%%
|
||||
%% Search base of LDAP directory:
|
||||
%%{ldap_base, "dc=example,dc=com"}.
|
||||
%%
|
||||
%% LDAP attribute that holds user ID:
|
||||
%%{ldap_uids, [{"mail", "%u@mail.example.org"}]}.
|
||||
%%
|
||||
%% LDAP filter:
|
||||
%%{ldap_filter, "(objectClass=shadowAccount)"}.
|
||||
|
||||
%%
|
||||
%% Anonymous login support:
|
||||
%% auth_method: anonymous
|
||||
%% anonymous_protocol: sasl_anon | login_anon | both
|
||||
%% allow_multiple_connections: true | false
|
||||
%%
|
||||
%%{host_config, "public.example.org", [{auth_method, anonymous},
|
||||
%% {allow_multiple_connections, false},
|
||||
%% {anonymous_protocol, sasl_anon}]}.
|
||||
%%
|
||||
%% To use both anonymous and internal authentication:
|
||||
%%
|
||||
%%{host_config, "public.example.org", [{auth_method, [internal, anonymous]}]}.
|
||||
|
||||
|
||||
%%%. ==============
|
||||
%%%' DATABASE SETUP
|
||||
|
||||
%% ejabberd by default uses the internal Mnesia database,
|
||||
%% so you do not necessarily need this section.
|
||||
%% This section provides configuration examples in case
|
||||
%% you want to use other database backends.
|
||||
%% Please consult the ejabberd Guide for details on database creation.
|
||||
|
||||
%%
|
||||
%% MySQL server:
|
||||
%%
|
||||
%%{odbc_server, {mysql, "server", "database", "username", "password"}}.
|
||||
%%
|
||||
%% If you want to specify the port:
|
||||
%%{odbc_server, {mysql, "server", 1234, "database", "username", "password"}}.
|
||||
|
||||
%%
|
||||
%% PostgreSQL server:
|
||||
%%
|
||||
%%{odbc_server, {pgsql, "server", "database", "username", "password"}}.
|
||||
%%
|
||||
%% If you want to specify the port:
|
||||
%%{odbc_server, {pgsql, "server", 1234, "database", "username", "password"}}.
|
||||
%%
|
||||
%% If you use PostgreSQL, have a large database, and need a
|
||||
%% faster but inexact replacement for "select count(*) from users"
|
||||
%%
|
||||
%%{pgsql_users_number_estimate, true}.
|
||||
|
||||
%%
|
||||
%% ODBC compatible or MSSQL server:
|
||||
%%
|
||||
%%{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}.
|
||||
|
||||
%%
|
||||
%% Number of connections to open to the database for each virtual host
|
||||
%%
|
||||
%%{odbc_pool_size, 10}.
|
||||
|
||||
%%
|
||||
%% Interval to make a dummy SQL request to keep the connections to the
|
||||
%% database alive. Specify in seconds: for example 28800 means 8 hours
|
||||
%%
|
||||
%%{odbc_keepalive_interval, undefined}.
|
||||
|
||||
|
||||
%%%. ===============
|
||||
%%%' TRAFFIC SHAPERS
|
||||
|
||||
%%
|
||||
%% The "normal" shaper limits traffic speed to 1000 B/s
|
||||
%%
|
||||
{shaper, normal, {maxrate, 1000}}.
|
||||
|
||||
%%
|
||||
%% The "fast" shaper limits traffic speed to 50000 B/s
|
||||
%%
|
||||
{shaper, fast, {maxrate, 50000}}.
|
||||
|
||||
%%
|
||||
%% This option specifies the maximum number of elements in the queue
|
||||
%% of the FSM. Refer to the documentation for details.
|
||||
%%
|
||||
{max_fsm_queue, 1000}.
|
||||
|
||||
|
||||
%%%. ====================
|
||||
%%%' ACCESS CONTROL LISTS
|
||||
|
||||
%%
|
||||
%% The 'admin' ACL grants administrative privileges to XMPP accounts.
|
||||
%% You can put here as many accounts as you want.
|
||||
%%
|
||||
%%{acl, admin, {user, "aleksey", "localhost"}}.
|
||||
%%{acl, admin, {user, "ermine", "example.org"}}.
|
||||
|
||||
%%
|
||||
%% Blocked users
|
||||
%%
|
||||
%%{acl, blocked, {user, "baduser", "example.org"}}.
|
||||
%%{acl, blocked, {user, "test"}}.
|
||||
|
||||
%%
|
||||
%% Local users: don't modify this line.
|
||||
%%
|
||||
% Local users:
|
||||
{acl, local, {user_regexp, ""}}.
|
||||
|
||||
%%
|
||||
%% More examples of ACLs
|
||||
%%
|
||||
%%{acl, jabberorg, {server, "jabber.org"}}.
|
||||
%%{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
|
||||
%%{acl, test, {user_regexp, "^test"}}.
|
||||
%%{acl, test, {user_glob, "test*"}}.
|
||||
|
||||
%%
|
||||
%% Define specific ACLs in a virtual host.
|
||||
%%
|
||||
%%{host_config, "localhost",
|
||||
%% [
|
||||
%% {acl, admin, {user, "bob-local", "localhost"}}
|
||||
%% ]
|
||||
%%}.
|
||||
% Another examples of ACLs:
|
||||
%{acl, jabberorg, {server, "jabber.org"}}.
|
||||
%{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
|
||||
%{acl, test, {user_regexp, "^test"}}.
|
||||
%{acl, test, {user_glob, "test*"}}.
|
||||
|
||||
|
||||
%%%. ============
|
||||
%%%' ACCESS RULES
|
||||
% Only admins can use configuration interface:
|
||||
{access, configure, [{allow, admin}]}.
|
||||
|
||||
%% Maximum number of simultaneous sessions allowed for a single user:
|
||||
{access, max_user_sessions, [{10, all}]}.
|
||||
% Every username can be registered via in-band registration:
|
||||
{access, register, [{allow, all}]}.
|
||||
|
||||
%% Maximum number of offline messages that users can have:
|
||||
{access, max_user_offline_messages, [{5000, admin}, {100, all}]}.
|
||||
% After successful registration user will get message with following subject
|
||||
% and body:
|
||||
{welcome_message,
|
||||
{"Welcome!",
|
||||
"Welcome to Jabber Service. "
|
||||
"For information about Jabber visit http://jabber.org"}}.
|
||||
% Replace them with 'none' if you don't want to send such message:
|
||||
%{welcome_message, none}.
|
||||
|
||||
%% This rule allows access only for local users:
|
||||
{access, local, [{allow, local}]}.
|
||||
% List of people who will get notifications about registered users
|
||||
%{registration_watchers, ["admin1@localhost",
|
||||
% "admin2@localhost"]}.
|
||||
|
||||
%% Only non-blocked users can use c2s connections:
|
||||
% Only admins can send announcement messages:
|
||||
{access, announce, [{allow, admin}]}.
|
||||
|
||||
|
||||
% Only non-blocked users can use c2s connections:
|
||||
{access, c2s, [{deny, blocked},
|
||||
{allow, all}]}.
|
||||
|
||||
%% For C2S connections, all users except admins use the "normal" shaper
|
||||
% Set shaper with name "normal" to limit traffic speed to 1000B/s
|
||||
{shaper, normal, {maxrate, 1000}}.
|
||||
|
||||
% Set shaper with name "fast" to limit traffic speed to 50000B/s
|
||||
{shaper, fast, {maxrate, 50000}}.
|
||||
|
||||
% For all users except admins used "normal" shaper
|
||||
{access, c2s_shaper, [{none, admin},
|
||||
{normal, all}]}.
|
||||
|
||||
%% All S2S connections use the "fast" shaper
|
||||
% For all S2S connections used "fast" shaper
|
||||
{access, s2s_shaper, [{fast, all}]}.
|
||||
|
||||
%% Only admins can send announcement messages:
|
||||
{access, announce, [{allow, admin}]}.
|
||||
|
||||
%% Only admins can use the configuration interface:
|
||||
{access, configure, [{allow, admin}]}.
|
||||
|
||||
%% Admins of this server are also admins of the MUC service:
|
||||
% Admins of this server are also admins of MUC service:
|
||||
{access, muc_admin, [{allow, admin}]}.
|
||||
|
||||
%% Only accounts of the local ejabberd server can create rooms:
|
||||
{access, muc_create, [{allow, local}]}.
|
||||
|
||||
%% All users are allowed to use the MUC service:
|
||||
% All users are allowed to use MUC service:
|
||||
{access, muc, [{allow, all}]}.
|
||||
|
||||
%% Only accounts on the local ejabberd server can create Pubsub nodes:
|
||||
{access, pubsub_createnode, [{allow, local}]}.
|
||||
|
||||
%% In-band registration allows registration of any possible username.
|
||||
%% To disable in-band registration, replace 'allow' with 'deny'.
|
||||
{access, register, [{allow, all}]}.
|
||||
|
||||
%% By default the frequency of account registrations from the same IP
|
||||
%% is limited to 1 account every 10 minutes. To disable, specify: infinity
|
||||
%%{registration_timeout, 600}.
|
||||
|
||||
%%
|
||||
%% Define specific Access Rules in a virtual host.
|
||||
%%
|
||||
%%{host_config, "localhost",
|
||||
%% [
|
||||
%% {access, c2s, [{allow, admin}, {deny, all}]},
|
||||
%% {access, register, [{deny, all}]}
|
||||
%% ]
|
||||
%%}.
|
||||
% This rule allows access only for local users:
|
||||
{access, local, [{allow, local}]}.
|
||||
|
||||
|
||||
%%%. ================
|
||||
%%%' DEFAULT LANGUAGE
|
||||
% Authentification method. If you want to use internal user base, then use
|
||||
% this line:
|
||||
{auth_method, internal}.
|
||||
|
||||
%%
|
||||
%% language: Default language used for server messages.
|
||||
%%
|
||||
% For LDAP authentification use these lines instead of above one:
|
||||
%{auth_method, ldap}.
|
||||
%{ldap_servers, ["localhost"]}. % List of LDAP servers
|
||||
%{ldap_uidattr, "uid"}. % LDAP attribute that holds user ID
|
||||
%{ldap_base, "dc=example,dc=com"}. % Base of LDAP directory
|
||||
|
||||
% For authentification via external script use the following:
|
||||
%{auth_method, external}.
|
||||
%{extauth_program, "/path/to/authentification/script"}.
|
||||
|
||||
|
||||
% Host name:
|
||||
{host, "localhost"}.
|
||||
|
||||
|
||||
% Default language for server messages
|
||||
{language, "en"}.
|
||||
|
||||
%%
|
||||
%% Set a different default language in a virtual host.
|
||||
%%
|
||||
%%{host_config, "localhost",
|
||||
%% [{language, "ru"}]
|
||||
%%}.
|
||||
|
||||
|
||||
%%%. =======
|
||||
%%%' CAPTCHA
|
||||
|
||||
%%
|
||||
%% Full path to a script that generates the image.
|
||||
%%
|
||||
%%{captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}.
|
||||
|
||||
%%
|
||||
%% Host for the URL and port where ejabberd listens for CAPTCHA requests.
|
||||
%%
|
||||
%%{captcha_host, "example.org:5280"}.
|
||||
|
||||
%%
|
||||
%% Limit CAPTCHA calls per minute for JID/IP to avoid DoS.
|
||||
%%
|
||||
%%{captcha_limit, 5}.
|
||||
|
||||
%%%. =======
|
||||
%%%' MODULES
|
||||
|
||||
%%
|
||||
%% Modules enabled in all ejabberd virtual hosts.
|
||||
%%
|
||||
{modules,
|
||||
[
|
||||
{mod_adhoc, []},
|
||||
{mod_announce, [{access, announce}]}, % recommends mod_adhoc
|
||||
{mod_blocking,[]}, % requires mod_privacy
|
||||
{mod_caps, []},
|
||||
{mod_configure,[]}, % requires mod_adhoc
|
||||
{mod_disco, []},
|
||||
%%{mod_echo, [{host, "echo.localhost"}]},
|
||||
{mod_irc, []},
|
||||
{mod_http_bind, []},
|
||||
%%{mod_http_fileserver, [
|
||||
%% {docroot, "/var/www"},
|
||||
%% {accesslog, "/var/log/ejabberd/access.log"}
|
||||
%% ]},
|
||||
{mod_last, []},
|
||||
{mod_muc, [
|
||||
%%{host, "conference.@HOST@"},
|
||||
{access, muc},
|
||||
{access_create, muc_create},
|
||||
{access_persistent, muc_create},
|
||||
{access_admin, muc_admin}
|
||||
]},
|
||||
%%{mod_muc_log,[]},
|
||||
{mod_offline, [{access_max_user_messages, max_user_offline_messages}]},
|
||||
{mod_ping, []},
|
||||
%%{mod_pres_counter,[{count, 5}, {interval, 60}]},
|
||||
{mod_privacy, []},
|
||||
{mod_private, []},
|
||||
%%{mod_proxy65,[]},
|
||||
{mod_pubsub, [
|
||||
{access_createnode, pubsub_createnode},
|
||||
{ignore_pep_from_offline, true}, % reduces resource comsumption, but XEP incompliant
|
||||
%%{ignore_pep_from_offline, false}, % XEP compliant, but increases resource comsumption
|
||||
{last_item_cache, false},
|
||||
{plugins, ["flat", "hometree", "pep"]} % pep requires mod_caps
|
||||
]},
|
||||
{mod_register, [
|
||||
%%
|
||||
%% Protect In-Band account registrations with CAPTCHA.
|
||||
%%
|
||||
%%{captcha_protected, true},
|
||||
|
||||
%%
|
||||
%% Set the minimum informational entropy for passwords.
|
||||
%%
|
||||
%%{password_strength, 32},
|
||||
|
||||
%%
|
||||
%% After successful registration, the user receives
|
||||
%% a message with this subject and body.
|
||||
%%
|
||||
{welcome_message, {"Welcome!",
|
||||
"Hi.\nWelcome to this XMPP server."}},
|
||||
|
||||
%%
|
||||
%% When a user registers, send a notification to
|
||||
%% these XMPP accounts.
|
||||
%%
|
||||
%%{registration_watchers, ["admin1@example.org"]},
|
||||
|
||||
%%
|
||||
%% Only clients in the server machine can register accounts
|
||||
%%
|
||||
{ip_access, [{allow, "127.0.0.0/8"},
|
||||
{deny, "0.0.0.0/0"}]},
|
||||
|
||||
%%
|
||||
%% Local c2s or remote s2s users cannot register accounts
|
||||
%%
|
||||
%%{access_from, deny},
|
||||
|
||||
{access, register}
|
||||
]},
|
||||
%%{mod_register_web, [
|
||||
%%
|
||||
%% When a user registers, send a notification to
|
||||
%% these XMPP accounts.
|
||||
%%
|
||||
%%{registration_watchers, ["admin1@example.org"]}
|
||||
%% ]},
|
||||
{mod_roster, []},
|
||||
%%{mod_service_log,[]},
|
||||
{mod_shared_roster,[]},
|
||||
{mod_stats, []},
|
||||
{mod_time, []},
|
||||
{mod_vcard, []},
|
||||
{mod_version, []}
|
||||
% Listened ports:
|
||||
{listen,
|
||||
[{5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper},
|
||||
starttls, {certfile, "./ssl.pem"}]},
|
||||
{5223, ejabberd_c2s, [{access, c2s},
|
||||
tls, {certfile, "./ssl.pem"}]},
|
||||
% Use these two lines instead if TLS support is not compiled
|
||||
%{5222, ejabberd_c2s, [{access, c2s}, {shaper, c2s_shaper}]},
|
||||
%{5223, ejabberd_c2s, [{access, c2s}, ssl, {certfile, "./ssl.pem"}]},
|
||||
{5269, ejabberd_s2s_in, [{shaper, s2s_shaper}]},
|
||||
{5280, ejabberd_http, [http_poll, web_admin]},
|
||||
{8888, ejabberd_service, [{access, all},
|
||||
{hosts, ["icq.localhost", "sms.localhost"],
|
||||
[{password, "secret"}]}]}
|
||||
]}.
|
||||
|
||||
%%
|
||||
%% Enable modules with custom options in a specific virtual host
|
||||
%%
|
||||
%%{host_config, "localhost",
|
||||
%% [{{add, modules},
|
||||
%% [
|
||||
%% {mod_echo, [{host, "mirror.localhost"}]}
|
||||
%% ]
|
||||
%% }
|
||||
%% ]}.
|
||||
% If SRV lookup fails, then port 5269 is used to communicate with remote server
|
||||
{outgoing_s2s_port, 5269}.
|
||||
|
||||
|
||||
%%%.
|
||||
%%%'
|
||||
% Used modules:
|
||||
{modules,
|
||||
[
|
||||
{mod_register, [{access, register}]},
|
||||
{mod_roster, []},
|
||||
{mod_privacy, []},
|
||||
{mod_configure, []},
|
||||
{mod_configure2, []},
|
||||
{mod_disco, []},
|
||||
{mod_stats, []},
|
||||
{mod_vcard, []},
|
||||
{mod_offline, []},
|
||||
{mod_announce, [{access, announce}]},
|
||||
{mod_echo, [{host, "echo.localhost"}]},
|
||||
{mod_private, []},
|
||||
{mod_irc, []},
|
||||
% Default options for mod_muc:
|
||||
% host: "conference." ++ ?MYNAME
|
||||
% access: all
|
||||
% access_create: all
|
||||
% access_admin: none (only room creator has owner privileges)
|
||||
{mod_muc, [{access, muc},
|
||||
{access_create, muc},
|
||||
{access_admin, muc_admin}]},
|
||||
{mod_pubsub, []},
|
||||
{mod_time, []},
|
||||
{mod_last, []},
|
||||
{mod_version, []}
|
||||
]}.
|
||||
|
||||
%%% $Id$
|
||||
|
||||
%%% Local Variables:
|
||||
%%% mode: erlang
|
||||
%%% End:
|
||||
%%% vim: set filetype=erlang tabstop=8 foldmarker=%%%',%%%. foldmethod=marker:
|
||||
|
||||
|
||||
% Local Variables:
|
||||
% mode: erlang
|
||||
% End:
|
||||
|
||||
@@ -1,43 +1,24 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%% File : ejabberd.erl
|
||||
%%% Author : Alexey Shchepin <alexey@process-one.net>
|
||||
%%% Purpose : ejabberd wrapper: start / stop
|
||||
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
|
||||
%%%
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose :
|
||||
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
-module(ejabberd).
|
||||
-author('alexey@process-one.net').
|
||||
-author('alexey@sevcom.net').
|
||||
-vsn('$Revision$ ').
|
||||
|
||||
-export([start/0, stop/0,
|
||||
get_pid_file/0,
|
||||
get_so_path/0, get_bin_path/0]).
|
||||
get_so_path/0]).
|
||||
|
||||
start() ->
|
||||
%%ejabberd_cover:start(),
|
||||
application:start(ejabberd).
|
||||
|
||||
stop() ->
|
||||
application:stop(ejabberd).
|
||||
%%ejabberd_cover:stop().
|
||||
|
||||
|
||||
get_so_path() ->
|
||||
case os:getenv("EJABBERD_SO_PATH") of
|
||||
@@ -51,27 +32,3 @@ get_so_path() ->
|
||||
Path ->
|
||||
Path
|
||||
end.
|
||||
|
||||
get_bin_path() ->
|
||||
case os:getenv("EJABBERD_BIN_PATH") of
|
||||
false ->
|
||||
case code:priv_dir(ejabberd) of
|
||||
{error, _} ->
|
||||
".";
|
||||
Path ->
|
||||
filename:join([Path, "bin"])
|
||||
end;
|
||||
Path ->
|
||||
Path
|
||||
end.
|
||||
|
||||
%% @spec () -> false | string()
|
||||
get_pid_file() ->
|
||||
case os:getenv("EJABBERD_PID_PATH") of
|
||||
false ->
|
||||
false;
|
||||
"" ->
|
||||
false;
|
||||
Path ->
|
||||
Path
|
||||
end.
|
||||
|
||||
@@ -1,77 +1,42 @@
|
||||
%%%----------------------------------------------------------------------
|
||||
%%%
|
||||
%%% ejabberd, Copyright (C) 2002-2013 ProcessOne
|
||||
%%%
|
||||
%%% This program is free software; you can redistribute it and/or
|
||||
%%% modify it under the terms of the GNU General Public License as
|
||||
%%% published by the Free Software Foundation; either version 2 of the
|
||||
%%% License, or (at your option) any later version.
|
||||
%%%
|
||||
%%% This program is distributed in the hope that it will be useful,
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
%%% 02111-1307 USA
|
||||
%%%
|
||||
%%% File : ejabberd.hrl
|
||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Purpose :
|
||||
%%% Created : 17 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
|
||||
%%% Id : $Id$
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
%% This macro returns a string of the ejabberd version running, e.g. "2.3.4"
|
||||
%% If the ejabberd application description isn't loaded, returns atom: undefined
|
||||
-define(VERSION, ejabberd_config:get_version()).
|
||||
-define(VERSION, "0.8-alpha").
|
||||
|
||||
-define(MYHOSTS, ejabberd_config:get_myhosts()).
|
||||
%-define(ejabberd_debug, true).
|
||||
%-define(DBGFSM, true).
|
||||
|
||||
-define(MYNAME, hd(ejabberd_config:get_myhosts())).
|
||||
|
||||
-define(MYLANG, ejabberd_config:get_mylang()).
|
||||
|
||||
-define(MSGS_DIR, <<"msgs">>).
|
||||
|
||||
-define(CONFIG_PATH, <<"ejabberd.cfg">>).
|
||||
|
||||
-define(LOG_PATH, <<"ejabberd.log">>).
|
||||
|
||||
-define(EJABBERD_URI, <<"http://www.process-one.net/en/ejabberd/">>).
|
||||
|
||||
-define(S2STIMEOUT, 600000).
|
||||
|
||||
%%-define(DBGFSM, true).
|
||||
|
||||
-record(scram,
|
||||
{storedkey = <<"">>,
|
||||
serverkey = <<"">>,
|
||||
salt = <<"">>,
|
||||
iterationcount = 0 :: integer()}).
|
||||
|
||||
-type scram() :: #scram{}.
|
||||
|
||||
-define(SCRAM_DEFAULT_ITERATION_COUNT, 4096).
|
||||
|
||||
%% ---------------------------------
|
||||
%% Logging mechanism
|
||||
|
||||
%% Print in standard output
|
||||
-define(PRINT(Format, Args), io:format(Format, Args)).
|
||||
|
||||
-define(DEBUG(Format, Args),
|
||||
ejabberd_logger:debug_msg(?MODULE, ?LINE, Format,
|
||||
Args)).
|
||||
|
||||
-define(INFO_MSG(Format, Args),
|
||||
ejabberd_logger:info_msg(?MODULE, ?LINE, Format, Args)).
|
||||
|
||||
-define(WARNING_MSG(Format, Args),
|
||||
ejabberd_logger:warning_msg(?MODULE, ?LINE, Format,
|
||||
Args)).
|
||||
-ifdef(ejabberd_debug).
|
||||
-define(DEBUG(Format, Args), io:format("D(~p:~p:~p) : "++Format++"~n",
|
||||
[self(),?MODULE,?LINE]++Args)).
|
||||
-else.
|
||||
-define(DEBUG(F,A),[]).
|
||||
-endif.
|
||||
|
||||
-define(ERROR_MSG(Format, Args),
|
||||
ejabberd_logger:error_msg(?MODULE, ?LINE, Format,
|
||||
Args)).
|
||||
error_logger:error_msg("E(~p:~p:~p): "++Format++"~n",
|
||||
[self(),?MODULE,?LINE]++Args)).
|
||||
|
||||
-define(INFO_MSG(Format, Args),
|
||||
error_logger:info_msg("I(~p:~p:~p): "++Format++"~n",
|
||||
[self(),?MODULE,?LINE]++Args)).
|
||||
|
||||
|
||||
%-define(MYNAME,"e.localhost").
|
||||
-define(MYNAME, ejabberd_config:get_global_option(host)).
|
||||
-define(S2STIMEOUT, 600000).
|
||||
%-define(S2STIMEOUT, 6000).
|
||||
-define(MYLANG, ejabberd_config:get_global_option(language)).
|
||||
|
||||
-define(MSGS_DIR, "msgs").
|
||||
-define(CONFIG_PATH, "ejabberd.cfg").
|
||||
-define(LOG_PATH, "ejabberd.log").
|
||||
|
||||
|
||||
-define(PRIVACY_SUPPORT, true).
|
||||
|
||||
-define(CRITICAL_MSG(Format, Args),
|
||||
ejabberd_logger:critical_msg(?MODULE, ?LINE, Format,
|
||||
Args)).
|
||||
|
||||