1 /*
2  * Copyright (C) 2000,2001  Florian Sander
3  *
4  * This program is free software; you can redistribute it under the
5  * terms of the GNU General Public License as published by the Free
6  * Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * $Id: gseen.c,v 1.1.0 2004/03/20 12:36:23 [Xp-AvR] Exp $
15  */
16 
17 #define MAKING_GSEEN
18 #define MODULE_NAME "gseen"
19 #define MODULE_VERSION "1.1.0"
20 #define MODULE_NUMVERSION 10100
21 #include "../module.h"
22 #include "../irc.mod/irc.h"
23 #include "../server.mod/server.h"
24 #include "../channels.mod/channels.h"
25 #include <stdlib.h>
26 #include <sys/stat.h>
27 #include <time.h>
28 
29 #undef global
30 static Function *global = NULL, *irc_funcs = NULL, *server_funcs = NULL, *channels_funcs = NULL;
31 
32 #ifndef Context
33 #define Context context
34 #endif
35 
36 #ifndef findchan_by_dname
37 #define findchan_by_dname findchan
38 #endif
39 
40 #include "gseen.h"
41 #include "seenlang.h"
42 
43 static struct slang_header *coreslangs = NULL;
44 static gseenres *results = NULL;
45 static seenreq *requests = NULL;
46 static ignoredword *ignoredwords = NULL;
47 static char *bnsnick = NULL;
48 static char *bnschan = NULL;
49 static char *seen_reply = NULL;
50 static char *temp_wildmatch_host;
51 static int numresults = 0;
52 static double glob_presearch, glob_aftersearch;
53 int numseens, glob_total_queries;
54 double glob_total_searchtime;
55 
56 static char gseenfile[121] = "gseen.dat";
57 static char no_pub[121];
58 static char quiet_seen[121];
59 static char quiet_ai_seen[121];
60 static char no_log[121];
61 static char ignore_words[1024];
62 static char default_slang[21] = "eng";
63 static int gseen_numversion = MODULE_NUMVERSION;
64 static int save_seens = 60;
65 static int save_seens_temp = 1;
66 static int expire_seens = 60;
67 static int maxseen_thr = 0;
68 static int maxseen_time = 0;
69 static int seenflood_thr = 0;
70 static time_t seenflood_time = 0;
71 static int use_handles = 0;
72 static int tell_seens = 1;
73 static int botnet_seen = 1;
74 int fuzzy_search = 1;
75 static int wildcard_search = 1;
76 static int max_matches = 500;
77 
78 #include "global_vars.c"
79 #define SLANG_NOTYPES 1
80 #define SLANG_NOFACTS 1
81 #define SLANG_NOGETALL 1
82 #define SLANG_NOVALIDATE 1
83 #include "slang.c"
84 #include "slang_gseen_commands.c"
85 #include "generic_binary_tree.c"
86 #include "seentree.c"
87 #include "datahandling.c"
88 #include "sensors.c"
89 #include "do_seen.c"
90 #include "gseencmds.c"
91 #include "ai.c"
92 #include "misc.c"
93 #include "tclcmds.c"
94 
gseen_expmem()95 static int gseen_expmem()
96 {
97   int size = 0;
98 
99   size += seentree_expmem();
100   size += expmem_seenresults();
101   size += expmem_seenreq();
102   size += expmem_ignoredwords();
103   size += slang_expmem(coreslangs);
104   size += slang_glob_expmem();
105   size += slang_chanlang_expmem(chanlangs);
106   if (bnsnick)
107     size += strlen(bnsnick) + 1;
108   if (bnschan)
109     size += strlen(bnschan) + 1;
110   if (seen_reply) {
111     size += strlen(seen_reply) + 1;
112   }
113   return size;
114 }
115 
free_gseen()116 static void free_gseen()
117 {
118   seentree_free();
119   slang_free(coreslangs);
120   slang_chanlang_free(chanlangs);
121   if (seen_reply)
122     nfree(seen_reply);
123   return;
124 }
125 
126 /* a report on the module status */
gseen_report(int idx,int details)127 static void gseen_report(int idx, int details)
128 {
129   int size = 0;
130 
131   Context;
132   if (details) {
133     size = gseen_expmem();
134     dprintf(idx, "    using %d bytes\n", size);
135   }
136 }
137 
gseen_minutely()138 static void gseen_minutely ()
139 {
140   if (save_seens_temp >= save_seens) {
141     write_seens();
142     save_seens_temp = 1;
143   } else
144     save_seens_temp++;
145 }
146 
gseen_daily()147 static void gseen_daily ()
148 {
149   Context;
150   purge_seens();
151 }
152 
153 static tcl_strings my_tcl_strings[] =
154 {
155   {"gseenfile", gseenfile, 121, 0},
156   {"ai-seen-ignore", ignore_words, 1024, 0},
157   {"no-pub-seens", no_pub, 121, 0},
158   {"quiet-seens", quiet_seen, 121, 0},
159   {"quiet-ai-seens", quiet_ai_seen, 121, 0},
160   {"no-log", no_log, 121, 0},
161   {"no-seendata", no_log, 121, 0},
162   {"default-slang", default_slang, 20, 0},
163   {0, 0, 0, 0}
164 };
165 
166 static tcl_ints my_tcl_ints[] =
167 {
168   {"save-seens", &save_seens, 0},
169   {"expire-seens", &expire_seens, 0},
170   {"use-handles", &use_handles, 0},
171   {"tell-seens", &tell_seens, 0},
172   {"botnet-seens", &botnet_seen, 0},
173   {"max-matches", &max_matches, 0},
174   {"fuzzy-search", &fuzzy_search, 0},
175   {"wildcard-search", &wildcard_search, 0},
176   {0, 0, 0}
177 };
178 
179 static tcl_coups my_tcl_coups[] =
180 {
181   {"max-seens", &maxseen_thr, &maxseen_time},
182   {0, 0, 0},
183 };
184 
gseen_close()185 static char *gseen_close()
186 {
187   Context;
188   write_seens();
189   slang_glob_free();
190   free_gseen();
191   free_seenreq();
192   free_seenresults();
193   free_ignoredwords();
194   if (bnsnick)
195     nfree(bnsnick);
196   if (bnschan)
197     nfree(bnschan);
198   rem_tcl_strings(my_tcl_strings);
199   rem_tcl_ints(my_tcl_ints);
200   rem_tcl_coups(my_tcl_coups);
201   rem_tcl_commands(mytcls);
202   rem_tcl_commands(gseentcls);
203   rem_tcl_commands(seendebugtcls);
204   rem_tcl_commands(gseentcls);
205   rem_builtins(H_dcc, mydcc);
206   rem_builtins(H_join, seen_join);
207   rem_builtins(H_kick, seen_kick);
208   rem_builtins(H_nick, seen_nick);
209   rem_builtins(H_part, seen_part);
210   rem_builtins(H_sign, seen_sign);
211   rem_builtins(H_splt, seen_splt);
212   rem_builtins(H_rejn, seen_rejn);
213   rem_builtins(H_pub, seen_pub);
214   rem_builtins(H_msg, seen_msg);
215   rem_builtins(H_bot, seen_bot);
216   del_hook(HOOK_MINUTELY, (Function) gseen_minutely);
217   del_hook(HOOK_DAILY, (Function) gseen_daily);
218   module_undepend(MODULE_NAME);
219   return NULL;
220 }
221 
222 char *gseen_start();
223 
224 static Function gseen_table[] =
225 {
226   (Function) gseen_start,
227   (Function) gseen_close,
228   (Function) gseen_expmem,
229   (Function) gseen_report,
230   /* 4 - 7 */
231   (Function) findseens,
232   (Function) free_seenresults,
233   (Function) gseen_duration,
234   (Function) & glob_seendat,
235   (Function) & numresults,
236   (Function) & fuzzy_search,
237   (Function) & numseens,
238   (Function) & glob_total_queries,
239   (Function) & glob_total_searchtime,
240   (Function) & gseen_numversion,
241 };
242 
gseen_start(Function * global_funcs)243 char *gseen_start(Function * global_funcs)
244 {
245   global = global_funcs;
246   Context;
247   module_register(MODULE_NAME, gseen_table, 1, 1);
248   if (!(irc_funcs = module_depend(MODULE_NAME, "irc", 1, 0)))
249     return "You need the irc module to use the gseen module.";
250   if (!(server_funcs = module_depend(MODULE_NAME, "server", 1, 0)))
251     return "You need the server module to use the gseen module.";
252   if (!(channels_funcs = module_depend(MODULE_NAME, "channels", 1, 0)))
253     return "You need the channels module to use the gseen module.";
254   if (!module_depend(MODULE_NAME, "evangeline", 106, 7)) {
255     module_undepend(MODULE_NAME);
256     return "This module needs Evangeline v1.0+";
257   }
258   chanlangs = NULL;
259   coreslangs = NULL;
260   slang_glob_init();
261 
262   results = NULL;
263   requests = NULL;
264   ignoredwords = NULL;
265   bnsnick = NULL;
266   bnschan = NULL;
267   seen_reply = NULL;
268 
269   numresults = 0;
270   numseens = 0;
271   glob_total_queries = 0;
272   glob_total_searchtime = 0.0;
273   ignore_words[0] = 0;
274   no_pub[0] = 0;
275   quiet_seen[0] = 0;
276   no_log[0] = 0;
277   seentree_init();
278   add_tcl_strings(my_tcl_strings);
279   add_tcl_ints(my_tcl_ints);
280   add_tcl_coups(my_tcl_coups);
281   add_tcl_commands(mytcls);
282   add_tcl_commands(seendebugtcls);
283   add_tcl_commands(gseentcls);
284   add_builtins(H_dcc, mydcc);
285   add_builtins(H_join, seen_join);
286   add_builtins(H_kick, seen_kick);
287   add_builtins(H_nick, seen_nick);
288   add_builtins(H_part, seen_part);
289   add_builtins(H_sign, seen_sign);
290   add_builtins(H_sign, seen_sign);
291   add_builtins(H_splt, seen_splt);
292   add_builtins(H_rejn, seen_rejn);
293   add_builtins(H_pub, seen_pub);
294   add_builtins(H_msg, seen_msg);
295   add_builtins(H_bot, seen_bot);
296   read_seens();
297   add_hook(HOOK_MINUTELY, (Function) gseen_minutely);
298   add_hook(HOOK_DAILY, (Function) gseen_daily);
299   initudef(1, "noseendata", 1);
300   initudef(1, "quietseens", 1);
301   initudef(1, "quietaiseens", 1);
302   initudef(1, "nopubseens", 1);
303   glob_slang_cmd_list = slang_commands_list_add(glob_slang_cmd_list, slang_text_gseen_command_table);
304   return NULL;
305 }
306