Kod: Kodu kopyalamak için üzerine çift tıklayın!
/*
* Text ban. (C) Copyright 2004-2005 Bram Matthys.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* See README for instructions
* Or scroll down ~30 lines to see 2 define's which you can tweak.
*/
#include "config.h"
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "proto.h"
#include "channel.h"
#include <time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <fcntl.h>
#include "h.h"
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif
#ifdef _WIN32
#include "version.h"
#endif
/** Max number of text bans per channel.
* This is basically the most important setting. It directly affects
* how much CPU you want to spend on text processing.
* For comparison: with 10 textbans of max length (150), and messages said in
* the channel with max length (~500 bytes), on an A1800+ (1.53GHz) machine
* this consumes 30 usec per-channel message PEAK/MAX (usec = 1/1000000 of a
* second), and in normal (non-supersize messages) count on 10-15 usec.
* Basically this means this allows for like >25000 messages per second at
* 100% CPU usage in a worth case scenario. Which seems by far sufficient to me.
* Also note that (naturally) only local clients are processed, only people
* that do not have halfops or higher, and only channels that have any
* textbans set.
* UPDATE: The speed impact for 15 bans per channel is 42 usec PEAK.
* HINT: If you are hitting the "normal banlimit" before you actually hit this
* one, then you might want to tweak the #define MAXBANS and #define
* MAXBANLENGTH in include/struct.h. Doubling MAXBANLENGTH is usually
* a good idea, and then you can enlarge MAXBANS too a bit if you want to.
*/
#define MAX_EXTBANT_PER_CHAN 15 /* Max number of ~T bans in a channel. */
/** Max length of a ban.
* NOTE: This is mainly for 'cosmetic' purposes. Lowering it does not
* decrease CPU usage for text processing.
*/
#define MAX_LENGTH 150 /* Max length of a ban */
/** Benchmark mode.
* Should never be used on production servers.
* Mainly meant for debugging/profiling purposes for myself, but if you
* have a test server and are curious about the speed of this module,
* then you can enable it of course ;).
*/
#undef BENCHMARK
ModuleHeader MOD_HEADER(textban)
= {
"textban",
"v1.0",
"ExtBan ~T (textban) by Syzop",
"3.2-b8-1",
NULL
};
/* Forward declarations */
char *extban_modeT_conv_param(char *para_in);
int extban_modeT_is_banned(aClient *sptr, aChannel *chptr, char *ban, int type);
int extban_modeT_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int what, int what2);
DLLFUNC char *textban_chanmsg(aClient *, aClient *, aChannel *, char *, int);
DLLFUNC int MOD_INIT(textban)(ModuleInfo *modinfo)
{
ExtbanInfo req;
memset(&req, 0, sizeof(ExtbanInfo));
req.flag = 'T';
req.conv_param = extban_modeT_conv_param;
req.is_banned = extban_modeT_is_banned;
req.is_ok = extban_modeT_is_ok;
if (!ExtbanAdd(modinfo->handle, req))
{
config_error("textban module: adding extban ~T failed! module NOT loaded");
return MOD_FAILED;
}
ModuleSetOptions(modinfo->handle, MOD_OPT_PERM);
HookAddPCharEx(modinfo->handle, HOOKTYPE_CHANMSG, textban_chanmsg);
return MOD_SUCCESS;
}
DLLFUNC int MOD_LOAD(textban)(int module_load)
{
return MOD_SUCCESS;
}
DLLFUNC int MOD_UNLOAD(textban)(int module_unload)
{
return MOD_SUCCESS;
}
unsigned int counttextbans(aChannel *chptr)
{
Ban *ban;
unsigned int cnt = 0;
for (ban = chptr->banlist; ban; ban=ban->next)
if ((ban->banstr[0] == '~') && (ban->banstr[1] == 'T') && (ban->banstr[2] == ':'))
cnt++;
for (ban = chptr->exlist; ban; ban=ban->next)
if ((ban->banstr[0] == '~') && (ban->banstr[1] == 'T') && (ban->banstr[2] == ':'))
cnt++;
return cnt;
}
int extban_modeT_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int what, int what2)
{
int n;
if ((what == MODE_ADD) && (what2 == EXBTYPE_EXCEPT) && MyClient(sptr))
return 0; /* except is not supported */
/* We check the # of bans in the channel, may not exceed MAX_EXTBANT_PER_CHAN */
if ((what == MODE_ADD) && (checkt == EXBCHK_PARAM) &&
MyClient(sptr) && !IsAnOper(sptr) &&
((n = counttextbans(chptr)) >= MAX_EXTBANT_PER_CHAN))
{
/* We check the # of bans in the channel, may not exceed MAX_EXTBANT_PER_CHAN */
sendto_one(sptr, err_str(ERR_BANLISTFULL), me.name, sptr->name, chptr->chname, para);
sendnotice(sptr, "Too many textbans for this channel");
return 0;
}
return 1;
}
/** Ban callbacks */
char *extban_modeT_conv_param(char *para_in)
{
static char retbuf[MAX_LENGTH+1];
char para[MAX_LENGTH+1], *action, *text, *p;
strlcpy(para, para_in+3, sizeof(para)); /* work on a copy (and truncate it) */
/* ~T:<action>:<text> */
text = strchr(para, ':');
if (!text)
return NULL;
*text++ = '\0';
/* para=action, text=text */
if (!*text)
return NULL; /* empty text */
/* ~T:<action>:<text> */
if (!strcasecmp(para, "block"))
action = "block";
else
return NULL; /* unknown action */
/* check the string.. */
for (p=text; *p; p++)
if ((*p == '\003') || (*p == '\002') ||
(*p == '\037') || (*p == '\026') ||
(*p == ' '))
return NULL; /* codes not permitted, would be confusing since they are stripped */
/* Rebuild the string.. */
snprintf(retbuf, sizeof(retbuf), "~T:%s:%s", action, text); /* can be cut off if too long */
return retbuf;
}
int extban_modeT_is_banned(aClient *sptr, aChannel *chptr, char *ban, int type)
{
/* Never banned here */
return 0;
}
/* Channel message callback */
DLLFUNC char *textban_chanmsg(aClient *cptr, aClient *sptr, aChannel *chptr, char *text, int notice)
{
static char filtered[512]; /* temp buffer */
Ban *ban;
long fl;
int done=0;
char *p;
#ifdef BENCHMARK
struct timeval tv_alpha, tv_beta;
gettimeofday(&tv_alpha, NULL);
#endif
if (!MyClient(sptr))
return text; /* Remote and servers are not affected */
fl = get_access(sptr, chptr);
if (fl & (CHFL_HALFOP|CHFL_CHANOP|CHFL_CHANPROT|CHFL_CHANOWNER))
return text; /* halfop or higher */
filtered[0] = '\0'; /* NOT needed, but... :P */
for (ban = chptr->banlist; ban; ban=ban->next)
{
if ((ban->banstr[0] == '~') && (ban->banstr[1] == 'T') && (ban->banstr[2] == ':'))
{
if (!done)
{
/* Prepare the text [done here, to avoid useless CPU time] */
strlcpy(filtered, StripControlCodes(text), sizeof(filtered));
done = 1;
}
p = ban->banstr + 3;
if (!strncasecmp(p, "block:", 6))
{
if (!_match(p+6, filtered))
{
sendto_one(sptr, err_str(ERR_CANNOTSENDTOCHAN),
me.name, sptr->name, chptr->chname,
"Message blocked due to a text ban", chptr->chname);
return NULL;
}
}
}
}
#ifdef BENCHMARK
gettimeofday(&tv_beta, NULL);
ircd_log(LOG_ERROR, "TextBan Timing: %ld microseconds (%s / %s / %d)",
((tv_beta.tv_sec - tv_alpha.tv_sec) * 1000000) + (tv_beta.tv_usec - tv_alpha.tv_usec),
sptr->name, chptr->chname, strlen(text));
#endif
return text;
}
mode #kanal +b ~T:*kelime* ile, Kullanıcıların Kanala *kelime* Yazmasını Engelleyebilirsiniz Bu Komutla. UnrealIRCd ile Alakalı Oldugu Dolayısıyla, Konu, UnrealIRCd Bölümüne Tasınmıstır.