summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorAdam <Adam@drink-coca-cola.info>2010-05-17 20:33:28 -0400
committerAdam <Adam@anope.org>2010-06-18 21:03:41 -0400
commit17ab4104005cc5098d9152e6c90d54977222dd06 (patch)
treed8ffffedcf5537292a4f19faeb5f1e7796969132 /src/core
parent2a22d9c2fdf6978858055f1143af0ec40e417424 (diff)
Removed process_numlist and having to mark everything as "in use" and constantly checking it. Replaced with a better system.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/bs_badwords.c170
-rw-r--r--src/core/cs_access.c319
-rw-r--r--src/core/cs_akick.c269
-rw-r--r--src/core/cs_set.c8
-rw-r--r--src/core/cs_xop.c232
-rw-r--r--src/core/db_plain.cpp5
-rw-r--r--src/core/ms_del.c64
-rw-r--r--src/core/ms_list.c119
-rw-r--r--src/core/ms_read.c111
-rw-r--r--src/core/os_session.c269
10 files changed, 789 insertions, 777 deletions
diff --git a/src/core/bs_badwords.c b/src/core/bs_badwords.c
index 3db6f1e42..ce026e9c4 100644
--- a/src/core/bs_badwords.c
+++ b/src/core/bs_badwords.c
@@ -14,40 +14,106 @@
#include "module.h"
-int badwords_del_callback(User * u, int num, va_list args);
-int badwords_list(User * u, int index, ChannelInfo * ci, int *sent_header);
-int badwords_list_callback(User * u, int num, va_list args);
+class BadwordsListCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ bool SentHeader;
+ public:
+ BadwordsListCallback(User *_u, ChannelInfo *_ci, const std::string &list) : NumberList(list), u(_u), ci(_ci), SentHeader(false)
+ {
+ }
+
+ ~BadwordsListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetBadWordCount())
+ return;
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name.c_str());
+ }
+
+ DoList(u, ci, Number - 1, ci->GetBadWord(Number - 1));
+ }
+
+ static void DoList(User *u, ChannelInfo *ci, unsigned Number, BadWord *bw)
+ {
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_FORMAT, Number + 1, bw->word.c_str(), ((bw->type == BW_SINGLE) ? "(SINGLE)" : ((bw->type == BW_START) ? "(START)" : ((bw->type == BW_END) ? "(END)" : ""))));
+ }
+};
+
+class BadwordsDelCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ unsigned Deleted;
+ public:
+ BadwordsDelCallback(User *_u, ChannelInfo *_ci, const std::string &list) : NumberList(list), u(_u), ci(_ci), Deleted(0)
+ {
+ }
+
+ ~BadwordsDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
+ else if (Deleted == 1)
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_ONE, ci->name.c_str());
+ else
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_SEVERAL, Deleted, ci->name.c_str());
+ }
+
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetBadWordCount())
+ return;
+
+ ++Deleted;
+ ci->EraseBadWord(Number - 1);
+ }
+};
class CommandBSBadwords : public Command
{
private:
CommandReturn DoList(User *u, ChannelInfo *ci, const ci::string &word)
{
- int sent_header = 0;
-
if (!ci->GetBadWordCount())
{
notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_EMPTY, ci->name.c_str());
- return MOD_CONT;
- }
- if (!word.empty() && strspn(word.c_str(), "1234567890,-") == word.length())
- {
- process_numlist(word.c_str(), NULL, badwords_list_callback, u, ci, &sent_header);
}
+ else if (!word.empty() && strspn(word.c_str(), "1234567890,-") == word.length())
+ (new BadwordsListCallback(u, ci, word.c_str()))->Process();
else
{
+ bool SentHeader = false;
+
for (unsigned i = 0; i < ci->GetBadWordCount(); i++)
{
- BadWord *badword = ci->GetBadWord(i);
+ BadWord *bw = ci->GetBadWord(i);
- if (!word.empty() && !Anope::Match(badword->word, word.c_str(), false))
+ if (!word.empty() && !Anope::Match(bw->word, word.c_str(), false))
continue;
- badwords_list(u, i, ci, &sent_header);
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name.c_str());
+ }
+
+ BadwordsListCallback::DoList(u, ci, i, bw);
}
+
+ if (!SentHeader)
+ notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
}
- if (!sent_header)
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
return MOD_CONT;
}
@@ -102,33 +168,7 @@ class CommandBSBadwords : public Command
{
/* Special case: is it a number/list? Only do search if it isn't. */
if (!word.empty() && isdigit(word[0]) && strspn(word.c_str(), "1234567890,-") == word.length())
- {
- int count, deleted, last = -1;
- deleted = process_numlist(word.c_str(), &count, badwords_del_callback, u, ci, &last);
-
- if (!deleted)
- {
- if (count == 1)
- {
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_SUCH_ENTRY, last, ci->name.c_str());
- }
- else
- {
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_NO_MATCH, ci->name.c_str());
- }
- }
- else if (deleted == 1)
- {
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_ONE, ci->name.c_str());
- }
- else
- {
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED_SEVERAL, deleted, ci->name.c_str());
- }
-
- if (deleted)
- ci->CleanBadWords();
- }
+ (new BadwordsDelCallback(u, ci, word.c_str()))->Process();
else
{
unsigned i;
@@ -148,7 +188,7 @@ class CommandBSBadwords : public Command
return MOD_CONT;
}
- ci->EraseBadWord(badword);
+ ci->EraseBadWord(i);
notice_lang(Config.s_BotServ, u, BOT_BADWORDS_DELETED, badword->word.c_str(), ci->name.c_str());
}
@@ -239,48 +279,4 @@ class BSBadwords : public Module
}
};
-int badwords_del_callback(User * u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *last = va_arg(args, int *);
-
- *last = num;
-
- if (num < 1 || num > ci->GetBadWordCount())
- return 0;
-
- ci->GetBadWord(num - 1)->InUse = false;
-
- return 1;
-}
-
-int badwords_list(User * u, int index, ChannelInfo * ci, int *sent_header)
-{
- BadWord *bw = ci->GetBadWord(index);
-
- if (!*sent_header)
- {
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_HEADER, ci->name.c_str());
- *sent_header = 1;
- }
-
- notice_lang(Config.s_BotServ, u, BOT_BADWORDS_LIST_FORMAT, index + 1, bw->word.c_str(),
- ((bw->type == BW_SINGLE) ? "(SINGLE)" : ((bw->type == BW_START) ? "(START)"
- : ((bw->type == BW_END) ? "(END)" : "")))
- );
-
- return 1;
-}
-
-int badwords_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->GetBadWordCount())
- return 0;
-
- return badwords_list(u, num - 1, ci, sent_header);
-}
-
MODULE_INIT(BSBadwords)
diff --git a/src/core/cs_access.c b/src/core/cs_access.c
index 718a7dc0f..f49fca990 100644
--- a/src/core/cs_access.c
+++ b/src/core/cs_access.c
@@ -14,116 +14,151 @@
#include "module.h"
-static int access_del(User * u, ChannelInfo *ci, ChanAccess * access, int *perm, int uacc)
+class AccessListCallback : public NumberList
{
- if (!access->in_use)
- return 0;
- if (uacc <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
+ protected:
+ User *u;
+ ChannelInfo *ci;
+ bool SentHeader;
+ public:
+ AccessListCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : NumberList(numlist), u(_u), ci(_ci), SentHeader(false)
{
- (*perm)++;
- return 0;
}
- NickCore *nc = access->nc;
- access->nc = NULL;
- access->in_use = 0;
- FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, nc));
+ ~AccessListCallback()
+ {
+ if (SentHeader)
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
+ }
- return 1;
-}
+ virtual void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAccessCount())
+ return;
-static int access_del_callback(User * u, int num, va_list args)
-{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *last = va_arg(args, int *);
- int *perm = va_arg(args, int *);
- int uacc = va_arg(args, int);
- if (num < 1 || num > ci->GetAccessCount())
- return 0;
- *last = num;
- return access_del(u, ci, ci->GetAccess(num - 1), perm, uacc);
-}
-
-
-static int access_list(User * u, int index, ChannelInfo * ci, int *sent_header)
-{
- ChanAccess *access = ci->GetAccess(index);
- const char *xop;
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
+ }
- if (!access->in_use)
- return 0;
+ DoList(u, ci, Number - 1, ci->GetAccess(Number - 1));
+ }
- if (!*sent_header)
+ static void DoList(User *u, ChannelInfo *ci, unsigned Number, ChanAccess *access)
{
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
- *sent_header = 1;
+ if (ci->HasFlag(CI_XOP))
+ {
+ const char *xop = get_xop_level(access->level);
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_XOP_FORMAT, Number + 1, xop, access->nc->display);
+ }
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_AXS_FORMAT, Number + 1, access->level, access->nc->display);
}
+};
- if (ci->HasFlag(CI_XOP))
+class AccessViewCallback : public AccessListCallback
+{
+ public:
+ AccessViewCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : AccessListCallback(_u, _ci, numlist)
{
- xop = get_xop_level(access->level);
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_XOP_FORMAT, index + 1, xop, access->nc->display);
}
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_AXS_FORMAT, index + 1, access->level, access->nc->display);
- return 1;
-}
-static int access_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->GetAccessCount())
- return 0;
- return access_list(u, num - 1, ci, sent_header);
-}
-
-static int access_view(User *u, int index, ChannelInfo *ci, int *sent_header)
-{
- ChanAccess *access = ci->GetAccess(index);
- const char *xop;
- char timebuf[64];
- tm tm;
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAccessCount())
+ return;
- if (!access || !access->in_use)
- return 0;
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
+ }
+
+ DoList(u, ci, Number - 1, ci->GetAccess(Number - 1));
+ }
- if (!*sent_header)
+ static void DoList(User *u, ChannelInfo *ci, unsigned Number, ChanAccess *access)
{
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
- *sent_header = 1;
+ char timebuf[64];
+ struct tm tm;
+
+ memset(&timebuf, 0, sizeof(timebuf));
+ if (ci->c && u->Account() && nc_on_chan(ci->c, u->Account()))
+ snprintf(timebuf, sizeof(timebuf), "Now");
+ else if (access->last_seen == 0)
+ snprintf(timebuf, sizeof(timebuf), "Never");
+ else
+ {
+ tm = *localtime(&access->last_seen);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm);
+ }
+
+ if (ci->HasFlag(CI_XOP))
+ {
+ const char *xop = get_xop_level(access->level);
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_XOP_FORMAT, Number + 1, xop, access->nc->display, access->creator.c_str(), timebuf);
+ }
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, access->level, access->nc->display, access->creator.c_str(), timebuf);
}
+};
- memset(&timebuf, 0, sizeof(timebuf));
- if (ci->c && u->Account() && nc_on_chan(ci->c, u->Account()))
- sprintf(timebuf, "Now");
- else if (access->last_seen == 0)
- sprintf(timebuf, "Never");
- else
+class AccessDelCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ unsigned Deleted;
+ std::string Nicks;
+ bool Denied;
+ public:
+ AccessDelCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : NumberList(numlist), u(_u), ci(_ci), Deleted(0), Denied(false)
{
- tm = *localtime(&access->last_seen);
- strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_DATE_TIME_FORMAT, &tm);
}
- if (ci->HasFlag(CI_XOP))
+ ~AccessDelCallback()
{
- xop = get_xop_level(access->level);
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_XOP_FORMAT, index + 1, xop, access->nc->display, access->creator.c_str(), timebuf);
+ if (Denied && !Deleted)
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ else if (!Deleted)
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
+ else
+ {
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci) << ") deleted access of user" << (Deleted == 1 ? " " : "s ") << Nicks << " on " << ci->name;
+
+ if (Deleted == 1)
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_ONE, ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_SEVERAL, Deleted, ci->name.c_str());
+ }
}
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_VIEW_AXS_FORMAT, index + 1, access->level, access->nc->display, access->creator.c_str(), timebuf);
- return 1;
-}
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAccessCount())
+ return;
+
+ ChanAccess *access = ci->GetAccess(Number - 1);
-static int access_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->GetAccessCount())
- return 0;
- return access_view(u, num - 1, ci, sent_header);
-}
+ if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
+ {
+ Denied = true;
+ return;
+ }
+
+ ++Deleted;
+ if (!Nicks.empty())
+ Nicks += ", " + std::string(access->nc->display);
+ else
+ Nicks = access->nc->display;
+
+ FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access->nc));
+
+ ci->EraseAccess(Number - 1);
+ }
+};
class CommandCSAccess : public Command
{
@@ -224,7 +259,7 @@ class CommandCSAccess : public Command
}
access->level = level;
- FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na, level));
+ FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, level));
Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level "
<< access->level << " to " << na->nick << " (group " << nc->display << ") on channel " << ci->name;
@@ -238,10 +273,9 @@ class CommandCSAccess : public Command
return MOD_CONT;
}
- std::string usernick = u->nick;
- ci->AddAccess(nc, level, usernick);
+ ci->AddAccess(nc, level, u->nick);
- FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, na, level));
+ FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level));
Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << ulev << ") set access level "
<< level << " to " << na->nick << " (group " << nc->display << ") on channel " << ci->name;
@@ -249,7 +283,6 @@ class CommandCSAccess : public Command
}
else if (cmd == "DEL")
{
- int deleted;
if (readonly)
{
notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DISABLED);
@@ -264,31 +297,7 @@ class CommandCSAccess : public Command
/* Special case: is it a number/list? Only do search if it isn't. */
if (isdigit(*nick) && strspn(nick, "1234567890,-") == strlen(nick))
- {
- int count, last = -1, perm = 0;
- deleted = process_numlist(nick, &count, access_del_callback, u, ci, &last, &perm, get_access(u, ci));
- if (!deleted)
- {
- if (perm)
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else if (count == 1)
- {
- last = atoi(nick);
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_SUCH_ENTRY, last, ci->name.c_str());
- }
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, ci->name.c_str());
- }
- else
- {
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci)
- << ") deleted access of user" << (deleted == 1 ? " " : "s ") << nick << " on " << chan;
- if (deleted == 1)
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_ONE, ci->name.c_str());
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED_SEVERAL, deleted, ci->name.c_str());
- }
- }
+ (new AccessDelCallback(u, ci, nick))->Process();
else
{
na = findnick(nick);
@@ -297,16 +306,25 @@ class CommandCSAccess : public Command
notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, nick);
return MOD_CONT;
}
+
nc = na->nc;
- access = ci->GetAccess(nc);
- if (!access)
+
+ for (i = 0; i < ci->GetAccessCount(); ++i)
+ {
+ access = ci->GetAccess(i);
+
+ if (access->nc == nc)
+ break;
+ }
+
+ if (i == ci->GetAccessCount())
{
notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NOT_FOUND, nick, chan);
return MOD_CONT;
}
+
if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify"))
{
- deleted = 0;
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
}
else
@@ -314,76 +332,81 @@ class CommandCSAccess : public Command
notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_DELETED, access->nc->display, ci->name.c_str());
Alog() << Config.s_ChanServ << ": " << u->GetMask() << " (level " << get_access(u, ci)
<< ") deleted access of " << na->nick << " (group " << access->nc->display << ") on " << chan;
- access->nc = NULL;
- access->in_use = 0;
- deleted = 1;
- }
- }
-
- if (deleted)
- {
- /* We'll free the access entries no longer in use... */
- ci->CleanAccess();
-
- /* Only call this event if na exists (if they deleted by user, not numlist).
- * The callback for deleting by numlist will call this event otherwise - Adam */
- if (na)
- {
FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc));
+
+ ci->EraseAccess(i);
}
}
}
else if (cmd == "LIST")
{
- int sent_header = 0;
-
if (!ci->GetAccessCount())
{
notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, chan);
return MOD_CONT;
}
if (nick && strspn(nick, "1234567890,-") == strlen(nick))
- process_numlist(nick, NULL, access_list_callback, u, ci, &sent_header);
+ (new AccessListCallback(u, ci, nick))->Process();
else
{
+ bool SentHeader = false;
+
for (i = 0; i < ci->GetAccessCount(); i++)
{
access = ci->GetAccess(i);
+
if (nick && access->nc && !Anope::Match(access->nc->display, nick, false))
continue;
- access_list(u, i, ci, &sent_header);
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
+ }
+
+ AccessListCallback::DoList(u, ci, i, access);
}
+
+ if (SentHeader)
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, chan);
}
- if (!sent_header)
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, chan);
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
}
else if (cmd == "VIEW")
{
- int sent_header = 0;
-
if (!ci->GetAccessCount())
{
notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, chan);
return MOD_CONT;
}
if (nick && strspn(nick, "1234567890,-") == strlen(nick))
- process_numlist(nick, NULL, access_view_callback, u, ci, &sent_header);
+ (new AccessViewCallback(u, ci, nick))->Process();
else
{
+ bool SentHeader = false;
+
for (i = 0; i < ci->GetAccessCount(); ++i)
{
access = ci->GetAccess(i);
+
if (nick && access->nc && !Anope::Match(access->nc->display, nick, false))
continue;
- access_view(u, i, ci, &sent_header);
+
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name.c_str());
+ }
+
+ AccessViewCallback::DoList(u, ci, i, access);
}
+
+ if (SentHeader)
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, chan);
}
- if (!sent_header)
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_NO_MATCH, chan);
- else
- notice_lang(Config.s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name.c_str());
}
else if (cmd == "CLEAR")
{
diff --git a/src/core/cs_akick.c b/src/core/cs_akick.c
index abd00be6a..42b79c362 100644
--- a/src/core/cs_akick.c
+++ b/src/core/cs_akick.c
@@ -45,103 +45,125 @@ static void split_usermask(const char *mask, const char **nick, const char **use
delete [] mask2;
}
-int akick_del_callback(User * u, int num, va_list args)
+class AkickListCallback : public NumberList
{
- ChannelInfo *ci = va_arg(args, ChannelInfo *);
- int *last = va_arg(args, int *);
+ protected:
+ User *u;
+ ChannelInfo *ci;
+ bool SentHeader;
+ public:
+ AkickListCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : NumberList(numlist), u(_u), ci(_ci), SentHeader(false)
+ {
+ }
+
+ ~AkickListCallback()
+ {
+ if (!SentHeader)
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str());
+ }
- *last = num;
+ virtual void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAkickCount())
+ return;
- if (num < 1 || num > ci->GetAkickCount())
- return 0;
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
+ }
- ci->GetAkick(num - 1)->InUse = false;
- return 1;
-}
+ DoList(u, ci, Number - 1, ci->GetAkick(Number - 1));
+ }
+ static void DoList(User *u, ChannelInfo *ci, unsigned index, AutoKick *akick)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_FORMAT, index + 1,
+ ((akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str()),
+ (!akick->reason.empty() ? akick->reason.c_str() : getstring(u, NO_REASON)));
+ }
+};
-int akick_list(User * u, int index, ChannelInfo * ci, int *sent_header)
+class AkickViewCallback : public AkickListCallback
{
- AutoKick *akick = ci->GetAkick(index);
-
- if (!akick->InUse)
- return 0;
- if (!*sent_header) {
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
- *sent_header = 1;
+ public:
+ AkickViewCallback(User *_u, ChannelInfo *_ci, const std::string &numlist) : AkickListCallback(u, ci, numlist)
+ {
}
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_FORMAT, index + 1,
- ((akick->HasFlag(AK_ISNICK)) ? akick->nc->
- display : akick->mask.c_str()),
- (!akick->reason.empty() ? akick->
- reason.c_str() : getstring(u, NO_REASON)));
- return 1;
-}
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAkickCount())
+ return;
-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->GetAkickCount())
- return 0;
- return akick_list(u, num - 1, ci, sent_header);
-}
+ if (!SentHeader)
+ {
+ SentHeader = true;
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
+ }
-int akick_view(User * u, int index, ChannelInfo * ci, int *sent_header)
-{
- AutoKick *akick = ci->GetAkick(index);
- char timebuf[64];
- struct tm tm;
-
- if (!akick->InUse)
- return 0;
- if (!*sent_header) {
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LIST_HEADER, ci->name.c_str());
- *sent_header = 1;
+ DoList(u, ci, Number - 1, ci->GetAkick(Number - 1));
}
- if (akick->addtime) {
- tm = *localtime(&akick->addtime);
- strftime_lang(timebuf, sizeof(timebuf), u,
- STRFTIME_SHORT_DATE_FORMAT, &tm);
- } else {
- snprintf(timebuf, sizeof(timebuf), "%s", getstring(u, UNKNOWN));
+ static void DoList(User *u, ChannelInfo *ci, unsigned index, AutoKick *akick)
+ {
+ char timebuf[64];
+ struct tm tm;
+
+ memset(&timebuf, 0, sizeof(timebuf));
+
+ if (akick->addtime)
+ {
+ tm = *localtime(&akick->addtime);
+ strftime_lang(timebuf, sizeof(timebuf), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ }
+ else
+ snprintf(timebuf, sizeof(timebuf), "%s", getstring(u, UNKNOWN));
+
+ notice_lang(Config.s_ChanServ, u, (akick->HasFlag(AK_STUCK) ? CHAN_AKICK_VIEW_FORMAT_STUCK : CHAN_AKICK_VIEW_FORMAT), index + 1,
+ ((akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str()),
+ !akick->creator.empty() ? akick->creator.c_str() : getstring(u, UNKNOWN), timebuf,
+ (!akick->reason.empty() ? akick->reason.c_str() : getstring(u, NO_REASON)));
+
+ if (akick->last_used)
+ {
+ char last_used[64];
+ tm = *localtime(&akick->last_used);
+ strftime_lang(last_used, sizeof(last_used), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LAST_USED, last_used);
+ }
}
+};
- notice_lang(Config.s_ChanServ, u, (akick->HasFlag(AK_STUCK) ? CHAN_AKICK_VIEW_FORMAT_STUCK : CHAN_AKICK_VIEW_FORMAT), index + 1,
- ((akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str()),
- !akick->creator.empty() ? akick->creator.c_str() : getstring(u, UNKNOWN), timebuf,
- (!akick->reason.empty() ? akick->reason.c_str() : getstring(u, NO_REASON)));
- if (akick->last_used)
+class AkickDelCallback : public NumberList
+{
+ User *u;
+ ChannelInfo *ci;
+ unsigned Deleted;
+ public:
+ AkickDelCallback(User *_u, ChannelInfo *_ci, const std::string &list) : NumberList(list), u(_u), ci(_ci), Deleted(0)
{
- char last_used[64];
- tm = *localtime(&akick->last_used);
- strftime_lang(last_used, sizeof(last_used), u, STRFTIME_SHORT_DATE_FORMAT, &tm);
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_LAST_USED, last_used);
}
- return 1;
-}
-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->GetAkickCount())
- return 0;
- return akick_view(u, num - 1, ci, sent_header);
-}
+ ~AkickDelCallback()
+ {
+ if (!Deleted)
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str());
+ else if (Deleted == 1)
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_ONE, ci->name.c_str());
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_SEVERAL, Deleted, ci->name.c_str());
+ }
-int get_access_nc(NickCore *nc, ChannelInfo *ci)
-{
- ChanAccess *access;
- if (!ci || !nc)
- return 0;
+ void HandleNumber(unsigned Number)
+ {
+ if (Number > ci->GetAkickCount())
+ return;
- if ((access = ci->GetAccess(nc)))
- return access->level;
- return 0;
-}
+ ++Deleted;
+ ci->EraseAkick(Number - 1);
+ }
+};
class CommandCSAKick : public Command
{
@@ -188,7 +210,7 @@ class CommandCSAKick : public Command
* or whether the mask matches a user with higher/equal access - Viper */
if ((ci->HasFlag(CI_PEACE)) && nc)
{
- if ((nc == ci->founder) || (get_access_nc(nc, ci) >= get_access(u, ci)))
+ if ((nc == ci->founder) || (get_access_level(ci, nc) >= get_access(u, ci)))
{
notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
return;
@@ -221,7 +243,7 @@ class CommandCSAKick : public Command
if (na2->HasFlag(NS_FORBIDDEN))
continue;
- if (na2->nc && ((na2->nc == ci->founder) || (get_access_nc(na2->nc, ci) >= get_access(u, ci))))
+ if (na2->nc && ((na2->nc == ci->founder) || (get_access_level(ci, na2->nc) >= get_access(u, ci))))
{
char buf[BUFSIZE];
@@ -238,8 +260,6 @@ class CommandCSAKick : public Command
for (unsigned j = 0; j < ci->GetAkickCount(); ++j)
{
akick = ci->GetAkick(j);
- if (!akick->InUse)
- continue;
if ((akick->HasFlag(AK_ISNICK)) ? akick->nc == nc : akick->mask == mask)
{
notice_lang(Config.s_ChanServ, u, CHAN_AKICK_ALREADY_EXISTS, (akick->HasFlag(AK_ISNICK)) ? akick->nc->display : akick->mask.c_str(), ci->name.c_str());
@@ -259,6 +279,8 @@ class CommandCSAKick : public Command
else
akick = ci->AddAkick(u->nick, mask.c_str(), !reason.empty() ? reason.c_str() : "");
+ FOREACH_MOD(I_OnAkickAdd, OnAkickAdd(u, ci, akick));
+
notice_lang(Config.s_ChanServ, u, CHAN_AKICK_ADDED, mask.c_str(), ci->name.c_str());
this->DoEnforce(u, ci, params);
@@ -285,7 +307,7 @@ class CommandCSAKick : public Command
{
akick = ci->GetAkick(i);
- if (!akick->InUse || akick->HasFlag(AK_ISNICK))
+ if (akick->HasFlag(AK_ISNICK))
continue;
if (akick->mask == mask)
break;
@@ -325,7 +347,7 @@ class CommandCSAKick : public Command
{
akick = ci->GetAkick(i);
- if (!akick->InUse || akick->HasFlag(AK_ISNICK))
+ if (akick->HasFlag(AK_ISNICK))
continue;
if (akick->mask == mask)
break;
@@ -355,25 +377,7 @@ class CommandCSAKick : public Command
/* 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;
-
- deleted = process_numlist(mask.c_str(), &count, akick_del_callback, u, ci, &last);
-
- if (!deleted)
- {
- if (count == 1)
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_SUCH_ENTRY, last, ci->name.c_str());
- else
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_NO_MATCH, ci->name.c_str());
- }
- else if (deleted == 1)
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_ONE, ci->name.c_str());
- else
- notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED_SEVERAL, deleted, ci->name.c_str());
- if (deleted)
- ci->CleanAkick();
- }
+ (new AkickDelCallback(u, ci, mask.c_str()))->Process();
else
{
NickAlias *na = findnick(mask.c_str());
@@ -383,8 +387,6 @@ class CommandCSAKick : public Command
{
akick = ci->GetAkick(i);
- if (!akick->InUse)
- continue;
if (((akick->HasFlag(AK_ISNICK)) && akick->nc == nc)
|| (!(akick->HasFlag(AK_ISNICK))
&& akick->mask == mask))
@@ -397,7 +399,7 @@ class CommandCSAKick : public Command
return;
}
- ci->EraseAkick(akick);
+ ci->EraseAkick(i);
notice_lang(Config.s_ChanServ, u, CHAN_AKICK_DELETED, mask.c_str(), ci->name.c_str());
}
@@ -405,10 +407,7 @@ class CommandCSAKick : public Command
void DoList(User *u, ChannelInfo *ci, const std::vector<ci::string> &params)
{
- int sent_header = 0;
ci::string mask = params.size() > 2 ? params[2] : "";
- unsigned i;
- AutoKick *akick;
if (!ci->GetAkickCount())
{
@@ -417,15 +416,15 @@ class CommandCSAKick : public Command
}
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);
+ (new AkickListCallback(u, ci, mask.c_str()))->Process();
else
{
- for (i = 0; i < ci->GetAkickCount(); ++i)
+ bool SentHeader = false;
+
+ for (unsigned i = 0; i < ci->GetAkickCount(); ++i)
{
- akick = ci->GetAkick(i);
+ AutoKick *akick = ci->GetAkick(i);
- if (!akick->InUse)
- continue;
if (!mask.empty())
{
if (!(akick->HasFlag(AK_ISNICK)) && !Anope::Match(akick->mask.c_str(), mask.c_str(), false))
@@ -433,21 +432,24 @@ class CommandCSAKick : public Command
if ((akick->HasFlag(AK_ISNICK)) && !Anope::Match(akick->nc->display, mask.c_str(), false))
continue;
}
- akick_list(u, i, ci, &sent_header);