source: trunk/ejabberd/src/mod_syslogbot.erl @ 3

Revision 3, 8.5 KB checked in by bombadil, 7 years ago (diff)

codigo del modulo para ejabberd

Line 
1-module(mod_syslogbot).
2-author('bombadil@bosqueviejo.net').
3
4-behaviour(gen_server).
5-behaviour(gen_mod).
6
7%% API
8-export([start_link/2, start/2, stop/1]).
9
10%% gen_server callbacks
11-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
12         terminate/2, code_change/3]).
13
14-include("ejabberd.hrl").
15-include("jlib.hrl").
16
17-record(state, {host, users, id, filters}).
18
19-define(PROCNAME, ejabberd_mod_syslogbot).
20
21%%====================================================================
22%% API
23%%====================================================================
24%%--------------------------------------------------------------------
25%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
26%% Description: Starts the server
27%%--------------------------------------------------------------------
28start_link(Host, Opts) ->
29    %% Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
30    gen_server:start_link({local, ?PROCNAME}, ?MODULE, [Host, Opts], []).
31
32start(Host, Opts) ->
33        application:start(inets),
34    Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
35    ChildSpec =
36        {Proc,
37         {?MODULE, start_link, [Host, Opts]},
38         temporary,
39         1000,
40         worker,
41         [?MODULE]},
42    supervisor:start_child(ejabberd_sup, ChildSpec).
43
44stop(Host) ->
45    Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
46    gen_server:call(Proc, stop),
47    supervisor:terminate_child(ejabberd_sup, Proc),
48    supervisor:delete_child(ejabberd_sup, Proc).
49
50
51%%====================================================================
52%% gen_server callbacks
53%%====================================================================
54
55%%--------------------------------------------------------------------
56%% Function: init(Args) -> {ok, State} |
57%%                         {ok, State, Timeout} |
58%%                         ignore               |
59%%                         {stop, Reason}
60%% Description: Initiates the server
61%%--------------------------------------------------------------------
62init([Host, Opts]) ->
63    MyHost = gen_mod:get_opt_host(Host, Opts, "syslogbot.@HOST@"),
64    MyOpts = gen_mod:get_opt(users, Opts),
65    ejabberd_router:register_route(MyHost),
66    {ok, #state{host = MyHost, users = MyOpts, id = "0001", filters=[]}}.
67
68%%--------------------------------------------------------------------
69%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
70%%                                      {reply, Reply, State, Timeout} |
71%%                                      {noreply, State} |
72%%                                      {noreply, State, Timeout} |
73%%                                      {stop, Reason, Reply, State} |
74%%                                      {stop, Reason, State}
75%% Description: Handling call messages
76%%--------------------------------------------------------------------
77handle_call(stop, _From, State) ->
78    {stop, normal, ok, State}.
79
80%%--------------------------------------------------------------------
81%% Function: handle_cast(Msg, State) -> {noreply, State} |
82%%                                      {noreply, State, Timeout} |
83%%                                      {stop, Reason, State}
84%% Description: Handling cast messages
85%%--------------------------------------------------------------------
86handle_cast({filter, Id, Params}, State) ->
87    Filters = case proplists:get_value(Id, State#state.filters) of
88        undefined -> State#state.filters;
89        Value -> State#state.filters -- [{Id, Value}]
90    end,
91    error_logger:info_msg("Filtro fijado a: ~p~n", [Params]),
92    {noreply, State#state{filters=Filters ++ [{Id, Params}]}};
93
94handle_cast({syslog, _Severity, _Facility, DateTime, Machine, Message} = _Msg, State) ->
95    MsgTxt = io_lib:format("~s ~s ~s", [DateTime, Machine, Message]),
96    error_logger:info_msg("Mensaje para ~p: [~s]~n", [State#state.users, MsgTxt]),
97    {noreply, send_msg_all(State#state.users, Machine, MsgTxt, State)};
98
99handle_cast(Msg, State) ->
100    error_logger:info_msg("Mensaje no reconocido: ~p~n", [Msg]),
101    {noreply, State}.
102
103%%--------------------------------------------------------------------
104%% Function: handle_info(Info, State) -> {noreply, State} |
105%%                                       {noreply, State, Timeout} |
106%%                                       {stop, Reason, State}
107%% Description: Handling all non call/cast messages
108%%--------------------------------------------------------------------
109handle_info({route, From, To, Packet}, State) ->
110        {jid, Id, _, _, _, _, _} = From,
111        Packet2 = case Packet of
112                ["status "|Pin] ->
113                        [Pin|" active"];
114                {xmlelement,"message",Q1,[{xmlelement,"body",Subject,[{xmlcdata,Body}]}|Q2]} ->
115                        {xmlelement,"message",Q1,[{xmlelement,"body",Subject,[{xmlcdata, get_body(Id, Body, State)}]}|Q2]};
116        {xmlelement,"message",Q1,[_Active,{xmlelement,"body",Subject,[{xmlcdata,Body}]}|Q2]} ->
117            {xmlelement,"message",Q1,[{xmlelement,"body",Subject,[{xmlcdata, get_body(Id, Body, State)}]}|Q2]};
118                P ->
119            error_logger:info_msg("Mensaje (diferente): ~p~n", [P]),
120                        P
121        end,
122    ejabberd_router:route(To, From, Packet2),
123    {noreply, State};
124
125handle_info(Info, State) ->
126    io:format("Recibida Info: ~p~n", [Info]),
127    {noreply, State}.
128
129%%--------------------------------------------------------------------
130%% Function: terminate(Reason, State) -> void()
131%% Description: This function is called by a gen_server when it is about to
132%% terminate. It should be the opposite of Module:init/1 and do any necessary
133%% cleaning up. When it returns, the gen_server terminates with Reason.
134%% The return value is ignored.
135%%--------------------------------------------------------------------
136terminate(_Reason, State) ->
137    ejabberd_router:unregister_route(State#state.host),
138    ok.
139
140%%--------------------------------------------------------------------
141%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
142%% Description: Convert process state when code is changed
143%%--------------------------------------------------------------------
144code_change(_OldVsn, State, _Extra) ->
145    {ok, State}.
146
147%=====================================================================
148% Internal functions
149%=====================================================================
150
151send_msg(Pin, Machine, MsgList, State) ->
152    Service = State#state.host,
153    Filter = proplists:get_value(Pin, State#state.filters),
154    error_logger:info_msg("Filter (~p): ~p~n", [Pin, Filter]),
155    if
156        (Filter =:= undefined) or (Filter =:= Machine) ->
157            [_,Host] = string:tokens(Service, "."),
158            case ejabberd_sm:get_user_info(Pin, Host, "Jet") of
159                offline -> State; %% no se hace nada para este caso.
160            _ ->
161                JId_src = {jid,[],Service,[],[],Service,[]},
162                JId_dst = {jid,Pin,Host,"Jet",Pin,Host,"Jet"},
163                IdNum = get_id(State#state.id),
164                Id = {"id", IdNum},
165                From = {"from", Service},
166                TypeMsg = {"type", "chat"},
167                To = {"to", Pin ++ "@" ++ Host ++ "/Jet"},
168                Msg = list_to_binary(MsgList),
169                ejabberd_router:route(JId_src, JId_dst, {xmlelement,"message",[Id, To, From, TypeMsg], [{xmlelement,"body",[],[{xmlcdata,Msg}]}, {xmlelement,"thread",[],[{xmlcdata,<<"QOR8C2">>}]}]}),
170                State#state{id=IdNum}
171            end;
172        true ->
173            error_logger:info_msg("Mensaje ignorado por filtro [~s]~n", [Filter]),
174            State
175    end.
176
177send_msg_all([Pin|Pines], Machine, MsgList, State) ->
178    send_msg_all(Pines, Machine, MsgList, send_msg(Pin, Machine, MsgList, State));
179
180send_msg_all([], _, _, State) ->
181    State.
182
183%% genera el ID para el mensaje
184get_id( [$9,$9,$9,$9] ) ->
185    "0000";
186get_id( [N1,$9,$9,$9] ) ->
187    [N1+1,$0,$0,$0];
188get_id( [N1,N2,$9,$9] ) ->
189    [N1,N2+1,$0,$0];
190get_id( [N1,N2,N3,$9] ) ->
191    [N1,N2,N3+1,$0];
192get_id( [N1,N2,N3,N4] ) ->
193    [N1,N2,N3,N4+1].
194
195get_body(Id, Body, State) ->
196    case erlang:binary_to_list(Body) of
197        "help" ->
198            io_lib:format("
199esyslog - ejabberd module
200
201commands:
202  remove filters      - removes all filters
203  show filters        - show all filters
204  filter machine XXX  - filter by machine XXX
205
206", []);
207        "remove filter" ++ _ ->
208            gen_server:cast(?PROCNAME, {filter, Id, undefined}),
209            io_lib:format("Removed filters.", []);
210        "show filter" ++ _ ->
211            io_lib:format("Filters: ~p", [proplists:get_value(Id, State#state.filters)]);
212        "filter machine " ++ Params ->
213            gen_server:cast(?PROCNAME, {filter, Id, Params}),
214            io_lib:format("Filters: ~p", [Params]);
215        BodyBin ->
216            error_logger:info_msg("Mensaje: ~p~n", [BodyBin]),
217            BodyBin
218    end.
Note: See TracBrowser for help on using the repository browser.