📄 m_tkl.c
字号:
if ((setat_1 != tk->set_at) || (expiry_1 != tk->expire_at) || strcmp(tk->reason, reason) || strcmp(tk->setby, parv[5])) { /* here's how it goes: * set_at: oldest wins * expire_at: longest wins * reason: highest strcmp wins * setby: highest strcmp wins * We broadcast the result of this back to all servers except * cptr's direction, because cptr will do the same thing and * send it back to his servers (except us)... no need for a * double networkwide flood ;p. -- Syzop */ tk->set_at = MIN(tk->set_at, setat_1); if (!tk->expire_at || !expiry_1) tk->expire_at = 0; else tk->expire_at = MAX(tk->expire_at, expiry_1); if (strcmp(tk->reason, reason) < 0) { MyFree(tk->reason); tk->reason = strdup(reason); } if (strcmp(tk->setby, parv[5]) < 0) { MyFree(tk->setby); tk->setby = strdup(parv[5]); } if (tk->type & TKL_NICK) { if (!(*tk->usermask) == 'H') sendto_snomask(SNO_JUNK, "tkl update for %s/reason='%s'/by=%s/set=%ld/expire=%ld [causedby: %s]", tk->hostmask, tk->reason, tk->setby, tk->set_at, tk->expire_at, sptr->name); } else sendto_snomask(SNO_JUNK, "tkl update for %s@%s/reason='%s'/by=%s/set=%ld/expire=%ld [causedby: %s]", tk->usermask, tk->hostmask, tk->reason, tk->setby, tk->set_at, tk->expire_at, sptr->name); if ((parc == 11) && (type & TKL_SPAMF)) { /* I decided to only send updates to OPT_TKLEXT in this case, * it's pretty useless to send it also to OPT_NOT_TKLEXT because * spamfilter entries are permanent (no expire time), the only stuff * that can differ for non-opt is the 'setby' and 'setat' field... */ sendto_serv_butone_token_opt(cptr, OPT_TKLEXT, sptr->name, MSG_TKL, TOK_TKL, "%s %s %s %s %s %ld %ld %ld %s :%s", parv[1], parv[2], parv[3], parv[4], tk->setby, tk->expire_at, tk->set_at, tk->ptr.spamf->tkl_duration, tk->ptr.spamf->tkl_reason, tk->reason); } else if (type & TKL_GLOBAL) sendto_serv_butone(cptr, ":%s TKL %s %s %s %s %s %ld %ld :%s", sptr->name, parv[1], parv[2], parv[3], parv[4], tk->setby, tk->expire_at, tk->set_at, tk->reason); } return 0; } /* there is something fucked here? */ if ((type & TKL_SPAMF) && (parc >= 11)) tk = tkl_add_line(type, parv[3], parv[4], reason, parv[5], expiry_1, setat_1, spamf_tklduration, parv[9]); else tk = tkl_add_line(type, parv[3], parv[4], reason, parv[5], expiry_1, setat_1, 0, NULL); if (!tk) return 0; /* ERROR on allocate or something else... */ RunHook5(HOOKTYPE_TKL_ADD, cptr, sptr, tk, parc, parv); strncpyzt(gmt, asctime(gmtime((TS *)&setat_1)), sizeof(gmt)); strncpyzt(gmt2, asctime(gmtime((TS *)&expiry_1)), sizeof(gmt2)); iCstrip(gmt); iCstrip(gmt2); switch (type) { case TKL_KILL: strcpy(txt, "K:Line"); break; case TKL_ZAP: strcpy(txt, "Z:Line"); break; case TKL_KILL | TKL_GLOBAL: strcpy(txt, "G:Line"); break; case TKL_ZAP | TKL_GLOBAL: strcpy(txt, "Global Z:line"); break; case TKL_SHUN | TKL_GLOBAL: strcpy(txt, "Shun"); break; case TKL_NICK | TKL_GLOBAL: strcpy(txt, "Global Q:line"); break; case TKL_NICK: strcpy(txt, "Q:line"); break; default: strcpy(txt, "Unknown *:Line"); } if (type & TKL_SPAMF) { char buf[512]; snprintf(buf, 512, "Spamfilter added: '%s' [target: %s] [action: %s] [reason: %s] on %s GMT (from %s)", reason, parv[3], banact_valtostring(banact_chartoval(*parv[4])), parc >= 10 ? unreal_decodespace(parv[9]) : SPAMFILTER_BAN_REASON, gmt, parv[5]); sendto_snomask(SNO_TKL, "*** %s", buf); ircd_log(LOG_TKL, "%s", buf); if (tk && (tk->ptr.spamf->action == BAN_ACT_WARN) && (tk->subtype & SPAMF_USER)) spamfilter_check_users(tk); } else { char buf[512]; if (expiry_1 != 0) { if (type & TKL_NICK) { if (*parv[3] != 'H') snprintf(buf, 512, "%s added for %s on %s GMT (from %s to expire at %s GMT: %s)", txt, parv[4], gmt, parv[5], gmt2, reason); } else snprintf(buf, 512, "%s added for %s@%s on %s GMT (from %s to expire at %s GMT: %s)", txt, parv[3], parv[4], gmt, parv[5], gmt2, reason); } else { if (type & TKL_NICK) { if (*parv[3] != 'H') snprintf(buf, 512, "Permanent %s added for %s on %s GMT (from %s: %s)", txt, parv[4], gmt, parv[5], reason); } else snprintf(buf, 512, "Permanent %s added for %s@%s on %s GMT (from %s: %s)", txt, parv[3], parv[4], gmt, parv[5], reason); } if (!((type & TKL_NICK) && *parv[3] == 'H')) { sendto_snomask(SNO_TKL, "*** %s", buf); ircd_log(LOG_TKL, "%s", buf); } } loop.do_bancheck = 1; /* Makes check_pings be run ^^ */ if (type & TKL_GLOBAL) { if ((parc == 11) && (type & TKL_SPAMF)) { sendto_serv_butone_token_opt(cptr, OPT_TKLEXT, sptr->name, MSG_TKL, TOK_TKL, "%s %s %s %s %s %s %s %s %s :%s", parv[1], parv[2], parv[3], parv[4], parv[5], parv[6], parv[7], parv[8], parv[9], parv[10]); sendto_serv_butone_token_opt(cptr, OPT_NOT_TKLEXT, sptr->name, MSG_TKL, TOK_TKL, "%s %s %s %s %s %s %s :%s", parv[1], parv[2], parv[3], parv[4], parv[5], parv[6], parv[7], parv[10]); } else sendto_serv_butone(cptr, ":%s TKL %s %s %s %s %s %s %s :%s", sptr->name, parv[1], parv[2], parv[3], parv[4], parv[5], parv[6], parv[7], parv[8]); } /* TKL_GLOBAL */ return 0; } case '-': if (!IsServer(sptr) && !IsMe(sptr)) return 0; if (parc < 6) return 0; if (*parv[2] == 'G') type = TKL_KILL | TKL_GLOBAL; else if (*parv[2] == 'Z') type = TKL_ZAP | TKL_GLOBAL; else if (*parv[2] == 'z') type = TKL_ZAP; else if (*parv[2] == 'k') type = TKL_KILL; else if (*parv[2] == 's') type = TKL_SHUN | TKL_GLOBAL; else if (*parv[2] == 'Q') type = TKL_NICK | TKL_GLOBAL; else if (*parv[2] == 'q') type = TKL_NICK; else if (*parv[2] == 'F') { if (parc < 8) { sendto_realops("[BUG] m_tkl called with bogus spamfilter removal request [F], from=%s, parc=%d", sptr->name, parc); return 0; /* bogus */ } type = TKL_SPAMF | TKL_GLOBAL; if (parc >= 11) reason = parv[10]; else reason = parv[8]; } else if (*parv[2] == 'f') { if (parc < 8) { sendto_realops("[BUG] m_tkl called with bogus spamfilter removal request [f], from=%s, parc=%d", sptr->name, parc); return 0; /* bogus */ } type = TKL_SPAMF; if (parc >= 11) reason = parv[10]; else reason = parv[8]; } else return 0; switch (type) { case TKL_KILL: strcpy(txt, "K:Line"); break; case TKL_ZAP: strcpy(txt, "Z:Line"); break; case TKL_KILL | TKL_GLOBAL: strcpy(txt, "G:Line"); break; case TKL_ZAP | TKL_GLOBAL: strcpy(txt, "Global Z:line"); break; case TKL_SHUN | TKL_GLOBAL: strcpy(txt, "Shun"); break; case TKL_NICK | TKL_GLOBAL: strcpy(txt, "Global Q:line"); break; case TKL_NICK: strcpy(txt, "Q:line"); break; default: strcpy(txt, "Unknown *:Line"); } found = 0; for (tk = tklines[tkl_hash(parv[2][0])]; tk; tk = tk->next) { if (tk->type == type) { int match = 0; if (type & TKL_NICK) { if (!stricmp(tk->hostmask, parv[4])) match = 1; } else if (type & TKL_SPAMF) { if (!strcmp(tk->hostmask, parv[4]) && !strcmp(tk->usermask, parv[3]) && !stricmp(tk->reason, reason)) match = 1; } else /* all other types... */ if (!stricmp(tk->hostmask, parv[4]) && !stricmp(tk->usermask, parv[3])) match = 1; if (match) { strncpyzt(gmt, asctime(gmtime((TS *)&tk->set_at)), sizeof(gmt)); iCstrip(gmt); /* broadcast remove msg to opers... */ if (type & TKL_NICK) { if (!(*parv[3] == 'H')) { sendto_snomask(SNO_TKL, "%s removed %s %s (set at %s - reason: %s)", parv[5], txt, tk->hostmask, gmt, tk->reason); ircd_log(LOG_TKL, "%s removed %s %s (set at %s - reason: %s)", parv[5], txt, tk->hostmask, gmt, tk->reason); } } else if (type & TKL_SPAMF) { sendto_snomask(SNO_TKL, "%s removed Spamfilter '%s' (set at %s)", parv[5], tk->reason, gmt); ircd_log(LOG_TKL, "%s removed Spamfilter '%s' (set at %s)", parv[5], tk->reason, gmt); } else { sendto_snomask(SNO_TKL, "%s removed %s %s@%s (set at %s - reason: %s)", parv[5], txt, tk->usermask, tk->hostmask, gmt, tk->reason); ircd_log(LOG_TKL, "%s removed %s %s@%s (set at %s - reason: %s)", parv[5], txt, tk->usermask, tk->hostmask, gmt, tk->reason); } if (type & TKL_SHUN) tkl_check_local_remove_shun(tk); RunHook5(HOOKTYPE_TKL_DEL, cptr, sptr, tk, parc, parv); tkl_del_line(tk); if (type & TKL_GLOBAL) { if (parc < 8) sendto_serv_butone(cptr, ":%s TKL %s %s %s %s %s", sptr->name, parv[1], parv[2], parv[3], parv[4], parv[5]); else sendto_serv_butone(cptr, ":%s TKL %s %s %s %s %s %s %s :%s", sptr->name, parv[1], parv[2], parv[3], parv[4], parv[5], parv[6], parv[7], reason); } break; } } } break; case '?': if (IsAnOper(sptr)) tkl_stats(sptr,0,NULL); } return 0;}/* execute_ban_action, a tkl helper. (Syzop/2003) * PARAMETERS: * sptr: the client which is affected * action: type of ban (BAN_ACT*) * reason: ban reason * duration: duration of ban in seconds * WHAT IT DOES: * This function will shun/kline/gline/zline the user. * If the action field is 0 (BAN_ACT_KILL) the user is * just killed (and the time parameter is ignored). * ASSUMES: * This function assumes that sptr is locally connected. * RETURN VALUE: * -1 in case of block/tempshun, FLUSH_BUFFER in case of * kill/zline/gline/etc.. (you should NOT read from 'sptr' * after you got FLUSH_BUFFER!!!) */int _place_host_ban(aClient *sptr, int action, char *reason, long duration){ switch(action) { case BAN_ACT_TEMPSHUN: /* We simply mark this connection as shunned and do not add a ban record */ sendto_snomask(SNO_TKL, "Temporary shun added at user %s (%s@%s) [%s]", sptr->name, sptr->user ? sptr->user->username : "unknown", sptr->user ? sptr->user->realhost : GetIP(sptr), reason); SetShunned(sptr); break; case BAN_ACT_SHUN: case BAN_ACT_KLINE: case BAN_ACT_ZLINE: case BAN_ACT_GLINE: case BAN_ACT_GZLINE: { char hostip[128], mo[100], mo2[100]; char *tkllayer[9] = { me.name, /*0 server.name */ "+", /*1 +|- */ "?", /*2 type */ "*", /*3 user */ NULL, /*4 host */ NULL, NULL, /*6 expire_at */ NULL, /*7 set_at */ NULL /*8 reason */ }; strlcpy(hostip, GetIP(sptr), sizeof(hostip)); if (action == BAN_ACT_KLINE) tkllayer[2] = "k"; else if (action == BAN_ACT_ZLINE) tkllayer[2] = "z"; else if (action == BAN_ACT_GZLINE) tkllayer[2] = "Z"; else if (action == BAN_ACT_GLINE) tkllayer[2] = "G"; else if (action == BAN_ACT_SHUN) tkllayer[2] = "s"; tkllayer[4] = hostip; tkllayer[5] = me.name; if (!duration) strcpy(mo, "0"); /* perm */ else ircsprintf(mo, "%li", duration + TStime()); ircsprintf(mo2, "%li", TStime()); tkllayer[6] = mo; tkllayer[7] = mo2; tkllayer[8] = reason; m_tkl(&me, &me, 9, tkllayer); if (action == BAN_ACT_SHUN) { find_shun(sptr); return -1; } else return find_tkline_match(sptr, 0); } case BAN_ACT_KILL: default: return exit_client(sptr, sptr, sptr, reason); } return -1;}/** Checks if 'target' is on the spamfilter exception list. * RETURNS 1 if found in list, 0 if not. */static int target_is_spamexcept(char *target){SpamExcept *e; for (e = iConf.spamexcept; e; e = e->next) { if (!match(e->name, target)) return 1; } return 0;}int _dospamfilter_viruschan(aClient *sptr, aTKline *tk, int type){char *xparv[3], chbuf[CHANNELLEN + 16], buf[2048];aChannel *chptr;int ret; snprintf(buf, sizeof(buf), "0,%s", SPAMFILTER_VIRUSCHAN); xparv[0] = sptr->name; xparv[1] = buf; xparv[2] = NULL; /* RECURSIVE CAUTION in case we ever add blacklisted chans */ spamf_ugly_vchanoverride = 1; ret = do_cmd(sptr, sptr, "JOIN", 2, xparv); spamf_ugly_vchanoverride = 0; if (ret == FLUSH_BUFFER) return FLUSH_BUFFER; /* don't ask me how we could have died... */ sendnotice(sptr, "You are now restricted to talking in %s: %s", SPAMFILTER_VIRUSCHAN, unreal_decodespace(tk->ptr.spamf->tkl_reason)); chptr = find_channel(SPAMFILTER_VIRUSCHAN, NULL); if (chptr) { ircsprintf(chbuf, "@%s", chptr->chname); ircsprintf(buf, "[Spamfilter] %s matched filter '%s' [%s] [%s]", sptr->name, tk->reason, cmdname_by_spamftarget(type), unreal_decodespace(tk->ptr.spamf->tkl_reason)); sendto_channelprefix_butone_tok(NULL, &me, chptr, PREFIX_OP|PREFIX_ADMIN|PREFIX_OWNER, MSG_NOTICE, TOK_NOTICE, chbuf, buf, 0); } SetVirus(sptr); return 0;}/** dospamfilter: executes the spamfilter onto the string. * @param str The text (eg msg text, notice text, part text, quit text, etc * @param type The spamfilter type (SPAMF_*) * @param target The target as a text string (can be NULL, eg: for away) * @param flags Any flags (SPAMFLAG_*) * @param rettk Pointer to an aTKLline struct, _used for special circumstances only_ * RETURN VALUE: * 0 if not matched, non-0 if it should be blocked. * Return value can be FLUSH_BUFFER (-2) which means 'sptr' is * _NOT_ valid anymore so you should return immediately * (like from m_message, m_part, m_quit, etc). */ int _dospamfilter
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -