/[smecontribs]/rpms/ejabberd/contribs7/mod_ctlextra.erl
ViewVC logotype

Diff of /rpms/ejabberd/contribs7/mod_ctlextra.erl

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

Revision 1.1 by slords, Thu May 8 19:50:18 2008 UTC Revision 1.4 by slords, Mon Aug 24 18:19:21 2009 UTC
# Line 3  Line 3 
3  %%% Author  : Badlop <badlop@ono.com>  %%% Author  : Badlop <badlop@ono.com>
4  %%% Purpose : Adds more commands to ejabberd_ctl  %%% Purpose : Adds more commands to ejabberd_ctl
5  %%% Created : 30 Nov 2006 by Badlop <badlop@ono.com>  %%% Created : 30 Nov 2006 by Badlop <badlop@ono.com>
6  %%% Id      : $Id$  %%% Id      : $Id: mod_ctlextra.erl 873 2009-02-09 18:30:21Z badlop $
7  %%%----------------------------------------------------------------------  %%%----------------------------------------------------------------------
8    
9  -module(mod_ctlextra).  -module(mod_ctlextra).
10  -author('badlop@ono.com').  -author('badlop@ono.com').
 -vsn('$Revision$ ').  
11    
12  -behaviour(gen_mod).  -behaviour(gen_mod).
13    
# Line 23  Line 22 
22  -include("jlib.hrl").  -include("jlib.hrl").
23  -include("mod_roster.hrl").  -include("mod_roster.hrl").
24    
25  -record(session, {sid, usr, us, priority}). % copied from ejabberd_sm.erl  %% Copied from ejabberd_sm.erl
26    -record(session, {sid, usr, us, priority, info}).
27    
28    -compile(export_all).
29    
30    %%-------------
31    %% gen_mod
32    %%-------------
33    
34  start(Host, _Opts) ->  start(Host, _Opts) ->
35      ejabberd_ctl:register_commands([      ejabberd_ctl:register_commands(commands_global(), ?MODULE, ctl_process),
36                                      {"compile file", "recompile and reload file"},      ejabberd_ctl:register_commands(Host, commands_host(), ?MODULE, ctl_process).
                                     {"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@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@server to group on host"},  
                                     {"srg-user-del user server group host", "delete user@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@server2 to user1@server1's roster"},  
                                     %%{"", "subs= none, from, to or both"},  
                                     %%{"", "example: add-roster peter localhost mike server.com MiKe Employees both"},  
                                     %%{"", "will add mike@server.com to peter@localhost roster"},  
                                     {"rem-rosteritem user1 server1 user2 server2", "Remove user2@server2 from user1@server1's roster"},  
                                     {"pushroster file user server", "push template roster in file to user@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.  
   
 stop(_Host) ->  
     ok.  
   
   
 ctl_process(_Val, ["blo"]) ->  
     FResources = "eeeaaa aaa",  
     io:format("~s", [FResources]),  
     ?STATUS_SUCCESS;  
37    
38  ctl_process(_Val, ["delete-older-messages", Days]) ->  stop(Host) ->
39      mod_offline:remove_old_messages(list_to_integer(Days)),      ejabberd_ctl:unregister_commands(commands_global(), ?MODULE, ctl_process),
40      ?STATUS_SUCCESS;      ejabberd_ctl:unregister_commands(Host, commands_host(), ?MODULE, ctl_process).
41    
42    commands_global() ->
43        [
44         {"compile file", "recompile and reload file"},
45         {"load-config file", "load config from file"},
46         {"remove-node nodename", "remove an ejabberd node from the database"},
47    
48         %% ejabberd_auth
49         {"delete-older-users days", "delete users that have not logged in the last 'days'"},
50         {"delete-older-users-vhost host days", "delete users that not logged in last 'days' in 'host'"},
51         {"set-password user server password", "set password to user@server"},
52    
53         %% ejd2odbc
54         {"export2odbc server output", "export Mnesia tables on server to files on output directory"},
55    
56         %% mod_shared_roster
57         {"srg-create group host name description display", "create the group with options"},
58         {"srg-delete group host", "delete the group"},
59         {"srg-user-add user server group host", "add user@server to group on host"},
60         {"srg-user-del user server group host", "delete user@server from group on host"},
61         {"srg-list-groups host", "list the shared roster groups from host"},
62         {"srg-get-info group host", "get info of a specific group on host"},
63    
64         %% mod_vcard
65         {"vcard-get user host data [data2]", "get data from the vCard of the user"},
66         {"vcard-set user host data [data2] content", "set data to content on the vCard"},
67    
68         %% mod_announce
69         %% announce_send_online host message
70         %% announce_send_all host, message
71    
72         %% mod_roster
73         {"add-rosteritem user1 server1 user2 server2 nick group subs", "Add user2@server2 to user1@server1's roster"},
74         %%{"", "subs= none, from, to or both"},
75         %%{"", "example: add-roster peter localhost mike server.com MiKe Employees both"},
76         %%{"", "will add mike@server.com to peter@localhost roster"},
77         {"rem-rosteritem user1 server1 user2 server2", "Remove user2@server2 from user1@server1's roster"},
78         {"rosteritem-purge [options]", "Purge all rosteritems that match filtering options"},
79         {"pushroster file user server", "push template roster in file to user@server"},
80         {"pushroster-all file", "push template roster in file to all those users"},
81         {"push-alltoall server group", "adds all the users to all the users in Group"},
82    
83         {"status-list status", "list the logged users with status"},
84         {"status-num status", "number of logged users with status"},
85    
86         {"stats registeredusers", "number of registered users"},
87         {"stats onlineusers", "number of logged users"},
88         {"stats onlineusersnode", "number of logged users in the ejabberd node"},
89         {"stats uptime-seconds", "uptime of ejabberd node in seconds"},
90    
91         %% misc
92         {"get-cookie", "get the Erlang cookie of this node"},
93         {"killsession user server resource", "kill a user session"}
94        ].
95    
96    commands_host() ->
97        [
98         %% mod_last
99         {"num-active-users days", "number of users active in the last 'days'"},
100         {"status-list status", "list the logged users with status"},
101         {"status-num status", "number of logged users with status"},
102         {"stats registeredusers", "number of registered users"},
103         {"stats onlineusers", "number of logged users"},
104    
105         %% misc
106         {"ban-account username [reason]", "ban account: kick sessions and change password"}
107        ].
108    
109    
110    %%-------------
111    %% Commands global
112    %%-------------
113    
114  ctl_process(_Val, ["delete-older-users", Days]) ->  ctl_process(_Val, ["delete-older-users", Days]) ->
115      {removed, N, UR} = delete_older_users(list_to_integer(Days)),      {removed, N, UR} = delete_older_users(list_to_integer(Days)),
116      io:format("Deleted ~p users: ~p~n", [N, UR]),      io:format("Deleted ~p users: ~p~n", [N, UR]),
117      ?STATUS_SUCCESS;      ?STATUS_SUCCESS;
118    
119    ctl_process(_Val, ["delete-older-users-vhost", Host, Days]) ->
120        {removed, N, UR} = delete_older_users_vhost(Host, list_to_integer(Days)),
121        io:format("Deleted ~p users: ~p~n", [N, UR]),
122        ?STATUS_SUCCESS;
123    
124  ctl_process(_Val, ["export2odbc", Server, Output]) ->  ctl_process(_Val, ["export2odbc", Server, Output]) ->
125      Tables = [      Tables = [
126                {export_last, last},                {export_last, last},
# Line 126  ctl_process(_Val, ["export2odbc", Server Line 133  ctl_process(_Val, ["export2odbc", Server
133      Export = fun({TableFun, Table}) ->      Export = fun({TableFun, Table}) ->
134                       Filename = filename:join([Output, atom_to_list(Table)++".txt"]),                       Filename = filename:join([Output, atom_to_list(Table)++".txt"]),
135                       io:format("Trying to export Mnesia table '~p' on server '~s' to file '~s'~n", [Table, Server, Filename]),                       io:format("Trying to export Mnesia table '~p' on server '~s' to file '~s'~n", [Table, Server, Filename]),
136                       catch ejd2odbc:TableFun(Server, Filename)                       Res = (catch ejd2odbc:TableFun(Server, Filename)),
137                         io:format("  Result: ~p~n", [Res])
138               end,               end,
139      lists:foreach(Export, Tables),      lists:foreach(Export, Tables),
140      ?STATUS_SUCCESS;      ?STATUS_SUCCESS;
# Line 163  ctl_process(_Val, ["remove-node", Node]) Line 171  ctl_process(_Val, ["remove-node", Node])
171      mnesia:del_table_copy(schema, list_to_atom(Node)),      mnesia:del_table_copy(schema, list_to_atom(Node)),
172      ?STATUS_SUCCESS;      ?STATUS_SUCCESS;
173    
174  ctl_process(_Val, ["srg-create", Group, Host, Name, Description, Display]) ->  ctl_process(_Val, ["srg-create" | Parameters]) ->
175            [Group, Host, Name, Description, Display] = group_parameters(Parameters, "'"),
176      Opts = [{name, Name}, {displayed_groups, [Display]}, {description, Description}],      Opts = [{name, Name}, {displayed_groups, [Display]}, {description, Description}],
177      {atomic, ok} = mod_shared_roster:create_group(Host, Group, Opts),      {atomic, ok} = mod_shared_roster:create_group(Host, Group, Opts),
178      ?STATUS_SUCCESS;      ?STATUS_SUCCESS;
# Line 180  ctl_process(_Val, ["srg-user-del", User, Line 189  ctl_process(_Val, ["srg-user-del", User,
189      {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),
190      ?STATUS_SUCCESS;      ?STATUS_SUCCESS;
191    
192  ctl_process(_Val, ["muc-purge", Days]) ->  ctl_process(_Val, ["srg-list-groups", Host]) ->
193      {purged, Num_total, Num_purged, Names_purged} = muc_purge(list_to_integer(Days)),      lists:foreach(
194      io:format("Purged ~p chatrooms from a total of ~p on the server:~n~p~n", [Num_purged, Num_total, Names_purged]),        fun(SrgGroup) ->
195                  io:format("~s~n",[SrgGroup])
196          end,
197          lists:sort(mod_shared_roster:list_groups(Host))),
198      ?STATUS_SUCCESS;      ?STATUS_SUCCESS;
199    
200  ctl_process(_Val, ["muc-online-rooms"]) ->  ctl_process(_Val, ["srg-get-info", Group, Host]) ->
201      format_print_room(all, ets:tab2list(muc_online_room)),      Opts = mod_shared_roster:get_group_opts(Host,Group),
202        [io:format("~s: ~p~n", [Title, Value]) || {Title , Value} <- Opts],
203        
204        Members = mod_shared_roster:get_group_explicit_users(Host,Group),
205        Members_string = [ " " ++ jlib:jid_to_string(jlib:make_jid(MUser, MServer, ""))
206                           || {MUser, MServer} <- Members],
207        io:format("members:~s~n", [Members_string]),
208        
209      ?STATUS_SUCCESS;      ?STATUS_SUCCESS;
210    
211  ctl_process(_Val, ["add-rosteritem", LocalUser, LocalServer, RemoteUser, RemoteServer, Nick, Group, Subs]) ->  ctl_process(_Val, ["add-rosteritem", LocalUser, LocalServer, RemoteUser, RemoteServer, Nick, Group, Subs]) ->
# Line 217  ctl_process(_Val, ["rem-rosteritem", Loc Line 236  ctl_process(_Val, ["rem-rosteritem", Loc
236              ?STATUS_BADRPC              ?STATUS_BADRPC
237      end;      end;
238    
239    ctl_process(_Val, ["rosteritem-purge"]) ->
240        io:format("Rosteritems that match all the filtering will be removed.~n"),
241        io:format("Options for filtering:~n"),
242        io:format("~n"),
243        io:format("  -subs none|from|to|both~n"),
244        io:format("       Subscription type. By default all values~n"),
245        io:format("~n"),
246        io:format("  -ask none|out|in~n"),
247        io:format("       Pending subscription. By default all values~n"),
248        io:format("~n"),
249        io:format("  -user JID~n"),
250        io:format("       The JID of the local user.~n"),
251        io:format("       Can use these globs: *, ? and [...].~n"),
252        io:format("       By default it is: * *@*~n"),
253        io:format("~n"),
254        io:format("  -contact JID~n"),
255        io:format("       Similar to 'user', but for the contact JID.~n"),
256        io:format("~n"),
257        io:format("Example:~n"),
258        io:format("  ejabberdctl rosteritem-purge -subs none from to -ask out in -contact *@*icq*~n"),
259        io:format("~n"),
260        ?STATUS_SUCCESS;
261    ctl_process(_Val, ["rosteritem-purge" | Options_list]) ->
262        Options_prop_list = lists:foldl(
263                              fun(O, R) ->
264                                      case O of
265                                          [$- | K] ->
266                                              [{K, []} | R];
267                                          V ->
268                                              [{K, Vs} | RT] = R,
269                                              [{K, [V|Vs]} | RT]
270                                      end
271                              end,
272                              [],
273                              Options_list),
274        
275        Subs = [list_to_atom(S)
276                || S <- proplists:get_value("subs",
277                                            Options_prop_list,
278                                            ["none", "from", "to", "both"])],
279        Asks = [list_to_atom(S)
280                || S <-
281                       proplists:get_value("ask",
282                                           Options_prop_list,
283                                           ["none", "out", "in"])],
284        User = proplists:get_value("user", Options_prop_list, ["*", "*@*"]),
285        Contact = proplists:get_value("contact", Options_prop_list, ["*", "*@*"]),
286        
287        case rosteritem_purge({Subs, Asks, User, Contact}) of
288            {atomic, ok} ->
289                ?STATUS_SUCCESS;
290            {error, Reason} ->
291                io:format("Error purging rosteritems: ~p~n",
292                          [Reason]),
293                ?STATUS_ERROR;
294            {badrpc, Reason} ->
295                io:format("BadRPC purging rosteritems: ~p~n",
296                          [Reason]),
297                ?STATUS_BADRPC
298        end;
299    
300  ctl_process(_Val, ["pushroster", File, User, Server]) ->  ctl_process(_Val, ["pushroster", File, User, Server]) ->
301      case pushroster(File, User, Server) of      case pushroster(File, User, Server) of
302          ok ->          ok ->
# Line 276  ctl_process(_Val, ["load-config", Path]) Line 356  ctl_process(_Val, ["load-config", Path])
356  ctl_process(_Val, ["stats", Stat]) ->  ctl_process(_Val, ["stats", Stat]) ->
357      Res = case Stat of      Res = case Stat of
358                "uptime-seconds" -> uptime_seconds();                "uptime-seconds" -> uptime_seconds();
359                "registeredusers" -> mnesia:table_info(passwd, size);                "registeredusers" -> length(ejabberd_auth:dirty_get_registered_users());
360                "onlineusers" -> mnesia:table_info(session, size)                "onlineusersnode" -> length(ejabberd_sm:dirty_get_my_sessions_list());
361                  "onlineusers" -> length(ejabberd_sm:dirty_get_sessions_list())
362            end,            end,
363      io:format("~p~n", [Res]),      io:format("~p~n", [Res]),
364      ?STATUS_SUCCESS;      ?STATUS_SUCCESS;
# Line 292  ctl_process(_Val, ["get-cookie"]) -> Line 373  ctl_process(_Val, ["get-cookie"]) ->
373      io:format("~s~n", [atom_to_list(erlang:get_cookie())]),      io:format("~s~n", [atom_to_list(erlang:get_cookie())]),
374      ?STATUS_SUCCESS;      ?STATUS_SUCCESS;
375    
376  ctl_process(_Val, ["killsession", User, Server, Resource]) ->  ctl_process(_Val, ["killsession", User, Server, Resource | Tail]) ->
377      ejabberd_router:route(      kick_session(User, Server, Resource, prepare_reason(Tail)),
       jlib:make_jid("", "", ""),  
       jlib:make_jid(User, Server, Resource),  
       {xmlelement, "broadcast", [], [{exit, "killed"}]}),  
378      ?STATUS_SUCCESS;      ?STATUS_SUCCESS;
379    
380  ctl_process(Val, _Args) ->  ctl_process(Val, _Args) ->
381      Val.      Val.
382    
383    
384  ctl_process(_Val, Host, ["muc-purge", Days]) ->  %%-------------
385      {purged, Num_total, Num_purged, Names_purged} = muc_purge(Host, list_to_integer(Days)),  %% Commands vhost
386      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;  
387    
388  ctl_process(_Val, Host, ["num-active-users", Days]) ->  ctl_process(_Val, Host, ["num-active-users", Days]) ->
389      Number = num_active_users(Host, list_to_integer(Days)),      Number = num_active_users(Host, list_to_integer(Days)),
# Line 336  ctl_process(_Val, Host, ["status-list", Line 408  ctl_process(_Val, Host, ["status-list",
408      [ io:format("~s@~s ~s ~p \"~s\"~n", [U, S, R, P, St]) || {U, S, R, P, St} <- Res],      [ io:format("~s@~s ~s ~p \"~s\"~n", [U, S, R, P, St]) || {U, S, R, P, St} <- Res],
409      ?STATUS_SUCCESS;      ?STATUS_SUCCESS;
410    
411    ctl_process(_Val, Host, ["ban-account", User | Tail]) ->
412        ban_account(User, Host, prepare_reason(Tail)),
413        ?STATUS_SUCCESS;
414    
415  ctl_process(Val, _Host, _Args) ->  ctl_process(Val, _Host, _Args) ->
416      Val.      Val.
417    
418    
419  %%-------------  %%-------------
420  %% UTILS  %% Utils
421  %%-------------  %%-------------
422    
423    uptime_seconds() ->
424        trunc(element(1, erlang:statistics(wall_clock))/1000).
425    
426  get_status_list(Host, Status_required) ->  get_status_list(Host, Status_required) ->
427      %% Get list of all logged users      %% Get list of all logged users
428      Sessions = ejabberd_sm:dirty_get_my_sessions_list(),      Sessions = ejabberd_sm:dirty_get_my_sessions_list(),
# Line 418  route_rosteritem(LocalUser, LocalServer, Line 497  route_rosteritem(LocalUser, LocalServer,
497      Packet = {xmlelement, "iq", [{"type", "set"}, {"to", ToS}], [Query]},      Packet = {xmlelement, "iq", [{"type", "set"}, {"to", ToS}], [Query]},
498      ejabberd_router:route(LJID, LJID, Packet).      ejabberd_router:route(LJID, LJID, Packet).
499    
500    
501    %%-----------------------------
502    %% Ban user
503    %%-----------------------------
504    
505    ban_account(User, Server, Reason) ->
506        kick_sessions(User, Server, Reason),
507        set_random_password(User, Server, Reason).
508    
509    kick_sessions(User, Server, Reason) ->
510        lists:map(
511          fun(Resource) ->
512                  kick_session(User, Server, Resource, Reason)
513          end,
514          get_resources(User, Server)).
515    
516    kick_session(User, Server, Resource, Reason) ->
517        ejabberd_router:route(
518          jlib:make_jid("", "", ""),
519          jlib:make_jid(User, Server, Resource),
520          {xmlelement, "broadcast", [], [{exit, Reason}]}).
521    
522    get_resources(User, Server) ->
523        lists:map(
524          fun(Session) ->
525                  element(3, Session#session.usr)
526          end,
527          get_sessions(User, Server)).
528    
529    get_sessions(User, Server) ->
530        LUser = jlib:nodeprep(User),
531        LServer = jlib:nameprep(Server),
532        Sessions =  mnesia:dirty_index_read(session, {LUser, LServer}, #session.us),
533        true = is_list(Sessions),
534        Sessions.
535    
536    set_random_password(User, Server, Reason) ->
537        NewPass = build_random_password(Reason),
538        set_password(User, Server, NewPass).
539    
540    build_random_password(Reason) ->
541        Date = jlib:timestamp_to_iso(calendar:universal_time()),
542        RandomString = randoms:get_string(),
543        "BANNED_ACCOUNT--" ++ Date ++ "--" ++ RandomString ++ "--" ++ Reason.
544    
545    set_password(User, Server, Password) ->
546        {atomic, ok} = ejabberd_auth:set_password(User, Server, Password).
547    
548    prepare_reason([]) ->
549        "Kicked by administrator";
550    prepare_reason([Reason]) ->
551        Reason;
552    prepare_reason(StringList) ->
553        string:join(StringList, "_").
554    
555    
556    %%-----------------------------
557    %% Purge roster items
558    %%-----------------------------
559    
560    rosteritem_purge(Options) ->
561        Num_rosteritems = mnesia:table_info(roster, size),
562        io:format("There are ~p roster items in total.~n", [Num_rosteritems]),
563        Key = mnesia:dirty_first(roster),
564        ok = rip(Key, Options, {0, Num_rosteritems, 0, 0}),
565        {atomic, ok}.
566    
567    rip('$end_of_table', _Options, Counters) ->
568        print_progress_line(Counters),
569        ok;
570    rip(Key, Options, {Pr, NT, NV, ND}) ->
571        Key_next = mnesia:dirty_next(roster, Key),
572        ND2 = case decide_rip(Key, Options) of
573                  true ->
574                      mnesia:dirty_delete(roster, Key),
575                      ND+1;
576                  false ->
577                      ND
578              end,
579        NV2 = NV+1,
580        Pr2 = print_progress_line({Pr, NT, NV2, ND2}),
581        rip(Key_next, Options, {Pr2, NT, NV2, ND2}).
582    
583    print_progress_line({Pr, NT, NV, ND}) ->
584        Pr2 = trunc((NV/NT)*100),
585        case Pr == Pr2 of
586            true ->
587                ok;
588            false ->
589                io:format("Progress ~p% - visited ~p - deleted ~p~n", [Pr2, NV, ND])
590        end,
591        Pr2.
592    
593    decide_rip(Key, {Subs, Asks, User, Contact}) ->
594        case catch mnesia:dirty_read(roster, Key) of
595            [RI] ->
596                lists:member(RI#roster.subscription, Subs)
597                    andalso lists:member(RI#roster.ask, Asks)
598                    andalso decide_rip_jid(RI#roster.us, User)
599                    andalso decide_rip_jid(RI#roster.jid, Contact);
600            _ ->
601                false
602        end.
603    
604    %% Returns true if the server of the JID is included in the servers
605    decide_rip_jid({UName, UServer, _UResource}, Match_list) ->
606        decide_rip_jid({UName, UServer}, Match_list);
607    decide_rip_jid({UName, UServer}, Match_list) ->
608        lists:any(
609          fun(Match_string) ->
610                  MJID = jlib:string_to_jid(Match_string),
611                  MName = MJID#jid.luser,
612                  MServer = MJID#jid.lserver,
613                  Is_server = is_glob_match(UServer, MServer),
614                  case MName of
615                      [] when UName == [] ->
616                          Is_server;
617                      [] ->
618                          false;
619                      _ ->
620                          Is_server
621                              andalso is_glob_match(UName, MName)
622                  end
623          end,
624          Match_list).
625    
626    %% Copied from ejabberd-2.0.0/src/acl.erl
627    is_regexp_match(String, RegExp) ->
628        case regexp:first_match(String, RegExp) of
629            nomatch ->
630                false;
631            {match, _, _} ->
632                true;
633            {error, ErrDesc} ->
634                io:format(
635                  "Wrong regexp ~p in ACL: ~p",
636                  [RegExp, lists:flatten(regexp:format_error(ErrDesc))]),
637                false
638        end.
639    is_glob_match(String, Glob) ->
640        is_regexp_match(String, regexp:sh_to_awk(Glob)).
641    
642    
643    %%-----------------------------
644    %% Push Roster from file
645    %%-----------------------------
646    
647  pushroster(File, User, Server) ->  pushroster(File, User, Server) ->
648      {ok, [Roster]} = file:consult(File),      {ok, [Roster]} = file:consult(File),
649      subscribe_roster({User, Server, "", User}, Roster).      subscribe_roster({User, Server, "", User}, Roster).
# Line 525  update_vcard_els(Data, Content, Els1) -> Line 751  update_vcard_els(Data, Content, Els1) ->
751  -record(last_activity, {us, timestamp, status}).  -record(last_activity, {us, timestamp, status}).
752    
753  delete_older_users(Days) ->  delete_older_users(Days) ->
754        %% Get the list of registered users
755        Users = ejabberd_auth:dirty_get_registered_users(),
756        delete_older_users(Days, Users).
757    
758    delete_older_users_vhost(Host, Days) ->
759        %% Get the list of registered users
760        Users = ejabberd_auth:get_vh_registered_users(Host),
761        delete_older_users(Days, Users).
762    
763    delete_older_users(Days, Users) ->
764      %% Convert older time      %% Convert older time
765      SecOlder = Days*24*60*60,      SecOlder = Days*24*60*60,
766    
# Line 532  delete_older_users(Days) -> Line 768  delete_older_users(Days) ->
768      {MegaSecs, Secs, _MicroSecs} = now(),      {MegaSecs, Secs, _MicroSecs} = now(),
769      TimeStamp_now = MegaSecs * 1000000 + Secs,      TimeStamp_now = MegaSecs * 1000000 + Secs,
770    
     %% Get the list of registered users  
     Users = ejabberd_auth:dirty_get_registered_users(),  
   
771      %% For a user, remove if required and answer true      %% For a user, remove if required and answer true
772      F = fun({LUser, LServer}) ->      F = fun({LUser, LServer}) ->
773                  %% Check if the user is logged                  %% Check if the user is logged
# Line 632  histogram([], _Integral, _Current, Count Line 865  histogram([], _Integral, _Current, Count
865              lists:reverse(Hist)              lists:reverse(Hist)
866      end.      end.
867    
868    group_parameters(Ps, [Char]) ->
869  format_print_room(Host1, Rooms)->          {none, Grouped_Ps} = lists:foldl(
870      lists:foreach(                  fun(P, {State, Res}) ->
871        fun({_, {Roomname, Host},_}) ->                          case State of
872                case Host1 of                                  none ->
873                    all ->                                          case P of
874                        io:format("~s ~s ~n", [Roomname, Host]);                                                  [Char | PTail]->
875                    Host ->                                                          {building, [PTail | Res]};
876                        io:format("~s ~s ~n", [Roomname, Host]);                                                  _ ->
877                    _ ->                                                          {none, [P | Res]}
878                        ok                                          end;
879                end                                  building ->
880        end,                                          [ResHead | ResTail] = Res,
881        Rooms).                                          case lists:last(P) of
882                                                    Char ->
883                                                            P2 = lists:sublist(P, length(P)-1),
884  %%----------------------------                                                          {none, [ResHead ++ " " ++ P2 | ResTail]};
885  %% Purge MUC                                                  _ ->
886  %%----------------------------                                                          {building, [ResHead ++ " " ++ P | ResTail]}
887                                            end
888  %% Required for muc_purge                          end
889  %% Copied from mod_muc/mod_muc_room.erl                  end,
890  -define(DICT, dict).                  {none, []},
891  -record(muc_online_room, {name_host, pid}).                  Ps),
892  -record(lqueue, {queue, len, max}).          lists:reverse(Grouped_Ps).
 -record(config, {title = "",  
                  allow_change_subj = true,  
                  allow_query_users = true,  
                  allow_private_messages = true,  
                  public = true,  
                  public_list = true,  
                  persistent = false,  
                  moderated = false, % TODO  
                  members_by_default = true,  
                  members_only = false,  
                  allow_user_invites = false,  
                  password_protected = false,  
                  password = "",  
                  anonymous = true,  
                  logging = false  
                 }).  
 -record(state, {room,  
                 host,  
                 server_host,  
                 access,  
                 jid,  
                 config = #config{},  
                 users,  
                 affiliations,  
                 history,  
                 subject = "",  
                 subject_author = "",  
                 just_created = false}).  
   
 muc_purge(Days) ->  
     ServerHost = global,  
     Host = global,  
     muc_purge2(ServerHost, Host, Days).  
   
 muc_purge(ServerHost, 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),  
   
     Num_rooms = length(Room_names),  
     Num_rooms_to_delete = length(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];  
 fill_serverhost(Rooms_to_delete, ServerHost) ->  
     [ {Name, Host, ServerHost}|| {Name, Host} <- Rooms_to_delete].  
   
 find_serverhost(Host, ServerHosts) ->  
     {value, {ServerHost, Host}} = lists:keysearch(Host, 2, ServerHosts),  
     ServerHost.  
   
 find_host(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),  
   
     C = get_room_config(Room_pid),  
     Persistent = C#config.persistent,  
   
     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,  
   
     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.  
   
 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_pid(Name, Host) ->  
     [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).  
   
 get_room_state(Room_pid) ->  
     gen_fsm:sync_send_all_state_event(Room_pid, get_state).  


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed