added mod-watchdog (without any functions, yet)
[srvx.git] / src / mod-watchdog.c
1 /* mod-watchdog.c - Watchdog module for srvx
2  * Copyright 2003-2004 Martijn Smit and srvx Development Team
3  *
4  * This file is part of srvx.
5  *
6  * srvx is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with srvx; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
19  */
20
21 /* Adds new section to srvx.conf:
22  * "modules" {
23  *     "watchdog" {
24  *         "nick" "Watchdog";
25  *         "modes" "+iok"
26  *     };
27  *  };
28  *
29  */
30
31 #include "chanserv.h"
32 #include "conf.h"
33 #include "modcmd.h"
34 #include "saxdb.h"
35 #include "timeq.h"
36
37 #define KEY_SENT "sent"
38
39 static const struct message_entry msgtab[] = {
40     { "WDMSG_NULL", "null." },
41     { NULL, NULL }
42 };
43
44 struct badword {
45     char *badword_mask;
46     unsigned int triggered : 29;
47     unsigned int action : 3;
48 };
49
50 DECLARE_LIST(shitList, struct badword*);
51 DEFINE_LIST(shitList, struct badword*)
52
53 /* badword.action fields */
54 #define BADACTION_KICK   1
55 #define BADACTION_KILL   2
56 #define BADACTION_GLINE  3
57
58 static struct {
59     char *nick;
60     char *modes;
61 } watchdog_conf;
62
63 struct userNode *watchdog;
64 static struct module *watchdog_module;
65 static struct service *watchdog_service;
66 static struct shitList *shitlist;
67
68
69 static MODCMD_FUNC(cmd_addbad)
70 {
71     //to be continued...
72     return 1;
73 }
74
75 static MODCMD_FUNC(cmd_delbad)
76 {
77     //to be continued...
78     return 1;
79 }
80
81 static MODCMD_FUNC(cmd_editbad)
82 {
83     //to be continued...
84     return 1;
85 }
86
87 static MODCMD_FUNC(cmd_listbad)
88 {
89     //to be continued...
90     return 1;
91 }
92
93 static void
94 watchdog_channel_message(struct userNode *user, struct chanNode *chan, const char *text, struct userNode *bot, unsigned int is_notice)
95 {
96     //to be continued...
97 }
98
99 static struct badword*
100 add_badword(char *badword, unsigned int triggered, unsigned int action)
101 {
102     struct badword *badword;
103
104     badword = calloc(1, sizeof(*badword));
105     if (!badword)
106         return NULL;
107
108     badword->badword_mask = strdup(badword);
109     badword->triggered = triggered;
110     badword->action = action;
111     shitlist_append(&shitlist, badword);
112     return badword;
113 }
114
115 static void
116 delete_badword(struct badword *badword)
117 {
118     shitlist_remove(&shitlist, badword);
119     free(badword->badword_mask);
120     free(badword);
121 }
122
123 static void
124 watchdog_conf_read(void)
125 {
126     dict_t conf_node;
127     const char *str;
128
129     str = "modules/watchdog";
130     if (!(conf_node = conf_get_data(str, RECDB_OBJECT))) {
131         log_module(MS_LOG, LOG_ERROR, "config node `%s' is missing or has wrong type.", str);
132         return;
133     }
134
135     str = database_get_data(conf_node, "nick", RECDB_QSTRING);
136     if(watchdog_conf.nick && strcmp(watchdog_conf.nick, str)) {
137         //nick changed
138     }
139     watchdog_conf.nick = str;
140     
141     str = database_get_data(conf_node, "modes", RECDB_QSTRING);
142     watchdog_conf.modes = str;
143 }
144
145 static int
146 watchdog_saxdb_read_shitlist(const char *name, void *data, UNUSED_ARG(void *extra))
147 {
148     struct record_data *rd = data;
149     char *badword;
150     char *triggered, *action;
151
152      if (rd->type == RECDB_OBJECT) {
153         dict_t obj = GET_RECORD_OBJECT(rd);
154         /* new style structure */
155         badword = database_get_data(obj, KEY_BADWORD_MASK, RECDB_QSTRING);
156         triggered = database_get_data(obj, KEY_BADWORD_TRIGGERED, RECDB_QSTRING);
157         action = database_get_data(obj, KEY_BADWORD_ACTION, RECDB_QSTRING);
158
159         add_badword(badword, strtoul(triggered, NULL, 0), strtoul(action, NULL, 0));
160         return 1;
161     } else
162         return 0;
163 }
164
165 static int
166 watchdog_saxdb_read(struct dict *db)
167 {
168     struct dict *object;
169     if ((object = database_get_data(conf_db, KEY_BADWORDS, RECDB_OBJECT)))
170         dict_foreach(object, watchdog_saxdb_read_shitlist, NULL);
171 }
172
173 static int
174 watchdog_saxdb_write(struct saxdb_context *ctx)
175 {
176     struct badword *badword;
177     char str[17];
178     unsigned int id = 0, ii;
179
180     saxdb_start_record(ctx, KEY_BADWORDS, 1);
181     for (ii = 0; ii < ma->recvd.used; ++ii) {
182         badword = ma->recvd.list[ii];
183         snprintf(str, sizeof(str), "%x", id++);
184         saxdb_start_record(ctx, str, 0);
185         saxdb_write_string(ctx, KEY_BADWORD_MASK, badword->badword_mask);
186         saxdb_write_int(ctx, KEY_BADWORD_TRIGGERED, badword->triggered);
187         saxdb_write_int(ctx, KEY_BADWORD_ACTION, badword->action);
188         saxdb_end_record(ctx);
189     }
190     saxdb_end_record(ctx);
191
192     return 0;
193 }
194
195 static void
196 watchdog_cleanup(void)
197 {
198     while (shitlist.used)
199         delete_badword(shitlist.list[0]);
200     shitlist_clean(&shitlist);
201 }
202
203 int
204 watchdog_init(void)
205 {
206     MS_LOG = log_register_type("Watchdog", "file:watchdog.log");
207     conf_register_reload(watchdog_conf_read);
208     reg_exit_func(watchdog_cleanup);
209     saxdb_register("Watchdog", watchdog_saxdb_read, watchdog_saxdb_write);
210
211     const char *nick, *modes;
212     if(nick = conf_get_data("services/spamserv/nick", RECDB_QSTRING)) {
213         modes = conf_get_data("services/spamserv/modes", RECDB_QSTRING);
214         spamserv = AddLocalUser(nick, nick, NULL, "Watchdog Service", modes);
215         spamserv_service = service_register(spamserv);
216         reg_allchanmsg_func(spamserv, watchdog_channel_message);
217     }
218
219     watchdog_module = module_register("Watchdog", MS_LOG, "mod-watchdog.help", NULL);
220     modcmd_register(watchdog_module, "addbad", cmd_addbad, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
221     modcmd_register(watchdog_module, "delbad", cmd_delbad, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
222     modcmd_register(watchdog_module, "editbad", cmd_editbad, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
223     modcmd_register(watchdog_module, "listbad", cmd_listbad, 1, MODCMD_REQUIRE_AUTHED, "flags", "+oper", NULL);
224     message_register_table(msgtab);
225
226     return 1;
227 }
228
229 int
230 watchdog_finalize(void) {
231     dict_t conf_node;
232     const char *str;
233
234     str = "modules/watchdog";
235     if (!(conf_node = conf_get_data(str, RECDB_OBJECT))) {
236         log_module(MS_LOG, LOG_ERROR, "config node `%s' is missing or has wrong type.", str);
237         return 0;
238     }
239
240     str = database_get_data(conf_node, "nick", RECDB_QSTRING);
241     if (str) watchdog_conf.nick = str;
242     
243     str = database_get_data(conf_node, "modes", RECDB_QSTRING);
244     if (str) watchdog_conf.modes = str;
245     return 1;
246 }