static void do_os_kick(User * u) { char *argv[3]; char *chan, *nick, *s; Channel *c; chan = strtok(NULL, " "); nick = strtok(NULL, " "); s = strtok(NULL, ""); if (!chan || !nick || !s) { syntax_error(s_OperServ, u, "KICK", OPER_KICK_SYNTAX); return; } if (!(c = findchan(chan))) { notice_lang(s_OperServ, u, CHAN_X_NOT_IN_USE, chan); } else if (c->bouncy_modes) { notice_lang(s_OperServ, u, OPER_BOUNCY_MODES_U_LINE); return; } send_cmd(s_OperServ, "KICK %s %s :%s (%s)", chan, nick, u->nick, s); if (WallOSKick) { wallops(s_OperServ, "%s used KICK on %s/%s", u->nick, nick, chan); } argv[0] = sstrdup(chan); argv[1] = sstrdup(nick); argv[2] = sstrdup(s); do_kick(s_OperServ, 3, argv); free(argv[2]); free(argv[1]); free(argv[0]); }
int xanadu_event_kick(char *source, int ac, char **av) { if (ac != 3) return MOD_CONT; do_kick(source, ac, av); return MOD_CONT; }
int denora_event_kick(char *source, int ac, char **av) { if (denora->protocoldebug) { protocol_debug(source, ac, av); } if (ac != 3) return MOD_CONT; do_kick(source, ac, av); return MOD_CONT; }
/** * The suspend command. * @param u The user who issued the command * @param ci The channel we will be suspending. * @param reason The reason given for suspending the channel. * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_suspend(User * u, ChannelInfo *ci, char *reason) { Channel *c; if (!ci) { moduleNoticeLang(ci->bi->nick, u, LANG_SUSPEND_SYNTAX); return MOD_CONT; } if (ForceForbidReason && !reason) { moduleNoticeLang(ci->bi->nick, u, LANG_SUSPEND_NO_REASON); return MOD_CONT; } if (readonly) { notice_lang(ci->bi->nick, u, READ_ONLY_MODE); return MOD_CONT; } ci->flags |= CI_SUSPENDED; ci->forbidby = sstrdup(u->nick); if (reason) ci->forbidreason = sstrdup(reason); if ((c = findchan(ci->name))) { struct c_userlist *cu, *next; char *av[3]; for (cu = c->users; cu; cu = next) { next = cu->next; if (is_oper(cu->user)) continue; av[0] = c->name; av[1] = cu->user->nick; av[2] = reason ? reason : "CHAN_SUSPEND_REASON"; xanadu_cmd_kick(ci->bi->nick, av[0], av[1], av[2]); do_kick(ci->bi->nick, 3, av); } } if (WallForbid) xanadu_cmd_global(ci->bi->nick, "\2%s\2 used SUSPEND on channel \2%s\2", u->nick, ci->name); alog("%s: %s set SUSPEND for channel %s", ci->bi->nick, u->nick, ci->name); notice_lang(ci->bi->nick, u, CHAN_SUSPEND_SUCCEEDED, ci->name); send_event(EVENT_CHAN_SUSPENDED, 1, ci->name); return MOD_CONT; }
void do_enforce_restricted(Channel * c) { struct c_userlist *user; struct c_userlist *next; ChannelInfo *ci; int16 old_nojoin_level; char mask[BUFSIZE]; char *reason; char *av[3]; User *u; if (!(ci = c->ci)) return; if (debug) alog("debug: cs_enforce: Enforcing RESTRICTED on %s", c->name); old_nojoin_level = ci->levels[CA_NOJOIN]; if (ci->levels[CA_NOJOIN] < 0) ci->levels[CA_NOJOIN] = 0; user = c->users; do { next = user->next; u = user->user; if (check_access(u, c->ci, CA_NOJOIN)) { get_idealban(ci, u, mask, sizeof(mask)); reason = getstring(u->na, CHAN_NOT_ALLOWED_TO_JOIN); anope_cmd_mode(whosends(ci), ci->name, "+b %s %lu", mask, time(NULL)); anope_cmd_kick(whosends(ci), ci->name, u->nick, "%s", reason); av[0] = ci->name; av[1] = u->nick; av[2] = reason; do_kick(s_ChanServ, 3, av); } user = next; } while (user); ci->levels[CA_NOJOIN] = old_nojoin_level; }
/** * 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; char *av[3]; struct c_userlist *cu, *cunext; if (ircd->chansqline) { if (*mask == '#') { xanadu_cmd_sqline(mask, reason); for (i = 0; i < 1024; i++) { for (c = chanlist[i]; c; c = next) { next = c->next; if (!match_wild_nocase(mask, c->name)) { 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; xanadu_cmd_kick(s_OperServ, av[0], av[1], "Q-Lined: %s", av[2]); do_kick(s_ChanServ, 3, av); } } } } else { xanadu_cmd_sqline(mask, reason); } } else { xanadu_cmd_sqline(mask, reason); } }
void do_enforce_cmode_R(Channel * c) { struct c_userlist *user; struct c_userlist *next; ChannelInfo *ci; char mask[BUFSIZE]; char *reason; char *av[3]; User *u; CBMode *cbm; if (!(ci = c->ci)) return; if (debug) alog("debug: cs_enforce: Enforcing mode +R on %s", c->name); user = c->users; do { next = user->next; u = user->user; if (!nick_identified(u)) { get_idealban(ci, u, mask, sizeof(mask)); reason = getstring(u->na, CHAN_NOT_ALLOWED_TO_JOIN); if (((cbm = &cbmodes['R'])->flag == 0) || !(c->mode & cbm->flag)) anope_cmd_mode(whosends(ci), ci->name, "+b %s %lu", mask, time(NULL)); anope_cmd_kick(whosends(ci), ci->name, u->nick, "%s", reason); av[0] = ci->name; av[1] = u->nick; av[2] = reason; do_kick(s_ChanServ, 3, av); } user = next; } while (user); }
bool IRCdMessage::OnKick(const Anope::string &source, const std::vector<Anope::string> ¶ms) { if (params.size() > 2) do_kick(source, params[0], params[1], params[2]); return true; }
/** * The /cs clear command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_clear(User * u) { char *chan = strtok(NULL, " "); char *what = strtok(NULL, " "); char tmp[BUFSIZE]; Channel *c; ChannelInfo *ci; if (!what) { syntax_error(s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX); } else 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, chan); } else if (ci->flags & CI_VERBOTEN) { notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan); } else if (!u || !check_access(u, ci, CA_CLEAR)) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); } else if (stricmp(what, "bans") == 0) { char *av[2]; int i; /* Save original ban info */ int count = c->bancount; char **bans = scalloc(sizeof(char *) * count, 1); for (i = 0; i < count; i++) bans[i] = sstrdup(c->bans[i]); for (i = 0; i < count; i++) { av[0] = sstrdup("-b"); av[1] = bans[i]; anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_BANS, chan); free(bans); } else if (ircd->except && stricmp(what, "excepts") == 0) { char *av[2]; int i; /* Save original except info */ int count = c->exceptcount; char **excepts = scalloc(sizeof(char *) * count, 1); for (i = 0; i < count; i++) excepts[i] = sstrdup(c->excepts[i]); for (i = 0; i < count; i++) { av[0] = sstrdup("-e"); av[1] = excepts[i]; anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_EXCEPTS, chan); free(excepts); } else if (ircd->invitemode && stricmp(what, "invites") == 0) { char *av[2]; int i; /* Save original except info */ int count = c->invitecount; char **invites = scalloc(sizeof(char *) * count, 1); for (i = 0; i < count; i++) invites[i] = sstrdup(c->invite[i]); for (i = 0; i < count; i++) { av[0] = sstrdup("-I"); av[1] = invites[i]; anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_INVITES, chan); free(invites); } else if (stricmp(what, "modes") == 0) { char buf[BUFSIZE], *end = buf; char *argv[2]; if (c->mode) { /* Clear modes the bulk of the modes */ anope_cmd_mode(whosends(ci), c->name, "%s", ircd->modestoremove); argv[0] = sstrdup(ircd->modestoremove); chan_set_modes(whosends(ci), c, 1, argv, 0); free(argv[0]); /* to prevent the internals from complaining send -k, -L, -f by themselves if we need to send them - TSL */ if (c->key) { anope_cmd_mode(whosends(ci), c->name, "-k %s", c->key); argv[0] = sstrdup("-k"); argv[1] = c->key; chan_set_modes(whosends(ci), c, 2, argv, 0); free(argv[0]); } if (ircd->Lmode && c->redirect) { anope_cmd_mode(whosends(ci), c->name, "-L %s", c->redirect); argv[0] = sstrdup("-L"); argv[1] = c->redirect; chan_set_modes(whosends(ci), c, 2, argv, 0); free(argv[0]); } if (ircd->fmode && c->flood) { if (flood_mode_char_remove) { anope_cmd_mode(whosends(ci), c->name, "%s %s", flood_mode_char_remove, c->flood); argv[0] = sstrdup(flood_mode_char_remove); argv[1] = c->flood; chan_set_modes(whosends(ci), c, 2, argv, 0); free(argv[0]); } else { if (debug) { alog("debug: flood_mode_char_remove was not set unable to remove flood/throttle modes"); } } } check_modes(c); } /* TODO: decide if the above implementation is better than this one. */ if (0) { CBModeInfo *cbmi = cbmodeinfos; CBMode *cbm; do { if (c->mode & cbmi->flag) *end++ = cbmi->mode; } while ((++cbmi)->flag != 0); cbmi = cbmodeinfos; do { if (cbmi->getvalue && (c->mode & cbmi->flag) && !(cbmi->flags & CBM_MINUS_NO_ARG)) { char *value = cbmi->getvalue(c); if (value) { *end++ = ' '; while (*value) *end++ = *value++; /* Free the value */ cbm = &cbmodes[(int) cbmi->mode]; cbm->setvalue(c, NULL); } } } while ((++cbmi)->flag != 0); *end = 0; anope_cmd_mode(whosends(ci), c->name, "-%s", buf); c->mode = 0; check_modes(c); } notice_lang(s_ChanServ, u, CHAN_CLEARED_MODES, chan); } else if (stricmp(what, "ops") == 0) { char *av[3]; struct c_userlist *cu, *next; if (ircd->svsmode_ucmode) { av[0] = sstrdup(chan); anope_cmd_svsmode_chan(av[0], "-o", NULL); if (ircd->owner) { anope_cmd_svsmode_chan(av[0], ircd->ownerunset, NULL); } if (ircd->protect || ircd->admin) { anope_cmd_svsmode_chan(av[0], ircd->adminunset, NULL); } for (cu = c->users; cu; cu = next) { next = cu->next; av[0] = sstrdup(chan); if (!chan_has_user_status(c, cu->user, CUS_OP)) { if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) { if (!chan_has_user_status(c, cu->user, CUS_OWNER)) { continue; } else { snprintf(tmp, BUFSIZE, "%so", ircd->ownerunset); av[1] = sstrdup(tmp); } } else { snprintf(tmp, BUFSIZE, "%so", ircd->adminunset); av[1] = sstrdup(tmp); } } else { av[1] = sstrdup("-o"); } av[2] = sstrdup(cu->user->nick); do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; av[0] = sstrdup(chan); if (!chan_has_user_status(c, cu->user, CUS_OP)) { if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) { if (!chan_has_user_status(c, cu->user, CUS_OWNER)) { continue; } else { snprintf(tmp, BUFSIZE, "%so", ircd->ownerunset); av[1] = sstrdup(tmp); } } else { snprintf(tmp, BUFSIZE, "%so", ircd->adminunset); av[1] = sstrdup(tmp); } } else { av[1] = sstrdup("-o"); } av[2] = sstrdup(cu->user->nick); anope_cmd_mode(whosends(ci), av[0], "%s :%s", av[1], av[2]); do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } } notice_lang(s_ChanServ, u, CHAN_CLEARED_OPS, chan); } else if (ircd->halfop && stricmp(what, "hops") == 0) { char *av[3]; struct c_userlist *cu, *next; for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_HALFOP)) continue; av[0] = sstrdup(chan); av[1] = sstrdup("-h"); av[2] = sstrdup(cu->user->nick); if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(av[0], av[1], NULL); do_cmode(s_ChanServ, 3, av); break; } else { anope_cmd_mode(whosends(ci), av[0], "%s :%s", av[1], av[2]); } do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_HOPS, chan); } else if (stricmp(what, "voices") == 0) { char *av[3]; struct c_userlist *cu, *next; for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_VOICE)) continue; av[0] = sstrdup(chan); av[1] = sstrdup("-v"); av[2] = sstrdup(cu->user->nick); if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(av[0], av[1], NULL); do_cmode(s_ChanServ, 3, av); break; } else { anope_cmd_mode(whosends(ci), av[0], "%s :%s", av[1], av[2]); } do_cmode(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_VOICES, chan); } else if (stricmp(what, "users") == 0) { char *av[3]; struct c_userlist *cu = NULL, *next = NULL; char buf[256]; snprintf(buf, sizeof(buf), "CLEAR USERS command from %s", u->nick); for (cu = c->users; cu; cu = next) { next = cu->next; if ((cu->user->mode & UMODE_q)) { continue; } av[0] = sstrdup(chan); av[1] = sstrdup(cu->user->nick); av[2] = sstrdup(buf); anope_cmd_kick(whosends(ci), av[0], av[1], av[2]); do_kick(s_ChanServ, 3, av); free(av[2]); free(av[1]); free(av[0]); } notice_lang(s_ChanServ, u, CHAN_CLEARED_USERS, chan); } else { syntax_error(s_ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX); } return MOD_CONT; }
/** * The /cs ban command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_ban(User * u) { char *chan = strtok(NULL, " "); char *params = strtok(NULL, " "); char *reason = strtok(NULL, ""); Channel *c; ChannelInfo *ci; User *u2; int is_same; if (!reason) { reason = "Requested"; } else { if (strlen(reason) > 200) reason[200] = '\0'; } if (!chan) { struct u_chanlist *uc, *next; /* Bans the user on every channels he is on. */ for (uc = u->chans; uc; uc = next) { next = uc->next; if ((ci = uc->chan->ci) && !(ci->flags & CI_VERBOTEN) && check_access(u, ci, CA_BANME)) { char *av[3]; char mask[BUFSIZE]; /* * Dont ban/kick the user on channels where he is excepted * to prevent services <-> server wars. */ if (ircd->except) { if (is_excepted(ci, u)) notice_lang(s_ChanServ, u, CHAN_EXCEPTED, u->nick, ci->name); continue; } if (is_protected(u)) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); continue; } av[0] = sstrdup("+b"); get_idealban(ci, u, mask, sizeof(mask)); av[1] = mask; xanadu_cmd_mode(whosends(ci), uc->chan->name, "+b %s", av[1]); chan_set_modes(s_ChanServ, uc->chan, 2, av, 1); free(av[0]); if ((ci->flags & CI_SIGNKICK) || ((ci->flags & CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK))) xanadu_cmd_kick(whosends(ci), ci->name, u->nick, "%s (%s)", reason, u->nick); else xanadu_cmd_kick(whosends(ci), ci->name, u->nick, "%s", reason); av[0] = ci->name; av[1] = u->nick; av[2] = reason; do_kick(s_ChanServ, 3, av); } } return MOD_CONT; } else if (!params) { params = u->nick; } is_same = (params == u->nick) ? 1 : (stricmp(params, u->nick) == 0); 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, chan); } else if (ci->flags & CI_VERBOTEN) { notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan); } else if (is_same ? !(u2 = u) : !(u2 = finduser(params))) { notice_lang(s_ChanServ, u, NICK_X_NOT_IN_USE, params); } else if (!is_same ? !check_access(u, ci, CA_BAN) : !check_access(u, ci, CA_BANME)) { notice_lang(s_ChanServ, u, ACCESS_DENIED); } else if (!is_same && (ci->flags & CI_PEACE) && (get_access(u2, ci) >= get_access(u, ci))) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); /* * Dont ban/kick the user on channels where he is excepted * to prevent services <-> server wars. */ } else if (ircd->except && is_excepted(ci, u2)) { notice_lang(s_ChanServ, u, CHAN_EXCEPTED, u2->nick, ci->name); } else if (ircd->protectedumode && is_protected(u2)) { notice_lang(s_ChanServ, u, PERMISSION_DENIED); } else { char *av[3]; char mask[BUFSIZE]; av[0] = sstrdup("+b"); get_idealban(ci, u2, mask, sizeof(mask)); av[1] = mask; xanadu_cmd_mode(whosends(ci), c->name, "+b %s", av[1]); chan_set_modes(s_ChanServ, c, 2, av, 1); free(av[0]); /* We still allow host banning while not allowing to kick */ if (!is_on_chan(c, u2)) return MOD_CONT; if ((ci->flags & CI_SIGNKICK) || ((ci->flags & CI_SIGNKICK_LEVEL) && !check_access(u, ci, CA_SIGNKICK))) xanadu_cmd_kick(whosends(ci), ci->name, params, "%s (%s)", reason, u->nick); else xanadu_cmd_kick(whosends(ci), ci->name, params, "%s", reason); av[0] = ci->name; av[1] = params; av[2] = reason; do_kick(s_ChanServ, 3, av); } return MOD_CONT; }
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; }
int do_clear(User *u, Channel *c, int type) { /* 1= Modes * 2= Bans * 3= Excepts * 4= Invites * 5= Ops * 6= Hops * 7= Voices * 8= Users */ char tmp[BUFSIZE]; /* Clear Channel Modes */ if (type == 1) { char *argv[2]; notice(c->ci->bi->nick, c->name, "CLEAR MODES command from %s", u->nick); if (c->mode) { /* Clear modes the bulk of the modes */ xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s", ircd->modestoremove); argv[0] = sstrdup(ircd->modestoremove); chan_set_modes(c->ci->bi->nick, c, 1, argv, 0); free(argv[0]); if (c->key) { xanadu_cmd_mode(c->ci->bi->nick, c->name, "-k %s", c->key); argv[0] = sstrdup("-k"); argv[1] = c->key; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } if (ircd->Lmode && c->redirect) { xanadu_cmd_mode(c->ci->bi->nick, c->name, "-L %s", c->redirect); argv[0] = sstrdup("-L"); argv[1] = c->redirect; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } if (ircd->fmode && c->flood) { if (flood_mode_char_remove) { xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s %s", flood_mode_char_remove, c->flood); argv[0] = sstrdup(flood_mode_char_remove); argv[1] = c->flood; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } } check_modes(c); } /* Clear Channel Bans */ } else if (type == 2) { char *av[2]; int i, count = c->bancount; char **bans = scalloc(sizeof(char *) * count, 1); /*count = c->bancount;*/ notice(c->ci->bi->nick, c->name, "CLEAR BANS command from %s", u->nick); /* Save original ban info */ for (i = 0; i < count; i++) bans[i] = sstrdup(c->bans[i]); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(c->name, "-b", NULL); for (i = 0; i < count; i++) { av[0] = sstrdup("-b"); av[1] = bans[i]; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[0]); free(av[1]); } } else { for (i = 0; i < count; i++) { av[0] = sstrdup("-b"); av[1] = bans[i]; xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[0]); free(av[1]); } } free(bans); /* Clear Channel Excepts */ } else if (ircd->except && type == 3) { char *av[2]; int i, count = c->exceptcount; char **excepts = scalloc(sizeof(char *) * count, 1); notice(c->ci->bi->nick, c->name, "CLEAR EXCEPTS command from %s", u->nick); /* Save original except info */ for (i = 0; i < count; i++) excepts[i] = sstrdup(c->excepts[i]); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(c->name, "-e", NULL); for (i = 0; i < count; i++) { av[0] = sstrdup("-e"); av[1] = excepts[i]; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[1]); free(av[0]); } } else { for (i = 0; i < count; i++) { av[0] = sstrdup("-e"); av[1] = excepts[i]; xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[1]); free(av[0]); } } free(excepts); } else if (!(ircd->except) && type == 3) { moduleNoticeLang(c->ci->bi->nick, u, LANG_EXCEPTS_UNSUPPORTED); /* Clear Channel Invites */ } else if (ircd->invitemode && type == 4) { char *av[2]; int i, count = c->invitecount; char **invites = scalloc(sizeof(char *) * count, 1); notice(c->ci->bi->nick, c->name, "CLEAR INVITES command from %s", u->nick); /* Save original invite info */ for (i = 0; i < count; i++) invites[i] = sstrdup(c->invite[i]); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(c->name, "-I", NULL); for (i = 0; i < count; i++) { av[0] = sstrdup("-I"); av[1] = invites[i]; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[1]); free(av[0]); } } else { for (i = 0; i < count; i++) { av[0] = sstrdup("-I"); av[1] = invites[i]; xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); free(av[1]); free(av[0]); } } free(invites); } else if (!(ircd->invitemode) && type == 4) { moduleNoticeLang(c->ci->bi->nick, u, LANG_INVITEMODE_UNSUPPORTED); /* Clear Channel OPs */ } else if (type == 5) { char *av[4]; struct c_userlist *cu, *next; char buf[BUFSIZE]; int ac; notice(c->ci->bi->nick, c->name, "CLEAR OPS command from %s", u->nick); av[0] = c->name; if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(c->name, "-o", NULL); if (ircd->owner) { xanadu_cmd_svsmode_chan(c->name, ircd->ownerunset, NULL); } if (ircd->protect || ircd->admin) { xanadu_cmd_svsmode_chan(c->name, ircd->adminunset, NULL); } for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_OP)) { if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) { if (!chan_has_user_status(c, cu->user, CUS_OWNER)) { continue; } else { snprintf(tmp, BUFSIZE, "%so", ircd->ownerunset); } } else { snprintf(tmp, BUFSIZE, "%so", ircd->adminunset); } } else { snprintf(tmp, BUFSIZE, "-o"); } if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[2] = tmp; av[3] = cu->user->nick; ac = 4; } else { av[1] = tmp; av[2] = cu->user->nick; ac = 3; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_OP)) { if (!chan_has_user_status(c, cu->user, CUS_PROTECT)) { if (!chan_has_user_status(c, cu->user, CUS_OWNER)) { continue; } else { snprintf(tmp, BUFSIZE, "%so", ircd->ownerunset); } } else { snprintf(tmp, BUFSIZE, "%so", ircd->adminunset); } } else { snprintf(tmp, BUFSIZE, "-o"); } if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[2] = tmp; av[3] = cu->user->nick; ac = 4; } else { av[1] = tmp; av[2] = cu->user->nick; ac = 3; } xanadu_cmd_mode(c->ci->bi->nick, c->name, "%s :%s", tmp, cu->user->nick); do_cmode(c->ci->bi->nick, ac, av); } } /* Clear Channel HOPs */ } else if (ircd->halfop && type == 6) { char *av[4]; struct c_userlist *cu, *next; char buf[BUFSIZE]; int ac; notice(c->ci->bi->nick, c->name, "CLEAR HOPS command from %s", u->nick); av[0] = c->name; if (ircdcap->tsmode) av[2] = sstrdup("-h"); else av[1] = sstrdup("-h"); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(c->name, "-h", NULL); for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_HALFOP)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_HALFOP)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } xanadu_cmd_mode(c->ci->bi->nick, c->name, "-h :%s", cu->user->nick); do_cmode(c->ci->bi->nick, ac, av); } } if (ircdcap->tsmode) free(av[2]); else free(av[1]); } else if (!(ircd->halfop) && type == 6) { moduleNoticeLang(c->ci->bi->nick, u, LANG_HOPS_UNSUPPORTED); /* Clear Channel Voices */ } else if (type == 7) { char *av[4]; struct c_userlist *cu, *next; char buf[BUFSIZE]; int ac; notice(c->ci->bi->nick, c->name, "CLEAR VOICES command from %s", u->nick); av[0] = c->name; if (ircdcap->tsmode) av[2] = sstrdup("-v"); else av[1] = sstrdup("-v"); if (ircd->svsmode_ucmode) { xanadu_cmd_svsmode_chan(av[0], "-v", NULL); for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_VOICE)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_VOICE)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } xanadu_cmd_mode(c->ci->bi->nick, c->name, "-v :%s", cu->user->nick); do_cmode(c->ci->bi->nick, ac, av); } } if (ircdcap->tsmode) free(av[2]); else free(av[1]); /* Clear Channel Users */ } else if (type == 8) { char *av[3]; struct c_userlist *cu, *next; char buf[256]; snprintf(buf, sizeof(buf), "CLEAR USERS command from %s", u->nick); notice(c->ci->bi->nick, c->name, buf); av[0] = c->name; av[2] = buf; for (cu = c->users; cu; cu = next) { next = cu->next; av[1] = cu->user->nick; xanadu_cmd_kick(c->ci->bi->nick, av[0], av[1], av[2]); do_kick(c->ci->bi->nick, 3, av); } } /* Should NEVER happen, therefor if it does, stop processing */ else { alog("[bs_fantasy_ext] An error has occured while processing CLEAR !!!"); return MOD_STOP; } return MOD_CONT; }
/** * The /cs forbid command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ static int do_forbid(User * u) { Channel *c; ChannelInfo *ci; char *chan = strtok(NULL, " "); char *reason = strtok(NULL, ""); Entry *cur, *enext; /* Assumes that permission checking has already been done. */ if (!chan || (ForceForbidReason && !reason)) { syntax_error(s_ChanServ, u, "FORBID", (ForceForbidReason ? CHAN_FORBID_SYNTAX_REASON : CHAN_FORBID_SYNTAX)); return MOD_CONT; } if (*chan != '#') { notice_lang(s_ChanServ, u, CHAN_SYMBOL_REQUIRED); return MOD_CONT; } else if (!anope_valid_chan(chan)) { notice_lang(s_ChanServ, u, CHAN_X_INVALID, chan); return MOD_CONT; } if (readonly) notice_lang(s_ChanServ, u, READ_ONLY_MODE); if ((ci = cs_findchan(chan)) != NULL) { delchan(ci); send_event(EVENT_CHAN_DROP, 1, chan); } ci = makechan(chan); if (ci) { ci->flags |= CI_VERBOTEN; ci->forbidby = sstrdup(u->nick); if (reason) ci->forbidreason = sstrdup(reason); if ((c = findchan(ci->name))) { struct c_userlist *cu, *next; char *av[3]; /* Before banning everyone, it might be prudent to clear +e and +I lists.. * to prevent ppl from rejoining.. ~ Viper */ if (ircd->except && c->excepts && c->excepts->count) { av[0] = sstrdup("-e"); for (cur = c->excepts->entries; cur; cur = enext) { enext = cur->next; av[1] = sstrdup(cur->mask); anope_cmd_mode(whosends(ci), chan, "-e %s", cur->mask); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); } free(av[0]); } if (ircd->invitemode && c->invites && c->invites->count) { av[0] = sstrdup("-I"); for (cur = c->invites->entries; cur; cur = enext) { enext = cur->next; av[1] = sstrdup(cur->mask); anope_cmd_mode(whosends(ci), chan, "-I %s", cur->mask); chan_set_modes(whosends(ci), c, 2, av, 0); free(av[1]); } free(av[0]); } for (cu = c->users; cu; cu = next) { next = cu->next; if (is_oper(cu->user)) continue; av[0] = c->name; av[1] = cu->user->nick; av[2] = reason ? reason : "CHAN_FORBID_REASON"; anope_cmd_kick(s_ChanServ, av[0], av[1], av[2]); do_kick(s_ChanServ, 3, av); } } if (WallForbid) anope_cmd_global(s_ChanServ, "\2%s\2 used FORBID on channel \2%s\2", u->nick, ci->name); if (ircd->chansqline) { anope_cmd_sqline(ci->name, ((reason) ? reason : "Forbidden")); } alog("%s: %s set FORBID for channel %s", s_ChanServ, u->nick, ci->name); notice_lang(s_ChanServ, u, CHAN_FORBID_SUCCEEDED, chan); send_event(EVENT_CHAN_FORBIDDEN, 1, chan); } else { alog("%s: Valid FORBID for %s by %s failed", s_ChanServ, ci->name, u->nick); notice_lang(s_ChanServ, u, CHAN_FORBID_FAILED, chan); } return MOD_CONT; }
int do_clear(User *u, Channel *c, int type) { /* 1= Modes * 2= Bans * 3= Excepts * 4= Invites * 5= Ops * 6= Hops * 7= Voices * 8= Users */ /* Clear Channel Modes */ if (type == 1) { char *argv[2]; notice(c->ci->bi->nick, c->name, "CLEAR MODES command from %s", u->nick); if (c->mode) { /* Clear modes the bulk of the modes */ anope_cmd_mode(c->ci->bi->nick, c->name, "%s", ircd->modestoremove); argv[0] = sstrdup(ircd->modestoremove); chan_set_modes(c->ci->bi->nick, c, 1, argv, 0); free(argv[0]); if (c->key) { anope_cmd_mode(c->ci->bi->nick, c->name, "-k %s", c->key); argv[0] = sstrdup("-k"); argv[1] = c->key; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } if (ircd->Lmode && c->redirect) { anope_cmd_mode(c->ci->bi->nick, c->name, "-L %s", c->redirect); argv[0] = sstrdup("-L"); argv[1] = c->redirect; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } if (ircd->fmode && c->flood) { if (flood_mode_char_remove) { anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", flood_mode_char_remove, c->flood); argv[0] = sstrdup(flood_mode_char_remove); argv[1] = c->flood; chan_set_modes(c->ci->bi->nick, c, 2, argv, 0); free(argv[0]); } } check_modes(c); } /* Clear Channel Bans */ } else if (type == 2) { char *av[2]; Entry *ban, *next; notice(c->ci->bi->nick, c->name, "CLEAR BANS command from %s", u->nick); if (c->bans && c->bans->count) { if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(c->name, "-b", NULL); av[0] = "-b"; for (ban = c->bans->entries; ban; ban = next) { next = ban->next; av[1] = ban->mask; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } else { av[0] = "-b"; for (ban = c->bans->entries; ban; ban = next) { next = ban->next; av[1] = ban->mask; anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } } /* Clear Channel Excepts */ } else if (ircd->except && type == 3) { char *av[2]; Entry *except, *next; notice(c->ci->bi->nick, c->name, "CLEAR EXCEPTS command from %s", u->nick); if (c->excepts && c->excepts->count) { if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(c->name, "-e", NULL); av[0] = "-e"; for (except = c->excepts->entries; except; except = next) { next = except->next; av[1] = except->mask; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } else { av[0] = "-e"; for (except = c->excepts->entries; except; except = next) { next = except->next; av[1] = except->mask; anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } } } else if (!(ircd->except) && type == 3) { noticeLang(c->ci->bi->nick, u, LANG_EXCEPTS_UNSUPPORTED); /* Clear Channel Invites */ } else if (ircd->invitemode && type == 4) { char *av[2]; Entry *invite, *next; notice(c->ci->bi->nick, c->name, "CLEAR INVITES command from %s", u->nick); if (c->invites && c->invites->count) { if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(c->name, "-e", NULL); av[0] = "-I"; for (invite = c->invites->entries; invite; invite = next) { next = invite->next; av[1] = invite->mask; chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } else { av[0] = "-I"; for (invite = c->invites->entries; invite; invite = next) { next = invite->next; av[1] = invite->mask; anope_cmd_mode(c->ci->bi->nick, c->name, "%s %s", av[0], av[1]); chan_set_modes(c->ci->bi->nick, c, 2, av, 0); } } } } else if (!(ircd->invitemode) && type == 4) { noticeLang(c->ci->bi->nick, u, LANG_INVITEMODE_UNSUPPORTED); /* Clear Channel OPs */ } else if (type == 5) { char *av[6]; /* The max we have to hold: chan, ts, modes(max3), nick, nick, nick */ int ac, isop, isadmin, isown, count, i; char buf[BUFSIZE], tmp[BUFSIZE], tmp2[BUFSIZE]; struct c_userlist *cu, *next; notice(c->ci->bi->nick, c->name, "CLEAR OPS command from %s", u->nick); av[0] = c->name; if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(c->name, "-o", NULL); if (ircd->owner) { anope_cmd_svsmode_chan(c->name, ircd->ownerunset, NULL); } if (ircd->protect || ircd->admin) { anope_cmd_svsmode_chan(c->name, ircd->adminunset, NULL); } for (cu = c->users; cu; cu = next) { next = cu->next; isop = chan_has_user_status(c, cu->user, CUS_OP); isadmin = chan_has_user_status(c, cu->user, CUS_PROTECT); isown = chan_has_user_status(c, cu->user, CUS_OWNER); count = (isop ? 1 : 0) + (isadmin ? 1 : 0) + (isown ? 1 : 0); if (!isop && !isadmin && !isown) continue; snprintf(tmp, BUFSIZE, "-%s%s%s", (isop ? "o" : ""), (isadmin ? ircd->adminunset+1 : ""), (isown ? ircd->ownerunset+1 : "")); if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[2] = tmp; /* We have to give as much nicks as modes.. - Viper */ for (i = 0; i < count; i++) av[i+3] = cu->user->nick; ac = 3 + i; } else { av[1] = tmp; /* We have to give as much nicks as modes.. - Viper */ for (i = 0; i < count; i++) av[i+2] = cu->user->nick; ac = 2 + i; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; isop = chan_has_user_status(c, cu->user, CUS_OP); isadmin = chan_has_user_status(c, cu->user, CUS_PROTECT); isown = chan_has_user_status(c, cu->user, CUS_OWNER); count = (isop ? 1 : 0) + (isadmin ? 1 : 0) + (isown ? 1 : 0); if (!isop && !isadmin && !isown) continue; snprintf(tmp, BUFSIZE, "-%s%s%s", (isop ? "o" : ""), (isadmin ? ircd->adminunset+1 : ""), (isown ? ircd->ownerunset+1 : "")); /* We need to send the IRCd a nick for every mode.. - Viper */ snprintf(tmp2, BUFSIZE, "%s %s %s", (isop ? cu->user->nick : ""), (isadmin ? cu->user->nick : ""), (isown ? cu->user->nick : "")); if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[2] = tmp; /* We have to give as much nicks as modes.. - Viper */ for (i = 0; i < count; i++) av[i+3] = cu->user->nick; ac = 3 + i; anope_cmd_mode(c->ci->bi->nick, av[0], "%s %s", av[2], tmp2); } else { av[1] = tmp; /* We have to give as much nicks as modes.. - Viper */ for (i = 0; i < count; i++) av[i+2] = cu->user->nick; ac = 2 + i; anope_cmd_mode(c->ci->bi->nick, av[0], "%s %s", av[1], tmp2); } do_cmode(c->ci->bi->nick, ac, av); } } /* Clear Channel HOPs */ } else if (ircd->halfop && type == 6) { char *av[4]; struct c_userlist *cu, *next; char buf[BUFSIZE]; int ac; notice(c->ci->bi->nick, c->name, "CLEAR HOPS command from %s", u->nick); av[0] = c->name; if (ircdcap->tsmode) av[2] = sstrdup("-h"); else av[1] = sstrdup("-h"); if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(c->name, "-h", NULL); for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_HALFOP)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_HALFOP)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } anope_cmd_mode(c->ci->bi->nick, c->name, "-h %s", cu->user->nick); do_cmode(c->ci->bi->nick, ac, av); } } if (ircdcap->tsmode) free(av[2]); else free(av[1]); } else if (!(ircd->halfop) && type == 6) { noticeLang(c->ci->bi->nick, u, LANG_HOPS_UNSUPPORTED); /* Clear Channel Voices */ } else if (type == 7) { char *av[4]; struct c_userlist *cu, *next; char buf[BUFSIZE]; int ac; notice(c->ci->bi->nick, c->name, "CLEAR VOICES command from %s", u->nick); av[0] = c->name; if (ircdcap->tsmode) av[2] = sstrdup("-v"); else av[1] = sstrdup("-v"); if (ircd->svsmode_ucmode) { anope_cmd_svsmode_chan(av[0], "-v", NULL); for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_VOICE)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } do_cmode(c->ci->bi->nick, ac, av); } } else { for (cu = c->users; cu; cu = next) { next = cu->next; if (!chan_has_user_status(c, cu->user, CUS_VOICE)) continue; if (ircdcap->tsmode) { snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL)); av[1] = buf; av[3] = cu->user->nick; ac = 4; } else { av[2] = cu->user->nick; ac = 3; } anope_cmd_mode(c->ci->bi->nick, c->name, "-v %s", cu->user->nick); do_cmode(c->ci->bi->nick, ac, av); } } if (ircdcap->tsmode) free(av[2]); else free(av[1]); /* Clear Channel Users */ } else if (type == 8) { char *av[3]; struct c_userlist *cu, *next; char buf[256]; snprintf(buf, sizeof(buf), "CLEAR USERS command from %s", u->nick); notice(c->ci->bi->nick, c->name, buf); av[0] = c->name; av[2] = buf; for (cu = c->users; cu; cu = next) { next = cu->next; av[1] = cu->user->nick; anope_cmd_kick(c->ci->bi->nick, av[0], av[1], av[2]); do_kick(c->ci->bi->nick, 3, av); } } /* Should NEVER happen, therefor if it does, stop processing */ else { alog("[bs_fantasy_ext] An error has occured while processing CLEAR !!!"); return MOD_STOP; } return MOD_CONT; }
/** * The /cs (un)suspend command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ static int do_suspend(User * u) { ChannelInfo *ci; char *chan = strtok(NULL, " "); char *reason = strtok(NULL, ""); Channel *c; /* Assumes that permission checking has already been done. */ if (!chan || (ForceForbidReason && !reason)) { syntax_error(s_ChanServ, u, "SUSPEND", (ForceForbidReason ? CHAN_SUSPEND_SYNTAX_REASON : CHAN_SUSPEND_SYNTAX)); return MOD_CONT; } if (chan[0] != '#') { notice_lang(s_ChanServ, u, CHAN_UNSUSPEND_ERROR); return MOD_CONT; } /* Only SUSPEND existing channels, otherwise use FORBID (bug #54) */ if ((ci = cs_findchan(chan)) == NULL) { notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan); return MOD_CONT; } /* You should not SUSPEND a FORBIDEN channel */ if (ci->flags & CI_VERBOTEN) { notice_lang(s_ChanServ, u, CHAN_MAY_NOT_BE_REGISTERED, chan); return MOD_CONT; } if (readonly) notice_lang(s_ChanServ, u, READ_ONLY_MODE); if (ci) { ci->flags |= CI_SUSPENDED; ci->forbidby = sstrdup(u->nick); if (reason) ci->forbidreason = sstrdup(reason); if ((c = findchan(ci->name))) { struct c_userlist *cu, *next; char *av[3]; for (cu = c->users; cu; cu = next) { next = cu->next; if (is_oper(cu->user)) continue; av[0] = c->name; av[1] = cu->user->nick; av[2] = reason ? reason : getstring(cu->user->na, CHAN_SUSPEND_REASON); anope_cmd_kick(s_ChanServ, av[0], av[1], av[2]); do_kick(s_ChanServ, 3, av); } } if (WallForbid) anope_cmd_global(s_ChanServ, "\2%s\2 used SUSPEND on channel \2%s\2", u->nick, ci->name); alog("%s: %s set SUSPEND for channel %s", s_ChanServ, u->nick, ci->name); notice_lang(s_ChanServ, u, CHAN_SUSPEND_SUCCEEDED, chan); send_event(EVENT_CHAN_SUSPENDED, 1, chan); } else { alog("%s: Valid SUSPEND for %s by %s failed", s_ChanServ, ci->name, u->nick); notice_lang(s_ChanServ, u, CHAN_SUSPEND_FAILED, chan); } return MOD_CONT; }