diff --git a/doc/guide.tex b/doc/guide.tex index 2a8837d46..bb72d30c8 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -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,15 +2633,16 @@ 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 of IQ queries of a namespace with this discipline. In addition, the processing 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 +\titem{\{queues, N\}} N separate queues are created to process the + 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} diff --git a/src/ejabberd.cfg.example b/src/ejabberd.cfg.example index 52ffc6825..c776a8cb9 100644 --- a/src/ejabberd.cfg.example +++ b/src/ejabberd.cfg.example @@ -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 diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl index 1d9417d81..2caef6e1f 100644 --- a/src/ejabberd_app.erl +++ b/src/ejabberd_app.erl @@ -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()]), diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index a44f66a7d..bc8b087db 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -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,45 +592,55 @@ wait_for_auth({xmlstreamelement, El}, StateData) -> "(~w) Accepted legacy authentication for ~s by ~p", [StateData#state.socket, jlib:jid_to_string(JID), AuthModule]), - 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, - StateData#state.server, - {[], []}, - [U, StateData#state.server]), - LJID = jlib:jid_tolower( - jlib:jid_remove_resource(JID)), - Fs1 = [LJID | Fs], - Ts1 = [LJID | Ts], - PrivList = - ejabberd_hooks:run_fold( - privacy_get_user_list, StateData#state.server, - #userlist{}, - [U, StateData#state.server]), - NewStateData = StateData#state{ - user = U, - resource = R, - jid = JID, - sid = SID, - conn = Conn, - auth_module = AuthModule, - pres_f = ?SETS:from_list(Fs1), - pres_t = ?SETS:from_list(Ts1), - privacy_list = PrivList}, - DebugFlag = ejabberd_hooks:run_fold(c2s_debug_start_hook, - NewStateData#state.server, - false, - [self(), NewStateData]), - maybe_migrate(session_established, NewStateData#state{debug=DebugFlag}); + 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), + Res1 = jlib:make_result_iq_reply(El), + Res = setelement(4, Res1, []), + send_element(StateData, Res), + change_shaper(StateData, JID), + {Fs, Ts} = ejabberd_hooks:run_fold( + roster_get_subscription_lists, + StateData#state.server, + {[], []}, + [U, StateData#state.server]), + LJID = jlib:jid_tolower( + jlib:jid_remove_resource(JID)), + Fs1 = [LJID | Fs], + Ts1 = [LJID | Ts], + PrivList = + ejabberd_hooks:run_fold( + privacy_get_user_list, + StateData#state.server, + #userlist{}, + [U, StateData#state.server]), + NewStateData = + StateData#state{ + user = U, + resource = R, + jid = JID, + sid = SID, + conn = Conn, + auth_module = AuthModule, + pres_f = ?SETS:from_list(Fs1), + pres_t = ?SETS:from_list(Ts1), + privacy_list = PrivList}, + DebugFlag = ejabberd_hooks:run_fold( + c2s_debug_start_hook, + NewStateData#state.server, + false, + [self(), NewStateData]), + maybe_migrate(session_established, + NewStateData#state{debug=DebugFlag}) + end; _ -> ?INFO_MSG( "(~w) Failed legacy authentication for ~s", @@ -713,21 +732,30 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) -> Mech, ClientIn) of {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]), - fsm_next_state(wait_for_stream, - StateData#state{ - streamid = new_id(), - authenticated = true, - auth_module = AuthModule, - user = U }); + catch (StateData#state.sockmod):reset_stream( + StateData#state.socket), + 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 }) + end; {continue, ServerOut, NewSASLState} -> send_element(StateData, {xmlelement, "challenge", @@ -867,20 +895,29 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) -> ClientIn) of {ok, Props} -> catch (StateData#state.sockmod):reset_stream( - StateData#state.socket), - send_element(StateData, - {xmlelement, "success", - [{"xmlns", ?NS_SASL}], []}), + StateData#state.socket), 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]), - fsm_next_state(wait_for_stream, - StateData#state{ - streamid = new_id(), - authenticated = true, - auth_module = AuthModule, - user = U}); + 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}) + 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" "\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. diff --git a/src/ejabberd_c2s.hrl b/src/ejabberd_c2s.hrl index 9af6b02d5..7889c0de5 100644 --- a/src/ejabberd_c2s.hrl +++ b/src/ejabberd_c2s.hrl @@ -57,6 +57,7 @@ conn = unknown, auth_module = unknown, ip, + redirect = false, aux_fields = [], fsm_limit_opts, lang, diff --git a/src/ejabberd_captcha.erl b/src/ejabberd_captcha.erl index a78deb192..f7b3f4778 100644 --- a/src/ejabberd_captcha.erl +++ b/src/ejabberd_captcha.erl @@ -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)), @@ -96,18 +97,18 @@ create_captcha(SID, From, To, Lang, Args) OOB = {xmlelement, "x", [{"xmlns", ?NS_OOB}], [{xmlelement, "url", [], [{xmlcdata, get_url(Id)}]}]}, Tref = erlang:send_after(?CAPTCHA_LIFETIME, ?MODULE, {remove_id, Id}), - ets:insert(captcha, #captcha{id=Id, pid=self(), key=Key, + 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). diff --git a/src/ejabberd_cluster.erl b/src/ejabberd_cluster.erl index c189eb450..bc2f85da6 100644 --- a/src/ejabberd_cluster.erl +++ b/src/ejabberd_cluster.erl @@ -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), diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index 4ec848b23..848bcf7ca 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -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) diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index 343a66528..4d5f2ecb4 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -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,23 +125,35 @@ 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, - timer = TRef}). + module = Module, + function = Function, + timer = TRef}). register_iq_handler(Host, XMLNS, Module, Fun) -> ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun}. diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index 13c2d6d07..99403f75c 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -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 diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index cca7db502..a96ae8a3a 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -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, + [] -> []; + [#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) -> - case catch do_route(From, To, Packet) of - {'EXIT', Reason} -> - ?ERROR_MSG("~p~nwhen processing: ~p", - [Reason, {From, To, Packet}]); - _ -> - ok +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 diff --git a/src/ejabberd_sup.erl b/src/ejabberd_sup.erl index ca531cf1d..f7c303333 100644 --- a/src/ejabberd_sup.erl +++ b/src/ejabberd_sup.erl @@ -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, diff --git a/src/ejabberdctl.cfg.example b/src/ejabberdctl.cfg.example index 4a3db1c8b..2106e3d22 100644 --- a/src/ejabberdctl.cfg.example +++ b/src/ejabberdctl.cfg.example @@ -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. # diff --git a/src/ejabberdctl.template b/src/ejabberdctl.template index 89b2d0cc1..172b68dc7 100644 --- a/src/ejabberdctl.template +++ b/src/ejabberdctl.template @@ -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#*-}" +KERNEL_OPTS="" +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" diff --git a/src/expat_erl.c b/src/expat_erl.c index 88aaf2b1e..e38420f5f 100644 --- a/src/expat_erl.c +++ b/src/expat_erl.c @@ -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; diff --git a/src/extauth.erl b/src/extauth.erl index c1721a0ef..f49392983 100644 --- a/src/extauth.erl +++ b/src/extauth.erl @@ -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 diff --git a/src/jlib.hrl b/src/jlib.hrl index a4f8fd0da..7ac220cc0 100644 --- a/src/jlib.hrl +++ b/src/jlib.hrl @@ -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, diff --git a/src/mod_ack.erl b/src/mod_ack.erl index 02f5ebb1a..68606283f 100644 --- a/src/mod_ack.erl +++ b/src/mod_ack.erl @@ -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}}; diff --git a/src/mod_irc/mod_irc_connection.erl b/src/mod_irc/mod_irc_connection.erl index 55432dd1c..c342f2877 100644 --- a/src/mod_irc/mod_irc_connection.erl +++ b/src/mod_irc/mod_irc_connection.erl @@ -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 %%%---------------------------------------------------------------------- diff --git a/src/mod_muc/mod_muc.erl b/src/mod_muc/mod_muc.erl index ff6482f73..078cb36c7 100644 --- a/src/mod_muc/mod_muc.erl +++ b/src/mod_muc/mod_muc.erl @@ -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( - Host, ServerHost, Access, - Room, HistorySize, - RoomShaper, From, - Nick, DefRoomOpts), - register_room(Host, Room, Pid), - mod_muc_room:route(Pid, From, Nick, Packet), - ok; + case start_new_room( + Host, ServerHost, Access, + Room, HistorySize, + RoomShaper, From, + 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", diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl index d1a3db346..5bf88a675 100644 --- a/src/mod_muc/mod_muc_room.erl +++ b/src/mod_muc/mod_muc_room.erl @@ -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; _ -> - captcha_required + 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} diff --git a/src/mod_muc/mod_muc_room.hrl b/src/mod_muc/mod_muc_room.hrl index eb5060e43..192ecf845 100644 --- a/src/mod_muc/mod_muc_room.hrl +++ b/src/mod_muc/mod_muc_room.hrl @@ -45,7 +45,8 @@ password = "", anonymous = true, max_users = ?MAX_USERS_DEFAULT, - logging = false + logging = false, + captcha_whitelist = ?SETS:empty() }). -record(user, {jid, diff --git a/src/mod_ping.erl b/src/mod_ping.erl index 87e34611e..463bffb5c 100644 --- a/src/mod_ping.erl +++ b/src/mod_ping.erl @@ -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), diff --git a/src/mod_privacy_odbc.erl b/src/mod_privacy_odbc.erl index 64543faa8..2df9ee27a 100644 --- a/src/mod_privacy_odbc.erl +++ b/src/mod_privacy_odbc.erl @@ -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 -> diff --git a/src/mod_register.erl b/src/mod_register.erl index 4b90be8df..048678373 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -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( diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 6ffbca2fe..63162b4d0 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -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), diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index c9825531d..a05113773 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -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; diff --git a/src/msgs/ca.msg b/src/msgs/ca.msg index 56a737c18..2742289a8 100644 --- a/src/msgs/ca.msg +++ b/src/msgs/ca.msg @@ -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"}. diff --git a/src/msgs/ca.po b/src/msgs/ca.po index c916641c1..4554e91cc 100644 --- a/src/msgs/ca.po +++ b/src/msgs/ca.po @@ -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" diff --git a/src/msgs/cs.msg b/src/msgs/cs.msg index 21d04c334..eed1c47d5 100644 --- a/src/msgs/cs.msg +++ b/src/msgs/cs.msg @@ -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"}. diff --git a/src/msgs/cs.po b/src/msgs/cs.po index fd3bd337f..c3f02cbf5 100644 --- a/src/msgs/cs.po +++ b/src/msgs/cs.po @@ -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" diff --git a/src/msgs/de.msg b/src/msgs/de.msg index 224b5241d..6dde04f8c 100644 --- a/src/msgs/de.msg +++ b/src/msgs/de.msg @@ -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"}. diff --git a/src/msgs/de.po b/src/msgs/de.po index 90abdd6ea..baec05323 100644 --- a/src/msgs/de.po +++ b/src/msgs/de.po @@ -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" diff --git a/src/msgs/ejabberd.pot b/src/msgs/ejabberd.pot index 3311d6b71..921a307fe 100644 --- a/src/msgs/ejabberd.pot +++ b/src/msgs/ejabberd.pot @@ -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 diff --git a/src/msgs/el.msg b/src/msgs/el.msg index d0b68fc7e..4fa37a046 100644 --- a/src/msgs/el.msg +++ b/src/msgs/el.msg @@ -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","Τετάρτη"}. diff --git a/src/msgs/el.po b/src/msgs/el.po index 35a74ac30..68561de5a 100644 --- a/src/msgs/el.po +++ b/src/msgs/el.po @@ -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" diff --git a/src/msgs/eo.msg b/src/msgs/eo.msg index 5fd21c37c..435f44d4f 100644 --- a/src/msgs/eo.msg +++ b/src/msgs/eo.msg @@ -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"}. diff --git a/src/msgs/eo.po b/src/msgs/eo.po index 9d84ba3eb..62b93a76f 100644 --- a/src/msgs/eo.po +++ b/src/msgs/eo.po @@ -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" diff --git a/src/msgs/es.msg b/src/msgs/es.msg index 3b5a7a761..17598c45a 100644 --- a/src/msgs/es.msg +++ b/src/msgs/es.msg @@ -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"}. diff --git a/src/msgs/es.po b/src/msgs/es.po index fffef21f2..0d791b811 100644 --- a/src/msgs/es.po +++ b/src/msgs/es.po @@ -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 \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" diff --git a/src/msgs/fr.msg b/src/msgs/fr.msg index 724582ec1..ee9ec2a38 100644 --- a/src/msgs/fr.msg +++ b/src/msgs/fr.msg @@ -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"}. diff --git a/src/msgs/fr.po b/src/msgs/fr.po index 8ee35396e..7a807d877 100644 --- a/src/msgs/fr.po +++ b/src/msgs/fr.po @@ -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" diff --git a/src/msgs/gl.msg b/src/msgs/gl.msg index d6db76590..219bea35d 100644 --- a/src/msgs/gl.msg +++ b/src/msgs/gl.msg @@ -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"}. diff --git a/src/msgs/gl.po b/src/msgs/gl.po index 3fe3b09e9..0e0036831 100644 --- a/src/msgs/gl.po +++ b/src/msgs/gl.po @@ -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" diff --git a/src/msgs/id.msg b/src/msgs/id.msg new file mode 100644 index 000000000..1922ad0c7 --- /dev/null +++ b/src/msgs/id.msg @@ -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"}. diff --git a/src/msgs/id.po b/src/msgs/id.po new file mode 100644 index 000000000..e71c74836 --- /dev/null +++ b/src/msgs/id.po @@ -0,0 +1,1799 @@ +# , 2010. +msgid "" +msgstr "" +"Project-Id-Version: 2.1.0-alpha\n" +"PO-Revision-Date: 2011-02-15 07:09+0800\n" +"Last-Translator: Irfan Mahfudz Guntur \n" +"Language-Team: SmartCommunity \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: Indonesian (Bahasa Indonesia)\n" + +#: ejabberd_c2s.erl:424 ejabberd_c2s.erl:727 +msgid "Use of STARTTLS required" +msgstr "Penggunaan STARTTLS diperlukan" + +#: ejabberd_c2s.erl:503 +msgid "No resource provided" +msgstr "Tidak ada sumber daya yang disediakan" + +#: ejabberd_c2s.erl:1147 +msgid "Replaced by new connection" +msgstr "Diganti dengan koneksi baru" + +#: ejabberd_c2s.erl:1832 +msgid "Your active privacy list has denied the routing of this stanza." +msgstr "Daftar privasi aktif Anda telah menolak routing ztanza ini" + +#: ejabberd_captcha.erl:94 ejabberd_captcha.erl:150 ejabberd_captcha.erl:176 +msgid "Enter the text you see" +msgstr "Masukkan teks yang Anda lihat" + +#: ejabberd_captcha.erl:99 +msgid "Your messages to ~s are being blocked. To unblock them, visit ~s" +msgstr "" +"Pesan Anda untuk ~s sedang diblokir. Untuk membuka blokir tersebut, kunjungi " +"~s" + +#: ejabberd_captcha.erl:132 +msgid "If you don't see the CAPTCHA image here, visit the web page." +msgstr "" +"Jika Anda tidak melihat gambar CAPTCHA disini, silahkan kunjungi halaman web." + +#: ejabberd_captcha.erl:144 +msgid "CAPTCHA web page" +msgstr "CAPTCHA laman web" + +#: ejabberd_captcha.erl:302 +msgid "The captcha is valid." +msgstr "Captcha ini benar." + +#: mod_adhoc.erl:95 mod_adhoc.erl:125 mod_adhoc.erl:143 mod_adhoc.erl:161 +msgid "Commands" +msgstr "Perintah" + +#: mod_adhoc.erl:149 mod_adhoc.erl:243 +msgid "Ping" +msgstr "Ping" + +#: mod_adhoc.erl:260 +msgid "Pong" +msgstr "Pong" + +#: mod_announce.erl:506 +msgid "Really delete message of the day?" +msgstr "Benar-benar ingin menghapus pesan harian?" + +#: mod_announce.erl:514 mod_configure.erl:1083 mod_configure.erl:1128 +msgid "Subject" +msgstr "Subyek" + +#: mod_announce.erl:519 mod_configure.erl:1088 mod_configure.erl:1133 +msgid "Message body" +msgstr "Isi Pesan" + +#: mod_announce.erl:599 +msgid "No body provided for announce message" +msgstr "Tidak ada isi pesan yang disediakan untuk mengirimkan pesan" + +#: mod_announce.erl:634 +msgid "Announcements" +msgstr "Pengumuman" + +#: mod_announce.erl:636 +msgid "Send announcement to all users" +msgstr "Kirim pengumuman untuk semua pengguna" + +#: mod_announce.erl:638 +msgid "Send announcement to all users on all hosts" +msgstr "Kirim pengumuman untuk semua pengguna pada semua host" + +#: mod_announce.erl:640 +msgid "Send announcement to all online users" +msgstr "Kirim pengumuman untuk semua pengguna yang online" + +#: mod_announce.erl:642 mod_configure.erl:1078 mod_configure.erl:1123 +msgid "Send announcement to all online users on all hosts" +msgstr "Kirim pengumuman untuk semua pengguna yang online pada semua host" + +#: mod_announce.erl:644 +msgid "Set message of the day and send to online users" +msgstr "Mengatur pesan harian dan mengirimkan ke pengguna yang online" + +#: mod_announce.erl:646 +msgid "Set message of the day on all hosts and send to online users" +msgstr "" +"Mengatur pesan harian pada semua host dan kirimkan ke pengguna yang online" + +#: mod_announce.erl:648 +msgid "Update message of the day (don't send)" +msgstr "Rubah pesan harian (tidak dikirim)" + +#: mod_announce.erl:650 +msgid "Update message of the day on all hosts (don't send)" +msgstr "Rubah pesan harian pada semua host (tidak dikirim)" + +#: mod_announce.erl:652 +msgid "Delete message of the day" +msgstr "Hapus pesan harian" + +#: mod_announce.erl:654 +msgid "Delete message of the day on all hosts" +msgstr "Hapus pesan harian pada semua host" + +#: mod_configure.erl:114 mod_configure.erl:274 mod_configure.erl:296 +#: mod_configure.erl:498 +msgid "Configuration" +msgstr "Pengaturan" + +#: mod_configure.erl:125 mod_configure.erl:576 web/ejabberd_web_admin.erl:1930 +msgid "Database" +msgstr "Database" + +#: mod_configure.erl:127 mod_configure.erl:595 +msgid "Start Modules" +msgstr "Memulai Modul" + +#: mod_configure.erl:129 mod_configure.erl:596 +msgid "Stop Modules" +msgstr "Hentikan Modul" + +#: mod_configure.erl:131 mod_configure.erl:604 web/ejabberd_web_admin.erl:1931 +msgid "Backup" +msgstr "Backup" + +#: mod_configure.erl:133 mod_configure.erl:605 +msgid "Restore" +msgstr "Mengembalikan" + +#: mod_configure.erl:135 mod_configure.erl:606 +msgid "Dump to Text File" +msgstr "Dump menjadi File Teks" + +#: mod_configure.erl:137 mod_configure.erl:615 +msgid "Import File" +msgstr "Impor File" + +#: mod_configure.erl:139 mod_configure.erl:616 +msgid "Import Directory" +msgstr "Impor Direktori" + +#: mod_configure.erl:141 mod_configure.erl:581 mod_configure.erl:1057 +msgid "Restart Service" +msgstr "Restart Layanan" + +#: mod_configure.erl:143 mod_configure.erl:582 mod_configure.erl:1102 +msgid "Shut Down Service" +msgstr "Shut Down Layanan" + +#: mod_configure.erl:145 mod_configure.erl:518 mod_configure.erl:1197 +#: web/ejabberd_web_admin.erl:1524 +msgid "Add User" +msgstr "Tambah Pengguna" + +#: mod_configure.erl:147 mod_configure.erl:519 mod_configure.erl:1219 +msgid "Delete User" +msgstr "Hapus Pengguna" + +#: mod_configure.erl:149 mod_configure.erl:520 mod_configure.erl:1231 +msgid "End User Session" +msgstr "Akhir Sesi Pengguna" + +#: mod_configure.erl:151 mod_configure.erl:521 mod_configure.erl:1243 +#: mod_configure.erl:1255 +msgid "Get User Password" +msgstr "Dapatkan User Password" + +#: mod_configure.erl:153 mod_configure.erl:522 +msgid "Change User Password" +msgstr "Ubah User Password" + +#: mod_configure.erl:155 mod_configure.erl:523 mod_configure.erl:1272 +msgid "Get User Last Login Time" +msgstr "Dapatkan Waktu Login Terakhir Pengguna " + +#: mod_configure.erl:157 mod_configure.erl:524 mod_configure.erl:1284 +msgid "Get User Statistics" +msgstr "Dapatkan Statistik Pengguna" + +#: mod_configure.erl:159 mod_configure.erl:525 +msgid "Get Number of Registered Users" +msgstr "Dapatkan Jumlah Pengguna Yang Terdaftar" + +#: mod_configure.erl:161 mod_configure.erl:526 +msgid "Get Number of Online Users" +msgstr "Dapatkan Jumlah User Yang Online" + +#: mod_configure.erl:163 mod_configure.erl:509 web/ejabberd_web_admin.erl:827 +#: web/ejabberd_web_admin.erl:868 +msgid "Access Control Lists" +msgstr "Akses Daftar Pengendalian" + +#: mod_configure.erl:165 mod_configure.erl:510 web/ejabberd_web_admin.erl:936 +#: web/ejabberd_web_admin.erl:972 +msgid "Access Rules" +msgstr "Aturan Akses" + +#: mod_configure.erl:297 mod_configure.erl:499 +msgid "User Management" +msgstr "Manajemen Pengguna" + +#: mod_configure.erl:500 web/ejabberd_web_admin.erl:1054 +#: web/ejabberd_web_admin.erl:1459 +msgid "Online Users" +msgstr "Pengguna Yang Online" + +#: mod_configure.erl:501 +msgid "All Users" +msgstr "Semua Pengguna" + +#: mod_configure.erl:502 +msgid "Outgoing s2s Connections" +msgstr "Koneksi Keluar s2s" + +#: mod_configure.erl:503 web/ejabberd_web_admin.erl:1901 +msgid "Running Nodes" +msgstr "Menjalankan Node" + +#: mod_configure.erl:504 web/ejabberd_web_admin.erl:1903 +msgid "Stopped Nodes" +msgstr "Menghentikan node" + +#: mod_configure.erl:577 mod_configure.erl:587 web/ejabberd_web_admin.erl:1947 +msgid "Modules" +msgstr "Modul" + +#: mod_configure.erl:578 +msgid "Backup Management" +msgstr "Manajemen Backup" + +#: mod_configure.erl:579 +msgid "Import Users From jabberd14 Spool Files" +msgstr "Impor Pengguna Dari jabberd14 Spool File" + +#: mod_configure.erl:699 +msgid "To ~s" +msgstr "Kepada ~s" + +#: mod_configure.erl:717 +msgid "From ~s" +msgstr "Dari ~s" + +#: mod_configure.erl:913 +msgid "Database Tables Configuration at " +msgstr "Database Tabel Konfigurasi pada" + +#: mod_configure.erl:918 +msgid "Choose storage type of tables" +msgstr "Pilih jenis penyimpanan tabel" + +#: mod_configure.erl:926 mod_configure.erl:928 +msgid "Disc only copy" +msgstr "Hanya salinan dari disc" + +#: mod_configure.erl:926 mod_configure.erl:928 +msgid "RAM and disc copy" +msgstr "RAM dan disc salinan" + +#: mod_configure.erl:926 mod_configure.erl:928 +msgid "RAM copy" +msgstr "Salinan RAM" + +#: mod_configure.erl:926 mod_configure.erl:928 +msgid "Remote copy" +msgstr "Salinan Remote" + +#: mod_configure.erl:950 +msgid "Stop Modules at " +msgstr "Hentikan Modul pada" + +#: mod_configure.erl:954 +msgid "Choose modules to stop" +msgstr "Pilih Modul untuk berhenti" + +#: mod_configure.erl:969 +msgid "Start Modules at " +msgstr "Mulai Modul pada" + +#: mod_configure.erl:973 +msgid "Enter list of {Module, [Options]}" +msgstr "Masukkan daftar {Modul, [Options]}" + +#: mod_configure.erl:974 +msgid "List of modules to start" +msgstr "Daftar modul untuk memulai" + +#: mod_configure.erl:983 +msgid "Backup to File at " +msgstr "Backup ke File pada" + +#: mod_configure.erl:987 mod_configure.erl:1001 +msgid "Enter path to backup file" +msgstr "Masukkan path untuk file cadangan" + +#: mod_configure.erl:988 mod_configure.erl:1002 mod_configure.erl:1016 +#: mod_configure.erl:1030 +msgid "Path to File" +msgstr "Jalur ke File" + +#: mod_configure.erl:997 +msgid "Restore Backup from File at " +msgstr "Kembalikan Backup dari File pada" + +#: mod_configure.erl:1011 +msgid "Dump Backup to Text File at " +msgstr "Dump Backup ke File Teks di" + +#: mod_configure.erl:1015 +msgid "Enter path to text file" +msgstr "Masukkan path ke file teks" + +#: mod_configure.erl:1025 +msgid "Import User from File at " +msgstr "Impor Pengguna dari File pada" + +#: mod_configure.erl:1029 +msgid "Enter path to jabberd14 spool file" +msgstr "Masukkan path ke file jabberd14 spool" + +#: mod_configure.erl:1039 +msgid "Import Users from Dir at " +msgstr "Impor Pengguna dari Dir di" + +#: mod_configure.erl:1043 +msgid "Enter path to jabberd14 spool dir" +msgstr "Masukkan path ke direktori spool jabberd14" + +#: mod_configure.erl:1044 +msgid "Path to Dir" +msgstr "Jalur ke Dir" + +#: mod_configure.erl:1060 mod_configure.erl:1105 +msgid "Time delay" +msgstr "Waktu tunda" + +#: mod_configure.erl:1143 +msgid "Access Control List Configuration" +msgstr "Konfigurasi Daftar Akses Pengendalian" + +#: mod_configure.erl:1147 +msgid "Access control lists" +msgstr "Daftar Pengendalian Akses" + +#: mod_configure.erl:1171 +msgid "Access Configuration" +msgstr "Akses Konfigurasi" + +#: mod_configure.erl:1175 +msgid "Access rules" +msgstr "Akses peraturan" + +#: mod_configure.erl:1200 mod_configure.erl:1222 mod_configure.erl:1234 +#: mod_configure.erl:1246 mod_configure.erl:1258 mod_configure.erl:1275 +#: mod_configure.erl:1287 mod_configure.erl:1652 mod_configure.erl:1702 +#: mod_configure.erl:1723 mod_roster.erl:948 mod_roster_odbc.erl:1048 +#: mod_vcard.erl:466 mod_vcard_ldap.erl:550 mod_vcard_odbc.erl:442 +msgid "Jabber ID" +msgstr "Jabber ID" + +#: mod_configure.erl:1205 mod_configure.erl:1263 mod_configure.erl:1653 +#: mod_configure.erl:1865 mod_muc/mod_muc_room.erl:2925 mod_register.erl:233 +#: web/ejabberd_web_admin.erl:1517 +msgid "Password" +msgstr "Sandi" + +#: mod_configure.erl:1210 +msgid "Password Verification" +msgstr "Verifikasi Sandi" + +#: mod_configure.erl:1301 +msgid "Number of registered users" +msgstr "Jumlah pengguna terdaftar" + +#: mod_configure.erl:1315 +msgid "Number of online users" +msgstr "Jumlah pengguna online" + +#: mod_configure.erl:1684 web/ejabberd_web_admin.erl:1585 +#: web/ejabberd_web_admin.erl:1737 +msgid "Never" +msgstr "Tidak Pernah" + +#: mod_configure.erl:1698 web/ejabberd_web_admin.erl:1598 +#: web/ejabberd_web_admin.erl:1750 +msgid "Online" +msgstr "Online" + +#: mod_configure.erl:1703 +msgid "Last login" +msgstr "Terakhir Login" + +#: mod_configure.erl:1724 +msgid "Roster size" +msgstr "Ukuran Daftar Kontak" + +#: mod_configure.erl:1725 +msgid "IP addresses" +msgstr "Alamat IP" + +#: mod_configure.erl:1726 +msgid "Resources" +msgstr "Sumber daya" + +#: mod_configure.erl:1852 +msgid "Administration of " +msgstr "Administrasi" + +#: mod_configure.erl:1855 +msgid "Action on user" +msgstr "Tindakan pada pengguna" + +#: mod_configure.erl:1859 +msgid "Edit Properties" +msgstr "Ganti Properti" + +#: mod_configure.erl:1862 web/ejabberd_web_admin.erl:1763 +msgid "Remove User" +msgstr "Hapus Pengguna" + +#: mod_irc/mod_irc.erl:201 mod_muc/mod_muc.erl:336 +msgid "Access denied by service policy" +msgstr "Akses ditolak oleh kebijakan layanan" + +#: mod_irc/mod_irc.erl:400 +msgid "IRC Transport" +msgstr "IRC Transport" + +#: mod_irc/mod_irc.erl:427 +msgid "ejabberd IRC module" +msgstr "ejabberd IRC modul" + +#: mod_irc/mod_irc.erl:558 +msgid "You need an x:data capable client to configure mod_irc settings" +msgstr "" +"Anda memerlukan x:data klien untuk mampu mengkonfigurasi pengaturan mod_irc" + +#: mod_irc/mod_irc.erl:565 +msgid "Registration in mod_irc for " +msgstr "Pendaftaran di mod_irc untuk" + +#: mod_irc/mod_irc.erl:570 +msgid "" +"Enter username, encodings, ports and passwords you wish to use for " +"connecting to IRC servers" +msgstr "" +"Masukkan username, pengkodean, port dan sandi yang ingin Anda gunakan untuk " +"menghubungkan ke layanan IRC" + +#: mod_irc/mod_irc.erl:575 +msgid "IRC Username" +msgstr "Nama Pengguna IRC" + +#: mod_irc/mod_irc.erl:585 +msgid "" +"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." +msgstr "" +"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." + +#: mod_irc/mod_irc.erl:597 +msgid "" +"Example: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." +"net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." +msgstr "" +"Contoh: [{\"irc.lucky.net\", \"koi8-r\", 6667, \"secret\"}, {\"vendetta.fef." +"net\", \"iso8859-1\", 7000}, {\"irc.sometestserver.net\", \"utf-8\"}]." + +#: mod_irc/mod_irc.erl:602 +msgid "Connections parameters" +msgstr "Parameter Koneksi" + +#: mod_irc/mod_irc.erl:727 +msgid "Join IRC channel" +msgstr "Gabung channel IRC" + +#: mod_irc/mod_irc.erl:731 +msgid "IRC channel (don't put the first #)" +msgstr "Channel IRC (tidak perlu menempatkan # sebelumnya)" + +#: mod_irc/mod_irc.erl:736 +msgid "IRC server" +msgstr "Layanan IRC" + +#: mod_irc/mod_irc.erl:769 mod_irc/mod_irc.erl:773 +msgid "Join the IRC channel here." +msgstr "Gabung ke channel IRC disini" + +#: mod_irc/mod_irc.erl:777 +msgid "Join the IRC channel in this Jabber ID: ~s" +msgstr "Gabung ke channel IRC dengan Jabber ID: ~s" + +#: mod_irc/mod_irc.erl:862 +msgid "IRC settings" +msgstr "Pengaturan IRC" + +#: mod_irc/mod_irc.erl:867 +msgid "" +"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." +msgstr "" +"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." + +#: mod_irc/mod_irc.erl:873 +msgid "IRC username" +msgstr "Nama Pengguna IRC" + +#: mod_irc/mod_irc.erl:922 +msgid "Password ~b" +msgstr "Kata Sandi ~b" + +#: mod_irc/mod_irc.erl:927 +msgid "Port ~b" +msgstr "Port ~b" + +#: mod_irc/mod_irc.erl:932 +msgid "Encoding for server ~b" +msgstr "Pengkodean untuk layanan ~b" + +#: mod_irc/mod_irc.erl:941 +msgid "Server ~b" +msgstr "Layanan ~b" + +#: mod_muc/mod_muc.erl:449 +msgid "Only service administrators are allowed to send service messages" +msgstr "" +"Layanan hanya diperuntukan kepada administrator yang diizinkan untuk " +"mengirim layanan pesan" + +#: mod_muc/mod_muc.erl:493 +msgid "Room creation is denied by service policy" +msgstr "Pembuatan Ruangan ditolak oleh kebijakan layanan" + +#: mod_muc/mod_muc.erl:500 +msgid "Conference room does not exist" +msgstr "Ruang Konferensi tidak ada" + +#: mod_muc/mod_muc.erl:581 +msgid "Chatrooms" +msgstr "Ruangan Chat" + +#: mod_muc/mod_muc.erl:711 +msgid "You need a client that supports x:data to register the nickname" +msgstr "Anda memerlukan klien yang mendukung x:data untuk mendaftar julukan" + +#: mod_muc/mod_muc.erl:717 +msgid "Nickname Registration at " +msgstr "Pendaftaran Julukan pada" + +#: mod_muc/mod_muc.erl:721 +msgid "Enter nickname you want to register" +msgstr "Masukkan nama julukan Anda jika ingin mendaftar" + +#: 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 +#: mod_vcard_odbc.erl:447 +msgid "Nickname" +msgstr "Nama Julukan" + +#: mod_muc/mod_muc.erl:761 mod_muc/mod_muc_room.erl:933 +#: mod_muc/mod_muc_room.erl:1577 +msgid "That nickname is registered by another person" +msgstr "Julukan tersebut telah didaftarkan oleh orang lain" + +#: mod_muc/mod_muc.erl:787 +msgid "You must fill in field \"Nickname\" in the form" +msgstr "Anda harus mengisi kolom \"Julukan\" dalam formulir" + +#: mod_muc/mod_muc.erl:807 +msgid "ejabberd MUC module" +msgstr "ejabberd MUC Module" + +#: mod_muc/mod_muc_log.erl:374 mod_muc/mod_muc_log.erl:381 +msgid "Chatroom configuration modified" +msgstr "Konfigurasi ruang chat diubah" + +#: mod_muc/mod_muc_log.erl:384 +msgid "joins the room" +msgstr "bergabung ke ruangan" + +#: mod_muc/mod_muc_log.erl:387 mod_muc/mod_muc_log.erl:390 +msgid "leaves the room" +msgstr "meninggalkan ruangan" + +#: mod_muc/mod_muc_log.erl:393 mod_muc/mod_muc_log.erl:396 +msgid "has been banned" +msgstr "telah dibanned" + +#: mod_muc/mod_muc_log.erl:399 mod_muc/mod_muc_log.erl:402 +msgid "has been kicked" +msgstr "telah dikick" + +#: mod_muc/mod_muc_log.erl:405 +msgid "has been kicked because of an affiliation change" +msgstr "telah dikick karena perubahan afiliasi" + +#: mod_muc/mod_muc_log.erl:408 +msgid "has been kicked because the room has been changed to members-only" +msgstr "telah dikick karena ruangan telah diubah menjadi hanya untuk member" + +#: mod_muc/mod_muc_log.erl:411 +msgid "has been kicked because of a system shutdown" +msgstr "telah dikick karena sistem shutdown" + +#: mod_muc/mod_muc_log.erl:414 +msgid "is now known as" +msgstr "sekarang dikenal sebagai" + +#: mod_muc/mod_muc_log.erl:417 mod_muc/mod_muc_log.erl:689 +#: mod_muc/mod_muc_room.erl:2112 +msgid " has set the subject to: " +msgstr "telah menetapkan topik yaitu:" + +#: mod_muc/mod_muc_log.erl:452 +msgid "Chatroom is created" +msgstr "Ruang chat telah dibuat" + +#: mod_muc/mod_muc_log.erl:453 +msgid "Chatroom is destroyed" +msgstr "Ruang chat dilenyapkan" + +#: mod_muc/mod_muc_log.erl:454 +msgid "Chatroom is started" +msgstr "Ruang chat dimulai" + +#: mod_muc/mod_muc_log.erl:455 +msgid "Chatroom is stopped" +msgstr "Ruang chat dihentikan" + +#: mod_muc/mod_muc_log.erl:459 +msgid "Monday" +msgstr "Senin" + +#: mod_muc/mod_muc_log.erl:460 +msgid "Tuesday" +msgstr "Selasa" + +#: mod_muc/mod_muc_log.erl:461 +msgid "Wednesday" +msgstr "Rabu" + +#: mod_muc/mod_muc_log.erl:462 +msgid "Thursday" +msgstr "Kamis" + +#: mod_muc/mod_muc_log.erl:463 +msgid "Friday" +msgstr "Jumat" + +#: mod_muc/mod_muc_log.erl:464 +msgid "Saturday" +msgstr "Sabtu" + +#: mod_muc/mod_muc_log.erl:465 +msgid "Sunday" +msgstr "Minggu" + +#: mod_muc/mod_muc_log.erl:469 +msgid "January" +msgstr "Januari" + +#: mod_muc/mod_muc_log.erl:470 +msgid "February" +msgstr "Februari" + +#: mod_muc/mod_muc_log.erl:471 +msgid "March" +msgstr "Maret" + +#: mod_muc/mod_muc_log.erl:472 +msgid "April" +msgstr "April" + +#: mod_muc/mod_muc_log.erl:473 +msgid "May" +msgstr "Mei" + +#: mod_muc/mod_muc_log.erl:474 +msgid "June" +msgstr "Juni" + +#: mod_muc/mod_muc_log.erl:475 +msgid "July" +msgstr "Juli" + +#: mod_muc/mod_muc_log.erl:476 +msgid "August" +msgstr "Agustus" + +#: mod_muc/mod_muc_log.erl:477 +msgid "September" +msgstr "September" + +#: mod_muc/mod_muc_log.erl:478 +msgid "October" +msgstr "Oktober" + +#: mod_muc/mod_muc_log.erl:479 +msgid "November" +msgstr "Nopember" + +#: mod_muc/mod_muc_log.erl:480 +msgid "December" +msgstr "Desember" + +#: mod_muc/mod_muc_log.erl:751 +msgid "Room Configuration" +msgstr "Konfigurasi Ruangan" + +#: mod_muc/mod_muc_log.erl:760 +msgid "Room Occupants" +msgstr "Penghuni Ruangan" + +#: mod_muc/mod_muc_room.erl:170 +msgid "Traffic rate limit is exceeded" +msgstr "Lalu lintas melebihi batas" + +#: mod_muc/mod_muc_room.erl:242 +msgid "" +"This participant is kicked from the room because he sent an error message" +msgstr "Peserta ini dikick dari ruangan karena dia mengirim pesan kesalahan" + +#: mod_muc/mod_muc_room.erl:251 +msgid "It is not allowed to send private messages to the conference" +msgstr "Hal ini tidak diperbolehkan untuk mengirim pesan pribadi ke konferensi" + +#: mod_muc/mod_muc_room.erl:296 +msgid "Improper message type" +msgstr "Jenis pesan yang tidak benar" + +#: mod_muc/mod_muc_room.erl:406 +msgid "" +"This participant is kicked from the room because he sent an error message to " +"another participant" +msgstr "" +"Participant ini dikick dari ruangan karena ia mengirim pesan kesalahan ke " +"participant lain" + +#: mod_muc/mod_muc_room.erl:419 +msgid "It is not allowed to send private messages of type \"groupchat\"" +msgstr "" +"Hal ini tidak diperbolehkan untuk mengirim pesan pribadi jenis \"groupchat \"" + +#: mod_muc/mod_muc_room.erl:431 mod_muc/mod_muc_room.erl:486 +msgid "Recipient is not in the conference room" +msgstr "Penerima tidak berada di ruangan konferensi" + +#: mod_muc/mod_muc_room.erl:451 mod_muc/mod_muc_room.erl:829 +#: mod_muc/mod_muc_room.erl:3543 +msgid "Only occupants are allowed to send messages to the conference" +msgstr "Hanya penghuni yang diizinkan untuk mengirim pesan ke konferensi" + +#: mod_muc/mod_muc_room.erl:460 +msgid "It is not allowed to send private messages" +msgstr "Hal ini tidak diperbolehkan untuk mengirim pesan pribadi" + +#: mod_muc/mod_muc_room.erl:509 +msgid "Only occupants are allowed to send queries to the conference" +msgstr "Hanya penghuni diizinkan untuk mengirim permintaan ke konferensi" + +#: mod_muc/mod_muc_room.erl:521 +msgid "Queries to the conference members are not allowed in this room" +msgstr "" +"Permintaan untuk para anggota konferensi tidak diperbolehkan di ruangan ini" + +#: mod_muc/mod_muc_room.erl:805 +msgid "" +"Only moderators and participants are allowed to change the subject in this " +"room" +msgstr "" +"Hanya moderator dan peserta yang diizinkan untuk mengganti topik pembicaraan " +"di ruangan ini" + +#: mod_muc/mod_muc_room.erl:810 +msgid "Only moderators are allowed to change the subject in this room" +msgstr "" +"Hanya moderator yang diperbolehkan untuk mengubah topik dalam ruangan ini" + +#: mod_muc/mod_muc_room.erl:820 +msgid "Visitors are not allowed to send messages to all occupants" +msgstr "Visitor tidak diperbolehkan untuk mengirim pesan ke semua penghuni" + +#: mod_muc/mod_muc_room.erl:891 +msgid "" +"This participant is kicked from the room because he sent an error presence" +msgstr "" +"Participant ini dikick dari ruangan karena ia mengirim kehadiran kesalahan" + +#: mod_muc/mod_muc_room.erl:909 +msgid "Visitors are not allowed to change their nicknames in this room" +msgstr "Visitor tidak diperbolehkan untuk mengubah nama julukan di ruangan ini" + +#: mod_muc/mod_muc_room.erl:922 mod_muc/mod_muc_room.erl:1569 +msgid "That nickname is already in use by another occupant" +msgstr "Julukan itu sudah digunakan oleh penghuni lain" + +#: mod_muc/mod_muc_room.erl:1558 +msgid "You have been banned from this room" +msgstr "Anda telah diblokir dari ruangan ini" + +#: mod_muc/mod_muc_room.erl:1561 +msgid "Membership is required to enter this room" +msgstr "Hanya Member yang dapat masuk ruangan ini" + +#: mod_muc/mod_muc_room.erl:1597 +msgid "This room is not anonymous" +msgstr "Ruangan ini tidak dikenal" + +#: mod_muc/mod_muc_room.erl:1623 +msgid "A password is required to enter this room" +msgstr "Diperlukan kata sandi untuk masuk ruangan ini" + +#: mod_muc/mod_muc_room.erl:1645 +msgid "Unable to generate a captcha" +msgstr "Tidak dapat menghasilkan captcha" + +#: mod_muc/mod_muc_room.erl:1655 +msgid "Incorrect password" +msgstr "Kata sandi salah" + +#: mod_muc/mod_muc_room.erl:2167 +msgid "Administrator privileges required" +msgstr "Hak istimewa Administrator dibutuhkan" + +#: mod_muc/mod_muc_room.erl:2182 +msgid "Moderator privileges required" +msgstr "Hak istimewa moderator dibutuhkan" + +#: mod_muc/mod_muc_room.erl:2337 +msgid "Jabber ID ~s is invalid" +msgstr "Jabber ID ~s tidak valid" + +#: mod_muc/mod_muc_room.erl:2351 +msgid "Nickname ~s does not exist in the room" +msgstr "Nama Julukan ~s tidak berada di dalam ruangan" + +#: mod_muc/mod_muc_room.erl:2377 mod_muc/mod_muc_room.erl:2759 +msgid "Invalid affiliation: ~s" +msgstr "Afiliasi tidak valid: ~s" + +#: mod_muc/mod_muc_room.erl:2434 +msgid "Invalid role: ~s" +msgstr "Peran tidak valid: ~s" + +#: mod_muc/mod_muc_room.erl:2736 mod_muc/mod_muc_room.erl:2772 +msgid "Owner privileges required" +msgstr "Hak istimewa owner dibutuhkan" + +#: mod_muc/mod_muc_room.erl:2896 +msgid "Configuration of room ~s" +msgstr "Pengaturan ruangan ~s" + +#: mod_muc/mod_muc_room.erl:2901 +msgid "Room title" +msgstr "Nama Ruangan" + +#: mod_muc/mod_muc_room.erl:2904 mod_muc/mod_muc_room.erl:3322 +msgid "Room description" +msgstr "Keterangan ruangan" + +#: mod_muc/mod_muc_room.erl:2911 +msgid "Make room persistent" +msgstr "Buat ruangan menjadi permanent" + +#: mod_muc/mod_muc_room.erl:2916 +msgid "Make room public searchable" +msgstr "Buat ruangan dapat dicari" + +#: mod_muc/mod_muc_room.erl:2919 +msgid "Make participants list public" +msgstr "Buat daftar participant diketahui oleh public" + +#: mod_muc/mod_muc_room.erl:2922 +msgid "Make room password protected" +msgstr "Buat ruangan yang dilindungi dengan kata sandi" + +#: mod_muc/mod_muc_room.erl:2933 +msgid "Maximum Number of Occupants" +msgstr "Maksimum Jumlah Penghuni" + +#: mod_muc/mod_muc_room.erl:2940 +msgid "No limit" +msgstr "Tidak terbatas" + +#: mod_muc/mod_muc_room.erl:2951 +msgid "Present real Jabber IDs to" +msgstr "Tampilkan Jabber ID secara lengkap" + +#: mod_muc/mod_muc_room.erl:2959 +msgid "moderators only" +msgstr "Hanya moderator" + +#: mod_muc/mod_muc_room.erl:2961 +msgid "anyone" +msgstr "Siapapun" + +#: mod_muc/mod_muc_room.erl:2963 +msgid "Make room members-only" +msgstr "Buat ruangan hanya untuk member saja" + +#: mod_muc/mod_muc_room.erl:2966 +msgid "Make room moderated" +msgstr "Buat ruangan hanya untuk moderator saja" + +#: mod_muc/mod_muc_room.erl:2969 +msgid "Default users as participants" +msgstr "pengguna pertama kali masuk sebagai participant" + +#: mod_muc/mod_muc_room.erl:2972 +msgid "Allow users to change the subject" +msgstr "Perbolehkan pengguna untuk mengganti topik" + +#: mod_muc/mod_muc_room.erl:2975 +msgid "Allow users to send private messages" +msgstr "perbolehkan pengguna mengirimkan pesan ke pengguna lain secara pribadi" + +#: mod_muc/mod_muc_room.erl:2978 +msgid "Allow users to query other users" +msgstr "Perbolehkan pengguna untuk mengetahui pengguna lain" + +#: mod_muc/mod_muc_room.erl:2981 +msgid "Allow users to send invites" +msgstr "Perbolehkan pengguna mengirimkan undangan" + +#: mod_muc/mod_muc_room.erl:2984 +msgid "Allow visitors to send status text in presence updates" +msgstr "Izinkan pengunjung untuk mengirim teks status terbaru" + +#: mod_muc/mod_muc_room.erl:2987 +msgid "Allow visitors to change nickname" +msgstr "Perbolehkan visitor mengganti nama julukan" + +#: mod_muc/mod_muc_room.erl:2993 +msgid "Make room captcha protected" +msgstr "Buat ruangan dilindungi dengan chapta" + +#: mod_muc/mod_muc_room.erl:3002 +msgid "Enable logging" +msgstr "Aktifkan catatan" + +#: mod_muc/mod_muc_room.erl:3010 +msgid "You need an x:data capable client to configure room" +msgstr "Anda memerlukan x:data klien untuk dapat mengkonfigurasi ruangan" + +#: mod_muc/mod_muc_room.erl:3324 +msgid "Number of occupants" +msgstr "Jumlah Penghuni" + +#: mod_muc/mod_muc_room.erl:3380 +msgid "private, " +msgstr "pribadi, " + +#: mod_muc/mod_muc_room.erl:3463 +msgid "~s invites you to the room ~s" +msgstr "~s mengundang anda ke ruangan ~s" + +#: mod_muc/mod_muc_room.erl:3472 +msgid "the password is" +msgstr "kata sandi yaitu:" + +#: mod_offline.erl:510 mod_offline_odbc.erl:352 +msgid "" +"Your contact offline message queue is full. The message has been discarded." +msgstr "" +"Kontak offline Anda pada antrian pesan sudah penuh. Pesan telah dibuang." + +#: mod_offline.erl:560 mod_offline_odbc.erl:408 +msgid "~s's Offline Messages Queue" +msgstr "Antrian Pesan Offline ~s" + +#: mod_offline.erl:563 mod_offline_odbc.erl:411 mod_roster.erl:992 +#: mod_roster_odbc.erl:1092 mod_shared_roster.erl:810 +#: mod_shared_roster.erl:911 web/ejabberd_web_admin.erl:829 +#: web/ejabberd_web_admin.erl:870 web/ejabberd_web_admin.erl:938 +#: web/ejabberd_web_admin.erl:974 web/ejabberd_web_admin.erl:1015 +#: web/ejabberd_web_admin.erl:1505 web/ejabberd_web_admin.erl:1754 +#: web/ejabberd_web_admin.erl:1925 web/ejabberd_web_admin.erl:1957 +#: web/ejabberd_web_admin.erl:2026 web/ejabberd_web_admin.erl:2130 +#: web/ejabberd_web_admin.erl:2155 web/ejabberd_web_admin.erl:2243 +msgid "Submitted" +msgstr "Ulangi masukan" + +#: mod_offline.erl:571 +msgid "Time" +msgstr "Waktu" + +#: mod_offline.erl:572 +msgid "From" +msgstr "Dari" + +#: mod_offline.erl:573 +msgid "To" +msgstr "Kepada" + +#: mod_offline.erl:574 mod_offline_odbc.erl:419 +msgid "Packet" +msgstr "Paket" + +#: mod_offline.erl:587 mod_offline_odbc.erl:432 mod_shared_roster.erl:817 +#: web/ejabberd_web_admin.erl:878 web/ejabberd_web_admin.erl:982 +msgid "Delete Selected" +msgstr "Hapus Yang Terpilih" + +#: mod_offline.erl:645 mod_offline_odbc.erl:519 +msgid "Offline Messages:" +msgstr "Pesan Offline:" + +#: mod_offline.erl:645 mod_offline_odbc.erl:519 +msgid "Remove All Offline Messages" +msgstr "Hapus Semua Pesan Offline" + +#: mod_proxy65/mod_proxy65_service.erl:213 +msgid "ejabberd SOCKS5 Bytestreams module" +msgstr "modul ejabberd SOCKS5 Bytestreams" + +#: mod_pubsub/mod_pubsub.erl:1119 mod_pubsub/mod_pubsub_odbc.erl:928 +msgid "Publish-Subscribe" +msgstr "Setujui-Pertemanan" + +#: mod_pubsub/mod_pubsub.erl:1213 mod_pubsub/mod_pubsub_odbc.erl:1024 +msgid "ejabberd Publish-Subscribe module" +msgstr "Modul ejabberd Setujui-Pertemanan" + +#: mod_pubsub/mod_pubsub.erl:1496 mod_pubsub/mod_pubsub_odbc.erl:1311 +msgid "PubSub subscriber request" +msgstr "Permintaan pertemanan PubSub" + +#: mod_pubsub/mod_pubsub.erl:1498 mod_pubsub/mod_pubsub_odbc.erl:1313 +msgid "Choose whether to approve this entity's subscription." +msgstr "Pilih apakah akan menyetujui hubungan pertemanan ini." + +#: mod_pubsub/mod_pubsub.erl:1504 mod_pubsub/mod_pubsub_odbc.erl:1319 +msgid "Node ID" +msgstr "ID Node" + +#: mod_pubsub/mod_pubsub.erl:1509 mod_pubsub/mod_pubsub_odbc.erl:1324 +msgid "Subscriber Address" +msgstr "Alamat Pertemanan" + +#: 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 "Izinkan ID Jabber ini untuk berlangganan pada node pubsub ini?" + +#: mod_pubsub/mod_pubsub.erl:3387 mod_pubsub/mod_pubsub_odbc.erl:3229 +msgid "Deliver payloads with event notifications" +msgstr "Memberikan muatan dengan pemberitahuan acara" + +#: mod_pubsub/mod_pubsub.erl:3388 mod_pubsub/mod_pubsub_odbc.erl:3230 +msgid "Deliver event notifications" +msgstr "Memberikan pemberitahuan acara" + +#: mod_pubsub/mod_pubsub.erl:3389 mod_pubsub/mod_pubsub_odbc.erl:3231 +msgid "Notify subscribers when the node configuration changes" +msgstr "Beritahu pelanggan ketika ada perubahan konfigurasi node" + +#: mod_pubsub/mod_pubsub.erl:3390 mod_pubsub/mod_pubsub_odbc.erl:3232 +msgid "Notify subscribers when the node is deleted" +msgstr "Beritahu pelanggan ketika node dihapus" + +#: mod_pubsub/mod_pubsub.erl:3391 mod_pubsub/mod_pubsub_odbc.erl:3233 +msgid "Notify subscribers when items are removed from the node" +msgstr "Beritahu pelanggan ketika item tersebut dikeluarkan dari node" + +#: mod_pubsub/mod_pubsub.erl:3392 mod_pubsub/mod_pubsub_odbc.erl:3234 +msgid "Persist items to storage" +msgstr "Pertahankan item ke penyimpanan" + +#: mod_pubsub/mod_pubsub.erl:3393 mod_pubsub/mod_pubsub_odbc.erl:3235 +msgid "A friendly name for the node" +msgstr "Nama yang dikenal untuk node" + +#: mod_pubsub/mod_pubsub.erl:3394 mod_pubsub/mod_pubsub_odbc.erl:3236 +msgid "Max # of items to persist" +msgstr "Max item untuk bertahan" + +#: mod_pubsub/mod_pubsub.erl:3395 mod_pubsub/mod_pubsub_odbc.erl:3237 +msgid "Whether to allow subscriptions" +msgstr "Apakah diperbolehkan untuk berlangganan" + +#: mod_pubsub/mod_pubsub.erl:3396 mod_pubsub/mod_pubsub_odbc.erl:3238 +msgid "Specify the access model" +msgstr "Tentukan model akses" + +#: mod_pubsub/mod_pubsub.erl:3399 mod_pubsub/mod_pubsub_odbc.erl:3241 +msgid "Roster groups allowed to subscribe" +msgstr "Kelompok kontak yang diizinkan untuk berlangganan" + +#: mod_pubsub/mod_pubsub.erl:3400 mod_pubsub/mod_pubsub_odbc.erl:3242 +msgid "Specify the publisher model" +msgstr "Tentukan model penerbitan" + +#: mod_pubsub/mod_pubsub.erl:3402 mod_pubsub/mod_pubsub_odbc.erl:3244 +msgid "Purge all items when the relevant publisher goes offline" +msgstr "Bersihkan semua item ketika penerbit yang relevan telah offline" + +#: mod_pubsub/mod_pubsub.erl:3403 mod_pubsub/mod_pubsub_odbc.erl:3245 +msgid "Specify the event message type" +msgstr "Tentukan jenis acara pesan" + +#: mod_pubsub/mod_pubsub.erl:3405 mod_pubsub/mod_pubsub_odbc.erl:3247 +msgid "Max payload size in bytes" +msgstr "Max kapasitas ukuran dalam bytes" + +#: mod_pubsub/mod_pubsub.erl:3406 mod_pubsub/mod_pubsub_odbc.erl:3248 +msgid "When to send the last published item" +msgstr "Ketika untuk mengirim item terakhir yang dipublikasikan" + +#: mod_pubsub/mod_pubsub.erl:3408 mod_pubsub/mod_pubsub_odbc.erl:3250 +msgid "Only deliver notifications to available users" +msgstr "Hanya mengirimkan pemberitahuan kepada pengguna yang tersedia" + +#: mod_pubsub/mod_pubsub.erl:3409 mod_pubsub/mod_pubsub_odbc.erl:3251 +msgid "The collections with which a node is affiliated" +msgstr "Koleksi dengan yang berafiliasi dengan sebuah node" + +#: mod_register.erl:191 +msgid "The CAPTCHA verification has failed" +msgstr "Verifikasi CAPTCHA telah gagal" + +#: mod_register.erl:218 +msgid "You need a client that supports x:data and CAPTCHA to register" +msgstr "" +"Anda memerlukan klien yang mendukung x:data dan CAPTCHA untuk mendaftar" + +#: mod_register.erl:224 mod_register.erl:258 +msgid "Choose a username and password to register with this server" +msgstr "Pilih nama pengguna dan kata sandi untuk mendaftar dengan layanan ini" + +#: 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 +msgid "User" +msgstr "Pengguna" + +#: mod_register.erl:244 +msgid "Unable to generate a CAPTCHA" +msgstr "Tidak dapat menghasilkan CAPTCHA" + +#: mod_register.erl:309 mod_register.erl:354 +msgid "The password is too weak" +msgstr "Kata sandi terlalu lemah" + +#: mod_register.erl:358 +msgid "Users are not allowed to register accounts so quickly" +msgstr "Pengguna tidak diperkenankan untuk mendaftar akun begitu cepat" + +#: mod_roster.erl:943 mod_roster_odbc.erl:1043 web/ejabberd_web_admin.erl:1695 +#: web/ejabberd_web_admin.erl:1880 web/ejabberd_web_admin.erl:1891 +#: web/ejabberd_web_admin.erl:2214 +msgid "None" +msgstr "Tak satupun" + +#: mod_roster.erl:950 mod_roster_odbc.erl:1050 +msgid "Subscription" +msgstr "Berlangganan" + +#: mod_roster.erl:951 mod_roster_odbc.erl:1051 +msgid "Pending" +msgstr "Tertunda" + +#: mod_roster.erl:952 mod_roster_odbc.erl:1052 +msgid "Groups" +msgstr "Grup" + +#: mod_roster.erl:979 mod_roster_odbc.erl:1079 +msgid "Validate" +msgstr "Mengesahkan" + +#: mod_roster.erl:987 mod_roster_odbc.erl:1087 +msgid "Remove" +msgstr "Menghapus" + +#: mod_roster.erl:990 mod_roster_odbc.erl:1090 +msgid "Roster of " +msgstr "Kontak dari" + +#: mod_roster.erl:993 mod_roster_odbc.erl:1093 mod_shared_roster.erl:811 +#: mod_shared_roster.erl:912 web/ejabberd_web_admin.erl:830 +#: web/ejabberd_web_admin.erl:871 web/ejabberd_web_admin.erl:939 +#: web/ejabberd_web_admin.erl:975 web/ejabberd_web_admin.erl:1016 +#: web/ejabberd_web_admin.erl:1506 web/ejabberd_web_admin.erl:1755 +#: web/ejabberd_web_admin.erl:1926 web/ejabberd_web_admin.erl:2131 +#: web/ejabberd_web_admin.erl:2156 +msgid "Bad format" +msgstr "Format yang buruk" + +#: mod_roster.erl:1000 mod_roster_odbc.erl:1100 +msgid "Add Jabber ID" +msgstr "Tambah Jabber ID" + +#: mod_roster.erl:1099 mod_roster_odbc.erl:1199 +msgid "Roster" +msgstr "Kontak" + +#: mod_shared_roster.erl:766 mod_shared_roster.erl:808 +#: mod_shared_roster.erl:908 +msgid "Shared Roster Groups" +msgstr "Berbagi grup kontak" + +#: mod_shared_roster.erl:804 web/ejabberd_web_admin.erl:1362 +#: web/ejabberd_web_admin.erl:2456 +msgid "Add New" +msgstr "Tambah Baru" + +#: mod_shared_roster.erl:879 +msgid "Name:" +msgstr "Nama:" + +#: mod_shared_roster.erl:884 +msgid "Description:" +msgstr "Keterangan:" + +#: mod_shared_roster.erl:892 +msgid "Members:" +msgstr "Anggota:" + +#: mod_shared_roster.erl:900 +msgid "Displayed Groups:" +msgstr "Tampilkan Grup:" + +#: mod_shared_roster.erl:909 +msgid "Group " +msgstr "Grup" + +#: mod_shared_roster.erl:918 web/ejabberd_web_admin.erl:836 +#: web/ejabberd_web_admin.erl:880 web/ejabberd_web_admin.erl:945 +#: web/ejabberd_web_admin.erl:1022 web/ejabberd_web_admin.erl:2011 +msgid "Submit" +msgstr "Serahkan" + +#: mod_vcard.erl:165 mod_vcard_ldap.erl:237 mod_vcard_odbc.erl:129 +msgid "Erlang Jabber Server" +msgstr "Layanan Erlang Jabber" + +#: mod_vcard.erl:358 mod_vcard.erl:472 mod_vcard_odbc.erl:336 +#: mod_vcard_odbc.erl:448 +msgid "Birthday" +msgstr "Hari Lahir" + +#: mod_vcard.erl:358 mod_vcard.erl:474 mod_vcard_odbc.erl:336 +#: mod_vcard_odbc.erl:450 +msgid "City" +msgstr "Kota" + +#: mod_vcard.erl:358 mod_vcard.erl:473 mod_vcard_odbc.erl:336 +#: mod_vcard_odbc.erl:449 +msgid "Country" +msgstr "Negara" + +#: mod_vcard.erl:358 mod_vcard.erl:475 mod_vcard_odbc.erl:336 +#: mod_vcard_odbc.erl:451 +msgid "Email" +msgstr "Email" + +#: mod_vcard.erl:358 mod_vcard.erl:470 mod_vcard_odbc.erl:336 +#: mod_vcard_odbc.erl:446 +msgid "Family Name" +msgstr "Nama Keluarga (marga)" + +#: mod_vcard.erl:358 mod_vcard_odbc.erl:336 +msgid "" +"Fill in the form to search for any matching Jabber User (Add * to the end of " +"field to match substring)" +msgstr "" +"Isi formulir untuk pencarian pengguna Jabber yang cocok (Tambahkan * ke " +"mengakhiri pengisian untuk menyamakan kata)" + +#: mod_vcard.erl:358 mod_vcard.erl:467 mod_vcard_odbc.erl:336 +#: mod_vcard_odbc.erl:443 +msgid "Full Name" +msgstr "Nama Lengkap" + +#: mod_vcard.erl:358 mod_vcard.erl:469 mod_vcard_odbc.erl:336 +#: mod_vcard_odbc.erl:445 +msgid "Middle Name" +msgstr "Nama Tengah" + +#: mod_vcard.erl:358 mod_vcard.erl:468 mod_vcard_odbc.erl:336 +#: mod_vcard_odbc.erl:444 web/ejabberd_web_admin.erl:2000 +msgid "Name" +msgstr "Nama" + +#: mod_vcard.erl:358 mod_vcard.erl:476 mod_vcard_odbc.erl:336 +#: mod_vcard_odbc.erl:452 +msgid "Organization Name" +msgstr "Nama Organisasi" + +#: mod_vcard.erl:358 mod_vcard.erl:477 mod_vcard_odbc.erl:336 +#: mod_vcard_odbc.erl:453 +msgid "Organization Unit" +msgstr "Unit Organisasi" + +#: mod_vcard.erl:358 mod_vcard_ldap.erl:458 mod_vcard_odbc.erl:336 +msgid "Search users in " +msgstr "Pencarian pengguna dalam" + +#: mod_vcard.erl:358 mod_vcard_ldap.erl:458 mod_vcard_odbc.erl:336 +msgid "You need an x:data capable client to search" +msgstr "Anda memerlukan x:data klien untuk melakukan pencarian" + +#: mod_vcard.erl:383 mod_vcard_ldap.erl:483 mod_vcard_odbc.erl:361 +msgid "vCard User Search" +msgstr "vCard Pencarian Pengguna" + +#: mod_vcard.erl:439 mod_vcard_ldap.erl:537 mod_vcard_odbc.erl:415 +msgid "ejabberd vCard module" +msgstr "Modul ejabberd vCard" + +#: mod_vcard.erl:463 mod_vcard_ldap.erl:547 mod_vcard_odbc.erl:439 +msgid "Search Results for " +msgstr "Hasil Pencarian untuk" + +#: mod_vcard_ldap.erl:458 +msgid "Fill in fields to search for any matching Jabber User" +msgstr "Isi kolom untuk mencari pengguna Jabber yang sama" + +#: web/ejabberd_web_admin.erl:189 web/ejabberd_web_admin.erl:199 +#: web/ejabberd_web_admin.erl:215 web/ejabberd_web_admin.erl:225 +msgid "Unauthorized" +msgstr "Ditolak" + +#: web/ejabberd_web_admin.erl:282 web/ejabberd_web_admin.erl:299 +msgid "ejabberd Web Admin" +msgstr "Admin Web ejabberd" + +#: web/ejabberd_web_admin.erl:765 web/ejabberd_web_admin.erl:776 +msgid "Administration" +msgstr "Administrasi" + +#: web/ejabberd_web_admin.erl:874 web/ejabberd_web_admin.erl:978 +msgid "Raw" +msgstr "mentah" + +#: web/ejabberd_web_admin.erl:1013 +msgid "~s access rule configuration" +msgstr "~s aturan akses konfigurasi" + +#: web/ejabberd_web_admin.erl:1031 +msgid "Virtual Hosts" +msgstr "Virtual Hosts" + +#: web/ejabberd_web_admin.erl:1039 web/ejabberd_web_admin.erl:1046 +msgid "Users" +msgstr "Pengguna" + +#: web/ejabberd_web_admin.erl:1074 +msgid "Users Last Activity" +msgstr "Aktifitas terakhir para pengguna" + +#: web/ejabberd_web_admin.erl:1076 +msgid "Period: " +msgstr "Periode:" + +#: web/ejabberd_web_admin.erl:1086 +msgid "Last month" +msgstr "Akhir bulan" + +#: web/ejabberd_web_admin.erl:1087 +msgid "Last year" +msgstr "Akhir tahun" + +#: web/ejabberd_web_admin.erl:1088 +msgid "All activity" +msgstr "Semua aktifitas" + +#: web/ejabberd_web_admin.erl:1090 +msgid "Show Ordinary Table" +msgstr "Tampilkan Tabel Normal" + +#: web/ejabberd_web_admin.erl:1092 +msgid "Show Integral Table" +msgstr "Tampilkan Tabel Terpisah" + +#: web/ejabberd_web_admin.erl:1101 web/ejabberd_web_admin.erl:1933 +msgid "Statistics" +msgstr "Statistik" + +#: web/ejabberd_web_admin.erl:1113 +msgid "Not Found" +msgstr "Tidak Ditemukan" + +#: web/ejabberd_web_admin.erl:1130 +msgid "Node not found" +msgstr "Node tidak ditemukan" + +#: web/ejabberd_web_admin.erl:1457 +msgid "Host" +msgstr "Host" + +#: web/ejabberd_web_admin.erl:1458 +msgid "Registered Users" +msgstr "Pengguna Terdaftar" + +#: web/ejabberd_web_admin.erl:1570 +msgid "Offline Messages" +msgstr "Pesan Offline" + +#: web/ejabberd_web_admin.erl:1571 web/ejabberd_web_admin.erl:1761 +msgid "Last Activity" +msgstr "Aktifitas Terakhir" + +#: web/ejabberd_web_admin.erl:1653 web/ejabberd_web_admin.erl:1669 +msgid "Registered Users:" +msgstr "Pengguna Terdaftar:" + +#: web/ejabberd_web_admin.erl:1655 web/ejabberd_web_admin.erl:1671 +#: web/ejabberd_web_admin.erl:2187 +msgid "Online Users:" +msgstr "Pengguna Online:" + +#: web/ejabberd_web_admin.erl:1657 +msgid "Outgoing s2s Connections:" +msgstr "Koneksi s2s yang keluar:" + +#: web/ejabberd_web_admin.erl:1659 +msgid "Outgoing s2s Servers:" +msgstr "Layanan s2s yang keluar:" + +#: web/ejabberd_web_admin.erl:1728 web/mod_register_web.erl:174 +#: web/mod_register_web.erl:367 web/mod_register_web.erl:376 +#: web/mod_register_web.erl:406 +msgid "Change Password" +msgstr "Ubah Kata Sandi" + +#: web/ejabberd_web_admin.erl:1752 +msgid "User " +msgstr "Pengguna" + +#: web/ejabberd_web_admin.erl:1759 +msgid "Connected Resources:" +msgstr "Sumber Daya Terhubung:" + +#: web/ejabberd_web_admin.erl:1760 web/mod_register_web.erl:226 +#: web/mod_register_web.erl:514 +msgid "Password:" +msgstr "Kata Sandi:" + +#: web/ejabberd_web_admin.erl:1822 +msgid "No Data" +msgstr "Tidak Ada Data" + +#: web/ejabberd_web_admin.erl:1900 +msgid "Nodes" +msgstr "Node-node" + +#: web/ejabberd_web_admin.erl:1923 web/ejabberd_web_admin.erl:1945 +msgid "Node " +msgstr "Node" + +#: web/ejabberd_web_admin.erl:1932 +msgid "Listened Ports" +msgstr "Port Terdeteksi" + +#: web/ejabberd_web_admin.erl:1934 web/ejabberd_web_admin.erl:2255 +#: web/ejabberd_web_admin.erl:2443 +msgid "Update" +msgstr "Memperbarui" + +#: web/ejabberd_web_admin.erl:1937 web/ejabberd_web_admin.erl:2564 +msgid "Restart" +msgstr "Jalankan Ulang" + +#: web/ejabberd_web_admin.erl:1939 web/ejabberd_web_admin.erl:2566 +msgid "Stop" +msgstr "Hentikan" + +#: web/ejabberd_web_admin.erl:1953 +msgid "RPC Call Error" +msgstr "Panggilan Kesalahan RPC" + +#: web/ejabberd_web_admin.erl:1994 +msgid "Database Tables at " +msgstr "Tabel Database pada" + +#: web/ejabberd_web_admin.erl:2001 +msgid "Storage Type" +msgstr "Jenis Penyimpanan" + +#: web/ejabberd_web_admin.erl:2002 +msgid "Elements" +msgstr "Elemen-elemen" + +#: web/ejabberd_web_admin.erl:2003 +msgid "Memory" +msgstr "Memori" + +#: web/ejabberd_web_admin.erl:2027 web/ejabberd_web_admin.erl:2132 +msgid "Error" +msgstr "Kesalahan" + +#: web/ejabberd_web_admin.erl:2029 +msgid "Backup of " +msgstr "Cadangan dari" + +#: web/ejabberd_web_admin.erl:2031 +msgid "" +"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." +msgstr "" +"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." + +#: web/ejabberd_web_admin.erl:2036 +msgid "Store binary backup:" +msgstr "Penyimpanan cadangan yang berpasangan:" + +#: web/ejabberd_web_admin.erl:2040 web/ejabberd_web_admin.erl:2047 +#: web/ejabberd_web_admin.erl:2055 web/ejabberd_web_admin.erl:2062 +#: web/ejabberd_web_admin.erl:2069 web/ejabberd_web_admin.erl:2076 +#: web/ejabberd_web_admin.erl:2083 web/ejabberd_web_admin.erl:2091 +#: web/ejabberd_web_admin.erl:2098 web/ejabberd_web_admin.erl:2105 +msgid "OK" +msgstr "YA" + +#: web/ejabberd_web_admin.erl:2043 +msgid "Restore binary backup immediately:" +msgstr "Segera mengembalikan cadangan yang berpasangan:" + +#: web/ejabberd_web_admin.erl:2051 +msgid "" +"Restore binary backup after next ejabberd restart (requires less memory):" +msgstr "" +"Mengembalikan cadangan yang berpasanagn setelah ejabberd berikutnya " +"dijalankan ulang (memerlukan memori lebih sedikit):" + +#: web/ejabberd_web_admin.erl:2058 +msgid "Store plain text backup:" +msgstr "Simpan cadangan teks biasa:" + +#: web/ejabberd_web_admin.erl:2065 +msgid "Restore plain text backup immediately:" +msgstr "Segera mengembalikan cadangan teks biasa:" + +#: web/ejabberd_web_admin.erl:2072 +msgid "Import users data from a PIEFXIS file (XEP-0227):" +msgstr "impor data-data pengguna dari sebuah PIEFXIS (XEP-0227):" + +#: web/ejabberd_web_admin.erl:2079 +msgid "Export data of all users in the server to PIEFXIS files (XEP-0227):" +msgstr "" +"Ekspor data dari semua pengguna pada layanan ke berkas PIEFXIS (XEP-0227):" + +#: web/ejabberd_web_admin.erl:2086 +msgid "Export data of users in a host to PIEFXIS files (XEP-0227):" +msgstr "Ekspor data pengguna pada sebuah host ke berkas PIEFXIS (XEP-0227):" + +#: web/ejabberd_web_admin.erl:2094 +msgid "Import user data from jabberd14 spool file:" +msgstr "Impor data pengguna dari sekumpulan berkas jabberd14:" + +#: web/ejabberd_web_admin.erl:2101 +msgid "Import users data from jabberd14 spool directory:" +msgstr "Импорт пользовательских данных из буферной директории jabberd14:" + +#: web/ejabberd_web_admin.erl:2127 +msgid "Listened Ports at " +msgstr "Mendeteksi Port-port di" + +#: web/ejabberd_web_admin.erl:2152 +msgid "Modules at " +msgstr "modul-modul di" + +#: web/ejabberd_web_admin.erl:2178 +msgid "Statistics of ~p" +msgstr "statistik dari ~p" + +#: web/ejabberd_web_admin.erl:2181 +msgid "Uptime:" +msgstr "Sampai saat:" + +#: web/ejabberd_web_admin.erl:2184 +msgid "CPU Time:" +msgstr "Waktu CPU:" + +#: web/ejabberd_web_admin.erl:2190 +msgid "Transactions Committed:" +msgstr "Transaksi yang dilakukan:" + +#: web/ejabberd_web_admin.erl:2193 +msgid "Transactions Aborted:" +msgstr "Transaksi yang dibatalkan:" + +#: web/ejabberd_web_admin.erl:2196 +msgid "Transactions Restarted:" +msgstr "Transaksi yang dijalankan ulang:" + +#: web/ejabberd_web_admin.erl:2199 +msgid "Transactions Logged:" +msgstr "Transaksi yang ditempuh:" + +#: web/ejabberd_web_admin.erl:2241 +msgid "Update " +msgstr "Memperbarui " + +#: web/ejabberd_web_admin.erl:2249 +msgid "Update plan" +msgstr "Rencana Perubahan" + +#: web/ejabberd_web_admin.erl:2250 +msgid "Modified modules" +msgstr "Modifikasi modul-modul" + +#: web/ejabberd_web_admin.erl:2251 +msgid "Update script" +msgstr "Perbarui naskah" + +#: web/ejabberd_web_admin.erl:2252 +msgid "Low level update script" +msgstr "Perbaruan naskah tingkat rendah" + +#: web/ejabberd_web_admin.erl:2253 +msgid "Script check" +msgstr "Periksa naskah" + +#: web/ejabberd_web_admin.erl:2421 +msgid "Port" +msgstr "Port" + +#: web/ejabberd_web_admin.erl:2422 +msgid "IP" +msgstr "IP" + +#: web/ejabberd_web_admin.erl:2423 +msgid "Protocol" +msgstr "Protocol" + +#: web/ejabberd_web_admin.erl:2424 web/ejabberd_web_admin.erl:2551 +msgid "Module" +msgstr "Modul" + +#: web/ejabberd_web_admin.erl:2425 web/ejabberd_web_admin.erl:2552 +msgid "Options" +msgstr "Pilihan-pilihan" + +#: web/ejabberd_web_admin.erl:2445 +msgid "Delete" +msgstr "Hapus" + +#: web/ejabberd_web_admin.erl:2574 +msgid "Start" +msgstr "Mulai" + +#: web/mod_register_web.erl:103 +msgid "Your Jabber account was successfully created." +msgstr "Jabber akun Anda telah sukses dibuat" + +#: web/mod_register_web.erl:106 +msgid "There was an error creating the account: " +msgstr "Ada kesalahan saat membuat akun:" + +#: web/mod_register_web.erl:114 +msgid "Your Jabber account was successfully deleted." +msgstr "Jabber akun Anda berhasil dihapus." + +#: web/mod_register_web.erl:117 +msgid "There was an error deleting the account: " +msgstr "Ada kesalahan saat menghapus akun:" + +#: web/mod_register_web.erl:127 +msgid "The password of your Jabber account was successfully changed." +msgstr "Kata sandi pada akun Jabber Anda telah berhasil diubah." + +#: web/mod_register_web.erl:130 +msgid "There was an error changing the password: " +msgstr "Ada kesalahan dalam mengubah password:" + +#: web/mod_register_web.erl:162 web/mod_register_web.erl:171 +msgid "Jabber Account Registration" +msgstr "Pendaftaran Akun Jabber" + +#: web/mod_register_web.erl:173 web/mod_register_web.erl:191 +#: web/mod_register_web.erl:200 +msgid "Register a Jabber account" +msgstr "Daftarkan sebuah akun 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 "Nonaktifkan akun jabber" + +#: web/mod_register_web.erl:202 +msgid "" +"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." +msgstr "" +"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." + +#: web/mod_register_web.erl:211 web/mod_register_web.erl:381 +#: web/mod_register_web.erl:504 +msgid "Username:" +msgstr "Nama Pengguna:" + +#: web/mod_register_web.erl:216 +msgid "This is case insensitive: macbeth is the same that MacBeth and Macbeth." +msgstr "" +"Pada bagian ini huruf besar dan kecil tidak dibedakan: Misalnya macbeth " +"adalah sama dengan MacBeth juga Macbeth." + +#: web/mod_register_web.erl:217 +msgid "Characters not allowed:" +msgstr "Karakter tidak diperbolehkan:" + +#: web/mod_register_web.erl:221 web/mod_register_web.erl:386 +#: web/mod_register_web.erl:509 +msgid "Server:" +msgstr "Layanan:" + +#: web/mod_register_web.erl:231 +msgid "" +"Don't tell your password to anybody, not even the administrators of the " +"Jabber server." +msgstr "" +"Jangan memberitahukan kata sandi Anda ke siapapun, bahkan para administrator " +"dari layanan Jabber." + +#: web/mod_register_web.erl:233 +msgid "You can later change your password using a Jabber client." +msgstr "" +"Anda dapat mengubah kata sandi anda dilain waktu dengan menggunakan klien " +"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 "" +"Beberapa klien Jabber dapat menyimpan password di komputer Anda. Gunakan " +"fitur itu hanya jika Anda mempercayai komputer Anda aman." + +#: web/mod_register_web.erl:236 +msgid "" +"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." +msgstr "" +"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." + +#: web/mod_register_web.erl:241 web/mod_register_web.erl:401 +msgid "Password Verification:" +msgstr "Verifikasi Kata Sandi:" + +#: web/mod_register_web.erl:249 +msgid "Register" +msgstr "Mendaftar" + +#: web/mod_register_web.erl:391 +msgid "Old Password:" +msgstr "Password Lama:" + +#: web/mod_register_web.erl:396 +msgid "New Password:" +msgstr "Password Baru:" + +#: web/mod_register_web.erl:499 +msgid "This page allows to unregister a Jabber account in this Jabber server." +msgstr "" +"Pada bagian ini memungkinkan Anda untuk membatalkan pendaftaran akun Jabber " +"pada layanan Jabber ini." + +#: web/mod_register_web.erl:519 +msgid "Unregister" +msgstr "Nonaktifkan" + +#, fuzzy +#~ msgid "Captcha test failed" +#~ msgstr "Проверка капчи прошла успешно." diff --git a/src/msgs/it.msg b/src/msgs/it.msg index 329450a54..712745abf 100644 --- a/src/msgs/it.msg +++ b/src/msgs/it.msg @@ -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ì"}. diff --git a/src/msgs/it.po b/src/msgs/it.po index 3dc6ddd24..b049385d6 100644 --- a/src/msgs/it.po +++ b/src/msgs/it.po @@ -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" diff --git a/src/msgs/ja.msg b/src/msgs/ja.msg index c5b5af3bd..8da952c61 100644 --- a/src/msgs/ja.msg +++ b/src/msgs/ja.msg @@ -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","水曜日"}. diff --git a/src/msgs/ja.po b/src/msgs/ja.po index 2efb82439..2c11e4347 100644 --- a/src/msgs/ja.po +++ b/src/msgs/ja.po @@ -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 \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 \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" @@ -379,7 +381,7 @@ msgstr "パスワード" #: mod_configure.erl:1210 msgid "Password Verification" -msgstr "パスワード(確認)" +msgstr "パスワード (確認)" #: mod_configure.erl:1301 msgid "Number of registered users" @@ -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,12 +458,12 @@ 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" -msgstr "IRCユーザー名" +msgstr "IRC ユーザー名" #: mod_irc/mod_irc.erl:585 msgid "" @@ -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 @@ -489,27 +491,27 @@ msgstr "接続パラメータ" #: mod_irc/mod_irc.erl:727 msgid "Join IRC channel" -msgstr "IRCチャンネルに参加" +msgstr "IRC チャンネルに参加" #: mod_irc/mod_irc.erl:731 msgid "IRC channel (don't put the first #)" -msgstr "IRCチャンネル(先頭に#は不要)" +msgstr "IRC チャンネル (先頭に#は不要)" #: mod_irc/mod_irc.erl:736 msgid "IRC server" -msgstr "IRCサーバー" +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" -msgstr "IRC設定" +msgstr "IRC 設定" #: mod_irc/mod_irc.erl:867 msgid "" @@ -517,13 +519,13 @@ 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 msgid "IRC username" -msgstr "IRCユーザー名" +msgstr "IRC ユーザー名" #: mod_irc/mod_irc.erl:922 msgid "Password ~b" @@ -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" @@ -1116,7 +1117,7 @@ msgstr "イベントメッセージ種別を設定" #: mod_pubsub/mod_pubsub.erl:3405 mod_pubsub/mod_pubsub_odbc.erl:3247 msgid "Max payload size in bytes" -msgstr "最大ぺイロードサイズ(byte)" +msgstr "最大ぺイロードサイズ (byte)" #: mod_pubsub/mod_pubsub.erl:3406 mod_pubsub/mod_pubsub_odbc.erl:3248 msgid "When to send the last published item" @@ -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" @@ -1220,11 +1221,11 @@ msgstr "新規追加" #: mod_shared_roster.erl:879 msgid "Name:" -msgstr "名前: " +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,15 +1378,15 @@ msgstr "去年" #: web/ejabberd_web_admin.erl:1088 msgid "All activity" -msgstr "全て" +msgstr "すべて" #: web/ejabberd_web_admin.erl:1090 msgid "Show Ordinary Table" -msgstr "Ordinaryテーブルを表示" +msgstr "Ordinary テーブルを表示" #: web/ejabberd_web_admin.erl:1092 msgid "Show Integral Table" -msgstr "Integralテーブルを表示" +msgstr "Integral テーブルを表示" #: web/ejabberd_web_admin.erl:1101 web/ejabberd_web_admin.erl:1933 msgid "Statistics" @@ -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,33 +1533,34 @@ 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):" -msgstr "ユーザーデータを PIEFXISファイルからインポート(XEP-0227):" +msgstr "ユーザーデータを PIEFXIS ファイルからインポート (XEP-0227):" #: 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):" -msgstr "ホストのユーザーデータをPIEFXISファイルにエクスポート(XEP-0227):" +msgstr "ホストのユーザーデータを PIEFXIS ファイルにエクスポート (XEP-0227):" #: web/ejabberd_web_admin.erl:2094 msgid "Import user data from jabberd14 spool file:" @@ -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" @@ -1658,7 +1660,7 @@ msgstr "開始" #: web/mod_register_web.erl:103 msgid "Your Jabber account was successfully created." -msgstr "Jabberアカウントの作成に成功しました。" +msgstr "Jabber アカウントの作成に成功しました。" #: web/mod_register_web.erl:106 msgid "There was an error creating the account: " @@ -1666,7 +1668,7 @@ msgstr "アカウントの作成中にエラーが発生しました: " #: web/mod_register_web.erl:114 msgid "Your Jabber account was successfully deleted." -msgstr "Jabberアカウントの削除に成功しました。" +msgstr "Jabber アカウントの削除に成功しました。" #: web/mod_register_web.erl:117 msgid "There was an error deleting the account: " @@ -1674,7 +1676,7 @@ msgstr "アカウントの削除中にエラーが発生しました: " #: web/mod_register_web.erl:127 msgid "The password of your Jabber account was successfully changed." -msgstr "Jabberアカウントのパスワード変更に成功しました。" +msgstr "Jabber アカウントのパスワード変更に成功しました。" #: web/mod_register_web.erl:130 msgid "There was an error changing the password: " @@ -1682,17 +1684,17 @@ msgstr "パスワードの変更中にエラーが発生しました: " #: web/mod_register_web.erl:162 web/mod_register_web.erl:171 msgid "Jabber Account Registration" -msgstr "Jabberアカウント登録" +msgstr "Jabber アカウント登録" #: web/mod_register_web.erl:173 web/mod_register_web.erl:191 #: web/mod_register_web.erl:200 msgid "Register a Jabber account" -msgstr "Jabberアカウントを登録" +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,13 +1753,13 @@ 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:" -msgstr "パスワード(確認):" +msgstr "パスワード (確認):" #: web/mod_register_web.erl:249 msgid "Register" @@ -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 "指定されたニックネームは既に登録されています" diff --git a/src/msgs/nl.msg b/src/msgs/nl.msg index a105c5d11..d793d3dea 100644 --- a/src/msgs/nl.msg +++ b/src/msgs/nl.msg @@ -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"}. diff --git a/src/msgs/nl.po b/src/msgs/nl.po index 0057aaaa8..bf2254700 100644 --- a/src/msgs/nl.po +++ b/src/msgs/nl.po @@ -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 diff --git a/src/msgs/no.msg b/src/msgs/no.msg index eea9eb526..0d8adf85f 100644 --- a/src/msgs/no.msg +++ b/src/msgs/no.msg @@ -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"}. diff --git a/src/msgs/no.po b/src/msgs/no.po index 560fe7fa7..cc66e81bb 100644 --- a/src/msgs/no.po +++ b/src/msgs/no.po @@ -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" diff --git a/src/msgs/pl.msg b/src/msgs/pl.msg index 01083e38d..1dc68356b 100644 --- a/src/msgs/pl.msg +++ b/src/msgs/pl.msg @@ -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"}. diff --git a/src/msgs/pl.po b/src/msgs/pl.po index 28bfa21e1..bc3932b0a 100644 --- a/src/msgs/pl.po +++ b/src/msgs/pl.po @@ -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" diff --git a/src/msgs/pt-br.msg b/src/msgs/pt-br.msg index f2cbf3e7f..f7c334751 100644 --- a/src/msgs/pt-br.msg +++ b/src/msgs/pt-br.msg @@ -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"}. diff --git a/src/msgs/pt-br.po b/src/msgs/pt-br.po index 59be6338a..e82979288 100644 --- a/src/msgs/pt-br.po +++ b/src/msgs/pt-br.po @@ -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" diff --git a/src/msgs/pt.po b/src/msgs/pt.po index 25145e820..7758ac720 100644 --- a/src/msgs/pt.po +++ b/src/msgs/pt.po @@ -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" diff --git a/src/msgs/ru.msg b/src/msgs/ru.msg index b618e6bde..3949ae07e 100644 --- a/src/msgs/ru.msg +++ b/src/msgs/ru.msg @@ -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","Среда"}. diff --git a/src/msgs/ru.po b/src/msgs/ru.po index e4b567819..9f302d431 100644 --- a/src/msgs/ru.po +++ b/src/msgs/ru.po @@ -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" diff --git a/src/msgs/sk.msg b/src/msgs/sk.msg index 3f5b24ab8..3fd23a6df 100644 --- a/src/msgs/sk.msg +++ b/src/msgs/sk.msg @@ -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"}. diff --git a/src/msgs/sk.po b/src/msgs/sk.po index c35d815c8..ad766ca82 100644 --- a/src/msgs/sk.po +++ b/src/msgs/sk.po @@ -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á" diff --git a/src/msgs/sv.msg b/src/msgs/sv.msg index 96aecf28a..fb69f9dce 100644 --- a/src/msgs/sv.msg +++ b/src/msgs/sv.msg @@ -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"}. diff --git a/src/msgs/sv.po b/src/msgs/sv.po index db5d1186f..6fa9b7110 100644 --- a/src/msgs/sv.po +++ b/src/msgs/sv.po @@ -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" diff --git a/src/msgs/th.msg b/src/msgs/th.msg index 74edb47b5..892fe48bb 100644 --- a/src/msgs/th.msg +++ b/src/msgs/th.msg @@ -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","เวลาที่ส่งรายการที่เผยแพร่ครั้งล่าสุด"}. diff --git a/src/msgs/th.po b/src/msgs/th.po index 36b5151e1..4a2aabdeb 100644 --- a/src/msgs/th.po +++ b/src/msgs/th.po @@ -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 "ชื่อเล่นที่ระบุได้รับการลงได้ทะเบียนแล้ว" diff --git a/src/msgs/tr.msg b/src/msgs/tr.msg index beff9c153..014b7c81a 100644 --- a/src/msgs/tr.msg +++ b/src/msgs/tr.msg @@ -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"}. diff --git a/src/msgs/tr.po b/src/msgs/tr.po index 11e88f569..333eaa5c3 100644 --- a/src/msgs/tr.po +++ b/src/msgs/tr.po @@ -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" diff --git a/src/msgs/uk.msg b/src/msgs/uk.msg index cf1e6a8db..4da7e09dc 100644 --- a/src/msgs/uk.msg +++ b/src/msgs/uk.msg @@ -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","Середа"}. diff --git a/src/msgs/uk.po b/src/msgs/uk.po index 2b1b195f9..92c3ab3f7 100644 --- a/src/msgs/uk.po +++ b/src/msgs/uk.po @@ -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" diff --git a/src/msgs/vi.msg b/src/msgs/vi.msg index a773c4cc6..da3101110 100644 --- a/src/msgs/vi.msg +++ b/src/msgs/vi.msg @@ -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"}. diff --git a/src/msgs/vi.po b/src/msgs/vi.po index 5132061d7..721caab88 100644 --- a/src/msgs/vi.po +++ b/src/msgs/vi.po @@ -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" diff --git a/src/msgs/wa.msg b/src/msgs/wa.msg index 327a08fac..199a6eaf8 100644 --- a/src/msgs/wa.msg +++ b/src/msgs/wa.msg @@ -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"}. diff --git a/src/msgs/wa.po b/src/msgs/wa.po index 4e3a664e2..b3ac7c799 100644 --- a/src/msgs/wa.po +++ b/src/msgs/wa.po @@ -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é" diff --git a/src/msgs/zh.msg b/src/msgs/zh.msg index b025b16d2..e13cd154f 100644 --- a/src/msgs/zh.msg +++ b/src/msgs/zh.msg @@ -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","星期三"}. diff --git a/src/msgs/zh.po b/src/msgs/zh.po index bd740c004..cb55bce26 100644 --- a/src/msgs/zh.po +++ b/src/msgs/zh.po @@ -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 "指定的昵称已被注册" diff --git a/src/odbc/mssql2000.sql b/src/odbc/mssql2000.sql index 151d474a5..d4a70989d 100644 --- a/src/odbc/mssql2000.sql +++ b/src/odbc/mssql2000.sql @@ -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 **/ diff --git a/src/odbc/mssql2005.sql b/src/odbc/mssql2005.sql index 8420b7690..911207078 100644 --- a/src/odbc/mssql2005.sql +++ b/src/odbc/mssql2005.sql @@ -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 **/ diff --git a/src/odbc/odbc_queries.erl b/src/odbc/odbc_queries.erl index 3e3a29422..b614fd790 100644 --- a/src/odbc/odbc_queries.erl +++ b/src/odbc/odbc_queries.erl @@ -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. diff --git a/src/pg2_backport.erl b/src/pg2_backport.erl index 353bef0eb..faa775524 100644 --- a/src/pg2_backport.erl +++ b/src/pg2_backport.erl @@ -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}, diff --git a/src/web/ejabberd_http.erl b/src/web/ejabberd_http.erl index a34aea993..fb38b17a4 100644 --- a/src/web/ejabberd_http.erl +++ b/src/web/ejabberd_http.erl @@ -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) -> diff --git a/src/web/ejabberd_web_admin.erl b/src/web/ejabberd_web_admin.erl index 607bdcbfe..f3809c15e 100644 --- a/src/web/ejabberd_web_admin.erl +++ b/src/web/ejabberd_web_admin.erl @@ -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"], diff --git a/src/web/mod_register_web.erl b/src/web/mod_register_web.erl index 2c6fda28f..98ee52fb9 100644 --- a/src/web/mod_register_web.erl +++ b/src/web/mod_register_web.erl @@ -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), - [?XE("li", [CText, - ?C(" "), - CId, - CKey, - ?BR, - CImg] - )]. + 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