diff options
| author | Adam <Adam@drink-coca-cola.info> | 2010-05-17 20:33:28 -0400 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2010-06-18 21:03:41 -0400 |
| commit | 17ab4104005cc5098d9152e6c90d54977222dd06 (patch) | |
| tree | d8ffffedcf5537292a4f19faeb5f1e7796969132 /src/core | |
| parent | 2a22d9c2fdf6978858055f1143af0ec40e417424 (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.c | 170 | ||||
| -rw-r--r-- | src/core/cs_access.c | 319 | ||||
| -rw-r--r-- | src/core/cs_akick.c | 269 | ||||
| -rw-r--r-- | src/core/cs_set.c | 8 | ||||
| -rw-r--r-- | src/core/cs_xop.c | 232 | ||||
| -rw-r--r-- | src/core/db_plain.cpp | 5 | ||||
| -rw-r--r-- | src/core/ms_del.c | 64 | ||||
| -rw-r--r-- | src/core/ms_list.c | 119 | ||||
| -rw-r--r-- | src/core/ms_read.c | 111 | ||||
| -rw-r--r-- | src/core/os_session.c | 269 |
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> ¶ms) { - 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); |
