📄 m_message.c
字号:
#ifdef STRIPBADWORDS int blocked = 0;#endif Hook *tmphook;#ifdef NEWCHFLOODPROT if (chptr->mode.floodprot && chptr->mode.floodprot->l[FLD_TEXT])#else if (chptr->mode.per)#endif if (check_for_chan_flood(cptr, sptr, chptr) == 1) continue; sendanyways = (strchr(CHANCMDPFX,parv[2][0]) ? 1 : 0); text = parv[2]; if (MyClient(sptr) && (chptr->mode.mode & MODE_STRIP)) text = StripColors(parv[2]);#ifdef STRIPBADWORDS if (MyClient(sptr)) { #ifdef STRIPBADWORDS_CHAN_ALWAYS text = stripbadwords_channel(text,& blocked); if (blocked) { if (!notice) sendto_one(sptr, err_str(ERR_CANNOTSENDTOCHAN), me.name, parv[0], chptr->chname, err_cantsend[6], p2); continue; } #else if (chptr->mode.extmode & EXTMODE_STRIPBADWORDS) { text = stripbadwords_channel(text, &blocked); if (blocked) { if (!notice) sendto_one(sptr, err_str(ERR_CANNOTSENDTOCHAN), me.name, parv[0], chptr->chname, err_cantsend[6], p2); continue; } } #endif }#endif if (MyClient(sptr)) { ret = dospamfilter(sptr, text, notice ? SPAMF_CHANNOTICE : SPAMF_CHANMSG, chptr->chname, 0, NULL); if (ret < 0) return ret; } for (tmphook = Hooks[HOOKTYPE_CHANMSG]; tmphook; tmphook = tmphook->next) { text = (*(tmphook->func.pcharfunc))(cptr, sptr, chptr, text, notice); if (!text) break; } if (!text) continue; sendto_channelprefix_butone_tok(cptr, sptr, chptr, prefix, notice ? MSG_NOTICE : MSG_PRIVATE, notice ? TOK_NOTICE : TOK_PRIVATE, nick, text, 1);#ifdef NEWCHFLOODPROT if (chptr->mode.floodprot && !is_skochanop(sptr, chptr) && !IsULine(sptr) && do_chanflood(chptr->mode.floodprot, FLD_MSG) && MyClient(sptr)) { do_chanflood_action(chptr, FLD_MSG, "msg/notice"); } if (chptr->mode.floodprot && !is_skochanop(sptr, chptr) && (text[0] == '\001') && strncmp(text+1, "ACTION ", 7) && do_chanflood(chptr->mode.floodprot, FLD_CTCP) && MyClient(sptr)) { do_chanflood_action(chptr, FLD_CTCP, "CTCP"); }#endif sendanyways = 0; continue; } else if (MyClient(sptr)) { if (!notice || (cansend == 8)) /* privmsg or 'cannot send notice'... */ sendto_one(sptr, err_str(ERR_CANNOTSENDTOCHAN), me.name, parv[0], chptr->chname, err_cantsend[cansend - 1], p2); } continue; } else if (p2) { sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], p2); continue; } /* ** the following two cases allow masks in NOTICEs ** (for OPERs only) ** ** Armin, 8Jun90 (gruner@informatik.tu-muenchen.de) */ if ((*nick == '$' || *nick == '#') && (IsAnOper(sptr) || IsULine(sptr))) { if (IsULine(sptr)) goto itsokay; if (!(s = (char *)rindex(nick, '.'))) { sendto_one(sptr, err_str(ERR_NOTOPLEVEL), me.name, parv[0], nick); continue; } while (*++s) if (*s == '.' || *s == '*' || *s == '?') break; if (*s == '*' || *s == '?') { sendto_one(sptr, err_str(ERR_WILDTOPLEVEL), me.name, parv[0], nick); continue; } itsokay: sendto_match_butone(IsServer(cptr) ? cptr : NULL, sptr, nick + 1, (*nick == '#') ? MATCH_HOST : MATCH_SERVER, ":%s %s %s :%s", parv[0], cmd, nick, parv[2]); continue; } /* ** user[%host]@server addressed? */ server = index(nick, '@'); if (server) /* meaning there is a @ */ { /* There is always a \0 if its a string */ if (*(server + 1) != '\0') { char fulltarget[NICKLEN + HOSTLEN + 1]; strlcpy(fulltarget, nick, sizeof(fulltarget)); /* lame.. I know.. */ srvptr = find_server_quick(server + 1); if (srvptr) { acptr = find_nickserv(nick, NULL); if (acptr && (acptr->srvptr == srvptr)) { text = parv[2]; newcmd = cmd; ret = can_privmsg(cptr, sptr, acptr, notice, &text, &newcmd); if (ret == CANPRIVMSG_CONTINUE) continue; else if (ret != CANPRIVMSG_SEND) return ret; /* If we end up here, we have to actually send it... */ if (IsMe(acptr)) sendto_prefix_one(acptr, sptr, ":%s %s %s :%s", sptr->name, newcmd, acptr->name, text); else sendto_message_one(acptr, sptr, sptr->name, newcmd, fulltarget, text); continue; } } /* NICK@SERVER NOT FOUND: */ if (server && strncasecmp(server + 1, SERVICES_NAME, strlen(SERVICES_NAME)) == 0) sendto_one(sptr, err_str(ERR_SERVICESDOWN), me.name, parv[0], nick); else sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], fulltarget); continue; } } /* nothing, nada, not anything found */ sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], nick); continue; } return 0;}/*** m_private** parv[0] = sender prefix** parv[1] = receiver list** parv[2] = message text*/DLLFUNC int m_private(aClient *cptr, aClient *sptr, int parc, char *parv[]){ return m_message(cptr, sptr, parc, parv, 0);}/*** m_notice** parv[0] = sender prefix** parv[1] = receiver list** parv[2] = notice text*/DLLFUNC int m_notice(aClient *cptr, aClient *sptr, int parc, char *parv[]){ return m_message(cptr, sptr, parc, parv, 1);}/*********************************************************************** * m_silence() - Added 19 May 1994 by Run. * ***********************************************************************//* * is_silenced : Does the actual check wether sptr is allowed * to send a message to acptr. * Both must be registered persons. * If sptr is silenced by acptr, his message should not be propagated, * but more over, if this is detected on a server not local to sptr * the SILENCE mask is sent upstream. */int _is_silenced(aClient *sptr, aClient *acptr){ Link *lp; anUser *user; static char sender[HOSTLEN + NICKLEN + USERLEN + 5]; static char senderx[HOSTLEN + NICKLEN + USERLEN + 5]; char checkv = 0; if (!(acptr->user) || !(lp = acptr->user->silence) || !(user = sptr->user)) return 0; ircsprintf(sender, "%s!%s@%s", sptr->name, user->username, user->realhost); /* We also check for matches against sptr->user->virthost if present, * this is checked regardless of mode +x so you can't do tricks like: * evil has +x and msgs, victim places silence on +x host, evil does -x * and can msg again. -- Syzop */ if (sptr->user->virthost) { ircsprintf(senderx, "%s!%s@%s", sptr->name, user->username, sptr->user->virthost); checkv = 1; } for (; lp; lp = lp->next) { if (!match(lp->value.cp, sender) || (checkv && !match(lp->value.cp, senderx))) { if (!MyConnect(sptr)) { sendto_one(sptr->from, ":%s SILENCE %s :%s", acptr->name, sptr->name, lp->value.cp); lp->flags = 1; } return 1; } } return 0;}/** Make a viewable dcc filename. * This is to protect a bit against tricks like 'flood-it-off-the-buffer' * and color 1,1 etc... */char *dcc_displayfile(char *f){static char buf[512];char *i, *o = buf;size_t n = strlen(f); if (n < 300) { for (i = f; *i; i++) if (*i < 32) *o++ = '?'; else *o++ = *i; *o = '\0'; return buf; } /* Else, we show it as: [first 256 chars]+"[..TRUNCATED..]"+[last 20 chars] */ for (i = f; i < f+256; i++) if (*i < 32) *o++ = '?'; else *o++ = *i; strcpy(o, "[..TRUNCATED..]"); o += sizeof("[..TRUNCATED..]"); for (i = f+n-20; *i; i++) if (*i < 32) *o++ = '?'; else *o++ = *i; *o = '\0'; return buf; }/** Checks if a DCC is allowed. * PARAMETERS: * sptr: the client to check for * target: the target (eg a user or a channel) * targetcli: the target client, NULL in case of a channel * text: the whole msg * RETURNS: * 1: allowed (no dcc, etc) * 0: block * <0: immediately return with this value (could be FLUSH_BUFFER) * HISTORY: * F:Line stuff by _Jozeph_ added by Stskeeps with comments. * moved and various improvements by Syzop. */static int check_dcc(aClient *sptr, char *target, aClient *targetcli, char *text){char *ctcp;ConfigItem_deny_dcc *fl;char *end, realfile[BUFSIZE];int size_string, ret; if ((*text != 1) || !MyClient(sptr) || IsOper(sptr) || (targetcli && IsAnOper(targetcli))) return 1; ctcp = &text[1]; /* Most likely a DCC send .. */ if (!myncmp(ctcp, "DCC SEND ", 9)) ctcp = text + 10; else if (!myncmp(ctcp, "DCC RESUME ", 11)) ctcp = text + 12; else return 1; /* something else, allow */ if (sptr->flags & FLAGS_DCCBLOCK) { sendto_one(sptr, ":%s NOTICE %s :*** You are blocked from sending files as you have tried to " "send a forbidden file - reconnect to regain ability to send", me.name, sptr->name); return 0; } for (; (*ctcp == ' '); ctcp++); /* skip leading spaces */ if (*ctcp == '"' && *(ctcp+1)) end = index(ctcp+1, '"'); else end = index(ctcp, ' '); /* check if it was fake.. just pass it along then .. */ if (!end || (end < ctcp)) return 1; /* allow */ size_string = (int)(end - ctcp); if (!size_string || (size_string > (BUFSIZE - 1))) return 1; /* allow */ strlcpy(realfile, ctcp, size_string+1); if ((ret = dospamfilter(sptr, realfile, SPAMF_DCC, target, 0, NULL)) < 0) return ret; if ((fl = dcc_isforbidden(sptr, realfile))) { char *displayfile = dcc_displayfile(realfile); sendto_one(sptr, ":%s %d %s :*** Cannot DCC SEND file %s to %s (%s)", me.name, RPL_TEXT, sptr->name, displayfile, target, fl->reason); sendto_one(sptr, ":%s NOTICE %s :*** You have been blocked from sending files, reconnect to regain permission to send files", me.name, sptr->name); sendto_umode(UMODE_VICTIM, "%s tried to send forbidden file %s (%s) to %s (is blocked now)", sptr->name, displayfile, fl->reason, target); sendto_serv_butone(NULL, ":%s SMO v :%s tried to send forbidden file %s (%s) to %s (is blocked now)", me.name, sptr->name, displayfile, fl->reason, target); sptr->flags |= FLAGS_DCCBLOCK; return 0; /* block */ } /* Channel dcc (???) and discouraged? just block */ if (!targetcli && ((fl = dcc_isdiscouraged(sptr, realfile)))) { char *displayfile = dcc_displayfile(realfile); sendto_one(sptr, ":%s %d %s :*** Cannot DCC SEND file %s to %s (%s)", me.name, RPL_TEXT, sptr->name, displayfile, target, fl->reason); return 0; /* block */ } return 1; /* allowed */}/** Checks if a DCC is allowed by DCCALLOW rules (only SOFT bans are checked). * PARAMETERS: * from: the sender client (possibly remote) * to: the target client (always local) * text: the whole msg * RETURNS: * 1: allowed * 0: block */static int check_dcc_soft(aClient *from, aClient *to, char *text){char *ctcp;ConfigItem_deny_dcc *fl;char *end, realfile[BUFSIZE];int size_string; if ((*text != 1) || IsOper(from) || IsOper(to)) return 1; ctcp = &text[1]; /* Most likely a DCC send .. */ if (!myncmp(ctcp, "DCC SEND ", 9)) ctcp = text + 10; else return 1; /* something else, allow */ if (*ctcp == '"' && *(ctcp+1)) end = index(ctcp+1, '"'); else end = index(ctcp, ' '); /* check if it was fake.. just pass it along then .. */ if (!end || (end < ctcp)) return 1; /* allow */ size_string = (int)(end - ctcp); if (!size_string || (size_string > (BUFSIZE - 1))) return 1; /* allow */ strlcpy(realfile, ctcp, size_string+1); if ((fl = dcc_isdiscouraged(from, realfile))) { if (!on_dccallow_list(to, from)) { char *displayfile = dcc_displayfile(realfile); sendto_one(from, ":%s %d %s :*** Cannot DCC SEND file %s to %s (%s)", me.name, RPL_TEXT, from->name, displayfile, to->name, fl->reason);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -