1
0
mirror of https://github.com/anope/anope.git synced 2026-06-26 11:36:38 +02:00
Files
anope/src/actions.c
T
2009-02-18 23:34:32 +00:00

227 lines
4.8 KiB
C

/* Various routines to perform simple actions.
*
* (C) 2003-2009 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*
* $Id$
*
*/
#include "services.h"
/*************************************************************************/
/**
* Note a bad password attempt for the given user. If they've used up
* their limit, toss them off.
* @param u the User to check
* @return void
*/
void bad_password(User * u)
{
time_t now = time(NULL);
if (!u || !BadPassLimit) {
return;
}
if (BadPassTimeout > 0 && u->invalid_pw_time > 0
&& u->invalid_pw_time < now - BadPassTimeout)
u->invalid_pw_count = 0;
u->invalid_pw_count++;
u->invalid_pw_time = now;
if (u->invalid_pw_count >= BadPassLimit) {
kill_user(NULL, u->nick, "Too many invalid passwords");
}
}
/*************************************************************************/
/**
* Remove a user from the IRC network.
* @param source is the nick which should generate the kill, or NULL for a server-generated kill.
* @param user to remove
* @param reason for the kill
* @return void
*/
void kill_user(const char *source, const char *user, const char *reason)
{
char buf[BUFSIZE];
if (!user || !*user) {
return;
}
if (!source || !*source) {
source = ServerName;
}
if (!reason) {
reason = "";
}
snprintf(buf, sizeof(buf), "%s (%s)", source, reason);
ircdproto->SendSVSKill(source, user, buf);
if (!ircd->quitonkill && finduser(user)) {
do_kill(user, buf);
}
}
/*************************************************************************/
/**
* Check and enforce SQlines
* @param mask of the sqline
* @param reason for the sqline
* @return void
*/
void sqline(char *mask, char *reason)
{
int i;
Channel *c, *next;
const char *av[3];
struct c_userlist *cu, *cunext;
if (ircd->chansqline) {
if (*mask == '#') {
ircdproto->SendSQLine(mask, reason);
for (i = 0; i < 1024; i++) {
for (c = chanlist[i]; c; c = next) {
next = c->next;
if (!Anope::Match(c->name, mask, false)) {
continue;
}
for (cu = c->users; cu; cu = cunext) {
cunext = cu->next;
if (is_oper(cu->user)) {
continue;
}
av[0] = c->name;
av[1] = cu->user->nick;
av[2] = reason;
ircdproto->SendKick(findbot(s_OperServ), av[0], av[1],
"Q-Lined: %s", av[2]);
do_kick(s_ChanServ, 3, av);
}
}
}
} else {
ircdproto->SendSQLine(mask, reason);
}
} else {
ircdproto->SendSQLine(mask, reason);
}
}
/*************************************************************************/
/**
* Unban the nick from a channel
* @param ci channel info for the channel
* @param nick to remove the ban for
* @return void
*/
void common_unban(ChannelInfo * ci, char *nick)
{
const char *av[4];
char *host = NULL;
char buf[BUFSIZE];
int ac;
uint32 ip = 0;
User *u;
Entry *ban, *next;
if (!ci || !ci->c || !nick) {
return;
}
if (!(u = finduser(nick))) {
return;
}
if (!ci->c->bans || (ci->c->bans->count == 0))
return;
if (u->hostip == NULL) {
host = host_resolve(u->host);
/* we store the just resolved hostname so we don't
* need to do this again */
if (host) {
u->hostip = sstrdup(host);
}
} else {
host = sstrdup(u->hostip);
}
/* Convert the host to an IP.. */
if (host)
ip = str_is_ip(host);
if (ircd->svsmode_unban) {
ircdproto->SendBanDel(ci->name, nick);
} else {
if (ircdcap->tsmode) {
snprintf(buf, BUFSIZE - 1, "%ld", static_cast<long>(time(NULL)));
av[0] = ci->name;
av[1] = buf;
av[2] = "-b";
ac = 4;
} else {
av[0] = ci->name;
av[1] = "-b";
ac = 3;
}
for (ban = ci->c->bans->entries; ban; ban = next) {
next = ban->next;
if (entry_match(ban, u->nick, u->GetIdent().c_str(), u->host, ip) ||
entry_match(ban, u->nick, u->GetIdent().c_str(), u->vhost, ip)) {
ircdproto->SendMode(whosends(ci), ci->name, "-b %s", ban->mask);
if (ircdcap->tsmode)
av[3] = ban->mask;
else
av[2] = ban->mask;
do_cmode(whosends(ci)->nick, ac, av);
}
}
}
/* host_resolve() sstrdup us this info so we gotta free it */
if (host) {
delete [] host;
}
}
/*************************************************************************/
/**
* Prepare to set SVSMODE and update internal user modes
* @param u user to apply modes to
* @param modes the modes to set on the user
* @param arg the arguments for the user modes
* @return void
*/
void common_svsmode(User * u, const char *modes, const char *arg)
{
int ac = 1;
const char *av[2];
av[0] = modes;
if (arg) {
av[1] = arg;
ac++;
}
ircdproto->SendSVSMode(u, ac, av);
ircdproto->ProcessUsermodes(u, ac, av);
}
/*************************************************************************/