Example #1
0
static void cs_cmd_drop(char *origin)
{
	user_t *u = user_find_named(origin);
	mychan_t *mc;
	char *name = strtok(NULL, " ");

	if (!name)
	{
		notice(chansvs.nick, origin, STR_INSUFFICIENT_PARAMS, "DROP");
		notice(chansvs.nick, origin, "Syntax: DROP <#channel>");
		return;
	}

	if (*name != '#')
	{
		notice(chansvs.nick, origin, STR_INVALID_PARAMS, "DROP");
		notice(chansvs.nick, origin, "Syntax: DROP <#channel>");
		return;
	}

	if (!(mc = mychan_find(name)))
	{
		notice(chansvs.nick, origin, "\2%s\2 is not registered.", name);
		return;
	}

	if (!is_founder(mc, u->myuser) && !has_priv(u, PRIV_CHAN_ADMIN))
	{
		notice(chansvs.nick, origin, "You are not authorized to perform this operation.");
		return;
	}

	if (metadata_find(mc, METADATA_CHANNEL, "private:close:closer") && !has_priv(u, PRIV_CHAN_ADMIN))
	{
		logcommand(chansvs.me, u, CMDLOG_REGISTER, "%s failed DROP (closed)", mc->name);
		notice(chansvs.nick, origin, "The channel \2%s\2 is closed; it cannot be dropped.", mc->name);
		return;
	}

	if (!is_founder(mc, u->myuser))
	{
		logcommand(chansvs.me, u, CMDLOG_ADMIN, "%s DROP", mc->name);
		wallops("%s dropped the channel \2%s\2", origin, name);
	}
	else
		logcommand(chansvs.me, u, CMDLOG_REGISTER, "%s DROP", mc->name);

	snoop("DROP: \2%s\2 by \2%s\2 as \2%s\2", mc->name, u->nick, u->myuser->name);

	hook_call_event("channel_drop", mc);
	if ((config_options.chan && irccasecmp(mc->name, config_options.chan)) || !config_options.chan)
		part(mc->name, chansvs.nick);
	mychan_delete(mc->name);
	notice(chansvs.nick, origin, "The channel \2%s\2 has been dropped.", name);
	return;
}
Example #2
0
static int do_deowner(User * u)
{
    char *av[2];
    char *chan = strtok(NULL, " ");

    Channel *c;
    ChannelInfo *ci;
    struct u_chanlist *uc;

    if (!ircd->owner) {
        return MOD_CONT;
    }

    if (!chan) {
        av[0] = sstrdup(ircd->ownerunset);
        av[1] = GET_USER(u);

        /* Sets the mode to the user on every channels he is on. */

        for (uc = u->chans; uc; uc = uc->next) {
            if ((ci = uc->chan->ci) && !(ci->flags & CI_VERBOTEN)
                && is_founder(u, ci)) {
                anope_cmd_mode(whosends(ci), uc->chan->name, "%s %s",
                               av[0], GET_USER(u));
                chan_set_modes(s_ChanServ, uc->chan, 2, av, 1);
            }
        }

        free(av[0]);
        return MOD_CONT;
    }

    if (!(c = findchan(chan))) {
        notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, chan);
    } else if (!(ci = c->ci)) {
        notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, c->name);
    } else if (ci->flags & CI_VERBOTEN) {
        notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, ci->name);
    } else if (!is_founder(u, ci)) {
        notice_lang(s_ChanServ, u, ACCESS_DENIED);
    } else if (!is_on_chan(c, u)) {
        notice_lang(s_ChanServ, u, NICK_X_NOT_ON_CHAN, u->nick, c->name);
    } else {
        anope_cmd_mode(whosends(ci), c->name, "%s %s", ircd->ownerunset,
                       GET_USER(u));

        av[0] = sstrdup(ircd->ownerunset);
        av[1] = GET_USER(u);
        chan_set_modes(s_ChanServ, c, 2, av, 1);
        free(av[0]);
    }
    return MOD_CONT;
}
Example #3
0
static void funserv_cmd_requestbot(sourceinfo_t *si, int parc, char *parv[])
{
	char *name = parv[0];
	mychan_t *mc;

	if (!name)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "REQUESTBOT");
		command_fail(si, fault_needmoreparams, _("Syntax: REQUESTBOT <#channel>"));
	}

	if (*name != '#')
	{
		command_fail(si, fault_needmoreparams, STR_INVALID_PARAMS, "REQUESTBOT");
		command_fail(si, fault_needmoreparams, _("Syntax: REQUESTBOT <#channel>"));
	}

	if (!(mc = mychan_find(name)))
	{
		command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), name);
		return;
	}

	if (!is_founder(mc, entity(si->smu)))
	{
		command_fail(si, fault_noprivs, _("You are not authorized to perform this operation."));
		return;
	}

	myuser_notice(funserv->nick, myuser_find_ext(BOTNAME), "JOIN %s", name);

	command_success_nodata(si, "The bot should now be in %s.", name);
}
int do_set_modes(User *u) {
	struct u_chanlist *uc = NULL;
	char *tmp;
	Channel *c;

	/* Walk users current channels */
	for (uc = u->chans; uc; uc = uc->next) {
		if ((c = findchan(uc->chan->name)) && (c->ci)) {
			if ((get_access_level(c->ci, u->na) >= AutoOwnerLevel) && !is_founder(u, c->ci)) {
				if (!(uc->status & CUS_OWNER)) {
					tmp = stripModePrefix(ircd->ownerset);
					xanadu_cmd_mode(whosends(c->ci), c->name, "+%s %s", tmp, u->nick);
					if (tmp) free(tmp);
					chan_set_user_status(c, u, CUS_OWNER);
				}
			}
		}
	}
	return MOD_CONT;
}
int do_on_join(int argc, char **argv) {
	User *u;
	Channel *c = NULL;
	int status;
	char *tmp;

	if (!AutoOwner)
		return MOD_CONT;

	if (argc != 3)
		return MOD_CONT;

	if (stricmp(argv[0], EVENT_STOP))
		return MOD_CONT;

	if (UseTS6 && ircd->ts6) {
		u = find_byuid(argv[1]);
		if (!u)
			u = finduser(argv[1]);
	} else
		u = finduser(argv[1]);
	c = findchan(argv[2]);

	if (!c || !c->ci)
		return MOD_CONT; /* chan not registered */
	if (!u || !nick_identified(u))
		return MOD_CONT;       /* user not found/identified */

	status = chan_get_user_status(c, u);

	if ((get_access_level(c->ci, u->na) >= AutoOwnerLevel) && (!is_founder(u,c->ci))) {
		if (!(status & CUS_OWNER)) {
			tmp = stripModePrefix(ircd->ownerset);
			xanadu_cmd_mode(whosends(c->ci), c->name, "+%s %s", tmp, u->nick);
			if (tmp) free(tmp);
			chan_set_user_status(c, u, CUS_OWNER);
		}
	}
	return MOD_CONT;
}
Example #6
0
/* FFLAGS <channel> <user> <flags> */
static void cs_cmd_fflags(sourceinfo_t *si, int parc, char *parv[])
{
	char *channel = parv[0];
	char *target = parv[1];
	char *flagstr = parv[2];
	mychan_t *mc;
	myuser_t *tmu;
	unsigned int addflags, removeflags;

	if (parc < 3)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FFLAGS");
		command_fail(si, fault_needmoreparams, _("Syntax: FFLAGS <channel> <target> <flags>"));
		return;
	}

	mc = mychan_find(channel);
	if (!mc)
	{
		command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), channel);
		return;
	}
	
	if (*flagstr == '+' || *flagstr == '-' || *flagstr == '=')
	{
		flags_make_bitmasks(flagstr, chanacs_flags, &addflags, &removeflags);
		if (addflags == 0 && removeflags == 0)
		{
			command_fail(si, fault_badparams, _("No valid flags given, use /%s%s HELP FLAGS for a list"), ircd->uses_rcommand ? "" : "msg ", chansvs.me->disp);
			return;
		}
	}
	else
	{
		addflags = get_template_flags(mc, flagstr);
		if (addflags == 0)
		{
			/* Hack -- jilles */
			if (*target == '+' || *target == '-' || *target == '=')
				command_fail(si, fault_badparams, _("Usage: FFLAGS %s <target> <flags>"), mc->name);
			else
				command_fail(si, fault_badparams, _("Invalid template name given, use /%s%s TEMPLATE %s for a list"), ircd->uses_rcommand ? "" : "msg ", chansvs.me->disp, mc->name);
			return;
		}
		removeflags = ca_all & ~addflags;
	}

	if (!validhostmask(target))
	{
		if (!(tmu = myuser_find_ext(target)))
		{
			command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), target);
			return;
		}
		target = tmu->name;

		/* XXX this should be more like flags.c */
		if (removeflags & CA_FLAGS)
			removeflags |= CA_FOUNDER, addflags &= ~CA_FOUNDER;
		else if (addflags & CA_FOUNDER)
			addflags |= CA_FLAGS, removeflags &= ~CA_FLAGS;
		if (is_founder(mc, tmu) && removeflags & CA_FOUNDER && mychan_num_founders(mc) == 1)
		{
			command_fail(si, fault_noprivs, _("You may not remove the last founder."));
			return;
		}

		if (!chanacs_change(mc, tmu, NULL, &addflags, &removeflags, ca_all))
		{
			/* this shouldn't happen */
			command_fail(si, fault_noprivs, _("You are not allowed to set \2%s\2 on \2%s\2 in \2%s\2."), bitmask_to_flags2(addflags, removeflags, chanacs_flags), tmu->name, mc->name);
			return;
		}
	}
	else
	{
		if (addflags & CA_FOUNDER)
		{
			command_fail(si, fault_badparams, _("You may not set founder status on a hostmask."));
			return;
		}
		if (!chanacs_change(mc, NULL, target, &addflags, &removeflags, ca_all))
		{
			/* this shouldn't happen */
			command_fail(si, fault_noprivs, _("You are not allowed to set \2%s\2 on \2%s\2 in \2%s\2."), bitmask_to_flags2(addflags, removeflags, chanacs_flags), target, mc->name);
			return;
		}
	}

	if ((addflags | removeflags) == 0)
	{
		command_fail(si, fault_nochange, _("Channel access to \2%s\2 for \2%s\2 unchanged."), channel, target);
		return;
	}
	flagstr = bitmask_to_flags2(addflags, removeflags, chanacs_flags);
	wallops("\2%s\2 is forcing flags change \2%s\2 on \2%s\2 in \2%s\2.", get_oper_name(si), flagstr, target, mc->name);
	snoop("FFLAGS: \2%s\2 \2%s\2 \2%s\2 by \2%s\2", channel, target, flagstr, get_oper_name(si));
	command_success_nodata(si, _("Flags \2%s\2 were set on \2%s\2 in \2%s\2."), flagstr, target, channel);
	logcommand(si, CMDLOG_ADMIN, "%s FFLAGS %s %s", mc->name, target, flagstr);
	verbose(mc, "\2%s\2 forced flags change \2%s\2 on \2%s\2.", get_source_name(si), flagstr, target);
}
Example #7
0
static void cs_cmd_drop(sourceinfo_t *si, int parc, char *parv[])
{
	mychan_t *mc;
	char *name = parv[0];
	char *key = parv[1];
	char fullcmd[512];
	char key0[80], key1[80];

	if (!name)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "DROP");
		command_fail(si, fault_needmoreparams, _("Syntax: DROP <#channel>"));
		return;
	}

	if (*name != '#')
	{
		command_fail(si, fault_badparams, STR_INVALID_PARAMS, "DROP");
		command_fail(si, fault_badparams, _("Syntax: DROP <#channel>"));
		return;
	}

	if (!(mc = mychan_find(name)))
	{
		command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), name);
		return;
	}

	if (si->c != NULL)
	{
		command_fail(si, fault_noprivs, _("For security reasons, you may not drop a channel registration with a fantasy command."));
		return;
	}

	if (!is_founder(mc, entity(si->smu)))
	{
		command_fail(si, fault_noprivs, _("You are not authorized to perform this operation."));
		return;
	}

	if (metadata_find(mc, "private:close:closer"))
	{
		logcommand(si, CMDLOG_REGISTER, "DROP: \2%s\2 failed to drop (closed)", mc->name);
		command_fail(si, fault_noprivs, _("The channel \2%s\2 is closed; it cannot be dropped."), mc->name);
		return;
	}

	if (mc->flags & MC_HOLD)
	{
		command_fail(si, fault_noprivs, _("The channel \2%s\2 is held; it cannot be dropped."), mc->name);
		return;
	}

	if (si->su != NULL)
	{
		if (!key)
		{
			create_challenge(si, mc->name, 0, key0);
			snprintf(fullcmd, sizeof fullcmd, "/%s%s DROP %s %s",
					(ircd->uses_rcommand == false) ? "msg " : "",
					chansvs.me->disp, mc->name, key0);
			command_success_nodata(si, _("To avoid accidental use of this command, this operation has to be confirmed. Please confirm by replying with \2%s\2"),
					fullcmd);
			return;
		}
		/* accept current and previous key */
		create_challenge(si, mc->name, 0, key0);
		create_challenge(si, mc->name, 1, key1);
		if (strcmp(key, key0) && strcmp(key, key1))
		{
			command_fail(si, fault_badparams, _("Invalid key for %s."), "DROP");
			return;
		}
	}

	logcommand(si, CMDLOG_REGISTER, "DROP: \2%s\2", mc->name);

	hook_call_channel_drop(mc);
	if (mc->chan != NULL && !(mc->chan->flags & CHAN_LOG))
		part(mc->name, chansvs.nick);
	object_unref(mc);
	command_success_nodata(si, _("The channel \2%s\2 has been dropped."), name);
	return;
}
Example #8
0
int do_akick(User * u, Channel *c, char *cmd, char *mask, char *reason) {
	ChannelInfo *ci = c->ci;
	AutoKick *akick;
	int i;
	struct c_userlist *cu = NULL, *next = NULL;
	User *u2;
	char *argv[3];
	int count = 0;

	if (!cmd || (!mask && (!stricmp(cmd, "ADD") || !stricmp(cmd, "STICK")
		|| !stricmp(cmd, "UNSTICK") || !stricmp(cmd, "DEL")))) {
		noticeLang(ci->bi->nick, u, LANG_AKICK_SYNTAX);
	} else if (!check_access(u, ci, CA_AKICK) && !is_services_admin(u)) {
		notice_lang(ci->bi->nick, u, ACCESS_DENIED);
	} else if (stricmp(cmd, "ADD") == 0) {
		NickAlias *na = findnick(mask), *na2;
		User *target = finduser(mask);
		NickCore *nc = NULL;
		char *nick, *user, *host;
		int freemask = 0;

		if (readonly) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DISABLED);
			return MOD_CONT;
		}

		if (!na) {
			if (target) {
				char tmp[BUFSIZE];
				mask = NULL;
				freemask = 1;
				get_idealban(ci, target, tmp, BUFSIZE);
				mask = sstrdup(tmp);
			} else {
				split_usermask(mask, &nick, &user, &host);
				mask = scalloc(strlen(nick) + strlen(user) + strlen(host) + 3, 1);
				freemask = 1;
				sprintf(mask, "%s!%s@%s", nick, user, host);

				free(nick);
				free(user);
				free(host);
			}
		} else {
			if (na->status & NS_VERBOTEN) {
				notice_lang(ci->bi->nick, u, NICK_X_FORBIDDEN, mask);
				return MOD_CONT;
			}
			nc = na->nc;
		}

		/* Check excepts BEFORE we get this far */
		if (ircd->except) {
			if (is_excepted_mask(ci, mask) == 1) {
				notice_lang(ci->bi->nick, u, CHAN_EXCEPTED, mask, c->name);
				if (freemask) free(mask);
				return MOD_CONT;
			}
		}

		/* Check whether target nick has equal/higher access 
		 * or whether the mask matches a user with higher/equal access ~ Viper */
		if ((ci->flags & CI_PEACE) && nc) {
			if ((nc == ci->founder) || (get_access_nc(nc, ci) >= get_access(u, ci))) {
				notice_lang(s_ChanServ, u, PERMISSION_DENIED);
				if (freemask)
					free(mask);
				return MOD_CONT;
			}
		} else if ((ci->flags & CI_PEACE)) {
			char buf[BUFSIZE];
			/* Match against all currently online users with equal or
			 * higher access. - Viper */
			for (i = 0; i < 1024; i++) {
				for (u2 = userlist[i]; u2; u2 = u2->next) {
					if (is_founder(u2, ci) || (get_access(u2, ci) >= get_access(u, ci))) {
						if (match_usermask(mask, u2)) {
							notice_lang(s_ChanServ, u, PERMISSION_DENIED);
							free(mask);
							return MOD_CONT;
						}
					}
				}
			}

			/* Match against the lastusermask of all nickalias's with equal
			 * or higher access. ~ Viper */
			for (i = 0; i < 1024; i++) {
				for (na2 = nalists[i]; na2; na2 = na2->next) {
					if (na2->status & NS_VERBOTEN)
						continue;

					if (na2->nc && ((na2->nc == ci->founder) || (get_access_nc(na2->nc, ci) 
							>= get_access(u, ci)))) {
						snprintf(buf, BUFSIZE, "%s!%s", na2->nick, na2->last_usermask);
						if (match_wild_nocase(mask, buf)) {
							notice_lang(s_ChanServ, u, PERMISSION_DENIED);
							free(mask);
							return MOD_CONT;
						}
					}
				}
			}
		}

		for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
			if (!(akick->flags & AK_USED))
				continue;
			if ((akick->flags & AK_ISNICK) ? akick->u.nc == nc : stricmp(akick->u.mask, mask) == 0) {
				notice_lang(ci->bi->nick, u, CHAN_AKICK_ALREADY_EXISTS, (akick->flags & AK_ISNICK) ? akick->u.nc->
					display : akick->u.mask, c->name);
				if (freemask) free(mask);
				return MOD_CONT;
			}
		}

		/* All entries should be in use so we don't have to go over
		 * the entire list. We simply add new entries at the end. */
		if (ci->akickcount >= CSAutokickMax) {
			notice_lang(s_ChanServ, u, CHAN_AKICK_REACHED_LIMIT, CSAutokickMax);
			if (freemask) free(mask);
			return MOD_CONT;
		}
		ci->akickcount++;
		ci->akick = srealloc(ci->akick, sizeof(AutoKick) * ci->akickcount);

		akick = &ci->akick[i];
		akick->flags = AK_USED;
		if (nc) {
			akick->flags |= AK_ISNICK;
			akick->u.nc = nc;
		} else {
			akick->u.mask = sstrdup(mask);
		}
		akick->creator = sstrdup(u->nick);
		akick->addtime = time(NULL);
		if (reason) {
			if (strlen(reason) > 200)
				reason[200] = '\0';
			akick->reason = sstrdup(reason);
		} else {
			akick->reason = NULL;
		}

		/* Auto ENFORCE #63 */
		cu = c->users;
		while (cu) {
			next = cu->next;
			if (check_kick(cu->user, c->name, c->creation_time)) {
				argv[0] = sstrdup(c->name);
				argv[1] = sstrdup(cu->user->nick);
				if (akick->reason)
					argv[2] = sstrdup(akick->reason);
				else
					argv[2] = sstrdup("none");

				do_kick(ci->bi->nick, 3, argv);

				free(argv[2]);
				free(argv[1]);
				free(argv[0]);
				count++;

			}
			cu = next;
		}
		alog("%s: %s!%s@%s added akick for %s to %s",
				ci->bi->nick, u->nick, u->username, u->host, mask, c->name);
		notice_lang(ci->bi->nick, u, CHAN_AKICK_ADDED, mask, c->name);

		if (count)
			notice_lang(ci->bi->nick, u, CHAN_AKICK_ENFORCE_DONE, c->name, count);

		if (freemask) free(mask);

	} else if (stricmp(cmd, "STICK") == 0) {
		NickAlias *na;
		NickCore *nc;

		if (readonly) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DISABLED);
			return MOD_CONT;
		}

		if (ci->akickcount == 0) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_LIST_EMPTY, ci->name);
			return MOD_CONT;
		}

		na = findnick(mask);
		nc = (na ? na->nc : NULL);

		for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
			if (!(akick->flags & AK_USED) || (akick->flags & AK_ISNICK))
				continue;
			if (!stricmp(akick->u.mask, mask))
				break;
		}

		if (i == ci->akickcount) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_NOT_FOUND, mask, ci->name);
			return MOD_CONT;
		}

		akick->flags |= AK_STUCK;
		alog("%s: %s!%s@%s set STICK on akick %s on %s",
				ci->bi->nick, u->nick, u->username, u->host, akick->u.mask, ci->name);
		notice_lang(ci->bi->nick, u, CHAN_AKICK_STUCK, akick->u.mask, ci->name);

		if (ci->c)
			stick_mask(ci, akick);

	} else if (stricmp(cmd, "UNSTICK") == 0) {
		NickAlias *na;
		NickCore *nc;

		if (readonly) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DISABLED);
			return MOD_CONT;
		}

		if (ci->akickcount == 0) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_LIST_EMPTY, ci->name);
			return MOD_CONT;
		}

		na = findnick(mask);
		nc = (na ? na->nc : NULL);

		for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
			if (!(akick->flags & AK_USED) || (akick->flags & AK_ISNICK))
				continue;
			if (!stricmp(akick->u.mask, mask))
				break;
		}

		if (i == ci->akickcount) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_NOT_FOUND, mask, ci->name);
			return MOD_CONT;
		}

		akick->flags &= ~AK_STUCK;
		alog("%s: %s!%s@%s unset STICK on akick %s on %s",
				ci->bi->nick, u->nick, u->username, u->host, akick->u.mask, ci->name);
		notice_lang(ci->bi->nick, u, CHAN_AKICK_UNSTUCK, akick->u.mask, ci->name);

	} else if (stricmp(cmd, "DEL") == 0) {
		int deleted, a, b;

		if (readonly) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DISABLED);
			return MOD_CONT;
		}

		if (ci->akickcount == 0) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_LIST_EMPTY, c->name);
			return MOD_CONT;
		}

		/* Special case: is it a number/list?  Only do search if it isn't. */
		if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
			int count, last = -1;
			deleted = process_numlist(mask, &count, akick_del_callback, u, ci, &last);
			if (!deleted) {
				if (count == 1) {
					notice_lang(ci->bi->nick, u, CHAN_AKICK_NO_SUCH_ENTRY, last, ci->name);
				} else {
					notice_lang(ci->bi->nick, u, CHAN_AKICK_NO_MATCH, ci->name);
				}
			} else if (deleted == 1) {
				alog("%s: %s!%s@%s deleted 1 akick on %s",
						ci->bi->nick, u->nick, u->username, u->host, ci->name);
				notice_lang(ci->bi->nick, u, CHAN_AKICK_DELETED_ONE, ci->name);
			} else {
				alog("%s: %s!%s@%s deleted %d akicks on %s",
						ci->bi->nick, u->nick, u->username, u->host, deleted, ci->name);
				notice_lang(ci->bi->nick, u, CHAN_AKICK_DELETED_SEVERAL, deleted, ci->name);
			}
		} else {
			NickAlias *na = findnick(mask);
			NickCore *nc = (na ? na->nc : NULL);

			for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
				if (!(akick->flags & AK_USED))
					continue;
				if (((akick->flags & AK_ISNICK) && akick->u.nc == nc) || (!(akick->flags & AK_ISNICK)
					&& stricmp(akick->u.mask, mask) == 0))
					break;
			}
			if (i == ci->akickcount) {
				notice_lang(ci->bi->nick, u, CHAN_AKICK_NOT_FOUND, mask, c->name);
				return MOD_CONT;
			}
			alog("%s: %s!%s@%s deleted akick %s on %s",
					ci->bi->nick, u->nick, u->username, u->host, mask, c->name);
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DELETED, mask, c->name);
			akick_del(u, akick);
			deleted = 1;
		}
		if (deleted) {
			/* Reordering - DrStein */
			for (b = 0; b < ci->akickcount; b++) {
				if (ci->akick[b].flags & AK_USED) {
					for (a = 0; a < ci->akickcount; a++) {
					if (a > b)
						break;
						if (!(ci->akick[a].flags & AK_USED)) {
							ci->akick[a].flags = ci->akick[b].flags;
							if (ci->akick[b].flags & AK_ISNICK) {
								ci->akick[a].u.nc = ci->akick[b].u.nc;
							} else {
								ci->akick[a].u.mask = sstrdup(ci->akick[b].u.mask);
							}
							/* maybe we should first check whether there
							is a reason before we sstdrup it -Certus */
							if (ci->akick[b].reason)
								ci->akick[a].reason = sstrdup(ci->akick[b].reason);
							else
								ci->akick[a].reason = NULL;
							ci->akick[a].creator = sstrdup(ci->akick[b].creator);
							ci->akick[a].addtime = ci->akick[b].addtime;

							akick_del(u, &ci->akick[b]);
							break;
						}
					}
				}
			}

			/* After reordering only the entries at the end could still be empty.
			 * We ll free the places no longer in use... - Viper */
			for (i = ci->akickcount - 1; i >= 0; i--) {
				if (ci->akick[i].flags & AK_USED)
					break;

				ci->akickcount--;
			}
			ci->akick = srealloc(ci->akick,sizeof(AutoKick) * ci->akickcount);
		}
    } else if (stricmp(cmd, "LIST") == 0) {
		int sent_header = 0;

		if (ci->akickcount == 0) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_LIST_EMPTY, c->name);
			return MOD_CONT;
		}
		if (mask && isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
			process_numlist(mask, NULL, akick_list_callback, u, ci, &sent_header);
		} else {
			for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
				if (!(akick->flags & AK_USED))
					continue;
				if (mask) {
					if (!(akick->flags & AK_ISNICK) && !my_match_wild_nocase(mask, akick->u.mask))
						continue;
					if ((akick->flags & AK_ISNICK) && !my_match_wild_nocase(mask, akick->u.nc->display))
						continue;
				}
				akick_list(u, i, ci, &sent_header);
			}
		}
		if (!sent_header)
		notice_lang(ci->bi->nick, u, CHAN_AKICK_NO_MATCH, c->name);

	} else if (stricmp(cmd, "VIEW") == 0) {
		int sent_header = 0;

		if (ci->akickcount == 0) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_LIST_EMPTY, c->name);
			return MOD_CONT;
		}
		if (mask && isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
			process_numlist(mask, NULL, akick_view_callback, u, ci, &sent_header);
		} else {
			for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
				if (!(akick->flags & AK_USED))
					continue;
				if (mask) {
					if (!(akick->flags & AK_ISNICK) && !my_match_wild_nocase(mask, akick->u.mask))
						continue;
					if ((akick->flags & AK_ISNICK) && !my_match_wild_nocase(mask, akick->u.nc->display))
						continue;
				}
				akick_view(u, i, ci, &sent_header);
			}
		}
		if (!sent_header)
		notice_lang(ci->bi->nick, u, CHAN_AKICK_NO_MATCH, c->name);

	} else if (stricmp(cmd, "ENFORCE") == 0) {
		struct c_userlist *cu = NULL, *next = NULL;
		char *argv[3];
		int count = 0;

		if (!c) {
			notice_lang(ci->bi->nick, u, CHAN_X_NOT_IN_USE, ci->name);
			return MOD_CONT;
		}

		cu = c->users;

		while (cu) {
			next = cu->next;
			if (check_kick(cu->user, c->name, c->creation_time)) {
				argv[0] = sstrdup(c->name);
				argv[1] = sstrdup(cu->user->nick);
				argv[2] = sstrdup(CSAutokickReason);

				do_kick(ci->bi->nick, 3, argv);

				free(argv[2]);
				free(argv[1]);
				free(argv[0]);

				count++;
			}
			cu = next;
		}

		notice_lang(ci->bi->nick, u, CHAN_AKICK_ENFORCE_DONE, ci->name, count);

	} else if (stricmp(cmd, "CLEAR") == 0) {

		if (readonly) {
			notice_lang(ci->bi->nick, u, CHAN_AKICK_DISABLED);
			return MOD_CONT;
		}

		for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
			if (!(akick->flags & AK_USED))
				continue;
			akick_del(u, akick);
		}

		free(ci->akick);
		ci->akick = NULL;
		ci->akickcount = 0;

		alog("%s: %s!%s@%s cleared akicks on %s",
				ci->bi->nick, u->nick, u->username, u->host, ci->name);
		notice_lang(ci->bi->nick, u, CHAN_AKICK_CLEAR, ci->name);

	} else {
		noticeLang(ci->bi->nick, u, LANG_AKICK_SYNTAX);
	}
	return MOD_CONT;
}
Example #9
0
/* yeah, this should be fun. */
void channel_mode(channel_t *chan, uint8_t parc, char *parv[])
{
  boolean_t matched = FALSE;
  int i, parpos = 0, whatt = MTYPE_NUL;
  char *pos = parv[0];
  mychan_t *mc;
  chanuser_t *cu = NULL;

  if ((!pos) || (*pos == '\0'))
    return;

  if (!chan)
    return;

  /* SJOIN modes of 0 means no change */
  if (*pos == '0')
    return;

  /* assumed that the parc is correct.  ircd does, too. */
  for (; *pos != '\0'; pos++)
  {
    matched = FALSE;

    if (*pos == '+')
    {
      whatt = MTYPE_ADD;
      continue;
    }
    if (*pos == '-')
    {
      whatt = MTYPE_DEL;
      continue;
    }

    for (i = 0; mode_list[i].mode != '\0'; i++)
    {
      if (*pos == mode_list[i].mode)
      {
        matched = TRUE;

        if (whatt == MTYPE_ADD)
          chan->modes |= mode_list[i].value;
        else
          chan->modes &= ~mode_list[i].value;

        break;
      }
    }

    if (matched == TRUE)
      continue;

    for (i = 0; ignore_mode_list[i].mode != '\0'; i++)
    {
      if (*pos == ignore_mode_list[i].mode)
      {
        matched = TRUE;
        parpos++;
        break;
      }
    }

    if (matched == TRUE)
      continue;

    for (i = 0; ignore_mode_list[i].mode != '\0'; i++)
    {
      if (*pos == ignore_mode_list[i].mode)
      {
        matched = TRUE;
        parpos++;
        break;
      }
    }

    if (matched == TRUE)
      continue;

    if (*pos == 'l')
    {
      if (whatt == MTYPE_ADD)
      {
        chan->modes |= CMODE_LIMIT;
        chan->limit = atoi(parv[++parpos]);
      }
      else
      {
        chan->modes &= ~CMODE_LIMIT;
        chan->limit = 0;
      }
      continue;
    }

    if (*pos == 'k')
    {
      if (whatt == MTYPE_ADD)
      {
        chan->modes |= CMODE_KEY;
        chan->key = sstrdup(parv[++parpos]);
      }
      else
      {
        chan->modes &= ~CMODE_KEY;
        free(chan->key);
        chan->key = NULL;
        /* ratbox typically sends either the key or a `*' on -k, so you
         * should eat a parameter
         */
        parpos++;
      }
      continue;
    }

    for (i = 0; status_mode_list[i].mode != '\0'; i++)
    {
      if (*pos == status_mode_list[i].mode)
      {
        cu = chanuser_find(chan, user_find(parv[++parpos]));

        if (cu == NULL)
        {
          slog(LG_ERROR, "channel_mode(): MODE %s %c%c %s", chan->name,
               (whatt == MTYPE_ADD) ? '+' : '-', status_mode_list[i].value,
               parv[parpos]);

          matched = TRUE;
        }

        if (matched == TRUE)
          break;

        matched = TRUE;

        if (whatt == MTYPE_ADD)
        {
          cu->modes |= status_mode_list[i].value;

          /* see if they did something we have to undo */
          if ((mc = mychan_find(cu->chan->name)))
          {
            myuser_t *mu = cu->user->myuser;

            if ((MC_SECURE & mc->flags) && (status_mode_list[i].mode == 'o'))
            {
              char hostbuf[BUFSIZE];

              snprintf(hostbuf, BUFSIZE, "%s!%s@%s",
                cu->user->nick, cu->user->user, cu->user->host);

              if ((!is_founder(mc, mu)) && (cu->user != svs.svs) &&
                  (!is_xop(mc, mu, (CA_AOP | CA_SOP))) &&
                  (!chanacs_find_host(mc, hostbuf, CA_AOP)))
              {
                /* they were opped and aren't on the list, deop them */
                cmode(svs.nick, mc->name, "-o", cu->user->nick);
                cu->modes &= ~status_mode_list[i].value;
              }
            }
          }
        }
        else
        {
          if (cu->user == svs.svs)
          {
            slog(LG_DEBUG, "channel_mode(): deopped on %s, rejoining",
                 cu->chan->name);

            /* we were deopped, part and join */
            part(cu->chan->name, svs.nick);
            join(cu->chan->name, svs.nick);

            continue;
          }

          cu->modes &= ~status_mode_list[i].value;
        }

        break;
      }
    }
    if (matched == TRUE)
      continue;

    slog(LG_DEBUG, "channel_mode(): mode %c not matched", *pos);
  }

  check_modes(mychan_find(chan->name));
}
Example #10
0
/**
 * The /bs info command.
 * @param u The user who issued the command
 * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing.
 **/
