summaryrefslogtreecommitdiff
path: root/src/core/cs_akick.c
diff options
context:
space:
mode:
authorAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-11-07 18:09:09 +0000
committerAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-11-07 18:09:09 +0000
commit029f39964b2e8f0371ef5bc776d1052d7894e695 (patch)
treeb0062108291f74a2296dd2ee06cc80be87a769a7 /src/core/cs_akick.c
parent2ec83162d68c33896e2266524d9b9a29c8ee4908 (diff)
Rewrote all of the akick code to be much cleaner
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2613 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src/core/cs_akick.c')
-rw-r--r--src/core/cs_akick.c821
1 files changed, 373 insertions, 448 deletions
diff --git a/src/core/cs_akick.c b/src/core/cs_akick.c
index c700dc21e..b68dbeec5 100644
--- a/src/core/cs_akick.c
+++ b/src/core/cs_akick.c
@@ -46,29 +46,6 @@ static void split_usermask(const char *mask, const char **nick, const char **use
delete [] mask2;
}
-int akick_del(User * u, AutoKick * akick)
-{
- if (!(akick->flags & AK_USED))
- return 0;
- if (akick->flags & AK_ISNICK) {
- akick->u.nc = NULL;
- } else {
- delete [] akick->u.mask;
- akick->u.mask = NULL;
- }
- if (akick->reason) {
- delete [] akick->reason;
- akick->reason = NULL;
- }
- if (akick->creator) {
- delete [] akick->creator;
- akick->creator = NULL;
- }
- akick->addtime = 0;
- akick->flags = 0;
- return 1;
-}
-
int akick_del_callback(User * u, int num, va_list args)
{
ChannelInfo *ci = va_arg(args, ChannelInfo *);
@@ -76,16 +53,17 @@ int akick_del_callback(User * u, int num, va_list args)
*last = num;
- if (num < 1 || num > ci->akickcount)
+ if (num < 1 || num > ci->akick.size())
return 0;
- return akick_del(u, &ci->akick[num - 1]);
+ ci->EraseAkick(ci->akick[num - 1]);
+ return 1;
}
int akick_list(User * u, int index, ChannelInfo * ci, int *sent_header)
{
- AutoKick *akick = &ci->akick[index];
+ AutoKick *akick = ci->akick[index];
if (!(akick->flags & AK_USED))
return 0;
@@ -95,10 +73,10 @@ int akick_list(User * u, int index, ChannelInfo * ci, int *sent_header)
}
notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_FORMAT, index + 1,
- ((akick->flags & AK_ISNICK) ? akick->u.nc->
- display : akick->u.mask),
- (akick->reason ? akick->
- reason : getstring(u, NO_REASON)));
+ ((akick->flags & AK_ISNICK) ? akick->nc->
+ display : akick->mask.c_str()),
+ (!akick->reason.empty() ? akick->
+ reason.c_str() : getstring(u, NO_REASON)));
return 1;
}
@@ -106,14 +84,14 @@ int akick_list_callback(User * u, int num, va_list args)
{
ChannelInfo *ci = va_arg(args, ChannelInfo *);
int *sent_header = va_arg(args, int *);
- if (num < 1 || num > ci->akickcount)
+ if (num < 1 || num > ci->akick.size())
return 0;
return akick_list(u, num - 1, ci, sent_header);
}
int akick_view(User * u, int index, ChannelInfo * ci, int *sent_header)
{
- AutoKick *akick = &ci->akick[index];
+ AutoKick *akick = ci->akick[index];
char timebuf[64];
struct tm tm;
@@ -136,13 +114,13 @@ int akick_view(User * u, int index, ChannelInfo * ci, int *sent_header)
((akick->
flags & AK_STUCK) ? CHAN_AKICK_VIEW_FORMAT_STUCK :
CHAN_AKICK_VIEW_FORMAT), index + 1,
- ((akick->flags & AK_ISNICK) ? akick->u.nc->
- display : akick->u.mask),
- akick->creator ? akick->creator : getstring(u,
+ ((akick->flags & AK_ISNICK) ? akick->nc->
+ display : akick->mask.c_str()),
+ !akick->creator.empty() ? akick->creator.c_str() : getstring(u,
UNKNOWN),
timebuf,
- (akick->reason ? akick->
- reason : getstring(u, NO_REASON)));
+ (!akick->reason.empty() ? akick->
+ reason.c_str() : getstring(u, NO_REASON)));
return 1;
}
@@ -150,7 +128,7 @@ int akick_view_callback(User * u, int num, va_list args)
{
ChannelInfo *ci = va_arg(args, ChannelInfo *);
int *sent_header = va_arg(args, int *);
- if (num < 1 || num > ci->akickcount)
+ if (num < 1 || num > ci->akick.size())
return 0;
return akick_view(u, num - 1, ci, sent_header);
}
@@ -168,477 +146,424 @@ int get_access_nc(NickCore *nc, ChannelInfo *ci)
class CommandCSAKick : public Command
{
- public:
- CommandCSAKick() : Command("AKICK", 2, 4)
+ void DoAdd(User *u, ChannelInfo *ci, std::vector<ci::string> &params)
{
- }
-
- CommandReturn Execute(User *u, std::vector<ci::string> &params)
- {
- const char *chan = params[0].c_str();
- ci::string cmd = params[1];
- const char *mask = params.size() > 2 ? params[2].c_str() : NULL;
- const char *reason = NULL;
-
- if (params.size() > 3)
- {
- params[3].resize(200); // XXX: is this right?
- reason = params[3].c_str();
- }
-
- ChannelInfo *ci = cs_findchan(chan);
+ ci::string mask = params[2];
+ ci::string reason = params.size() > 3 ? params[3] : "";
+ NickAlias *na = findnick(mask.c_str());
+ NickCore *nc = NULL;
AutoKick *akick;
int i;
- Channel *c;
- struct c_userlist *cu = NULL;
- struct c_userlist *unext;
- User *u2;
- const char *argv[3];
- int count = 0;
- if (!mask && (cmd == "ADD" || cmd == "STICK" || cmd == "UNSTICK" || cmd == "DEL"))
- syntax_error(s_ChanServ, u, "AKICK", CHAN_AKICK_SYNTAX);
- else if (!check_access(u, ci, CA_AKICK) && !u->nc->HasPriv("chanserv/access/modify"))
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- else if (cmd == "ADD") {
- NickAlias *na = findnick(mask), *na2;
- NickCore *nc = NULL;
+ if (!na)
+ {
const char *nick, *user, *host;
- int freemask = 0;
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
- return MOD_CONT;
- }
+ split_usermask(mask.c_str(), &nick, &user, &host);
+ mask = ci::string(nick) + "!" + user + "@" + host;
+ delete [] nick;
+ delete [] user;
+ delete [] host;
+ }
+ else
+ {
+ if (na->status & NS_FORBIDDEN)
+ {
+ notice_lang(s_ChanServ, u, NICK_X_FORBIDDEN, mask.c_str());
+ return;
+ }
- if (!na) {
- split_usermask(mask, &nick, &user, &host);
- std::string smask = std::string(nick) + "!" + user + "@" + host;
- freemask = 1;
- mask = sstrdup(smask.c_str());
- delete [] nick;
- delete [] user;
- delete [] host;
- } else {
- if (na->status & NS_FORBIDDEN) {
- notice_lang(s_ChanServ, u, NICK_X_FORBIDDEN, mask);
- return MOD_CONT;
- }
- nc = na->nc;
- }
+ nc = na->nc;
+ }
- /* Check excepts BEFORE we get this far */
- if (ModeManager::FindChannelModeByName(CMODE_EXCEPT))
- {
- if (is_excepted_mask(ci, mask) == 1) {
- notice_lang(s_ChanServ, u, CHAN_EXCEPTED, mask, chan);
- if (freemask)
- delete [] mask;
- return MOD_CONT;
- }
- }
+ /* Check excepts BEFORE we get this far */
+ if (ModeManager::FindChannelModeByName(CMODE_EXCEPT))
+ {
+ if (is_excepted_mask(ci, mask.c_str()))
+ {
+ notice_lang(s_ChanServ, u, CHAN_EXCEPTED, mask.c_str(), ci->name);
+ return;
+ }
+ }
- /* 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, ACCESS_DENIED);
- if (freemask)
- delete [] 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 (IsFounder(u2, ci) || (get_access(u2, ci) >= get_access(u, ci))) {
- if (match_usermask(mask, u2)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- delete [] 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, ACCESS_DENIED);
+ return;
+ }
+ }
+ 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 (User *u2 = userlist[i]; u2; u2 = u2->next)
+ {
+ if (IsFounder(u2, ci) || (get_access(u2, ci) >= get_access(u, ci)))
+ {
+ if (match_usermask(mask.c_str(), u2))
+ {
+ notice_lang(s_ChanServ, u, ACCESS_DENIED);
+ return;
}
}
}
+ }
+
+
+ /* Match against the lastusermask of all nickalias's with equal
+ * or higher access. - Viper */
+ for (i = 0; i < 1024; i++)
+ {
+ for (NickAlias *na2 = nalists[i]; na2; na2 = na2->next)
+ {
+ if (na2->status & NS_FORBIDDEN)
+ continue;
- /* 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_FORBIDDEN)
- 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 (Anope::Match(buf, mask, false)) {
- notice_lang(s_ChanServ, u, ACCESS_DENIED);
- delete [] mask;
- return MOD_CONT;
- }
+ 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 (Anope::Match(buf, mask.c_str(), false))
+ {
+ notice_lang(s_ChanServ, u, ACCESS_DENIED);
+ return;
}
}
}
- }
+ }
+ }
- 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(s_ChanServ, u, CHAN_AKICK_ALREADY_EXISTS,
- (akick->flags & AK_ISNICK) ? akick->u.nc->
- display : akick->u.mask, chan);
- if (freemask)
- delete [] mask;
- return MOD_CONT;
- }
+ for (unsigned j = 0; j < ci->akick.size(); ++j)
+ {
+ akick = ci->akick[j];
+ if (!(akick->flags & AK_USED))
+ continue;
+ if ((akick->flags & AK_ISNICK) ? akick->nc == nc : akick->mask == mask)
+ {
+ notice_lang(s_ChanServ, u, CHAN_AKICK_ALREADY_EXISTS, (akick->flags & AK_ISNICK) ? akick->nc->display : akick->mask.c_str(), ci->name);
+ return;
}
+ }
- /* 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)
- delete [] mask;
- return MOD_CONT;
- }
- ci->akickcount++;
- ci->akick =
- static_cast<AutoKick *>(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) {
- akick->reason = sstrdup(reason);
- } else {
- akick->reason = NULL;
- }
+ /* 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->akick.size() >= CSAutokickMax)
+ {
+ notice_lang(s_ChanServ, u, CHAN_AKICK_REACHED_LIMIT, CSAutokickMax);
+ return;
+ }
- /* Auto ENFORCE #63 */
- c = findchan(ci->name);
- if (c) {
- cu = c->users;
- while (cu) {
- unext = 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(s_ChanServ, 3, argv);
-
- delete [] argv[2];
- delete [] argv[1];
- delete [] argv[0];
- count++;
+ if (nc)
+ akick = ci->AddAkick(u->nick, nc, !reason.empty() ? reason.c_str() : "");
+ else
+ akick = ci->AddAkick(u->nick, mask.c_str(), !reason.empty() ? reason.c_str() : "");
- }
- cu = unext;
- }
- }
- notice_lang(s_ChanServ, u, CHAN_AKICK_ADDED, mask, chan);
+ notice_lang(s_ChanServ, u, CHAN_AKICK_ADDED, mask.c_str(), ci->name);
- if (count)
- notice_lang(s_ChanServ, u, CHAN_AKICK_ENFORCE_DONE, chan,
- count);
+ this->DoEnforce(u, ci, params);
+ }
- if (freemask)
- delete [] mask;
+ void DoStick(User *u, ChannelInfo *ci, std::vector<ci::string> &params)
+ {
+ NickAlias *na;
+ NickCore *nc;
+ ci::string mask = params[2];
+ unsigned i;
+ AutoKick *akick;
- } else if (cmd == "STICK") {
- NickAlias *na;
- NickCore *nc;
+ if (ci->akick.empty())
+ {
+ notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name);
+ return;
+ }
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
- return MOD_CONT;
- }
+ na = findnick(mask.c_str());
+ nc = (na ? na->nc : NULL);
- if (ci->akickcount == 0) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name);
- return MOD_CONT;
- }
+ for (i = 0; i < ci->akick.size(); ++i)
+ {
+ akick = ci->akick[i];
- na = findnick(mask);
- nc = (na ? na->nc : NULL);
+ if (!(akick->flags & AK_USED) || (akick->flags & AK_ISNICK))
+ continue;
+ if (akick->mask == mask)
+ break;
+ }
- 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->akick.size()) {
+ notice_lang(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask.c_str(), ci->name);
+ return;
+ }
- if (i == ci->akickcount) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask,
- ci->name);
- return MOD_CONT;
- }
+ akick->flags |= AK_STUCK;
+ notice_lang(s_ChanServ, u, CHAN_AKICK_STUCK, akick->mask.c_str(), ci->name);
- akick->flags |= AK_STUCK;
- notice_lang(s_ChanServ, u, CHAN_AKICK_STUCK, akick->u.mask,
- ci->name);
+ if (ci->c)
+ stick_mask(ci, akick);
+ }
- if (ci->c)
- stick_mask(ci, akick);
- } else if (cmd == "UNSTICK") {
- NickAlias *na;
- NickCore *nc;
+ void DoUnStick(User *u, ChannelInfo *ci, std::vector<ci::string> &params)
+ {
+ NickAlias *na;
+ NickCore *nc;
+ AutoKick *akick;
+ unsigned i;
+ ci::string mask = params[2];
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
- return MOD_CONT;
- }
+ if (ci->akick.empty())
+ {
+ notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name);
+ return;
+ }
- if (ci->akickcount == 0) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name);
- return MOD_CONT;
- }
+ na = findnick(mask.c_str());
+ nc = (na ? na->nc : NULL);
- na = findnick(mask);
- nc = (na ? na->nc : NULL);
+ for (i = 0; i < ci->akick.size(); ++i)
+ {
+ akick = ci->akick[i];
- 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 (!(akick->flags & AK_USED) || (akick->flags & AK_ISNICK))
+ continue;
+ if (akick->mask == mask)
+ break;
+ }
- if (i == ci->akickcount) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask,
- ci->name);
- return MOD_CONT;
- }
+ if (i == ci->akick.size())
+ {
+ notice_lang(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask.c_str(), ci->name);
+ return;
+ }
- akick->flags &= ~AK_STUCK;
- notice_lang(s_ChanServ, u, CHAN_AKICK_UNSTUCK, akick->u.mask,
- ci->name);
+ akick->flags &= ~AK_STUCK;
+ notice_lang(s_ChanServ, u, CHAN_AKICK_UNSTUCK, akick->mask.c_str(), ci->name);
+ }
- } else if (cmd == "DEL") {
- int deleted, a, b;
+ void DoDel(User *u, ChannelInfo *ci, std::vector<ci::string> &params)
+ {
+ ci::string mask = params[2];
+ AutoKick *akick;
+ unsigned i;
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
- return MOD_CONT;
- }
+ if (ci->akick.empty())
+ {
+ notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name);
+ return;
+ }
- if (ci->akickcount == 0) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, chan);
- return MOD_CONT;
- }
+ /* Special case: is it a number/list? Only do search if it isn't. */
+ if (isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == strlen(mask.c_str()))
+ {
+ int last = -1, deleted, count;
- /* Special case: is it a number/list? Only do search if it isn't. */
- if (isdigit(*mask) && strspn(mask, "1234567890,-") == strlen(mask)) {
- int last = -1;
- deleted = process_numlist(mask, &count, akick_del_callback, u,
- ci, &last);
- if (!deleted) {
- if (count == 1) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_NO_SUCH_ENTRY,
- last, ci->name);
- } else {
- notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH,
- ci->name);
- }
- } else if (deleted == 1) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED_ONE,
- ci->name);
- } else {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED_SEVERAL,
- deleted, ci->name);
- }
- } else {
- NickAlias *na = findnick(mask);
- NickCore *nc = (na ? na->nc : NULL);
+ deleted = process_numlist(mask.c_str(), &count, akick_del_callback, u, ci, &last);
- 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(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask,
- chan);
- return MOD_CONT;
- }
- notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED, mask, chan);
- 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;
+ if (!deleted)
+ {
+ if (count == 1)
+ notice_lang(s_ChanServ, u, CHAN_AKICK_NO_SUCH_ENTRY, last, ci->name);
+ else
+ notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name);
+ }
+ else if (deleted == 1)
+ notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED_ONE, ci->name);
+ else
+ notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED_SEVERAL, deleted, ci->name);
+ }
+ else
+ {
+ NickAlias *na = findnick(mask.c_str());
+ NickCore *nc = (na ? na->nc : NULL);
- ci->akickcount--;
- }
- ci->akick =
- static_cast<AutoKick *>(srealloc(ci->akick,sizeof(AutoKick) * ci->akickcount));
- }
- } else if (cmd == "LIST") {
- int sent_header = 0;
+ for (i = 0; i < ci->akick.size(); ++i)
+ {
+ akick = ci->akick[i];
- if (ci->akickcount == 0) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, chan);
- 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)
- && !Anope::Match(akick->u.mask, mask, false))
- continue;
- if ((akick->flags & AK_ISNICK)
- && !Anope::Match(akick->u.nc->display, mask, false))
- continue;
- }
- akick_list(u, i, ci, &sent_header);
- }
- }
- if (!sent_header)
- notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH, chan);
-
- } else if (cmd == "VIEW") {
- int sent_header = 0;
- if (ci->akickcount == 0) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, chan);
- 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)
- && !Anope::Match(akick->u.mask, mask, false))
- continue;
- if ((akick->flags & AK_ISNICK)
- && !Anope::Match(akick->u.nc->display, mask, false))
- continue;
- }
- akick_view(u, i, ci, &sent_header);
- }
+ if (!(akick->flags & AK_USED))
+ continue;
+ if (((akick->flags & AK_ISNICK) && akick->nc == nc)
+ || (!(akick->flags & AK_ISNICK)
+ && akick->mask == mask))
+ break;
}
- if (!sent_header)
- notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH, chan);
+
+ if (i == ci->akick.size())
+ {
+ notice_lang(s_ChanServ, u, CHAN_AKICK_NOT_FOUND, mask.c_str(), ci->name);
+ return;
+ }
+
+ ci->EraseAkick(akick);
+
+ notice_lang(s_ChanServ, u, CHAN_AKICK_DELETED, mask.c_str(), ci->name);
+ }
+ }
- } else if (cmd == "ENFORCE") {
- c = findchan(ci->name);
- cu = NULL;
- count = 0;
+ void DoList(User *u, ChannelInfo *ci, std::vector<ci::string> &params)
+ {
+ int sent_header = 0;
+ ci::string mask = params.size() > 2 ? params[2] : "";
+ unsigned i;
+ AutoKick *akick;
- if (!c) {
- notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, ci->name);
- return MOD_CONT;
- }
+ if (ci->akick.empty())
+ {
+ notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name);
+ return;
+ }
- cu = c->users;
+ if (!mask.empty() && isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == strlen(mask.c_str()))
+ process_numlist(mask.c_str(), NULL, akick_list_callback, u, ci, &sent_header);
+ else
+ {
+ for (i = 0; i < ci->akick.size(); ++i)
+ {
+ akick = ci->akick[i];
- while (cu) {
- unext = 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);
+ if (!(akick->flags & AK_USED))
+ continue;
+ if (!mask.empty())
+ {
+ if (!(akick->flags & AK_ISNICK) && !Anope::Match(akick->mask.c_str(), mask.c_str(), false))
+ continue;
+ if ((akick->flags & AK_ISNICK) && !Anope::Match(akick->nc->display, mask.c_str(), false))
+ continue;
+ }
+ akick_list(u, i, ci, &sent_header);
+ }
+ }
- do_kick(s_ChanServ, 3, argv);
+ if (!sent_header)
+ notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name);
- delete [] argv[2];
- delete [] argv[1];
- delete [] argv[0];
+ }
- count++;
- }
- cu = unext;
- }
+ void DoView(User *u, ChannelInfo *ci, std::vector<ci::string> &params)
+ {
+ int sent_header = 0;
+ ci::string mask = params.size() > 2 ? params[2] : "";
+ AutoKick *akick;
+ unsigned i;
- notice_lang(s_ChanServ, u, CHAN_AKICK_ENFORCE_DONE, chan, count);
+ if (ci->akick.empty())
+ {
+ notice_lang(s_ChanServ, u, CHAN_AKICK_LIST_EMPTY, ci->name);
+ return;
+ }
- } else if (cmd == "CLEAR") {
- if (readonly) {
- notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
- return MOD_CONT;
- }
+ if (!mask.empty() && isdigit(*mask.c_str()) && strspn(mask.c_str(), "1234567890,-") == strlen(mask.c_str()))
+ process_numlist(mask.c_str(), NULL, akick_view_callback, u, ci, &sent_header);
+ else
+ {
+ for (i = 0; i < ci->akick.size(); ++i)
+ {
+ akick = ci->akick[i];
- for (akick = ci->akick, i = 0; i < ci->akickcount; akick++, i++) {
- if (!(akick->flags & AK_USED))
+ if (!(akick->flags & AK_USED))
continue;
- akick_del(u, akick);
- }
+ if (!mask.empty())
+ {
+ if (!(akick->flags & AK_ISNICK) && !Anope::Match(akick->mask.c_str(), mask.c_str(), false))
+ continue;
+ if ((akick->flags & AK_ISNICK) && !Anope::Match(akick->nc->display, mask.c_str(), false))
+ continue;
+ }
+ akick_view(u, i, ci, &sent_header);
+ }
+ }
+ if (!sent_header)
+ notice_lang(s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name);
- free(ci->akick);
- ci->akick = NULL;
- ci->akickcount = 0;
+ }
- notice_lang(s_ChanServ, u, CHAN_AKICK_CLEAR, ci->name);
+ void DoEnforce(User *u, ChannelInfo *ci, std::vector<ci::string> &params)
+ {
+ Channel *c = ci->c;
+ c_userlist *cu, *unext;
+ int count = 0;
+ const char *argv[3];
- } else {
- syntax_error(s_ChanServ, u, "AKICK", CHAN_AKICK_SYNTAX);
+ if (!c)
+ {
+ notice_lang(s_ChanServ, u, CHAN_X_NOT_IN_USE, ci->name);
+ return;
}
+
+ cu = c->users;
+
+ while (cu)
+ {
+ unext = 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(s_ChanServ, 3, argv);
+
+ delete [] argv[2];
+ delete [] argv[1];
+ delete [] argv[0];
+ count++;
+ }
+ cu = unext;
+ }
+
+ notice_lang(s_ChanServ, u, CHAN_AKICK_ENFORCE_DONE, ci->name, count);
+ }
+
+ void DoClear(User *u, ChannelInfo *ci, std::vector<ci::string> &params)
+ {
+ ci->ClearAkick();
+ notice_lang(s_ChanServ, u, CHAN_AKICK_CLEAR, ci->name);
+ }
+
+ public:
+ CommandCSAKick() : Command("AKICK", 2, 4)
+ {
+ }
+
+ CommandReturn Execute(User *u, std::vector<ci::string> &params)
+ {
+ ci::string chan = params[0];
+ ci::string cmd = params[1];
+ ci::string mask = params.size() > 2 ? params[2] : "";
+
+ ChannelInfo *ci = cs_findchan(chan.c_str());
+
+ if (mask.empty() && (cmd == "ADD" || cmd == "STICK" || cmd == "UNSTICK" || cmd == "DEL"))
+ this->OnSyntaxError(u);
+ else if (!check_access(u, ci, CA_AKICK) && !u->nc->HasPriv("chanserv/access/modify"))
+ notice_lang(s_ChanServ, u, ACCESS_DENIED);
+ else if (cmd != "LIST" && cmd != "VIEW" && cmd != "ENFORCE" && readonly)
+ notice_lang(s_ChanServ, u, CHAN_AKICK_DISABLED);
+ else if (cmd == "ADD")
+ this->DoAdd(u, ci, params);
+ else if (cmd == "STICK")
+ this->DoStick(u, ci, params);
+ else if (cmd == "UNSTICK")
+ this->DoUnStick(u, ci, params);
+ else if (cmd == "DEL")
+ this->DoDel(u, ci, params);
+ else if (cmd == "LIST")
+ this->DoList(u, ci, params);
+ else if (cmd == "VIEW")
+ this->DoView(u, ci, params);
+ else if (cmd == "ENFORCE")
+ this->DoEnforce(u, ci, params);
+ else if (cmd == "CLEAR")
+ this->DoClear(u, ci, params);
+ else
+ this->OnSyntaxError(u);
+
return MOD_CONT;
}