int ignore_check(SERVER_REC *server, const char *nick, const char *host, const char *channel, const char *text, int level) { CHANNEL_REC *chanrec; NICK_REC *nickrec; IGNORE_REC *rec; GSList *tmp; char *nickmask; int len, best_mask, best_match, best_patt; if (nick == NULL) nick = ""; chanrec = server == NULL || channel == NULL ? NULL : channel_find(server, channel); if (chanrec != NULL && nick != NULL && (nickrec = nicklist_find(chanrec, nick)) != NULL) { /* nick found - check only ignores in nickmatch cache */ if (nickrec->host == NULL) nicklist_set_host(chanrec, nickrec, host); tmp = nickmatch_find(nickmatch, nickrec); nickmask = NULL; } else { tmp = ignores; nickmask = g_strconcat(nick, "!", host, NULL); } best_mask = best_patt = -1; best_match = FALSE; for (; tmp != NULL; tmp = tmp->next) { int match = 1; rec = tmp->data; if (nickmask != NULL) match = ignore_match_server(rec, server) && ignore_match_channel(rec, channel) && ignore_match_nickmask(rec, nick, nickmask); if (match && ignore_match_level(rec, level) && ignore_match_pattern(rec, text)) { len = rec->mask == NULL ? 0 : strlen(rec->mask); if (len > best_mask) { best_mask = len; best_match = !rec->exception; } else if (len == best_mask) { len = rec->pattern == NULL ? 0 : strlen(rec->pattern); if (len > best_patt) { best_patt = len; best_match = !rec->exception; } else if (len == best_patt && rec->exception) best_match = 0; } } } g_free(nickmask); if (best_match || (level & MSGLEVEL_PUBLIC) == 0) return best_match; return ignore_check_replies(chanrec, text, level); }
int ignore_check(IRC_SERVER_REC *server, const char *nick, const char *host, const char *channel, const char *text, int level) { GSList *tmp; int ok, mask_len, patt_len; int best_mask, best_patt, best_ignore; g_return_val_if_fail(server != NULL, 0); best_mask = 0; best_patt = 0; best_ignore = FALSE; for (tmp = ignores; tmp != NULL; tmp = tmp->next) { IGNORE_REC *rec = tmp->data; if ((level & (rec->level|rec->except_level)) == 0) continue; /* server */ if (rec->servertag != NULL && g_strcasecmp(server->tag, rec->servertag) != 0) continue; /* channel list */ if (rec->channels != NULL) { if (channel == NULL || !ischannel(*channel)) continue; if (strarray_find(rec->channels, channel) == -1) continue; } /* nick mask */ mask_len = 0; if (rec->mask != NULL) { if (nick == NULL) continue; mask_len = strlen(rec->mask); if (mask_len <= best_mask) continue; ok = ((host == NULL || *host == '\0')) ? match_wildcards(rec->mask, nick) : irc_mask_match_address(rec->mask, nick, host); if (!ok) { /* nick didn't match, but maybe this is a reply to nick? */ if (!rec->replies || channel == NULL || text == NULL || !ignore_check_replies(rec, server, channel, text)) continue; } } /* pattern */ patt_len = 0; if (rec->pattern != NULL) { if (!mask_len && !best_mask) { patt_len = strlen(rec->pattern); if (patt_len <= best_patt) continue; } ok = rec->regexp ? regexp_match(text, rec->pattern) : rec->fullword ? stristr_full(text, rec->pattern) != NULL : stristr(text, rec->pattern) != NULL; if (!ok) continue; } if (mask_len || best_mask) best_mask = mask_len; else if (patt_len) best_patt = patt_len; best_ignore = (rec->level & level) != 0; } return best_ignore; }