configure: add stuff for spell checking
[rofl0r-ixchat.git] / src / common / ignore.c
blobc3544f3092db243ff81a0673c4015c925f64ece0
1 /* X-Chat
2 * Copyright (C) 1998 Peter Zelezny.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
27 #include "xchat.h"
28 #include "ignore.h"
29 #include "cfgfiles.h"
30 #include "fe.h"
31 #include "text.h"
32 #include "util.h"
33 #include "xchatc.h"
36 int ignored_ctcp = 0; /* keep a count of all we ignore */
37 int ignored_priv = 0;
38 int ignored_chan = 0;
39 int ignored_noti = 0;
40 int ignored_invi = 0;
41 static int ignored_total = 0;
43 /* ignore_exists ():
44 * returns: struct ig, if this mask is in the ignore list already
45 * NULL, otherwise
47 struct ignore *
48 ignore_exists (char *mask)
50 struct ignore *ig = 0;
51 GSList *list;
53 list = ignore_list;
54 while (list)
56 ig = (struct ignore *) list->data;
57 if (!rfc_casecmp (ig->mask, mask))
58 return ig;
59 list = list->next;
61 return NULL;
65 /* ignore_add(...)
67 * returns:
68 * 0 fail
69 * 1 success
70 * 2 success (old ignore has been changed)
73 int
74 ignore_add (char *mask, int type)
76 struct ignore *ig = 0;
77 int change_only = FALSE;
79 /* first check if it's already ignored */
80 ig = ignore_exists (mask);
81 if (ig)
82 change_only = TRUE;
84 if (!change_only)
85 ig = malloc (sizeof (struct ignore));
87 if (!ig)
88 return 0;
90 ig->mask = strdup (mask);
91 ig->type = type;
93 if (!change_only)
94 ignore_list = g_slist_prepend (ignore_list, ig);
95 fe_ignore_update (1);
97 if (change_only)
98 return 2;
100 return 1;
103 void
104 ignore_showlist (session *sess)
106 struct ignore *ig;
107 GSList *list = ignore_list;
108 char tbuf[256];
109 int i = 0;
111 EMIT_SIGNAL (XP_TE_IGNOREHEADER, sess, 0, 0, 0, 0, 0);
113 while (list)
115 ig = list->data;
116 i++;
118 snprintf (tbuf, sizeof (tbuf), " %-25s ", ig->mask);
119 if (ig->type & IG_PRIV)
120 strcat (tbuf, _("YES "));
121 else
122 strcat (tbuf, _("NO "));
123 if (ig->type & IG_NOTI)
124 strcat (tbuf, _("YES "));
125 else
126 strcat (tbuf, _("NO "));
127 if (ig->type & IG_CHAN)
128 strcat (tbuf, _("YES "));
129 else
130 strcat (tbuf, _("NO "));
131 if (ig->type & IG_CTCP)
132 strcat (tbuf, _("YES "));
133 else
134 strcat (tbuf, _("NO "));
135 if (ig->type & IG_DCC)
136 strcat (tbuf, _("YES "));
137 else
138 strcat (tbuf, _("NO "));
139 if (ig->type & IG_INVI)
140 strcat (tbuf, _("YES "));
141 else
142 strcat (tbuf, _("NO "));
143 if (ig->type & IG_UNIG)
144 strcat (tbuf, _("YES "));
145 else
146 strcat (tbuf, _("NO "));
147 strcat (tbuf, "\n");
148 PrintText (sess, tbuf);
149 /*EMIT_SIGNAL (XP_TE_IGNORELIST, sess, ig->mask, 0, 0, 0, 0); */
150 /* use this later, when TE's support 7 args */
151 list = list->next;
154 if (!i)
155 EMIT_SIGNAL (XP_TE_IGNOREEMPTY, sess, 0, 0, 0, 0, 0);
157 EMIT_SIGNAL (XP_TE_IGNOREFOOTER, sess, 0, 0, 0, 0, 0);
160 /* ignore_del()
162 * one of the args must be NULL, use mask OR *ig, not both
167 ignore_del (char *mask, struct ignore *ig)
169 if (!ig)
171 GSList *list = ignore_list;
173 while (list)
175 ig = (struct ignore *) list->data;
176 if (!rfc_casecmp (ig->mask, mask))
177 break;
178 list = list->next;
179 ig = 0;
182 if (ig)
184 ignore_list = g_slist_remove (ignore_list, ig);
185 free (ig->mask);
186 free (ig);
187 fe_ignore_update (1);
188 return TRUE;
190 return FALSE;
193 /* check if a msg should be ignored by browsing our ignore list */
196 ignore_check (char *host, int type)
198 struct ignore *ig;
199 GSList *list = ignore_list;
201 /* check if there's an UNIGNORE first, they take precendance. */
202 while (list)
204 ig = (struct ignore *) list->data;
205 if (ig->type & IG_UNIG)
207 if (ig->type & type)
209 if (match (ig->mask, host))
210 return FALSE;
213 list = list->next;
216 list = ignore_list;
217 while (list)
219 ig = (struct ignore *) list->data;
221 if (ig->type & type)
223 if (match (ig->mask, host))
225 ignored_total++;
226 if (type & IG_PRIV)
227 ignored_priv++;
228 if (type & IG_NOTI)
229 ignored_noti++;
230 if (type & IG_CHAN)
231 ignored_chan++;
232 if (type & IG_CTCP)
233 ignored_ctcp++;
234 if (type & IG_INVI)
235 ignored_invi++;
236 fe_ignore_update (2);
237 return TRUE;
240 list = list->next;
243 return FALSE;
246 static char *
247 ignore_read_next_entry (char *my_cfg, struct ignore *ignore)
249 char tbuf[1024];
251 /* Casting to char * done below just to satisfy compiler */
253 if (my_cfg)
255 my_cfg = cfg_get_str (my_cfg, "mask", tbuf, sizeof (tbuf));
256 if (!my_cfg)
257 return NULL;
258 ignore->mask = strdup (tbuf);
260 if (my_cfg)
262 my_cfg = cfg_get_str (my_cfg, "type", tbuf, sizeof (tbuf));
263 ignore->type = atoi (tbuf);
265 return my_cfg;
268 void
269 ignore_load ()
271 struct ignore *ignore;
272 struct stat st;
273 char *cfg, *my_cfg;
274 int fh, i;
276 fh = xchat_open_file ("ignore.conf", O_RDONLY, 0, 0);
277 if (fh != -1)
279 fstat (fh, &st);
280 if (st.st_size)
282 cfg = malloc (st.st_size + 1);
283 cfg[0] = '\0';
284 i = read (fh, cfg, st.st_size);
285 if (i >= 0)
286 cfg[i] = '\0';
287 my_cfg = cfg;
288 while (my_cfg)
290 ignore = malloc (sizeof (struct ignore));
291 memset (ignore, 0, sizeof (struct ignore));
292 if ((my_cfg = ignore_read_next_entry (my_cfg, ignore)))
293 ignore_list = g_slist_prepend (ignore_list, ignore);
294 else
295 free (ignore);
297 free (cfg);
299 close (fh);
303 void
304 ignore_save ()
306 char buf[1024];
307 int fh;
308 GSList *temp = ignore_list;
309 struct ignore *ig;
311 fh = xchat_open_file ("ignore.conf", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
312 if (fh != -1)
314 while (temp)
316 ig = (struct ignore *) temp->data;
317 if (!(ig->type & IG_NOSAVE))
319 snprintf (buf, sizeof (buf), "mask = %s\ntype = %d\n\n",
320 ig->mask, ig->type);
321 write (fh, buf, strlen (buf));
323 temp = temp->next;
325 close (fh);
330 static gboolean
331 flood_autodialog_timeout (gpointer data)
333 prefs.autodialog = 1;
334 return FALSE;
338 flood_check (char *nick, char *ip, server *serv, session *sess, int what) /*0=ctcp 1=priv */
341 serv
342 int ctcp_counter;
343 time_t ctcp_last_time;
344 prefs
345 unsigned int ctcp_number_limit;
346 unsigned int ctcp_time_limit;
348 char buf[512];
349 char real_ip[132];
350 int i;
351 time_t current_time;
352 current_time = time (NULL);
354 if (what == 0)
356 if (serv->ctcp_last_time == 0) /*first ctcp in this server */
358 serv->ctcp_last_time = time (NULL);
359 serv->ctcp_counter++;
360 } else
362 if (difftime (current_time, serv->ctcp_last_time) < prefs.ctcp_time_limit) /*if we got the ctcp in the seconds limit */
364 serv->ctcp_counter++;
365 if (serv->ctcp_counter == prefs.ctcp_number_limit) /*if we reached the maximun numbers of ctcp in the seconds limits */
367 serv->ctcp_last_time = current_time; /*we got the flood, restore all the vars for next one */
368 serv->ctcp_counter = 0;
369 for (i = 0; i < 128; i++)
370 if (ip[i] == '@')
371 break;
372 snprintf (real_ip, sizeof (real_ip), "*!*%s", &ip[i]);
373 /*ignore_add (char *mask, int priv, int noti, int chan,
374 int ctcp, int invi, int unignore, int no_save) */
376 snprintf (buf, sizeof (buf),
377 _("You are being CTCP flooded from %s, ignoring %s\n"),
378 nick, real_ip);
379 PrintText (sess, buf);
381 /*FIXME: only ignore ctcp or all?, its ignoring ctcps for now */
382 ignore_add (real_ip, IG_CTCP);
383 return 0;
387 } else
389 if (serv->msg_last_time == 0)
391 serv->msg_last_time = time (NULL);
392 serv->ctcp_counter++;
393 } else
395 if (difftime (current_time, serv->msg_last_time) <
396 prefs.msg_time_limit)
398 serv->msg_counter++;
399 if (serv->msg_counter == prefs.msg_number_limit) /*if we reached the maximun numbers of ctcp in the seconds limits */
401 snprintf (buf, sizeof (buf),
402 _("You are being MSG flooded from %s, setting gui_auto_open_dialog OFF.\n"),
403 ip);
404 PrintText (sess, buf);
405 serv->msg_last_time = current_time; /*we got the flood, restore all the vars for next one */
406 serv->msg_counter = 0;
407 /*ignore_add (char *mask, int priv, int noti, int chan,
408 int ctcp, int invi, int unignore, int no_save) */
410 if (prefs.autodialog)
412 /*FIXME: only ignore ctcp or all?, its ignoring ctcps for now */
413 prefs.autodialog = 0;
414 /* turn it back on in 30 secs */
415 fe_timeout_add (30000, flood_autodialog_timeout, NULL);
417 return 0;
422 return 1;