public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/ejabberd] f45: Ver. 2.1.0
@ 2026-09-23 19:06 Peter Lemenkov
0 siblings, 0 replies; only message in thread
From: Peter Lemenkov @ 2026-09-23 19:06 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/ejabberd
Branch : f45
Commit : 63ecd49025a9416f9d058ca62ef9e31b816691fe
Author : Peter Lemenkov <peter@fedoraproject.org>
Date : 2009-11-21T08:01:19+00:00
Stats : +166/-1597 in 13 file(s)
URL : https://src.fedoraproject.org/rpms/ejabberd/c/63ecd49025a9416f9d058ca62ef9e31b816691fe?branch=f45
Log:
Ver. 2.1.0
---
diff --git a/.cvsignore b/.cvsignore
index 7182d06..1a0dda1 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1 +1 @@
-ejabberd-2.0.5.tar.gz
+ejabberd-2.1.0.tar.gz
diff --git a/ejabberd-build.patch b/ejabberd-build.patch
deleted file mode 100644
index f0e02dd..0000000
--- a/ejabberd-build.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/Makefile.in.fix_paths 2008-08-01 16:34:28.000000000 +0400
-+++ src/Makefile.in 2008-08-09 19:54:03.000000000 +0400
-@@ -58,7 +58,7 @@
-
- DESTDIR =
-
--EJABBERDDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
-+EJABBERDDIR = $(DESTDIR)@libdir@/ejabberd
- BEAMDIR = $(EJABBERDDIR)/ebin
- SPOOLDIR = $(EJABBERDDIR)/db
- PRIVDIR = $(EJABBERDDIR)/priv
diff --git a/ejabberd-captcha.patch b/ejabberd-captcha.patch
deleted file mode 100644
index 4e9334b..0000000
--- a/ejabberd-captcha.patch
+++ /dev/null
@@ -1,641 +0,0 @@
-Binary files ejabberd-2.0.4/src/.DS_Store and ejabberd-2.0.4-new/src/.DS_Store differ
-diff -urN ejabberd-2.0.4/src/ejabberd_captcha.erl ejabberd-2.0.4-new/src/ejabberd_captcha.erl
---- ejabberd-2.0.4/src/ejabberd_captcha.erl 1970-01-01 01:00:00.000000000 +0100
-+++ ejabberd-2.0.4-new/src/ejabberd_captcha.erl 2009-03-14 07:27:05.000000000 +0100
-@@ -0,0 +1,312 @@
-+%%%-------------------------------------------------------------------
-+%%% File : ejabberd_captcha.erl
-+%%% Author : Evgeniy Khramtsov <xramtsov@gmail.com>
-+%%% Description : CAPTCHA processing.
-+%%%
-+%%% Created : 26 Apr 2008 by Evgeniy Khramtsov <xramtsov@gmail.com>
-+%%%-------------------------------------------------------------------
-+-module(ejabberd_captcha).
-+
-+-behaviour(gen_server).
-+
-+%% API
-+-export([start_link/0]).
-+
-+%% gen_server callbacks
-+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
-+ terminate/2, code_change/3]).
-+
-+-export([create_captcha/6, process_reply/1, process/2]).
-+
-+-include("jlib.hrl").
-+-include("ejabberd.hrl").
-+-include("web/ejabberd_http.hrl").
-+
-+-define(VFIELD(Type, Var, Value),
-+ {xmlelement, "field", [{"type", Type}, {"var", Var}],
-+ [{xmlelement, "value", [], [Value]}]}).
-+
-+-define(CAPTCHA_BODY(Lang, Room, URL),
-+ translate:translate(Lang, "Your messages to ") ++ Room
-+ ++ translate:translate(Lang, " are being blocked. To unblock them, visit ")
-+ ++ URL).
-+
-+-define(CAPTCHA_TEXT(Lang), translate:translate(Lang, "Enter the text you see")).
-+-define(CAPTCHA_LIFETIME, 120000). % two minutes
-+
-+-record(state, {}).
-+-record(captcha, {id, pid, key, tref, args}).
-+
-+-define(T(S),
-+ case catch mnesia:transaction(fun() -> S end) of
-+ {atomic, Res} ->
-+ Res;
-+ {_, Reason} ->
-+ ?ERROR_MSG("mnesia transaction failed: ~p", [Reason]),
-+ {error, Reason}
-+ end).
-+
-+%%====================================================================
-+%% API
-+%%====================================================================
-+%%--------------------------------------------------------------------
-+%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
-+%% Description: Starts the server
-+%%--------------------------------------------------------------------
-+start_link() ->
-+ gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-+
-+create_captcha(Id, SID, From, To, Lang, Args)
-+ when is_list(Id), is_list(Lang), is_list(SID),
-+ is_record(From, jid), is_record(To, jid) ->
-+ case create_image() of
-+ {ok, Type, Key, Image} ->
-+ B64Image = jlib:encode_base64(binary_to_list(Image)),
-+ JID = jlib:jid_to_string(From),
-+ CID = "sha1+" ++ sha:sha(Image) ++ "@bob.xmpp.org",
-+ Data = {xmlelement, "data",
-+ [{"xmlns", ?NS_BOB}, {"cid", CID},
-+ {"max-age", "0"}, {"type", Type}],
-+ [{xmlcdata, B64Image}]},
-+ Captcha =
-+ {xmlelement, "captcha", [{"xmlns", ?NS_CAPTCHA}],
-+ [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}],
-+ [?VFIELD("hidden", "FORM_TYPE", {xmlcdata, ?NS_CAPTCHA}),
-+ ?VFIELD("hidden", "from", {xmlcdata, jlib:jid_to_string(To)}),
-+ ?VFIELD("hidden", "challenge", {xmlcdata, Id}),
-+ ?VFIELD("hidden", "sid", {xmlcdata, SID}),
-+ {xmlelement, "field", [{"var", "ocr"}],
-+ [{xmlelement, "media", [{"xmlns", ?NS_MEDIA}],
-+ [{xmlelement, "uri", [{"type", Type}],
-+ [{xmlcdata, "cid:" ++ CID}]}]}]}]}]},
-+ Body = {xmlelement, "body", [],
-+ [{xmlcdata, ?CAPTCHA_BODY(Lang, JID, get_url(Id))}]},
-+ OOB = {xmlelement, "x", [{"xmlns", ?NS_OOB}],
-+ [{xmlelement, "url", [], [{xmlcdata, get_url(Id)}]}]},
-+ Tref = erlang:send_after(?CAPTCHA_LIFETIME, ?MODULE, {remove_id, Id}),
-+ ?T(mnesia:write(#captcha{id=Id, pid=self(), key=Key,
-+ tref=Tref, args=Args})),
-+ {ok, [Body, OOB, Captcha, Data]};
-+ _Err ->
-+ error
-+ end.
-+
-+process_reply({xmlelement, "captcha", _, _} = El) ->
-+ case xml:get_subtag(El, "x") of
-+ false ->
-+ {error, malformed};
-+ Xdata ->
-+ Fields = jlib:parse_xdata_submit(Xdata),
-+ [Id | _] = proplists:get_value("challenge", Fields, [none]),
-+ [OCR | _] = proplists:get_value("ocr", Fields, [none]),
-+ ?T(case mnesia:read(captcha, Id, write) of
-+ [#captcha{pid=Pid, args=Args, key=Key, tref=Tref}] ->
-+ mnesia:delete({captcha, Id}),
-+ erlang:cancel_timer(Tref),
-+ if OCR == Key ->
-+ Pid ! {captcha_succeed, Args},
-+ ok;
-+ true ->
-+ Pid ! {captcha_failed, Args},
-+ {error, bad_match}
-+ end;
-+ _ ->
-+ {error, not_found}
-+ end)
-+ end;
-+process_reply(_) ->
-+ {error, malformed}.
-+
-+process(_Handlers, #request{method='GET', lang=Lang, path=[_, Id]}) ->
-+ case mnesia:dirty_read(captcha, Id) of
-+ [#captcha{}] ->
-+ Form =
-+ {xmlelement, "div", [{"align", "center"}],
-+ [{xmlelement, "form", [{"action", get_url(Id)},
-+ {"name", "captcha"},
-+ {"method", "POST"}],
-+ [{xmlelement, "img", [{"src", get_url(Id ++ "/image")}], []},
-+ {xmlelement, "br", [], []},
-+ {xmlcdata, ?CAPTCHA_TEXT(Lang)},
-+ {xmlelement, "br", [], []},
-+ {xmlelement, "input", [{"type", "text"},
-+ {"name", "key"},
-+ {"size", "10"}], []},
-+ {xmlelement, "br", [], []},
-+ {xmlelement, "input", [{"type", "submit"},
-+ {"name", "enter"},
-+ {"value", "OK"}], []}]}]},
-+ ejabberd_web:make_xhtml([Form]);
-+ _ ->
-+ ejabberd_web:error(not_found)
-+ end;
-+
-+process(_Handlers, #request{method='GET', path=[_, Id, "image"]}) ->
-+ case mnesia:dirty_read(captcha, Id) of
-+ [#captcha{key=Key}] ->
-+ case create_image(Key) of
-+ {ok, Type, _, Img} ->
-+ {200,
-+ [{"Content-Type", Type},
-+ {"Cache-Control", "no-cache"},
-+ {"Last-Modified", httpd_util:rfc1123_date()}],
-+ Img};
-+ _ ->
-+ ejabberd_web:error(not_found)
-+ end;
-+ _ ->
-+ ejabberd_web:error(not_found)
-+ end;
-+
-+process(_Handlers, #request{method='POST', q=Q, path=[_, Id]}) ->
-+ ?T(case mnesia:read(captcha, Id, write) of
-+ [#captcha{pid=Pid, args=Args, key=Key, tref=Tref}] ->
-+ mnesia:delete({captcha, Id}),
-+ erlang:cancel_timer(Tref),
-+ Input = proplists:get_value("key", Q, none),
-+ if Input == Key ->
-+ Pid ! {captcha_succeed, Args},
-+ ejabberd_web:make_xhtml([]);
-+ true ->
-+ Pid ! {captcha_failed, Args},
-+ ejabberd_web:error(not_allowed)
-+ end;
-+ _ ->
-+ ejabberd_web:error(not_found)
-+ end).
-+
-+%%====================================================================
-+%% gen_server callbacks
-+%%====================================================================
-+init([]) ->
-+ mnesia:create_table(captcha,
-+ [{ram_copies, [node()]},
-+ {attributes, record_info(fields, captcha)}]),
-+ mnesia:add_table_copy(captcha, node(), ram_copies),
-+ {ok, #state{}}.
-+
-+handle_call(_Request, _From, State) ->
-+ {reply, bad_request, State}.
-+
-+handle_cast(_Msg, State) ->
-+ {noreply, State}.
-+
-+handle_info({remove_id, Id}, State) ->
-+ ?DEBUG("captcha ~p timed out", [Id]),
-+ ?T(case mnesia:read(captcha, Id, write) of
-+ [#captcha{args=Args, pid=Pid}] ->
-+ Pid ! {captcha_failed, Args},
-+ mnesia:delete({captcha, Id});
-+ _ ->
-+ ok
-+ end),
-+ {noreply, State};
-+
-+handle_info(_Info, State) ->
-+ {noreply, State}.
-+
-+terminate(_Reason, _State) ->
-+ ok.
-+
-+code_change(_OldVsn, State, _Extra) ->
-+ {ok, State}.
-+
-+%%--------------------------------------------------------------------
-+%%% Internal functions
-+%%--------------------------------------------------------------------
-+%%--------------------------------------------------------------------
-+%% Function: create_image() -> {ok, Type, Key, Image} | {error, Reason}
-+%% Type = "image/png" | "image/jpeg" | "image/gif"
-+%% Key = string()
-+%% Image = binary()
-+%% Reason = atom()
-+%%--------------------------------------------------------------------
-+create_image() ->
-+ %% Six numbers from 1 to 9.
-+ Key = string:substr(randoms:get_string(), 1, 6),
-+ create_image(Key).
-+
-+create_image(Key) ->
-+ FileName = get_prog_name(),
-+ Cmd = lists:flatten(io_lib:format("~s ~s", [FileName, Key])),
-+ case cmd(Cmd) of
-+ {ok, <<16#89, $P, $N, $G, $\r, $\n, 16#1a, $\n, _/binary>> = Img} ->
-+ {ok, "image/png", Key, Img};
-+ {ok, <<16#ff, 16#d8, _/binary>> = Img} ->
-+ {ok, "image/jpeg", Key, Img};
-+ {ok, <<$G, $I, $F, $8, X, $a, _/binary>> = Img} when X==$7; X==$9 ->
-+ {ok, "image/gif", Key, Img};
-+ {error, Reason} ->
-+ ?ERROR_MSG("Failed to process an output from \"~s\": ~p",
-+ [Cmd, Reason]),
-+ {error, Reason};
-+ _ ->
-+ Reason = malformed_image,
-+ ?ERROR_MSG("Failed to process an output from \"~s\": ~p",
-+ [Cmd, Reason]),
-+ {error, Reason}
-+ end.
-+
-+get_prog_name() ->
-+ case ejabberd_config:get_local_option(captcha_cmd) of
-+ FileName when is_list(FileName) ->
-+ FileName;
-+ _ ->
-+ ""
-+ end.
-+
-+get_url(Str) ->
-+ case ejabberd_config:get_local_option(captcha_host) of
-+ Host when is_list(Host) ->
-+ "http://" ++ Host ++ "/captcha/" ++ Str;
-+ _ ->
-+ "http://" ++ ?MYNAME ++ "/captcha/" ++ Str
-+ end.
-+
-+%%--------------------------------------------------------------------
-+%% Function: cmd(Cmd) -> Data | {error, Reason}
-+%% Cmd = string()
-+%% Data = binary()
-+%% Description: os:cmd/1 replacement
-+%%--------------------------------------------------------------------
-+-define(CMD_TIMEOUT, 5000).
-+-define(MAX_FILE_SIZE, 64*1024).
-+
-+cmd(Cmd) ->
-+ Port = open_port({spawn, Cmd}, [stream, eof, binary]),
-+ TRef = erlang:start_timer(?CMD_TIMEOUT, self(), timeout),
-+ recv_data(Port, TRef, <<>>).
-+
-+recv_data(Port, TRef, Buf) ->
-+ receive
-+ {Port, {data, Bytes}} ->
-+ NewBuf = <<Buf/binary, Bytes/binary>>,
-+ if size(NewBuf) > ?MAX_FILE_SIZE ->
-+ return(Port, TRef, {error, efbig});
-+ true ->
-+ recv_data(Port, TRef, NewBuf)
-+ end;
-+ {Port, {data, _}} ->
-+ return(Port, TRef, {error, efbig});
-+ {Port, eof} when Buf /= <<>> ->
-+ return(Port, TRef, {ok, Buf});
-+ {Port, eof} ->
-+ return(Port, TRef, {error, enodata});
-+ {timeout, TRef, _} ->
-+ return(Port, TRef, {error, timeout})
-+ end.
-+
-+return(Port, TRef, Result) ->
-+ case erlang:cancel_timer(TRef) of
-+ false ->
-+ receive
-+ {timeout, TRef, _} ->
-+ ok
-+ after 0 ->
-+ ok
-+ end;
-+ _ ->
-+ ok
-+ end,
-+ catch port_close(Port),
-+ Result.
-diff -urN ejabberd-2.0.4/src/ejabberd_config.erl ejabberd-2.0.4-new/src/ejabberd_config.erl
---- ejabberd-2.0.4/src/ejabberd_config.erl 2009-03-12 09:41:02.000000000 +0100
-+++ ejabberd-2.0.4-new/src/ejabberd_config.erl 2009-03-14 11:43:35.000000000 +0100
-@@ -164,6 +164,10 @@
- add_option(watchdog_admins, Admins, State);
- {registration_timeout, Timeout} ->
- add_option(registration_timeout, Timeout, State);
-+ {captcha_cmd, Cmd} ->
-+ add_option(captcha_cmd, Cmd, State);
-+ {captcha_host, Host} ->
-+ add_option(captcha_host, Host, State);
- {loglevel, Loglevel} ->
- ejabberd_loglevel:set(Loglevel),
- State;
-diff -urN ejabberd-2.0.4/src/ejabberd_sup.erl ejabberd-2.0.4-new/src/ejabberd_sup.erl
---- ejabberd-2.0.4/src/ejabberd_sup.erl 2009-03-12 09:41:02.000000000 +0100
-+++ ejabberd-2.0.4-new/src/ejabberd_sup.erl 2009-03-14 12:36:43.000000000 +0100
-@@ -84,6 +84,13 @@
- brutal_kill,
- worker,
- [ejabberd_local]},
-+ Captcha =
-+ {ejabberd_captcha,
-+ {ejabberd_captcha, start_link, []},
-+ permanent,
-+ brutal_kill,
-+ worker,
-+ [ejabberd_captcha]},
- Listener =
- {ejabberd_listener,
- {ejabberd_listener, start_link, []},
-@@ -170,6 +177,7 @@
- SM,
- S2S,
- Local,
-+ Captcha,
- ReceiverSupervisor,
- C2SSupervisor,
- S2SInSupervisor,
-diff -urN ejabberd-2.0.4/src/jlib.hrl ejabberd-2.0.4-new/src/jlib.hrl
---- ejabberd-2.0.4/src/jlib.hrl 2009-03-12 09:41:02.000000000 +0100
-+++ ejabberd-2.0.4-new/src/jlib.hrl 2009-03-14 11:41:46.000000000 +0100
-@@ -74,6 +74,12 @@
-
- -define(NS_CAPS, "http://jabber.org/protocol/caps").
-
-+%% CAPTCHA related NSes.
-+-define(NS_OOB, "jabber:x:oob").
-+-define(NS_CAPTCHA, "urn:xmpp:captcha").
-+-define(NS_MEDIA, "urn:xmpp:media-element").
-+-define(NS_BOB, "urn:xmpp:bob").
-+
- % TODO: remove "code" attribute (currently it used for backward-compatibility)
- -define(STANZA_ERROR(Code, Type, Condition),
- {xmlelement, "error",
-diff -urN ejabberd-2.0.4/src/mod_muc/mod_muc_room.erl ejabberd-2.0.4-new/src/mod_muc/mod_muc_room.erl
---- ejabberd-2.0.4/src/mod_muc/mod_muc_room.erl 2009-03-12 09:41:02.000000000 +0100
-+++ ejabberd-2.0.4-new/src/mod_muc/mod_muc_room.erl 2009-03-14 11:40:40.000000000 +0100
-@@ -69,6 +69,7 @@
- public_list = true,
- persistent = false,
- moderated = true,
-+ captcha_protected = false,
- members_by_default = true,
- members_only = false,
- allow_user_invites = false,
-@@ -98,6 +99,7 @@
- jid,
- config = #config{},
- users = ?DICT:new(),
-+ robots = ?DICT:new(),
- affiliations = ?DICT:new(),
- history = lqueue_new(20),
- subject = "",
-@@ -382,7 +384,8 @@
- (XMLNS == ?NS_MUC_ADMIN) or
- (XMLNS == ?NS_MUC_OWNER) or
- (XMLNS == ?NS_DISCO_INFO) or
-- (XMLNS == ?NS_DISCO_ITEMS) ->
-+ (XMLNS == ?NS_DISCO_ITEMS) or
-+ (XMLNS == ?NS_CAPTCHA) ->
- Res1 = case XMLNS of
- ?NS_MUC_ADMIN ->
- process_iq_admin(From, Type, Lang, SubEl, StateData);
-@@ -391,7 +394,9 @@
- ?NS_DISCO_INFO ->
- process_iq_disco_info(From, Type, Lang, StateData);
- ?NS_DISCO_ITEMS ->
-- process_iq_disco_items(From, Type, Lang, StateData)
-+ process_iq_disco_items(From, Type, Lang, StateData);
-+ ?NS_CAPTCHA ->
-+ process_iq_captcha(From, Type, Lang, SubEl, StateData)
- end,
- {IQRes, NewStateData} =
- case Res1 of
-@@ -761,6 +766,30 @@
- {empty, _} ->
- {next_state, StateName, StateData}
- end;
-+handle_info({captcha_succeed, From}, normal_state, StateData) ->
-+ NewState = case ?DICT:find(From, StateData#state.robots) of
-+ {ok, {Nick, Packet}} ->
-+ Robots = ?DICT:store(From, passed, StateData#state.robots),
-+ add_new_user(From, Nick, Packet, StateData#state{robots=Robots});
-+ _ ->
-+ StateData
-+ end,
-+ {next_state, normal_state, NewState};
-+handle_info({captcha_failed, From}, normal_state, StateData) ->
-+ NewState = case ?DICT:find(From, StateData#state.robots) of
-+ {ok, {Nick, Packet}} ->
-+ Robots = ?DICT:erase(From, StateData#state.robots),
-+ Err = jlib:make_error_reply(
-+ Packet, ?ERR_NOT_AUTHORIZED),
-+ ejabberd_router:route( % TODO: s/Nick/""/
-+ jlib:jid_replace_resource(
-+ StateData#state.jid, Nick),
-+ From, Err),
-+ StateData#state{robots=Robots};
-+ _ ->
-+ StateData
-+ end,
-+ {next_state, normal_state, NewState};
- handle_info(_Info, StateName, StateData) ->
- {next_state, StateName, StateData}.
-
-@@ -1461,7 +1490,8 @@
- From, Err),
- StateData;
- {_, _, _, Role} ->
-- case check_password(ServiceAffiliation, Els, StateData) of
-+ case check_password(ServiceAffiliation, Affiliation,
-+ Els, From, StateData) of
- true ->
- NewState =
- add_user_presence(
-@@ -1494,7 +1524,8 @@
- true ->
- NewState#state{just_created = false};
- false ->
-- NewState
-+ Robots = ?DICT:erase(From, StateData#state.robots),
-+ NewState#state{robots = Robots}
- end;
- nopass ->
- ErrText = "Password required to enter this room",
-@@ -1505,6 +1536,29 @@
- StateData#state.jid, Nick),
- From, Err),
- StateData;
-+ captcha_required ->
-+ ID = randoms:get_string(),
-+ SID = xml:get_attr_s("id", Attrs),
-+ RoomJID = StateData#state.jid,
-+ To = jlib:jid_replace_resource(RoomJID, Nick),
-+ case ejabberd_captcha:create_captcha(
-+ ID, SID, RoomJID, To, Lang, From) of
-+ {ok, 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 ->
-+ ErrText = "Unable to generate a captcha",
-+ Err = jlib:make_error_reply(
-+ Packet, ?ERRT_INTERNAL_SERVER_ERROR(Lang, ErrText)),
-+ ejabberd_router:route( % TODO: s/Nick/""/
-+ jlib:jid_replace_resource(
-+ StateData#state.jid, Nick),
-+ From, Err),
-+ StateData
-+ end;
- _ ->
- ErrText = "Incorrect password",
- Err = jlib:make_error_reply(
-@@ -1517,13 +1571,13 @@
- end
- end.
-
--check_password(owner, _Els, _StateData) ->
-+check_password(owner, _Affiliation, _Els, _From, _StateData) ->
- %% Don't check pass if user is owner in MUC service (access_admin option)
- true;
--check_password(_ServiceAffiliation, Els, StateData) ->
-+check_password(_ServiceAffiliation, Affiliation, Els, From, StateData) ->
- case (StateData#state.config)#config.password_protected of
- false ->
-- true;
-+ check_captcha(Affiliation, From, StateData);
- true ->
- Pass = extract_password(Els),
- case Pass of
-@@ -1539,6 +1593,19 @@
- end
- end.
-
-+check_captcha(Affiliation, From, StateData) ->
-+ case (StateData#state.config)#config.captcha_protected of
-+ true when Affiliation == none ->
-+ case ?DICT:find(From, StateData#state.robots) of
-+ {ok, passed} ->
-+ true;
-+ _ ->
-+ captcha_required
-+ end;
-+ _ ->
-+ true
-+ end.
-+
- extract_password([]) ->
- false;
- extract_password([{xmlelement, _Name, Attrs, _SubEls} = El | Els]) ->
-@@ -2713,6 +2780,9 @@
- ?BOOLXFIELD("Make room members-only",
- "muc#roomconfig_membersonly",
- Config#config.members_only),
-+ ?BOOLXFIELD("Make room captcha protected",
-+ "captcha_protected",
-+ Config#config.captcha_protected),
- ?BOOLXFIELD("Make room moderated",
- "muc#roomconfig_moderatedroom",
- Config#config.moderated),
-@@ -2823,6 +2893,8 @@
- ?SET_BOOL_XOPT(members_by_default, Val);
- set_xoption([{"muc#roomconfig_membersonly", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(members_only, Val);
-+set_xoption([{"captcha_protected", [Val]} | Opts], Config) ->
-+ ?SET_BOOL_XOPT(captcha_protected, Val);
- set_xoption([{"muc#roomconfig_allowinvites", [Val]} | Opts], Config) ->
- ?SET_BOOL_XOPT(allow_user_invites, Val);
- set_xoption([{"muc#roomconfig_passwordprotectedroom", [Val]} | Opts], Config) ->
-@@ -2913,6 +2985,7 @@
- ?CASE_CONFIG_OPT(members_only);
- ?CASE_CONFIG_OPT(allow_user_invites);
- ?CASE_CONFIG_OPT(password_protected);
-+ ?CASE_CONFIG_OPT(captcha_protected);
- ?CASE_CONFIG_OPT(password);
- ?CASE_CONFIG_OPT(anonymous);
- ?CASE_CONFIG_OPT(logging);
-@@ -2954,6 +3027,7 @@
- ?MAKE_CONFIG_OPT(members_only),
- ?MAKE_CONFIG_OPT(allow_user_invites),
- ?MAKE_CONFIG_OPT(password_protected),
-+ ?MAKE_CONFIG_OPT(captcha_protected),
- ?MAKE_CONFIG_OPT(password),
- ?MAKE_CONFIG_OPT(anonymous),
- ?MAKE_CONFIG_OPT(logging),
-@@ -3074,6 +3148,17 @@
- {error, ?ERR_FORBIDDEN}
- end.
-
-+process_iq_captcha(_From, get, _Lang, _SubEl, _StateData) ->
-+ {error, ?ERR_NOT_ALLOWED};
-+
-+process_iq_captcha(_From, set, _Lang, SubEl, StateData) ->
-+ case ejabberd_captcha:process_reply(SubEl) of
-+ ok ->
-+ {result, [], StateData};
-+ _ ->
-+ {error, ?ERR_NOT_ACCEPTABLE}
-+ end.
-+
- get_title(StateData) ->
- case (StateData#state.config)#config.title of
- "" ->
-diff -urN ejabberd-2.0.4/src/web/ejabberd_http.erl ejabberd-2.0.4-new/src/web/ejabberd_http.erl
---- ejabberd-2.0.4/src/web/ejabberd_http.erl 2009-03-12 09:41:02.000000000 +0100
-+++ ejabberd-2.0.4-new/src/web/ejabberd_http.erl 2009-03-14 10:57:34.000000000 +0100
-@@ -106,6 +106,10 @@
- {value, {request_handlers, H}} -> H;
- false -> []
- end ++
-+ case lists:member(captcha, Opts) of
-+ true -> [{["captcha"], ejabberd_captcha}];
-+ false -> []
-+ end ++
- case lists:member(web_admin, Opts) of
- true -> [{["admin"], ejabberd_web_admin}];
- false -> []
-Binary files ejabberd-2.0.4/tools/.DS_Store and ejabberd-2.0.4-new/tools/.DS_Store differ
-diff -urN ejabberd-2.0.4/tools/captcha.sh ejabberd-2.0.4-new/tools/captcha.sh
---- ejabberd-2.0.4/tools/captcha.sh 1970-01-01 01:00:00.000000000 +0100
-+++ ejabberd-2.0.4-new/tools/captcha.sh 2009-03-14 11:46:42.000000000 +0100
-@@ -0,0 +1,21 @@
-+#!/bin/sh
-+
-+SIGN=$(($RANDOM % 2))
-+
-+R1=$(($RANDOM % 20))
-+R2=$(($RANDOM % 10 + 40))
-+
-+if [ $SIGN -eq "0" ]; then
-+ S1=$(( -1*($RANDOM % 20 + 50) ))
-+ S2=$(( $RANDOM % 20 + 50 ))
-+else
-+ S2=$(( -1*($RANDOM % 20 + 50) ))
-+ S1=$(( $RANDOM % 20 + 50 ))
-+fi
-+
-+convert -size 140x60 xc:white \
-+ -pointsize 30 -draw "text 20,30 '$1'" \
-+ -roll -$R2+$R1 -swirl $S1 \
-+ -roll +$R2-$R1 -swirl $S2 \
-+ +repage -resize 120x60 \
-+ -quality 90 -depth 8 png:-
---- ejabberd-2.0.5/ChangeLog~ 2009-04-01 19:23:52.000000000 +0400
-+++ ejabberd-2.0.5/ChangeLog 2009-04-03 23:45:03.174979944 +0400
-@@ -15,6 +15,15 @@
- stanza (EJAB-300).
- * src/ejabberd_c2s.erl: Likewise
-
-+2009-03-13 Evgeniy Khramtsov <ekhramtsov@process-one.net>
-+
-+ * src/ejabberd_captcha.erl: XEP-158 (CAPTCHA Forms).
-+ * src/ejabberd_config.erl: likewise.
-+ * src/ejabberd_sup.erl: likewise.
-+ * src/jlib.hrl: likewise.
-+ * src/web/ejabberd_http.erl: likewise.
-+ * src/mod_muc/mod_muc_room.erl: CAPTCHA support.
-+
- 2009-03-10 Badlop <badlop@process-one.net>
-
- * doc/release_notes_2.0.4.txt: Added file for new release
diff --git a/ejabberd-decrease_buffers_in_mod_proxy65.patch b/ejabberd-decrease_buffers_in_mod_proxy65.patch
deleted file mode 100644
index 2bcb135..0000000
--- a/ejabberd-decrease_buffers_in_mod_proxy65.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-Patch by Evgeniy Khramtsov decreases proxy65 buffer sizes (size 65535 is known
-to confuse users with tight shapers).
-
-Index: src/mod_proxy65/mod_proxy65_stream.erl
-===================================================================
---- src/mod_proxy65/mod_proxy65_stream.erl 2009-04-01 17:23:51.000000000 +0200
-+++ src/mod_proxy65/mod_proxy65_stream.erl 2009-04-05 22:51:20.000000000 +0200
-@@ -89,8 +89,8 @@
- process_flag(trap_exit, true),
- AuthType = gen_mod:get_opt(auth_type, Opts, anonymous),
- Shaper = gen_mod:get_opt(shaper, Opts, none),
-- RecvBuf = gen_mod:get_opt(recbuf, Opts, 65535),
-- SendBuf = gen_mod:get_opt(sndbuf, Opts, 65535),
-+ RecvBuf = gen_mod:get_opt(recbuf, Opts, 8192),
-+ SendBuf = gen_mod:get_opt(sndbuf, Opts, 8192),
- TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop),
- inet:setopts(Socket, [{active, true}, {recbuf, RecvBuf}, {sndbuf, SendBuf}]),
- {ok, wait_for_init, #state{host = Host,
diff --git a/ejabberd-dynamic_compile_loglevel.patch b/ejabberd-dynamic_compile_loglevel.patch
deleted file mode 100644
index 62083a0..0000000
--- a/ejabberd-dynamic_compile_loglevel.patch
+++ /dev/null
@@ -1,768 +0,0 @@
---- /dev/null 1994-03-08 01:27:08.504001460 +0300
-+++ src/dynamic_compile.erl 2009-11-05 16:25:27.647417513 +0300
-@@ -0,0 +1,269 @@
-+%% Copyright (c) 2007
-+%% Mats Cronqvist <mats.cronqvist@ericsson.com>
-+%% Chris Newcombe <chris.newcombe@gmail.com>
-+%% Jacob Vorreuter <jacob.vorreuter@gmail.com>
-+%%
-+%% Permission is hereby granted, free of charge, to any person
-+%% obtaining a copy of this software and associated documentation
-+%% files (the "Software"), to deal in the Software without
-+%% restriction, including without limitation the rights to use,
-+%% copy, modify, merge, publish, distribute, sublicense, and/or sell
-+%% copies of the Software, and to permit persons to whom the
-+%% Software is furnished to do so, subject to the following
-+%% conditions:
-+%%
-+%% The above copyright notice and this permission notice shall be
-+%% included in all copies or substantial portions of the Software.
-+%%
-+%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-+%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-+%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-+%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-+%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-+%% OTHER DEALINGS IN THE SOFTWARE.
-+
-+%%%-------------------------------------------------------------------
-+%%% File : dynamic_compile.erl
-+%%% Description :
-+%%% Authors : Mats Cronqvist <mats.cronqvist@ericsson.com>
-+%%% Chris Newcombe <chris.newcombe@gmail.com>
-+%%% Jacob Vorreuter <jacob.vorreuter@gmail.com>
-+%%% TODO :
-+%%% - add support for limit include-file depth (and prevent circular references)
-+%%% prevent circular macro expansion set FILE correctly when -module() is found
-+%%% -include_lib support $ENVVAR in include filenames
-+%%% substitute-stringize (??MACRO)
-+%%% -undef/-ifdef/-ifndef/-else/-endif
-+%%% -file(File, Line)
-+%%%-------------------------------------------------------------------
-+-module(dynamic_compile).
-+
-+%% API
-+-export([from_string/1, from_string/2]).
-+
-+-import(lists, [reverse/1, keyreplace/4]).
-+
-+%%====================================================================
-+%% API
-+%%====================================================================
-+%%--------------------------------------------------------------------
-+%% Function:
-+%% Description:
-+%% Returns a binary that can be used with
-+%% code:load_binary(Module, ModuleFilenameForInternalRecords, Binary).
-+%%--------------------------------------------------------------------
-+from_string(CodeStr) ->
-+ from_string(CodeStr, []).
-+
-+% takes Options as for compile:forms/2
-+from_string(CodeStr, CompileFormsOptions) ->
-+ %% Initialise the macro dictionary with the default predefined macros,
-+ %% (adapted from epp.erl:predef_macros/1
-+ Filename = "compiled_from_string",
-+ %%Machine = list_to_atom(erlang:system_info(machine)),
-+ Ms0 = dict:new(),
-+ % Ms1 = dict:store('FILE', {[], "compiled_from_string"}, Ms0),
-+ % Ms2 = dict:store('LINE', {[], 1}, Ms1), % actually we might add special code for this
-+ % Ms3 = dict:store('MODULE', {[], undefined}, Ms2),
-+ % Ms4 = dict:store('MODULE_STRING', {[], undefined}, Ms3),
-+ % Ms5 = dict:store('MACHINE', {[], Machine}, Ms4),
-+ % InitMD = dict:store(Machine, {[], true}, Ms5),
-+ InitMD = Ms0,
-+
-+ %% From the docs for compile:forms:
-+ %% When encountering an -include or -include_dir directive, the compiler searches for header files in the following directories:
-+ %% 1. ".", the current working directory of the file server;
-+ %% 2. the base name of the compiled file;
-+ %% 3. the directories specified using the i option. The directory specified last is searched first.
-+ %% In this case, #2 is meaningless.
-+ IncludeSearchPath = ["." | reverse([Dir || {i, Dir} <- CompileFormsOptions])],
-+ {RevForms, _OutMacroDict} = scan_and_parse(CodeStr, Filename, 1, [], InitMD, IncludeSearchPath),
-+ Forms = reverse(RevForms),
-+
-+ %% note: 'binary' is forced as an implicit option, whether it is provided or not.
-+ case compile:forms(Forms, CompileFormsOptions) of
-+ {ok, ModuleName, CompiledCodeBinary} when is_binary(CompiledCodeBinary) ->
-+ {ModuleName, CompiledCodeBinary};
-+ {ok, ModuleName, CompiledCodeBinary, []} when is_binary(CompiledCodeBinary) -> % empty warnings list
-+ {ModuleName, CompiledCodeBinary};
-+ {ok, _ModuleName, _CompiledCodeBinary, Warnings} ->
-+ throw({?MODULE, warnings, Warnings});
-+ Other ->
-+ throw({?MODULE, compile_forms, Other})
-+ end.
-+
-+%%====================================================================
-+%% Internal functions
-+%%====================================================================
-+%%% Code from Mats Cronqvist
-+%%% See http://www.erlang.org/pipermail/erlang-questions/2007-March/025507.html
-+%%%## 'scan_and_parse'
-+%%%
-+%%% basically we call the OTP scanner and parser (erl_scan and
-+%%% erl_parse) line-by-line, but check each scanned line for (or
-+%%% definitions of) macros before parsing.
-+%% returns {ReverseForms, FinalMacroDict}
-+scan_and_parse([], _CurrFilename, _CurrLine, RevForms, MacroDict, _IncludeSearchPath) ->
-+ {RevForms, MacroDict};
-+
-+scan_and_parse(RemainingText, CurrFilename, CurrLine, RevForms, MacroDict, IncludeSearchPath) ->
-+ case scanner(RemainingText, CurrLine, MacroDict) of
-+ {tokens, NLine, NRemainingText, Toks} ->
-+ {ok, Form} = erl_parse:parse_form(Toks),
-+ scan_and_parse(NRemainingText, CurrFilename, NLine, [Form | RevForms], MacroDict, IncludeSearchPath);
-+ {macro, NLine, NRemainingText, NMacroDict} ->
-+ scan_and_parse(NRemainingText, CurrFilename, NLine, RevForms,NMacroDict, IncludeSearchPath);
-+ {include, NLine, NRemainingText, IncludeFilename} ->
-+ IncludeFileRemainingTextents = read_include_file(IncludeFilename, IncludeSearchPath),
-+ %%io:format("include file ~p contents: ~n~p~nRemainingText = ~p~n", [IncludeFilename,IncludeFileRemainingTextents, RemainingText]),
-+ %% Modify the FILE macro to reflect the filename
-+ %%IncludeMacroDict = dict:store('FILE', {[],IncludeFilename}, MacroDict),
-+ IncludeMacroDict = MacroDict,
-+
-+ %% Process the header file (inc. any nested header files)
-+ {RevIncludeForms, IncludedMacroDict} = scan_and_parse(IncludeFileRemainingTextents, IncludeFilename, 1, [], IncludeMacroDict, IncludeSearchPath),
-+ %io:format("include file results = ~p~n", [R]),
-+ %% Restore the FILE macro in the NEW MacroDict (so we keep any macros defined in the header file)
-+ %%NMacroDict = dict:store('FILE', {[],CurrFilename}, IncludedMacroDict),
-+ NMacroDict = IncludedMacroDict,
-+
-+ %% Continue with the original file
-+ scan_and_parse(NRemainingText, CurrFilename, NLine, RevIncludeForms ++ RevForms, NMacroDict, IncludeSearchPath);
-+ done ->
-+ scan_and_parse([], CurrFilename, CurrLine, RevForms, MacroDict, IncludeSearchPath)
-+ end.
-+
-+scanner(Text, Line, MacroDict) ->
-+ case erl_scan:tokens([],Text,Line) of
-+ {done, {ok,Toks,NLine}, LeftOverChars} ->
-+ case pre_proc(Toks, MacroDict) of
-+ {tokens, NToks} -> {tokens, NLine, LeftOverChars, NToks};
-+ {macro, NMacroDict} -> {macro, NLine, LeftOverChars, NMacroDict};
-+ {include, Filename} -> {include, NLine, LeftOverChars, Filename}
-+ end;
-+ {more, _Continuation} ->
-+ %% This is supposed to mean "term is not yet complete" (i.e. a '.' has
-+ %% not been reached yet).
-+ %% However, for some bizarre reason we also get this if there is a comment after the final '.' in a file.
-+ %% So we check to see if Text only consists of comments.
-+ case is_only_comments(Text) of
-+ true ->
-+ done;
-+ false ->
-+ throw({incomplete_term, Text, Line})
-+ end
-+ end.
-+
-+is_only_comments(Text) -> is_only_comments(Text, not_in_comment).
-+
-+is_only_comments([], _) -> true;
-+is_only_comments([$ |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment
-+is_only_comments([$\t |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment
-+is_only_comments([$\n |T], not_in_comment) -> is_only_comments(T, not_in_comment); % skipping whitspace outside of comment
-+is_only_comments([$% |T], not_in_comment) -> is_only_comments(T, in_comment); % found start of a comment
-+is_only_comments(_, not_in_comment) -> false;
-+% found any significant char NOT in a comment
-+is_only_comments([$\n |T], in_comment) -> is_only_comments(T, not_in_comment); % found end of a comment
-+is_only_comments([_ |T], in_comment) -> is_only_comments(T, in_comment). % skipping over in-comment chars
-+
-+%%%## 'pre-proc'
-+%%%
-+%%% have to implement a subset of the pre-processor, since epp insists
-+%%% on running on a file.
-+%%% only handles 2 cases;
-+%% -define(MACRO, something).
-+%% -define(MACRO(VAR1,VARN),{stuff,VAR1,more,stuff,VARN,extra,stuff}).
-+pre_proc([{'-',_},{atom,_,define},{'(',_},{_,_,Name}|DefToks],MacroDict) ->
-+ false = dict:is_key(Name, MacroDict),
-+ case DefToks of
-+ [{',',_} | Macro] ->
-+ {macro, dict:store(Name, {[], macro_body_def(Macro, [])}, MacroDict)};
-+ [{'(',_} | Macro] ->
-+ {macro, dict:store(Name, macro_params_body_def(Macro, []), MacroDict)}
-+ end;
-+
-+pre_proc([{'-',_}, {atom,_,include}, {'(',_}, {string,_,Filename}, {')',_}, {dot,_}], _MacroDict) ->
-+ {include, Filename};
-+
-+pre_proc(Toks,MacroDict) ->
-+ {tokens, subst_macros(Toks, MacroDict)}.
-+
-+macro_params_body_def([{')',_},{',',_} | Toks], RevParams) ->
-+ {reverse(RevParams), macro_body_def(Toks, [])};
-+macro_params_body_def([{var,_,Param} | Toks], RevParams) ->
-+ macro_params_body_def(Toks, [Param | RevParams]);
-+macro_params_body_def([{',',_}, {var,_,Param} | Toks], RevParams) ->
-+ macro_params_body_def(Toks, [Param | RevParams]).
-+
-+macro_body_def([{')',_}, {dot,_}], RevMacroBodyToks) ->
-+ reverse(RevMacroBodyToks);
-+macro_body_def([Tok|Toks], RevMacroBodyToks) ->
-+ macro_body_def(Toks, [Tok | RevMacroBodyToks]).
-+
-+subst_macros(Toks, MacroDict) ->
-+ reverse(subst_macros_rev(Toks, MacroDict, [])).
-+
-+%% returns a reversed list of tokes
-+subst_macros_rev([{'?',_}, {_,LineNum,'LINE'} | Toks], MacroDict, RevOutToks) ->
-+ %% special-case for ?LINE, to avoid creating a new MacroDict for every line in the source file
-+ subst_macros_rev(Toks, MacroDict, [{integer,LineNum,LineNum}] ++ RevOutToks);
-+
-+subst_macros_rev([{'?',_}, {_,_,Name}, {'(',_} = Paren | Toks], MacroDict, RevOutToks) ->
-+ case dict:fetch(Name, MacroDict) of
-+ {[], MacroValue} ->
-+ %% This macro does not have any vars, so ignore the fact that the invocation is followed by "(...stuff"
-+ %% Recursively expand any macro calls inside this macro's value
-+ %% TODO: avoid infinite expansion due to circular references (even indirect ones)
-+ RevExpandedOtherMacrosToks = subst_macros_rev(MacroValue, MacroDict, []),
-+ subst_macros_rev([Paren|Toks], MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks);
-+ ParamsAndBody ->
-+ %% This macro does have vars.
-+ %% Collect all of the passe arguments, in an ordered list
-+ {NToks, Arguments} = subst_macros_get_args(Toks, []),
-+ %% Expand the varibles
-+ ExpandedParamsToks = subst_macros_subst_args_for_vars(ParamsAndBody, Arguments),
-+ %% Recursively expand any macro calls inside this macro's value
-+ %% TODO: avoid infinite expansion due to circular references (even indirect ones)
-+ RevExpandedOtherMacrosToks = subst_macros_rev(ExpandedParamsToks, MacroDict, []),
-+ subst_macros_rev(NToks, MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks)
-+ end;
-+
-+subst_macros_rev([{'?',_}, {_,_,Name} | Toks], MacroDict, RevOutToks) ->
-+ %% This macro invocation does not have arguments.
-+ %% Therefore the definition should not have parameters
-+ {[], MacroValue} = dict:fetch(Name, MacroDict),
-+
-+ %% Recursively expand any macro calls inside this macro's value
-+ %% TODO: avoid infinite expansion due to circular references (even indirect ones)
-+ RevExpandedOtherMacrosToks = subst_macros_rev(MacroValue, MacroDict, []),
-+ subst_macros_rev(Toks, MacroDict, RevExpandedOtherMacrosToks ++ RevOutToks);
-+
-+subst_macros_rev([Tok|Toks], MacroDict, RevOutToks) ->
-+subst_macros_rev(Toks, MacroDict, [Tok|RevOutToks]);
-+subst_macros_rev([], _MacroDict, RevOutToks) -> RevOutToks.
-+
-+subst_macros_get_args([{')',_} | Toks], RevArgs) ->
-+ {Toks, reverse(RevArgs)};
-+subst_macros_get_args([{',',_}, {var,_,ArgName} | Toks], RevArgs) ->
-+ subst_macros_get_args(Toks, [ArgName| RevArgs]);
-+subst_macros_get_args([{var,_,ArgName} | Toks], RevArgs) ->
-+ subst_macros_get_args(Toks, [ArgName | RevArgs]).
-+
-+subst_macros_subst_args_for_vars({[], BodyToks}, []) ->
-+ BodyToks;
-+subst_macros_subst_args_for_vars({[Param | Params], BodyToks}, [Arg|Args]) ->
-+ NBodyToks = keyreplace(Param, 3, BodyToks, {var,1,Arg}),
-+ subst_macros_subst_args_for_vars({Params, NBodyToks}, Args).
-+
-+read_include_file(Filename, IncludeSearchPath) ->
-+ case file:path_open(IncludeSearchPath, Filename, [read, raw, binary]) of
-+ {ok, IoDevice, FullName} ->
-+ {ok, Data} = file:read(IoDevice, filelib:file_size(FullName)),
-+ file:close(IoDevice),
-+ binary_to_list(Data);
-+ {error, Reason} ->
-+ throw({failed_to_read_include_file, Reason, Filename, IncludeSearchPath})
-+ end.
-+
---- src/ejabberd.app 2009-04-01 19:23:51.000000000 +0400
-+++ src/ejabberd.app 2009-11-05 16:27:10.081417222 +0300
-@@ -115,7 +115,6 @@
- nodetree_virtual,
- p1_fsm,
- p1_mnesia,
-- ram_file_io_server,
- randoms,
- sha,
- shaper,
---- src/ejabberd_loglevel.erl 2009-04-01 19:23:52.000000000 +0400
-+++ src/ejabberd_loglevel.erl 2009-11-05 16:27:47.816415376 +0300
-@@ -38,51 +38,30 @@
- -define(LOGMODULE, "error_logger").
-
- %% Error levels:
--%% 0 -> No log
--%% 1 -> Critical
--%% 2 -> Error
--%% 3 -> Warning
--%% 4 -> Info
--%% 5 -> Debug
-+-define(LOG_LEVELS,[ {0, no_log, "No log"}
-+ ,{1, critical, "Critical"}
-+ ,{2, error, "Error"}
-+ ,{3, warning, "Warning"}
-+ ,{4, info, "Info"}
-+ ,{5, debug, "Debug"}
-+ ]).
-+
-+set(LogLevel) when is_atom(LogLevel) ->
-+ set(level_to_integer(LogLevel));
- set(Loglevel) when is_integer(Loglevel) ->
-- Forms = compile_string(?LOGMODULE, ejabberd_logger_src(Loglevel)),
-- load_logger(Forms, ?LOGMODULE, Loglevel);
-+ try
-+ {Mod,Code} = dynamic_compile:from_string(ejabberd_logger_src(Loglevel)),
-+ code:load_binary(Mod, ?LOGMODULE ++ ".erl", Code)
-+ catch
-+ Type:Error -> ?CRITICAL_MSG("Error compiling logger (~p): ~p~n", [Type, Error])
-+ end;
- set(_) ->
- exit("Loglevel must be an integer").
--
--%% --------------------------------------------------------------
--%% Compile a string into a module and returns the binary
--compile_string(Mod, Str) ->
-- Fname = Mod ++ ".erl",
-- {ok, Fd} = open_ram_file(Fname),
-- file:write(Fd, Str),
-- file:position(Fd, 0),
-- case epp_dodger:parse(Fd) of
-- {ok, Tree} ->
-- Forms = revert_tree(Tree),
-- close_ram_file(Fd),
-- Forms;
-- Error ->
-- close_ram_file(Fd),
-- Error
-- end.
--
--open_ram_file(Fname) ->
-- ram_file_io_server:start(self(), Fname, [read,write]).
--
--close_ram_file(Fd) ->
-- file:close(Fd).
--
--revert_tree(Tree) ->
-- [erl_syntax:revert(T) || T <- Tree].
--
--load_logger(Forms, Mod, Loglevel) ->
-- Fname = Mod ++ ".erl",
-- case compile:forms(Forms, [binary, {d,'LOGLEVEL',Loglevel}]) of
-- {ok, M, Bin} ->
-- code:load_binary(M, Fname, Bin);
-- Error ->
-- ?CRITICAL_MSG("Error ~p~n", [Error])
-+
-+level_to_integer(Level) ->
-+ case lists:keyfind(Level, 2, ?LOG_LEVELS) of
-+ {Int, Level, _Desc} -> Int;
-+ _ -> erlang:error({no_such_loglevel, Level})
- end.
-
- %% --------------------------------------------------------------
---- src/ram_file_io_server.erl 2009-04-01 19:23:51.000000000 +0400
-+++ /dev/null 1994-03-08 01:27:08.504001460 +0300
-@@ -1,408 +0,0 @@
--%% ``The contents of this file are subject to the Erlang Public License,
--%% Version 1.1, (the "License"); you may not use this file except in
--%% compliance with the License. You should have received a copy of the
--%% Erlang Public License along with this software. If not, it can be
--%% retrieved via the world wide web at http://www.erlang.org/.
--%%
--%% Software distributed under the License is distributed on an "AS IS"
--%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
--%% the License for the specific language governing rights and limitations
--%% under the License.
--%%
--%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
--%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
--%% AB. All Rights Reserved.''
--%%
--%% $Id: ram_file_io_server.erl 970 2007-11-15 10:33:18Z mremond $
--%%
--%% This file is mostly copied from Erlang file_io_server.erl
--%% See: http://www.erlang.org/ml-archive/erlang-questions/200607/msg00080.html
--%% for details on ram_file_io_server.erl (Erlang OTP R11B-2)
---module(ram_file_io_server).
--
--%% A simple file server for io to one file instance per server instance.
--
---export([format_error/1]).
---export([start/3, start_link/3]).
--
---record(state, {handle,owner,mref,buf,read_mode}).
--
---define(PRIM_FILE, ram_file).
---define(READ_SIZE_LIST, 128).
---define(READ_SIZE_BINARY, (8*1024)).
--
---define(eat_message(M, T), receive M -> M after T -> timeout end).
--
--%%%-----------------------------------------------------------------
--%%% Exported functions
--
--format_error({_Line, ?MODULE, Reason}) ->
-- io_lib:format("~w", [Reason]);
--format_error({_Line, Mod, Reason}) ->
-- Mod:format_error(Reason);
--format_error(ErrorId) ->
-- erl_posix_msg:message(ErrorId).
--
--start(Owner, FileName, ModeList)
-- when pid(Owner), list(FileName), list(ModeList) ->
-- do_start(spawn, Owner, FileName, ModeList).
--
--start_link(Owner, FileName, ModeList)
-- when pid(Owner), list(FileName), list(ModeList) ->
-- do_start(spawn_link, Owner, FileName, ModeList).
--
--%%%-----------------------------------------------------------------
--%%% Server starter, dispatcher and helpers
--
--do_start(Spawn, Owner, FileName, ModeList) ->
-- Self = self(),
-- Ref = make_ref(),
-- Pid =
-- erlang:Spawn(
-- fun() ->
-- %% process_flag(trap_exit, true),
-- {ReadMode,Opts} =
-- case lists:member(binary, ModeList) of
-- true ->
-- {binary,ModeList};
-- false ->
-- {list,[binary|ModeList]}
-- end,
-- case ?PRIM_FILE:open(FileName, Opts) of
-- {error, Reason} = Error ->
-- Self ! {Ref, Error},
-- exit(Reason);
-- {ok, Handle} ->
-- %% XXX must I handle R6 nodes here?
-- M = erlang:monitor(process, Owner),
-- Self ! {Ref, ok},
-- server_loop(
-- #state{handle = Handle,
-- owner = Owner,
-- mref = M,
-- buf = <<>>,
-- read_mode = ReadMode})
-- end
-- end),
-- Mref = erlang:monitor(process, Pid),
-- receive
-- {Ref, {error, _Reason} = Error} ->
-- erlang:demonitor(Mref),
-- receive {'DOWN', Mref, _, _, _} -> ok after 0 -> ok end,
-- Error;
-- {Ref, ok} ->
-- erlang:demonitor(Mref),
-- receive
-- {'DOWN', Mref, _, _, Reason} ->
-- {error, Reason}
-- after 0 ->
-- {ok, Pid}
-- end;
-- {'DOWN', Mref, _, _, Reason} ->
-- {error, Reason}
-- end.
--
--server_loop(#state{mref = Mref} = State) ->
-- receive
-- {file_request, From, ReplyAs, Request} when pid(From) ->
-- case file_request(Request, State) of
-- {reply, Reply, NewState} ->
-- file_reply(From, ReplyAs, Reply),
-- server_loop(NewState);
-- {error, Reply, NewState} ->
-- %% error is the same as reply, except that
-- %% it breaks the io_request_loop further down
-- file_reply(From, ReplyAs, Reply),
-- server_loop(NewState);
-- {stop, Reason, Reply, _NewState} ->
-- file_reply(From, ReplyAs, Reply),
-- exit(Reason)
-- end;
-- {io_request, From, ReplyAs, Request} when pid(From) ->
-- case io_request(Request, State) of
-- {reply, Reply, NewState} ->
-- io_reply(From, ReplyAs, Reply),
-- server_loop(NewState);
-- {error, Reply, NewState} ->
-- %% error is the same as reply, except that
-- %% it breaks the io_request_loop further down
-- io_reply(From, ReplyAs, Reply),
-- server_loop(NewState);
-- {stop, Reason, Reply, _NewState} ->
-- io_reply(From, ReplyAs, Reply),
-- exit(Reason)
-- end;
-- {'DOWN', Mref, _, _, Reason} ->
-- exit(Reason);
-- _ ->
-- server_loop(State)
-- end.
--
--file_reply(From, ReplyAs, Reply) ->
-- From ! {file_reply, ReplyAs, Reply}.
--
--io_reply(From, ReplyAs, Reply) ->
-- From ! {io_reply, ReplyAs, Reply}.
--
--%%%-----------------------------------------------------------------
--%%% file requests
--
--file_request({pread,At,Sz},
-- #state{handle=Handle,buf=Buf,read_mode=ReadMode}=State) ->
-- case position(Handle, At, Buf) of
-- {ok,_Offs} ->
-- case ?PRIM_FILE:read(Handle, Sz) of
-- {ok,Bin} when ReadMode==list ->
-- std_reply({ok,binary_to_list(Bin)}, State);
-- Reply ->
-- std_reply(Reply, State)
-- end;
-- Reply ->
-- std_reply(Reply, State)
-- end;
--file_request({pwrite,At,Data},
-- #state{handle=Handle,buf=Buf}=State) ->
-- case position(Handle, At, Buf) of
-- {ok,_Offs} ->
-- std_reply(?PRIM_FILE:write(Handle, Data), State);
-- Reply ->
-- std_reply(Reply, State)
-- end;
--file_request(sync,
-- #state{handle=Handle}=State) ->
-- case ?PRIM_FILE:sync(Handle) of
-- {error,_}=Reply ->
-- {stop,normal,Reply,State};
-- Reply ->
-- {reply,Reply,State}
-- end;
--file_request(close,
-- #state{handle=Handle}=State) ->
-- {stop,normal,?PRIM_FILE:close(Handle),State#state{buf= <<>>}};
--file_request({position,At},
-- #state{handle=Handle,buf=Buf}=State) ->
-- std_reply(position(Handle, At, Buf), State);
--file_request(truncate,
-- #state{handle=Handle}=State) ->
-- case ?PRIM_FILE:truncate(Handle) of
-- {error,_Reason}=Reply ->
-- {stop,normal,Reply,State#state{buf= <<>>}};
-- Reply ->
-- {reply,Reply,State}
-- end;
--file_request(Unknown,
-- #state{}=State) ->
-- Reason = {request, Unknown},
-- {error,{error,Reason},State}.
--
--std_reply({error,_}=Reply, State) ->
-- {error,Reply,State#state{buf= <<>>}};
--std_reply(Reply, State) ->
-- {reply,Reply,State#state{buf= <<>>}}.
--
--%%%-----------------------------------------------------------------
--%%% I/O request
--
--io_request({put_chars,Chars}, % binary(Chars) new in R9C
-- #state{buf= <<>>}=State) ->
-- put_chars(Chars, State);
--io_request({put_chars,Chars}, % binary(Chars) new in R9C
-- #state{handle=Handle,buf=Buf}=State) ->
-- case position(Handle, cur, Buf) of
-- {error,_}=Reply ->
-- {stop,normal,Reply,State#state{buf= <<>>}};
-- _ ->
-- put_chars(Chars, State#state{buf= <<>>})
-- end;
--io_request({put_chars,Mod,Func,Args},
-- #state{}=State) ->
-- case catch apply(Mod, Func, Args) of
-- Chars when list(Chars); binary(Chars) ->
-- io_request({put_chars,Chars}, State);
-- _ ->
-- {error,{error,Func},State}
-- end;
--io_request({get_until,_Prompt,Mod,Func,XtraArgs},
-- #state{}=State) ->
-- get_chars(io_lib, get_until, {Mod, Func, XtraArgs}, State);
--io_request({get_chars,_Prompt,N}, % New in R9C
-- #state{}=State) ->
-- get_chars(N, State);
--io_request({get_chars,_Prompt,Mod,Func,XtraArg}, % New in R9C
-- #state{}=State) ->
-- get_chars(Mod, Func, XtraArg, State);
--io_request({get_line,_Prompt}, % New in R9C
-- #state{}=State) ->
-- get_chars(io_lib, collect_line, [], State);
--io_request({setopts, Opts}, % New in R9C
-- #state{}=State) when list(Opts) ->
-- setopts(Opts, State);
--io_request({requests,Requests},
-- #state{}=State) when list(Requests) ->
-- io_request_loop(Requests, {reply,ok,State});
--io_request(Unknown,
-- #state{}=State) ->
-- Reason = {request,Unknown},
-- {error,{error,Reason},State}.
--
--
--
--%% Process a list of requests as long as the results are ok.
--
--io_request_loop([], Result) ->
-- Result;
--io_request_loop([_Request|_Tail],
-- {stop,_Reason,_Reply,_State}=Result) ->
-- Result;
--io_request_loop([_Request|_Tail],
-- {error,_Reply,_State}=Result) ->
-- Result;
--io_request_loop([Request|Tail],
-- {reply,_Reply,State}) ->
-- io_request_loop(Tail, io_request(Request, State)).
--
--
--
--%% I/O request put_chars
--%%
--put_chars(Chars, #state{handle=Handle}=State) ->
-- case ?PRIM_FILE:write(Handle, Chars) of
-- {error,_}=Reply ->
-- {stop,normal,Reply,State};
-- Reply ->
-- {reply,Reply,State}
-- end.
--
--
--%% Process the I/O request get_chars
--%%
--get_chars(0, #state{read_mode=ReadMode}=State) ->
-- {reply,cast(<<>>, ReadMode),State};
--get_chars(N, #state{buf=Buf,read_mode=ReadMode}=State)
-- when integer(N), N > 0, N =< size(Buf) ->
-- {B1,B2} = split_binary(Buf, N),
-- {reply,cast(B1, ReadMode),State#state{buf=B2}};
--get_chars(N, #state{handle=Handle,buf=Buf,read_mode=ReadMode}=State)
-- when integer(N), N > 0 ->
-- BufSize = size(Buf),
-- NeedSize = N-BufSize,
-- Size = max(NeedSize, ?READ_SIZE_BINARY),
-- case ?PRIM_FILE:read(Handle, Size) of
-- {ok, B} ->
-- if BufSize+size(B) < N ->
-- std_reply(cat(Buf, B, ReadMode), State);
-- true ->
-- {B1,B2} = split_binary(B, NeedSize),
-- {reply,cat(Buf, B1, ReadMode),State#state{buf=B2}}
-- end;
-- eof when BufSize==0 ->
-- {reply,eof,State};
-- eof ->
-- std_reply(cast(Buf, ReadMode), State);
-- {error,Reason}=Error ->
-- {stop,Reason,Error,State#state{buf= <<>>}}
-- end;
--get_chars(_N, #state{}=State) ->
-- {error,{error,get_chars},State}.
--
--get_chars(Mod, Func, XtraArg, #state{buf= <<>>}=State) ->
-- get_chars_empty(Mod, Func, XtraArg, start, State);
--get_chars(Mod, Func, XtraArg, #state{buf=Buf}=State) ->
-- get_chars_apply(Mod, Func, XtraArg, start, State#state{buf= <<>>}, Buf).
--
--get_chars_empty(Mod, Func, XtraArg, S,
-- #state{handle=Handle,read_mode=ReadMode}=State) ->
-- case ?PRIM_FILE:read(Handle, read_size(ReadMode)) of
-- {ok,Bin} ->
-- get_chars_apply(Mod, Func, XtraArg, S, State, Bin);
-- eof ->
-- get_chars_apply(Mod, Func, XtraArg, S, State, eof);
-- {error,Reason}=Error ->
-- {stop,Reason,Error,State}
-- end.
--
--get_chars_apply(Mod, Func, XtraArg, S0,
-- #state{read_mode=ReadMode}=State, Data0) ->
-- Data1 = case ReadMode of
-- list when binary(Data0) -> binary_to_list(Data0);
-- _ -> Data0
-- end,
-- case catch Mod:Func(S0, Data1, XtraArg) of
-- {stop,Result,Buf} ->
-- {reply,Result,State#state{buf=cast_binary(Buf)}};
-- {'EXIT',Reason} ->
-- {stop,Reason,{error,err_func(Mod, Func, XtraArg)},State};
-- S1 ->
-- get_chars_empty(Mod, Func, XtraArg, S1, State)
-- end.
--
--%% Convert error code to make it look as before
--err_func(io_lib, get_until, {_,F,_}) ->
-- F;
--err_func(_, F, _) ->
-- F.
--
--
--
--%% Process the I/O request setopts
--%%
--%% setopts
--setopts(Opts0, State) ->
-- Opts = proplists:substitute_negations([{list,binary}], Opts0),
-- case proplists:get_value(binary, Opts) of
-- true ->
-- {ok,ok,State#state{read_mode=binary}};
-- false ->
-- {ok,ok,State#state{read_mode=list}};
-- _ ->
-- {error,{error,badarg},State}
-- end.
--
--
--
--%% Concatenate two binaries and convert the result to list or binary
--cat(B1, B2, binary) ->
-- list_to_binary([B1,B2]);
--cat(B1, B2, list) ->
-- binary_to_list(B1)++binary_to_list(B2).
--
--%% Cast binary to list or binary
--cast(B, binary) ->
-- B;
--cast(B, list) ->
-- binary_to_list(B).
--
--%% Convert buffer to binary
--cast_binary(Binary) when binary(Binary) ->
-- Binary;
--cast_binary(List) when list(List) ->
-- list_to_binary(List);
--cast_binary(_EOF) ->
-- <<>>.
--
--%% Read size for different read modes
--read_size(binary) ->
-- ?READ_SIZE_BINARY;
--read_size(list) ->
-- ?READ_SIZE_LIST.
--
--max(A, B) when A >= B ->
-- A;
--max(_, B) ->
-- B.
--
--%%%-----------------------------------------------------------------
--%%% ?PRIM_FILE helpers
--
--%% Compensates ?PRIM_FILE:position/2 for the number of bytes
--%% we have buffered
--
--position(Handle, cur, Buf) ->
-- position(Handle, {cur, 0}, Buf);
--position(Handle, {cur, Offs}, Buf) when list(Buf) ->
-- ?PRIM_FILE:position(Handle, {cur, Offs-length(Buf)});
--position(Handle, {cur, Offs}, Buf) when binary(Buf) ->
-- ?PRIM_FILE:position(Handle, {cur, Offs-size(Buf)});
--position(Handle, At, _Buf) ->
-- ?PRIM_FILE:position(Handle, At).
--
diff --git a/ejabberd-ejabberd_cfg_pam_name.diff b/ejabberd-ejabberd_cfg_pam_name.diff
index 7c0d519..3b9ed7d 100644
--- a/ejabberd-ejabberd_cfg_pam_name.diff
+++ b/ejabberd-ejabberd_cfg_pam_name.diff
@@ -1,6 +1,6 @@
---- src/ejabberd.cfg.example~ 2008-08-01 16:34:28.000000000 +0400
-+++ src/ejabberd.cfg.example 2008-08-09 21:09:07.000000000 +0400
-@@ -214,7 +214,7 @@
+--- src/ejabberd.cfg.example 2009-11-20 15:07:57.317704955 +0300
++++ src/ejabberd.cfg.example 2009-11-20 15:08:11.522704968 +0300
+@@ -235,7 +235,7 @@
%% Authentication using PAM
%%
%%{auth_method, pam}.
diff --git a/ejabberd-ejabberdctl_fix.diff b/ejabberd-ejabberdctl_fix.diff
index 8c8a27b..3bf5419 100644
--- a/ejabberd-ejabberdctl_fix.diff
+++ b/ejabberd-ejabberdctl_fix.diff
@@ -1,6 +1,6 @@
---- src/ejabberdctl.template 2009-04-01 19:23:51.000000000 +0400
-+++ src/ejabberdctl.template 2009-08-25 23:06:19.258685929 +0400
-@@ -9,13 +9,14 @@
+--- src/ejabberdctl.template.fix_ctl 2009-11-06 22:53:19.000000000 +0300
++++ src/ejabberdctl.template 2009-11-21 10:43:17.654686409 +0300
+@@ -9,10 +9,10 @@
# define default environment variables
NODE=ejabberd
@@ -8,75 +8,25 @@
+HOST=`hostname -s 2>/dev/null || echo "localhost"`
ERLANG_NODE=$NODE@$HOST
ERL=@erl@
--ROOTDIR=@rootdir@
-+ROOTDIR=
-+MAINDIR=
- EJABBERD_CONFIG_PATH=$ROOTDIR/etc/ejabberd/ejabberd.cfg
- LOGS_DIR=$ROOTDIR/var/log/ejabberd/
--EJABBERD_DB=$ROOTDIR/var/lib/ejabberd/db/$NODE
-+EJABBERD_DB=$ROOTDIR/var/lib/ejabberd/spool
+-INSTALLUSER=@installuser@
++INSTALLUSER=ejabberd
- # read custom configuration
- CONFIG=$ROOTDIR/etc/ejabberd/ejabberdctl.cfg
-@@ -43,10 +44,10 @@
- ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES"
+ # parse command line parameters
+ ARGS=
+@@ -60,14 +60,14 @@
+ EJID=`id -g $INSTALLUSER`
+ EXEC_CMD="false"
+ if [ $ID -eq 0 ] ; then
+- EXEC_CMD="su ${INSTALLUSER} -c"
++ EXEC_CMD="/sbin/runuser -s /bin/bash -p ejabberd -c"
+ fi
+ if [ "$ID" -eq "$EJID" ] ; then
+ EXEC_CMD="sh -c"
+ fi
+ if [ "$EXEC_CMD" = "false" ] ; then
+ echo "This command can only be run by root or the user $INSTALLUSER" >&2
+- exit 1
++ exit 4
+ fi
- # define additional environment variables
--EJABBERD_EBIN=$ROOTDIR/var/lib/ejabberd/ebin
--EJABBERD_MSGS_PATH=$ROOTDIR/var/lib/ejabberd/priv/msgs
--EJABBERD_SO_PATH=$ROOTDIR/var/lib/ejabberd/priv/lib
--EJABBERD_BIN_PATH=$ROOTDIR/var/lib/ejabberd/priv/bin
-+EJABBERD_EBIN=$MAINDIR/ebin
-+EJABBERD_MSGS_PATH=$MAINDIR/priv/msgs
-+EJABBERD_SO_PATH=$MAINDIR/priv/lib
-+EJABBERD_BIN_PATH=$MAINDIR/priv/bin
- EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
- SASL_LOG_PATH=$LOGS_DIR/sasl.log
- DATETIME=`date "+%Y%m%d-%H%M%S"`
-@@ -75,14 +76,16 @@
- # start server
- start ()
- {
-- $ERL \
-+ ERL_COMMAND="$ERL \
- $NAME $ERLANG_NODE \
- -noinput -detached \
- -pa $EJABBERD_EBIN \
-- -mnesia dir "\"$EJABBERD_DB\"" \
-+ -mnesia dir \\\"$EJABBERD_DB\\\" \
- -s ejabberd \
-- -sasl sasl_error_logger \{file,\"$SASL_LOG_PATH\"\} \
-- $ERLANG_OPTS $ARGS "$@"
-+ -sasl sasl_error_logger \{file,\\\"$SASL_LOG_PATH\\\"\} \
-+ $ERLANG_OPTS $ARGS "$@" \
-+ "
-+ /sbin/runuser -s /bin/bash -p ejabberd -c "$ERL_COMMAND"
- }
-
- # attach to server
-@@ -105,7 +108,7 @@
- read foo
- echo ""
- $ERL \
-- $NAME ${NODE}debug \
-+ $NAME debug-${ERLANG_NODE} \
- -remsh $ERLANG_NODE \
- $ERLANG_OPTS $ARGS "$@"
- }
-@@ -139,11 +142,13 @@
- # common control function
- ctl ()
- {
-- $ERL \
-- $NAME ejabberdctl \
-+ ERL_COMMAND="$ERL \
-+ $NAME ctl-${ERLANG_NODE} \
- -noinput \
- -pa $EJABBERD_EBIN \
-- -s ejabberd_ctl -extra $ERLANG_NODE $@
-+ -s ejabberd_ctl -extra $ERLANG_NODE $@ \
-+ "
-+ /sbin/runuser -s /bin/bash -p ejabberd -c "$ERL_COMMAND"
- result=$?
- case $result in
- 0) :;;
+ NAME=-name
diff --git a/ejabberd-fixed_delays_in_s2s.patch b/ejabberd-fixed_delays_in_s2s.patch
index 0090ea7..c520d6f 100644
--- a/ejabberd-fixed_delays_in_s2s.patch
+++ b/ejabberd-fixed_delays_in_s2s.patch
@@ -18,18 +18,18 @@ Index: src/ejabberd_s2s_in.erl
Key, StateData#state.streamid}),
Index: src/ejabberd_s2s_out.erl
===================================================================
---- src/ejabberd_s2s_out.erl 2009-04-01 17:23:51.000000000 +0200
-+++ src/ejabberd_s2s_out.erl 2009-04-05 22:51:20.000000000 +0200
-@@ -93,7 +93,7 @@
- %% Only change this value if you now what your are doing:
- -define(FSMLIMITS,[]).
- %% -define(FSMLIMITS, [{max_queue, 2000}]).
+--- src/ejabberd_s2s_out.erl 2009-11-06 22:53:19.000000000 +0300
++++ src/ejabberd_s2s_out.erl 2009-11-20 15:59:53.445703654 +0300
+@@ -90,7 +90,7 @@
+ [From, Host, Type])).
+ -endif.
+
--define(FSMTIMEOUT, 30000).
+-define(FSMTIMEOUT, 60000).
%% We do not block on send anymore.
-define(TCP_SEND_TIMEOUT, 15000).
-@@ -227,8 +227,8 @@
+@@ -226,8 +226,8 @@
{error, _Reason} ->
?INFO_MSG("s2s connection: ~s -> ~s (remote server not found)",
[StateData#state.myname, StateData#state.server]),
diff --git a/ejabberd-turn_off_error_messages_in_mod_caps.patch b/ejabberd-turn_off_error_messages_in_mod_caps.patch
deleted file mode 100644
index dd722ad..0000000
--- a/ejabberd-turn_off_error_messages_in_mod_caps.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-Patch by Sergei Golovan turns unnecessary error messages into debug messages.
-
-Index: src/mod_caps.erl
-===================================================================
---- src/mod_caps.erl 2009-04-01 17:23:51.000000000 +0200
-+++ src/mod_caps.erl 2009-04-05 22:51:20.000000000 +0200
-@@ -301,7 +301,7 @@
- end),
- gen_server:cast(self(), visit_feature_queries);
- error ->
-- ?ERROR_MSG("ID '~s' matches no query", [ID])
-+ ?DEBUG("ID '~s' matches no query", [ID])
- end;
- {error, _} ->
- %% XXX: if we get error, we cache empty feature not to probe the client continuously
-@@ -315,7 +315,7 @@
- end),
- gen_server:cast(self(), visit_feature_queries);
- error ->
-- ?ERROR_MSG("ID '~s' matches no query", [ID])
-+ ?DEBUG("ID '~s' matches no query", [ID])
- end;
- %gen_server:cast(self(), visit_feature_queries),
- %?DEBUG("Error IQ reponse from ~s:~n~p", [jlib:jid_to_string(From), SubEls]);
diff --git a/ejabberd.init b/ejabberd.init
index 8115600..9670916 100644
--- a/ejabberd.init
+++ b/ejabberd.init
@@ -11,6 +11,8 @@
# Provides: ejabberd
# Required-Start: network
# Required-Stop: network
+# Default-Start:
+# Default-Stop: 0 1 6
# Short-Description: Start and stop ejabberd
# Description: A distributed, fault-tolerant Jabber/XMPP server
### END INIT INFO
diff --git a/ejabberd.spec b/ejabberd.spec
index 0191087..9086ec0 100644
--- a/ejabberd.spec
+++ b/ejabberd.spec
@@ -1,6 +1,18 @@
+%bcond_without fedora
+%global uid 27
+
+# Currently, hevea available only in Fedora
+%if %{defined fedora}
+# No hevea on Fedora for ppc64
+# see https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=250253
+%ifnarch ppc64
+%define with_hevea 1
+%endif
+%endif
+
Name: ejabberd
-Version: 2.0.5
-Release: 10%{?dist}
+Version: 2.1.0
+Release: 1%{?dist}
Summary: A distributed, fault-tolerant Jabber/XMPP server
Group: Applications/Internet
@@ -12,10 +24,12 @@ Source2: ejabberd.logrotate
Source3: ejabberd.sysconfig
# http://www.ejabberd.im/mod_ctlextra
+# this module will be removed in the near future in favor of mod_admin_extra
# svn export -r 1020 https://svn.process-one.net/ejabberd-modules/mod_ctlextra/trunk/src/mod_ctlextra.erl
Source4: mod_ctlextra.erl
# The following were extracted from a patch found on http://realloc.spb.ru/share/ejabberdad.html
+# These are unmaintained and will be removed soon (users should use *_ldap.erl instead)
Source5: ejabberd_auth_ad.erl
Source6: mod_shared_roster_ad.erl
Source7: mod_vcard_ad.erl
@@ -25,27 +39,14 @@ Source9: ejabberdctl.pam
Source10: ejabberdctl.apps
Source11: ejabberd.pam
-# Fedora-specific stuff - fixing paths
-Patch1: ejabberd-build.patch
# BZ# 439583, 452326, 451554, 465196, 502361
Patch2: ejabberd-ejabberdctl_fix.diff
# Use ejabberd as an example for PAM service name
Patch3: ejabberd-ejabberd_cfg_pam_name.diff
-# CAPTCHA support, see https://support.process-one.net/doc/display/XAAI/Fighting+Multi-User+Chat+SPAM+with+CAPTCHA
-# wget https://support.process-one.net/secure/attachment/13851/XEP-0158_ejabberd-2.0.4.patch -O ejabberd-captcha.patch
-Patch4: ejabberd-captcha.patch
# Mention mod_ctlextra as an ejabberd module
Patch5: ejabberd-mod_ctlextra_mentioning_in_ejabberd_app.diff
-# Turn off unnecessary error messages in mod_caps (backport from upstream)
-Patch6: ejabberd-turn_off_error_messages_in_mod_caps.patch
-# Decrease mod_proxy65 send/receive buffers (backport from upstream)
-Patch7: ejabberd-decrease_buffers_in_mod_proxy65.patch
# fixed delays in s2s connections
Patch8: ejabberd-fixed_delays_in_s2s.patch
-# Common dynamic compilation facility for Erlang R11/R12/R13 instead of old one
-# See https://support.process-one.net/browse/EJAB-919
-# Fixes BZ# 533021
-Patch9: ejabberd-dynamic_compile_loglevel.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -55,22 +56,25 @@ BuildRequires: openssl-devel
BuildRequires: pam-devel
BuildRequires: erlang
BuildRequires: dos2unix
-%if %{undefined rhel}
+BuildRequires: fedora-usermgmt-devel
+
+%if 0%{?with_hevea}
BuildRequires: hevea
%endif
-Requires: erlang
-Requires: usermode
-
-Requires(pre): fedora-usermgmt
+%{?FE_USERADD_REQ}
Requires(post): /sbin/chkconfig
Requires(post): /usr/bin/openssl
Requires(preun): /sbin/chkconfig
Requires(preun): /sbin/service
Requires(postun): /sbin/service
-# https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=250253
-ExcludeArch: ppc64
+Provides: user(%{name}) = %{uid}
+Provides: group(%{name}) = %{uid}
+
+Requires: erlang
+Requires: usermode
+
%description
ejabberd is a Free and Open Source distributed fault-tolerant
@@ -86,12 +90,12 @@ Group: Documentation
Documentation for ejabberd.
%pre
-/usr/sbin/fedora-groupadd 27 -r ejabberd &>/dev/null || :
-/usr/sbin/fedora-useradd 27 -r -s /sbin/nologin -d /var/lib/ejabberd -M \
- -c 'ejabberd' -g ejabberd ejabberd &>/dev/null || :
+%{__fe_groupadd} %{uid} -r %{name} &>/dev/null || :
+%{__fe_useradd} %{uid} -r -s /sbin/nologin -d /var/lib/ejabberd -M \
+ -c 'ejabberd' -g %{name} %{name} &>/dev/null || :
%post
-/sbin/chkconfig --add ejabberd
+/sbin/chkconfig --add %{name}
(cd /etc/ejabberd
if [ ! -f ejabberd.pem ]
@@ -115,28 +119,23 @@ fi)
%preun
if [ $1 = 0 ]; then
- /sbin/service ejabberd stop >/dev/null 2>&1
- /sbin/chkconfig --del ejabberd
+ /sbin/service %{name} stop >/dev/null 2>&1
+ /sbin/chkconfig --del %{name}
fi
%postun
if [ "$1" -ge "1" ]; then
- /sbin/service ejabberd condrestart >/dev/null 2>&1
+ /sbin/service %{name} condrestart >/dev/null 2>&1
fi
%prep
%setup -q
-%patch1 -p0 -b .fix_paths
%patch2 -p0 -b .fix_ctl
%patch3 -p0 -b .pam_name
-%patch4 -p1 -b .captcha
%patch5 -p0 -b .mod_ctlextra
-%patch6 -p0 -b .error_msg
-%patch7 -p0 -b .decrease_buffers
%patch8 -p0 -b .s2s
-%patch9 -p0 -b .dyn_compile
-dos2unix src/odbc/mssql.sql
+dos2unix src/odbc/mssql2000.sql
cp %{S:4} src
cp %{S:5} src
@@ -149,8 +148,10 @@ pushd src
# doesn't builds on SMP currently
make
popd
-%if %{undefined rhel}
+%if 0%{?with_hevea}
pushd doc
+# remove pre-built docs
+rm -f dev.html features.html features.pdf guide.html guide.pdf
make html pdf
popd
%endif
@@ -162,9 +163,11 @@ pushd src
make install DESTDIR=%{buildroot}
popd
+# surprisingly, generic ejabberd makefile installs libraries with 644 permissions
chmod a+x %{buildroot}%{_libdir}/%{name}/priv/lib/*.so
-%{__perl} -pi -e 's!./ssl.pem!/etc/ejabberd/ejabberd.pem!g' %{buildroot}/etc/ejabberd/ejabberd.cfg
+# fix example SSL certificate path to real one, which we created recently (see above)
+%{__perl} -pi -e 's!/path/to/ssl.pem!/etc/ejabberd/ejabberd.pem!g' %{buildroot}/etc/ejabberd/ejabberd.cfg
mkdir -p %{buildroot}/var/log/ejabberd
mkdir -p %{buildroot}/var/lib/ejabberd/spool
@@ -184,18 +187,26 @@ install -D -p -m 0644 %{S:2} %{buildroot}%{_sysconfdir}/logrotate.d/ejabberd
# install sysconfig file
install -D -p -m 0644 %{S:3} %{buildroot}%{_sysconfdir}/sysconfig/ejabberd
-%{__perl} -pi -e 's!\@libdir\@!%{_libdir}!g' %{buildroot}%{_initrddir}/ejabberd %{buildroot}%{_sysconfdir}/logrotate.d/ejabberd %{buildroot}%{_sbindir}/ejabberdctl
-%{__perl} -pi -e 's!\@version\@!%{version}!g' %{buildroot}%{_initrddir}/ejabberd %{buildroot}%{_sysconfdir}/logrotate.d/ejabberd %{buildroot}%{_sbindir}/ejabberdctl
+# create room for necessary data
+install -d %{buildroot}%{_datadir}/%{name}
+# install sql-scripts for creating db schemes for various RDBMS
+install -p -m 0644 src/odbc/mssql2000.sql %{buildroot}%{_datadir}/%{name}
+install -p -m 0644 src/odbc/mssql2005.sql %{buildroot}%{_datadir}/%{name}
+install -p -m 0644 src/odbc/mysql.sql %{buildroot}%{_datadir}/%{name}
+install -p -m 0644 src/odbc/pg.sql %{buildroot}%{_datadir}/%{name}
+# install example script for CAPTCHA-protection
+install -p -m 0644 tools/captcha.sh %{buildroot}%{_datadir}/%{name}
-# BZ# 439583
-%{__perl} -pi -e 's!MAINDIR=!MAINDIR=%{_libdir}/ejabberd!g' %{buildroot}%{_sbindir}/ejabberdctl
+# removed files, which would be packaged later (see 'files' section)
+rm -rf %{buildroot}%{_docdir}/%{name}
+rm -f %{buildroot}%{_libdir}/%{name}/priv/bin/captcha.sh
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root,-)
-%doc COPYING src/odbc/mysql.sql src/odbc/mssql.sql src/odbc/pg.sql tools/captcha.sh
+%doc COPYING
%attr(750,ejabberd,ejabberd) %dir %{_sysconfdir}/ejabberd
%attr(640,ejabberd,ejabberd) %config(noreplace) %{_sysconfdir}/ejabberd/ejabberd.cfg
@@ -213,30 +224,97 @@ rm -rf %{buildroot}
%dir %{_libdir}/%{name}
%dir %{_libdir}/%{name}/ebin
+%dir %{_libdir}/%{name}/include
+%dir %{_libdir}/%{name}/include/eldap
+%dir %{_libdir}/%{name}/include/mod_muc
+%dir %{_libdir}/%{name}/include/mod_proxy65
+%dir %{_libdir}/%{name}/include/mod_pubsub
+%dir %{_libdir}/%{name}/include/web
%dir %{_libdir}/%{name}/priv
%dir %{_libdir}/%{name}/priv/bin
-%attr(4750,root,ejabberd) %{_libdir}/%{name}/priv/bin/epam
%dir %{_libdir}/%{name}/priv/lib
%dir %{_libdir}/%{name}/priv/msgs
-%{_libdir}/%{name}/ebin/*.app
+%{_libdir}/%{name}/ebin/%{name}.app
%{_libdir}/%{name}/ebin/*.beam
-%{_libdir}/%{name}/priv/lib/*.so
+%{_libdir}/%{name}/include/XmppAddr.hrl
+%{_libdir}/%{name}/include/adhoc.hrl
+%{_libdir}/%{name}/include/ejabberd.hrl
+%{_libdir}/%{name}/include/ejabberd_commands.hrl
+%{_libdir}/%{name}/include/ejabberd_config.hrl
+%{_libdir}/%{name}/include/ejabberd_ctl.hrl
+%{_libdir}/%{name}/include/eldap/ELDAPv3.hrl
+%{_libdir}/%{name}/include/eldap/eldap.hrl
+%{_libdir}/%{name}/include/jlib.hrl
+%{_libdir}/%{name}/include/mod_muc/mod_muc_room.hrl
+%{_libdir}/%{name}/include/mod_privacy.hrl
+%{_libdir}/%{name}/include/mod_proxy65/mod_proxy65.hrl
+%{_libdir}/%{name}/include/mod_pubsub/pubsub.hrl
+%{_libdir}/%{name}/include/mod_roster.hrl
+%{_libdir}/%{name}/include/web/ejabberd_http.hrl
+%{_libdir}/%{name}/include/web/ejabberd_web_admin.hrl
+%attr(4750,root,ejabberd) %{_libdir}/%{name}/priv/bin/epam
+%{_libdir}/%{name}/priv/lib/ejabberd_zlib_drv.so
+%{_libdir}/%{name}/priv/lib/expat_erl.so
+%{_libdir}/%{name}/priv/lib/iconv_erl.so
+%{_libdir}/%{name}/priv/lib/stringprep_drv.so
+%{_libdir}/%{name}/priv/lib/tls_drv.so
%{_libdir}/%{name}/priv/msgs/*.msg
+%dir %{_datadir}/%{name}
+%{_datadir}/%{name}/captcha.sh
+%{_datadir}/%{name}/mssql2000.sql
+%{_datadir}/%{name}/mssql2005.sql
+%{_datadir}/%{name}/mysql.sql
+%{_datadir}/%{name}/pg.sql
+
%attr(750,ejabberd,ejabberd) %dir /var/lib/ejabberd
%attr(750,ejabberd,ejabberd) %dir /var/lib/ejabberd/spool
%attr(750,ejabberd,ejabberd) %dir /var/log/ejabberd
%files doc
%defattr(-,root,root,-)
-%if %{undefined rhel}
-%doc ChangeLog COPYING doc/release_notes_* doc/*.pdf doc/*.html doc/*.png
-%else
-%doc ChangeLog COPYING doc/release_notes_*
-%endif
+%doc COPYING
+%doc doc/dev.html
+%doc doc/discorus.png
+%doc doc/features.html
+%doc doc/features.pdf
+%doc doc/guide.html
+%doc doc/guide.pdf
+%doc doc/logo.png
+%doc doc/release_notes_0.9.txt
+%doc doc/release_notes_0.9.1.txt
+%doc doc/release_notes_0.9.8.txt
+%doc doc/release_notes_1.0.0.txt
+%doc doc/release_notes_1.1.0.txt
+%doc doc/release_notes_1.1.1.txt
+%doc doc/release_notes_1.1.2.txt
+%doc doc/release_notes_1.1.3.txt
+%doc doc/release_notes_1.1.4.txt
+%doc doc/release_notes_2.0.0.txt
+%doc doc/release_notes_2.0.1.txt
+%doc doc/release_notes_2.0.2.txt
+%doc doc/release_notes_2.0.3.txt
+%doc doc/release_notes_2.0.4.txt
+%doc doc/release_notes_2.0.5.txt
+%doc doc/release_notes_2.1.0.txt
+%doc doc/webadmmain.png
+%doc doc/webadmmainru.png
+%doc doc/yozhikheader.png
%changelog
+* Fri Nov 20 2009 Peter Lemenkov <lemenkov@gmail.com> 2.1.0-1
+- Ver. 2.1.0
+- Upstream no longer providing ChangeLog
+- Dropped ejabberd-build.patch (upstreamed)
+- Dropped ejabberd-captcha.patch (upstreamed)
+- Dropped ejabberd-decrease_buffers_in_mod_proxy65.patch (upstreamed)
+- Dropped ejabberd-dynamic_compile_loglevel.patch (upstreamed)
+- Dropped ejabberd-turn_off_error_messages_in_mod_caps.patch (upstreamed)
+- Docs reorganized and added ability to rebuild them if possible
+- Added back ppc64 target
+- SQL-scripts moved to %%{_datadir}/%%{name} from %%doc
+
* Thu Nov 5 2009 Peter Lemenkov <lemenkov@gmail.com> 2.0.5-10
- mod_ctlextra was updated from r873 to r1020
- Fix for BZ# 533021
diff --git a/import.log b/import.log
index 548962f..cc1cb86 100644
--- a/import.log
+++ b/import.log
@@ -12,3 +12,4 @@ ejabberd-2_0_5-3_fc10:HEAD:ejabberd-2.0.5-3.fc10.src.rpm:1240304532
ejabberd-2_0_5-6_fc11:HEAD:ejabberd-2.0.5-6.fc11.src.rpm:1251228870
ejabberd-2_0_5-8_fc11:HEAD:ejabberd-2.0.5-8.fc11.src.rpm:1252493017
ejabberd-2_0_5-10_fc11:HEAD:ejabberd-2.0.5-10.fc11.src.rpm:1257428310
+ejabberd-2_1_0-1_fc12:HEAD:ejabberd-2.1.0-1.fc12.src.rpm:1258790332
diff --git a/sources b/sources
index 77e1427..cc4348c 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-2d85b47df969daf0a78ed3b16562d731 ejabberd-2.0.5.tar.gz
+373be6e99acf7c930ab85531489c63c4 ejabberd-2.1.0.tar.gz
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-23 19:06 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-23 19:06 [rpms/ejabberd] f45: Ver. 2.1.0 Peter Lemenkov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox