summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chanserv.c112
-rw-r--r--src/core/cs_access.c228
-rw-r--r--src/core/cs_akick.c2
-rw-r--r--src/core/cs_set.c7
-rw-r--r--src/core/cs_xop.c125
5 files changed, 185 insertions, 289 deletions
diff --git a/src/chanserv.c b/src/chanserv.c
index a4079cd8b..827f82911 100644
--- a/src/chanserv.c
+++ b/src/chanserv.c
@@ -205,7 +205,8 @@ void get_chanserv_stats(long *nrec, long *memuse)
mem += strlen(ci->url) + 1;
if (ci->email)
mem += strlen(ci->email) + 1;
- mem += ci->accesscount * sizeof(ChanAccess);
+ if (!ci->access.empty())
+ mem += ci->access.size() * sizeof(ChanAccess);
mem += ci->akickcount * sizeof(AutoKick);
for (j = 0; j < ci->akickcount; j++) {
if (!(ci->akick[j].flags & AK_ISNICK)
@@ -393,27 +394,29 @@ void load_cs_dbase()
ci->levels[j] = static_cast<int16>(tmp16);
}
- SAFE(read_int16(&ci->accesscount, f));
- if (ci->accesscount) {
- ci->access = static_cast<ChanAccess *>(scalloc(ci->accesscount, sizeof(ChanAccess)));
- for (j = 0; j < ci->accesscount; j++) {
- SAFE(read_int16(&ci->access[j].in_use, f));
- if (ci->access[j].in_use) {
- SAFE(read_int16(&tmp16, f));
- ci->access[j].level = static_cast<int16>(tmp16);
+ uint16 accesscount = 0;
+ SAFE(read_int16(&accesscount, f));
+ if (accesscount) {
+ for (j = 0; j < accesscount; j++) {
+ uint16 in_use = 0;
+ SAFE(read_int16(&in_use, f));
+ if (in_use) {
+ uint16 level;
+ SAFE(read_int16(&level, f));
+ NickCore *nc;
SAFE(read_string(&s, f));
if (s) {
- ci->access[j].nc = findcore(s);
+ nc = findcore(s);
delete [] s;
}
- if (ci->access[j].nc == NULL)
- ci->access[j].in_use = 0;
- SAFE(read_int32(&tmp32, f));
- ci->access[j].last_seen = tmp32;
+ else
+ nc = NULL;
+ uint32 last_seen;
+ SAFE(read_int32(&last_seen, f));
+ if (nc)
+ ci->AddAccess(nc, level, last_seen);
}
}
- } else {
- ci->access = NULL;
}
SAFE(read_int16(&ci->akickcount, f));
@@ -610,14 +613,15 @@ void save_cs_dbase()
for (j = 0; j < CA_SIZE; j++)
SAFE(write_int16(ci->levels[j], f));
- SAFE(write_int16(ci->accesscount, f));
- for (j = 0; j < ci->accesscount; j++) {
- SAFE(write_int16(ci->access[j].in_use, f));
- if (ci->access[j].in_use) {
- SAFE(write_int16(ci->access[j].level, f));
- SAFE(write_string(ci->access[j].nc->display, f));
- SAFE(write_int32(ci->access[j].last_seen, f));
- }
+ SAFE(write_int16(ci->access.empty() ? 0 : ci->access.size(), f));
+ for (j = 0; j < ci->access.size(); j++) {
+ ChanAccess *access = ci->GetAccess(j);
+ if (!access->in_use)
+ continue;
+ SAFE(write_int16(access->in_use, f));
+ SAFE(write_int16(access->level, f));
+ SAFE(write_string(access->nc->display, f));
+ SAFE(write_int32(access->last_seen, f));
}
SAFE(write_int16(ci->akickcount, f));
@@ -1441,11 +1445,12 @@ void cs_remove_nick(const NickCore * nc)
if (ci->successor == nc)
ci->successor = NULL;
- for (ca = ci->access, j = ci->accesscount; j > 0; ca++, j--) {
- if (ca->in_use && ca->nc == nc) {
- ca->in_use = 0;
- ca->nc = NULL;
- }
+ for (j = ci->access.size(); j > 0; --j)
+ {
+ ca = ci->GetAccess(j - 1);
+
+ if (ca->in_use && ca->nc == nc)
+ ci->EraseAccess(j - 1);
}
for (akick = ci->akick, j = 0; j < ci->akickcount; akick++, j++) {
@@ -1730,8 +1735,6 @@ int delchan(ChannelInfo * ci)
delete [] ci->forbidby;
if (ci->forbidreason)
delete [] ci->forbidreason;
- if (ci->access)
- free(ci->access);
if (debug >= 2) {
alog("debug: delchan() top of the akick list");
}
@@ -1874,26 +1877,6 @@ int is_identified(User * user, ChannelInfo * ci)
/*************************************************************************/
-/* Returns the ChanAccess entry for an user */
-
-ChanAccess *get_access_entry(NickCore * nc, ChannelInfo * ci)
-{
- ChanAccess *access;
- int i;
-
- if (!ci || !nc) {
- return NULL;
- }
-
- for (access = ci->access, i = 0; i < ci->accesscount; access++, i++)
- if (access->in_use && access->nc == nc)
- return access;
-
- return NULL;
-}
-
-/*************************************************************************/
-
/* Return the access level the given user has on the channel. If the
* channel doesn't exist, the user isn't on the access list, or the channel
* is CS_SECURE and the user hasn't IDENTIFY'd with NickServ, return 0. */
@@ -1917,7 +1900,7 @@ int get_access(User * user, ChannelInfo * ci)
if (nick_identified(user)
|| (nick_recognized(user) && !(ci->flags & CI_SECURE)))
- if ((access = get_access_entry(user->nc, ci)))
+ if ((access = ci->GetAccess(user->nc)))
return access->level;
if (nick_identified(user))
@@ -1937,7 +1920,7 @@ void update_cs_lastseen(User * user, ChannelInfo * ci)
if (is_founder(user, ci) || nick_identified(user)
|| (nick_recognized(user) && !(ci->flags & CI_SECURE)))
- if ((access = get_access_entry(user->nc, ci)))
+ if ((access = ci->GetAccess(user->nc)))
access->last_seen = time(NULL);
}
@@ -2117,28 +2100,19 @@ void cs_set_redirect(ChannelInfo * ci, const char *value)
int get_access_level(ChannelInfo * ci, NickAlias * na)
{
ChanAccess *access;
- int num;
- if (!ci || !na) {
+ if (!ci || !na)
return 0;
- }
- if (na->nc == ci->founder) {
+ if (na->nc == ci->founder)
return ACCESS_FOUNDER;
- }
- for (num = 0; num < ci->accesscount; num++) {
-
- access = &ci->access[num];
-
- if (access->nc && access->nc == na->nc && access->in_use) {
- return access->level;
- }
-
- }
-
- return 0;
+ access = ci->GetAccess(na->nc);
+ if (!access)
+ return 0;
+ else
+ return access->level;
}
const char *get_xop_level(int level)
diff --git a/src/core/cs_access.c b/src/core/cs_access.c
index f144bda1b..411462e72 100644
--- a/src/core/cs_access.c
+++ b/src/core/cs_access.c
@@ -52,35 +52,34 @@ static int access_del_callback(User * u, int num, va_list args)
int *last = va_arg(args, int *);
int *perm = va_arg(args, int *);
int uacc = va_arg(args, int);
- if (num < 1 || num > ci->accesscount)
+ if (num < 1 || num > ci->access.size())
return 0;
*last = num;
- return access_del(u, ci, &ci->access[num - 1], perm, uacc);
+ return access_del(u, ci, ci->GetAccess(num - 1), perm, uacc);
}
-static int access_list(User * u, int index, ChannelInfo * ci,
- int *sent_header)
+static int access_list(User * u, int index, ChannelInfo * ci, int *sent_header)
{
- ChanAccess *access = &ci->access[index];
+ ChanAccess *access = ci->GetAccess(index);
const char *xop;
if (!access->in_use)
return 0;
- if (!*sent_header) {
+ if (!*sent_header)
+ {
notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_HEADER, ci->name);
*sent_header = 1;
}
- if (ci->flags & CI_XOP) {
+ if (ci->flags & CI_XOP)
+ {
xop = get_xop_level(access->level);
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_XOP_FORMAT, index + 1,
- xop, access->nc->display);
- } else {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_AXS_FORMAT, index + 1,
- access->level, access->nc->display);
+ notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_XOP_FORMAT, index + 1, xop, access->nc->display);
}
+ else
+ notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_AXS_FORMAT, index + 1, access->level, access->nc->display);
return 1;
}
@@ -88,7 +87,7 @@ 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->accesscount)
+ if (num < 1 || num > ci->access.size())
return 0;
return access_list(u, num - 1, ci, sent_header);
}
@@ -116,34 +115,35 @@ class CommandCSAccess : public Command
unsigned i;
int level = 0, ulev;
- int is_list = (cmd && stricmp(cmd, "LIST") == 0);
+ int is_list = (cmd && !stricmp(cmd, "LIST"));
/* If LIST, we don't *require* any parameters, but we can take any.
* If DEL, we require a nick and no level.
* Else (ADD), we require a level (which implies a nick). */
- if (!cmd || ((is_list || !stricmp(cmd, "CLEAR")) ? 0 :
- (stricmp(cmd, "DEL") == 0) ? (!nick || s) : !s)) {
+ if (!cmd || ((is_list || !stricmp(cmd, "CLEAR")) ? 0 : (!stricmp(cmd, "DEL")) ? (!nick || s) : !s))
this->OnSyntaxError(u);
- } else if (!(ci = cs_findchan(chan))) {
+ else if (!(ci = cs_findchan(chan)))
notice_lang(s_ChanServ, u, CHAN_X_NOT_REGISTERED, chan);
- } else if (ci->flags & CI_FORBIDDEN) {
+ else if (ci->flags & CI_FORBIDDEN)
notice_lang(s_ChanServ, u, CHAN_X_FORBIDDEN, chan);
- /* We still allow LIST in xOP mode, but not others */
- } else if ((ci->flags & CI_XOP) && !is_list) {
+ /* We still allow LIST in xOP mode, but not others */
+ else if ((ci->flags & CI_XOP) && !is_list)
+ {
if (ircd->halfop)
notice_lang(s_ChanServ, u, CHAN_ACCESS_XOP_HOP, s_ChanServ);
else
notice_lang(s_ChanServ, u, CHAN_ACCESS_XOP, s_ChanServ);
- } else if (
- (
+ }
+ else if ((
(is_list && !check_access(u, ci, CA_ACCESS_LIST) && !u->nc->HasCommand("chanserv/access/list"))
||
(!is_list && !check_access(u, ci, CA_ACCESS_CHANGE) && !u->nc->HasPriv("chanserv/access/modify"))
))
- {
notice_lang(s_ChanServ, u, ACCESS_DENIED);
- } else if (stricmp(cmd, "ADD") == 0) {
- if (readonly) {
+ else if (!stricmp(cmd, "ADD"))
+ {
+ if (readonly)
+ {
notice_lang(s_ChanServ, u, CHAN_ACCESS_DISABLED);
return MOD_CONT;
}
@@ -157,82 +157,76 @@ class CommandCSAccess : public Command
return MOD_CONT;
}
- if (level == 0) {
+ if (!level)
+ {
notice_lang(s_ChanServ, u, CHAN_ACCESS_LEVEL_NONZERO);
return MOD_CONT;
- } else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LEVEL_RANGE,
- ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
+ }
+ else if (level <= ACCESS_INVALID || level >= ACCESS_FOUNDER)
+ {
+ notice_lang(s_ChanServ, u, CHAN_ACCESS_LEVEL_RANGE, ACCESS_INVALID + 1, ACCESS_FOUNDER - 1);
return MOD_CONT;
}
na = findnick(nick);
- if (!na) {
+ if (!na)
+ {
notice_lang(s_ChanServ, u, CHAN_ACCESS_NICKS_ONLY);
return MOD_CONT;
}
- if (na->status & NS_FORBIDDEN) {
+ if (na->status & NS_FORBIDDEN)
+ {
notice_lang(s_ChanServ, u, NICK_X_FORBIDDEN, nick);
return MOD_CONT;
}
nc = na->nc;
- for (access = ci->access, i = 0; i < ci->accesscount;
- access++, i++) {
- if (access->nc == nc) {
- /* Don't allow lowering from a level >= ulev */
- if (access->level >= ulev && !u->nc->HasPriv("chanserv/access/change"))
- {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- return MOD_CONT;
- }
- if (access->level == level) {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LEVEL_UNCHANGED,
- access->nc->display, chan, level);
- return MOD_CONT;
- }
- access->level = level;
- snprintf(event_access, BUFSIZE, "%d", access->level);
- send_event(EVENT_ACCESS_CHANGE, 4, ci->name, u->nick,
- na->nick, event_access);
- alog("%s: %s!%s@%s (level %d) set access level %d to %s (group %s) on channel %s", s_ChanServ, u->nick, u->GetIdent().c_str(), u->host, ulev, access->level, na->nick, nc->display, ci->name);
- notice_lang(s_ChanServ, u, CHAN_ACCESS_LEVEL_CHANGED,
- access->nc->display, chan, level);
+ access = ci->GetAccess(nc);
+ if (access)
+ {
+ /* Don't allow lowering from a level >= ulev */
+ if (access->level >= ulev && !u->nc->HasPriv("chanserv/access/change"))
+ {
+ notice_lang(s_ChanServ, u, PERMISSION_DENIED);
+ return MOD_CONT;
+ }
+ if (access->level == level)
+ {
+ notice_lang(s_ChanServ, u, CHAN_ACCESS_LEVEL_UNCHANGED, access->nc->display, chan, level);
return MOD_CONT;
}
+ access->level = level;
+ snprintf(event_access, BUFSIZE, "%d", access->level);
+ send_event(EVENT_ACCESS_CHANGE, 4, ci->name, u->nick, na->nick, event_access);
+ alog("%s: %s!%s@%s (level %d) set access level %d to %s (group %s) on channel %s", s_ChanServ, u->nick, u->GetIdent().c_str(), u->host, ulev, access->level, na->nick, nc->display, ci->name);
+ notice_lang(s_ChanServ, u, CHAN_ACCESS_LEVEL_CHANGED, access->nc->display, chan, level);
+ return MOD_CONT;
}
- if (i < CSAccessMax) {
- ci->accesscount++;
- ci->access =
- static_cast<ChanAccess *>(srealloc(ci->access,
- sizeof(ChanAccess) * ci->accesscount));
- } else {
- notice_lang(s_ChanServ, u, CHAN_ACCESS_REACHED_LIMIT,
- CSAccessMax);
+ if (ci->access.size() >= CSAccessMax)
+ {
+ notice_lang(s_ChanServ, u, CHAN_ACCESS_REACHED_LIMIT, CSAccessMax);
return MOD_CONT;
}
- access = &ci->access[i];
- access->nc = nc;
- access->in_use = 1;
- access->level = level;
- access->last_seen = 0;
+ ci->AddAccess(nc, level);
snprintf(event_access, BUFSIZE, "%d", access->level);
- send_event(EVENT_ACCESS_ADD, 4, ci->name, u->nick, na->nick,
- event_access);
+ send_event(EVENT_ACCESS_ADD, 4, ci->name, u->nick, na->nick, event_access);
alog("%s: %s!%s@%s (level %d) set access level %d to %s (group %s) on channel %s", s_ChanServ, u->nick, u->GetIdent().c_str(), u->host, ulev, access->level, na->nick, nc->display, ci->name);
- notice_lang(s_ChanServ, u, CHAN_ACCESS_ADDED, nc->display,
- ci->name, access->level);
- } else if (stricmp(cmd, "DEL") == 0) {
- int deleted, a, b;
- if (readonly) {
+ notice_lang(s_ChanServ, u, CHAN_ACCESS_ADDED, nc->display, ci->name, access->level);
+ }
+ else if (!stricmp(cmd, "DEL"))
+ {
+ int deleted;
+ if (readonly)
+ {
notice_lang(s_ChanServ, u, CHAN_ACCESS_DISABLED);
return MOD_CONT;
}
- if (ci->accesscount == 0) {
+ if (ci->access.empty())
+ {
notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, chan);
return MOD_CONT;
}
@@ -241,8 +235,7 @@ class CommandCSAccess : public Command
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));
+ deleted = process_numlist(nick, &count, access_del_callback, u, ci, &last, &perm, get_access(u, ci));
if (!deleted)
{
if (perm)
@@ -273,15 +266,12 @@ class CommandCSAccess : public Command
return MOD_CONT;
}
nc = na->nc;
- for (i = 0; i < ci->accesscount; i++)
- if (ci->access[i].nc == nc)
- break;
- if (i == ci->accesscount)
+ access = ci->GetAccess(nc);
+ if (!access)
{
notice_lang(s_ChanServ, u, CHAN_ACCESS_NOT_FOUND, nick, chan);
return MOD_CONT;
}
- access = &ci->access[i];
if (get_access(u, ci) <= access->level && !u->nc->HasPriv("chanserv/access/change"))
{
deleted = 0;
@@ -297,37 +287,10 @@ class CommandCSAccess : public Command
}
}
- if (deleted) {
- /* Reordering - DrStein */
- for (b = 0; b < ci->accesscount; b++) {
- if (ci->access[b].in_use) {
- for (a = 0; a < ci->accesscount; a++) {
- if (a > b)
- break;
- if (!ci->access[a].in_use) {
- ci->access[a].in_use = 1;
- ci->access[a].level = ci->access[b].level;
- ci->access[a].nc = ci->access[b].nc;
- ci->access[a].last_seen =
- ci->access[b].last_seen;
- ci->access[b].nc = NULL;
- ci->access[b].in_use = 0;
- break;
- }
- }
- }
- }
-
- /* After reordering only the entries at the end could still be empty.
- * We ll free the places no longer in use... */
- for (int j = ci->accesscount - 1; j >= 0; j--) {
- if (ci->access[j].in_use == 1)
- break;
-
- ci->accesscount--;
- }
- ci->access =
- static_cast<ChanAccess *>(srealloc(ci->access,sizeof(ChanAccess) * ci->accesscount));
+ if (deleted)
+ {
+ /* We'll free the access entries no longer in use... */
+ ci->CleanAccess();
/* We don't know the nick if someone used numbers, so we trigger the event without
* nick param. We just do this once, even if someone enters a range. -Certus */
@@ -336,32 +299,37 @@ class CommandCSAccess : public Command
else
send_event(EVENT_ACCESS_DEL, 2, ci->name, u->nick);
}
- } else if (stricmp(cmd, "LIST") == 0) {
+ }
+ else if (!stricmp(cmd, "LIST"))
+ {
int sent_header = 0;
- if (ci->accesscount == 0) {
+ if (ci->access.empty())
+ {
notice_lang(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);
- } else {
- for (i = 0; i < ci->accesscount; i++) {
- if (nick && ci->access[i].nc
- && !Anope::Match(ci->access[i].nc->display, nick, false))
+ if (nick && strspn(nick, "1234567890,-") == strlen(nick))
+ process_numlist(nick, NULL, access_list_callback, u, ci, &sent_header);
+ else
+ {
+ for (i = 0; i < ci->access.size(); 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 (!sent_header) {
+ if (!sent_header)
notice_lang(s_ChanServ, u, CHAN_ACCESS_NO_MATCH, chan);
- } else {
+ else
notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_FOOTER, ci->name);
- }
- } else if (stricmp(cmd, "CLEAR") == 0) {
-
- if (readonly) {
+ }
+ else if (!stricmp(cmd, "CLEAR"))
+ {
+ if (readonly)
+ {
notice_lang(s_ChanServ, u, CHAN_ACCESS_DISABLED);
return MOD_CONT;
}
@@ -372,9 +340,7 @@ class CommandCSAccess : public Command
return MOD_CONT;
}
- free(ci->access);
- ci->access = NULL;
- ci->accesscount = 0;
+ ci->ClearAccess();
send_event(EVENT_ACCESS_CLEAR, 2, ci->name, u->nick);
@@ -383,9 +349,9 @@ class CommandCSAccess : public Command
s_ChanServ, u->nick, u->GetIdent().c_str(), u->host,
get_access(u, ci), chan);
- } else {
- this->OnSyntaxError(u);
}
+ else
+ this->OnSyntaxError(u);
return MOD_CONT;
}
diff --git a/src/core/cs_akick.c b/src/core/cs_akick.c
index 753ebd64f..229678780 100644
--- a/src/core/cs_akick.c
+++ b/src/core/cs_akick.c
@@ -176,7 +176,7 @@ int get_access_nc(NickCore *nc, ChannelInfo *ci)
if (!ci || !nc)
return 0;
- if ((access = get_access_entry(nc, ci)))
+ if ((access = ci->GetAccess(nc)))
return access->level;
return 0;
}
diff --git a/src/core/cs_set.c b/src/core/cs_set.c
index f9426b510..76ec975b8 100644
--- a/src/core/cs_set.c
+++ b/src/core/cs_set.c
@@ -464,8 +464,8 @@ class CommandCSSet : public Command
int i;
ChanAccess *access;
- for (access = ci->access, i = 0; i < ci->accesscount;
- access++, i++) {
+ for (i = 0; i < ci->access.size(); i++) {
+ access = ci->GetAccess(i);
if (!access->in_use)
continue;
/* This will probably cause wrong levels to be set, but hey,
@@ -490,6 +490,9 @@ class CommandCSSet : public Command
}
}
+ /* The above may have set an access entry to not be in use, this will clean that up. */
+ ci->CleanAccess();
+
reset_levels(ci);
ci->flags |= CI_XOP;
}
diff --git a/src/core/cs_xop.c b/src/core/cs_xop.c
index 6f2c302e8..ea603c1c0 100644
--- a/src/core/cs_xop.c
+++ b/src/core/cs_xop.c
@@ -109,7 +109,7 @@ class XOPBase : public Command
{
const char *nick = params.size() > 2 ? params[2].c_str() : NULL;
ChanAccess *access;
- int change = 0, i;
+ int change = 0;
char event_access[BUFSIZE];
if (!nick)
@@ -145,43 +145,33 @@ class XOPBase : public Command
}
NickCore *nc = na->nc;
- for (access = ci->access, i = 0; i < ci->accesscount; ++access, ++i)
+ access = ci->GetAccess(nc);
+ if (access)
{
- if (access->nc == nc)
+ /**
+ * Patch provided by PopCorn to prevert AOP's reducing SOP's levels
+ **/
+ if (access->level >= ulev && !u->nc->HasPriv("chanserv/access/modify"))
{
- /**
- * Patch provided by PopCorn to prevert AOP's reducing SOP's levels
- **/
- if (access->level >= ulev && !u->nc->HasPriv("chanserv/access/modify"))
- {
- notice_lang(s_ChanServ, u, PERMISSION_DENIED);
- return MOD_CONT;
- }
- ++change;
- break;
+ notice_lang(s_ChanServ, u, PERMISSION_DENIED);
+ return MOD_CONT;
}
+ ++change;
}
- if (!change)
+ if (!change && ci->access.size() >= CSAccessMax)
{
- if (i < CSAccessMax)
- {
- ++ci->accesscount;
- ci->access = static_cast<ChanAccess *>(srealloc(ci->access, sizeof(ChanAccess) * ci->accesscount));
- }
- else
- {
- notice_lang(s_ChanServ, u, CHAN_XOP_REACHED_LIMIT, CSAccessMax);
- return MOD_CONT;
- }
-
- access = &ci->access[i];
- access->nc = nc;
+ notice_lang(s_ChanServ, u, CHAN_XOP_REACHED_LIMIT, CSAccessMax);
+ return MOD_CONT;
}
- access->in_use = 1;
- access->level = level;
- access->last_seen = 0;
+ if (!change)
+ ci->AddAccess(nc, level);
+ else
+ {
+ access->level = level;
+ access->last_seen = 0;
+ }
alog("%s: %s!%s@%s (level %d) %s access level %d to %s (group %s) on channel %s", s_ChanServ, u->nick, u->GetIdent().c_str(), u->host, ulev, change ? "changed" : "set", access->level, na->nick, nc->display, ci->name);
@@ -205,9 +195,8 @@ class XOPBase : public Command
{
const char *nick = params.size() > 2 ? params[2].c_str() : NULL;
ChanAccess *access;
- int i;
- int deleted, a, b;
+ int deleted;
if (!nick)
{
@@ -221,7 +210,7 @@ class XOPBase : public Command
return MOD_CONT;
}
- if (!ci->accesscount)
+ if (ci->access.empty())
{
notice_lang(s_ChanServ, u, messages[XOP_LIST_EMPTY], ci->name);
return MOD_CONT;
@@ -266,18 +255,14 @@ class XOPBase : public Command
return MOD_CONT;
}
NickCore *nc = na->nc;
+ access = ci->GetAccess(nc, level);
- for (i = 0; i < ci->accesscount; ++i)
- if (ci->access[i].nc == nc && ci->access[i].level == level)
- break;
-
- if (i == ci->accesscount)
+ if (!access)
{
notice_lang(s_ChanServ, u, messages[XOP_NOT_FOUND], nick, ci->name);
return MOD_CONT;
}
- access = &ci->access[i];
if (ulev <= access->level && !u->nc->HasPriv("chanserv/access/change"))
{
deleted = 0;
@@ -294,41 +279,10 @@ class XOPBase : public Command
}
if (deleted)
{
- /* Reordering - DrStein */
- for (b = 0; b < ci->accesscount; ++b)
- {
- if (ci->access[b].in_use)
- {
- for (a = 0; a < ci->accesscount; ++a)
- {
- if (a > b)
- break;
- if (!ci->access[a].in_use)
- {
- ci->access[a].in_use = 1;
- ci->access[a].level = ci->access[b].level;
- ci->access[a].nc = ci->access[b].nc;
- ci->access[a].last_seen = ci->access[b].last_seen;
- ci->access[b].nc = NULL;
- ci->access[b].in_use = 0;
- break;
- }
- }
- }
- }
-
/* If the patch provided in bug #706 is applied, this should be placed
* before sending the events! */
- /* After reordering only the entries at the end could still be empty.
- * We ll free the places no longer in use... */
- for (i = ci->accesscount - 1; i >= 0; --i)
- {
- if (ci->access[i].in_use == 1)
- break;
-
- --ci->accesscount;
- }
- ci->access = static_cast<ChanAccess *>(srealloc(ci->access, sizeof(ChanAccess) * ci->accesscount));
+ /* We'll free the access entries no longer in use... */
+ ci->CleanAccess();
}
return MOD_CONT;
@@ -345,7 +299,7 @@ class XOPBase : public Command
return MOD_CONT;
}
- if (!ci->accesscount)
+ if (ci->access.empty())
{
notice_lang(s_ChanServ, u, messages[XOP_LIST_EMPTY], ci->name);
return MOD_CONT;
@@ -355,9 +309,10 @@ class XOPBase : public Command
process_numlist(nick, NULL, xop_list_callback, u, ci, &sent_header, level, messages[XOP_LIST_HEADER]);
else
{
- for (int i = 0; i < ci->accesscount; ++i)
+ for (int i = 0; i < ci->access.size(); ++i)
{
- if (nick && ci->access[i].nc && !Anope::Match(ci->access[i].nc->display, nick, false))
+ ChanAccess *access = ci->GetAccess(i);
+ if (nick && access->nc && !Anope::Match(access->nc->display, nick, false))
continue;
xop_list(u, i, ci, &sent_header, level, messages[XOP_LIST_HEADER]);
}
@@ -376,7 +331,7 @@ class XOPBase : public Command
return MOD_CONT;
}
- if (!ci->accesscount)
+ if (ci->access.empty())
{
notice_lang(s_ChanServ, u, messages[XOP_LIST_EMPTY], ci->name);
return MOD_CONT;
@@ -388,13 +343,11 @@ class XOPBase : public Command
return MOD_CONT;
}
- for (int i = 0; i < ci->accesscount; ++i)
+ for (unsigned i = ci->access.size(); i > 0; --i)
{
- if (ci->access[i].in_use && ci->access[i].level == level)
- {
- ci->access[i].nc = NULL;
- ci->access[i].in_use = 0;
- }
+ ChanAccess *access = ci->GetAccess(i - 1);
+ if (access->in_use && access->level == level)
+ ci->EraseAccess(i - 1);
}
send_event(EVENT_ACCESS_CLEAR, 2, ci->name, u->nick);
@@ -600,17 +553,17 @@ int xop_del_callback(User *u, int num, va_list args)
int uacc = va_arg(args, int);
int xlev = va_arg(args, int);
- if (num < 1 || num > ci->accesscount)
+ if (num < 1 || num > ci->access.size())
return 0;
*last = num;
- return xop_del(u, ci, &ci->access[num - 1], perm, uacc, xlev);
+ return xop_del(u, ci, ci->GetAccess(num - 1), perm, uacc, xlev);
}
int xop_list(User *u, int index, ChannelInfo *ci, int *sent_header, int xlev, int xmsg)
{
- ChanAccess *access = &ci->access[index];
+ ChanAccess *access = ci->GetAccess(index);
if (!access->in_use || access->level != xlev)
return 0;
@@ -632,7 +585,7 @@ int xop_list_callback(User *u, int num, va_list args)
int xlev = va_arg(args, int);
int xmsg = va_arg(args, int);
- if (num < 1 || num > ci->accesscount)
+ if (num < 1 || num > ci->access.size())
return 0;
return xop_list(u, num - 1, ci, sent_header, xlev, xmsg);