25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-24 17:29:28 +01:00

Merge branch '2.2.x' of gitorious.process-one.net:+ejabberd-developers/ejabberd/maincustomers into 2.2.x

This commit is contained in:
Eric Cestari 2011-05-09 10:51:43 +02:00
commit 9aabd59a1f
84 changed files with 3561 additions and 636 deletions

View File

@ -1031,7 +1031,7 @@ However, the c2s and s2s connections to the domain \term{example.com} use the fi
\item Port 5269 listens for s2s connections with STARTTLS. The socket is set for IPv6 instead of IPv4.
\item Port 3478 listens for STUN requests over UDP.
\item Port 5280 listens for HTTP requests, and serves the HTTP Poll service.
\item Port 5281 listens for HTTP requests, and serves the Web Admin using HTTPS as explained in
\item Port 5281 listens for HTTP requests, using HTTPS to serve HTTP-Bind (BOSH) and the Web Admin as explained in
section~\ref{webadmin}. The socket only listens connections to the IP address 127.0.0.1.
\end{itemize}
\begin{verbatim}
@ -1060,6 +1060,7 @@ However, the c2s and s2s connections to the domain \term{example.com} use the fi
]},
{{5281, "127.0.0.1"}, ejabberd_http, [
web_admin,
http_bind,
tls, {certfile, "/etc/ejabberd/server.pem"},
]}
]
@ -1636,11 +1637,14 @@ The configurable options are:
\titem{\{captcha\_cmd, Path\}}
Full path to a script that generates the image.
The default value is an empty string: \term{""}
\titem{\{captcha\_host, Host\}}
Host part of the URL sent to the user.
You can include the port number.
The URL sent to the user is formed by: \term{http://Host/captcha/}
The default value is the first hostname configured.
\titem{\{captcha\_host, ProtocolHostPort\}}
ProtocolHostPort is a string with the host, and optionally the Protocol and Port number.
It must identify where ejabberd listens for CAPTCHA requests.
The URL sent to the user is formed by: \term{Protocol://Host:Port/captcha/}
The default value is: protocol \term{http}, the first hostname configured, and port \term{80}.
If you specify a port number that does not match exactly an ejabberd listener
(because you are using a reverse proxy or other port-forwarding tool),
then you must specify the transfer protocol, as seen in the example below.
\end{description}
Additionally, an \term{ejabberd\_http} listener must be enabled with the \term{captcha} option.
@ -1652,6 +1656,8 @@ Example configuration:
{captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}.
{captcha_host, "example.org:5280"}.
%% {captcha_host, "https://example.org:443"}.
%% {captcha_host, "http://example.com"}.
{listen,
[
@ -2627,7 +2633,8 @@ The syntax is:
Possible \term{Value} are:
\begin{description}
\titem{no\_queue} All queries of a namespace with this processing discipline are
processed immediately. This also means that no other packets can be processed
processed directly. This means that the XMPP connection that sends this IQ query gets blocked:
no other packets can be processed
until this one has been completely processed. Hence this discipline is not
recommended if the processing of a query can take a relatively long time.
\titem{one\_queue} In this case a separate queue is created for the processing
@ -2635,7 +2642,7 @@ Possible \term{Value} are:
of this queue is done in parallel with that of other packets. This discipline
is most recommended.
\titem{\{queues, N\}} N separate queues are created to process the
queries. The queries are thus process in parallel, but in a
queries. The queries are thus processed in parallel, but in a
controlled way.
\titem{parallel} For every packet with this discipline a separate Erlang process
is spawned. Consequently, all these packets are processed in parallel.
@ -3823,10 +3830,11 @@ enables end users to use a \XMPP{} client to:
Options:
\begin{description}
\titem{\{access, AccessName\}} \ind{options!access}This option can be configured to specify
rules to restrict registration. If a rule returns `deny' on the requested
user name, registration for that user name is denied. (there are no
restrictions by default).
\titem{\{access, AccessName\}} \ind{options!access}
Specify rules to restrict what usernames can be registered and unregistered.
If a rule returns `deny' on the requested username,
registration and unregistration of that user name is denied.
There are no restrictions by default.
\titem{\{access\_from, AccessName\}} \ind{options!access\_from}By default, \ejabberd{}
doesn't allow to register new accounts from s2s or existing c2s sessions. You can
change it by defining access rule in this option. Use with care: allowing registration
@ -4064,11 +4072,13 @@ has a unique identification and the following parameters:
\item[Name] The name of the group, which will be displayed in the roster.
\item[Description] The description of the group. This parameter does not affect
anything.
\item[Members] A list of full JIDs of group members, entered one per line in
\item[Members] A list of JIDs of group members, entered one per line in
the Web Admin.
To put as members all the registered users in the virtual hosts,
you can use the special directive: @all@.
Note that this directive is designed for a small server with just a few hundred users.
The special member directive \term{@all@}
represents all the registered users in the virtual host;
which is only recommended for a small server with just a few hundred users.
The special member directive \term{@online@}
represents the online users in the virtual host.
\item[Displayed groups] A list of groups that will be in the rosters of this
group's members.
\end{description}
@ -4999,6 +5009,9 @@ The command line parameters:
If using \term{-sname}, specify either this option or \term{ERL\_INETRC}.
\titem{-kernel inet\_dist\_listen\_min 4200 inet\_dist\_listen\_min 4210}
Define the first and last ports that \term{epmd} (section \ref{epmd}) can listen to.
\titem{-kernel inet\_dist\_use\_interface "\{ 127,0,0,1 \}"}
Define the IP address where this Erlang node listens for other nodes
connections (see section \ref{epmd}).
\titem{-detached}
Starts the Erlang system detached from the system console.
Useful for running daemons and backgrounds processes.
@ -5411,6 +5424,12 @@ The Erlang command-line parameter used internally is, for example:
\begin{verbatim}
erl ... -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375
\end{verbatim}
It is also possible to configure in \term{ejabberdctl.cfg}
the network interface where the Erlang node will listen and accept connections.
The Erlang command-line parameter used internally is, for example:
\begin{verbatim}
erl ... -kernel inet_dist_use_interface "{127,0,0,1}"
\end{verbatim}
\makesection{cookie}{Erlang Cookie}

View File

@ -475,10 +475,14 @@
%%{captcha_cmd, "/lib/ejabberd/priv/bin/captcha.sh"}.
%%
%% Host part of the URL sent to the user.
%% 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

View File

@ -67,8 +67,9 @@ start(normal, _Args) ->
%ejabberd_debug:eprof_start(),
%ejabberd_debug:fprof_start(),
maybe_add_nameservers(),
{ok, Pid} = ejabberd_cluster:start(),
start_modules(),
ejabberd_cluster:announce(),
ejabberd_cluster:announce(Pid),
ejabberd_node_groups:start(),
ejabberd_listener:start_listeners(),
?INFO_MSG("ejabberd ~s is started in the node ~p", [?VERSION, node()]),

View File

@ -194,7 +194,7 @@ stop(FsmRef) ->
?GEN_FSM:send_event(FsmRef, closed).
migrate(FsmRef, Node, After) ->
?GEN_FSM:send_all_state_event(FsmRef, {migrate, Node, After}).
erlang:send_after(After, FsmRef, {migrate, Node}).
%%%----------------------------------------------------------------------
%%% Callback functions from gen_fsm
@ -231,6 +231,12 @@ init([{SockMod, Socket}, Opts, FSMLimitOpts]) ->
(_) -> false
end, Opts),
TLSOpts = [verify_none | TLSOpts1],
Redirect = case lists:keysearch(redirect, 1, Opts) of
{value, {_, true}} ->
true;
_ ->
false
end,
IP = case lists:keysearch(frontend_ip, 1, Opts) of
{value, {_, IP1}} ->
IP1;
@ -246,7 +252,7 @@ init([{SockMod, Socket}, Opts, FSMLimitOpts]) ->
false ->
Socket1 =
if
TLSEnabled ->
TLSEnabled andalso SockMod /= ejabberd_frontend_socket ->
SockMod:starttls(Socket, TLSOpts);
true ->
Socket
@ -265,6 +271,7 @@ init([{SockMod, Socket}, Opts, FSMLimitOpts]) ->
access = Access,
shaper = Shaper,
ip = IP,
redirect = Redirect,
fsm_limit_opts = FSMLimitOpts},
{ok, wait_for_stream, StateData, ?C2S_OPEN_TIMEOUT}
end;
@ -282,6 +289,7 @@ init([StateName, StateData, _FSMLimitOpts]) ->
El ->
get_priority_from_presence(El)
end,
ejabberd_sm:drop_session(StateData#state.sid),
ejabberd_sm:open_session(
SID,
StateData#state.user,
@ -289,6 +297,7 @@ init([StateName, StateData, _FSMLimitOpts]) ->
StateData#state.resource,
Priority,
Info),
%%ejabberd_sm:drop_session(StateData#state.sid),
NewStateData = StateData#state{sid = SID, socket_monitor = MRef},
StateData2 = change_reception(NewStateData, true),
StateData3 = start_keepalive_timer(StateData2),
@ -583,15 +592,20 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
"(~w) Accepted legacy authentication for ~s by ~p",
[StateData#state.socket,
jlib:jid_to_string(JID), AuthModule]),
case need_redirect(StateData#state{user = U}) of
{true, Host} ->
?INFO_MSG("(~w) Redirecting ~s to ~s",
[StateData#state.socket,
jlib:jid_to_string(JID), Host]),
send_element(StateData, ?SERR_SEE_OTHER_HOST(Host)),
send_trailer(StateData),
{stop, normal, StateData};
false ->
SID = {now(), self()},
Conn = get_conn_type(StateData),
%% Info = [{ip, StateData#state.ip}, {conn, Conn},
%% {auth_module, AuthModule}],
Res1 = jlib:make_result_iq_reply(El),
Res = setelement(4, Res1, []),
send_element(StateData, Res),
%% ejabberd_sm:open_session(
%% SID, U, StateData#state.server, R, Info),
change_shaper(StateData, JID),
{Fs, Ts} = ejabberd_hooks:run_fold(
roster_get_subscription_lists,
@ -604,10 +618,12 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
Ts1 = [LJID | Ts],
PrivList =
ejabberd_hooks:run_fold(
privacy_get_user_list, StateData#state.server,
privacy_get_user_list,
StateData#state.server,
#userlist{},
[U, StateData#state.server]),
NewStateData = StateData#state{
NewStateData =
StateData#state{
user = U,
resource = R,
jid = JID,
@ -617,11 +633,14 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
pres_f = ?SETS:from_list(Fs1),
pres_t = ?SETS:from_list(Ts1),
privacy_list = PrivList},
DebugFlag = ejabberd_hooks:run_fold(c2s_debug_start_hook,
DebugFlag = ejabberd_hooks:run_fold(
c2s_debug_start_hook,
NewStateData#state.server,
false,
[self(), NewStateData]),
maybe_migrate(session_established, NewStateData#state{debug=DebugFlag});
maybe_migrate(session_established,
NewStateData#state{debug=DebugFlag})
end;
_ ->
?INFO_MSG(
"(~w) Failed legacy authentication for ~s",
@ -715,19 +734,28 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
{ok, Props} ->
catch (StateData#state.sockmod):reset_stream(
StateData#state.socket),
send_element(StateData,
{xmlelement, "success",
[{"xmlns", ?NS_SASL}], []}),
U = xml:get_attr_s(username, Props),
AuthModule = xml:get_attr_s(auth_module, Props),
?INFO_MSG("(~w) Accepted authentication for ~s by ~p",
[StateData#state.socket, U, AuthModule]),
case need_redirect(StateData#state{user = U}) of
{true, Host} ->
?INFO_MSG("(~w) Redirecting ~s to ~s",
[StateData#state.socket, U, Host]),
send_element(StateData, ?SERR_SEE_OTHER_HOST(Host)),
send_trailer(StateData),
{stop, normal, StateData};
false ->
send_element(StateData,
{xmlelement, "success",
[{"xmlns", ?NS_SASL}], []}),
fsm_next_state(wait_for_stream,
StateData#state{
streamid = new_id(),
authenticated = true,
auth_module = AuthModule,
user = U });
user = U })
end;
{continue, ServerOut, NewSASLState} ->
send_element(StateData,
{xmlelement, "challenge",
@ -868,19 +896,28 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
{ok, Props} ->
catch (StateData#state.sockmod):reset_stream(
StateData#state.socket),
send_element(StateData,
{xmlelement, "success",
[{"xmlns", ?NS_SASL}], []}),
U = xml:get_attr_s(username, Props),
AuthModule = xml:get_attr_s(auth_module, Props),
?INFO_MSG("(~w) Accepted authentication for ~s by ~p",
[StateData#state.socket, U, AuthModule]),
case need_redirect(StateData#state{user = U}) of
{true, Host} ->
?INFO_MSG("(~w) Redirecting ~s to ~s",
[StateData#state.socket, U, Host]),
send_element(StateData, ?SERR_SEE_OTHER_HOST(Host)),
send_trailer(StateData),
{stop, normal, StateData};
false ->
send_element(StateData,
{xmlelement, "success",
[{"xmlns", ?NS_SASL}], []}),
fsm_next_state(wait_for_stream,
StateData#state{
streamid = new_id(),
authenticated = true,
auth_module = AuthModule,
user = U});
user = U})
end;
{continue, ServerOut, NewSASLState} ->
send_element(StateData,
{xmlelement, "challenge",
@ -1232,9 +1269,6 @@ session_established2(El, StateData) ->
%% {next_state, NextStateName, NextStateData, Timeout} |
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
handle_event({migrate, Node, After}, StateName, StateData) when Node /= node() ->
fsm_migrate(StateName, StateData, Node, After * 2);
handle_event({add_rosteritem, IJID, ISubscription}, StateName, StateData) ->
NewStateData = roster_change(IJID, ISubscription, StateData),
fsm_next_state(StateName, NewStateData);
@ -1624,6 +1658,12 @@ handle_info({force_update_presence, LUser}, StateName,
StateData
end,
{next_state, StateName, NewStateData};
handle_info({migrate, Node}, StateName, StateData) ->
if Node /= node() ->
fsm_migrate(StateName, StateData, Node, 0);
true ->
fsm_next_state(StateName, StateData)
end;
handle_info({broadcast, Type, From, Packet}, StateName, StateData) ->
Recipients = ejabberd_hooks:run_fold(
c2s_broadcast_recipients, StateData#state.server,
@ -2516,13 +2556,12 @@ peerip(SockMod, Socket) ->
maybe_migrate(StateName, StateData) ->
PackedStateData = pack(StateData),
case ejabberd_cluster:get_node({StateData#state.user,
StateData#state.server}) of
#state{user = U, server = S, resource = R, sid = SID} = StateData,
case ejabberd_cluster:get_node({jlib:nodeprep(U), jlib:nameprep(S)}) of
Node when Node == node() ->
Conn = get_conn_type(StateData),
Info = [{ip, StateData#state.ip}, {conn, Conn},
{auth_module, StateData#state.auth_module}],
#state{user = U, server = S, resource = R, sid = SID} = StateData,
Presence = StateData#state.pres_last,
Priority =
case Presence of
@ -2535,13 +2574,6 @@ maybe_migrate(StateName, StateData) ->
StateData2 = change_reception(PackedStateData, true),
StateData3 = start_keepalive_timer(StateData2),
erlang:garbage_collect(),
case ejabberd_cluster:get_node_new({U, S}) of
Node ->
ok;
NewNode ->
After = ejabberd_cluster:rehash_timeout(),
migrate(self(), NewNode, After)
end,
fsm_next_state(StateName, StateData3);
Node ->
fsm_migrate(StateName, PackedStateData, Node, 0)
@ -3397,3 +3429,21 @@ flash_policy_string() ->
++ ToPortsString ++
"\"/>\n"
"</cross-domain-policy>\n\0".
need_redirect(#state{redirect = true, user = User, server = Server}) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
case ejabberd_cluster:get_node({LUser, LServer}) of
Node when node() == Node ->
false;
Node ->
case rpc:call(Node, ejabberd_config,
get_local_option, [hostname], 5000) of
Host when is_list(Host) ->
{true, Host};
_ ->
false
end
end;
need_redirect(_) ->
false.

View File

@ -57,6 +57,7 @@
conn = unknown,
auth_module = unknown,
ip,
redirect = false,
aux_fields = [],
fsm_limit_opts,
lang,

View File

@ -35,9 +35,9 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
-export([create_captcha/5, build_captcha_html/2, check_captcha/2,
-export([create_captcha/6, build_captcha_html/2, check_captcha/2,
process_reply/1, process/2, is_feature_available/0,
create_captcha_x/4, create_captcha_x/5]).
create_captcha_x/5, create_captcha_x/6]).
-include("jlib.hrl").
-include("ejabberd.hrl").
@ -50,8 +50,9 @@
-define(CAPTCHA_TEXT(Lang), translate:translate(Lang, "Enter the text you see")).
-define(CAPTCHA_LIFETIME, 120000). % two minutes
-define(RPC_TIMEOUT, 5000).
-define(LIMIT_PERIOD, 60*1000*1000). % one minute
-record(state, {}).
-record(state, {limits = treap:empty()}).
-record(captcha, {id, pid, key, tref, args}).
%%====================================================================
@ -64,10 +65,10 @@
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
create_captcha(SID, From, To, Lang, Args)
create_captcha(SID, From, To, Lang, Limiter, Args)
when is_list(Lang), is_list(SID),
is_record(From, jid), is_record(To, jid) ->
case create_image() of
case create_image(Limiter) of
{ok, Type, Key, Image} ->
Id = randoms:get_string() ++ "-" ++ ejabberd_cluster:node_id(),
B64Image = jlib:encode_base64(binary_to_list(Image)),
@ -99,15 +100,15 @@ create_captcha(SID, From, To, Lang, Args)
ets:insert(captcha, #captcha{id=Id, pid=self(), key=Key,
tref=Tref, args=Args}),
{ok, Id, [Body, OOB, Captcha, Data]};
_Err ->
error
Err ->
Err
end.
create_captcha_x(SID, To, Lang, HeadEls) ->
create_captcha_x(SID, To, Lang, HeadEls, []).
create_captcha_x(SID, To, Lang, Limiter, HeadEls) ->
create_captcha_x(SID, To, Lang, Limiter, HeadEls, []).
create_captcha_x(SID, To, Lang, HeadEls, TailEls) ->
case create_image() of
create_captcha_x(SID, To, Lang, Limiter, HeadEls, TailEls) ->
case create_image(Limiter) of
{ok, Type, Key, Image} ->
Id = randoms:get_string() ++ "-" ++ ejabberd_cluster:node_id(),
B64Image = jlib:encode_base64(binary_to_list(Image)),
@ -144,8 +145,8 @@ create_captcha_x(SID, To, Lang, HeadEls, TailEls) ->
Tref = erlang:send_after(?CAPTCHA_LIFETIME, ?MODULE, {remove_id, Id}),
ets:insert(captcha, #captcha{id=Id, key=Key, tref=Tref}),
{ok, [Captcha, Data]};
_ ->
error
Err ->
Err
end.
%% @spec (Id::string(), Lang::string()) -> {FormEl, {ImgEl, TextEl, IdEl, KeyEl}} | captcha_not_found
@ -242,16 +243,19 @@ process(_Handlers, #request{method='GET', lang=Lang, path=[_, Id]}) ->
ejabberd_web:error(not_found)
end;
process(_Handlers, #request{method='GET', path=[_, Id, "image"]}) ->
process(_Handlers, #request{method='GET', path=[_, Id, "image"], ip = IP}) ->
{Addr, _Port} = IP,
case lookup_captcha(Id) of
{ok, #captcha{key=Key}} ->
case create_image(Key) of
case create_image(Addr, Key) of
{ok, Type, _, Img} ->
{200,
[{"Content-Type", Type},
{"Cache-Control", "no-cache"},
{"Last-Modified", httpd_util:rfc1123_date()}],
Img};
{error, limit} ->
ejabberd_web:error(not_allowed);
_ ->
ejabberd_web:error(not_found)
end;
@ -288,6 +292,20 @@ init([]) ->
check_captcha_setup(),
{ok, #state{}}.
handle_call({is_limited, Limiter, RateLimit}, _From, State) ->
NowPriority = now_priority(),
CleanPriority = NowPriority + ?LIMIT_PERIOD,
Limits = clean_treap(State#state.limits, CleanPriority),
case treap:lookup(Limiter, Limits) of
{ok, _, Rate} when Rate >= RateLimit ->
{reply, true, State#state{limits = Limits}};
{ok, Priority, Rate} ->
NewLimits = treap:insert(Limiter, Priority, Rate+1, Limits),
{reply, false, State#state{limits = NewLimits}};
_ ->
NewLimits = treap:insert(Limiter, NowPriority, 1, Limits),
{reply, false, State#state{limits = NewLimits}}
end;
handle_call(_Request, _From, State) ->
{reply, bad_request, State}.
@ -329,11 +347,22 @@ code_change(_OldVsn, State, _Extra) ->
%% Reason = atom()
%%--------------------------------------------------------------------
create_image() ->
create_image(undefined).
create_image(Limiter) ->
%% Six numbers from 1 to 9.
Key = string:substr(randoms:get_string(), 1, 6),
create_image(Key).
create_image(Limiter, Key).
create_image(Key) ->
create_image(Limiter, Key) ->
case is_limited(Limiter) of
true ->
{error, limit};
false ->
do_create_image(Key)
end.
do_create_image(Key) ->
FileName = get_prog_name(),
Cmd = lists:flatten(io_lib:format("~s ~s", [FileName, Key])),
case cmd(Cmd) of
@ -363,31 +392,33 @@ get_prog_name() ->
case ejabberd_config:get_local_option(captcha_cmd) of
FileName when is_list(FileName) ->
FileName;
_ ->
Value when (Value == undefined) or (Value == "") ->
?DEBUG("The option captcha_cmd is not configured, but some "
"module wants to use the CAPTCHA feature.", []),
throw({error, option_not_configured_captcha_cmd})
false
end.
get_url(Str) ->
CaptchaHost = ejabberd_config:get_local_option(captcha_host),
TransferProt = atom_to_list(get_transfer_protocol(CaptchaHost)),
case CaptchaHost of
Host when is_list(Host) ->
TransferProt ++ "://" ++ Host ++ "/captcha/" ++ Str;
case string:tokens(CaptchaHost, ":") of
[Host] ->
"http://" ++ Host ++ "/captcha/" ++ Str;
["http"++_ = TransferProt, Host] ->
TransferProt ++ ":" ++ Host ++ "/captcha/" ++ Str;
[Host, PortString] ->
TransferProt = atom_to_list(get_transfer_protocol(PortString)),
TransferProt ++ "://" ++ Host ++ ":" ++ PortString ++ "/captcha/" ++ Str;
[TransferProt, Host, PortString] ->
TransferProt ++ ":" ++ Host ++ ":" ++ PortString ++ "/captcha/" ++ Str;
_ ->
TransferProt ++ "://" ++ ?MYNAME ++ "/captcha/" ++ Str
"http://" ++ ?MYNAME ++ "/captcha/" ++ Str
end.
get_transfer_protocol(CaptchaHost) ->
PortNumber = get_port_number_from_captcha_host_option(CaptchaHost),
get_transfer_protocol(PortString) ->
PortNumber = list_to_integer(PortString),
PortListeners = get_port_listeners(PortNumber),
get_captcha_transfer_protocol(PortListeners).
get_port_number_from_captcha_host_option(CaptchaHost) ->
[_Host, PortString] = string:tokens(CaptchaHost, ":"),
list_to_integer(PortString).
get_port_listeners(PortNumber) ->
AllListeners = ejabberd_config:get_local_option(listen),
lists:filter(
@ -400,7 +431,8 @@ get_port_listeners(PortNumber) ->
get_captcha_transfer_protocol([]) ->
throw("The port number mentioned in captcha_host is not "
"a ejabberd_http listener with 'captcha' option.");
"a ejabberd_http listener with 'captcha' option. "
"Change the port number or specify http:// in that option.");
get_captcha_transfer_protocol([{{_Port, _Ip, tcp}, ejabberd_http, Opts}
| Listeners]) ->
case lists:member(captcha, Opts) of
@ -417,6 +449,25 @@ get_captcha_transfer_protocol([{{_Port, _Ip, tcp}, ejabberd_http, Opts}
get_captcha_transfer_protocol([_ | Listeners]) ->
get_captcha_transfer_protocol(Listeners).
is_limited(undefined) ->
false;
is_limited(Limiter) ->
case ejabberd_config:get_local_option(captcha_limit) of
Int when is_integer(Int), Int > 0 ->
case catch gen_server:call(?MODULE, {is_limited, Limiter, Int},
5000) of
true ->
true;
false ->
false;
Err ->
?ERROR_MSG("Call failed: ~p", [Err]),
false
end;
_ ->
false
end.
%%--------------------------------------------------------------------
%% Function: cmd(Cmd) -> Data | {error, Reason}
%% Cmd = string()
@ -465,28 +516,22 @@ return(Port, TRef, Result) ->
catch port_close(Port),
Result.
is_feature_enabled() ->
try get_prog_name() of
Prog when is_list(Prog) -> true
catch
_:_ -> false
end.
is_feature_available() ->
case is_feature_enabled() of
false -> false;
true ->
case create_image() of
{ok, _, _, _} -> true;
_Error -> false
end
case get_prog_name() of
Prog when is_list(Prog) -> true;
false -> false
end.
check_captcha_setup() ->
case is_feature_enabled() andalso not is_feature_available() of
AbleToGenerateCaptcha = case create_image() of
{ok, _, _, _} -> true;
_Error -> false
end,
case is_feature_available() andalso not AbleToGenerateCaptcha of
true ->
?CRITICAL_MSG("Captcha is enabled in the option captcha_cmd, "
"but it can't generate images.", []);
"but it can't generate images.", []),
throw({error, captcha_cmd_enabled_but_fails});
false ->
ok
end.
@ -538,3 +583,21 @@ do_check_captcha(Id, ProvidedKey) ->
_ ->
captcha_not_found
end.
clean_treap(Treap, CleanPriority) ->
case treap:is_empty(Treap) of
true ->
Treap;
false ->
{_Key, Priority, _Value} = treap:get_root(Treap),
if
Priority > CleanPriority ->
clean_treap(treap:delete_root(Treap), CleanPriority);
true ->
Treap
end
end.
now_priority() ->
{MSec, Sec, USec} = now(),
-((MSec*1000000 + Sec)*1000000 + USec).

View File

@ -10,8 +10,8 @@
-behaviour(gen_server).
%% API
-export([start_link/0, get_node/1, get_node_new/1, announce/0, shutdown/0,
node_id/0, get_node_by_id/1, get_nodes/0, rehash_timeout/0]).
-export([start_link/0, get_node/1, get_node_new/1, announce/1, shutdown/0,
node_id/0, get_node_by_id/1, get_nodes/0, rehash_timeout/0, start/0]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@ -22,15 +22,28 @@
-define(HASHTBL, nodes_hash).
-define(HASHTBL_NEW, nodes_hash_new).
-define(POINTS, 64).
-define(REHASH_TIMEOUT, 30000).
-define(REHASH_TIMEOUT, timer:seconds(30)).
-define(MIGRATE_TIMEOUT, timer:minutes(2)).
%%-define(REHASH_TIMEOUT, timer:seconds(10)).
%%-define(MIGRATE_TIMEOUT, timer:seconds(5)).
-define(LOCK, {migrate, node()}).
-record(state, {}).
%%====================================================================
%% API
%%====================================================================
start() ->
ChildSpec = {?MODULE,
{?MODULE, start_link, []},
permanent,
brutal_kill,
worker,
[?MODULE]},
supervisor:start_child(ejabberd_sup, ChildSpec).
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
gen_server:start_link(?MODULE, [], []).
get_node(Key) ->
Hash = erlang:phash2(Key),
@ -44,8 +57,8 @@ get_nodes() ->
%% TODO
mnesia:system_info(running_db_nodes).
announce() ->
gen_server:call(?MODULE, announce, infinity).
announce(Pid) ->
gen_server:call(Pid, announce, infinity).
node_id() ->
integer_to_list(erlang:phash2(node())).
@ -80,13 +93,15 @@ shutdown() ->
%% gen_server callbacks
%%====================================================================
init([]) ->
{A, B, C} = now(),
random:seed(A, B, C),
net_kernel:monitor_nodes(true, [{node_type, visible}]),
ets:new(?HASHTBL, [named_table, public, ordered_set]),
ets:new(?HASHTBL_NEW, [named_table, public, ordered_set]),
register_node(),
AllNodes = mnesia:system_info(running_db_nodes),
AllNodes = get_nodes(),
OtherNodes = case AllNodes of
[_] ->
[_MyNode] ->
AllNodes;
_ ->
AllNodes -- [node()]
@ -96,35 +111,59 @@ init([]) ->
{ok, #state{}}.
handle_call(announce, _From, State) ->
case mnesia:system_info(running_db_nodes) of
case global:set_lock(?LOCK, get_nodes(), 0) of
false ->
?INFO_MSG("Another node is recently attached to "
"the cluster and is being rebalanced. "
"Waiting for the rebalancing to be completed "
"before starting this node. "
"This may take serveral minutes. "
"Please, be patient.", []),
global:set_lock(?LOCK, get_nodes(), infinity);
true ->
ok
end,
case get_nodes() of
[_MyNode] ->
ok;
register(?MODULE, self()),
global:del_lock(?LOCK);
Nodes ->
OtherNodes = Nodes -- [node()],
lists:foreach(
fun(Node) ->
{?MODULE, Node} ! {node_ready, node()}
end, OtherNodes),
?INFO_MSG("waiting for migration from nodes: ~w",
[OtherNodes]),
timer:sleep(?REHASH_TIMEOUT),
append_node(?HASHTBL, node())
{_Res, BadNodes} = gen_server:multi_call(
OtherNodes, ?MODULE,
{node_ready, node()}, ?REHASH_TIMEOUT),
append_node(?HASHTBL, node()),
register(?MODULE, self()),
case OtherNodes -- BadNodes of
[] ->
global:del_lock(?LOCK);
WorkingNodes ->
gen_server:abcast(WorkingNodes, ?MODULE, {node_ready, node()}),
erlang:send_after(?MIGRATE_TIMEOUT, self(), del_lock)
end
end,
{reply, ok, State};
handle_call({node_ready, Node}, _From, State) ->
?INFO_MSG("node ~p is ready, preparing migration", [Node]),
append_node(?HASHTBL_NEW, Node),
ejabberd_hooks:run(node_up, [Node]),
{reply, ok, State};
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
handle_cast({node_ready, Node}, State) ->
?INFO_MSG("adding node ~p to hash and starting migration", [Node]),
append_node(?HASHTBL, Node),
ejabberd_hooks:run(node_hash_update, [?MIGRATE_TIMEOUT]),
{noreply, State};
handle_cast(_Msg, State) ->
{noreply, State}.
handle_info({node_ready, Node}, State) ->
?INFO_MSG("node ~p is ready, starting migration", [Node]),
append_node(?HASHTBL_NEW, Node),
ejabberd_hooks:run(node_hash_update, [?REHASH_TIMEOUT]),
timer:sleep(?REHASH_TIMEOUT),
?INFO_MSG("adding node ~p to hash", [Node]),
append_node(?HASHTBL, Node),
handle_info(del_lock, State) ->
global:del_lock(?LOCK),
{noreply, State};
handle_info({node_down, Node}, State) ->
delete_node(?HASHTBL, Node),

View File

@ -431,6 +431,8 @@ process_term(Term, State) ->
add_option(captcha_cmd, Cmd, State);
{captcha_host, Host} ->
add_option(captcha_host, Host, State);
{captcha_limit, Limit} ->
add_option(captcha_limit, Limit, State);
{ejabberdctl_access_commands, ACs} ->
add_option(ejabberdctl_access_commands, ACs, State);
{loglevel, Loglevel} ->
@ -438,6 +440,8 @@ process_term(Term, State) ->
State;
{max_fsm_queue, N} ->
add_option(max_fsm_queue, N, State);
{hostname, Host} ->
add_option(hostname, Host, State);
{_Opt, _Val} ->
lists:foldl(fun(Host, S) -> process_host_term(Term, Host, S) end,
State, State#state.hosts)

View File

@ -34,10 +34,12 @@
-export([route/3,
route_iq/4,
route_iq/5,
process_iq_reply/3,
register_iq_handler/4,
register_iq_handler/5,
register_iq_response_handler/4,
register_iq_response_handler/5,
unregister_iq_handler/2,
unregister_iq_response_handler/2,
refresh_iq_handlers/0,
@ -123,19 +125,31 @@ route(From, To, Packet) ->
ok
end.
route_iq(From, To, #iq{type = Type} = IQ, F) when is_function(F) ->
route_iq(From, To, IQ, F) ->
route_iq(From, To, IQ, F, undefined).
route_iq(From, To, #iq{type = Type} = IQ, F, Timeout) when is_function(F) ->
Packet = if Type == set; Type == get ->
ID = ejabberd_router:make_id(),
Host = From#jid.lserver,
register_iq_response_handler(Host, ID, undefined, F),
register_iq_response_handler(Host, ID, undefined, F, Timeout),
jlib:iq_to_xml(IQ#iq{id = ID});
true ->
jlib:iq_to_xml(IQ)
end,
ejabberd_router:route(From, To, Packet).
register_iq_response_handler(_Host, ID, Module, Function) ->
TRef = erlang:start_timer(?IQ_TIMEOUT, ejabberd_local, ID),
register_iq_response_handler(Host, ID, Module, Function) ->
register_iq_response_handler(Host, ID, Module, Function, undefined).
register_iq_response_handler(_Host, ID, Module, Function, Timeout0) ->
Timeout = case Timeout0 of
undefined ->
?IQ_TIMEOUT;
N when is_integer(N), N > 0 ->
N
end,
TRef = erlang:start_timer(Timeout, ejabberd_local, ID),
ets:insert(iq_response, #iq_response{id = ID,
module = Module,
function = Function,

View File

@ -203,9 +203,9 @@ migrate(After) ->
['$$']}]),
lists:foreach(
fun([FromTo, Pid]) ->
case ejabberd_cluster:get_node_new(FromTo) of
case ejabberd_cluster:get_node(FromTo) of
Node when Node /= node() ->
ejabberd_s2s_out:stop_connection(Pid, After * 2);
ejabberd_s2s_out:stop_connection(Pid, After);
_ ->
ok
end

View File

@ -37,6 +37,7 @@
open_session/6,
close_session/4,
close_migrated_session/4,
drop_session/1,
check_in_subscription/6,
bounce_offline_message/3,
disconnect_removed_user/2,
@ -60,6 +61,7 @@
get_session_pid/3,
get_user_info/3,
get_user_ip/3,
node_up/1,
migrate/1
]).
@ -108,27 +110,37 @@ open_session(SID, User, Server, Resource, Priority, Info) ->
[SID, JID, Info]).
close_session(SID, User, Server, Resource) ->
Info = do_close_session(SID, User, Server, Resource),
Info = do_close_session(SID),
US = {jlib:nodeprep(User), jlib:nameprep(Server)},
case ejabberd_cluster:get_node_new(US) of
Node when Node /= node() ->
rpc:cast(Node, ?MODULE, drop_session, [SID]);
_ ->
ok
end,
JID = jlib:make_jid(User, Server, Resource),
ejabberd_hooks:run(sm_remove_connection_hook, JID#jid.lserver,
[SID, JID, Info]).
close_migrated_session(SID, User, Server, Resource) ->
Info = do_close_session(SID, User, Server, Resource),
Info = do_close_session(SID),
JID = jlib:make_jid(User, Server, Resource),
ejabberd_hooks:run(sm_remove_migrated_connection_hook, JID#jid.lserver,
[SID, JID, Info]).
do_close_session(SID, User, Server, Resource) ->
do_close_session(SID) ->
Info = case mnesia:dirty_read({session, SID}) of
[] -> [];
[#session{info=I}] -> I
end,
drop_session(SID),
Info.
drop_session(SID) ->
F = fun() ->
mnesia:delete({session, SID})
end,
mnesia:sync_dirty(F),
Info.
mnesia:sync_dirty(F).
check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) ->
case ejabberd_auth:is_user_exists(User, Server) of
@ -312,14 +324,33 @@ migrate(After) ->
['$$']}]),
lists:foreach(
fun([US, Pid]) ->
case ejabberd_cluster:get_node_new(US) of
case ejabberd_cluster:get_node(US) of
Node when Node /= node() ->
ejabberd_c2s:migrate(Pid, Node, After);
ejabberd_c2s:migrate(Pid, Node, random:uniform(After));
_ ->
ok
end
end, Ss).
node_up(_Node) ->
copy_sessions(mnesia:dirty_first(session)).
copy_sessions('$end_of_table') ->
ok;
copy_sessions(Key) ->
case mnesia:dirty_read(session, Key) of
[#session{us = US} = Session] ->
case ejabberd_cluster:get_node_new(US) of
Node when node() /= Node ->
rpc:cast(Node, mnesia, dirty_write, [Session]);
_ ->
ok
end;
_ ->
ok
end,
copy_sessions(mnesia:dirty_next(session, Key)).
%%====================================================================
%% gen_server callbacks
%%====================================================================
@ -341,6 +372,7 @@ init([]) ->
mnesia:add_table_index(session, us),
mnesia:add_table_copy(session, node(), ram_copies),
ets:new(sm_iqtable, [named_table]),
ejabberd_hooks:add(node_up, ?MODULE, node_up, 100),
ejabberd_hooks:add(node_hash_update, ?MODULE, migrate, 100),
lists:foreach(
fun(Host) ->
@ -352,7 +384,7 @@ init([]) ->
ejabberd_sm, disconnect_removed_user, 100)
end, ?MYHOSTS),
ejabberd_commands:register_commands(commands()),
start_dispatchers(),
{ok, #state{}}.
%%--------------------------------------------------------------------
@ -383,13 +415,19 @@ handle_cast(_Msg, State) ->
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info({route, From, To, Packet}, State) ->
handle_info({route, From, To, Packet} = Msg, State) ->
case get_proc_num() of
N when N > 1 ->
#jid{luser = U, lserver = S} = To,
get_proc_by_hash({U, S}) ! Msg;
_ ->
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
[Reason, {From, To, Packet}]);
_ ->
ok
end
end,
{noreply, State};
handle_info({register_iq_handler, Host, XMLNS, Module, Function}, State) ->
@ -418,8 +456,10 @@ handle_info(_Info, State) ->
%% The return value is ignored.
%%--------------------------------------------------------------------
terminate(_Reason, _State) ->
ejabberd_hooks:delete(node_up, ?MODULE, node_up, 100),
ejabberd_hooks:delete(node_hash_update, ?MODULE, migrate, 100),
ejabberd_commands:unregister_commands(commands()),
stop_dispatchers(),
ok.
%%--------------------------------------------------------------------
@ -433,7 +473,7 @@ code_change(_OldVsn, State, _Extra) ->
%%% Internal functions
%%--------------------------------------------------------------------
set_session(SID, User, Server, Resource, Priority, Info) ->
set_session({_, Pid} = SID, User, Server, Resource, Priority, Info) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
LResource = jlib:resourceprep(Resource),
@ -446,7 +486,31 @@ set_session(SID, User, Server, Resource, Priority, Info) ->
priority = Priority,
info = Info})
end,
mnesia:sync_dirty(F).
mnesia:sync_dirty(F),
case ejabberd_cluster:get_node_new(US) of
Node when node() /= Node ->
%% New node has just been added. But we may miss session records
%% copy procedure, so we copy the session record manually just
%% to make sure
rpc:cast(Node, mnesia, dirty_write,
[#session{sid = SID,
usr = USR,
us = US,
priority = Priority,
info = Info}]),
case ejabberd_cluster:get_node(US) of
Node when node() /= Node ->
%% Migration to new node has completed, and seems like
%% we missed it, so we migrate the session pid manually.
%% It is not a problem if we have already got migration
%% notification: dups are just ignored by the c2s pid.
ejabberd_c2s:migrate(Pid, Node, 0);
_ ->
ok
end;
_ ->
ok
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -818,6 +882,55 @@ user_resources(User, Server) ->
Resources = get_user_resources(User, Server),
lists:sort(Resources).
get_proc_num() ->
erlang:system_info(logical_processors).
get_proc_by_hash(Term) ->
N = erlang:phash2(Term, get_proc_num()) + 1,
get_proc(N).
get_proc(N) ->
list_to_atom(atom_to_list(?MODULE) ++ "_" ++ integer_to_list(N)).
start_dispatchers() ->
case get_proc_num() of
N when N > 1 ->
lists:foreach(
fun(I) ->
Pid = spawn(fun dispatch/0),
erlang:register(get_proc(I), Pid)
end, lists:seq(1, N));
_ ->
ok
end.
stop_dispatchers() ->
case get_proc_num() of
N when N > 1 ->
lists:foreach(
fun(I) ->
get_proc(I) ! stop
end, lists:seq(1, N));
_ ->
ok
end.
dispatch() ->
receive
{route, From, To, Packet} ->
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
[Reason, {From, To, Packet}]);
_ ->
ok
end,
dispatch();
stop ->
stopped;
_ ->
dispatch()
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Update Mnesia tables

View File

@ -178,13 +178,6 @@ init([]) ->
infinity,
supervisor,
[ejabberd_tmp_sup]},
Cluster =
{ejabberd_cluster,
{ejabberd_cluster, start_link, []},
permanent,
brutal_kill,
worker,
[ejabberd_cluster]},
CacheTabSupervisor =
{cache_tab_sup,
{cache_tab_sup, start_link, []},
@ -194,7 +187,6 @@ init([]) ->
[cache_tab_sup]},
{ok, {{one_for_one, 10, 1},
[Hooks,
Cluster,
SystemMonitor,
Router,
SM,

View File

@ -50,12 +50,23 @@
#
#FIREWALL_WINDOW=
#.
#' INET_DIST_INTERFACE: IP address where this Erlang node listens other nodes
#
# This communication is used by ejabberdctl command line tool,
# and in a cluster of several ejabberd nodes.
# Notice that the IP address must be specified in the Erlang syntax.
#
# Default: {127,0,0,1}
#
INET_DIST_INTERFACE={127,0,0,1}
#.
#' ERL_PROCESSES: Maximum number of Erlang processes
#
# Erlang consumes a lot of lightweight processes. If there is a lot of activity
# on ejabberd so that the maximum number of processes is reached, people will
# experiment greater latency times. As these processes are implemented in
# experience greater latency times. As these processes are implemented in
# Erlang, and therefore not related to the operating system processes, you do
# not have to worry about allowing a huge number of them.
#

View File

@ -76,10 +76,12 @@ fi
NAME=-name
[ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && NAME=-sname
if [ "$FIREWALL_WINDOW" = "" ] ; then
KERNEL_OPTS=""
else
KERNEL_OPTS="-kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
if [ "$FIREWALL_WINDOW" != "" ] ; then
KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
fi
if [ "$INET_DIST_INTERFACE" != "" ] ; then
KERNEL_OPTS="${KERNEL_OPTS} -kernel inet_dist_use_interface \"${INET_DIST_INTERFACE}\""
fi
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $ERL_OPTIONS"

View File

@ -35,6 +35,7 @@
#define PARSE_FINAL_COMMAND 1
ei_x_buff event_buf;
ei_x_buff xmlns_buf;
typedef struct {
ErlDrvPort port;
@ -43,6 +44,32 @@ typedef struct {
static XML_Memory_Handling_Suite ms = {driver_alloc, driver_realloc, driver_free};
void encode_name(const XML_Char *name)
{
char *name_start;
char *prefix_start;
char *buf;
int name_len, prefix_len, buf_len;
if ((name_start = strchr(name, '\n'))) {
if ((prefix_start = strchr(name_start+1, '\n'))) {
name_len = prefix_start - name_start;
prefix_len = strlen(prefix_start+1);
buf_len = prefix_len + name_len;
buf = driver_alloc(buf_len);
memcpy(buf, prefix_start+1, prefix_len);
memcpy(buf+prefix_len, name_start, name_len);
buf[prefix_len] = ':';
ei_x_encode_string_len(&event_buf, buf, buf_len);
driver_free(buf);
} else {
ei_x_encode_string(&event_buf, name_start+1);
};
} else {
ei_x_encode_string(&event_buf, name);
}
}
void *erlXML_StartElementHandler(expat_data *d,
const XML_Char *name,
const XML_Char **atts)
@ -53,7 +80,10 @@ void *erlXML_StartElementHandler(expat_data *d,
ei_x_encode_tuple_header(&event_buf, 2);
ei_x_encode_long(&event_buf, XML_START);
ei_x_encode_tuple_header(&event_buf, 2);
ei_x_encode_string(&event_buf, name);
encode_name(name);
ei_x_append(&event_buf, &xmlns_buf);
ei_x_free(&xmlns_buf);
ei_x_new(&xmlns_buf);
for (i = 0; atts[i]; i += 2) {}
@ -64,7 +94,7 @@ void *erlXML_StartElementHandler(expat_data *d,
for (i = 0; atts[i]; i += 2)
{
ei_x_encode_tuple_header(&event_buf, 2);
ei_x_encode_string(&event_buf, atts[i]);
encode_name(atts[i]);
ei_x_encode_string(&event_buf, atts[i+1]);
}
}
@ -80,7 +110,7 @@ void *erlXML_EndElementHandler(expat_data *d,
ei_x_encode_list_header(&event_buf, 1);
ei_x_encode_tuple_header(&event_buf, 2);
ei_x_encode_long(&event_buf, XML_END);
ei_x_encode_string(&event_buf, name);
encode_name(name);
return NULL;
}
@ -95,12 +125,35 @@ void *erlXML_CharacterDataHandler(expat_data *d,
return NULL;
}
void *erlXML_StartNamespaceDeclHandler(expat_data *d,
const XML_Char *prefix,
const XML_Char *uri)
{
int prefix_len;
char *buf;
ei_x_encode_list_header(&xmlns_buf, 1);
ei_x_encode_tuple_header(&xmlns_buf, 2);
if (prefix) {
prefix_len = strlen(prefix);
buf = driver_alloc(7 + prefix_len);
strcpy(buf, "xmlns:");
strcpy(buf+6, prefix);
ei_x_encode_string(&xmlns_buf, buf);
driver_free(buf);
} else {
ei_x_encode_string(&xmlns_buf, "xmlns");
};
ei_x_encode_string(&xmlns_buf, uri);
return NULL;
}
static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
{
expat_data* d = (expat_data*)driver_alloc(sizeof(expat_data));
d->port = port;
d->parser = XML_ParserCreate_MM("UTF-8", &ms, NULL);
d->parser = XML_ParserCreate_MM("UTF-8", &ms, "\n");
XML_SetUserData(d->parser, d);
set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY);
@ -112,6 +165,9 @@ static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff)
XML_SetCharacterDataHandler(
d->parser, (XML_CharacterDataHandler)erlXML_CharacterDataHandler);
XML_SetStartNamespaceDeclHandler(
d->parser, (XML_StartNamespaceDeclHandler) erlXML_StartNamespaceDeclHandler);
XML_SetReturnNSTriplet(d->parser, 1);
return (ErlDrvData)d;
}
@ -138,6 +194,7 @@ static int expat_erl_control(ErlDrvData drv_data,
case PARSE_COMMAND:
case PARSE_FINAL_COMMAND:
ei_x_new_with_version(&event_buf);
ei_x_new(&xmlns_buf);
#ifdef ENABLE_FLASH_HACK
/* Flash hack - Flash clients send a null byte after the stanza. Remove that... */
{
@ -190,6 +247,7 @@ static int expat_erl_control(ErlDrvData drv_data,
memcpy(b->orig_bytes, event_buf.buff, size);
ei_x_free(&event_buf);
ei_x_free(&xmlns_buf);
*rbuf = (char *)b;
return size;

View File

@ -45,11 +45,18 @@
start(Host, ExtPrg) ->
lists:foreach(
fun(This) ->
spawn(?MODULE, init, [get_process_name(Host, This), ExtPrg])
start_instance(get_process_name(Host, This), ExtPrg)
end,
lists:seq(0, get_instances(Host)-1)
).
start_instance(ProcessName, ExtPrg) ->
spawn(?MODULE, init, [ProcessName, ExtPrg]).
restart_instance(ProcessName, ExtPrg) ->
unregister(ProcessName),
start_instance(ProcessName, ExtPrg).
init(ProcessName, ExtPrg) ->
register(ProcessName, self()),
process_flag(trap_exit,true),
@ -125,8 +132,8 @@ loop(Port, Timeout, ProcessName, ExtPrg) ->
Timeout ->
?ERROR_MSG("extauth call '~p' didn't receive response", [Msg]),
Caller ! {eauth, false},
unregister(ProcessName),
spawn(?MODULE, init, [ProcessName, ExtPrg]),
Pid = restart_instance(ProcessName, ExtPrg),
flush_buffer_and_forward_messages(Pid),
exit(port_terminated)
end;
stop ->
@ -136,10 +143,21 @@ loop(Port, Timeout, ProcessName, ExtPrg) ->
exit(normal)
end;
{'EXIT', Port, Reason} ->
?CRITICAL_MSG("~p ~n", [Reason]),
?CRITICAL_MSG("extauth script has exitted abruptly with reason '~p'", [Reason]),
Pid = restart_instance(ProcessName, ExtPrg),
flush_buffer_and_forward_messages(Pid),
exit(port_terminated)
end.
flush_buffer_and_forward_messages(Pid) ->
receive
Message ->
Pid ! Message,
flush_buffer_and_forward_messages(Pid)
after 0 ->
true
end.
join(List, Sep) ->
lists:foldl(fun(A, "") -> A;
(A, Acc) -> Acc ++ Sep ++ A

View File

@ -206,117 +206,117 @@
?ERRT_CONFLICT(Lang, "Resource conflict")).
-define(STREAM_ERROR(Condition),
-define(STREAM_ERROR(Condition, Cdata),
{xmlelement, "stream:error",
[],
[{xmlelement, Condition, [{"xmlns", ?NS_STREAMS}], []}]}).
[{xmlelement, Condition, [{"xmlns", ?NS_STREAMS}],
[{xmlcdata, Cdata}]}]}).
-define(SERR_BAD_FORMAT,
?STREAM_ERROR("bad-format")).
?STREAM_ERROR("bad-format", "")).
-define(SERR_BAD_NAMESPACE_PREFIX,
?STREAM_ERROR("bad-namespace-prefix")).
?STREAM_ERROR("bad-namespace-prefix", "")).
-define(SERR_CONFLICT,
?STREAM_ERROR("conflict")).
?STREAM_ERROR("conflict", "")).
-define(SERR_CONNECTION_TIMEOUT,
?STREAM_ERROR("connection-timeout")).
?STREAM_ERROR("connection-timeout", "")).
-define(SERR_HOST_GONE,
?STREAM_ERROR("host-gone")).
?STREAM_ERROR("host-gone", "")).
-define(SERR_HOST_UNKNOWN,
?STREAM_ERROR("host-unknown")).
?STREAM_ERROR("host-unknown", "")).
-define(SERR_IMPROPER_ADDRESSING,
?STREAM_ERROR("improper-addressing")).
?STREAM_ERROR("improper-addressing", "")).
-define(SERR_INTERNAL_SERVER_ERROR,
?STREAM_ERROR("internal-server-error")).
?STREAM_ERROR("internal-server-error", "")).
-define(SERR_INVALID_FROM,
?STREAM_ERROR("invalid-from")).
?STREAM_ERROR("invalid-from", "")).
-define(SERR_INVALID_ID,
?STREAM_ERROR("invalid-id")).
?STREAM_ERROR("invalid-id", "")).
-define(SERR_INVALID_NAMESPACE,
?STREAM_ERROR("invalid-namespace")).
?STREAM_ERROR("invalid-namespace", "")).
-define(SERR_INVALID_XML,
?STREAM_ERROR("invalid-xml")).
?STREAM_ERROR("invalid-xml", "")).
-define(SERR_NOT_AUTHORIZED,
?STREAM_ERROR("not-authorized")).
?STREAM_ERROR("not-authorized", "")).
-define(SERR_POLICY_VIOLATION,
?STREAM_ERROR("policy-violation")).
?STREAM_ERROR("policy-violation", "")).
-define(SERR_REMOTE_CONNECTION_FAILED,
?STREAM_ERROR("remote-connection-failed")).
?STREAM_ERROR("remote-connection-failed", "")).
-define(SERR_RESOURSE_CONSTRAINT,
?STREAM_ERROR("resource-constraint")).
?STREAM_ERROR("resource-constraint", "")).
-define(SERR_RESTRICTED_XML,
?STREAM_ERROR("restricted-xml")).
% TODO: include hostname or IP
-define(SERR_SEE_OTHER_HOST,
?STREAM_ERROR("see-other-host")).
?STREAM_ERROR("restricted-xml", "")).
-define(SERR_SEE_OTHER_HOST(Host),
?STREAM_ERROR("see-other-host", Host)).
-define(SERR_SYSTEM_SHUTDOWN,
?STREAM_ERROR("system-shutdown")).
?STREAM_ERROR("system-shutdown", "")).
-define(SERR_UNSUPPORTED_ENCODING,
?STREAM_ERROR("unsupported-encoding")).
?STREAM_ERROR("unsupported-encoding", "")).
-define(SERR_UNSUPPORTED_STANZA_TYPE,
?STREAM_ERROR("unsupported-stanza-type")).
?STREAM_ERROR("unsupported-stanza-type", "")).
-define(SERR_UNSUPPORTED_VERSION,
?STREAM_ERROR("unsupported-version")).
?STREAM_ERROR("unsupported-version", "")).
-define(SERR_XML_NOT_WELL_FORMED,
?STREAM_ERROR("xml-not-well-formed")).
?STREAM_ERROR("xml-not-well-formed", "")).
%-define(SERR_,
% ?STREAM_ERROR("")).
% ?STREAM_ERROR("", "")).
-define(STREAM_ERRORT(Condition, Lang, Text),
-define(STREAM_ERRORT(Condition, Cdata, Lang, Text),
{xmlelement, "stream:error",
[],
[{xmlelement, Condition, [{"xmlns", ?NS_STREAMS}], []},
[{xmlelement, Condition, [{"xmlns", ?NS_STREAMS}],
[{xmlcdata, Cdata}]},
{xmlelement, "text", [{"xml:lang", Lang}, {"xmlns", ?NS_STREAMS}],
[{xmlcdata, translate:translate(Lang, Text)}]}]}).
-define(SERRT_BAD_FORMAT(Lang, Text),
?STREAM_ERRORT("bad-format", Lang, Text)).
?STREAM_ERRORT("bad-format", "", Lang, Text)).
-define(SERRT_BAD_NAMESPACE_PREFIX(Lang, Text),
?STREAM_ERRORT("bad-namespace-prefix", Lang, Text)).
?STREAM_ERRORT("bad-namespace-prefix", "", Lang, Text)).
-define(SERRT_CONFLICT(Lang, Text),
?STREAM_ERRORT("conflict", Lang, Text)).
?STREAM_ERRORT("conflict", "", Lang, Text)).
-define(SERRT_CONNECTION_TIMEOUT(Lang, Text),
?STREAM_ERRORT("connection-timeout", Lang, Text)).
?STREAM_ERRORT("connection-timeout", "", Lang, Text)).
-define(SERRT_HOST_GONE(Lang, Text),
?STREAM_ERRORT("host-gone", Lang, Text)).
?STREAM_ERRORT("host-gone", "", Lang, Text)).
-define(SERRT_HOST_UNKNOWN(Lang, Text),
?STREAM_ERRORT("host-unknown", Lang, Text)).
?STREAM_ERRORT("host-unknown", "", Lang, Text)).
-define(SERRT_IMPROPER_ADDRESSING(Lang, Text),
?STREAM_ERRORT("improper-addressing", Lang, Text)).
?STREAM_ERRORT("improper-addressing", "", Lang, Text)).
-define(SERRT_INTERNAL_SERVER_ERROR(Lang, Text),
?STREAM_ERRORT("internal-server-error", Lang, Text)).
?STREAM_ERRORT("internal-server-error", "", Lang, Text)).
-define(SERRT_INVALID_FROM(Lang, Text),
?STREAM_ERRORT("invalid-from", Lang, Text)).
?STREAM_ERRORT("invalid-from", "", Lang, Text)).
-define(SERRT_INVALID_ID(Lang, Text),
?STREAM_ERRORT("invalid-id", Lang, Text)).
?STREAM_ERRORT("invalid-id", "", Lang, Text)).
-define(SERRT_INVALID_NAMESPACE(Lang, Text),
?STREAM_ERRORT("invalid-namespace", Lang, Text)).
?STREAM_ERRORT("invalid-namespace", "", Lang, Text)).
-define(SERRT_INVALID_XML(Lang, Text),
?STREAM_ERRORT("invalid-xml", Lang, Text)).
?STREAM_ERRORT("invalid-xml", "", Lang, Text)).
-define(SERRT_NOT_AUTHORIZED(Lang, Text),
?STREAM_ERRORT("not-authorized", Lang, Text)).
?STREAM_ERRORT("not-authorized", "", Lang, Text)).
-define(SERRT_POLICY_VIOLATION(Lang, Text),
?STREAM_ERRORT("policy-violation", Lang, Text)).
?STREAM_ERRORT("policy-violation", "", Lang, Text)).
-define(SERRT_REMOTE_CONNECTION_FAILED(Lang, Text),
?STREAM_ERRORT("remote-connection-failed", Lang, Text)).
?STREAM_ERRORT("remote-connection-failed", "", Lang, Text)).
-define(SERRT_RESOURSE_CONSTRAINT(Lang, Text),
?STREAM_ERRORT("resource-constraint", Lang, Text)).
?STREAM_ERRORT("resource-constraint", "", Lang, Text)).
-define(SERRT_RESTRICTED_XML(Lang, Text),
?STREAM_ERRORT("restricted-xml", Lang, Text)).
% TODO: include hostname or IP
-define(SERRT_SEE_OTHER_HOST(Lang, Text),
?STREAM_ERRORT("see-other-host", Lang, Text)).
?STREAM_ERRORT("restricted-xml", "", Lang, Text)).
-define(SERRT_SEE_OTHER_HOST(Host, Lang, Text),
?STREAM_ERRORT("see-other-host", Host, Lang, Text)).
-define(SERRT_SYSTEM_SHUTDOWN(Lang, Text),
?STREAM_ERRORT("system-shutdown", Lang, Text)).
?STREAM_ERRORT("system-shutdown", "", Lang, Text)).
-define(SERRT_UNSUPPORTED_ENCODING(Lang, Text),
?STREAM_ERRORT("unsupported-encoding", Lang, Text)).
?STREAM_ERRORT("unsupported-encoding", "", Lang, Text)).
-define(SERRT_UNSUPPORTED_STANZA_TYPE(Lang, Text),
?STREAM_ERRORT("unsupported-stanza-type", Lang, Text)).
?STREAM_ERRORT("unsupported-stanza-type", "", Lang, Text)).
-define(SERRT_UNSUPPORTED_VERSION(Lang, Text),
?STREAM_ERRORT("unsupported-version", Lang, Text)).
?STREAM_ERRORT("unsupported-version", "", Lang, Text)).
-define(SERRT_XML_NOT_WELL_FORMED(Lang, Text),
?STREAM_ERRORT("xml-not-well-formed", Lang, Text)).
?STREAM_ERRORT("xml-not-well-formed", "", Lang, Text)).
%-define(SERRT_(Lang, Text),
% ?STREAM_ERRORT("", Lang, Text)).
% ?STREAM_ERRORT("", "", Lang, Text)).
-record(jid, {user, server, resource,

View File

@ -215,14 +215,15 @@ handle_cast({del, Pid}, State) ->
lists:foreach(
fun({_, _, {TRef, {From, To, El}}}) ->
cancel_timer(TRef),
El1 = xml:append_subtags(
El, [{xmlelement, "x", [{"xmlns", ?NS_P1_PUSHED}], []}]),
El1 = xml:remove_subtags(El, "x", {"xmlns", ?NS_P1_PUSHED}),
El2 = xml:append_subtags(
El1, [{xmlelement, "x", [{"xmlns", ?NS_P1_PUSHED}], []}]),
?DEBUG("Resending message:~n"
"** From: ~p~n"
"** To: ~p~n"
"** El: ~p",
[From, To, El1]),
ejabberd_router:route(From, To, El1)
[From, To, El2]),
ejabberd_router:route(From, To, El2)
end, to_list(Pid, State#state.timers)),
Timers = delete(Pid, State#state.timers),
{noreply, State#state{timers = Timers}};

View File

@ -219,6 +219,7 @@ handle_info({route_chan, Channel, Resource,
NewStateData =
case xml:get_attr_s("type", Attrs) of
"unavailable" ->
send_stanza_unavailable(Channel, StateData),
S1 = ?SEND(io_lib:format("PART #~s\r\n", [Channel])),
S1#state{channels =
dict:erase(Channel, S1#state.channels)};
@ -656,13 +657,9 @@ terminate(_Reason, _StateName, FullStateData) ->
bounce_messages("Server Connect Failed"),
lists:foreach(
fun(Chan) ->
ejabberd_router:route(
jlib:make_jid(
lists:concat([Chan, "%", StateData#state.server]),
StateData#state.host, StateData#state.nick),
StateData#state.user,
{xmlelement, "presence", [{"type", "error"}],
[Error]})
Stanza = {xmlelement, "presence", [{"type", "error"}],
[Error]},
send_stanza(Chan, StateData, Stanza)
end, dict:fetch_keys(StateData#state.channels)),
case StateData#state.socket of
undefined ->
@ -672,6 +669,30 @@ terminate(_Reason, _StateName, FullStateData) ->
end,
ok.
send_stanza(Chan, StateData, Stanza) ->
ejabberd_router:route(
jlib:make_jid(
lists:concat([Chan, "%", StateData#state.server]),
StateData#state.host, StateData#state.nick),
StateData#state.user,
Stanza).
send_stanza_unavailable(Chan, StateData) ->
Affiliation = "member", % this is a simplification
Role = "none",
Stanza =
{xmlelement, "presence", [{"type", "unavailable"}],
[{xmlelement, "x", [{"xmlns", ?NS_MUC_USER}],
[{xmlelement, "item",
[{"affiliation", Affiliation},
{"role", Role}],
[]},
{xmlelement, "status",
[{"code", "110"}],
[]}
]}]},
send_stanza(Chan, StateData, Stanza).
%%%----------------------------------------------------------------------
%%% Internal functions
%%%----------------------------------------------------------------------

View File

@ -42,6 +42,7 @@
process_iq_disco_items/4,
broadcast_service_message/2,
register_room/3,
node_up/1,
migrate/1,
get_vh_rooms/1,
can_use_nick/3]).
@ -175,14 +176,33 @@ migrate(After) ->
['$$']}]),
lists:foreach(
fun([NameHost, Pid]) ->
case ejabberd_cluster:get_node_new(NameHost) of
case ejabberd_cluster:get_node(NameHost) of
Node when Node /= node() ->
mod_muc_room:migrate(Pid, Node, After);
mod_muc_room:migrate(Pid, Node, random:uniform(After));
_ ->
ok
end
end, Rs).
node_up(_Node) ->
copy_rooms(mnesia:dirty_first(muc_online_room)).
copy_rooms('$end_of_table') ->
ok;
copy_rooms(Key) ->
case mnesia:dirty_read(muc_online_room, Key) of
[#muc_online_room{name_host = NameHost} = Room] ->
case ejabberd_cluster:get_node_new(NameHost) of
Node when node() /= Node ->
rpc:cast(Node, mnesia, dirty_write, [Room]);
_ ->
ok
end;
_ ->
ok
end,
copy_rooms(mnesia:dirty_next(muc_online_room, Key)).
%%====================================================================
%% gen_server callbacks
%%====================================================================
@ -219,6 +239,7 @@ init([Host, Opts]) ->
DefRoomOpts = gen_mod:get_opt(default_room_options, Opts, []),
RoomShaper = gen_mod:get_opt(room_shaper, Opts, none),
ejabberd_router:register_route(MyHost),
ejabberd_hooks:add(node_up, ?MODULE, node_up, 100),
ejabberd_hooks:add(node_hash_update, ?MODULE, migrate, 100),
load_permanent_rooms(MyHost, Host,
{Access, AccessCreate, AccessAdmin, AccessPersistent},
@ -306,7 +327,15 @@ handle_info({room_destroyed, RoomHost, Pid}, State) ->
mnesia:delete_object(#muc_online_room{name_host = RoomHost,
pid = Pid})
end,
mnesia:sync_dirty(F),
mnesia:async_dirty(F),
case ejabberd_cluster:get_node_new(RoomHost) of
Node when Node /= node() ->
rpc:cast(Node, mnesia, dirty_delete_object,
[#muc_online_room{name_host = RoomHost,
pid = Pid}]);
_ ->
ok
end,
{noreply, State};
handle_info(_Info, State) ->
{noreply, State}.
@ -319,6 +348,7 @@ handle_info(_Info, State) ->
%% The return value is ignored.
%%--------------------------------------------------------------------
terminate(_Reason, State) ->
ejabberd_hooks:delete(node_up, ?MODULE, node_up, 100),
ejabberd_hooks:delete(node_hash_update, ?MODULE, migrate, 100),
ejabberd_router:unregister_route(State#state.host),
ok.
@ -507,14 +537,20 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
AccessCreate, From,
Room) of
true ->
{ok, Pid} = start_new_room(
case start_new_room(
Host, ServerHost, Access,
Room, HistorySize,
RoomShaper, From,
Nick, DefRoomOpts),
register_room(Host, Room, Pid),
Nick, DefRoomOpts) of
{ok, Pid} ->
mod_muc_room:route(Pid, From, Nick, Packet),
register_room(Host, Room, Pid),
ok;
_Err ->
Err = jlib:make_error_reply(
Packet, ?ERR_INTERNAL_SERVER_ERROR),
ejabberd_router:route(To, From, Err)
end;
false ->
Lang = xml:get_attr_s("xml:lang", Attrs),
ErrText = "Room creation is denied by service policy",
@ -603,7 +639,28 @@ register_room(Host, Room, Pid) ->
mnesia:write(#muc_online_room{name_host = {Room, Host},
pid = Pid})
end,
mnesia:sync_dirty(F).
mnesia:async_dirty(F),
case ejabberd_cluster:get_node_new({Room, Host}) of
Node when Node /= node() ->
%% New node has just been added. But we may miss MUC records
%% copy procedure, so we copy the MUC record manually just
%% to make sure
rpc:cast(Node, mnesia, dirty_write,
[#muc_online_room{name_host = {Room, Host},
pid = Pid}]),
case ejabberd_cluster:get_node({Room, Host}) of
Node when node() /= Node ->
%% Migration to new node has completed, and seems like
%% we missed it, so we migrate the MUC room pid manually.
%% It is not a problem if we have already got migration
%% notification: dups are just ignored by the MUC room pid.
mod_muc_room:migrate(Pid, Node, 0);
_ ->
ok
end;
_ ->
ok
end.
iq_disco_info(Lang) ->
[{xmlelement, "identity",

View File

@ -110,7 +110,7 @@ start_link(StateName, StateData) ->
?GEN_FSM:start_link(?MODULE, [StateName, StateData], ?FSMOPTS).
migrate(FsmRef, Node, After) ->
?GEN_FSM:send_all_state_event(FsmRef, {migrate, Node, After}).
erlang:send_after(After, FsmRef, {migrate, Node}).
%%%----------------------------------------------------------------------
%%% Callback functions from gen_fsm
@ -597,9 +597,6 @@ handle_event(destroy, StateName, StateData) ->
handle_event({set_affiliations, Affiliations}, StateName, StateData) ->
{next_state, StateName, StateData#state{affiliations = Affiliations}};
handle_event({migrate, Node, After}, StateName, StateData) when Node /= node() ->
{migrate, StateData,
{Node, ?MODULE, start, [StateName, StateData]}, After * 2};
handle_event(_Event, StateName, StateData) ->
{next_state, StateName, StateData}.
@ -716,6 +713,13 @@ handle_info({captcha_failed, From}, normal_state, StateData) ->
StateData
end,
{next_state, normal_state, NewState};
handle_info({migrate, Node}, StateName, StateData) ->
if Node /= node() ->
{migrate, StateData,
{Node, ?MODULE, start, [StateName, StateData]}, 0};
true ->
{next_state, StateName, StateData}
end;
handle_info(_Info, StateName, StateData) ->
{next_state, StateName, StateData}.
@ -1662,15 +1666,25 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
SID = xml:get_attr_s("id", Attrs),
RoomJID = StateData#state.jid,
To = jlib:jid_replace_resource(RoomJID, Nick),
Limiter = {From#jid.luser, From#jid.lserver},
case ejabberd_captcha:create_captcha(
SID, RoomJID, To, Lang, From) of
SID, RoomJID, To, Lang, Limiter, From) of
{ok, ID, CaptchaEls} ->
MsgPkt = {xmlelement, "message", [{"id", ID}], CaptchaEls},
Robots = ?DICT:store(From,
{Nick, Packet}, StateData#state.robots),
ejabberd_router:route(RoomJID, From, MsgPkt),
StateData#state{robots = Robots};
error ->
{error, limit} ->
ErrText = "Too many CAPTCHA requests",
Err = jlib:make_error_reply(
Packet, ?ERRT_RESOURCE_CONSTRAINT(Lang, ErrText)),
ejabberd_router:route( % TODO: s/Nick/""/
jlib:jid_replace_resource(
StateData#state.jid, Nick),
From, Err),
StateData;
_ ->
ErrText = "Unable to generate a captcha",
Err = jlib:make_error_reply(
Packet, ?ERRT_INTERNAL_SERVER_ERROR(Lang, ErrText)),
@ -1722,7 +1736,24 @@ check_captcha(Affiliation, From, StateData) ->
{ok, passed} ->
true;
_ ->
WList = (StateData#state.config)#config.captcha_whitelist,
#jid{luser = U, lserver = S, lresource = R} = From,
case ?SETS:is_element({U, S, R}, WList) of
true ->
true;
false ->
case ?SETS:is_element({U, S, ""}, WList) of
true ->
true;
false ->
case ?SETS:is_element({"", S, ""}, WList) of
true ->
true;
false ->
captcha_required
end
end
end
end;
_ ->
true
@ -2522,6 +2553,11 @@ can_change_ra(_FAffiliation, _FRole,
%% A room owner tries to add as persistent owner a
%% participant that is already owner because he is MUC admin
true;
can_change_ra(_FAffiliation, _FRole,
_TAffiliation, _TRole,
_RoleorAffiliation, _Value, owner) ->
%% Nobody can decrease MUC admin's role/affiliation
false;
can_change_ra(_FAffiliation, _FRole,
TAffiliation, _TRole,
affiliation, Value, _ServiceAf)
@ -2696,14 +2732,21 @@ send_kickban_presence(JID, Reason, Code, NewAffiliation, StateData) ->
end, LJIDs).
send_kickban_presence1(UJID, Reason, Code, Affiliation, StateData) ->
{ok, #user{jid = _RealJID,
{ok, #user{jid = RealJID,
nick = Nick}} =
?DICT:find(jlib:jid_tolower(UJID), StateData#state.users),
SAffiliation = affiliation_to_list(Affiliation),
BannedJIDString = jlib:jid_to_string(RealJID),
lists:foreach(
fun({_LJID, Info}) ->
JidAttrList = case (Info#user.role == moderator) orelse
((StateData#state.config)#config.anonymous
== false) of
true -> [{"jid", BannedJIDString}];
false -> []
end,
ItemAttrs = [{"affiliation", SAffiliation},
{"role", "none"}],
{"role", "none"}] ++ JidAttrList,
ItemEls = case Reason of
"" ->
[];
@ -2904,6 +2947,13 @@ is_password_settings_correct(XEl, StateData) ->
-define(PRIVATEXFIELD(Label, Var, Val),
?XFIELD("text-private", Label, Var, Val)).
-define(JIDMULTIXFIELD(Label, Var, JIDList),
{xmlelement, "field", [{"type", "jid-multi"},
{"label", translate:translate(Lang, Label)},
{"var", Var}],
[{xmlelement, "value", [], [{xmlcdata, jlib:jid_to_string(JID)}]}
|| JID <- JIDList]}).
get_default_room_maxusers(RoomState) ->
DefRoomOpts = gen_mod:get_module_opt(RoomState#state.server_host, mod_muc, default_room_options, []),
RoomState2 = set_opts(DefRoomOpts, RoomState),
@ -3024,6 +3074,9 @@ get_config(Lang, StateData, From) ->
Config#config.captcha_protected)];
false -> []
end ++
[?JIDMULTIXFIELD("Exclude Jabber IDs from CAPTCHA challenge",
"muc#roomconfig_captcha_whitelist",
?SETS:to_list(Config#config.captcha_whitelist))] ++
case mod_muc_log:check_access_log(
StateData#state.server_host, From) of
allow ->
@ -3093,6 +3146,18 @@ set_config(XEl, StateData) ->
-define(SET_STRING_XOPT(Opt, Val),
set_xoption(Opts, Config#config{Opt = Val})).
-define(SET_JIDMULTI_XOPT(Opt, Vals),
begin
Set = lists:foldl(
fun({U, S, R}, Set1) ->
?SETS:add_element({U, S, R}, Set1);
(#jid{luser = U, lserver = S, lresource = R}, Set1) ->
?SETS:add_element({U, S, R}, Set1);
(_, Set1) ->
Set1
end, ?SETS:empty(), Vals),
set_xoption(Opts, Config#config{Opt = Set})
end).
set_xoption([], Config) ->
Config;
@ -3150,6 +3215,9 @@ set_xoption([{"muc#roomconfig_maxusers", [Val]} | Opts], Config) ->
end;
set_xoption([{"muc#roomconfig_enablelogging", [Val]} | Opts], Config) ->
?SET_BOOL_XOPT(logging, Val);
set_xoption([{"muc#roomconfig_captcha_whitelist", Vals} | Opts], Config) ->
JIDs = [jlib:string_to_jid(Val) || Val <- Vals],
?SET_JIDMULTI_XOPT(captcha_whitelist, JIDs);
set_xoption([{"FORM_TYPE", _} | Opts], Config) ->
%% Ignore our FORM_TYPE
set_xoption(Opts, Config);
@ -3219,6 +3287,7 @@ set_opts([{Opt, Val} | Opts], StateData) ->
password -> StateData#state{config = (StateData#state.config)#config{password = Val}};
anonymous -> StateData#state{config = (StateData#state.config)#config{anonymous = Val}};
logging -> StateData#state{config = (StateData#state.config)#config{logging = Val}};
captcha_whitelist -> StateData#state{config = (StateData#state.config)#config{captcha_whitelist = ?SETS:from_list(Val)}};
max_users ->
ServiceMaxUsers = get_service_max_users(StateData),
MaxUsers = if
@ -3263,6 +3332,8 @@ make_opts(StateData) ->
?MAKE_CONFIG_OPT(anonymous),
?MAKE_CONFIG_OPT(logging),
?MAKE_CONFIG_OPT(max_users),
{captcha_whitelist,
?SETS:to_list((StateData#state.config)#config.captcha_whitelist)},
{affiliations, ?DICT:to_list(StateData#state.affiliations)},
{subject, StateData#state.subject},
{subject_author, StateData#state.subject_author}

View File

@ -45,7 +45,8 @@
password = "",
anonymous = true,
max_users = ?MAX_USERS_DEFAULT,
logging = false
logging = false,
captcha_whitelist = ?SETS:empty()
}).
-record(user, {jid,

View File

@ -95,7 +95,7 @@ init([Host, Opts]) ->
SendPings = gen_mod:get_opt(send_pings, Opts, ?DEFAULT_SEND_PINGS),
PingInterval = gen_mod:get_opt(ping_interval, Opts, ?DEFAULT_PING_INTERVAL),
TimeoutAction = gen_mod:get_opt(timeout_action, Opts, none),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
IQDisc = gen_mod:get_opt(iqdisc, Opts, no_queue),
mod_disco:register_feature(Host, ?NS_PING),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PING,
?MODULE, iq_ping, IQDisc),

View File

@ -751,9 +751,9 @@ item_to_raw(#listitem{type = Type,
none ->
{"n", ""};
jid ->
{"j", jlib:jid_to_string(Value)};
{"j", ejabberd_odbc:escape(jlib:jid_to_string(Value))};
group ->
{"g", Value};
{"g", ejabberd_odbc:escape(Value)};
subscription ->
case Value of
none ->

View File

@ -106,8 +106,10 @@ process_iq(From, To,
PTag = xml:get_subtag(SubEl, "password"),
RTag = xml:get_subtag(SubEl, "remove"),
Server = To#jid.lserver,
Access = gen_mod:get_module_opt(Server, ?MODULE, access, all),
AllowRemove = (allow == acl:match_rule(Server, Access, From)),
if
(UTag /= false) and (RTag /= false) ->
(UTag /= false) and (RTag /= false) and AllowRemove ->
User = xml:get_tag_cdata(UTag),
case From of
#jid{user = User, lserver = Server} ->
@ -148,7 +150,7 @@ process_iq(From, To,
sub_el = [SubEl, ?ERR_BAD_REQUEST]}
end
end;
(UTag == false) and (RTag /= false) ->
(UTag == false) and (RTag /= false) and AllowRemove ->
case From of
#jid{user = User,
lserver = Server,
@ -234,13 +236,18 @@ process_iq(From, To,
{"var", "password"}],
[{xmlelement, "required", [], []}]},
case ejabberd_captcha:create_captcha_x(
ID, To, Lang, [InstrEl, UField, PField]) of
ID, To, Lang, Source, [InstrEl, UField, PField]) of
{ok, CaptchaEls} ->
IQ#iq{type = result,
sub_el = [{xmlelement, "query",
[{"xmlns", "jabber:iq:register"}],
[TopInstrEl | CaptchaEls]}]};
error ->
{error, limit} ->
ErrText = "Too many CAPTCHA requests",
IQ#iq{type = error,
sub_el = [SubEl, ?ERRT_RESOURCE_CONSTRAINT(
Lang, ErrText)]};
_Err ->
ErrText = "Unable to generate a CAPTCHA",
IQ#iq{type = error,
sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(

View File

@ -161,7 +161,7 @@ get_versioning_feature(Acc, Host) ->
Feature = {xmlelement,
"ver",
[{"xmlns", ?NS_ROSTER_VER}],
[{xmlelement, "optional", [], []}]},
[]},
[Feature | Acc];
false -> []
end.
@ -411,10 +411,17 @@ push_item(User, Server, From, Item) ->
% TODO: don't push to those who didn't load roster
push_item(User, Server, Resource, From, Item) ->
push_item(User, Server, Resource, From, Item, not_found).
push_item(User, Server, Resource, From, Item, RosterVersion) ->
ExtraAttrs = case RosterVersion of
not_found -> [];
_ -> [{"ver", RosterVersion}]
end,
ResIQ = #iq{type = set, xmlns = ?NS_ROSTER,
id = "push" ++ randoms:get_string(),
sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_ROSTER}],
[{"xmlns", ?NS_ROSTER}|ExtraAttrs],
[item_to_xml(Item)]}]},
ejabberd_router:route(
From,
@ -425,21 +432,9 @@ push_item(User, Server, Resource, From, Item) ->
%% TODO: don't push to those who didn't load roster
push_item_version(Server, User, From, Item, RosterVersion) ->
lists:foreach(fun(Resource) ->
push_item_version(User, Server, Resource, From, Item, RosterVersion)
push_item(User, Server, Resource, From, Item, RosterVersion)
end, ejabberd_sm:get_user_resources(User, Server)).
push_item_version(User, Server, Resource, From, Item, RosterVersion) ->
IQPush = #iq{type = 'set', xmlns = ?NS_ROSTER,
id = "push" ++ randoms:get_string(),
sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_ROSTER},
{"ver", RosterVersion}],
[item_to_xml(Item)]}]},
ejabberd_router:route(
From,
jlib:make_jid(User, Server, Resource),
jlib:iq_to_xml(IQPush)).
get_subscription_lists(_, User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),

View File

@ -37,6 +37,8 @@
process_item/2,
in_subscription/6,
out_subscription/4,
user_available/1,
unset_presence/4,
register_user/2,
remove_user/2,
list_groups/1,
@ -85,6 +87,10 @@ start(Host, _Opts) ->
?MODULE, get_jid_info, 70),
ejabberd_hooks:add(roster_process_item, Host,
?MODULE, process_item, 50),
ejabberd_hooks:add(user_available_hook, Host,
?MODULE, user_available, 50),
ejabberd_hooks:add(unset_presence_hook, Host,
?MODULE, unset_presence, 50),
ejabberd_hooks:add(register_user, Host,
?MODULE, register_user, 50),
ejabberd_hooks:add(remove_user, Host,
@ -109,6 +115,10 @@ stop(Host) ->
?MODULE, get_jid_info, 70),
ejabberd_hooks:delete(roster_process_item, Host,
?MODULE, process_item, 50),
ejabberd_hooks:delete(user_available_hook, Host,
?MODULE, user_available, 50),
ejabberd_hooks:delete(unset_presence_hook, Host,
?MODULE, unset_presence, 50),
ejabberd_hooks:delete(register_user, Host,
?MODULE, register_user, 50),
ejabberd_hooks:delete(remove_user, Host,
@ -470,21 +480,38 @@ get_group_opt(Host, Group, Opt, Default) ->
Default
end.
get_online_users(Host) ->
lists:usort([{U, S} || {U, S, _} <- ejabberd_sm:get_vh_session_list(Host)]).
get_group_users(Host, Group) ->
case get_group_opt(Host, Group, all_users, false) of
true ->
ejabberd_auth:get_vh_registered_users(Host);
false ->
[]
end ++ get_group_explicit_users(Host, Group).
end ++
case get_group_opt(Host, Group, online_users, false) of
true ->
get_online_users(Host);
false ->
[]
end ++
get_group_explicit_users(Host, Group).
get_group_users(_User, Host, Group, GroupOpts) ->
get_group_users(Host, Group, GroupOpts) ->
case proplists:get_value(all_users, GroupOpts, false) of
true ->
ejabberd_auth:get_vh_registered_users(Host);
false ->
[]
end ++ get_group_explicit_users(Host, Group).
end ++
case proplists:get_value(online_users, GroupOpts, false) of
true ->
get_online_users(Host);
false ->
[]
end ++
get_group_explicit_users(Host, Group).
%% @spec (Host::string(), Group::string()) -> [{User::string(), Server::string()}]
get_group_explicit_users(Host, Group) ->
@ -502,11 +529,20 @@ get_group_explicit_users(Host, Group) ->
get_group_name(Host, Group) ->
get_group_opt(Host, Group, name, Group).
%% Get list of names of groups that have @all@ in the memberlist
%% Get list of names of groups that have @all@/@online@/etc in the memberlist
get_special_users_groups(Host) ->
lists:filter(
fun(Group) ->
get_group_opt(Host, Group, all_users, false)
orelse get_group_opt(Host, Group, online_users, false)
end,
list_groups(Host)).
%% Get list of names of groups that have @online@ in the memberlist
get_special_users_groups_online(Host) ->
lists:filter(
fun(Group) ->
get_group_opt(Host, Group, online_users, false)
end,
list_groups(Host)).
@ -661,7 +697,7 @@ push_user_to_members(User, Server, Subscription) ->
lists:foreach(
fun({U, S}) ->
push_roster_item(U, S, LUser, LServer, GroupName, Subscription)
end, get_group_users(LUser, LServer, Group, GroupOpts))
end, get_group_users(LServer, Group, GroupOpts))
end, lists:usort(SpecialGroups++UserGroups)).
push_user_to_displayed(LUser, LServer, Group, Subscription) ->
@ -673,7 +709,8 @@ push_user_to_displayed(LUser, LServer, Group, Subscription) ->
push_user_to_group(LUser, LServer, Group, GroupName, Subscription) ->
lists:foreach(
fun({U, S}) ->
fun({U, S}) when (U == LUser) and (S == LServer) -> ok;
({U, S}) ->
push_roster_item(U, S, LUser, LServer, GroupName, Subscription)
end, get_group_users(LServer, Group)).
@ -757,6 +794,51 @@ ask_to_pending(subscribe) -> out;
ask_to_pending(unsubscribe) -> none;
ask_to_pending(Ask) -> Ask.
user_available(New) ->
LUser = New#jid.luser,
LServer = New#jid.lserver,
Resources = ejabberd_sm:get_user_resources(LUser, LServer),
?DEBUG("user_available for ~p @ ~p (~p resources)",
[LUser, LServer, length(Resources)]),
case length(Resources) of
%% first session for this user
1 ->
%% This is a simplification - we ignore he 'display'
%% property - @online@ is always reflective.
OnlineGroups = get_special_users_groups_online(LServer),
lists:foreach(
fun(OG) ->
?DEBUG("user_available: pushing ~p @ ~p grp ~p",
[LUser, LServer, OG ]),
push_user_to_displayed(LUser, LServer, OG, both)
end, OnlineGroups);
_ ->
ok
end.
unset_presence(LUser, LServer, Resource, Status) ->
Resources = ejabberd_sm:get_user_resources(LUser, LServer),
?DEBUG("unset_presence for ~p @ ~p / ~p -> ~p (~p resources)",
[LUser, LServer, Resource, Status, length(Resources)]),
%% if user has no resources left...
case length(Resources) of
0 ->
%% This is a simplification - we ignore he 'display'
%% property - @online@ is always reflective.
OnlineGroups = get_special_users_groups_online(LServer),
%% for each of these groups...
lists:foreach(
fun(OG) ->
%% Push removal of the old user to members of groups
%% where the group that this uwas members was displayed
push_user_to_displayed(LUser, LServer, OG, remove),
%% Push removal of members of groups that where
%% displayed to the group which thiuser has left
push_displayed_to_user(LUser, LServer, OG, LServer,remove)
end, OnlineGroups);
_ ->
ok
end.
%%---------------------
%% Web Admin
@ -860,6 +942,7 @@ shared_roster_group(Host, Group, Query, Lang) ->
Name = get_opt(GroupOpts, name, ""),
Description = get_opt(GroupOpts, description, ""),
AllUsers = get_opt(GroupOpts, all_users, false),
OnlineUsers = get_opt(GroupOpts, online_users, false),
%%Disabled = false,
DisplayedGroups = get_opt(GroupOpts, displayed_groups, []),
Members = mod_shared_roster:get_group_explicit_users(Host, Group),
@ -869,7 +952,14 @@ shared_roster_group(Host, Group, Query, Lang) ->
"@all@\n";
true ->
[]
end ++ [[us_to_list(Member), $\n] || Member <- Members],
end ++
if
OnlineUsers ->
"@online@\n";
true ->
[]
end ++
[[us_to_list(Member), $\n] || Member <- Members],
FDisplayedGroups = [[DG, $\n] || DG <- DisplayedGroups],
DescNL = length(element(2, regexp:split(Description, "\n"))),
FGroup =
@ -953,6 +1043,8 @@ shared_roster_group_parse_query(Host, Group, Query) ->
case SJID of
"@all@" ->
USs;
"@online@" ->
USs;
_ ->
case jlib:string_to_jid(SJID) of
JID when is_record(JID, jid) ->
@ -967,10 +1059,15 @@ shared_roster_group_parse_query(Host, Group, Query) ->
true -> [{all_users, true}];
false -> []
end,
OnlineUsersOpt =
case lists:member("@online@", SJIDs) of
true -> [{online_users, true}];
false -> []
end,
mod_shared_roster:set_group_opts(
Host, Group,
NameOpt ++ DispGroupsOpt ++ DescriptionOpt ++ AllUsersOpt),
NameOpt ++ DispGroupsOpt ++ DescriptionOpt ++ AllUsersOpt ++ OnlineUsersOpt),
if
NewMembers == error -> error;

View File

@ -77,7 +77,6 @@
{"ejabberd Publish-Subscribe module","Mòdul ejannerd Publicar-Subscriure"}.
{"ejabberd SOCKS5 Bytestreams module","mòdul ejabberd SOCKS5 Bytestreams"}.
{"ejabberd vCard module","Mòdul ejabberd vCard"}.
{"ejabberd virtual hosts","Hosts virtuals del ejabberd"}.
{"ejabberd Web Admin","Web d'administració del ejabberd"}.
{"Elements","Elements"}.
{"Email","Email"}.
@ -362,6 +361,7 @@
{"User","Usuari"}.
{"Validate","Validar"}.
{"vCard User Search","Recerca de vCard d'usuari"}.
{"Virtual Hosts","Hosts virtuals"}.
{"Visitors are not allowed to change their nicknames in this room","Els visitants no tenen permés canviar el seus Nicknames en esta sala"}.
{"Visitors are not allowed to send messages to all occupants","Els visitants no poden enviar missatges a tots els ocupants"}.
{"Wednesday","Dimecres"}.

View File

@ -1365,8 +1365,8 @@ msgid "~s access rule configuration"
msgstr "Configuració de les Regles d'Accés ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "Hosts virtuals del ejabberd"
msgid "Virtual Hosts"
msgstr "Hosts virtuals"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -80,7 +80,6 @@
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe modul"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams modul"}.
{"ejabberd vCard module","ejabberd vCard modul"}.
{"ejabberd virtual hosts","Virtuální hostitelé ejabberd"}.
{"ejabberd Web Admin","Webová administrace ejabberd"}.
{"Elements","Položek"}.
{"Email","E-mail"}.
@ -388,6 +387,7 @@
{"User","Uživatel"}.
{"Validate","Ověřit"}.
{"vCard User Search","Hledání uživatelů podle vizitek"}.
{"Virtual Hosts","Virtuální hostitelé"}.
{"Visitors are not allowed to change their nicknames in this room","Návštěvníkům této místnosti je zakázáno měnit přezdívku"}.
{"Visitors are not allowed to send messages to all occupants","Návštevníci nemají povoleno zasílat zprávy všem účastníkům konference"}.
{"Wednesday","Středa"}.

View File

@ -1345,8 +1345,8 @@ msgid "~s access rule configuration"
msgstr "~s konfigurace pravidla přístupu"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "Virtuální hostitelé ejabberd"
msgid "Virtual Hosts"
msgstr "Virtuální hostitelé"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -80,7 +80,6 @@
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe-Modul"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5-Bytestreams-Modul"}.
{"ejabberd vCard module","ejabberd vCard-Modul"}.
{"ejabberd virtual hosts","ejabberd virtuelle Hosts"}.
{"ejabberd Web Admin","ejabberd Web-Admin"}.
{"Elements","Elemente"}.
{"Email","E-Mail"}.
@ -388,6 +387,7 @@
{"Users Last Activity","Letzte Benutzeraktivität"}.
{"Validate","Validieren"}.
{"vCard User Search","vCard-Benutzer-Suche"}.
{"Virtual Hosts","Virtuelle Hosts"}.
{"Visitors are not allowed to change their nicknames in this room","Besucher dürfen in diesem Raum ihren Benutzernamen nicht ändern"}.
{"Visitors are not allowed to send messages to all occupants","Besucher dürfen nicht an alle Teilnehmer Nachrichten verschicken"}.
{"Wednesday","Mittwoch"}.

View File

@ -1378,8 +1378,8 @@ msgid "~s access rule configuration"
msgstr "~s Zugangsregel-Konfiguration"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "ejabberd virtuelle Hosts"
msgid "Virtual Hosts"
msgstr "Virtuelle Hosts"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -1329,7 +1329,7 @@ msgid "~s access rule configuration"
msgstr ""
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgid "Virtual Hosts"
msgstr ""
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046

View File

@ -80,7 +80,6 @@
{"ejabberd Publish-Subscribe module","ejabberd module Δημοσίευσης-Εγγραφής"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}.
{"ejabberd vCard module","ejabberd vCard module"}.
{"ejabberd virtual hosts","εικονικοί κεντρικοί υπολογιστές ejabberd"}.
{"ejabberd Web Admin","ejabberd Web Admin"}.
{"Elements","Στοιχεία"}.
{"Email","Email"}.
@ -388,6 +387,7 @@
{"User","Χρήστης"}.
{"Validate","Επαληθεύστε"}.
{"vCard User Search","vCard Αναζήτηση χρηστών"}.
{"Virtual Hosts","εικονικοί κεντρικοί υπολογιστές"}.
{"Visitors are not allowed to change their nicknames in this room","Οι επισκέπτες δεν επιτρέπεται να αλλάξουν τα ψευδώνυμα τους σε αυτή την αίθουσα"}.
{"Visitors are not allowed to send messages to all occupants","Οι επισκέπτες δεν επιτρέπεται να στείλουν μηνύματα σε όλους τους συμμετέχωντες"}.
{"Wednesday","Τετάρτη"}.

View File

@ -1382,8 +1382,8 @@ msgid "~s access rule configuration"
msgstr "~s διαμόρφωση κανόνα πρόσβασης"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "εικονικοί κεντρικοί υπολογιστές ejabberd"
msgid "Virtual Hosts"
msgstr "εικονικοί κεντρικοί υπολογιστές"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -77,7 +77,6 @@
{"ejabberd Publish-Subscribe module","ejabberd Public-Abonada modulo"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bajtfluo modulo"}.
{"ejabberd vCard module","ejabberd vCard-modulo"}.
{"ejabberd virtual hosts","ejabberd virtual-gastigoj"}.
{"ejabberd Web Admin","ejabberd Teksaĵa Administro"}.
{"Elements","Eroj"}.
{"Email","Retpoŝto"}.
@ -362,6 +361,7 @@
{"User","Uzanto"}.
{"Validate","Validigu"}.
{"vCard User Search","Serĉado de vizitkartoj"}.
{"Virtual Hosts","Virtual-gastigoj"}.
{"Visitors are not allowed to change their nicknames in this room","Ne estas permesata al vizitantoj ŝanĝi siajn kaŝnomojn en ĉi tiu ĉambro"}.
{"Visitors are not allowed to send messages to all occupants","Vizitantoj ne rajtas sendi mesaĝojn al ĉiuj partoprenantoj"}.
{"Wednesday","Merkredo"}.

View File

@ -1359,8 +1359,8 @@ msgid "~s access rule configuration"
msgstr "Agordo de atingo-reguloj de ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "ejabberd virtual-gastigoj"
msgid "Virtual Hosts"
msgstr "Virtual-gastigoj"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"
@ -1789,9 +1789,6 @@ msgstr ""
#~ msgid "(Raw)"
#~ msgstr "(Kruda)"
#~ msgid "Virtual Hosts"
#~ msgstr "Virtual-gastigoj"
#~ msgid "Specified nickname is already registered"
#~ msgstr "Donita kaŝnomo jam estas registrita"

View File

@ -80,7 +80,6 @@
{"ejabberd Publish-Subscribe module","Módulo de Publicar-Subscribir de ejabberd"}.
{"ejabberd SOCKS5 Bytestreams module","Módulo SOCKS5 Bytestreams para ejabberd"}.
{"ejabberd vCard module","Módulo vCard para ejabberd"}.
{"ejabberd virtual hosts","Dominios de ejabberd"}.
{"ejabberd Web Admin","ejabberd Web Admin"}.
{"Elements","Elementos"}.
{"Email","correo"}.
@ -388,6 +387,7 @@
{"User","Usuario"}.
{"Validate","Validar"}.
{"vCard User Search","Buscar vCard de usuario"}.
{"Virtual Hosts","Dominios Virtuales"}.
{"Visitors are not allowed to change their nicknames in this room","Los visitantes no tienen permitido cambiar sus apodos en esta sala"}.
{"Visitors are not allowed to send messages to all occupants","Los visitantes no pueden enviar mensajes a todos los ocupantes"}.
{"Wednesday","miércoles"}.

View File

@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: es\n"
"PO-Revision-Date: 2010-11-19 13:40+0100\n"
"Last-Translator: \n"
"Last-Translator: Badlop <badlop@process-one.net>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -1367,8 +1367,8 @@ msgid "~s access rule configuration"
msgstr "Configuración de las Regla de Acceso ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "Dominios de ejabberd"
msgid "Virtual Hosts"
msgstr "Dominios Virtuales"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -80,7 +80,6 @@
{"ejabberd Publish-Subscribe module","Module Publish-Subscribe d'ejabberd"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}.
{"ejabberd vCard module","Module vCard ejabberd"}.
{"ejabberd virtual hosts","Serveurs virtuels d'ejabberd"}.
{"ejabberd Web Admin","Console Web d'administration de ejabberd"}.
{"Elements","Éléments"}.
{"Email","Email"}.
@ -388,6 +387,7 @@
{"User","Utilisateur"}.
{"Validate","Valider"}.
{"vCard User Search","Recherche dans l'annnuaire"}.
{"Virtual Hosts","Serveurs virtuels"}.
{"Visitors are not allowed to change their nicknames in this room","Les visiteurs ne sont pas autorisés à changer de pseudo dans ce salon"}.
{"Visitors are not allowed to send messages to all occupants","Les visiteurs ne sont pas autorisés à envoyer des messages à tout les occupants"}.
{"Wednesday","Mercredi"}.

View File

@ -1381,8 +1381,8 @@ msgid "~s access rule configuration"
msgstr "Configuration des règles d'accès ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "Serveurs virtuels d'ejabberd"
msgid "Virtual Hosts"
msgstr "Serveurs virtuels"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"
@ -1824,6 +1824,3 @@ msgstr "Effacer"
#~ msgid "(Raw)"
#~ msgstr "(Brut)"
#~ msgid "Virtual Hosts"
#~ msgstr "Serveurs virtuels"

View File

@ -73,7 +73,6 @@
{"ejabberd Publish-Subscribe module","Módulo de Publicar-Subscribir de ejabberd"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}.
{"ejabberd vCard module","Módulo vCard para ejabberd"}.
{"ejabberd virtual hosts","Hosts virtuais de ejabberd"}.
{"ejabberd Web Admin","Ejabberd Administrador Web"}.
{"Elements","Elementos"}.
{"Email","Email"}.
@ -356,6 +355,7 @@
{"User","Usuario"}.
{"Validate","Validar"}.
{"vCard User Search","Procura de usuario en vCard"}.
{"Virtual Hosts","Hosts Virtuais"}.
{"Visitors are not allowed to change their nicknames in this room","Os visitantes non están autorizados a cambiar os seus That alcumes nesta sala"}.
{"Visitors are not allowed to send messages to all occupants","Os visitantes non poden enviar mensaxes a todos os ocupantes"}.
{"Wednesday","Mércores"}.

View File

@ -1370,8 +1370,8 @@ msgid "~s access rule configuration"
msgstr "Configuración das Regra de Acceso ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "Hosts virtuais de ejabberd"
msgid "Virtual Hosts"
msgstr "Hosts Virtuais"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"
@ -1805,9 +1805,6 @@ msgstr ""
#~ msgid "(Raw)"
#~ msgstr "(Cru)"
#~ msgid "Virtual Hosts"
#~ msgstr "Hosts Virtuais"
#~ msgid "Specified nickname is already registered"
#~ msgstr "O alcume especificado xa está rexistrado, terás que buscar outro"

408
src/msgs/id.msg Normal file
View File

@ -0,0 +1,408 @@
{"Access Configuration","Akses Konfigurasi"}.
{"Access Control List Configuration","Konfigurasi Daftar Akses Pengendalian"}.
{"Access Control Lists","Akses Daftar Pengendalian"}.
{"Access control lists","Daftar Pengendalian Akses"}.
{"Access denied by service policy","Akses ditolak oleh kebijakan layanan"}.
{"Access rules","Akses peraturan"}.
{"Access Rules","Aturan Akses"}.
{"Action on user","Tindakan pada pengguna"}.
{"Add Jabber ID","Tambah Jabber ID"}.
{"Add New","Tambah Baru"}.
{"Add User","Tambah Pengguna"}.
{"Administration","Administrasi"}.
{"Administration of ","Administrasi"}.
{"Administrator privileges required","Hak istimewa Administrator dibutuhkan"}.
{"A friendly name for the node","Nama yang dikenal untuk node"}.
{"All activity","Semua aktifitas"}.
{"Allow this Jabber ID to subscribe to this pubsub node?","Izinkan ID Jabber ini untuk berlangganan pada node pubsub ini?"}.
{"Allow users to change the subject","Perbolehkan pengguna untuk mengganti topik"}.
{"Allow users to query other users","Perbolehkan pengguna untuk mengetahui pengguna lain"}.
{"Allow users to send invites","Perbolehkan pengguna mengirimkan undangan"}.
{"Allow users to send private messages","perbolehkan pengguna mengirimkan pesan ke pengguna lain secara pribadi"}.
{"Allow visitors to change nickname","Perbolehkan visitor mengganti nama julukan"}.
{"Allow visitors to send status text in presence updates","Izinkan pengunjung untuk mengirim teks status terbaru"}.
{"All Users","Semua Pengguna"}.
{"Announcements","Pengumuman"}.
{"anyone","Siapapun"}.
{"A password is required to enter this room","Diperlukan kata sandi untuk masuk ruangan ini"}.
{"April","April"}.
{"August","Agustus"}.
{"Backup","Backup"}.
{"Backup Management","Manajemen Backup"}.
{"Backup of ","Cadangan dari"}.
{"Backup to File at ","Backup ke File pada"}.
{"Bad format","Format yang buruk"}.
{"Birthday","Hari Lahir"}.
{"CAPTCHA web page","CAPTCHA laman web"}.
{"Change Password","Ubah Kata Sandi"}.
{"Change User Password","Ubah User Password"}.
{"Characters not allowed:","Karakter tidak diperbolehkan:"}.
{"Chatroom configuration modified","Konfigurasi ruang chat diubah"}.
{"Chatroom is created","Ruang chat telah dibuat"}.
{"Chatroom is destroyed","Ruang chat dilenyapkan"}.
{"Chatroom is started","Ruang chat dimulai"}.
{"Chatroom is stopped","Ruang chat dihentikan"}.
{"Chatrooms","Ruangan Chat"}.
{"Choose a username and password to register with this server","Pilih nama pengguna dan kata sandi untuk mendaftar dengan layanan ini"}.
{"Choose modules to stop","Pilih Modul untuk berhenti"}.
{"Choose storage type of tables","Pilih jenis penyimpanan tabel"}.
{"Choose whether to approve this entity's subscription.","Pilih apakah akan menyetujui hubungan pertemanan ini."}.
{"City","Kota"}.
{"Commands","Perintah"}.
{"Conference room does not exist","Ruang Konferensi tidak ada"}.
{"Configuration of room ~s","Pengaturan ruangan ~s"}.
{"Configuration","Pengaturan"}.
{"Connected Resources:","Sumber Daya Terhubung:"}.
{"Connections parameters","Parameter Koneksi"}.
{"Country","Negara"}.
{"CPU Time:","Waktu CPU:"}.
{"Database","Database"}.
{"Database Tables at ","Tabel Database pada"}.
{"Database Tables Configuration at ","Database Tabel Konfigurasi pada"}.
{"December","Desember"}.
{"Default users as participants","pengguna pertama kali masuk sebagai participant"}.
{"Delete","Hapus"}.
{"Delete message of the day","Hapus pesan harian"}.
{"Delete message of the day on all hosts","Hapus pesan harian pada semua host"}.
{"Delete Selected","Hapus Yang Terpilih"}.
{"Delete User","Hapus Pengguna"}.
{"Deliver event notifications","Memberikan pemberitahuan acara"}.
{"Deliver payloads with event notifications","Memberikan muatan dengan pemberitahuan acara"}.
{"Description:","Keterangan:"}.
{"Disc only copy","Hanya salinan dari disc"}.
{"Displayed Groups:","Tampilkan Grup:"}.
{"Don't tell your password to anybody, not even the administrators of the Jabber server.","Jangan memberitahukan kata sandi Anda ke siapapun, bahkan para administrator dari layanan Jabber."}.
{"Dump Backup to Text File at ","Dump Backup ke File Teks di"}.
{"Dump to Text File","Dump menjadi File Teks"}.
{"Edit Properties","Ganti Properti"}.
{"ejabberd IRC module","ejabberd IRC modul"}.
{"ejabberd MUC module","ejabberd MUC Module"}.
{"ejabberd Publish-Subscribe module","Modul ejabberd Setujui-Pertemanan"}.
{"ejabberd SOCKS5 Bytestreams module","modul ejabberd SOCKS5 Bytestreams"}.
{"ejabberd vCard module","Modul ejabberd vCard"}.
{"ejabberd Web Admin","Admin Web ejabberd"}.
{"Elements","Elemen-elemen"}.
{"Email","Email"}.
{"Enable logging","Aktifkan catatan"}.
{"Encoding for server ~b","Pengkodean untuk layanan ~b"}.
{"End User Session","Akhir Sesi Pengguna"}.
{"Enter list of {Module, [Options]}","Masukkan daftar {Modul, [Options]}"}.
{"Enter nickname you want to register","Masukkan nama julukan Anda jika ingin mendaftar"}.
{"Enter path to backup file","Masukkan path untuk file cadangan"}.
{"Enter path to jabberd14 spool dir","Masukkan path ke direktori spool jabberd14"}.
{"Enter path to jabberd14 spool file","Masukkan path ke file jabberd14 spool"}.
{"Enter path to text file","Masukkan path ke file teks"}.
{"Enter the text you see","Masukkan teks yang Anda lihat"}.
{"Enter username and encodings you wish to use for connecting to IRC servers. Press 'Next' to get more fields to fill in. Press 'Complete' to save settings.","Masukkan username dan pengkodean yang ingin Anda gunakan untuk menghubungkan ke layanan IRC. Tekan 'Selanjutnya' untuk mendapatkan lagi formulir kemudian Tekan 'Lengkap' untuk menyimpan pengaturan."}.
{"Enter username, encodings, ports and passwords you wish to use for connecting to IRC servers","Masukkan username, pengkodean, port dan sandi yang ingin Anda gunakan untuk menghubungkan ke layanan IRC"}.
{"Erlang Jabber Server","Layanan Erlang Jabber"}.
{"Error","Kesalahan"}.
{"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}].","Contoh: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef.net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]."}.
{"Export data of all users in the server to PIEFXIS files (XEP-0227):","Ekspor data dari semua pengguna pada layanan ke berkas PIEFXIS (XEP-0227):"}.
{"Export data of users in a host to PIEFXIS files (XEP-0227):","Ekspor data pengguna pada sebuah host ke berkas PIEFXIS (XEP-0227):"}.
{"Family Name","Nama Keluarga (marga)"}.
{"February","Februari"}.
{"Fill in fields to search for any matching Jabber User","Isi kolom untuk mencari pengguna Jabber yang sama"}.
{"Fill in the form to search for any matching Jabber User (Add * to the end of field to match substring)","Isi formulir untuk pencarian pengguna Jabber yang cocok (Tambahkan * ke mengakhiri pengisian untuk menyamakan kata)"}.
{"Friday","Jumat"}.
{"From","Dari"}.
{"From ~s","Dari ~s"}.
{"Full Name","Nama Lengkap"}.
{"Get Number of Online Users","Dapatkan Jumlah User Yang Online"}.
{"Get Number of Registered Users","Dapatkan Jumlah Pengguna Yang Terdaftar"}.
{"Get User Last Login Time","Dapatkan Waktu Login Terakhir Pengguna "}.
{"Get User Password","Dapatkan User Password"}.
{"Get User Statistics","Dapatkan Statistik Pengguna"}.
{"Group ","Grup"}.
{"Groups","Grup"}.
{"has been banned","telah dibanned"}.
{"has been kicked because of an affiliation change","telah dikick karena perubahan afiliasi"}.
{"has been kicked because of a system shutdown","telah dikick karena sistem shutdown"}.
{"has been kicked because the room has been changed to members-only","telah dikick karena ruangan telah diubah menjadi hanya untuk member"}.
{"has been kicked","telah dikick"}.
{" has set the subject to: ","telah menetapkan topik yaitu:"}.
{"Host","Host"}.
{"If you don't see the CAPTCHA image here, visit the web page.","Jika Anda tidak melihat gambar CAPTCHA disini, silahkan kunjungi halaman web."}.
{"If you want to specify different ports, passwords, encodings for IRC servers, fill this list with values in format '{\"irc server\", \"encoding\", port, \"password\"}'. By default this service use \"~s\" encoding, port ~p, empty password.","Jika Anda ingin menentukan port yang berbeda, sandi, pengkodean untuk layanan IRC, isi daftar ini dengan nilai-nilai dalam format '{\"server irc \", \"encoding \", port, \"sandi \"}'. Secara default ini menggunakan layanan \"~s \" pengkodean, port ~p, kata sandi kosong."}.
{"Import Directory","Impor Direktori"}.
{"Import File","Impor File"}.
{"Import user data from jabberd14 spool file:","Impor data pengguna dari sekumpulan berkas jabberd14:"}.
{"Import User from File at ","Impor Pengguna dari File pada"}.
{"Import users data from a PIEFXIS file (XEP-0227):","impor data-data pengguna dari sebuah PIEFXIS (XEP-0227):"}.
{"Import users data from jabberd14 spool directory:","Импорт пользовательских данных из буферной директории jabberd14:"}.
{"Import Users from Dir at ","Impor Pengguna dari Dir di"}.
{"Import Users From jabberd14 Spool Files","Impor Pengguna Dari jabberd14 Spool File"}.
{"Improper message type","Jenis pesan yang tidak benar"}.
{"Incorrect password","Kata sandi salah"}.
{"Invalid affiliation: ~s","Afiliasi tidak valid: ~s"}.
{"Invalid role: ~s","Peran tidak valid: ~s"}.
{"IP addresses","Alamat IP"}.
{"IP","IP"}.
{"IRC channel (don't put the first #)","Channel IRC (tidak perlu menempatkan # sebelumnya)"}.
{"IRC server","Layanan IRC"}.
{"IRC settings","Pengaturan IRC"}.
{"IRC Transport","IRC Transport"}.
{"IRC username","Nama Pengguna IRC"}.
{"IRC Username","Nama Pengguna IRC"}.
{"is now known as","sekarang dikenal sebagai"}.
{"It is not allowed to send private messages","Hal ini tidak diperbolehkan untuk mengirim pesan pribadi"}.
{"It is not allowed to send private messages of type \"groupchat\"","Hal ini tidak diperbolehkan untuk mengirim pesan pribadi jenis \"groupchat \""}.
{"It is not allowed to send private messages to the conference","Hal ini tidak diperbolehkan untuk mengirim pesan pribadi ke konferensi"}.
{"Jabber Account Registration","Pendaftaran Akun Jabber"}.
{"Jabber ID","Jabber ID"}.
{"Jabber ID ~s is invalid","Jabber ID ~s tidak valid"}.
{"January","Januari"}.
{"Join IRC channel","Gabung channel IRC"}.
{"joins the room","bergabung ke ruangan"}.
{"Join the IRC channel here.","Gabung ke channel IRC disini"}.
{"Join the IRC channel in this Jabber ID: ~s","Gabung ke channel IRC dengan Jabber ID: ~s"}.
{"July","Juli"}.
{"June","Juni"}.
{"Last Activity","Aktifitas Terakhir"}.
{"Last login","Terakhir Login"}.
{"Last month","Akhir bulan"}.
{"Last year","Akhir tahun"}.
{"leaves the room","meninggalkan ruangan"}.
{"Listened Ports at ","Mendeteksi Port-port di"}.
{"Listened Ports","Port Terdeteksi"}.
{"List of modules to start","Daftar modul untuk memulai"}.
{"Low level update script","Perbaruan naskah tingkat rendah"}.
{"Make participants list public","Buat daftar participant diketahui oleh public"}.
{"Make room captcha protected","Buat ruangan dilindungi dengan chapta"}.
{"Make room members-only","Buat ruangan hanya untuk member saja"}.
{"Make room moderated","Buat ruangan hanya untuk moderator saja"}.
{"Make room password protected","Buat ruangan yang dilindungi dengan kata sandi"}.
{"Make room persistent","Buat ruangan menjadi permanent"}.
{"Make room public searchable","Buat ruangan dapat dicari"}.
{"March","Maret"}.
{"Maximum Number of Occupants","Maksimum Jumlah Penghuni"}.
{"Max # of items to persist","Max item untuk bertahan"}.
{"Max payload size in bytes","Max kapasitas ukuran dalam bytes"}.
{"May","Mei"}.
{"Members:","Anggota:"}.
{"Membership is required to enter this room","Hanya Member yang dapat masuk ruangan ini"}.
{"Memorize your password, or write it in a paper placed in a safe place. In Jabber there isn't an automated way to recover your password if you forget it.","Hafalkan kata sandi Anda, atau dicatat dan letakkan di tempat yang aman. Didalam Jabber tidak ada cara otomatis untuk mendapatkan kembali password Anda jika Anda lupa."}.
{"Memory","Memori"}.
{"Message body","Isi Pesan"}.
{"Middle Name","Nama Tengah"}.
{"Moderator privileges required","Hak istimewa moderator dibutuhkan"}.
{"moderators only","Hanya moderator"}.
{"Modified modules","Modifikasi modul-modul"}.
{"Module","Modul"}.
{"Modules at ","modul-modul di"}.
{"Modules","Modul"}.
{"Monday","Senin"}.
{"Name:","Nama:"}.
{"Name","Nama"}.
{"Never","Tidak Pernah"}.
{"New Password:","Password Baru:"}.
{"Nickname","Nama Julukan"}.
{"Nickname Registration at ","Pendaftaran Julukan pada"}.
{"Nickname ~s does not exist in the room","Nama Julukan ~s tidak berada di dalam ruangan"}.
{"No body provided for announce message","Tidak ada isi pesan yang disediakan untuk mengirimkan pesan"}.
{"No Data","Tidak Ada Data"}.
{"Node ID","ID Node"}.
{"Node ","Node"}.
{"Node not found","Node tidak ditemukan"}.
{"Nodes","Node-node"}.
{"No limit","Tidak terbatas"}.
{"None","Tak satupun"}.
{"No resource provided","Tidak ada sumber daya yang disediakan"}.
{"Not Found","Tidak Ditemukan"}.
{"Notify subscribers when items are removed from the node","Beritahu pelanggan ketika item tersebut dikeluarkan dari node"}.
{"Notify subscribers when the node configuration changes","Beritahu pelanggan ketika ada perubahan konfigurasi node"}.
{"Notify subscribers when the node is deleted","Beritahu pelanggan ketika node dihapus"}.
{"November","Nopember"}.
{"Number of occupants","Jumlah Penghuni"}.
{"Number of online users","Jumlah pengguna online"}.
{"Number of registered users","Jumlah pengguna terdaftar"}.
{"October","Oktober"}.
{"Offline Messages:","Pesan Offline:"}.
{"Offline Messages","Pesan Offline"}.
{"OK","YA"}.
{"Old Password:","Password Lama:"}.
{"Online","Online"}.
{"Online Users:","Pengguna Online:"}.
{"Online Users","Pengguna Yang Online"}.
{"Only deliver notifications to available users","Hanya mengirimkan pemberitahuan kepada pengguna yang tersedia"}.
{"Only moderators and participants are allowed to change the subject in this room","Hanya moderator dan peserta yang diizinkan untuk mengganti topik pembicaraan di ruangan ini"}.
{"Only moderators are allowed to change the subject in this room","Hanya moderator yang diperbolehkan untuk mengubah topik dalam ruangan ini"}.
{"Only occupants are allowed to send messages to the conference","Hanya penghuni yang diizinkan untuk mengirim pesan ke konferensi"}.
{"Only occupants are allowed to send queries to the conference","Hanya penghuni diizinkan untuk mengirim permintaan ke konferensi"}.
{"Only service administrators are allowed to send service messages","Layanan hanya diperuntukan kepada administrator yang diizinkan untuk mengirim layanan pesan"}.
{"Options","Pilihan-pilihan"}.
{"Organization Name","Nama Organisasi"}.
{"Organization Unit","Unit Organisasi"}.
{"Outgoing s2s Connections","Koneksi Keluar s2s"}.
{"Outgoing s2s Connections:","Koneksi s2s yang keluar:"}.
{"Outgoing s2s Servers:","Layanan s2s yang keluar:"}.
{"Owner privileges required","Hak istimewa owner dibutuhkan"}.
{"Packet","Paket"}.
{"Password ~b","Kata Sandi ~b"}.
{"Password:","Kata Sandi:"}.
{"Password","Sandi"}.
{"Password Verification:","Verifikasi Kata Sandi:"}.
{"Password Verification","Verifikasi Sandi"}.
{"Path to Dir","Jalur ke Dir"}.
{"Path to File","Jalur ke File"}.
{"Pending","Tertunda"}.
{"Period: ","Periode:"}.
{"Persist items to storage","Pertahankan item ke penyimpanan"}.
{"Ping","Ping"}.
{"Please note that these options will only backup the builtin Mnesia database. If you are using the ODBC module, you also need to backup your SQL database separately.","Harap dicatat bahwa pilihan ini hanya akan membuat cadangan builtin Mnesia database. Jika Anda menggunakan modul ODBC, anda juga perlu untuk membuat cadangan database SQL Anda secara terpisah."}.
{"Pong","Pong"}.
{"Port ~b","Port ~b"}.
{"Port","Port"}.
{"Present real Jabber IDs to","Tampilkan Jabber ID secara lengkap"}.
{"private, ","pribadi, "}.
{"Protocol","Protocol"}.
{"Publish-Subscribe","Setujui-Pertemanan"}.
{"PubSub subscriber request","Permintaan pertemanan PubSub"}.
{"Purge all items when the relevant publisher goes offline","Bersihkan semua item ketika penerbit yang relevan telah offline"}.
{"Queries to the conference members are not allowed in this room","Permintaan untuk para anggota konferensi tidak diperbolehkan di ruangan ini"}.
{"RAM and disc copy","RAM dan disc salinan"}.
{"RAM copy","Salinan RAM"}.
{"Raw","mentah"}.
{"Really delete message of the day?","Benar-benar ingin menghapus pesan harian?"}.
{"Recipient is not in the conference room","Penerima tidak berada di ruangan konferensi"}.
{"Register a Jabber account","Daftarkan sebuah akun jabber"}.
{"Registered Users:","Pengguna Terdaftar:"}.
{"Registered Users","Pengguna Terdaftar"}.
{"Register","Mendaftar"}.
{"Registration in mod_irc for ","Pendaftaran di mod_irc untuk"}.
{"Remote copy","Salinan Remote"}.
{"Remove All Offline Messages","Hapus Semua Pesan Offline"}.
{"Remove","Menghapus"}.
{"Remove User","Hapus Pengguna"}.
{"Replaced by new connection","Diganti dengan koneksi baru"}.
{"Resources","Sumber daya"}.
{"Restart","Jalankan Ulang"}.
{"Restart Service","Restart Layanan"}.
{"Restore Backup from File at ","Kembalikan Backup dari File pada"}.
{"Restore binary backup after next ejabberd restart (requires less memory):","Mengembalikan cadangan yang berpasanagn setelah ejabberd berikutnya dijalankan ulang (memerlukan memori lebih sedikit):"}.
{"Restore binary backup immediately:","Segera mengembalikan cadangan yang berpasangan:"}.
{"Restore","Mengembalikan"}.
{"Restore plain text backup immediately:","Segera mengembalikan cadangan teks biasa:"}.
{"Room Configuration","Konfigurasi Ruangan"}.
{"Room creation is denied by service policy","Pembuatan Ruangan ditolak oleh kebijakan layanan"}.
{"Room description","Keterangan ruangan"}.
{"Room Occupants","Penghuni Ruangan"}.
{"Room title","Nama Ruangan"}.
{"Roster groups allowed to subscribe","Kelompok kontak yang diizinkan untuk berlangganan"}.
{"Roster","Kontak"}.
{"Roster of ","Kontak dari"}.
{"Roster size","Ukuran Daftar Kontak"}.
{"RPC Call Error","Panggilan Kesalahan RPC"}.
{"Running Nodes","Menjalankan Node"}.
{"~s access rule configuration","~s aturan akses konfigurasi"}.
{"Saturday","Sabtu"}.
{"Script check","Periksa naskah"}.
{"Search Results for ","Hasil Pencarian untuk"}.
{"Search users in ","Pencarian pengguna dalam"}.
{"Send announcement to all online users","Kirim pengumuman untuk semua pengguna yang online"}.
{"Send announcement to all online users on all hosts","Kirim pengumuman untuk semua pengguna yang online pada semua host"}.
{"Send announcement to all users","Kirim pengumuman untuk semua pengguna"}.
{"Send announcement to all users on all hosts","Kirim pengumuman untuk semua pengguna pada semua host"}.
{"September","September"}.
{"Server ~b","Layanan ~b"}.
{"Server:","Layanan:"}.
{"Set message of the day and send to online users","Mengatur pesan harian dan mengirimkan ke pengguna yang online"}.
{"Set message of the day on all hosts and send to online users","Mengatur pesan harian pada semua host dan kirimkan ke pengguna yang online"}.
{"Shared Roster Groups","Berbagi grup kontak"}.
{"Show Integral Table","Tampilkan Tabel Terpisah"}.
{"Show Ordinary Table","Tampilkan Tabel Normal"}.
{"Shut Down Service","Shut Down Layanan"}.
{"~s invites you to the room ~s","~s mengundang anda ke ruangan ~s"}.
{"Some Jabber clients can store your password in your computer. Use that feature only if you trust your computer is safe.","Beberapa klien Jabber dapat menyimpan password di komputer Anda. Gunakan fitur itu hanya jika Anda mempercayai komputer Anda aman."}.
{"Specify the access model","Tentukan model akses"}.
{"Specify the event message type","Tentukan jenis acara pesan"}.
{"Specify the publisher model","Tentukan model penerbitan"}.
{"~s's Offline Messages Queue","Antrian Pesan Offline ~s"}.
{"Start Modules at ","Mulai Modul pada"}.
{"Start Modules","Memulai Modul"}.
{"Start","Mulai"}.
{"Statistics of ~p","statistik dari ~p"}.
{"Statistics","Statistik"}.
{"Stop","Hentikan"}.
{"Stop Modules at ","Hentikan Modul pada"}.
{"Stop Modules","Hentikan Modul"}.
{"Stopped Nodes","Menghentikan node"}.
{"Storage Type","Jenis Penyimpanan"}.
{"Store binary backup:","Penyimpanan cadangan yang berpasangan:"}.
{"Store plain text backup:","Simpan cadangan teks biasa:"}.
{"Subject","Subyek"}.
{"Submit","Serahkan"}.
{"Submitted","Ulangi masukan"}.
{"Subscriber Address","Alamat Pertemanan"}.
{"Subscription","Berlangganan"}.
{"Sunday","Minggu"}.
{"That nickname is already in use by another occupant","Julukan itu sudah digunakan oleh penghuni lain"}.
{"That nickname is registered by another person","Julukan tersebut telah didaftarkan oleh orang lain"}.
{"The captcha is valid.","Captcha ini benar."}.
{"The CAPTCHA verification has failed","Verifikasi CAPTCHA telah gagal"}.
{"The collections with which a node is affiliated","Koleksi dengan yang berafiliasi dengan sebuah node"}.
{"the password is","kata sandi yaitu:"}.
{"The password is too weak","Kata sandi terlalu lemah"}.
{"The password of your Jabber account was successfully changed.","Kata sandi pada akun Jabber Anda telah berhasil diubah."}.
{"There was an error changing the password: ","Ada kesalahan dalam mengubah password:"}.
{"There was an error creating the account: ","Ada kesalahan saat membuat akun:"}.
{"There was an error deleting the account: ","Ada kesalahan saat menghapus akun:"}.
{"This is case insensitive: macbeth is the same that MacBeth and Macbeth.","Pada bagian ini huruf besar dan kecil tidak dibedakan: Misalnya macbeth adalah sama dengan MacBeth juga Macbeth."}.
{"This page allows to create a Jabber account in this Jabber server. Your JID (Jabber IDentifier) will be of the form: username@server. Please read carefully the instructions to fill correctly the fields.","Halaman ini memungkinkan untuk membuat akun Jabber di layanan Jabber ini. JID Anda (Jabber Pengenal) akan berbentuk: namapengguna@layanan. Harap baca dengan seksama petunjuk-petunjuk untuk mengisi kolom dengan benar."}.
{"This page allows to unregister a Jabber account in this Jabber server.","Pada bagian ini memungkinkan Anda untuk membatalkan pendaftaran akun Jabber pada layanan Jabber ini."}.
{"This participant is kicked from the room because he sent an error message","Peserta ini dikick dari ruangan karena dia mengirim pesan kesalahan"}.
{"This participant is kicked from the room because he sent an error message to another participant","Participant ini dikick dari ruangan karena ia mengirim pesan kesalahan ke participant lain"}.
{"This participant is kicked from the room because he sent an error presence","Participant ini dikick dari ruangan karena ia mengirim kehadiran kesalahan"}.
{"This room is not anonymous","Ruangan ini tidak dikenal"}.
{"Thursday","Kamis"}.
{"Time delay","Waktu tunda"}.
{"Time","Waktu"}.
{"To","Kepada"}.
{"To ~s","Kepada ~s"}.
{"Traffic rate limit is exceeded","Lalu lintas melebihi batas"}.
{"Transactions Aborted:","Transaksi yang dibatalkan:"}.
{"Transactions Committed:","Transaksi yang dilakukan:"}.
{"Transactions Logged:","Transaksi yang ditempuh:"}.
{"Transactions Restarted:","Transaksi yang dijalankan ulang:"}.
{"Tuesday","Selasa"}.
{"Unable to generate a captcha","Tidak dapat menghasilkan captcha"}.
{"Unable to generate a CAPTCHA","Tidak dapat menghasilkan CAPTCHA"}.
{"Unauthorized","Ditolak"}.
{"Unregister a Jabber account","Nonaktifkan akun jabber"}.
{"Unregister","Nonaktifkan"}.
{"Update ","Memperbarui "}.
{"Update","Memperbarui"}.
{"Update message of the day (don't send)","Rubah pesan harian (tidak dikirim)"}.
{"Update message of the day on all hosts (don't send)","Rubah pesan harian pada semua host (tidak dikirim)"}.
{"Update plan","Rencana Perubahan"}.
{"Update script","Perbarui naskah"}.
{"Uptime:","Sampai saat:"}.
{"Use of STARTTLS required","Penggunaan STARTTLS diperlukan"}.
{"User Management","Manajemen Pengguna"}.
{"Username:","Nama Pengguna:"}.
{"User ","Pengguna"}.
{"User","Pengguna"}.
{"Users are not allowed to register accounts so quickly","Pengguna tidak diperkenankan untuk mendaftar akun begitu cepat"}.
{"Users Last Activity","Aktifitas terakhir para pengguna"}.
{"Users","Pengguna"}.
{"Validate","Mengesahkan"}.
{"vCard User Search","vCard Pencarian Pengguna"}.
{"Virtual Hosts","Virtual Hosts"}.
{"Visitors are not allowed to change their nicknames in this room","Visitor tidak diperbolehkan untuk mengubah nama julukan di ruangan ini"}.
{"Visitors are not allowed to send messages to all occupants","Visitor tidak diperbolehkan untuk mengirim pesan ke semua penghuni"}.
{"Wednesday","Rabu"}.
{"When to send the last published item","Ketika untuk mengirim item terakhir yang dipublikasikan"}.
{"Whether to allow subscriptions","Apakah diperbolehkan untuk berlangganan"}.
{"You can later change your password using a Jabber client.","Anda dapat mengubah kata sandi anda dilain waktu dengan menggunakan klien Jabber."}.
{"You have been banned from this room","Anda telah diblokir dari ruangan ini"}.
{"You must fill in field \"Nickname\" in the form","Anda harus mengisi kolom \"Julukan\" dalam formulir"}.
{"You need a client that supports x:data and CAPTCHA to register","Anda memerlukan klien yang mendukung x:data dan CAPTCHA untuk mendaftar"}.
{"You need a client that supports x:data to register the nickname","Anda memerlukan klien yang mendukung x:data untuk mendaftar julukan"}.
{"You need an x:data capable client to configure mod_irc settings","Anda memerlukan x:data klien untuk mampu mengkonfigurasi pengaturan mod_irc"}.
{"You need an x:data capable client to configure room","Anda memerlukan x:data klien untuk dapat mengkonfigurasi ruangan"}.
{"You need an x:data capable client to search","Anda memerlukan x:data klien untuk melakukan pencarian"}.
{"Your active privacy list has denied the routing of this stanza.","Daftar privasi aktif Anda telah menolak routing ztanza ini"}.
{"Your contact offline message queue is full. The message has been discarded.","Kontak offline Anda pada antrian pesan sudah penuh. Pesan telah dibuang."}.
{"Your Jabber account was successfully created.","Jabber akun Anda telah sukses dibuat"}.
{"Your Jabber account was successfully deleted.","Jabber akun Anda berhasil dihapus."}.
{"Your messages to ~s are being blocked. To unblock them, visit ~s","Pesan Anda untuk ~s sedang diblokir. Untuk membuka blokir tersebut, kunjungi ~s"}.

1799
src/msgs/id.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -77,7 +77,6 @@
{"ejabberd Publish-Subscribe module","Modulo Pubblicazione/Iscrizione (PubSub) per ejabberd"}.
{"ejabberd SOCKS5 Bytestreams module","Modulo SOCKS5 Bytestreams per ejabberd"}.
{"ejabberd vCard module","Modulo vCard per ejabberd"}.
{"ejabberd virtual hosts","Host virtuali di ejabberd"}.
{"ejabberd Web Admin","Amministrazione web ejabberd"}.
{"Elements","Elementi"}.
{"Email","E-mail"}.
@ -362,6 +361,7 @@
{"User","Utente"}.
{"Validate","Validare"}.
{"vCard User Search","Ricerca di utenti per vCard"}.
{"Virtual Hosts","Host Virtuali"}.
{"Visitors are not allowed to change their nicknames in this room","Non è consentito ai visitatori cambiare il nickname in questa stanza"}.
{"Visitors are not allowed to send messages to all occupants","Non è consentito ai visitatori l'invio di messaggi a tutti i presenti"}.
{"Wednesday","Mercoledì"}.

View File

@ -1372,8 +1372,8 @@ msgid "~s access rule configuration"
msgstr "Configurazione delle regole di accesso per ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "Host virtuali di ejabberd"
msgid "Virtual Hosts"
msgstr "Host Virtuali"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -80,7 +80,6 @@
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe module"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}.
{"ejabberd vCard module","ejabberd vCard module"}.
{"ejabberd virtual hosts","ejabberd ヴァーチャルホスト"}.
{"ejabberd Web Admin","ejabberd Web 管理"}.
{"Elements","要素"}.
{"Email","メールアドレス"}.
@ -388,6 +387,7 @@
{"Users Last Activity","ユーザーの活動履歴"}.
{"Validate","検証"}.
{"vCard User Search","vCard ユーザー検索"}.
{"Virtual Hosts","ヴァーチャルホスト"}.
{"Visitors are not allowed to change their nicknames in this room","ビジターはこのチャットルームでニックネームを変更することは許可されていません"}.
{"Visitors are not allowed to send messages to all occupants","ビジターが移住者ににメッセージを送ることは許可されていません"}.
{"Wednesday","水曜日"}.

View File

@ -1,15 +1,17 @@
msgid ""
msgstr ""
"Project-Id-Version: 2.1.0-alpha\n"
"Last-Translator: Tsukasa Hamano\n"
"Project-Id-Version: ejabberd 2.1.x\n"
"PO-Revision-Date: 2010-12-24 18:46+0900\n"
"Last-Translator: Mako N <mako@pasero.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Language: Japanese (日本語)\n"
"X-Additional-Translator: Tsukasa Hamano <code@cuspy.org>\n"
#: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727
msgid "Use of STARTTLS required"
msgstr "STARTTLS を使用"
msgstr "STARTTLS の使用が必要です"
#: ejabberd_c2s.erl:503
msgid "No resource provided"
@ -34,15 +36,15 @@ msgstr ""
#: ejabberd_captcha.erl:132
msgid "If you don't see the CAPTCHA image here, visit the web page."
msgstr "ここにキャプチャ画像が表示されない場合、WEBページを参照してください。"
msgstr "ここに CAPTCHA 画像が表示されない場合、web ページを参照してください。"
#: ejabberd_captcha.erl:144
msgid "CAPTCHA web page"
msgstr "キャプチャWEBページ"
msgstr "CAPTCHA web ページ"
#: ejabberd_captcha.erl:302
msgid "The captcha is valid."
msgstr "キャプチャは有効です。"
msgstr "CAPTCHA は有効です。"
#: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161
msgid "Commands"
@ -58,7 +60,7 @@ msgstr "Pong"
#: mod_announce.erl:506
msgid "Really delete message of the day?"
msgstr "本当にお知らせメッセージを削除しますか"
msgstr "本当にお知らせメッセージを削除しますか ?"
#: mod_announce.erl:514 mod_configure.erl:1083 mod_configure.erl:1128
msgid "Subject"
@ -78,43 +80,43 @@ msgstr "アナウンス"
#: mod_announce.erl:636
msgid "Send announcement to all users"
msgstr "アナウンスを全てのユーザーに送信"
msgstr "すべてのユーザーにアナウンスを送信"
#: mod_announce.erl:638
msgid "Send announcement to all users on all hosts"
msgstr "アナウンスを全ホストのユーザーに送信"
msgstr "全ホストのユーザーにアナウンスを送信"
#: mod_announce.erl:640
msgid "Send announcement to all online users"
msgstr "アナウンスを全てのオンラインユーザーに送信"
msgstr "すべてのオンラインユーザーにアナウンスを送信"
#: mod_announce.erl:642 mod_configure.erl:1078 mod_configure.erl:1123
msgid "Send announcement to all online users on all hosts"
msgstr "全ホストのオンラインユーザアナウンスを送信"
msgstr "全ホストのオンラインユーザーにアナウンスを送信"
#: mod_announce.erl:644
msgid "Set message of the day and send to online users"
msgstr "お知らせメッセージを設定し、オンラインユーザーに送信する"
msgstr "お知らせメッセージを設定し、オンラインユーザーに送信"
#: mod_announce.erl:646
msgid "Set message of the day on all hosts and send to online users"
msgstr "全ホストのお知らせメッセージを設定し、オンラインユーザーに送信する"
msgstr "全ホストのお知らせメッセージを設定し、オンラインユーザーに送信"
#: mod_announce.erl:648
msgid "Update message of the day (don't send)"
msgstr "お知らせメッセージを更新する(送信しない)"
msgstr "お知らせメッセージを更新 (送信しない)"
#: mod_announce.erl:650
msgid "Update message of the day on all hosts (don't send)"
msgstr "全ホストのお知らせメッセージを更新する"
msgstr "全ホストのお知らせメッセージを更新 (送信しない)"
#: mod_announce.erl:652
msgid "Delete message of the day"
msgstr "お知らせメッセージを削除する"
msgstr "お知らせメッセージを削除"
#: mod_announce.erl:654
msgid "Delete message of the day on all hosts"
msgstr "全ホストのお知らせメッセージを削除する"
msgstr "全ホストのお知らせメッセージを削除"
#: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296
#: mod_configure.erl:498
@ -127,11 +129,11 @@ msgstr "データーベース"
#: mod_configure.erl:127 mod_configure.erl:595
msgid "Start Modules"
msgstr "モジュール起動"
msgstr "モジュール起動"
#: mod_configure.erl:129 mod_configure.erl:596
msgid "Stop Modules"
msgstr "モジュール停止"
msgstr "モジュール停止"
#: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1931
msgid "Backup"
@ -147,7 +149,7 @@ msgstr "テキストファイルに出力"
#: mod_configure.erl:137 mod_configure.erl:615
msgid "Import File"
msgstr "ファイルかインポート"
msgstr "ファイルかインポート"
#: mod_configure.erl:139 mod_configure.erl:616
msgid "Import Directory"
@ -168,7 +170,7 @@ msgstr "ユーザーを追加"
#: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219
msgid "Delete User"
msgstr "ユーザを削除"
msgstr "ユーザを削除"
#: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231
msgid "End User Session"
@ -185,11 +187,11 @@ msgstr "パスワードを変更"
#: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272
msgid "Get User Last Login Time"
msgstr "最終ログイン時間取得"
msgstr "最終ログイン時間取得"
#: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284
msgid "Get User Statistics"
msgstr "ユーザー統計取得"
msgstr "ユーザー統計取得"
#: mod_configure.erl:159 mod_configure.erl:525
msgid "Get Number of Registered Users"
@ -197,7 +199,7 @@ msgstr "登録ユーザー数を取得"
#: mod_configure.erl:161 mod_configure.erl:526
msgid "Get Number of Online Users"
msgstr "登録ユーザーを取得"
msgstr "オンラインユーザー数を取得"
#: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:827
#: web/ejabberd_web_admin.erl:868
@ -260,7 +262,7 @@ msgstr "データーベーステーブル設定 "
#: mod_configure.erl:918
msgid "Choose storage type of tables"
msgstr "テーブルのストレージタイプ選択"
msgstr "テーブルのストレージタイプ選択"
#: mod_configure.erl:926 mod_configure.erl:928
msgid "Disc only copy"
@ -280,19 +282,19 @@ msgstr "リモートコピー"
#: mod_configure.erl:950
msgid "Stop Modules at "
msgstr "モジュールの停止 "
msgstr "モジュールを停止: "
#: mod_configure.erl:954
msgid "Choose modules to stop"
msgstr "停止するモジュール選択"
msgstr "停止するモジュール選択"
#: mod_configure.erl:969
msgid "Start Modules at "
msgstr "モジュールの開始"
msgstr "モジュールを開始: "
#: mod_configure.erl:973
msgid "Enter list of {Module, [Options]}"
msgstr "{モジュール, [オプション]}のリストを入力してさい"
msgstr "{モジュール, [オプション]}のリストを入力してください"
#: mod_configure.erl:974
msgid "List of modules to start"
@ -300,44 +302,44 @@ msgstr "起動モジュールの一覧"
#: mod_configure.erl:983
msgid "Backup to File at "
msgstr "ファイルにバックアップ"
msgstr "ファイルにバックアップ: "
#: mod_configure.erl:987 mod_configure.erl:1001
msgid "Enter path to backup file"
msgstr "バックアップファイルのパスを入力してさい"
msgstr "バックアップファイルのパスを入力してください"
#: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016
#: mod_configure.erl:1030
msgid "Path to File"
msgstr "ファイルパス"
msgstr "ファイルパス"
#: mod_configure.erl:997
msgid "Restore Backup from File at "
msgstr "ファイルからバックアップをリストア"
msgstr "ファイルからバックアップをリストア: "
#: mod_configure.erl:1011
msgid "Dump Backup to Text File at "
msgstr "テキストファイルにバックアップ"
msgstr "テキストファイルにバックアップ: "
#: mod_configure.erl:1015
msgid "Enter path to text file"
msgstr "テキストファイルのパスを入力してさい"
msgstr "テキストファイルのパスを入力してください"
#: mod_configure.erl:1025
msgid "Import User from File at "
msgstr "ファイルからユーザーをインポート"
msgstr "ファイルからユーザーをインポート: "
#: mod_configure.erl:1029
msgid "Enter path to jabberd14 spool file"
msgstr "jabberd14 spool ファイルのパスを入力してさい"
msgstr "jabberd14 spool ファイルのパスを入力してください"
#: mod_configure.erl:1039
msgid "Import Users from Dir at "
msgstr "ディレクトリからユーザーをインポート"
msgstr "ディレクトリからユーザーをインポート: "
#: mod_configure.erl:1043
msgid "Enter path to jabberd14 spool dir"
msgstr "jabberd14 spool ディレクトリのパスを入力して下さい"
msgstr "jabberd14 spool ディレクトリのディレクトリを入力してください"
#: mod_configure.erl:1044
msgid "Path to Dir"
@ -392,7 +394,7 @@ msgstr "オンラインユーザー数"
#: mod_configure.erl:1684 web/ejabberd_web_admin.erl:1585
#: web/ejabberd_web_admin.erl:1737
msgid "Never"
msgstr "し"
msgstr "し"
#: mod_configure.erl:1698 web/ejabberd_web_admin.erl:1598
#: web/ejabberd_web_admin.erl:1750
@ -425,11 +427,11 @@ msgstr "ユーザー操作"
#: mod_configure.erl:1859
msgid "Edit Properties"
msgstr "プロパティ編集"
msgstr "プロパティ編集"
#: mod_configure.erl:1862 web/ejabberd_web_admin.erl:1763
msgid "Remove User"
msgstr "ユーザー削除"
msgstr "ユーザー削除"
#: mod_irc/mod_irc.erl:201 mod_muc/mod_muc.erl:336
msgid "Access denied by service policy"
@ -456,8 +458,8 @@ msgid ""
"Enter username, encodings, ports and passwords you wish to use for "
"connecting to IRC servers"
msgstr ""
"IRCサーバーに接続先する為に、使用するユーザー名、文字エンコーディング、ポー"
"ト、パスワードを入力してさい"
"IRC サーバーに接続先するために使用するユーザー名、文字エンコーディング、ポー"
"ト、パスワードを入力してください"
#: mod_irc/mod_irc.erl:575
msgid "IRC Username"
@ -471,8 +473,8 @@ msgid ""
"~p, empty password."
msgstr ""
"別のポートやパスワード、文字エンコーディングを使用したい場合、'{\"irc server"
"\", \"encoding\", port, \"password\"}' という形式のリストを入力して下さい。デ"
"フォルトでエンコーディングは \"~s\" を使用し、ポートは ~p、パスワードは空に"
"\", \"encoding\", port, \"password\"}' という形式のリストを入力してください。"
"フォルトでエンコーディングは \"~s\" を使用し、ポートは ~p、パスワードは空に"
"なっています。"
#: mod_irc/mod_irc.erl:597
@ -501,11 +503,11 @@ msgstr "IRCサーバー"
#: mod_irc/mod_irc.erl:769 mod_irc/mod_irc.erl:773
msgid "Join the IRC channel here."
msgstr "このIRCチャンネルに参加"
msgstr "この IRC チャンネルに参加します。"
#: mod_irc/mod_irc.erl:777
msgid "Join the IRC channel in this Jabber ID: ~s"
msgstr "Jabber ID: ~s でIRCチャンネルに参加"
msgstr "Jabber ID: ~s でこの IRC チャンネルに参加"
#: mod_irc/mod_irc.erl:862
msgid "IRC settings"
@ -517,8 +519,8 @@ msgid ""
"Press 'Next' to get more fields to fill in. Press 'Complete' to save "
"settings."
msgstr ""
"IRCサーバーに接続先する為のユーザー名と文字エンコーディングを入力して下さ"
"い。'Next' を押して次の項目に進みます。'Complete' を押すと設定が保存されま"
"IRC サーバーに接続先するためのユーザー名と文字エンコーディングを入力してくだ"
"い。'Next' を押して次の項目に進みます。'Complete' を押すと設定が保存されま"
"す。"
#: mod_irc/mod_irc.erl:873
@ -543,7 +545,7 @@ msgstr "サーバー ~b"
#: mod_muc/mod_muc.erl:449
msgid "Only service administrators are allowed to send service messages"
msgstr "カービス管理者のみがサービスメッセージを送信出来ます"
msgstr "サービス管理者のみがサービスメッセージを送信できます"
#: mod_muc/mod_muc.erl:493
msgid "Room creation is denied by service policy"
@ -568,7 +570,7 @@ msgstr "ニックネーム登録: "
#: mod_muc/mod_muc.erl:721
msgid "Enter nickname you want to register"
msgstr "登録するニックネームを入力してさい"
msgstr "登録するニックネームを入力してください"
#: mod_muc/mod_muc.erl:722 mod_roster.erl:949 mod_roster_odbc.erl:1049
#: mod_vcard.erl:358 mod_vcard.erl:471 mod_vcard_odbc.erl:336
@ -579,7 +581,7 @@ msgstr "ニックネーム"
#: mod_muc/mod_muc.erl:761 mod_muc/mod_muc_room.erl:936
#: mod_muc/mod_muc_room.erl:1580
msgid "That nickname is registered by another person"
msgstr "ニックネームはの人によって登録されています"
msgstr "ニックネームはほかの人によって登録されています"
#: mod_muc/mod_muc.erl:787
msgid "You must fill in field \"Nickname\" in the form"
@ -591,15 +593,15 @@ msgstr "ejabberd MUC module"
#: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381
msgid "Chatroom configuration modified"
msgstr "チャットルームの設定を変更しました"
msgstr "チャットルームの設定が変更されました"
#: mod_muc/mod_muc_log.erl:384
msgid "joins the room"
msgstr "チャットルームに参加"
msgstr "チャットルームに参加しました"
#: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390
msgid "leaves the room"
msgstr "チャットルームから退出"
msgstr "チャットルームから退出しました"
#: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396
msgid "has been banned"
@ -611,11 +613,11 @@ msgstr "はキックされました"
#: mod_muc/mod_muc_log.erl:405
msgid "has been kicked because of an affiliation change"
msgstr "は提携が変更されたためキックされました"
msgstr "は分掌が変更されたためキックされました"
#: mod_muc/mod_muc_log.erl:408
msgid "has been kicked because the room has been changed to members-only"
msgstr "はチャットルームのメンバー制限によりキックされました"
msgstr "はチャットルームのメンバーのみに変更されたためキックされました"
#: mod_muc/mod_muc_log.erl:411
msgid "has been kicked because of a system shutdown"
@ -632,19 +634,19 @@ msgstr " は件名を設定しました: "
#: mod_muc/mod_muc_log.erl:452
msgid "Chatroom is created"
msgstr "チャットルームは作られました。"
msgstr "チャットルームを作りました"
#: mod_muc/mod_muc_log.erl:453
msgid "Chatroom is destroyed"
msgstr "チャットルームは削除されました。"
msgstr "チャットルームを削除しました"
#: mod_muc/mod_muc_log.erl:454
msgid "Chatroom is started"
msgstr "チャットルームが開始しました。"
msgstr "チャットルームを開始しました"
#: mod_muc/mod_muc_log.erl:455
msgid "Chatroom is stopped"
msgstr "チャットルームが停止しました。"
msgstr "チャットルームを停止しました"
#: mod_muc/mod_muc_log.erl:459
msgid "Monday"
@ -728,7 +730,7 @@ msgstr "チャットルーム設定"
#: mod_muc/mod_muc_log.erl:760
msgid "Room Occupants"
msgstr "居住者の数"
msgstr "在室者の数"
#: mod_muc/mod_muc_room.erl:170
msgid "Traffic rate limit is exceeded"
@ -741,7 +743,7 @@ msgstr "エラーメッセージを送信したため、この参加者はキッ
#: mod_muc/mod_muc_room.erl:251
msgid "It is not allowed to send private messages to the conference"
msgstr "カンファレンスルームにプライベートメッセージを送信することは出来ません"
msgstr "カンファレンスルームにプライベートメッセージを送信することはできません"
#: mod_muc/mod_muc_room.erl:296
msgid "Improper message type"
@ -756,44 +758,44 @@ msgstr ""
#: mod_muc/mod_muc_room.erl:419
msgid "It is not allowed to send private messages of type \"groupchat\""
msgstr "種別が\"groupchat\" であるプライベートメッセージは許可されていません"
msgstr ""
"種別が\"groupchat\" であるプライベートメッセージを送信することはできません"
#: mod_muc/mod_muc_room.erl:431 mod_muc/mod_muc_room.erl:486
msgid "Recipient is not in the conference room"
msgstr "受信者がカンファレンスルームにません"
msgstr "受信者がカンファレンスルームにません"
#: mod_muc/mod_muc_room.erl:451 mod_muc/mod_muc_room.erl:829
#: mod_muc/mod_muc_room.erl:3546
msgid "Only occupants are allowed to send messages to the conference"
msgstr "移住者のみがカンファレンスに"
msgstr "在室者のみがカンファレンスにメッセージを送ることができます"
#: mod_muc/mod_muc_room.erl:460
msgid "It is not allowed to send private messages"
msgstr "プライベートメッセージを送信することは許可されませんでした"
msgstr "プライベートメッセージを送信することはできません"
#: mod_muc/mod_muc_room.erl:509
msgid "Only occupants are allowed to send queries to the conference"
msgstr "移住者のみがカンファレンスにクエリーを送信出来ます"
msgstr "在室者のみがカンファレンスにクエリーを送信することができます"
#: mod_muc/mod_muc_room.erl:521
msgid "Queries to the conference members are not allowed in this room"
msgstr ""
"このチャットルームではカンファレンスメンバーへのクエリーは禁止されています"
"このチャットルームではカンファレンスメンバーへのクエリーは禁止されています"
#: mod_muc/mod_muc_room.erl:805
msgid ""
"Only moderators and participants are allowed to change the subject in this "
"room"
msgstr ""
"モデレーターと参加者のみがチャットルームの件名を変更する事を許可されています"
msgstr "モデレーターと参加者のみがチャットルームの件名を変更できます"
#: mod_muc/mod_muc_room.erl:810
msgid "Only moderators are allowed to change the subject in this room"
msgstr "モデレーターのみがチャットルームの件名を変更出来ます"
msgstr "モデレーターのみがチャットルームの件名を変更できます"
#: mod_muc/mod_muc_room.erl:820
msgid "Visitors are not allowed to send messages to all occupants"
msgstr "ビジターが移住者ににメッセージを送ることは許可されていません"
msgstr "ビジターはすべての在室者にメッセージを送信することはできません"
#: mod_muc/mod_muc_room.erl:894
msgid ""
@ -802,12 +804,11 @@ msgstr "エラープレゼンスを送信したため、この参加者はキッ
#: mod_muc/mod_muc_room.erl:912
msgid "Visitors are not allowed to change their nicknames in this room"
msgstr ""
"ビジターはこのチャットルームでニックネームを変更することは許可されていません"
msgstr "ビジターはこのチャットルームでニックネームを変更することはできません"
#: mod_muc/mod_muc_room.erl:925 mod_muc/mod_muc_room.erl:1572
msgid "That nickname is already in use by another occupant"
msgstr "ニックネームは既に他の移住者によって使用されています"
msgstr "ニックネームは既にほかの在室者によって使用されています"
#: mod_muc/mod_muc_room.erl:1561
msgid "You have been banned from this room"
@ -827,7 +828,7 @@ msgstr "チャットルームに入るにはパスワードが必要です"
#: mod_muc/mod_muc_room.erl:1648
msgid "Unable to generate a captcha"
msgstr "キャプチャを生成することが出来ません。"
msgstr "CAPTCHA を生成することができません"
#: mod_muc/mod_muc_room.erl:1658
msgid "Incorrect password"
@ -847,15 +848,15 @@ msgstr "Jabber ID ~s は無効です"
#: mod_muc/mod_muc_room.erl:2354
msgid "Nickname ~s does not exist in the room"
msgstr "ニックネーム ~s はこのチャットルームにません"
msgstr "ニックネーム ~s はこのチャットルームにません"
#: mod_muc/mod_muc_room.erl:2380 mod_muc/mod_muc_room.erl:2762
msgid "Invalid affiliation: ~s"
msgstr "無効な提携です: ~s"
msgstr "無効な分掌です: ~s"
#: mod_muc/mod_muc_room.erl:2437
msgid "Invalid role: ~s"
msgstr "無効なロールです: ~s"
msgstr "無効なです: ~s"
#: mod_muc/mod_muc_room.erl:2739 mod_muc/mod_muc_room.erl:2775
msgid "Owner privileges required"
@ -871,35 +872,35 @@ msgstr "チャットルームタイトル"
#: mod_muc/mod_muc_room.erl:2907 mod_muc/mod_muc_room.erl:3325
msgid "Room description"
msgstr "チャットルームの詳細"
msgstr "チャットルームの説明"
#: mod_muc/mod_muc_room.erl:2914
msgid "Make room persistent"
msgstr "チャットルームを永続化します"
msgstr "チャットルームを永続化"
#: mod_muc/mod_muc_room.erl:2919
msgid "Make room public searchable"
msgstr "チャットルームを検索可能にします"
msgstr "チャットルームを検索可"
#: mod_muc/mod_muc_room.erl:2922
msgid "Make participants list public"
msgstr "参加者一覧を公開します"
msgstr "参加者一覧を公開"
#: mod_muc/mod_muc_room.erl:2925
msgid "Make room password protected"
msgstr "チャットルームにパスワードを設定します"
msgstr "チャットルームにパスワードを設定"
#: mod_muc/mod_muc_room.erl:2936
msgid "Maximum Number of Occupants"
msgstr "最大移住者数"
msgstr "最大在室者数"
#: mod_muc/mod_muc_room.erl:2943
msgid "No limit"
msgstr "制限し"
msgstr "制限し"
#: mod_muc/mod_muc_room.erl:2954
msgid "Present real Jabber IDs to"
msgstr "本当の Jabber ID を公開する"
msgstr "本当の Jabber ID を公開"
#: mod_muc/mod_muc_room.erl:2962
msgid "moderators only"
@ -911,61 +912,61 @@ msgstr "誰でも"
#: mod_muc/mod_muc_room.erl:2966
msgid "Make room members-only"
msgstr "チャットルームをメンバーのみに制限する"
msgstr "チャットルームをメンバーのみに制限"
#: mod_muc/mod_muc_room.erl:2969
msgid "Make room moderated"
msgstr "チャットルームをモデレートする"
msgstr "チャットルームをモデレート"
#: mod_muc/mod_muc_room.erl:2972
msgid "Default users as participants"
msgstr "デフォルトのユーザーは参加者にする"
msgstr "デフォルトのユーザーは参加者"
#: mod_muc/mod_muc_room.erl:2975
msgid "Allow users to change the subject"
msgstr "ユーザーによる件名の変更を許可する"
msgstr "ユーザーによる件名の変更を許可"
#: mod_muc/mod_muc_room.erl:2978
msgid "Allow users to send private messages"
msgstr "ユーザーによるプライベートメッセージの送信を許可する"
msgstr "ユーザーによるプライベートメッセージの送信を許可"
#: mod_muc/mod_muc_room.erl:2981
msgid "Allow users to query other users"
msgstr "ユーザーによる他のユーザーへの問い合わせを許可する"
msgstr "ユーザーによる他のユーザーへのクエリーを許可"
#: mod_muc/mod_muc_room.erl:2984
msgid "Allow users to send invites"
msgstr "ユーザーによる招待を許可する"
msgstr "ユーザーによる招待を許可"
#: mod_muc/mod_muc_room.erl:2987
msgid "Allow visitors to send status text in presence updates"
msgstr "ビジターがプレゼンス更新のステータス文を送信する事を許可する"
msgstr "ビジターによるプレゼンス更新のステータス文の送信を許可"
#: mod_muc/mod_muc_room.erl:2990
msgid "Allow visitors to change nickname"
msgstr "ビジターがニックネームを変更する事を許可します"
msgstr "ビジターのニックネームの変更を許可"
#: mod_muc/mod_muc_room.erl:2996
msgid "Make room captcha protected"
msgstr "チャットルームをキャプチャで保護します"
msgstr "チャットルームを CAPTCHA で保護"
#: mod_muc/mod_muc_room.erl:3005
msgid "Enable logging"
msgstr "ロギングを有効にする"
msgstr "ロギングを有効"
#: mod_muc/mod_muc_room.erl:3013
msgid "You need an x:data capable client to configure room"
msgstr ""
"チャットルームを設定するにはにはクライアントが x:data をサポートする必要があ"
"ります"
"チャットルームを設定するにはクライアントが x:data をサポートする必要がありま"
"す"
#: mod_muc/mod_muc_room.erl:3327
msgid "Number of occupants"
msgstr "居住者の数"
msgstr "在室者の数"
#: mod_muc/mod_muc_room.erl:3383
msgid "private, "
msgstr "プライベート"
msgstr "プライベート"
#: mod_muc/mod_muc_room.erl:3466
msgid "~s invites you to the room ~s"
@ -983,7 +984,7 @@ msgstr ""
#: mod_offline.erl:560 mod_offline_odbc.erl:408
msgid "~s's Offline Messages Queue"
msgstr "~s's オフラインメッセージキュー"
msgstr "~s' オフラインメッセージキュー"
#: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:992
#: mod_roster_odbc.erl:1092 mod_shared_roster.erl:810
@ -1020,11 +1021,11 @@ msgstr "選択した項目を削除"
#: mod_offline.erl:645 mod_offline_odbc.erl:519
msgid "Offline Messages:"
msgstr "オフラインメッセージ"
msgstr "オフラインメッセージ:"
#: mod_offline.erl:645 mod_offline_odbc.erl:519
msgid "Remove All Offline Messages"
msgstr "すべてのオフラインメッセージを削除します"
msgstr "すべてのオフラインメッセージを削除"
#: mod_proxy65/mod_proxy65_service.erl:213
msgid "ejabberd SOCKS5 Bytestreams module"
@ -1040,11 +1041,11 @@ msgstr "ejabberd Publish-Subscribe module"
#: mod_pubsub/mod_pubsub.erl:1496 mod_pubsub/mod_pubsub_odbc.erl:1311
msgid "PubSub subscriber request"
msgstr "PubSub 購読リクエスト"
msgstr "PubSub 購読者のリクエスト"
#: mod_pubsub/mod_pubsub.erl:1498 mod_pubsub/mod_pubsub_odbc.erl:1313
msgid "Choose whether to approve this entity's subscription."
msgstr "このエントリを承認するかどうかを選択してさい"
msgstr "このエントリを承認するかどうかを選択してください"
#: mod_pubsub/mod_pubsub.erl:1504 mod_pubsub/mod_pubsub_odbc.erl:1319
msgid "Node ID"
@ -1052,31 +1053,31 @@ msgstr "ードID"
#: mod_pubsub/mod_pubsub.erl:1509 mod_pubsub/mod_pubsub_odbc.erl:1324
msgid "Subscriber Address"
msgstr "購読アドレス"
msgstr "購読者のアドレス"
#: mod_pubsub/mod_pubsub.erl:1515 mod_pubsub/mod_pubsub_odbc.erl:1330
msgid "Allow this Jabber ID to subscribe to this pubsub node?"
msgstr "この Jabber ID をこの pubsubードへ購読することを許可しますか"
msgstr "この Jabber ID に、この pubsubードの購読を許可しますか ?"
#: mod_pubsub/mod_pubsub.erl:3387 mod_pubsub/mod_pubsub_odbc.erl:3229
msgid "Deliver payloads with event notifications"
msgstr "イベント通知と同時にペイロードを配送します"
msgstr "イベント通知と同時にペイロードを配送す"
#: mod_pubsub/mod_pubsub.erl:3388 mod_pubsub/mod_pubsub_odbc.erl:3230
msgid "Deliver event notifications"
msgstr "イベント通知を配送します"
msgstr "イベント通知を配送す"
#: mod_pubsub/mod_pubsub.erl:3389 mod_pubsub/mod_pubsub_odbc.erl:3231
msgid "Notify subscribers when the node configuration changes"
msgstr "ノード設定に変更があった時に購読者へ通知します"
msgstr "ノード設定に変更があった時に購読者へ通知す"
#: mod_pubsub/mod_pubsub.erl:3390 mod_pubsub/mod_pubsub_odbc.erl:3232
msgid "Notify subscribers when the node is deleted"
msgstr "ノードが削除された時に購読者へ通知します"
msgstr "ノードが削除された時に購読者へ通知す"
#: mod_pubsub/mod_pubsub.erl:3391 mod_pubsub/mod_pubsub_odbc.erl:3233
msgid "Notify subscribers when items are removed from the node"
msgstr "アイテムがノードから消された時に購読者へ通知します"
msgstr "アイテムがノードから消された時に購読者へ通知す"
#: mod_pubsub/mod_pubsub.erl:3392 mod_pubsub/mod_pubsub_odbc.erl:3234
msgid "Persist items to storage"
@ -1084,11 +1085,11 @@ msgstr "アイテムをストレージに保存する"
#: mod_pubsub/mod_pubsub.erl:3393 mod_pubsub/mod_pubsub_odbc.erl:3235
msgid "A friendly name for the node"
msgstr "ノードの為のフレンドリネーム"
msgstr "ノードのフレンドリネーム"
#: mod_pubsub/mod_pubsub.erl:3394 mod_pubsub/mod_pubsub_odbc.erl:3236
msgid "Max # of items to persist"
msgstr "アイテムの最大保存数 #"
msgstr "アイテムの最大保存数"
#: mod_pubsub/mod_pubsub.erl:3395 mod_pubsub/mod_pubsub_odbc.erl:3237
msgid "Whether to allow subscriptions"
@ -1108,7 +1109,7 @@ msgstr "公開モデルを指定する"
#: mod_pubsub/mod_pubsub.erl:3402 mod_pubsub/mod_pubsub_odbc.erl:3244
msgid "Purge all items when the relevant publisher goes offline"
msgstr "公開者がオフラインになる時に、全てののアイテムを削除"
msgstr "公開者がオフラインになるときに、すべてのアイテムを削除"
#: mod_pubsub/mod_pubsub.erl:3403 mod_pubsub/mod_pubsub_odbc.erl:3245
msgid "Specify the event message type"
@ -1132,16 +1133,16 @@ msgstr "提携されたノードの集合です"
#: mod_register.erl:191
msgid "The CAPTCHA verification has failed"
msgstr "キャプチャ検証は失敗しました"
msgstr "CAPTCHA 検証は失敗しました"
#: mod_register.erl:218
msgid "You need a client that supports x:data and CAPTCHA to register"
msgstr ""
"登録を行うにはクライアントがx:dataとキャプチャをサポートする必要があります"
"登録を行うにはクライアントが x:data と CAPTCHA をサポートする必要があります"
#: mod_register.erl:224 mod_register.erl:258
msgid "Choose a username and password to register with this server"
msgstr "サーバーに登録するユーザー名とパスワードを選択してさい"
msgstr "サーバーに登録するユーザー名とパスワードを選択してください"
#: mod_register.erl:228 mod_vcard.erl:358 mod_vcard_odbc.erl:336
#: web/ejabberd_web_admin.erl:1512 web/ejabberd_web_admin.erl:1569
@ -1150,7 +1151,7 @@ msgstr "ユーザー"
#: mod_register.erl:244
msgid "Unable to generate a CAPTCHA"
msgstr "キャプチャを生成出来ませんでした"
msgstr "CAPTCHA を生成できませんでした"
#: mod_register.erl:309 mod_register.erl:354
msgid "The password is too weak"
@ -1164,7 +1165,7 @@ msgstr "早すぎるユーザーアカウント登録は許可されていませ
#: web/ejabberd_web_admin.erl:1880 web/ejabberd_web_admin.erl:1891
#: web/ejabberd_web_admin.erl:2214
msgid "None"
msgstr "し"
msgstr "し"
#: mod_roster.erl:950 mod_roster_odbc.erl:1050
msgid "Subscription"
@ -1202,7 +1203,7 @@ msgstr "不正なフォーマット"
#: mod_roster.erl:1000 mod_roster_odbc.erl:1100
msgid "Add Jabber ID"
msgstr "Jabber ID 追加"
msgstr "Jabber ID 追加"
#: mod_roster.erl:1099 mod_roster_odbc.erl:1199
msgid "Roster"
@ -1224,7 +1225,7 @@ msgstr "名前: "
#: mod_shared_roster.erl:884
msgid "Description:"
msgstr "詳細:"
msgstr "説明:"
#: mod_shared_roster.erl:892
msgid "Members:"
@ -1328,7 +1329,7 @@ msgstr "検索結果: "
#: mod_vcard_ldap.erl:458
msgid "Fill in fields to search for any matching Jabber User"
msgstr "項目を埋めて Jabber User を検索してさい"
msgstr "項目を埋めて Jabber User を検索してください"
#: web/ejabberd_web_admin.erl:189 web/ejabberd_web_admin.erl:199
#: web/ejabberd_web_admin.erl:215 web/ejabberd_web_admin.erl:225
@ -1377,7 +1378,7 @@ msgstr "去年"
#: web/ejabberd_web_admin.erl:1088
msgid "All activity"
msgstr "て"
msgstr "すべて"
#: web/ejabberd_web_admin.erl:1090
msgid "Show Ordinary Table"
@ -1436,7 +1437,7 @@ msgstr "外向き s2s サービス:"
#: web/mod_register_web.erl:367 web/mod_register_web.erl:376
#: web/mod_register_web.erl:406
msgid "Change Password"
msgstr "パスワード変更"
msgstr "パスワード変更"
#: web/ejabberd_web_admin.erl:1752
msgid "User "
@ -1453,7 +1454,7 @@ msgstr "パスワード"
#: web/ejabberd_web_admin.erl:1822
msgid "No Data"
msgstr "データし"
msgstr "データし"
#: web/ejabberd_web_admin.erl:1900
msgid "Nodes"
@ -1514,13 +1515,13 @@ msgid ""
"If you are using the ODBC module, you also need to backup your SQL database "
"separately."
msgstr ""
"これらのオプションは組み込みの Mnesiaデーターベースをバックアップのみを行うこ"
"とに注意して下さい。もしも ODBCモジュールを使用している場合は SQLデーターベー"
"スのバックアップを別に行う必要があります。"
"これらのオプションは組み込みの Mnesia データーベースのバックアップのみを行う"
"ことに注意してください。もし ODBC モジュールを使用している場合は、SQL デー"
"ターベースのバックアップを別に行う必要があります。"
#: web/ejabberd_web_admin.erl:2036
msgid "Store binary backup:"
msgstr "バイナリバックアップの保存"
msgstr "バイナリバックアップを保存:"
#: web/ejabberd_web_admin.erl:2040 web/ejabberd_web_admin.erl:2047
#: web/ejabberd_web_admin.erl:2055 web/ejabberd_web_admin.erl:2062
@ -1532,20 +1533,20 @@ msgstr "OK"
#: web/ejabberd_web_admin.erl:2043
msgid "Restore binary backup immediately:"
msgstr "直ちにバイナリバックアップからリストア"
msgstr "直ちにバイナリバックアップからリストア:"
#: web/ejabberd_web_admin.erl:2051
msgid ""
"Restore binary backup after next ejabberd restart (requires less memory):"
msgstr "ejabberd の再起動時にバイナリバックアップからリストア"
msgstr "ejabberd の再起動時にバイナリバックアップからリストア (メモリ少):"
#: web/ejabberd_web_admin.erl:2058
msgid "Store plain text backup:"
msgstr "プレーンテキストバックアップの保存"
msgstr "プレーンテキストバックアップを保存:"
#: web/ejabberd_web_admin.erl:2065
msgid "Restore plain text backup immediately:"
msgstr "直ちにプレーンテキストバックアップからリストア"
msgstr "直ちにプレーンテキストバックアップからリストア:"
#: web/ejabberd_web_admin.erl:2072
msgid "Import users data from a PIEFXIS file (XEP-0227):"
@ -1554,7 +1555,8 @@ msgstr "ユーザーデータを PIEFXISファイルからインポート(XEP-02
#: web/ejabberd_web_admin.erl:2079
msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):"
msgstr ""
"サーバーにある全てのユーザーデータをPIEFXISファイルにエクスポート(XEP-0227):"
"サーバーにあるすべてのユーザーデータを PIEFXIS ファイルにエクスポート "
"(XEP-0227):"
#: web/ejabberd_web_admin.erl:2086
msgid "Export data of users in a host to PIEFXIS files (XEP-0227):"
@ -1582,7 +1584,7 @@ msgstr "~p の統計"
#: web/ejabberd_web_admin.erl:2181
msgid "Uptime:"
msgstr "起動時間"
msgstr "起動時間:"
#: web/ejabberd_web_admin.erl:2184
msgid "CPU Time:"
@ -1614,7 +1616,7 @@ msgstr "更新計画"
#: web/ejabberd_web_admin.erl:2250
msgid "Modified modules"
msgstr "モジュールを変更しました"
msgstr "変更されたモジュール"
#: web/ejabberd_web_admin.erl:2251
msgid "Update script"
@ -1692,7 +1694,7 @@ msgstr "Jabberアカウントを登録"
#: web/mod_register_web.erl:175 web/mod_register_web.erl:488
#: web/mod_register_web.erl:497
msgid "Unregister a Jabber account"
msgstr "Jabberアカウントの登録解除"
msgstr "Jabber アカウントを削除"
#: web/mod_register_web.erl:202
msgid ""
@ -1700,9 +1702,9 @@ msgid ""
"(Jabber IDentifier) will be of the form: username@server. Please read "
"carefully the instructions to fill correctly the fields."
msgstr ""
"ここはJabberサーバーにアカウント作成を行うページです。あなたのJID(JabberID)"
"は username@server の様な形式に成ります。注意事項通り、正しく項目に記入して下"
"さい。"
"ここは Jabber サーバーにアカウントを作成するページです。あなたの JID "
"(JabberID) は username@server のような形式になります。注意事項どおり、正しく"
"項目を記入してください。"
#: web/mod_register_web.erl:211 web/mod_register_web.erl:381
#: web/mod_register_web.erl:504
@ -1716,7 +1718,7 @@ msgstr ""
#: web/mod_register_web.erl:217
msgid "Characters not allowed:"
msgstr "許可されていない文字:"
msgstr "使用できない文字:"
#: web/mod_register_web.erl:221 web/mod_register_web.erl:386
#: web/mod_register_web.erl:509
@ -1728,21 +1730,22 @@ msgid ""
"Don't tell your password to anybody, not even the administrators of the "
"Jabber server."
msgstr ""
"パスワードは誰にも教えないようにして下さい。Jabberサーバーの管理者があなたに"
"パスワードを尋ねることはありません。"
"パスワードは誰にも教えないようにしてください。Jabber サーバーの管理者があなた"
"パスワードを尋ねることはありません。"
#: web/mod_register_web.erl:233
msgid "You can later change your password using a Jabber client."
msgstr ""
"あなたは後からJabberクライアントを使用してパスワードを変更する事が出来ます。"
"あなたは後から Jabber クライアントを使用してパスワードを変更することができま"
"す。"
#: web/mod_register_web.erl:234
msgid ""
"Some Jabber clients can store your password in your computer. Use that "
"feature only if you trust your computer is safe."
msgstr ""
"Jabberクライアントはコンピューターにあなたのパスワード記憶出来ます。この機能"
"を使用する場合コンピューターが安全であることを確認してさい。"
"Jabber クライアントはコンピューターにあなたのパスワードを記憶できます。この機能"
"を使用する場合コンピューターが安全であることを確認してください。"
#: web/mod_register_web.erl:236
msgid ""
@ -1750,9 +1753,9 @@ msgid ""
"Jabber there isn't an automated way to recover your password if you forget "
"it."
msgstr ""
"パスワードは記憶するか、紙に書いて安全な場所に保管して下さい。もしあなたがパ"
"スワードを忘れてしまった場合、Jabberではパスワードのリカバリを自動的に行う"
"とは出来ません。"
"パスワードは記憶するか、紙に書いて安全な場所に保管してください。もしあなたが"
"スワードを忘れてしまった場合、Jabber ではパスワードのリカバリを自動的に行う"
"ことはできません。"
#: web/mod_register_web.erl:241 web/mod_register_web.erl:401
msgid "Password Verification:"
@ -1772,11 +1775,11 @@ msgstr "新しいパスワード:"
#: web/mod_register_web.erl:499
msgid "This page allows to unregister a Jabber account in this Jabber server."
msgstr "ここはサーバーのJabberアカウントの登録削除を行うページです。"
msgstr "ここはサーバーの Jabber アカウントの削除を行うページです。"
#: web/mod_register_web.erl:519
msgid "Unregister"
msgstr "登録解除"
msgstr "除"
#~ msgid "Captcha test failed"
#~ msgstr "キャプチャのテストに失敗しました"
@ -1787,8 +1790,8 @@ msgstr "登録解除"
#~ msgid "(Raw)"
#~ msgstr "(Raw)"
#~ msgid "Virtual Hosts"
#~ msgstr "ヴァーチャルホスト"
msgid "Virtual Hosts"
msgstr "ヴァーチャルホスト"
#~ msgid "Specified nickname is already registered"
#~ msgstr "指定されたニックネームは既に登録されています"

View File

@ -77,7 +77,6 @@
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe module"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}.
{"ejabberd vCard module","ejabberd's vCard-module"}.
{"ejabberd virtual hosts","Virtuele hosts"}.
{"ejabberd Web Admin","ejabberd Webbeheer"}.
{"Elements","Elementen"}.
{"Email","E-mail"}.
@ -362,6 +361,7 @@
{"Users Last Activity","Laatste activiteit van gebruikers"}.
{"Validate","Bevestigen"}.
{"vCard User Search","Gebruikers zoeken"}.
{"Virtual Hosts","Virtuele hosts"}.
{"Visitors are not allowed to change their nicknames in this room","Het is bezoekers niet toegestaan hun naam te veranderen in dit kanaal"}.
{"Visitors are not allowed to send messages to all occupants","Bezoekers mogen geen berichten verzenden naar alle aanwezigen"}.
{"Wednesday","Woensdag"}.

View File

@ -1378,7 +1378,7 @@ msgid "~s access rule configuration"
msgstr "Access rules op ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgid "Virtual Hosts"
msgstr "Virtuele hosts"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046

View File

@ -77,7 +77,6 @@
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe modul"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams modul"}.
{"ejabberd vCard module","ejabberd vCard modul"}.
{"ejabberd virtual hosts","virtuella ejabberd maskiner"}.
{"ejabberd Web Admin","ejabberd Web Admin"}.
{"Elements","Elementer"}.
{"Email","Epost"}.
@ -362,6 +361,7 @@
{"Users Last Activity","Brukers Siste Aktivitet"}.
{"Validate","Bekrefte gyldighet"}.
{"vCard User Search","vCard Bruker Søk"}.
{"Virtual Hosts","Virtuella Maskiner"}.
{"Visitors are not allowed to change their nicknames in this room","Besøkende får ikke lov å endre kallenavn i dette "}.
{"Visitors are not allowed to send messages to all occupants","Besøkende får ikke sende meldinger til alle deltakere"}.
{"Wednesday","onsdag"}.

View File

@ -1352,8 +1352,8 @@ msgid "~s access rule configuration"
msgstr "tilgangsregel konfigurasjon for ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "virtuella ejabberd maskiner"
msgid "Virtual Hosts"
msgstr "Virtuella Maskiner"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -80,7 +80,6 @@
{"ejabberd Publish-Subscribe module","Moduł Publish-Subscribe"}.
{"ejabberd SOCKS5 Bytestreams module","Moduł SOCKS5 Bytestreams"}.
{"ejabberd vCard module","Moduł vCard ejabberd"}.
{"ejabberd virtual hosts","wirtualne hosty ejabberd"}.
{"ejabberd Web Admin","ejabberd: Panel Administracyjny"}.
{"Elements","Elementy"}.
{"Email","Email"}.
@ -388,6 +387,7 @@
{"User","Użytkownik"}.
{"Validate","Potwierdź"}.
{"vCard User Search","Wyszukiwanie vCard użytkowników"}.
{"Virtual Hosts","Wirtualne Hosty"}.
{"Visitors are not allowed to change their nicknames in this room","Uczestnicy tego pokoju nie mogą zmieniać swoich nicków"}.
{"Visitors are not allowed to send messages to all occupants","Odwiedzający nie mogą wysyłać wiadomości do wszystkich obecnych"}.
{"Wednesday","Środa"}.

View File

@ -1360,8 +1360,8 @@ msgid "~s access rule configuration"
msgstr "~s konfiguracja zasad dostępu"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "wirtualne hosty ejabberd"
msgid "Virtual Hosts"
msgstr "Wirtualne Hosty"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -78,7 +78,6 @@
{"ejabberd Publish-Subscribe module","Módulo para Publicar Tópicos do ejabberd"}.
{"ejabberd SOCKS5 Bytestreams module","Modulo ejabberd SOCKS5 Bytestreams"}.
{"ejabberd vCard module","Módulo vCard para ejabberd"}.
{"ejabberd virtual hosts","Hosts virtuais de ejabberd"}.
{"ejabberd Web Admin","ejabberd Web Admin"}.
{"Elements","Elementos"}.
{"Email","Email"}.
@ -376,6 +375,7 @@
{"User","Usuário"}.
{"Validate","Validar"}.
{"vCard User Search","Busca de Usuário vCard"}.
{"Virtual Hosts","Hosts virtuais"}.
{"Visitors are not allowed to change their nicknames in this room","Nesta sala, os visitantes não pode mudar seus apelidos"}.
{"Visitors are not allowed to send messages to all occupants","Os visitantes não podem enviar mensagens a todos os ocupantes"}.
{"Wednesday","Quarta"}.

View File

@ -1368,8 +1368,8 @@ msgid "~s access rule configuration"
msgstr "Configuração da Regra de Acesso ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "Hosts virtuais de ejabberd"
msgid "Virtual Hosts"
msgstr "Hosts virtuais"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -1425,8 +1425,8 @@ msgstr "Configuração das Regra de Acesso ~s"
#: web/ejabberd_web_admin.erl:1031
#, fuzzy
msgid "ejabberd virtual hosts"
msgstr "Estatísticas do ejabberd"
msgid "Virtual Hosts"
msgstr "Servidores virtuales"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -80,7 +80,6 @@
{"ejabberd Publish-Subscribe module","Модуль ejabberd Публикации-Подписки"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams модуль"}.
{"ejabberd vCard module","ejabberd vCard модуль"}.
{"ejabberd virtual hosts","Виртуальные хосты ejabberd"}.
{"ejabberd Web Admin","Web-интерфейс администрирования ejabberd"}.
{"Elements","Элементы"}.
{"Email","Электронная почта"}.
@ -388,6 +387,7 @@
{"User","Пользователь"}.
{"Validate","Утвердить"}.
{"vCard User Search","Поиск пользователей по vCard"}.
{"Virtual Hosts","Виртуальные хосты"}.
{"Visitors are not allowed to change their nicknames in this room","Посетителям запрещено изменять свои псевдонимы в этой комнате"}.
{"Visitors are not allowed to send messages to all occupants","Посетителям не разрешается посылать сообщения всем присутствующим"}.
{"Wednesday","Среда"}.

View File

@ -1363,8 +1363,8 @@ msgid "~s access rule configuration"
msgstr "Конфигурация правила доступа ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "Виртуальные хосты ejabberd"
msgid "Virtual Hosts"
msgstr "Виртуальные хосты"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -77,7 +77,6 @@
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe modul"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams modul"}.
{"ejabberd vCard module","ejabberd vCard modul"}.
{"ejabberd virtual hosts","ejabberd virtuálne servery"}.
{"ejabberd Web Admin","ejabberd Web Admin"}.
{"Elements","Prvky"}.
{"Email","E-mail"}.
@ -362,6 +361,7 @@
{"User","Užívateľ"}.
{"Validate","Overiť"}.
{"vCard User Search","Hľadať užívateľov vo vCard"}.
{"Virtual Hosts","Virtuálne servery"}.
{"Visitors are not allowed to change their nicknames in this room","V tejto miestnosti nieje povolené meniť prezývky"}.
{"Visitors are not allowed to send messages to all occupants","Návštevníci nemajú povolené zasielať správy všetkým prihláseným do konferencie"}.
{"Wednesday","Streda"}.

View File

@ -1355,8 +1355,8 @@ msgid "~s access rule configuration"
msgstr "~s konfigurácia prístupového pravidla"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "ejabberd virtuálne servery"
msgid "Virtual Hosts"
msgstr "Virtuálne servery"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"
@ -1788,9 +1788,6 @@ msgstr ""
#~ msgid "(Raw)"
#~ msgstr "(Raw)"
#~ msgid "Virtual Hosts"
#~ msgstr "Virtuálne servery"
#~ msgid "Specified nickname is already registered"
#~ msgstr "Zadaná prezývka je už registrovaná"

View File

@ -72,7 +72,6 @@
{"ejabberd Publish-Subscribe module","ejabberd publikprenumerations modul"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestrem modul"}.
{"ejabberd vCard module","ejabberd vCard-modul"}.
{"ejabberd virtual hosts","Virtuella ejabberd-servrar"}.
{"ejabberd Web Admin","ejabberd Web Admin"}.
{"Elements","Elements"}.
{"Email","Email"}.
@ -348,6 +347,7 @@
{"Users Last Activity","Användarens senaste aktivitet"}.
{"Validate","Validera"}.
{"vCard User Search","vCard användare sök"}.
{"Virtual Hosts","Virtuella servrar"}.
{"Visitors are not allowed to change their nicknames in this room","Det är inte tillåtet for gäster att ändra sina smeknamn i detta rummet"}.
{"Visitors are not allowed to send messages to all occupants","Besökare får inte skicka medelande till alla"}.
{"Wednesday","Onsdag"}.

View File

@ -1371,8 +1371,8 @@ msgid "~s access rule configuration"
msgstr "Åtkomstregelkonfiguration för ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "Virtuella ejabberd-servrar"
msgid "Virtual Hosts"
msgstr "Virtuella servrar"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -66,7 +66,6 @@
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe module"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams module"}.
{"ejabberd vCard module","ejabberd vCard module"}.
{"ejabberd virtual hosts","โฮสต์เสมือน ejabberd"}.
{"Email","อีเมล"}.
{"Enable logging","เปิดใช้งานการบันทึก"}.
{"End User Session","สิ้นสุดเซสชันของผู้ใช้"}.
@ -297,6 +296,7 @@
{"Users Last Activity","กิจกรรมล่าสุดของผู้ใช้"}.
{"Validate","ตรวจสอบ"}.
{"vCard User Search","ค้นหาผู้ใช้ vCard "}.
{"Virtual Hosts","โฮสต์เสมือน"}.
{"Visitors are not allowed to send messages to all occupants","ผู้เยี่ยมเยือนไม่ได้รับอนุญาตให้ส่งข้อความถึงผู้ครอบครองห้องทั้งหมด"}.
{"Wednesday","วันพุธ"}.
{"When to send the last published item","เวลาที่ส่งรายการที่เผยแพร่ครั้งล่าสุด"}.

View File

@ -1372,8 +1372,8 @@ msgid "~s access rule configuration"
msgstr "~s การกำหนดค่ากฎการเข้าถึง"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "โฮสต์เสมือน ejabberd"
msgid "Virtual Hosts"
msgstr "โฮสต์เสมือน"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"
@ -1803,9 +1803,6 @@ msgstr ""
#~ msgid "(Raw)"
#~ msgstr "(ข้อมูลดิบ)"
#~ msgid "Virtual Hosts"
#~ msgstr "โฮสต์เสมือน"
#~ msgid "Specified nickname is already registered"
#~ msgstr "ชื่อเล่นที่ระบุได้รับการลงได้ทะเบียนแล้ว"

View File

@ -73,7 +73,6 @@
{"ejabberd Publish-Subscribe module","ejabberd Publish-Subscribe modülü"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams modülü"}.
{"ejabberd vCard module","ejabberd vCard modülü"}.
{"ejabberd virtual hosts","ejabberd sanal sunucuları"}.
{"ejabberd Web Admin","ejabberd Web Yöneticisi"}.
{"Elements","Elementler"}.
{"Email","E-posta"}.
@ -356,6 +355,7 @@
{"Users Last Activity","Kullanıcıların Son Aktiviteleri"}.
{"Validate","Geçerli"}.
{"vCard User Search","vCard Kullanıcı Araması"}.
{"Virtual Hosts","Sanal Sunucuları"}.
{"Visitors are not allowed to change their nicknames in this room","Bu odada ziyaretçilerin takma isimlerini değiştirmesine izin verilmiyor"}.
{"Visitors are not allowed to send messages to all occupants","Ziyaretçilerin odadaki tüm sakinlere mesaj göndermesine izin verilmiyor"}.
{"Wednesday","Çarşamba"}.

View File

@ -1375,8 +1375,8 @@ msgid "~s access rule configuration"
msgstr "~s erişim kuralları ayarları"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "ejabberd sanal sunucuları"
msgid "Virtual Hosts"
msgstr "Sanal Sunucuları"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -80,7 +80,6 @@
{"ejabberd Publish-Subscribe module","Модуль ejabberd Публікації-Абонування"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 Bytestreams модуль"}.
{"ejabberd vCard module","ejabberd vCard модуль"}.
{"ejabberd virtual hosts","віртуальні хости ejabberd"}.
{"ejabberd Web Admin","Веб-інтерфейс Адміністрування ejabberd"}.
{"Elements","Елементи"}.
{"Email","Електронна пошта"}.
@ -388,6 +387,7 @@
{"User","Користувач"}.
{"Validate","Затвердити"}.
{"vCard User Search","Пошук користувачів по vCard"}.
{"Virtual Hosts","віртуальні хости"}.
{"Visitors are not allowed to change their nicknames in this room","Відвідувачам не дозволяється змінювати псевдонім в цій кімнаті"}.
{"Visitors are not allowed to send messages to all occupants","Відвідувачам не дозволяється надсилати повідомлення всім присутнім"}.
{"Wednesday","Середа"}.

View File

@ -1368,8 +1368,8 @@ msgid "~s access rule configuration"
msgstr "Конфігурація правила доступу ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "віртуальні хости ejabberd"
msgid "Virtual Hosts"
msgstr "віртуальні хости"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"

View File

@ -66,7 +66,6 @@
{"ejabberd Publish-Subscribe module","Môdun ejabberd Xuất Bản-Đăng Ký Bản quyền"}.
{"ejabberd SOCKS5 Bytestreams module","Môdun SOCKS5 Bytestreams Bản quyền"}.
{"ejabberd vCard module","Môdun ejabberd vCard Bản quyền"}.
{"ejabberd virtual hosts","Máy chủ ảo ejabberd"}.
{"Email","Email"}.
{"Enable logging","Cho phép ghi nhật ký"}.
{"End User Session","Kết Thúc Phiên Giao Dịch Người Sử Dụng"}.
@ -297,6 +296,7 @@
{"Users","Người sử dụng"}.
{"Validate","Xác nhận hợp lệ"}.
{"vCard User Search","Tìm Kiếm Người Sử Dụng vCard"}.
{"Virtual Hosts","Máy Chủ Ảo"}.
{"Visitors are not allowed to send messages to all occupants","Người ghé thăm không được phép gửi thư đến tất cả các người tham dự"}.
{"Wednesday","Thứ Tư"}.
{"When to send the last published item","Khi cần gửi mục được xuất bản cuối cùng"}.

View File

@ -1395,8 +1395,8 @@ msgid "~s access rule configuration"
msgstr "~s cấu hình quy tắc truy cập"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "Máy chủ ảo ejabberd"
msgid "Virtual Hosts"
msgstr "Máy Chủ Ảo"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"
@ -1828,9 +1828,6 @@ msgstr ""
#~ msgid "(Raw)"
#~ msgstr "(Thô)"
#~ msgid "Virtual Hosts"
#~ msgstr "Máy Chủ Ảo"
#~ msgid "Specified nickname is already registered"
#~ msgstr "Bí danh xác định đã đăng ký rồi"

View File

@ -69,7 +69,6 @@
{"ejabberd Publish-Subscribe module","Module d' eplaidaedje-abounmint po ejabberd"}.
{"ejabberd SOCKS5 Bytestreams module","Module SOCKS5 Bytestreams po ejabberd"}.
{"ejabberd vCard module","Module vCard ejabberd"}.
{"ejabberd virtual hosts","Forveyous sierveus da ejabberd"}.
{"ejabberd Web Admin","Manaedjeu waibe ejabberd"}.
{"Email","Emile"}.
{"Enable logging","Mete en alaedje li djournå"}.
@ -310,6 +309,7 @@
{"User","Uzeu"}.
{"Validate","Valider"}.
{"vCard User Search","Calpin des uzeus"}.
{"Virtual Hosts","Forveyous sierveus"}.
{"Visitors are not allowed to change their nicknames in this room","Les viziteus èn polèt nén candjî leus metous no po ç' såle ci"}.
{"Visitors are not allowed to send messages to all occupants","Les viziteus n' polèt nén evoyî des messaedjes a tos les prezints"}.
{"Wednesday","mierkidi"}.

View File

@ -1393,8 +1393,8 @@ msgid "~s access rule configuration"
msgstr "Apontiaedje des rîles d' accès a ~s"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "Forveyous sierveus da ejabberd"
msgid "Virtual Hosts"
msgstr "Forveyous sierveus"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"
@ -1827,9 +1827,6 @@ msgstr ""
#~ msgid "(Raw)"
#~ msgstr "(Dinêyes brutes)"
#~ msgid "Virtual Hosts"
#~ msgstr "Forveyous sierveus"
#~ msgid "Specified nickname is already registered"
#~ msgstr "Li no metou dné est ddja edjîstré"

View File

@ -80,7 +80,6 @@
{"ejabberd Publish-Subscribe module","ejabberd 发行-订阅模块"}.
{"ejabberd SOCKS5 Bytestreams module","ejabberd SOCKS5 字节流模块"}.
{"ejabberd vCard module","ejabberd vCard 模块"}.
{"ejabberd virtual hosts","ejabberd 虚拟主机"}.
{"ejabberd Web Admin","ejabberd 网页管理"}.
{"Elements","元素"}.
{"Email","电子邮件"}.
@ -388,6 +387,7 @@
{"User","用户"}.
{"Validate","确认"}.
{"vCard User Search","vCard 用户搜索"}.
{"Virtual Hosts","虚拟主机"}.
{"Visitors are not allowed to change their nicknames in this room","此房间不允许用户更改昵称"}.
{"Visitors are not allowed to send messages to all occupants","不允许访客给所有占有者发送消息"}.
{"Wednesday","星期三"}.

View File

@ -1338,8 +1338,8 @@ msgid "~s access rule configuration"
msgstr "~s 访问规则配置"
#: web/ejabberd_web_admin.erl:1031
msgid "ejabberd virtual hosts"
msgstr "ejabberd 虚拟主机"
msgid "Virtual Hosts"
msgstr "虚拟主机"
#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046
msgid "Users"
@ -1765,9 +1765,6 @@ msgstr "取消注册"
#~ msgid "(Raw)"
#~ msgstr "(原始格式)"
#~ msgid "Virtual Hosts"
#~ msgstr "虚拟主机"
#~ msgid "Specified nickname is already registered"
#~ msgstr "指定的昵称已被注册"

View File

@ -597,6 +597,40 @@ BEGIN
END
GO
/******************************************************************/
/****** Object: StoredProcedure [dbo].[set_roster_version] **/
/** Update users roster_version **/
/******************************************************************/
CREATE PROCEDURE [dbo].[set_roster_version]
@Username varchar(200),
@Version varchar(50)
AS
BEGIN
IF EXISTS (SELECT username FROM roster_version WITH (NOLOCK) WHERE username=@Username)
BEGIN
UPDATE roster_version SET username=@Username, version=@Version WHERE username=@Username;
END
ELSE
BEGIN
INSERT INTO roster_version (username, version) VALUES (@Username, @Version);
END
END
GO
/******************************************************************/
/****** Object: StoredProcedure [dbo].[get_roster_version] **/
/** Retrive the user roster_version **/
/******************************************************************/
CREATE PROCEDURE [dbo].[get_roster_version]
@Username varchar(200)
AS
BEGIN
SELECT roster_version.version as version
FROM roster_version WITH (NOLOCK)
WHERE username=@Username;
END
GO
/***************************************************************/
/****** Object: StoredProcedure [dbo].[clean_spool_msg] ******/
/** Delete messages older that 3 days from spool **/

View File

@ -918,6 +918,40 @@ BEGIN
END
GO
/******************************************************************/
/****** Object: StoredProcedure [dbo].[set_roster_version] **/
/** Update users roster_version **/
/******************************************************************/
CREATE PROCEDURE [dbo].[set_roster_version]
@Username varchar(200),
@Version varchar(8000)
AS
BEGIN
IF EXISTS (SELECT username FROM roster_version WITH (NOLOCK) WHERE username=@Username)
BEGIN
UPDATE roster_version SET username=@Username, version=@Version WHERE username=@Username;
END
ELSE
BEGIN
INSERT INTO roster_version (username, version) VALUES (@Username, @Version);
END
END
GO
/******************************************************************/
/****** Object: StoredProcedure [dbo].[get_roster_version] **/
/** Retrive the user roster_version **/
/******************************************************************/
CREATE PROCEDURE [dbo].[get_roster_version]
@Username varchar(200)
AS
BEGIN
SELECT roster_version.version as version
FROM roster_version WITH (NOLOCK)
WHERE username=@Username;
END
GO
/***************************************************************/
/****** Object: StoredProcedure [dbo].[clean_spool_msg] ******/
/** Delete messages older that 3 days from spool **/

View File

@ -90,6 +90,8 @@
-define(generic, true).
-endif.
-include("ejabberd.hrl").
%% Almost a copy of string:join/2.
%% We use this version because string:join/2 is relatively
%% new function (introduced in R12B-0).
@ -882,8 +884,14 @@ count_records_where(LServer, Table, WhereClause) ->
["select count(*) from ", Table, " with (nolock) ", WhereClause]).
get_roster_version(LServer, LUser) ->
ejabberd_odbc:sql_query(LServer,
["select version from dbo.roster_version with (nolock) where username = '", LUser, "'"]).
set_roster_version(LUser, Version) ->
update_t("dbo.roster_version", ["username", "version"], [LUser, Version], ["username = '", LUser, "'"]).
ejabberd_odbc:sql_query(
LServer,
["EXECUTE dbo.get_roster_version '", LUser, "'"]).
set_roster_version(Username, Version) ->
%% This function doesn't know the vhost, so we hope it's the first one defined:
LServer = ?MYNAME,
ejabberd_odbc:sql_query(
LServer,
["EXECUTE dbo.set_roster_version '", Username, "', '", Version, "'"]).
-endif.

View File

@ -207,9 +207,12 @@ terminate(_Reason, _S) ->
store(List) ->
_ = [(assure_group(Name)
andalso
[join_group(Name, P) || P <- Members -- group_members(Name)]) ||
store2(Name, Members)) ||
[Name, Members] <- List],
ok.
store2(Name, Members) ->
[join_group(Name, P) || P <- Members -- group_members(Name)],
true.
assure_group(Name) ->
Key = {group, Name},

View File

@ -636,7 +636,13 @@ make_xhtml_output(State, Status, Headers, XHTML) ->
end, HeadersOut),
SL = [Version, integer_to_list(Status), " ",
code_to_phrase(Status), "\r\n"],
[SL, H, "\r\n", Data].
Data2 = case State#state.request_method of
'HEAD' -> "";
_ -> Data
end,
[SL, H, "\r\n", Data2].
make_text_output(State, Status, Headers, Text) when is_list(Text) ->
make_text_output(State, Status, Headers, list_to_binary(Text));
@ -673,7 +679,13 @@ make_text_output(State, Status, Headers, Data) when is_binary(Data) ->
end, HeadersOut),
SL = [Version, integer_to_list(Status), " ",
code_to_phrase(Status), "\r\n"],
[SL, H, "\r\n", Data].
Data2 = case State#state.request_method of
'HEAD' -> "";
_ -> Data
end,
[SL, H, "\r\n", Data2].
parse_lang(Langs) ->

View File

@ -64,11 +64,15 @@ get_acl_rule(["additions.js"],_) -> {"localhost", [all]};
get_acl_rule(["vhosts"],_) -> {"localhost", [all]};
%% The pages of a vhost are only accesible if the user is admin of that vhost:
get_acl_rule(["server", VHost | _RPath], 'GET') -> {VHost, [configure, webadmin_view]};
get_acl_rule(["server", VHost | _RPath], Method)
when Method=:='GET' orelse Method=:='HEAD' ->
{VHost, [configure, webadmin_view]};
get_acl_rule(["server", VHost | _RPath], 'POST') -> {VHost, [configure]};
%% Default rule: only global admins can access any other random page
get_acl_rule(_RPath, 'GET') -> {global, [configure, webadmin_view]};
get_acl_rule(_RPath, Method)
when Method=:='GET' orelse Method=:='HEAD' ->
{global, [configure, webadmin_view]};
get_acl_rule(_RPath, 'POST') -> {global, [configure]}.
is_acl_match(Host, Rules, Jid) ->
@ -1028,7 +1032,7 @@ process_admin(global,
auth = {_, _Auth, AJID},
lang = Lang}) ->
Res = list_vhosts(Lang, AJID),
make_xhtml(?H1GL(?T("ejabberd virtual hosts"), "virtualhost", "Virtual Hosting") ++ Res, global, Lang, AJID);
make_xhtml(?H1GL(?T("Virtual Hosts"), "virtualhost", "Virtual Hosting") ++ Res, global, Lang, AJID);
process_admin(Host,
#request{path = ["users"],

View File

@ -86,8 +86,9 @@ process([], #request{method = 'GET', lang = Lang}) ->
process(["register.css"], #request{method = 'GET'}) ->
serve_css();
process(["new"], #request{method = 'GET', lang = Lang, host = Host}) ->
form_new_get(Host, Lang);
process(["new"], #request{method = 'GET', lang = Lang, host = Host, ip = IP}) ->
{Addr, _Port} = IP,
form_new_get(Host, Lang, Addr);
process(["delete"], #request{method = 'GET', lang = Lang, host = Host}) ->
form_del_get(Host, Lang);
@ -185,8 +186,8 @@ index_page(Lang) ->
%%% Formulary new account GET
%%%----------------------------------------------------------------------
form_new_get(Host, Lang) ->
CaptchaEls = build_captcha_li_list(Lang),
form_new_get(Host, Lang, IP) ->
CaptchaEls = build_captcha_li_list(Lang, IP),
HeadEls = [
?XCT("title", "Register a Jabber account"),
?XA("link",
@ -336,27 +337,31 @@ form_new_post(Username, Host, Password, {Id, Key}) ->
%%% Formulary Captcha support for new GET/POST
%%%----------------------------------------------------------------------
build_captcha_li_list(Lang) ->
build_captcha_li_list(Lang, IP) ->
case ejabberd_captcha:is_feature_available() of
true -> build_captcha_li_list2(Lang);
true -> build_captcha_li_list2(Lang, IP);
false -> []
end.
build_captcha_li_list2(Lang) ->
Id = randoms:get_string(),
build_captcha_li_list2(Lang, IP) ->
SID = "",
From = #jid{user = "", server = "test", resource = ""},
To = #jid{user = "", server = "test", resource = ""},
Args = [],
ejabberd_captcha:create_captcha(Id, SID, From, To, Lang, Args),
{_, {CImg,CText,CId,CKey}} = ejabberd_captcha:build_captcha_html(Id, Lang),
case ejabberd_captcha:create_captcha(SID, From, To, Lang, IP, Args) of
{ok, Id, _} ->
{_, {CImg,CText,CId,CKey}} =
ejabberd_captcha:build_captcha_html(Id, Lang),
[?XE("li", [CText,
?C(" "),
CId,
CKey,
?BR,
CImg]
)].
)];
_ ->
[]
end.
%%%----------------------------------------------------------------------
%%% Formulary change password GET