summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-11-25 04:52:49 +0000
committerAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-11-25 04:52:49 +0000
commite2c6825cd233a4271f7bdb79c2f294ad7c4566b9 (patch)
tree911308889941bb32e1151910ebf95947c8bb6000 /src
parentfdcc5b5ee1f25a0abdc3925332c3f920578e0591 (diff)
Cleaned up a lot of the channel access reordering code, properly change users with less than voice access on channels to XOP, and fix a potential crashbug after switching to XOP on IRCds that do not support halfop
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/stable@2667 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src')
-rw-r--r--src/chanserv.c45
-rw-r--r--src/core/cs_access.c86
-rw-r--r--src/core/cs_set.c7
-rw-r--r--src/core/cs_xop.c65
4 files changed, 58 insertions, 145 deletions
diff --git a/src/chanserv.c b/src/chanserv.c
index 983c21719..ba1147072 100644
--- a/src/chanserv.c
+++ b/src/chanserv.c
@@ -2747,3 +2747,48 @@ void stick_all(ChannelInfo * ci)
free(av[0]);
}
}
+
+/** Reorder the access list to get rid of unused entries
+ * @param ci The channel to reorder the access of
+ */
+void CleanAccess(ChannelInfo *ci)
+{
+ int a, b;
+
+ if (!ci)
+ return;
+
+ 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, entries on the end of the list may be empty, remove them */
+ for (b = ci->accesscount - 1; b >= 0; --b)
+ {
+ if (ci->access[b].in_use)
+ break;
+ ci->accesscount--;
+ }
+
+ /* Reallocate the access list to only use the memory we need */
+ ci->access = srealloc(ci->access, sizeof(ChanAccess) * ci->accesscount);
+}
+
diff --git a/src/core/cs_access.c b/src/core/cs_access.c
index 5cf0de061..1799e4a14 100644
--- a/src/core/cs_access.c
+++ b/src/core/cs_access.c
@@ -236,14 +236,6 @@ int do_access(User * u)
}
}
- /* All entries should be in use so we no longer need
- * to go over the entire list..
- for (i = 0; i < ci->accesscount; i++) {
- if (!ci->access[i].in_use)
- break;
- }
- */
-
if (i < CSAccessMax) {
ci->accesscount++;
ci->access =
@@ -268,8 +260,9 @@ int do_access(User * u)
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) {
+ int deleted;
+
+ if (readonly) {
notice_lang(s_ChanServ, u, CHAN_ACCESS_DISABLED);
return MOD_CONT;
}
@@ -279,24 +272,8 @@ int do_access(User * u)
return MOD_CONT;
}
- 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;
- }
- }
- }
- }
+ /* Clean the access list to make sure every thing is in use */
+ CleanAccess(ci);
/* Special case: is it a number/list? Only do search if it isn't. */
if (isdigit(*nick) && strspn(nick, "1234567890,-") == strlen(nick)) {
@@ -354,37 +331,7 @@ int do_access(User * u)
}
}
- 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 (i = ci->accesscount - 1; i >= 0; i--) {
- if (ci->access[i].in_use == 1)
- break;
-
- ci->accesscount--;
- }
- ci->access =
- srealloc(ci->access,sizeof(ChanAccess) * ci->accesscount);
+ CleanAccess(ci);
/* 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 */
@@ -392,34 +339,15 @@ int do_access(User * u)
send_event(EVENT_ACCESS_DEL, 3, ci->name, u->nick, na->nick);
else
send_event(EVENT_ACCESS_DEL, 2, ci->name, u->nick);
- }
} else if (stricmp(cmd, "LIST") == 0) {
int sent_header = 0;
- int a, b;
if (ci->accesscount == 0) {
notice_lang(s_ChanServ, u, CHAN_ACCESS_LIST_EMPTY, chan);
return MOD_CONT;
}
- 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;
- }
- }
- }
- }
+ CleanAccess(ci);
if (nick && strspn(nick, "1234567890,-") == strlen(nick)) {
process_numlist(nick, NULL, access_list_callback, u, ci,
diff --git a/src/core/cs_set.c b/src/core/cs_set.c
index 63d99b34e..0ba6430cd 100644
--- a/src/core/cs_set.c
+++ b/src/core/cs_set.c
@@ -765,17 +765,16 @@ int do_set_xop(User * u, ChannelInfo * ci, char *param)
} else if (CHECKLEV(CA_AUTOOP) || CHECKLEV(CA_OPDEOP)
|| CHECKLEV(CA_OPDEOPME)) {
access->level = ACCESS_AOP;
- } else if (ircd->halfop) {
- if (CHECKLEV(CA_AUTOHALFOP) || CHECKLEV(CA_HALFOP)
- || CHECKLEV(CA_HALFOPME)) {
+ } else if (ircd->halfop && (CHECKLEV(CA_AUTOHALFOP) || CHECKLEV(CA_HALFOP)
+ || CHECKLEV(CA_HALFOPME))) {
access->level = ACCESS_HOP;
- }
} else if (CHECKLEV(CA_AUTOVOICE) || CHECKLEV(CA_VOICE)
|| CHECKLEV(CA_VOICEME)) {
access->level = ACCESS_VOP;
} else {
access->in_use = 0;
access->nc = NULL;
+ CleanAccess(ci);
}
}
diff --git a/src/core/cs_xop.c b/src/core/cs_xop.c
index 539bc6fcb..a29756856 100644
--- a/src/core/cs_xop.c
+++ b/src/core/cs_xop.c
@@ -303,13 +303,6 @@ int do_xop(User * u, char *xname, int xlev, int *xmsgs)
}
if (!change) {
- /* All entries should be in use so we no longer need
- * to go over the entire list..
- for (i = 0; i < ci->accesscount; i++)
- if (!ci->access[i].in_use)
- break;
- */
-
if (i < CSAccessMax) {
ci->accesscount++;
ci->access =
@@ -415,40 +408,8 @@ int do_xop(User * u, char *xname, int xlev, int *xmsgs)
deleted = 1;
}
}
- 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 =
- srealloc(ci->access,sizeof(ChanAccess) * ci->accesscount);
- }
+ if (deleted)
+ CleanAccess(ci);
} else if (stricmp(cmd, "LIST") == 0) {
int sent_header = 0;
@@ -500,30 +461,10 @@ int do_xop(User * u, char *xname, int xlev, int *xmsgs)
if (ci->access[i].in_use && ci->access[i].level == xlev) {
ci->access[i].nc = NULL;
ci->access[i].in_use = 0;
- j++;
}
}
- 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;
- }
- }
- }
- }
-
- ci->accesscount = ci->accesscount - j;
+ CleanAccess(ci);
send_event(EVENT_ACCESS_CLEAR, 2, ci->name, u->nick);