static void filter_msg_user(void *data);
static void filter_msg_channel(void *data);
+static void filter_client_quit(void *data);
static void on_client_exit(void *data);
static void mo_setfilter(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
static const char *cmdname[MESSAGE_TYPE_COUNT] = {
[MESSAGE_TYPE_PRIVMSG] = "PRIVMSG",
[MESSAGE_TYPE_NOTICE] = "NOTICE",
+ [MESSAGE_TYPE_PART] = "PART",
};
enum filter_state {
mapi_hfn_list_av1 filter_hfnlist[] = {
{ "privmsg_user", (hookfn) filter_msg_user },
{ "privmsg_channel", (hookfn) filter_msg_channel },
+ { "client_quit", (hookfn) filter_client_quit },
{ "client_exit", (hookfn) on_client_exit },
{ NULL, NULL }
};
if (!strcasecmp(data, "disable")) {
filter_enable = 0;
- sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
"Filtering disabled.");
return 0;
}
if (!strcasecmp(data, "enable")) {
filter_enable = 1;
- sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
"Filtering enabled.");
return 0;
}
}
state = FILTER_LOADED;
filter_db = db;
- sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
"New filters loaded.");
rb_free(filter_data);
filter_data = 0;
return 0;
if (!filter_db)
return 0;
- snprintf(check_buffer, sizeof check_buffer, "%s:%s!%s@%s#%c %s %s :%s",
+ if (!command)
+ return 0;
+ snprintf(check_buffer, sizeof check_buffer, "%s:%s!%s@%s#%c %s%s%s :%s",
prefix,
#if FILTER_NICK
source->name,
"*",
#endif
source->user && source->user->suser[0] != '\0' ? '1' : '0',
- command, target,
+ command,
+ target ? " " : "",
+ target ? target : "",
msg);
hs_error_t r = hs_scan(filter_db, check_buffer, strlen(check_buffer), 0, filter_scratch, match_callback, &state);
if (r != HS_SUCCESS && r != HS_SCAN_TERMINATED)
data->approved = 1;
}
if (r & ACT_ALARM) {
- sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
"FILTER: %s!%s@%s [%s]",
s->name, s->username, s->host, s->sockhost);
}
data->approved = 1;
}
if (r & ACT_ALARM) {
- sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
"FILTER: %s!%s@%s [%s]",
s->name, s->username, s->host, s->sockhost);
}
}
}
+void
+filter_client_quit(void *data_)
+{
+ hook_data_client_quit *data = data_;
+ struct Client *s = data->client;
+ if (IsOper(s)) {
+ return;
+ }
+ char *text = strcpy(clean_buffer, data->orig_reason);
+ strip_colour(text);
+ strip_unprintable(text);
+ unsigned r = match_message("0", s, "QUIT", NULL, data->orig_reason) |
+ match_message("1", s, "QUIT", NULL, text);
+ if (r & ACT_DROP) {
+ data->reason = NULL;
+ }
+ if (r & ACT_ALARM) {
+ sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
+ "FILTER: %s!%s@%s [%s]",
+ s->name, s->username, s->host, s->sockhost);
+ }
+ /* No point in doing anything with ACT_KILL */
+}
+
void
on_client_exit(void *data_)
{
state = filter_db ? FILTER_LOADED : FILTER_EMPTY;
}
}
-