int do_info(User * u)
{
    BotInfo *bi;
    ChannelInfo *ci;
    char *query = strtok(NULL, " ");

    int need_comma = 0, is_servadmin = is_services_admin(u);
    char buf[BUFSIZE], *end;
    const char *commastr = getstring(u->na, COMMA_SPACE);

    if (!query)
        syntax_error(s_BotServ, u, "INFO", BOT_INFO_SYNTAX);
    else if ((bi = findbot(query))) {
        char buf[BUFSIZE];
        struct tm *tm;

        notice_lang(s_BotServ, u, BOT_INFO_BOT_HEADER, bi->nick);
        notice_lang(s_BotServ, u, BOT_INFO_BOT_MASK, bi->user, bi->host);
        notice_lang(s_BotServ, u, BOT_INFO_BOT_REALNAME, bi->real);
        tm = localtime(&bi->created);
        strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm);
        notice_lang(s_BotServ, u, BOT_INFO_BOT_CREATED, buf);
        notice_lang(s_BotServ, u, BOT_INFO_BOT_OPTIONS,
                    getstring(u->na,
                              (bi->
                               flags & BI_PRIVATE) ? BOT_INFO_OPT_PRIVATE :
                              BOT_INFO_OPT_NONE));
        notice_lang(s_BotServ, u, BOT_INFO_BOT_USAGE, bi->chancount);

        if (is_services_admin(u))
            send_bot_channels(u, bi);
    } else if ((ci = cs_findchan(query))) {
        if (!is_servadmin && !is_founder(u, ci)) {
            notice_lang(s_BotServ, u, PERMISSION_DENIED);
            return MOD_CONT;
        }
        if (ci->flags & CI_VERBOTEN) {
            notice_lang(s_BotServ, u, CHAN_X_FORBIDDEN, query);
            return MOD_CONT;
        }

        notice_lang(s_BotServ, u, BOT_INFO_CHAN_HEADER, ci->name);
        if (ci->bi)
            notice_lang(s_BotServ, u, BOT_INFO_CHAN_BOT, ci->bi->nick);
        else
            notice_lang(s_BotServ, u, BOT_INFO_CHAN_BOT_NONE);

        if (ci->botflags & BS_KICK_BADWORDS) {
            if (ci->ttb[TTB_BADWORDS])
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_BADWORDS_BAN,
                            getstring(u->na, BOT_INFO_ACTIVE),
                            ci->ttb[TTB_BADWORDS]);
            else
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_BADWORDS,
                            getstring(u->na, BOT_INFO_ACTIVE));
        } else
            notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_BADWORDS,
                        getstring(u->na, BOT_INFO_INACTIVE));
        if (ci->botflags & BS_KICK_BOLDS) {
            if (ci->ttb[TTB_BOLDS])
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_BOLDS_BAN,
                            getstring(u->na, BOT_INFO_ACTIVE),
                            ci->ttb[TTB_BOLDS]);
            else
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_BOLDS,
                            getstring(u->na, BOT_INFO_ACTIVE));
        } else
            notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_BOLDS,
                        getstring(u->na, BOT_INFO_INACTIVE));
        if (ci->botflags & BS_KICK_CAPS) {
            if (ci->ttb[TTB_CAPS])
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_CAPS_BAN,
                            getstring(u->na, BOT_INFO_ACTIVE),
                            ci->ttb[TTB_CAPS], ci->capsmin,
                            ci->capspercent);
            else
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_CAPS_ON,
                            getstring(u->na, BOT_INFO_ACTIVE), ci->capsmin,
                            ci->capspercent);
        } else
            notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_CAPS_OFF,
                        getstring(u->na, BOT_INFO_INACTIVE));
        if (ci->botflags & BS_KICK_COLORS) {
            if (ci->ttb[TTB_COLORS])
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_COLORS_BAN,
                            getstring(u->na, BOT_INFO_ACTIVE),
                            ci->ttb[TTB_COLORS]);
            else
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_COLORS,
                            getstring(u->na, BOT_INFO_ACTIVE));
        } else
            notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_COLORS,
                        getstring(u->na, BOT_INFO_INACTIVE));
        if (ci->botflags & BS_KICK_FLOOD) {
            if (ci->ttb[TTB_FLOOD])
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_FLOOD_BAN,
                            getstring(u->na, BOT_INFO_ACTIVE),
                            ci->ttb[TTB_FLOOD], ci->floodlines,
                            ci->floodsecs);
            else
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_FLOOD_ON,
                            getstring(u->na, BOT_INFO_ACTIVE),
                            ci->floodlines, ci->floodsecs);
        } else
            notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_FLOOD_OFF,
                        getstring(u->na, BOT_INFO_INACTIVE));
        if (ci->botflags & BS_KICK_REPEAT) {
            if (ci->ttb[TTB_REPEAT])
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_REPEAT_BAN,
                            getstring(u->na, BOT_INFO_ACTIVE),
                            ci->ttb[TTB_REPEAT], ci->repeattimes);
            else
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_REPEAT_ON,
                            getstring(u->na, BOT_INFO_ACTIVE),
                            ci->repeattimes);
        } else
            notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_REPEAT_OFF,
                        getstring(u->na, BOT_INFO_INACTIVE));
        if (ci->botflags & BS_KICK_REVERSES) {
            if (ci->ttb[TTB_REVERSES])
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_REVERSES_BAN,
                            getstring(u->na, BOT_INFO_ACTIVE),
                            ci->ttb[TTB_REVERSES]);
            else
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_REVERSES,
                            getstring(u->na, BOT_INFO_ACTIVE));
        } else
            notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_REVERSES,
                        getstring(u->na, BOT_INFO_INACTIVE));
        if (ci->botflags & BS_KICK_UNDERLINES) {
            if (ci->ttb[TTB_UNDERLINES])
                notice_lang(s_BotServ, u,
                            BOT_INFO_CHAN_KICK_UNDERLINES_BAN,
                            getstring(u->na, BOT_INFO_ACTIVE),
                            ci->ttb[TTB_UNDERLINES]);
            else
                notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_UNDERLINES,
                            getstring(u->na, BOT_INFO_ACTIVE));
        } else
            notice_lang(s_BotServ, u, BOT_INFO_CHAN_KICK_UNDERLINES,
                        getstring(u->na, BOT_INFO_INACTIVE));

        end = buf;
        *end = 0;
        if (ci->botflags & BS_DONTKICKOPS) {
            end += snprintf(end, sizeof(buf) - (end - buf), "%s",
                            getstring(u->na, BOT_INFO_OPT_DONTKICKOPS));
            need_comma = 1;
        }
        if (ci->botflags & BS_DONTKICKVOICES) {
            end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
                            need_comma ? commastr : "",
                            getstring(u->na, BOT_INFO_OPT_DONTKICKVOICES));
            need_comma = 1;
        }
        if (ci->botflags & BS_FANTASY) {
            end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
                            need_comma ? commastr : "",
                            getstring(u->na, BOT_INFO_OPT_FANTASY));
            need_comma = 1;
        }
        if (ci->botflags & BS_GREET) {
            end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
                            need_comma ? commastr : "",
                            getstring(u->na, BOT_INFO_OPT_GREET));
            need_comma = 1;
        }
        if (ci->botflags & BS_NOBOT) {
            end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
                            need_comma ? commastr : "",
                            getstring(u->na, BOT_INFO_OPT_NOBOT));
            need_comma = 1;
        }
        if (ci->botflags & BS_SYMBIOSIS) {
            end += snprintf(end, sizeof(buf) - (end - buf), "%s%s",
                            need_comma ? commastr : "",
                            getstring(u->na, BOT_INFO_OPT_SYMBIOSIS));
            need_comma = 1;
        }
        notice_lang(s_BotServ, u, BOT_INFO_CHAN_OPTIONS,
                    *buf ? buf : getstring(u->na, BOT_INFO_OPT_NONE));

    } else
        notice_lang(s_BotServ, u, BOT_INFO_NOT_FOUND, query);
    return MOD_CONT;
}
Example #11
0
int do_core_kick(User * u, Channel *c, char *target, char *reason) {
	ChannelInfo *ci = c->ci;
	User *u2;
	int is_same, exists;

	if (!target)
		target = u->nick;

	is_same = (target == u->nick) ? 1 : (stricmp(target, u->nick) == 0);

	if (is_same) {
		u2 = u;
		exists = 1;
	} else
		exists = ((u2 = finduser(target)) ? 1 : 0);

	if (!is_same ? !check_access(u, ci, CA_KICK) : !check_access(u, ci, CA_KICKME)) {
		notice_lang(ci->bi->nick, u, ACCESS_DENIED);
	} else if (!is_same && exists && (ci->flags & CI_PEACE) && (get_access(u2, ci) >= get_access(u, ci))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	} else if (exists && ((ircd->protectedumode && is_protected(u2)) && !is_founder(u, ci))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	} else if (exists && RestrictKB && ((!is_founder(u, ci) && is_services_oper(u2)) ||
			(is_founder(u, ci) && is_services_admin(u2)))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	} else if (stricmp(target, ci->bi->nick) == 0) {
		bot_raw_kick(u, ci, u->nick, "Oops!");
	} else {
		if (exists) {
			if (is_on_chan(ci->c, u2)) {
				if (!reason)
					bot_raw_kick(u, ci, target, "Requested");
				else
					bot_raw_kick(u, ci, target, reason);
			}

		} else {
			char mask[BUFSIZE];
			struct c_userlist *cu = NULL, *next = NULL;

			if (my_match_wild_nocase("*!*@*", target))
				snprintf(mask, BUFSIZE, "%s", target);
			/* If we get a *@* target we need to add the *!... */
			else if (my_match_wild_nocase("*@*", target))
				snprintf(mask, BUFSIZE, "*!%s", target);
			else if (my_match_wild_nocase("*!*", target))
				snprintf(mask, BUFSIZE, "%s@*", target);
			/* If we get a * target we need to add the !*@* (assume nick)... */
			else
				snprintf(mask, BUFSIZE, "%s!*@*", target);

			cu = c->users;
			while (cu) {
				next = cu->next;
				/* This only checks against the cloacked host & vhost for normal users.
				 * IPs are only checked when triggered by an oper.. */
				if (is_oper(u) ? match_usermask_full(mask, cu->user, true) : match_usermask(mask, cu->user)) {
					/* Check whether we are allowed to kick this matching user.. */
					if (!((ircd->protectedumode && is_protected(cu->user) && !is_founder(u, ci))
							|| ((ci->flags & CI_PEACE) && (get_access(cu->user, ci) >= get_access(u, ci)))
							|| (RestrictKB && ((!is_founder(u, ci) && is_services_oper(cu->user)) ||
							(is_founder(u, ci) && is_services_admin(cu->user)))))) {
						if (!reason)
							bot_raw_kick(u, ci, cu->user->nick, "Requested");
						else
							bot_raw_kick(u, ci, cu->user->nick, reason);
					}
				}
				cu = next;
			}
		}
	}
	return MOD_CONT;
}
Example #12
0
int do_core_kickban(User * u, Channel *c, char *target, char *reason) {
	ChannelInfo *ci = c->ci;
	User *u2;
	int is_same, exists;
	char *av[2];

	if (!target)
		target = u->nick;

	is_same = (target == u->nick) ? 1 : (stricmp(target, u->nick) == 0);

	if (is_same) {
		u2 = u;
		exists = 1;
	} else
		exists = ((u2 = finduser(target)) ? 1 : 0);

	if (!is_same ? !check_access(u, ci, CA_BAN) : !check_access(u, ci, CA_BANME)) {
		notice_lang(ci->bi->nick, u, ACCESS_DENIED);
	} else if (!is_same && exists && (ci->flags & CI_PEACE) && (get_access(u2, ci) >= get_access(u, ci))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	} else if (exists && ((ircd->protectedumode && is_protected(u2)) && !is_founder(u, ci))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	/**
	 * Dont ban the user on channels where he is excepted
	 * to prevent services <-> server wars.
	 **/
	} else if (exists && (ircd->except && is_excepted(ci, u2))) {
		notice_lang(ci->bi->nick, u, CHAN_EXCEPTED, u2->nick, ci->name);
	} else if (!exists && (ircd->except && is_excepted_mask(ci, target))) {
		notice_lang(ci->bi->nick, u, CHAN_EXCEPTED, target, ci->name);
	} else if (exists && RestrictKB && ((!is_founder(u, ci) && is_services_oper(u2)) ||
			(is_founder(u, ci) && is_services_admin(u2)))) {
		notice_lang(ci->bi->nick, u, PERMISSION_DENIED);
	} else if (stricmp(target, ci->bi->nick) == 0) {
		bot_raw_ban(u, ci, u->nick, "Oops!");
	} else {
		if (exists) {
			if (is_on_chan(ci->c, u2)) {
				if (!reason)
					bot_raw_ban(u, ci, target, "Requested");
				else
					bot_raw_ban(u, ci, target, reason);
			}

		} else if (my_match_wild_nocase("*@*", target)) {
			char mask[BUFSIZE];

			/* If we get a *@* target we need to add the *!... */
			if (!my_match_wild_nocase("*!*@*", target))
				snprintf(mask, BUFSIZE, "*!%s", target);
			else
				snprintf(mask, BUFSIZE, "%s", target);

			/* Only continue if the mask doesn't match an exception or is otherwise prohibited.. */
			if (check_banmask(u, c, mask)) {
				struct c_userlist *cu = NULL, *next = NULL;

				av[0] = "+b";
				av[1] = mask;

				anope_cmd_mode(ci->bi->nick, c->name, "+b %s", av[1]);
				chan_set_modes(ci->bi->nick, c, 2, av, 1);

				cu = c->users;
				while (cu) {
					next = cu->next;
					/* This only checks against the cloacked host & vhost for normal users.
					 * IPs are only checked when triggered by an oper.. */
					if (is_oper(u) ? match_usermask_full(mask, cu->user, true) : match_usermask(mask, cu->user)) {
						if (!reason)
							bot_raw_kick(u, ci, cu->user->nick, "Requested");
						else
							bot_raw_kick(u, ci, cu->user->nick, reason);
					}
					cu = next;
				}
			}
		} else
			noticeLang(ci->bi->nick, u, LANG_REQ_NICK_OR_MASK);
	}
	return MOD_CONT;
}