rpms/ejabberd/F-7 .cvsignore, 1.4, 1.5 ejabberd.spec, 1.12, 1.13 mod_ctlextra.erl, 1.2, 1.3 sources, 1.4, 1.5 ejabberd-1.1.3-ldapfix.patch, 1.1, NONE
Jeffrey C. Ollie (jcollie)
fedora-extras-commits at redhat.com
Thu Sep 6 15:07:08 UTC 2007
- Previous message (by thread): rpms/mash/F-7 mash-multilib.patch,NONE,1.1 mash.spec,1.6,1.7
- Next message (by thread): rpms/phpMyAdmin/devel .cvsignore, 1.7, 1.8 phpMyAdmin.htaccess, 1.1, 1.2 phpMyAdmin.spec, 1.10, 1.11 sources, 1.7, 1.8
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: jcollie
Update of /cvs/pkgs/rpms/ejabberd/F-7
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv731
Modified Files:
.cvsignore ejabberd.spec mod_ctlextra.erl sources
Removed Files:
ejabberd-1.1.3-ldapfix.patch
Log Message:
Update to 1.1.4
Index: .cvsignore
===================================================================
RCS file: /cvs/pkgs/rpms/ejabberd/F-7/.cvsignore,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- .cvsignore 2 Feb 2007 21:21:08 -0000 1.4
+++ .cvsignore 6 Sep 2007 15:06:36 -0000 1.5
@@ -1 +1 @@
-ejabberd-1.1.3.tar.gz
+ejabberd-1.1.4.tar.gz
Index: ejabberd.spec
===================================================================
RCS file: /cvs/pkgs/rpms/ejabberd/F-7/ejabberd.spec,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- ejabberd.spec 4 Sep 2007 12:42:20 -0000 1.12
+++ ejabberd.spec 6 Sep 2007 15:06:36 -0000 1.13
@@ -1,6 +1,6 @@
Name: ejabberd
-Version: 1.1.3
-Release: 11%{?dist}
+Version: 1.1.4
+Release: 1%{?dist}
Summary: A distributed, fault-tolerant Jabber/XMPP server
Group: Applications/Internet
@@ -23,8 +23,6 @@
Source9: ejabberdctl.pam
Source10: ejabberdctl.apps
-Patch1: ejabberd-1.1.3-ldapfix.patch
-
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: expat-devel
@@ -79,8 +77,6 @@
%prep
%setup -q
-%patch1 -p1
-
%{__perl} -pi -e "s!/var/lib/ejabberd!%{_libdir}/ejabberd-%{version}!g" src/Makefile.in
%{__perl} -pi -e "s!/etc!%{_sysconfdir}!g" src/Makefile.in
%{__perl} -pi -e "s!\@prefix\@!!g" src/Makefile.in
@@ -173,6 +169,11 @@
%doc ChangeLog COPYING TODO doc/*.pdf doc/*.html doc/*.png doc/release_notes_*
%changelog
+* Wed Sep 5 2007 Jeffrey C. Ollie <jeff at ocjtech.us> - 1.1.4-1
+- Drop LDAP patch
+- Update mod_ctlextra
+- Update to 1.1.4
+
* Tue Sep 4 2007 Jeffrey C. Ollie <jeff at ocjtech.us> - 1.1.3-11
- Fix ejabberdctl wrapper script - #276071
Index: mod_ctlextra.erl
===================================================================
RCS file: /cvs/pkgs/rpms/ejabberd/F-7/mod_ctlextra.erl,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- mod_ctlextra.erl 31 Jul 2007 12:50:20 -0000 1.2
+++ mod_ctlextra.erl 6 Sep 2007 15:06:36 -0000 1.3
@@ -1,191 +1,193 @@
%%%----------------------------------------------------------------------
%%% File : mod_ctlextra.erl
-%%% Author : Badlop
-%%% Purpose : Adds more options for ejabberd_ctl
-%%% Created :
+%%% Author : Badlop <badlop at ono.com>
+%%% Purpose : Adds more commands to ejabberd_ctl
+%%% Created : 30 Nov 2006 by Badlop <badlop at ono.com>
%%% Id : $Id$
%%%----------------------------------------------------------------------
-module(mod_ctlextra).
--author('').
--vsn('$Revision$').
+-author('badlop at ono.com').
+-vsn('$Revision$ ').
-behaviour(gen_mod).
--export([
- start/2,
- stop/1,
- ctl_process/2,
- ctl_process/3
+-export([start/2,
+ stop/1,
+ ctl_process/2,
+ ctl_process/3
]).
-include("ejabberd.hrl").
-include("ejabberd_ctl.hrl").
-include("jlib.hrl").
+-include("mod_roster.hrl").
-record(session, {sid, usr, us, priority}). % copied from ejabberd_sm.erl
start(Host, _Opts) ->
- ejabberd_ctl:register_commands([
- {"compile file", "recompile and reload file"},
- {"load-config file", "load config from file"},
- {"remove-node nodename", "remove an ejabberd node from the database"},
-
- % ejabberd_auth
- {"delete-older-users days", "delete users that have not logged in the last 'days'"},
- {"set-password user server password", "set password to user at server"},
-
- % ejd2odbc
- {"export2odbc server output", "export Mnesia tables on server to files on output directory"},
-
- % mod_offline
- {"delete-older-messages days", "delete offline messages older than 'days'"},
-
- % mod_shared_roster
- {"srg-create group host name description display", "create the group with options"},
- {"srg-delete group host", "delete the group"},
- {"srg-user-add user server group host", "add user at server to group on host"},
- {"srg-user-del user server group host", "delete user at server from group on host"},
-
- % mod_vcard
- {"vcard-get user host data [data2]", "get data from the vCard of the user"},
- {"vcard-set user host data [data2] content", "set data to content on the vCard"},
-
- % mod_announce
- % announce_send_online host message
- % announce_send_all host, message
-
- % mod_muc
- % muc-add room opts
- % muc-del room
- {"muc-purge days", "destroy rooms with not activity on the last 'days'"},
- {"muc-online-rooms", "list existing rooms"},
-
- % mod_roster
- {"add-rosteritem user1 server1 user2 server2 nick group subs", "Add user2 at server2 to user1 at server1"},
- %{"", "subs= none, from, to or both"},
- %{"", "example: add-roster peter localhost mike server.com MiKe Employees both"},
- %{"", "will add mike at server.com to peter at localhost roster"},
- {"pushroster file user server", "push template roster in file to user at server"},
- {"pushroster-all file", "push template roster in file to all those users"},
- {"push-alltoall server group", "adds all the users to all the users in Group"},
-
- {"status-list status", "list the logged users with status"},
- {"status-num status", "number of logged users with status"},
-
- {"stats registeredusers", "number of registered users"},
- {"stats onlineusers", "number of logged users"},
-
- % misc
- {"get-cookie", "get the Erlang cookie of this node"},
- {"killsession user server resource", "kill a user session"}
- ], ?MODULE, ctl_process),
+ ejabberd_ctl:register_commands([
+ {"compile file", "recompile and reload file"},
+ {"load-config file", "load config from file"},
+ {"remove-node nodename", "remove an ejabberd node from the database"},
+
+ %% ejabberd_auth
+ {"delete-older-users days", "delete users that have not logged in the last 'days'"},
+ {"set-password user server password", "set password to user at server"},
+
+ %% ejd2odbc
+ {"export2odbc server output", "export Mnesia tables on server to files on output directory"},
+
+ %% mod_offline
+ {"delete-older-messages days", "delete offline messages older than 'days'"},
+
+ %% mod_shared_roster
+ {"srg-create group host name description display", "create the group with options"},
+ {"srg-delete group host", "delete the group"},
+ {"srg-user-add user server group host", "add user at server to group on host"},
+ {"srg-user-del user server group host", "delete user at server from group on host"},
+
+ %% mod_vcard
+ {"vcard-get user host data [data2]", "get data from the vCard of the user"},
+ {"vcard-set user host data [data2] content", "set data to content on the vCard"},
+
+ %% mod_announce
+ %% announce_send_online host message
+ %% announce_send_all host, message
+
+ %% mod_muc
+ %% muc-add room opts
+ %% muc-del room
+ {"muc-purge days", "destroy rooms with not activity on the last 'days'"},
+ {"muc-online-rooms", "list existing rooms"},
+
+ %% mod_roster
+ {"add-rosteritem user1 server1 user2 server2 nick group subs", "Add user2 at server2 to user1 at server1's roster"},
+ %%{"", "subs= none, from, to or both"},
+ %%{"", "example: add-roster peter localhost mike server.com MiKe Employees both"},
+ %%{"", "will add mike at server.com to peter at localhost roster"},
+ {"rem-rosteritem user1 server1 user2 server2", "Remove user2 at server2 from user1 at server1's roster"},
+ {"pushroster file user server", "push template roster in file to user at server"},
+ {"pushroster-all file", "push template roster in file to all those users"},
+ {"push-alltoall server group", "adds all the users to all the users in Group"},
+
+ {"status-list status", "list the logged users with status"},
+ {"status-num status", "number of logged users with status"},
+
+ {"stats registeredusers", "number of registered users"},
+ {"stats onlineusers", "number of logged users"},
+ {"stats uptime-seconds", "uptime of ejabberd node in seconds"},
+
+ %% misc
+ {"get-cookie", "get the Erlang cookie of this node"},
+ {"killsession user server resource", "kill a user session"}
+ ], ?MODULE, ctl_process),
ejabberd_ctl:register_commands(Host, [
- % mod_muc
- {"muc-purge days", "destroy rooms with not activity on the last 'days'"},
- {"muc-online-rooms", "list existing rooms"},
-
- % mod_last
- {"num-active-users days", "number of users active in the last 'days'"},
- {"status-list status", "list the logged users with status"},
- {"status-num status", "number of logged users with status"},
- {"stats registeredusers", "number of registered users"},
- {"stats onlineusers", "number of logged users"}
- ], ?MODULE, ctl_process),
- ok.
+ %% mod_muc
+ {"muc-purge days", "destroy rooms with not activity on the last 'days'"},
+ {"muc-online-rooms", "list existing rooms"},
+
+ %% mod_last
+ {"num-active-users days", "number of users active in the last 'days'"},
+ {"status-list status", "list the logged users with status"},
+ {"status-num status", "number of logged users with status"},
+ {"stats registeredusers", "number of registered users"},
+ {"stats onlineusers", "number of logged users"}
+ ], ?MODULE, ctl_process),
+ ok.
stop(_Host) ->
- ok.
+ ok.
ctl_process(_Val, ["blo"]) ->
- FResources = "eeeaaa aaa",
- io:format("~s", [FResources]),
- ?STATUS_SUCCESS;
+ FResources = "eeeaaa aaa",
+ io:format("~s", [FResources]),
+ ?STATUS_SUCCESS;
ctl_process(_Val, ["delete-older-messages", Days]) ->
mod_offline:remove_old_messages(list_to_integer(Days)),
?STATUS_SUCCESS;
ctl_process(_Val, ["delete-older-users", Days]) ->
- {removed, N, UR} = delete_older_users(list_to_integer(Days)),
- io:format("Deleted ~p users: ~p~n", [N, UR]),
- ?STATUS_SUCCESS;
+ {removed, N, UR} = delete_older_users(list_to_integer(Days)),
+ io:format("Deleted ~p users: ~p~n", [N, UR]),
+ ?STATUS_SUCCESS;
ctl_process(_Val, ["export2odbc", Server, Output]) ->
- Tables = [
- {export_last, last},
- {export_offline, offline},
- {export_passwd, passwd},
- {export_private_storage, private_storage},
- {export_roster, roster},
- {export_vcard, vcard},
- {export_vcard_search, vcard_search}],
- Export = fun({TableFun, Table}) ->
- Filename = filename:join([Output, atom_to_list(Table)++".txt"]),
- io:format("Trying to export Mnesia table '~p' on server '~s' to file '~s'~n", [Table, Server, Filename]),
- catch ejd2odbc:TableFun(Server, Filename)
- end,
- lists:foreach(Export, Tables),
- ?STATUS_SUCCESS;
+ Tables = [
+ {export_last, last},
+ {export_offline, offline},
+ {export_passwd, passwd},
+ {export_private_storage, private_storage},
+ {export_roster, roster},
+ {export_vcard, vcard},
+ {export_vcard_search, vcard_search}],
+ Export = fun({TableFun, Table}) ->
+ Filename = filename:join([Output, atom_to_list(Table)++".txt"]),
+ io:format("Trying to export Mnesia table '~p' on server '~s' to file '~s'~n", [Table, Server, Filename]),
+ catch ejd2odbc:TableFun(Server, Filename)
+ end,
+ lists:foreach(Export, Tables),
+ ?STATUS_SUCCESS;
ctl_process(_Val, ["set-password", User, Server, Password]) ->
ejabberd_auth:set_password(User, Server, Password),
- ?STATUS_SUCCESS;
+ ?STATUS_SUCCESS;
ctl_process(_Val, ["vcard-get", User, Server, Data]) ->
- {ok, Res} = vcard_get(User, Server, {Data}),
+ {ok, Res} = vcard_get(User, Server, [Data]),
io:format("~s~n", [Res]),
?STATUS_SUCCESS;
ctl_process(_Val, ["vcard-get", User, Server, Data1, Data2]) ->
- {ok, Res} = vcard_get(User, Server, {Data1, Data2}),
+ {ok, Res} = vcard_get(User, Server, [Data1, Data2]),
io:format("~s~n", [Res]),
?STATUS_SUCCESS;
-ctl_process(_Val, ["vcard-set", User, Server, Data, Content]) ->
- {ok, Res} = vcard_set(User, Server, Data, Content),
+ctl_process(_Val, ["vcard-set", User, Server, Data1, Content]) ->
+ {ok, Res} = vcard_set(User, Server, [Data1], Content),
io:format("~s~n", [Res]),
?STATUS_SUCCESS;
ctl_process(_Val, ["vcard-set", User, Server, Data1, Data2, Content]) ->
- {ok, Res} = vcard_set(User, Server, Data1, Data2, Content),
+ {ok, Res} = vcard_set(User, Server, [Data1, Data2], Content),
io:format("~s~n", [Res]),
?STATUS_SUCCESS;
ctl_process(_Val, ["compile", Module]) ->
compile:file(Module),
- ?STATUS_SUCCESS;
+ ?STATUS_SUCCESS;
ctl_process(_Val, ["remove-node", Node]) ->
- mnesia:del_table_copy(schema, list_to_atom(Node)),
- ?STATUS_SUCCESS;
+ mnesia:del_table_copy(schema, list_to_atom(Node)),
+ ?STATUS_SUCCESS;
ctl_process(_Val, ["srg-create", Group, Host, Name, Description, Display]) ->
- Opts = [{name, Name}, {displayed_groups, [Display]}, {description, Description}],
- {atomic, ok} = mod_shared_roster:create_group(Host, Group, Opts),
+ Opts = [{name, Name}, {displayed_groups, [Display]}, {description, Description}],
+ {atomic, ok} = mod_shared_roster:create_group(Host, Group, Opts),
?STATUS_SUCCESS;
ctl_process(_Val, ["srg-delete", Group, Host]) ->
- {atomic, ok} = mod_shared_roster:delete_group(Host, Group),
+ {atomic, ok} = mod_shared_roster:delete_group(Host, Group),
?STATUS_SUCCESS;
ctl_process(_Val, ["srg-user-add", User, Server, Group, Host]) ->
- {atomic, ok} = mod_shared_roster:add_user_to_group(Host, {User, Server}, Group),
+ {atomic, ok} = mod_shared_roster:add_user_to_group(Host, {User, Server}, Group),
?STATUS_SUCCESS;
ctl_process(_Val, ["srg-user-del", User, Server, Group, Host]) ->
- {atomic, ok} = mod_shared_roster:remove_user_from_group(Host, {User, Server}, Group),
+ {atomic, ok} = mod_shared_roster:remove_user_from_group(Host, {User, Server}, Group),
?STATUS_SUCCESS;
ctl_process(_Val, ["muc-purge", Days]) ->
- {purged, Num_total, Num_purged, Names_purged} = muc_purge(list_to_integer(Days)),
- io:format("Purged ~p chatrooms from a total of ~p on the server:~n~p~n", [Num_purged, Num_total, Names_purged]),
- ?STATUS_SUCCESS;
+ {purged, Num_total, Num_purged, Names_purged} = muc_purge(list_to_integer(Days)),
+ io:format("Purged ~p chatrooms from a total of ~p on the server:~n~p~n", [Num_purged, Num_total, Names_purged]),
+ ?STATUS_SUCCESS;
ctl_process(_Val, ["muc-online-rooms"]) ->
- format_print_room(all, ets:tab2list(muc_online_room)),
- ?STATUS_SUCCESS;
+ format_print_room(all, ets:tab2list(muc_online_room)),
+ ?STATUS_SUCCESS;
ctl_process(_Val, ["add-rosteritem", LocalUser, LocalServer, RemoteUser, RemoteServer, Nick, Group, Subs]) ->
case add_rosteritem(LocalUser, LocalServer, RemoteUser, RemoteServer, Nick, Group, list_to_atom(Subs), []) of
@@ -201,6 +203,20 @@
?STATUS_BADRPC
end;
+ctl_process(_Val, ["rem-rosteritem", LocalUser, LocalServer, RemoteUser, RemoteServer]) ->
+ case rem_rosteritem(LocalUser, LocalServer, RemoteUser, RemoteServer) of
+ {atomic, ok} ->
+ ?STATUS_SUCCESS;
+ {error, Reason} ->
+ io:format("Can't remove ~p@~p to ~p@~p: ~p~n",
+ [RemoteUser, RemoteServer, LocalUser, LocalServer, Reason]),
+ ?STATUS_ERROR;
+ {badrpc, Reason} ->
+ io:format("Can't remove roster item to user ~p: ~p~n",
+ [LocalUser, Reason]),
+ ?STATUS_BADRPC
+ end;
+
ctl_process(_Val, ["pushroster", File, User, Server]) ->
case pushroster(File, User, Server) of
ok ->
@@ -258,18 +274,19 @@
end;
ctl_process(_Val, ["stats", Stat]) ->
- Res = case Stat of
- "registeredusers" -> mnesia:table_info(passwd, size);
- "onlineusers" -> mnesia:table_info(session, size)
- end,
+ Res = case Stat of
+ "uptime-seconds" -> uptime_seconds();
+ "registeredusers" -> mnesia:table_info(passwd, size);
+ "onlineusers" -> mnesia:table_info(session, size)
+ end,
io:format("~p~n", [Res]),
?STATUS_SUCCESS;
ctl_process(_Val, ["status-num", Status_required]) ->
- ctl_process(_Val, "all", ["status-num", Status_required]);
+ ctl_process(_Val, "all", ["status-num", Status_required]);
ctl_process(_Val, ["status-list", Status_required]) ->
- ctl_process(_Val, "all", ["status-list", Status_required]);
+ ctl_process(_Val, "all", ["status-list", Status_required]);
ctl_process(_Val, ["get-cookie"]) ->
io:format("~s~n", [atom_to_list(erlang:get_cookie())]),
@@ -277,50 +294,50 @@
ctl_process(_Val, ["killsession", User, Server, Resource]) ->
ejabberd_router:route(
- jlib:make_jid("", "", ""),
- jlib:make_jid(User, Server, Resource),
- {xmlelement, "broadcast", [], [{exit, "killed"}]}),
+ jlib:make_jid("", "", ""),
+ jlib:make_jid(User, Server, Resource),
+ {xmlelement, "broadcast", [], [{exit, "killed"}]}),
?STATUS_SUCCESS;
ctl_process(Val, _Args) ->
- Val.
+ Val.
ctl_process(_Val, Host, ["muc-purge", Days]) ->
- {purged, Num_total, Num_purged, Names_purged} = muc_purge(Host, list_to_integer(Days)),
- io:format("Purged ~p chatrooms from a total of ~p on the host ~p:~n~p~n", [Num_purged, Num_total, Host, Names_purged]),
- ?STATUS_SUCCESS;
+ {purged, Num_total, Num_purged, Names_purged} = muc_purge(Host, list_to_integer(Days)),
+ io:format("Purged ~p chatrooms from a total of ~p on the host ~p:~n~p~n", [Num_purged, Num_total, Host, Names_purged]),
+ ?STATUS_SUCCESS;
ctl_process(_Val, ServerHost, ["muc-online-rooms"]) ->
- MUCHost = find_host(ServerHost),
- format_print_room(MUCHost, ets:tab2list(muc_online_room)),
- ?STATUS_SUCCESS;
+ MUCHost = find_host(ServerHost),
+ format_print_room(MUCHost, ets:tab2list(muc_online_room)),
+ ?STATUS_SUCCESS;
ctl_process(_Val, Host, ["num-active-users", Days]) ->
- Number = num_active_users(Host, list_to_integer(Days)),
+ Number = num_active_users(Host, list_to_integer(Days)),
io:format("~p~n", [Number]),
?STATUS_SUCCESS;
ctl_process(_Val, Host, ["stats", Stat]) ->
- Res = case Stat of
- "registeredusers" -> length(ejabberd_auth:get_vh_registered_users(Host));
- "onlineusers" -> length(ejabberd_sm:get_vh_session_list(Host))
- end,
+ Res = case Stat of
+ "registeredusers" -> length(ejabberd_auth:get_vh_registered_users(Host));
+ "onlineusers" -> length(ejabberd_sm:get_vh_session_list(Host))
+ end,
io:format("~p~n", [Res]),
?STATUS_SUCCESS;
ctl_process(_Val, Host, ["status-num", Status_required]) ->
- Num = length(get_status_list(Host, Status_required)),
+ Num = length(get_status_list(Host, Status_required)),
io:format("~p~n", [Num]),
?STATUS_SUCCESS;
ctl_process(_Val, Host, ["status-list", Status_required]) ->
- Res = get_status_list(Host, Status_required),
+ Res = get_status_list(Host, Status_required),
[ io:format("~s@~s ~s ~p \"~s\"~n", [U, S, R, P, St]) || {U, S, R, P, St} <- Res],
?STATUS_SUCCESS;
ctl_process(Val, _Host, _Args) ->
- Val.
+ Val.
%%-------------
@@ -328,205 +345,241 @@
%%-------------
get_status_list(Host, Status_required) ->
- % Get list of all logged users
- Sessions = ejabberd_sm:dirty_get_my_sessions_list(),
- % Reformat the list
- Sessions2 = [ {Session#session.usr, Session#session.sid, Session#session.priority} || Session <- Sessions],
- Fhost = case Host of
+ %% Get list of all logged users
+ Sessions = ejabberd_sm:dirty_get_my_sessions_list(),
+ %% Reformat the list
+ Sessions2 = [ {Session#session.usr, Session#session.sid, Session#session.priority} || Session <- Sessions],
+ Fhost = case Host of
"all" ->
- % All hosts are requested, so don't filter at all
- fun(_, _) -> true end;
+ %% All hosts are requested, so dont filter at all
+ fun(_, _) -> true end;
_ ->
- % Filter the list, only Host is interesting
- fun(A, B) -> A == B end
- end,
- Sessions3 = [ {Pid, Server, Priority} || {{_User, Server, _Resource}, {_, Pid}, Priority} <- Sessions2, apply(Fhost, [Server, Host])],
- % For each Pid, get its presence
- Sessions4 = [ {ejabberd_c2s:get_presence(Pid), Server, Priority} || {Pid, Server, Priority} <- Sessions3],
- % Filter by status
- Fstatus = case Status_required of
- "all" ->
- fun(_, _) -> true end;
- _ ->
- fun(A, B) -> A == B end
- end,
- [{User, Server, Resource, Priority, stringize(Status_text)}
- || {{User, Resource, Status, Status_text}, Server, Priority} <- Sessions4,
- apply(Fstatus, [Status, Status_required])].
+ %% Filter the list, only Host is interesting
+ fun(A, B) -> A == B end
+ end,
+ Sessions3 = [ {Pid, Server, Priority} || {{_User, Server, _Resource}, {_, Pid}, Priority} <- Sessions2, apply(Fhost, [Server, Host])],
+ %% For each Pid, get its presence
+ Sessions4 = [ {ejabberd_c2s:get_presence(Pid), Server, Priority} || {Pid, Server, Priority} <- Sessions3],
+ %% Filter by status
+ Fstatus = case Status_required of
+ "all" ->
+ fun(_, _) -> true end;
+ _ ->
+ fun(A, B) -> A == B end
+ end,
+ [{User, Server, Resource, Priority, stringize(Status_text)}
+ || {{User, Resource, Status, Status_text}, Server, Priority} <- Sessions4,
+ apply(Fstatus, [Status, Status_required])].
-% Make string more print-friendly
+%% Make string more print-friendly
stringize(String) ->
- % Replace newline characters with other code
- element(2, regexp:gsub(String, "\n", "\\n")).
+ %% Replace newline characters with other code
+ element(2, regexp:gsub(String, "\n", "\\n")).
add_rosteritem(LU, LS, RU, RS, Nick, Group, Subscription, Xattrs) ->
- subscribe(LU, LS, RU, RS, Nick, Group, Subscription, Xattrs),
- % TODO: if the server is not local and Subs=to or both: send subscription request
- % TODO: check if the 'remote server' is a virtual host here, else do nothing
- %add_rosteritem2(RU, RS, LU, LS, LU, "", invert_subs(Subscription), Xattrs, Host).
- subscribe(RU, RS, LU, LS, LU, "", invert_subs(Subscription), Xattrs).
-
-invert_subs(none) -> none;
-invert_subs(to) -> none;
-invert_subs(from) -> to;
-invert_subs(both) -> both.
+ subscribe(LU, LS, RU, RS, Nick, Group, Subscription, Xattrs),
+ route_rosteritem(LU, LS, RU, RS, Nick, Group, Subscription),
+ {atomic, ok}.
subscribe(LocalUser, LocalServer, RemoteUser, RemoteServer, Nick, Group, Subscription, Xattrs) ->
- mnesia:transaction(
- fun() ->
- mnesia:write({
- roster,
- {LocalUser,LocalServer,{RemoteUser,RemoteServer,[]}}, % usj
- {LocalUser,LocalServer}, % us
- {RemoteUser,RemoteServer,[]}, % jid
- Nick, % name: "Mom", []
- Subscription, % subscription: none, to=you see him, from=he sees you, both
- none, % ask: out=send request, in=somebody requests you, none
- [Group], % groups: ["Family"]
- Xattrs, % xattrs: [{"category","conference"}]
- [] % xs: []
- })
- end).
+ R = #roster{usj = {LocalUser,LocalServer,{RemoteUser,RemoteServer,[]}},
+ us = {LocalUser,LocalServer},
+ jid = {RemoteUser,RemoteServer,[]},
+ name = Nick,
+ subscription = Subscription, % none, to=you see him, from=he sees you, both
+ ask = none, % out=send request, in=somebody requests you, none
+ groups = [Group],
+ askmessage = Xattrs, % example: [{"category","conference"}]
+ xs = []},
+ mnesia:transaction(fun() -> mnesia:write(R) end).
+
+rem_rosteritem(LU, LS, RU, RS) ->
+ unsubscribe(LU, LS, RU, RS),
+ route_rosteritem(LU, LS, RU, RS, "", "", "remove"),
+ {atomic, ok}.
+
+unsubscribe(LocalUser, LocalServer, RemoteUser, RemoteServer) ->
+ Key = {{LocalUser,LocalServer,{RemoteUser,RemoteServer,[]}},
+ {LocalUser,LocalServer}},
+ mnesia:transaction(fun() -> mnesia:delete(roster, Key, write) end).
+
+route_rosteritem(LocalUser, LocalServer, RemoteUser, RemoteServer, Nick, Group, Subscription) ->
+ LJID = jlib:make_jid(LocalUser, LocalServer, ""),
+ RJID = jlib:make_jid(RemoteUser, RemoteServer, ""),
+ ToS = jlib:jid_to_string(LJID),
+ ItemJIDS = jlib:jid_to_string(RJID),
+ GroupXML = {xmlelement, "group", [], [{xmlcdata, Group}]},
+ Item = {xmlelement, "item",
+ [{"jid", ItemJIDS},
+ {"name", Nick},
+ {"subscription", Subscription}],
+ [GroupXML]},
+ Query = {xmlelement, "query", [{"xmlns", ?NS_ROSTER}], [Item]},
+ Packet = {xmlelement, "iq", [{"type", "set"}, {"to", ToS}], [Query]},
+ ejabberd_router:route(LJID, LJID, Packet).
pushroster(File, User, Server) ->
- {ok, [Roster]} = file:consult(File),
- subscribe_roster({User, Server, "", User}, Roster).
+ {ok, [Roster]} = file:consult(File),
+ subscribe_roster({User, Server, "", User}, Roster).
pushroster_all(File) ->
- {ok, [Roster]} = file:consult(File),
- subscribe_all(Roster).
+ {ok, [Roster]} = file:consult(File),
+ subscribe_all(Roster).
subscribe_all(Roster) ->
- subscribe_all(Roster, Roster).
+ subscribe_all(Roster, Roster).
subscribe_all([], _) ->
- ok;
+ ok;
subscribe_all([User1 | Users], Roster) ->
- subscribe_roster(User1, Roster),
- subscribe_all(Users, Roster).
+ subscribe_roster(User1, Roster),
+ subscribe_all(Users, Roster).
subscribe_roster(_, []) ->
- ok;
-% Do not subscribe a user to itself
+ ok;
+%% Do not subscribe a user to itself
subscribe_roster({Name, Server, Group, Nick}, [{Name, Server, _, _} | Roster]) ->
- subscribe_roster({Name, Server, Group, Nick}, Roster);
-% Subscribe Name2 to Name1
+ subscribe_roster({Name, Server, Group, Nick}, Roster);
+%% Subscribe Name2 to Name1
subscribe_roster({Name1, Server1, Group1, Nick1}, [{Name2, Server2, Group2, Nick2} | Roster]) ->
- subscribe(Name1, Server1, Name2, Server2, Nick2, Group2, both, []),
- subscribe_roster({Name1, Server1, Group1, Nick1}, Roster).
+ subscribe(Name1, Server1, Name2, Server2, Nick2, Group2, both, []),
+ subscribe_roster({Name1, Server1, Group1, Nick1}, Roster).
push_alltoall(S, G) ->
- Users = ejabberd_auth:get_vh_registered_users(S),
- Users2 = build_list_users(G, Users, []),
- subscribe_all(Users2).
+ Users = ejabberd_auth:get_vh_registered_users(S),
+ Users2 = build_list_users(G, Users, []),
+ subscribe_all(Users2).
build_list_users(_Group, [], Res) ->
- Res;
+ Res;
build_list_users(Group, [{User, Server}|Users], Res) ->
- build_list_users(Group, Users, [{User, Server, Group, User}|Res]).
+ build_list_users(Group, Users, [{User, Server, Group, User}|Res]).
-vcard_get(User, Server, DataX) ->
- [{_, _, A1}] = mnesia:dirty_read(vcard, {User, Server}),
- Elem = vcard_get(DataX, A1),
- {ok, xml:get_tag_cdata(Elem)}.
-
-vcard_get({Data1, Data2}, A1) ->
- A2 = xml:get_subtag(A1, Data1),
- A3 = xml:get_subtag(A2, Data2),
- case A3 of
- "" -> A2;
- _ -> A3
- end;
+vcard_get(User, Server, Data) ->
+ [{_, Module, Function, _Opts}] = ets:lookup(sm_iqtable, {?NS_VCARD, Server}),
+ JID = jlib:make_jid(User, Server, ""),
+ IQ = #iq{type = get, xmlns = ?NS_VCARD},
+ IQr = Module:Function(JID, JID, IQ),
+ Res = case IQr#iq.sub_el of
+ [A1] ->
+ case vcard_get(Data, A1) of
+ false -> no_value;
+ Elem -> xml:get_tag_cdata(Elem)
+ end;
+ [] ->
+ no_vcard
+ end,
+ {ok, Res}.
+
+vcard_get([Data1, Data2], A1) ->
+ case xml:get_subtag(A1, Data1) of
+ false -> false;
+ A2 -> vcard_get([Data2], A2)
+ end;
-vcard_get({Data}, A1) ->
+vcard_get([Data], A1) ->
xml:get_subtag(A1, Data).
-vcard_set(User, Server, Data1, Data2, Content) ->
- Content2 = {xmlelement, Data2, [], [{xmlcdata,Content}]},
- R = {xmlelement, Data1, [], [Content2]},
- vcard_set2(User, Server, R, Data1).
-
vcard_set(User, Server, Data, Content) ->
- R = {xmlelement, Data, [], [{xmlcdata,Content}]},
- vcard_set2(User, Server, R, Data).
-
-vcard_set2(User, Server, R, Data) ->
- % Get old vcard
- A4 = case mnesia:dirty_read(vcard, {User, Server}) of
- [] ->
- [R];
- [{_, _, A1}] ->
- {_, _, _, A2} = A1,
- A3 = lists:keydelete(Data, 2, A2),
- [R | A3]
- end,
-
- % Build new vcard
- SubEl = {xmlelement, "vCard", [{"xmlns","vcard-temp"}], A4},
- IQ = #iq{type=set, sub_el = SubEl},
- JID = jlib:make_jid(User, Server, ""),
-
- mod_vcard:process_sm_iq(JID, JID, IQ),
- {ok, "done"}.
-
+ [{_, Module, Function, _Opts}] = ets:lookup(sm_iqtable, {?NS_VCARD, Server}),
+ JID = jlib:make_jid(User, Server, ""),
+ IQ = #iq{type = get, xmlns = ?NS_VCARD},
+ IQr = Module:Function(JID, JID, IQ),
+
+ %% Get old vcard
+ A4 = case IQr#iq.sub_el of
+ [A1] ->
+ {_, _, _, A2} = A1,
+ update_vcard_els(Data, Content, A2);
+ [] ->
+ update_vcard_els(Data, Content, [])
+ end,
+
+ %% Build new vcard
+ SubEl = {xmlelement, "vCard", [{"xmlns","vcard-temp"}], A4},
+ IQ2 = #iq{type=set, sub_el = SubEl},
+
+ Module:Function(JID, JID, IQ2),
+ {ok, "done"}.
+
+update_vcard_els(Data, Content, Els1) ->
+ Els2 = lists:keysort(2, Els1),
+ [Data1 | Data2] = Data,
+ NewEl = case Data2 of
+ [] ->
+ {xmlelement, Data1, [], [{xmlcdata,Content}]};
+ [D2] ->
+ OldEl = case lists:keysearch(Data1, 2, Els2) of
+ {value, A} -> A;
+ false -> {xmlelement, Data1, [], []}
+ end,
+ {xmlelement, _, _, ContentOld1} = OldEl,
+ Content2 = [{xmlelement, D2, [], [{xmlcdata,Content}]}],
+ ContentOld2 = lists:keysort(2, ContentOld1),
+ ContentOld3 = lists:keydelete(D2, 2, ContentOld2),
+ ContentNew = lists:keymerge(2, Content2, ContentOld3),
+ {xmlelement, Data1, [], ContentNew}
+ end,
+ Els3 = lists:keydelete(Data1, 2, Els2),
+ lists:keymerge(2, [NewEl], Els3).
-record(last_activity, {us, timestamp, status}).
delete_older_users(Days) ->
- % Convert older time
- SecOlder = Days*24*60*60,
+ %% Convert older time
+ SecOlder = Days*24*60*60,
+
+ %% Get current time
+ {MegaSecs, Secs, _MicroSecs} = now(),
+ TimeStamp_now = MegaSecs * 1000000 + Secs,
+
+ %% Get the list of registered users
+ Users = ejabberd_auth:dirty_get_registered_users(),
- % Get current time
- {MegaSecs, Secs, _MicroSecs} = now(),
- TimeStamp_now = MegaSecs * 1000000 + Secs,
-
- % Get the list of registered users
- Users = ejabberd_auth:dirty_get_registered_users(),
-
- % For a user, remove if required and answer true
- F = fun({LUser, LServer}) ->
- % Check if the user is logged
+ %% For a user, remove if required and answer true
+ F = fun({LUser, LServer}) ->
+ %% Check if the user is logged
case ejabberd_sm:get_user_resources(LUser, LServer) of
- % If it isn't
- [] ->
- % Look for his last_activity
- case mnesia:dirty_read(last_activity, {LUser, LServer}) of
- % If it is
- % existent:
- [#last_activity{timestamp = TimeStamp}] ->
- % get his age
- Sec = TimeStamp_now - TimeStamp,
- % If he is
- if
- % younger than SecOlder:
- Sec < SecOlder ->
- % do nothing
- false;
- % older:
- true ->
- % remove the user
- ejabberd_auth:remove_user(LUser, LServer),
- true
- end;
- % nonexistent:
- [] ->
- % remove the user
- ejabberd_auth:remove_user(LUser, LServer),
- true
+ %% If it isnt
+ [] ->
+ %% Look for his last_activity
+ case mnesia:dirty_read(last_activity, {LUser, LServer}) of
+ %% If it is
+ %% existent:
+ [#last_activity{timestamp = TimeStamp}] ->
+ %% get his age
+ Sec = TimeStamp_now - TimeStamp,
+ %% If he is
+ if
+ %% younger than SecOlder:
+ Sec < SecOlder ->
+ %% do nothing
+ false;
+ %% older:
+ true ->
+ %% remove the user
+ ejabberd_auth:remove_user(LUser, LServer),
+ true
end;
- % Else
- _ ->
- % do nothing
- false
+ %% nonexistent:
+ [] ->
+ %% remove the user
+ ejabberd_auth:remove_user(LUser, LServer),
+ true
+ end;
+ %% Else
+ _ ->
+ %% do nothing
+ false
end
end,
- % Apply the function to every user in the list
- Users_removed = lists:filter(F, Users),
- {removed, length(Users_removed), Users_removed}.
+ %% Apply the function to every user in the list
+ Users_removed = lists:filter(F, Users),
+ {removed, length(Users_removed), Users_removed}.
num_active_users(Host, Days) ->
- list_last_activity(Host, true, Days).
+ list_last_activity(Host, true, Days).
-% Code based on ejabberd/src/web/ejabberd_web_admin.erl
+%% Code based on ejabberd/src/web/ejabberd_web_admin.erl
list_last_activity(Host, Integral, Days) ->
{MegaSecs, Secs, _MicroSecs} = now(),
TimeStamp = MegaSecs * 1000000 + Secs,
@@ -537,29 +590,29 @@
[{'trunc', {'/',
{'-', TimeStamp, '$1'},
86400}}]}]) of
- {'EXIT', _Reason} ->
- [];
- Vals ->
- Hist = histogram(Vals, Integral),
- if
- Hist == [] ->
- 0;
- true ->
- Left = if
- Days == infinity ->
- 0;
- true ->
- Days - length(Hist)
- end,
- Tail = if
- Integral ->
- lists:duplicate(Left, lists:last(Hist));
- true ->
- lists:duplicate(Left, 0)
- end,
- lists:nth(Days, Hist ++ Tail)
- end
- end.
+ {'EXIT', _Reason} ->
+ [];
+ Vals ->
+ Hist = histogram(Vals, Integral),
+ if
+ Hist == [] ->
+ 0;
+ true ->
+ Left = if
+ Days == infinity ->
+ 0;
+ true ->
+ Days - length(Hist)
+ end,
+ Tail = if
+ Integral ->
+ lists:duplicate(Left, lists:last(Hist));
+ true ->
+ lists:duplicate(Left, 0)
+ end,
+ lists:nth(Days, Hist ++ Tail)
+ end
+ end.
histogram(Values, Integral) ->
histogram(lists:sort(Values), Integral, 0, 0, []).
histogram([H | T], Integral, Current, Count, Hist) when Current == H ->
@@ -581,26 +634,26 @@
format_print_room(Host1, Rooms)->
- lists:foreach(
- fun({_, {Roomname, Host},_}) ->
- case Host1 of
- all ->
- io:format("~s ~s ~n", [Roomname, Host]);
- Host ->
- io:format("~s ~s ~n", [Roomname, Host]);
- _ ->
- ok
- end
- end,
- Rooms).
+ lists:foreach(
+ fun({_, {Roomname, Host},_}) ->
+ case Host1 of
+ all ->
+ io:format("~s ~s ~n", [Roomname, Host]);
+ Host ->
+ io:format("~s ~s ~n", [Roomname, Host]);
+ _ ->
+ ok
+ end
+ end,
+ Rooms).
%%----------------------------
%% Purge MUC
%%----------------------------
-% Required for muc_purge
-% Copied from mod_muc/mod_muc_room.erl
+%% Required for muc_purge
+%% Copied from mod_muc/mod_muc_room.erl
-define(DICT, dict).
-record(muc_online_room, {name_host, pid}).
-record(lqueue, {queue, len, max}).
@@ -634,103 +687,106 @@
just_created = false}).
muc_purge(Days) ->
- ServerHost = global,
- Host = global,
- muc_purge2(ServerHost, Host, Days).
+ ServerHost = global,
+ Host = global,
+ muc_purge2(ServerHost, Host, Days).
muc_purge(ServerHost, Days) ->
- Host = find_host(ServerHost),
- muc_purge2(ServerHost, Host, Days).
+ Host = find_host(ServerHost),
+ muc_purge2(ServerHost, Host, Days).
muc_purge2(ServerHost, Host, Last_allowed) ->
- Room_names = get_room_names(Host),
-
- Decide = fun(N) -> decide(N, Last_allowed) end,
- Rooms_to_delete = lists:filter(Decide, Room_names),
+ Room_names = get_room_names(Host),
- Num_rooms = length(Room_names),
- Num_rooms_to_delete = length(Rooms_to_delete),
+ Decide = fun(N) -> decide(N, Last_allowed) end,
+ Rooms_to_delete = lists:filter(Decide, Room_names),
- Rooms_to_delete_full = fill_serverhost(Rooms_to_delete, ServerHost),
+ Num_rooms = length(Room_names),
+ Num_rooms_to_delete = length(Rooms_to_delete),
- Delete = fun({N, H, SH}) ->
- mod_muc:room_destroyed(H, N, SH),
- mod_muc:forget_room(H, N)
- end,
- lists:foreach(Delete, Rooms_to_delete_full),
- {purged, Num_rooms, Num_rooms_to_delete, Rooms_to_delete}.
+ Rooms_to_delete_full = fill_serverhost(Rooms_to_delete, ServerHost),
+
+ Delete = fun({N, H, SH}) ->
+ mod_muc:room_destroyed(H, N, SH),
+ mod_muc:forget_room(H, N)
+ end,
+ lists:foreach(Delete, Rooms_to_delete_full),
+ {purged, Num_rooms, Num_rooms_to_delete, Rooms_to_delete}.
fill_serverhost(Rooms_to_delete, global) ->
- ServerHosts1 = ?MYHOSTS,
- ServerHosts2 = [ {ServerHost, find_host(ServerHost)} || ServerHost <- ServerHosts1],
- [ {Name, Host, find_serverhost(Host, ServerHosts2)} || {Name, Host} <- Rooms_to_delete];
+ ServerHosts1 = ?MYHOSTS,
+ ServerHosts2 = [ {ServerHost, find_host(ServerHost)} || ServerHost <- ServerHosts1],
+ [ {Name, Host, find_serverhost(Host, ServerHosts2)} || {Name, Host} <- Rooms_to_delete];
fill_serverhost(Rooms_to_delete, ServerHost) ->
- [ {Name, Host, ServerHost}|| {Name, Host} <- Rooms_to_delete].
+ [ {Name, Host, ServerHost}|| {Name, Host} <- Rooms_to_delete].
find_serverhost(Host, ServerHosts) ->
- {value, {ServerHost, Host}} = lists:keysearch(Host, 2, ServerHosts),
- ServerHost.
+ {value, {ServerHost, Host}} = lists:keysearch(Host, 2, ServerHosts),
+ ServerHost.
find_host(ServerHost) ->
- gen_mod:get_module_opt(ServerHost, mod_muc, host, "conference." ++ ServerHost).
+ gen_mod:get_module_opt(ServerHost, mod_muc, host, "conference." ++ ServerHost).
decide({Room_name, Host}, Last_allowed) ->
- Room_pid = get_room_pid(Room_name, Host),
+ Room_pid = get_room_pid(Room_name, Host),
- C = get_room_config(Room_pid),
- Persistent = C#config.persistent,
+ C = get_room_config(Room_pid),
+ Persistent = C#config.persistent,
- S = get_room_state(Room_pid),
- Just_created = S#state.just_created,
+ S = get_room_state(Room_pid),
+ Just_created = S#state.just_created,
- Room_users = S#state.users,
- Num_users = length(?DICT:to_list(Room_users)),
-
- History = (S#state.history)#lqueue.queue,
- Ts_now = calendar:now_to_universal_time(now()),
- Ts_uptime = element(1, erlang:statistics(wall_clock))/1000,
- {Have_history, Last} = case queue:is_empty(History) of
- true ->
- {false, Ts_uptime};
- false ->
- Last_message = queue:last(History),
- {_, _, _, Ts_last, _} = Last_message,
- Ts_diff =
- calendar:datetime_to_gregorian_seconds(Ts_now)
- - calendar:datetime_to_gregorian_seconds(Ts_last),
- {true, Ts_diff}
- end,
+ Room_users = S#state.users,
+ Num_users = length(?DICT:to_list(Room_users)),
- case {Persistent, Just_created, Num_users, Have_history, seconds_to_days(Last)} of
- {true, false, 0, _, Last_days}
- when Last_days > Last_allowed ->
- true;
- _ ->
- false
- end.
+ History = (S#state.history)#lqueue.queue,
+ Ts_now = calendar:now_to_universal_time(now()),
+ Ts_uptime = element(1, erlang:statistics(wall_clock))/1000,
+ {Have_history, Last} = case queue:is_empty(History) of
+ true ->
+ {false, Ts_uptime};
+ false ->
+ Last_message = queue:last(History),
+ {_, _, _, Ts_last, _} = Last_message,
+ Ts_diff =
+ calendar:datetime_to_gregorian_seconds(Ts_now)
+ - calendar:datetime_to_gregorian_seconds(Ts_last),
+ {true, Ts_diff}
+ end,
+
+ case {Persistent, Just_created, Num_users, Have_history, seconds_to_days(Last)} of
+ {true, false, 0, _, Last_days}
+ when Last_days > Last_allowed ->
+ true;
+ _ ->
+ false
+ end.
seconds_to_days(S) ->
- round(S) div 60*60*24.
+ round(S) div 60*60*24.
+
+uptime_seconds() ->
+ trunc(element(1, erlang:statistics(wall_clock))/1000).
get_room_names(Host) ->
- Get_room_names = fun(Room_reg, Names) ->
- case {Host, Room_reg#muc_online_room.name_host} of
- {Host, {Name1, Host}} ->
- [{Name1, Host} | Names];
- {global, {Name1, Host1}} ->
- [{Name1, Host1} | Names];
- _ ->
- Names
- end
- end,
- ets:foldr(Get_room_names, [], muc_online_room).
+ Get_room_names = fun(Room_reg, Names) ->
+ case {Host, Room_reg#muc_online_room.name_host} of
+ {Host, {Name1, Host}} ->
+ [{Name1, Host} | Names];
+ {global, {Name1, Host1}} ->
+ [{Name1, Host1} | Names];
+ _ ->
+ Names
+ end
+ end,
+ ets:foldr(Get_room_names, [], muc_online_room).
get_room_pid(Name, Host) ->
- [Room_ets] = ets:lookup(muc_online_room, {Name, Host}),
- Room_ets#muc_online_room.pid.
+ [Room_ets] = ets:lookup(muc_online_room, {Name, Host}),
+ Room_ets#muc_online_room.pid.
get_room_config(Room_pid) ->
- gen_fsm:sync_send_all_state_event(Room_pid, get_config).
+ gen_fsm:sync_send_all_state_event(Room_pid, get_config).
get_room_state(Room_pid) ->
- gen_fsm:sync_send_all_state_event(Room_pid, get_state).
+ gen_fsm:sync_send_all_state_event(Room_pid, get_state).
Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/ejabberd/F-7/sources,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- sources 2 Feb 2007 21:21:08 -0000 1.4
+++ sources 6 Sep 2007 15:06:36 -0000 1.5
@@ -1 +1 @@
-bdb39965a147506fc194d5a28117172a ejabberd-1.1.3.tar.gz
+65e9cd346f11a28afbacfe1d7be3a33b ejabberd-1.1.4.tar.gz
--- ejabberd-1.1.3-ldapfix.patch DELETED ---
- Previous message (by thread): rpms/mash/F-7 mash-multilib.patch,NONE,1.1 mash.spec,1.6,1.7
- Next message (by thread): rpms/phpMyAdmin/devel .cvsignore, 1.7, 1.8 phpMyAdmin.htaccess, 1.1, 1.2 phpMyAdmin.spec, 1.10, 1.11 sources, 1.7, 1.8
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list