summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorviper viper@31f1291d-b8d6-0310-a050-a5561fc1590b <viper viper@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864>2008-09-03 20:11:12 +0000
committerviper viper@31f1291d-b8d6-0310-a050-a5561fc1590b <viper viper@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864>2008-09-03 20:11:12 +0000
commit790dc8a4bf326a7598fc41aa8c018e867edee33a (patch)
tree281aa0f14877734a92336a21355eb945a8d1517e /src
parent482a8aa766c9e1a96ff63b44ed319fe51588c35c (diff)
BUILD : 1.7.21 (1426) BUGS : 876 NOTES : We now support CIDR in channel ban/invite/except lists. Introduces new CIDR capable generic lists system.
git-svn-id: svn://svn.anope.org/anope/trunk@1426 31f1291d-b8d6-0310-a050-a5561fc1590b git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@1141 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src')
-rw-r--r--src/actions.c57
-rw-r--r--src/botserv.c33
-rw-r--r--src/channels.c592
-rw-r--r--src/chanserv.c25
-rw-r--r--src/core/cs_clear.c87
-rw-r--r--src/core/os_clearmodes.c79
-rw-r--r--src/misc.c168
-rw-r--r--src/protocol/bahamut.c3
-rw-r--r--src/protocol/charybdis.c9
-rw-r--r--src/protocol/dreamforge.c3
-rw-r--r--src/protocol/hybrid.c7
-rw-r--r--src/protocol/inspircd10.c1
-rw-r--r--src/protocol/inspircd11.c1
-rw-r--r--src/protocol/plexus2.c3
-rw-r--r--src/protocol/plexus3.c3
-rw-r--r--src/protocol/ptlink.c3
-rw-r--r--src/protocol/rageircd.c3
-rw-r--r--src/protocol/ratbox.c3
-rw-r--r--src/protocol/shadowircd.c3
-rw-r--r--src/protocol/solidircd.c3
-rw-r--r--src/protocol/ultimate2.c1
-rw-r--r--src/protocol/ultimate3.c3
-rw-r--r--src/protocol/unreal31.c1
-rw-r--r--src/protocol/unreal32.c3
-rw-r--r--src/protocol/viagra.c1
-rw-r--r--src/users.c50
26 files changed, 801 insertions, 344 deletions
diff --git a/src/actions.c b/src/actions.c
index d7c1ecda1..acf945420 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -130,13 +130,13 @@ void sqline(char *mask, char *reason)
*/
void common_unban(ChannelInfo * ci, char *nick)
{
- int count, i;
- char *av[4], **bans;
- int ac;
+ char *av[4];
+ char *host = NULL;
char buf[BUFSIZE];
+ int ac;
+ uint32 ip = 0;
User *u;
- char *host = NULL;
- int matchfound = 0;
+ Entry *ban, *next;
if (!ci || !ci->c || !nick) {
return;
@@ -146,6 +146,9 @@ void common_unban(ChannelInfo * ci, char *nick)
return;
}
+ if (!ci->c->bans || (ci->c->bans->count == 0))
+ return;
+
if (u->hostip == NULL) {
host = host_resolve(u->host);
/* we store the just resolved hostname so we don't
@@ -156,6 +159,9 @@ void common_unban(ChannelInfo * ci, char *nick)
} else {
host = sstrdup(u->hostip);
}
+ /* Convert the host to an IP.. */
+ if (host)
+ ip = str_is_ip(host);
if (ircd->svsmode_unban) {
anope_cmd_unban(ci->name, nick);
@@ -171,44 +177,21 @@ void common_unban(ChannelInfo * ci, char *nick)
av[1] = sstrdup("-b");
ac = 3;
}
- count = ci->c->bancount;
- bans = scalloc(sizeof(char *) * count, 1);
- memcpy(bans, ci->c->bans, sizeof(char *) * count);
- for (i = 0; i < count; i++) {
- if (match_usermask(bans[i], u)) {
- anope_cmd_mode(whosends(ci), ci->name, "-b %s", bans[i]);
+
+ for (ban = ci->c->bans->entries; ban; ban = next) {
+ next = ban->next;
+ if (entry_match(ban, u->nick, u->username, u->host, ip) ||
+ entry_match(ban, u->nick, u->username, u->vhost, ip)) {
+ anope_cmd_mode(whosends(ci), ci->name, "-b %s", ban->mask);
if (ircdcap->tsmode)
- av[3] = bans[i];
+ av[3] = ban->mask;
else
- av[2] = bans[i];
+ av[2] = ban->mask;
do_cmode(whosends(ci), ac, av);
- matchfound++;
}
- if (host) {
- /* prevent multiple unbans if the first one was successful in
- locating the ban for us. This is due to match_userip() checks
- the vhost again, and thus can return false positive results
- for the function. but won't prevent thus from clearing out
- the bans against an IP address since the first would fail and
- the second would match - TSL
- */
- if (!matchfound) {
- if (match_userip(bans[i], u, host)) {
- anope_cmd_mode(whosends(ci), ci->name, "-b %s",
- bans[i]);
- if (ircdcap->tsmode)
- av[3] = bans[i];
- else
- av[2] = bans[i];
-
- do_cmode(whosends(ci), ac, av);
- }
- }
- }
- matchfound = 0;
}
- free(bans);
+
if (ircdcap->tsmode)
free(av[2]);
else
diff --git a/src/botserv.c b/src/botserv.c
index 57719a003..f8eea632e 100644
--- a/src/botserv.c
+++ b/src/botserv.c
@@ -757,25 +757,17 @@ static UserData *get_user_data(Channel * c, User * u)
void bot_join(ChannelInfo * ci)
{
- int i;
-
if (!ci || !ci->c || !ci->bi)
return;
if (BSSmartJoin) {
/* We check for bans */
- int count = ci->c->bancount;
- if (count) {
- char botmask[BUFSIZE];
+ if (ci->c->bans && ci->c->bans->count) {
char buf[BUFSIZE];
- char **bans = scalloc(sizeof(char *) * count, 1);
char *av[4];
+ Entry *ban, *next;
int ac;
- memcpy(bans, ci->c->bans, sizeof(char *) * count);
- snprintf(botmask, sizeof(botmask), "%s!%s@%s", ci->bi->nick,
- ci->bi->user, ci->bi->host);
-
if (ircdcap->tsmode) {
snprintf(buf, BUFSIZE - 1, "%ld", (long int) time(NULL));
av[0] = ci->c->name;
@@ -788,21 +780,16 @@ void bot_join(ChannelInfo * ci)
ac = 3;
}
- for (i = 0; i < count; i++) {
- if (match_wild_nocase(ci->c->bans[i], botmask)) {
- anope_cmd_mode(ci->bi->nick, ci->name, "-b %s",
- bans[i]);
+ for (ban = ci->c->bans->entries; ban; ban = next) {
+ next = ban->next;
+ if (entry_match(ban, ci->bi->nick, ci->bi->user, ci->bi->host, 0)) {
+ anope_cmd_mode(whosends(ci), ci->name, "-b %s", ban->mask);
if (ircdcap->tsmode)
- av[3] = sstrdup(bans[i]);
+ av[3] = ban->mask;
else
- av[2] = sstrdup(bans[i]);
-
- do_cmode(ci->bi->nick, ac, av);
+ av[2] = ban->mask;
- if (ircdcap->tsmode)
- free(av[3]);
- else
- free(av[2]);
+ do_cmode(whosends(ci), ac, av);
}
}
@@ -810,8 +797,6 @@ void bot_join(ChannelInfo * ci)
free(av[2]);
else
free(av[1]);
-
- free(bans);
}
/* Should we be invited? */
diff --git a/src/channels.c b/src/channels.c
index 297c8b8ec..89beeadc7 100644
--- a/src/channels.c
+++ b/src/channels.c
@@ -427,7 +427,7 @@ void get_channel_stats(long *nrec, long *memuse)
Channel *chan;
struct c_userlist *cu;
BanData *bd;
- int i, j;
+ int i;
for (i = 0; i < 1024; i++) {
for (chan = chanlist[i]; chan; chan = chan->next) {
@@ -445,24 +445,12 @@ void get_channel_stats(long *nrec, long *memuse)
if (chan->redirect)
mem += strlen(chan->redirect) + 1;
}
- mem += sizeof(char *) * chan->bansize;
- for (j = 0; j < chan->bancount; j++) {
- if (chan->bans[j])
- mem += strlen(chan->bans[j]) + 1;
- }
+ mem += get_memuse(chan->bans);
if (ircd->except) {
- mem += sizeof(char *) * chan->exceptsize;
- for (j = 0; j < chan->exceptcount; j++) {
- if (chan->excepts[j])
- mem += strlen(chan->excepts[j]) + 1;
- }
+ mem += get_memuse(chan->excepts);
}
if (ircd->invitemode) {
- mem += sizeof(char *) * chan->invitesize;
- for (j = 0; j < chan->invitecount; j++) {
- if (chan->invite[j])
- mem += strlen(chan->invite[j]) + 1;
- }
+ mem += get_memuse(chan->invites);
}
for (cu = chan->users; cu; cu = cu->next) {
mem += sizeof(*cu);
@@ -1270,6 +1258,7 @@ void do_topic(const char *source, int ac, char **av)
void add_ban(Channel * chan, char *mask)
{
+ Entry *ban;
/* check for NULL values otherwise we will segfault */
if (!chan || !mask) {
if (debug) {
@@ -1278,25 +1267,28 @@ void add_ban(Channel * chan, char *mask)
return;
}
+ /* Check if the list already exists, if not create it.
+ * Create a new ban and add it to the list.. ~ Viper */
+ if (!chan->bans)
+ chan->bans = list_create();
+ ban = entry_add(chan->bans, mask);
+
+ if (!ban)
+ fatal("Creating new ban entry failed");
+
+ /* Check whether it matches a botserv bot after adding internally
+ * and parsing it through cidr support. ~ Viper */
if (s_BotServ && BSSmartJoin && chan->ci && chan->ci->bi
&& chan->usercount >= BSMinUsers) {
- char botmask[BUFSIZE];
BotInfo *bi = chan->ci->bi;
- snprintf(botmask, sizeof(botmask), "%s!%s@%s", bi->nick, bi->user,
- bi->host);
- if (match_wild_nocase(mask, botmask)) {
+ if (entry_match(ban, bi->nick, bi->user, bi->host, 0)) {
anope_cmd_mode(bi->nick, chan->name, "-b %s", mask);
+ entry_delete(chan->bans, ban);
return;
}
}
- if (chan->bancount >= chan->bansize) {
- chan->bansize += 8;
- chan->bans = srealloc(chan->bans, sizeof(char *) * chan->bansize);
- }
- chan->bans[chan->bancount++] = sstrdup(mask);
-
if (debug)
alog("debug: Added ban %s to channel %s", mask, chan->name);
}
@@ -1305,18 +1297,22 @@ void add_ban(Channel * chan, char *mask)
void add_exception(Channel * chan, char *mask)
{
+ Entry *exception;
+
if (!chan || !mask) {
if (debug)
alog("debug: add_exception called with NULL values");
return;
}
- if (chan->exceptcount >= chan->exceptsize) {
- chan->exceptsize += 8;
- chan->excepts =
- srealloc(chan->excepts, sizeof(char *) * chan->exceptsize);
- }
- chan->excepts[chan->exceptcount++] = sstrdup(mask);
+ /* Check if the list already exists, if not create it.
+ * Create a new exception and add it to the list.. ~ Viper */
+ if (!chan->excepts)
+ chan->excepts = list_create();
+ exception = entry_add(chan->excepts, mask);
+
+ if (!exception)
+ fatal("Creating new exception entry failed");
if (debug)
alog("debug: Added except %s to channel %s", mask, chan->name);
@@ -1326,18 +1322,22 @@ void add_exception(Channel * chan, char *mask)
void add_invite(Channel * chan, char *mask)
{
+ Entry *invite;
+
if (!chan || !mask) {
if (debug)
alog("debug: add_invite called with NULL values");
return;
}
- if (chan->invitecount >= chan->invitesize) {
- chan->invitesize += 8;
- chan->invite =
- srealloc(chan->invite, sizeof(char *) * chan->invitesize);
- }
- chan->invite[chan->invitecount++] = sstrdup(mask);
+ /* Check if the list already exists, if not create it.
+ * Create a new invite and add it to the list.. ~ Viper */
+ if (!chan->invites)
+ chan->invites = list_create();
+ invite = entry_add(chan->invites, mask);
+
+ if (!invite)
+ fatal("Creating new exception entry failed");
if (debug)
alog("debug: Added invite %s to channel %s", mask, chan->name);
@@ -1621,7 +1621,6 @@ Channel *chan_create(char *chan, time_t ts)
void chan_delete(Channel * c)
{
BanData *bd, *next;
- int i;
if (debug)
alog("debug: Deleting channel %s", c->name);
@@ -1650,37 +1649,26 @@ void chan_delete(Channel * c)
free(c->redirect);
}
- for (i = 0; i < c->bancount; ++i) {
- if (c->bans[i])
- free(c->bans[i]);
- else
- alog("channel: BUG freeing %s: bans[%d] is NULL!", c->name, i);
+ if (c->bans && c->bans->count) {
+ while (c->bans->entries) {
+ entry_delete(c->bans, c->bans->entries);
+ }
}
- if (c->bansize)
- free(c->bans);
if (ircd->except) {
- for (i = 0; i < c->exceptcount; ++i) {
- if (c->excepts[i])
- free(c->excepts[i]);
- else
- alog("channel: BUG freeing %s: excepts[%d] is NULL!",
- c->name, i);
+ if (c->excepts && c->excepts->count) {
+ while (c->excepts->entries) {
+ entry_delete(c->excepts, c->excepts->entries);
+ }
}
- if (c->exceptsize)
- free(c->excepts);
}
if (ircd->invitemode) {
- for (i = 0; i < c->invitecount; ++i) {
- if (c->invite[i])
- free(c->invite[i]);
- else
- alog("channel: BUG freeing %s: invite[%d] is NULL!",
- c->name, i);
+ if (c->invites && c->invites->count) {
+ while (c->invites->entries) {
+ entry_delete(c->invites, c->invites->entries);
+ }
}
- if (c->invitesize)
- free(c->invite);
}
if (c->next)
@@ -1697,28 +1685,20 @@ void chan_delete(Channel * c)
void del_ban(Channel * chan, char *mask)
{
- char **s = chan->bans;
- int i = 0;
AutoKick *akick;
+ Entry *ban;
/* Sanity check as it seems some IRCD will just send -b without a mask */
- if (!mask) {
+ if (!mask || !chan->bans || (chan->bans->count == 0))
return;
- }
- while (i < chan->bancount && strcmp(*s, mask) != 0) {
- i++;
- s++;
- }
+ ban = elist_find_mask(chan->bans, mask);
- if (i < chan->bancount) {
- chan->bancount--;
- if (i < chan->bancount)
- memmove(s, s + 1, sizeof(char *) * (chan->bancount - i));
+ if (ban) {
+ entry_delete(chan->bans, ban);
if (debug)
- alog("debug: Deleted ban %s from channel %s", mask,
- chan->name);
+ alog("debug: Deleted ban %s from channel %s", mask, chan->name);
}
if (chan->ci && (akick = is_stuck(chan->ci, mask)))
@@ -1729,58 +1709,41 @@ void del_ban(Channel * chan, char *mask)
void del_exception(Channel * chan, char *mask)
{
- int i;
- int reset = 0;
+ Entry *exception;
/* Sanity check as it seems some IRCD will just send -e without a mask */
- if (!mask) {
+ if (!mask|| !chan->excepts || (chan->excepts->count == 0))
return;
- }
- for (i = 0; i < chan->exceptcount; i++) {
- if ((!reset) && (stricmp(chan->excepts[i], mask) == 0)) {
- free(chan->excepts[i]);
- reset = 1;
- }
- if (reset)
- chan->excepts[i] =
- (i == chan->exceptcount) ? NULL : chan->excepts[i + 1];
- }
+ exception = elist_find_mask(chan->excepts, mask);
- if (reset)
- chan->exceptcount--;
+ if (exception) {
+ entry_delete(chan->excepts, exception);
- if (debug)
- alog("debug: Deleted except %s to channel %s", mask, chan->name);
+ if (debug)
+ alog("debug: Deleted except %s to channel %s", mask, chan->name);
+ }
}
/*************************************************************************/
void del_invite(Channel * chan, char *mask)
{
- int i;
- int reset = 0;
+ Entry *invite;
/* Sanity check as it seems some IRCD will just send -I without a mask */
- if (!mask) {
+ if (!mask || !chan->invites || (chan->invites->count == 0)) {
return;
}
- for (i = 0; i < chan->invitecount; i++) {
- if ((!reset) && (stricmp(chan->invite[i], mask) == 0)) {
- free(chan->invite[i]);
- reset = 1;
- }
- if (reset)
- chan->invite[i] =
- (i == chan->invitecount) ? NULL : chan->invite[i + 1];
- }
+ invite = elist_find_mask(chan->invites, mask);
- if (reset)
- chan->invitecount--;
+ if (invite) {
+ entry_delete(chan->invites, invite);
- if (debug)
- alog("debug: Deleted invite %s to channel %s", mask, chan->name);
+ if (debug)
+ alog("debug: Deleted invite %s to channel %s", mask, chan->name);
+ }
}
@@ -1936,3 +1899,414 @@ void restore_unsynced_topics(void)
}
/*************************************************************************/
+
+/**
+ * This handles creating a new Entry.
+ * This function destroys and free's the given mask as a side effect.
+ * @param mask Host/IP/CIDR mask to convert to an entry
+ * @return Entry struct for the given mask, NULL if creation failed
+ */
+Entry *entry_create(char *mask)
+{
+ Entry *entry;
+ char *nick = NULL, *user, *host, *cidrhost;
+ int do_free;
+ uint32 ip, cidr;
+
+ entry = scalloc(1, sizeof(Entry));
+ entry->type = ENTRYTYPE_NONE;
+ entry->prev = NULL;
+ entry->next = NULL;
+ entry->nick = NULL;
+ entry->user = NULL;
+ entry->host = NULL;
+ entry->mask = sstrdup(mask);
+
+ host = strchr(mask, '@');
+ if (host) {
+ *host++ = '\0';
+ /* If the user is purely a wildcard, ignore it */
+ if (str_is_pure_wildcard(mask))
+ user = NULL;
+ else {
+
+ /* There might be a nick too */
+ user = strchr(mask, '!');
+ if (user) {
+ *user++ = '\0';
+ /* If the nick is purely a wildcard, ignore it */
+ if (str_is_pure_wildcard(mask))
+ nick = NULL;
+ else
+ nick = mask;
+ } else {
+ nick = NULL;
+ user = mask;
+ }
+ }
+ } else {
+ /* It is possibly an extended ban/invite mask, but we do
+ * not support these at this point.. ~ Viper */
+ /* If there's no user in the mask, assume a pure wildcard */
+ user = NULL;
+ host = mask;
+ }
+
+ if (nick) {
+ entry->nick = sstrdup(nick);
+ /* Check if we have a wildcard user */
+ if (str_is_wildcard(nick))
+ entry->type |= ENTRYTYPE_NICK_WILD;
+ else
+ entry->type |= ENTRYTYPE_NICK;
+ }
+
+ if (user) {
+ entry->user = sstrdup(user);
+ /* Check if we have a wildcard user */
+ if (str_is_wildcard(user))
+ entry->type |= ENTRYTYPE_USER_WILD;
+ else
+ entry->type |= ENTRYTYPE_USER;
+ }
+
+ /* Only check the host if it's not a pure wildcard */
+ if (*host && !str_is_pure_wildcard(host)) {
+ if (ircd->cidrchanbei && str_is_cidr(host, &ip, &cidr, &cidrhost)) {
+ entry->cidr_ip = ip;
+ entry->cidr_mask = cidr;
+ entry->type |= ENTRYTYPE_CIDR4;
+ host = cidrhost;
+ do_free = 1;
+ } else if (ircd->cidrchanbei && strchr(host, '/')) {
+ /* Most IRCd's don't enforce sane bans therefore it is not
+ * so unlikely we will encounter this.
+ * Currently we only support strict CIDR without taking into
+ * account quirks of every single ircd (nef) that ignore everything
+ * after the first /cidr. To add this, sanitaze before sending to
+ * str_is_cidr() as this expects a standard cidr.
+ * Add it to the internal list (so it is included in for example clear)
+ * but do not use if during matching.. ~ Viper */
+ entry->type = ENTRYTYPE_NONE;
+ } else {
+ entry->host = sstrdup(host);
+ if (str_is_wildcard(host))
+ entry->type |= ENTRYTYPE_HOST_WILD;
+ else
+ entry->type |= ENTRYTYPE_HOST;
+ }
+ }
+ free(mask);
+
+ return entry;
+}
+
+
+/**
+ * Create an entry and add it at the beginning of given list.
+ * @param list The List the mask should be added to
+ * @param mask The mask to parse and add to the list
+ * @return Pointer to newly added entry. NULL if it fails.
+ */
+Entry *entry_add(EList *list, char *mask)
+{
+ Entry *e;
+ char *hostmask;
+
+ hostmask = sstrdup(mask);
+ e = entry_create(hostmask);
+
+ if (!e)
+ return NULL;
+
+ e->next = list->entries;
+ e->prev = NULL;
+
+ if (list->entries)
+ list->entries->prev = e;
+ list->entries = e;
+ list->count++;
+
+ return e;
+}
+
+
+/**
+ * Delete the given entry from a given list.
+ * @param list Linked list from which entry needs to be removed.
+ * @param e The entry to be deleted, must be member of list.
+ */
+void entry_delete(EList *list, Entry *e)
+{
+ if (!list || !e)
+ return;
+
+ if (e->next)
+ e->next->prev = e->prev;
+ if (e->prev)
+ e->prev->next = e->next;
+
+ if (list->entries == e)
+ list->entries = e->next;
+
+ if (e->nick)
+ free(e->nick);
+ if (e->user)
+ free(e->user);
+ if (e->host)
+ free(e->host);
+ free(e->mask);
+ free(e);
+
+ list->count--;
+}
+
+
+/**
+ * Create and initialize a new entrylist
+ * @return Pointer to the created EList object
+ **/
+EList *list_create() {
+ EList *list;
+
+ list = scalloc(1, sizeof(EList));
+ list->entries = NULL;
+ list->count = 0;
+
+ return list;
+}
+
+
+/**
+ * Match the given Entry to the given user/host and optional IP addy
+ * @param e Entry struct to match against
+ * @param nick Nick to match against
+ * @param user User to match against
+ * @param host Host to match against
+ * @param ip IP to match against, set to 0 to not match this
+ * @return 1 for a match, 0 for no match
+ */
+int entry_match(Entry *e, char *nick, char *user, char *host, uint32 ip)
+{
+ /* If we don't get an entry, or it s an invalid one, no match ~ Viper*/
+ if (!e || e->type == ENTRYTYPE_NONE)
+ return 0;
+
+ if (ircd->cidrchanbei && (e->type & ENTRYTYPE_CIDR4) &&
+ (!ip || (ip && ((ip & e->cidr_mask) != e->cidr_ip))))
+ return 0;
+ if ((e->type & ENTRYTYPE_NICK) && (stricmp(e->nick, nick) != 0))
+ return 0;
+ if ((e->type & ENTRYTYPE_USER) && (stricmp(e->user, user) != 0))
+ return 0;
+ if ((e->type & ENTRYTYPE_HOST) && (stricmp(e->host, host) != 0))
+ return 0;
+ if ((e->type & ENTRYTYPE_NICK_WILD) && !match_wild_nocase(e->nick, nick))
+ return 0;
+ if ((e->type & ENTRYTYPE_USER_WILD) && !match_wild_nocase(e->user, user))
+ return 0;
+ if ((e->type & ENTRYTYPE_HOST_WILD) && !match_wild_nocase(e->host, host))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * Match the given Entry to the given hostmask and optional IP addy.
+ * @param e Entry struct to match against
+ * @param mask Hostmask to match against
+ * @param ip IP to match against, set to 0 to not match this
+ * @return 1 for a match, 0 for no match
+ */
+int entry_match_mask(Entry *e, char *mask, uint32 ip)
+{
+ char *hostmask, *nick, *user, *host;
+ int res;
+
+ hostmask = sstrdup(mask);
+
+ host = strchr(hostmask, '@');
+ if (host) {
+ *host++ = '\0';
+ user = strchr(hostmask, '!');
+ if (user) {
+ *user++ = '\0';
+ nick = hostmask;
+ } else {
+ nick = NULL;
+ user = hostmask;
+ }
+ } else {
+ nick = NULL;
+ user = NULL;
+ host = hostmask;
+ }
+
+ res = entry_match(e, nick, user, host, ip);
+
+ /* Free the destroyed mask. */
+ free(hostmask);
+
+ return res;
+}
+
+/**
+ * Match a nick, user, host, and ip to a list entry
+ * @param e List that should be matched against
+ * @param nick The nick to match
+ * @param user The user to match
+ * @param host The host to match
+ * @param ip The ip to match
+ * @return Returns the first matching entry, if none, NULL is returned.
+ */
+Entry *elist_match(EList *list, char *nick, char *user, char *host, uint32 ip)
+{
+ Entry *e;
+
+ if (!list || !list->entries)
+ return NULL;
+
+ for (e = list->entries; e; e = e->next) {
+ if (entry_match(e, nick, user, host, ip))
+ return e;
+ }
+
+ /* We matched none */
+ return NULL;
+}
+
+/**
+ * Match a mask and ip to a list.
+ * @param list EntryList that should be matched against
+ * @param mask The nick!user@host mask to match
+ * @param ip The ip to match
+ * @return Returns the first matching entry, if none, NULL is returned.
+ */
+Entry *elist_match_mask(EList *list, char *mask, uint32 ip)
+{
+ char *hostmask, *nick, *user, *host;
+ Entry *res;
+
+ if (!list || !list->entries || !mask)
+ return NULL;
+
+ hostmask = sstrdup(mask);
+
+ host = strchr(hostmask, '@');
+ if (host) {
+ *host++ = '\0';
+ user = strchr(hostmask, '!');
+ if (user) {
+ *user++ = '\0';
+ nick = hostmask;
+ } else {
+ nick = NULL;
+ user = hostmask;
+ }
+ } else {
+ nick = NULL;
+ user = NULL;
+ host = hostmask;
+ }
+
+ res = elist_match(list, nick, user, host, ip);
+
+ /* Free the destroyed mask. */
+ free(hostmask);
+
+ return res;
+}
+
+/**
+ * Check if a user matches an entry on a list.
+ * @param list EntryList that should be matched against
+ * @param user The user to match against the entries
+ * @return Returns the first matching entry, if none, NULL is returned.
+ */
+Entry *elist_match_user(EList *list, User *u)
+{
+ Entry *res;
+ char *host;
+ uint32 ip = 0;
+
+ if (!list || !list->entries || !u)
+ return NULL;
+
+ if (u->hostip == NULL) {
+ host = host_resolve(u->host);
+ /* we store the just resolved hostname so we don't
+ * need to do this again */
+ if (host) {
+ u->hostip = sstrdup(host);
+ }
+ } else {
+ host = sstrdup(u->hostip);
+ }
+
+ /* Convert the host to an IP.. */
+ if (host)
+ ip = str_is_ip(host);
+
+ /* Match what we ve got against the lists.. */
+ res = elist_match(list, u->nick, u->username, u->host, ip);
+ if (!res)
+ elist_match(list, u->nick, u->username, u->vhost, ip);
+
+ if (host)
+ free(host);
+
+ return res;
+}
+
+/**
+ * Find a entry identical to the given mask..
+ * @param list EntryList that should be matched against
+ * @param mask The *!*@* mask to match
+ * @return Returns the first matching entry, if none, NULL is returned.
+ */
+Entry *elist_find_mask(EList *list, char *mask)
+{
+ Entry *e;
+
+ if (!list || !list->entries || !mask)
+ return NULL;
+
+ for (e = list->entries; e; e = e->next) {
+ if (!stricmp(e->mask, mask))
+ return e;
+ }
+
+ return NULL;
+}
+
+/**
+ * Gets the total memory use of an entrylit.
+ * @param list The list we should estimate the mem use of.
+ * @return Returns the memory useage of the given list.
+ */
+long get_memuse(EList *list) {
+ Entry *e;
+ long mem = 0;
+
+ if (!list)
+ return 0;
+
+ mem += sizeof(EList *);
+ mem += sizeof(Entry *) * list->count;
+ if (list->entries) {
+ for (e = list->entries; e; e = e->next) {
+ if (e->nick)
+ mem += strlen(e->nick) + 1;
+ if (e->user)
+ mem += strlen(e->user) + 1;
+ if (e->host)
+ mem += strlen(e->host) + 1;
+ if (e->mask)
+ mem += strlen(e->mask) + 1;
+ }
+ }
+
+ return mem;
+}
+
+/*************************************************************************/
diff --git a/src/chanserv.c b/src/chanserv.c
index 68197a230..8dd72130c 100644
--- a/src/chanserv.c
+++ b/src/chanserv.c
@@ -2570,29 +2570,30 @@ AutoKick *is_stuck(ChannelInfo * ci, char *mask)
void stick_mask(ChannelInfo * ci, AutoKick * akick)
{
- int i;
char *av[2];
+ Entry *ban;
if (!ci) {
return;
}
- for (i = 0; i < ci->c->bancount; i++) {
- /* If akick is already covered by a wider ban.
- Example: c->bans[i] = *!*@*.org and akick->u.mask = *!*@*.epona.org */
- if (match_wild_nocase(ci->c->bans[i], akick->u.mask))
- return;
-
- if (ircd->reversekickcheck) {
- /* If akick is wider than a ban already in place.
- Example: c->bans[i] = *!*@irc.epona.org and akick->u.mask = *!*@*.epona.org */
- if (match_wild_nocase(akick->u.mask, ci->c->bans[i]))
+ if (ci->c->bans && ci->c->bans->entries != 0) {
+ for (ban = ci->c->bans->entries; ban; ban = ban->next) {
+ /* If akick is already covered by a wider ban.
+ Example: c->bans[i] = *!*@*.org and akick->u.mask = *!*@*.epona.org */
+ if (entry_match_mask(ban, sstrdup(akick->u.mask), 0))
return;
+
+ if (ircd->reversekickcheck) {
+ /* If akick is wider than a ban already in place.
+ Example: c->bans[i] = *!*@irc.epona.org and akick->u.mask = *!*@*.epona.org */
+ if (match_wild_nocase(akick->u.mask, ban->mask))
+ return;
+ }
}
}
/* Falling there means set the ban */
-
av[0] = sstrdup("+b");
av[1] = akick->u.mask;
anope_cmd_mode(whosends(ci), ci->c->name, "+b %s", akick->u.mask);
diff --git a/src/core/cs_clear.c b/src/core/cs_clear.c
index 16e5d6044..5596d0900 100644
--- a/src/core/cs_clear.c
+++ b/src/core/cs_clear.c
@@ -85,65 +85,54 @@ int do_clear(User * u)
notice_lang(s_ChanServ, u, PERMISSION_DENIED);
} else if (stricmp(what, "bans") == 0) {
char *av[2];
- int i;
-
- /* Save original ban info */
- int count = c->bancount;
- char **bans = scalloc(sizeof(char *) * count, 1);
- for (i = 0; i < count; i++)
- bans[i] = sstrdup(c->bans[i]);
-
- for (i = 0; i < count; i++) {
- av[0] = sstrdup("-b");
- av[1] = bans[i];
- anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]);
- chan_set_modes(whosends(ci), c, 2, av, 0);
- free(av[1]);
- free(av[0]);
+ Entry *ban, *next;
+
+ if (c->bans && c->bans->count) {
+ for (ban = c->bans->entries; ban; ban = next) {
+ next = ban->next;
+ av[0] = sstrdup("-b");
+ av[1] = sstrdup(ban->mask);
+ anope_cmd_mode(whosends(ci), chan, "-b %s", ban->mask);
+ chan_set_modes(whosends(ci), c, 2, av, 0);
+ free(av[0]);
+ free(av[1]);
+ }
}
+
notice_lang(s_ChanServ, u, CHAN_CLEARED_BANS, chan);
- free(bans);
} else if (ircd->except && stricmp(what, "excepts") == 0) {
char *av[2];
- int i;
-
- /* Save original except info */
- int count = c->exceptcount;
- char **excepts = scalloc(sizeof(char *) * count, 1);
- for (i = 0; i < count; i++)
- excepts[i] = sstrdup(c->excepts[i]);
-
- for (i = 0; i < count; i++) {
- av[0] = sstrdup("-e");
- av[1] = excepts[i];
- anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]);
- chan_set_modes(whosends(ci), c, 2, av, 0);
- free(av[1]);
- free(av[0]);
+ Entry *except, *next;
+
+ if (c->excepts && c->excepts->count) {
+ for (except = c->excepts->entries; except; except = next) {
+ next = except->next;
+ av[0] = sstrdup("-e");
+ av[1] = sstrdup(except->mask);
+ anope_cmd_mode(whosends(ci), chan, "-e %s", except->mask);
+ chan_set_modes(whosends(ci), c, 2, av, 0);
+ free(av[0]);
+ free(av[1]);
+ }
}
notice_lang(s_ChanServ, u, CHAN_CLEARED_EXCEPTS, chan);
- free(excepts);
} else if (ircd->invitemode && stricmp(what, "invites") == 0) {
char *av[2];
- int i;
-
- /* Save original except info */
- int count = c->invitecount;
- char **invites = scalloc(sizeof(char *) * count, 1);
- for (i = 0; i < count; i++)
- invites[i] = sstrdup(c->invite[i]);
-
- for (i = 0; i < count; i++) {
- av[0] = sstrdup("-I");
- av[1] = invites[i];
- anope_cmd_mode(whosends(ci), chan, "%s %s", av[0], av[1]);
- chan_set_modes(whosends(ci), c, 2, av, 0);
- free(av[1]);
- free(av[0]);
+ Entry *invite, *next;
+
+ if (c->invites && c->invites->count) {
+ for (invite = c->invites->entries; invite; invite = next) {
+ next = invite->next;
+ av[0] = sstrdup("-I");
+ av[1] = sstrdup(invite->mask);
+ anope_cmd_mode(whosends(ci), chan, "-I %s", invite->mask);
+ chan_set_modes(whosends(ci), c, 2, av, 0);
+ free(av[0]);
+ free(av[1]);
+ }
}
notice_lang(s_ChanServ, u, CHAN_CLEARED_INVITES, chan);
- free(invites);
} else if (stricmp(what, "modes") == 0) {
char *argv[2];
@@ -189,7 +178,7 @@ int do_clear(User * u)
}
check_modes(c);
}
-
+
notice_lang(s_ChanServ, u, CHAN_CLEARED_MODES, chan);
} else if (stricmp(what, "ops") == 0) {
char *av[4];
diff --git a/src/core/os_clearmodes.c b/src/core/os_clearmodes.c
index 36f1b97bf..7bea57697 100644
--- a/src/core/os_clearmodes.c
+++ b/src/core/os_clearmodes.c
@@ -75,13 +75,8 @@ int do_clearmodes(User * u)
char *chan = strtok(NULL, " ");
Channel *c;
int all = 0;
- int count; /* For saving ban info */
- char **bans; /* For saving ban info */
- int exceptcount; /* For saving except info */
- char **excepts; /* For saving except info */
- int invitecount; /* For saving invite info */
- char **invites; /* For saving invite info */
struct c_userlist *cu, *next;
+ Entry *entry, *nexte;
if (!chan) {
syntax_error(s_OperServ, u, "CLEARMODES", OPER_CLEARMODES_SYNTAX);
@@ -286,67 +281,43 @@ int do_clearmodes(User * u)
}
/* Clear bans */
- count = c->bancount;
- bans = scalloc(sizeof(char *) * count, 1);
-
- for (i = 0; i < count; i++)
- bans[i] = sstrdup(c->bans[i]);
-
- for (i = 0; i < count; i++) {
- argv[0] = sstrdup("-b");
- argv[1] = bans[i];
- anope_cmd_mode(s_OperServ, c->name, "-b %s", argv[1]);
- chan_set_modes(s_OperServ, c, 2, argv, 0);
- free(argv[1]);
- free(argv[0]);
+ if (c->bans && c->bans->count) {
+ for (entry = c->bans->entries; entry; entry = nexte) {
+ nexte = entry->next;
+ argv[0] = sstrdup("-b");
+ argv[1] = sstrdup(entry->mask);
+ anope_cmd_mode(s_OperServ, c->name, "-b %s", entry->mask);
+ chan_set_modes(s_OperServ, c, 2, argv, 0);
+ free(argv[0]);
+ free(argv[1]);
+ }
}
- free(bans);
-
- excepts = NULL;
-
- if (ircd->except) {
- /* Clear excepts */
- exceptcount = c->exceptcount;
- excepts = scalloc(sizeof(char *) * exceptcount, 1);
-
- for (i = 0; i < exceptcount; i++)
- excepts[i] = sstrdup(c->excepts[i]);
-
- for (i = 0; i < exceptcount; i++) {
+ /* Clear excepts */
+ if (ircd->except && c->excepts && c->excepts->count) {
+ for (entry = c->excepts->entries; entry; entry = nexte) {
+ nexte = entry->next;
argv[0] = sstrdup("-e");
- argv[1] = excepts[i];
- anope_cmd_mode(s_OperServ, c->name, "-e %s", argv[1]);
+ argv[1] = sstrdup(entry->mask);
+ anope_cmd_mode(s_OperServ, c->name, "-e %s", entry->mask);
chan_set_modes(s_OperServ, c, 2, argv, 0);
- free(argv[1]);
free(argv[0]);
- }
-
- if (excepts) {
- free(excepts);
+ free(argv[1]);
}
}
- if (ircd->invitemode) {
- /* Clear invites */
- invitecount = c->invitecount;
- invites = scalloc(sizeof(char *) * invitecount, 1);
-
- for (i = 0; i < invitecount; i++)
- invites[i] = sstrdup(c->invite[i]);
-
- for (i = 0; i < invitecount; i++) {
+ /* Clear invites */
+ if (ircd->invitemode && c->invites && c->invites->count) {
+ for (entry = c->invites->entries; entry; entry = nexte) {
+ nexte = entry->next;
argv[0] = sstrdup("-I");
- argv[1] = invites[i];
- anope_cmd_mode(s_OperServ, c->name, "-I %s", argv[1]);
+ argv[1] = sstrdup(entry->mask);
+ anope_cmd_mode(s_OperServ, c->name, "-I %s", entry->mask);
chan_set_modes(s_OperServ, c, 2, argv, 0);
- free(argv[1]);
free(argv[0]);
+ free(argv[1]);
}
-
- free(invites);
}
-
}
if (all) {
diff --git a/src/misc.c b/src/misc.c
index 86106889c..633efd63b 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -1492,4 +1492,172 @@ int SupportedWindowsVersion(void)
#endif
+
+/*************************************************************************/
+/* This 2 functions were originally found in Bahamut */
+
+/**
+ * Turn a cidr value into a netmask
+ * @param cidr CIDR value
+ * @return Netmask value
+ */
+uint32 cidr_to_netmask(uint16 cidr)
+{
+ if (cidr == 0)
+ return 0;
+
+ return (0xFFFFFFFF - (1 << (32 - cidr)) + 1);
+}
+
+/**
+ * Turn a netmask into a cidr value
+ * @param mask Netmask
+ * @return CIDR value
+ */
+uint16 netmask_to_cidr(uint32 mask)
+{
+ int tmp = 0;
+
+ while (!(mask & (1 << tmp)) && (tmp < 32))
+ tmp++;
+
+ return (32 - tmp);
+}
+
+/*************************************************************************/
+
+/**
+ * Check if the given string is some sort of wildcard
+ * @param str String to check
+ * @return 1 for wildcard, 0 for anything else
+ */
+int str_is_wildcard(const char *str)
+{
+ while (*str) {
+ if ((*str == '*') || (*str == '?'))
+ return 1;
+ str++;
+ }
+
+ return 0;
+}
+
+/**
+ * Check if the given string is a pure wildcard
+ * @param str String to check
+ * @return 1 for pure wildcard, 0 for anything else
+ */
+int str_is_pure_wildcard(const char *str)
+{
+ while (*str) {
+ if (*str != '*')
+ return 0;
+ str++;
+ }
+
+ return 1;
+}
+
+/*************************************************************************/
+
+/**
+ * Check if the given string is an IP, and return the IP.
+ * @param str String to check
+ * @return The IP, if one found. 0 if none.
+ */
+uint32 str_is_ip(char *str)
+{
+ int i;
+ int octets[4] = { -1, -1, -1, -1 };
+ char *s = str;
+ uint32 ip;
+
+ for (i = 0; i < 4; i++) {
+ octets[i] = strtol(s, &s, 10);
+ /* Bail out if the octet is invalid or wrongly terminated */
+ if ((octets[i] < 0) || (octets[i] > 255)
+ || ((i < 3) && (*s != '.')))
+ return 0;
+ if (i < 3)
+ s++;
+ }
+
+ /* Fill the IP - the dirty way */
+ ip = octets[3];
+ ip += octets[2] * 256;
+ ip += octets[1] * 65536;
+ ip += octets[0] * 16777216;
+
+ return ip;
+}
+
+/*************************************************************************/
+
+/**
+ * Check if the given string is an IP or CIDR mask, and fill the given
+ * ip/cidr params if so.
+ * @param str String to check
+ * @param ip The ipmask to fill when a CIDR is found
+ * @param mask The CIDR mask to fill when a CIDR is found
+ * @param host Displayed host
+ * @return 1 for IP/CIDR, 0 for anything else
+ */
+int str_is_cidr(char *str, uint32 * ip, uint32 * mask, char **host)
+{
+ int i;
+ int octets[4] = { -1, -1, -1, -1 };
+ char *s = str;
+ char buf[512];
+ uint16 cidr;
+
+ for (i = 0; i < 4; i++) {
+ octets[i] = strtol(s, &s, 10);
+ /* Bail out if the octet is invalid or wrongly terminated */
+ if ((octets[i] < 0) || (octets[i] > 255)
+ || ((i < 3) && (*s != '.')))
+ return 0;
+ if (i < 3)
+ s++;
+ }
+
+ /* Fill the IP - the dirty way */
+ *ip = octets[3];
+ *ip += octets[2] * 256;
+ *ip += octets[1] * 65536;
+ *ip += octets[0] * 16777216;
+
+ if (*s == '/') {
+ s++;
+ /* There's a CIDR mask here! */
+ cidr = strtol(s, &s, 10);
+ /* Bail out if the CIDR is invalid or the string isn't done yet */
+ if ((cidr > 32) || (*s))
+ return 0;
+ } else {
+ /* No CIDR mask here - use 32 so the whole ip will be matched */
+ cidr = 32;
+ }
+
+ *mask = cidr_to_netmask(cidr);
+ /* Apply the mask to avoid 255.255.255.255/8 bans */
+ *ip &= *mask;
+
+ /* Refill the octets to fill the host */
+ octets[0] = (*ip & 0xFF000000) / 16777216;
+ octets[1] = (*ip & 0x00FF0000) / 65536;
+ octets[2] = (*ip & 0x0000FF00) / 256;
+ octets[3] = (*ip & 0x000000FF);
+
+ if (cidr == 32)
+ snprintf(buf, 512, "%d.%d.%d.%d", octets[0], octets[1], octets[2],
+ octets[3]);
+ else
+ snprintf(buf, 512, "%d.%d.%d.%d/%d", octets[0], octets[1],
+ octets[2], octets[3], cidr);
+
+ *host = sstrdup(buf);
+
+ return 1;
+}
+
/* EOF */
diff --git a/src/protocol/bahamut.c b/src/protocol/bahamut.c
index 96ff089bb..e00fa2a45 100644
--- a/src/protocol/bahamut.c
+++ b/src/protocol/bahamut.c
@@ -107,6 +107,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
1, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -634,7 +635,7 @@ void moduleAddIRCDMsgs(void) {
/* first update the cs protect info about this ircd */
updateProtectDetails("PROTECT","PROTECTME","protect","deprotect","AUTOPROTECT","+","-");
-
+
/* now add the commands */
m = createMessage("401", anope_event_null); addCoreMessage(IRCD,m);
m = createMessage("402", anope_event_null); addCoreMessage(IRCD,m);
diff --git a/src/protocol/charybdis.c b/src/protocol/charybdis.c
index 002cd23b3..23c758324 100644
--- a/src/protocol/charybdis.c
+++ b/src/protocol/charybdis.c
@@ -104,6 +104,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
0, /* reports sync state */
+ 1, /* CIDR channelbans */
}
,
{NULL}
@@ -237,7 +238,7 @@ unsigned long umodes[128] = {
0, /* y */
UMODE_z, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
@@ -741,15 +742,15 @@ int anope_event_tburst(char *source, int ac, char **av)
c->topic_time = topic_time;
record_topic(av[0]);
-
+
if (ac > 1 && *av[3])
send_event(EVENT_TOPIC_UPDATED, 2, av[0], av[3]);
else
send_event(EVENT_TOPIC_UPDATED, 2, av[0], "");
-
+
if (setter)
free(setter);
-
+
return MOD_CONT;
}
diff --git a/src/protocol/dreamforge.c b/src/protocol/dreamforge.c
index 1f6be1a9d..3809f3bd7 100644
--- a/src/protocol/dreamforge.c
+++ b/src/protocol/dreamforge.c
@@ -105,6 +105,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
0, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -254,7 +255,7 @@ unsigned long umodes[128] = {
0, /* y */
0, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
char myCsmodes[128] = {
diff --git a/src/protocol/hybrid.c b/src/protocol/hybrid.c
index 5ee3cc890..454913517 100644
--- a/src/protocol/hybrid.c
+++ b/src/protocol/hybrid.c
@@ -105,6 +105,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
0, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -256,7 +257,7 @@ unsigned long umodes[128] = {
UMODE_y, /* y */
UMODE_z, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
@@ -568,11 +569,11 @@ int anope_event_topic(char *source, int ac, char **av)
c->topic_time = topic_time;
record_topic(av[0]);
-
+
if (ac > 1 && *av[1])
send_event(EVENT_TOPIC_UPDATED, 2, av[0], av[1]);
else
- send_event(EVENT_TOPIC_UPDATED, 2, av[0], "");
+ send_event(EVENT_TOPIC_UPDATED, 2, av[0], "");
}
return MOD_CONT;
}
diff --git a/src/protocol/inspircd10.c b/src/protocol/inspircd10.c
index f494a2d29..30ced466d 100644
--- a/src/protocol/inspircd10.c
+++ b/src/protocol/inspircd10.c
@@ -124,6 +124,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
0, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
diff --git a/src/protocol/inspircd11.c b/src/protocol/inspircd11.c
index 7f3cbb9e3..b6b168ec6 100644
--- a/src/protocol/inspircd11.c
+++ b/src/protocol/inspircd11.c
@@ -124,6 +124,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
0, /* reports sync state */
+ 1, /* CIDR channelbans */
}
,
{NULL}
diff --git a/src/protocol/plexus2.c b/src/protocol/plexus2.c
index cc6dc08f1..0a91194f4 100644
--- a/src/protocol/plexus2.c
+++ b/src/protocol/plexus2.c
@@ -103,6 +103,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
1, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -322,7 +323,7 @@ unsigned long umodes[128] = {
0, /* y */
0, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
diff --git a/src/protocol/plexus3.c b/src/protocol/plexus3.c
index 70118de1f..0fe8a74c4 100644
--- a/src/protocol/plexus3.c
+++ b/src/protocol/plexus3.c
@@ -103,6 +103,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
1, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -264,7 +265,7 @@ unsigned long umodes[128] = {
0, /* y */
0, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
diff --git a/src/protocol/ptlink.c b/src/protocol/ptlink.c
index d41eb62ca..9e6eb08b1 100644
--- a/src/protocol/ptlink.c
+++ b/src/protocol/ptlink.c
@@ -105,6 +105,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
0, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -192,7 +193,7 @@ unsigned long umodes[128] = {
UMODE_y, /* y */
UMODE_z, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
char myCsmodes[128] = {
diff --git a/src/protocol/rageircd.c b/src/protocol/rageircd.c
index 1c7b3d4ae..94fc7824e 100644
--- a/src/protocol/rageircd.c
+++ b/src/protocol/rageircd.c
@@ -105,6 +105,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
1, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -192,7 +193,7 @@ unsigned long umodes[128] = {
0, /* y */
0, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
char myCsmodes[128] = {
diff --git a/src/protocol/ratbox.c b/src/protocol/ratbox.c
index 6bc0f1b5c..d8c33b4a3 100644
--- a/src/protocol/ratbox.c
+++ b/src/protocol/ratbox.c
@@ -105,6 +105,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
0, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -236,7 +237,7 @@ unsigned long umodes[128] = {
0, /* y */
0, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
diff --git a/src/protocol/shadowircd.c b/src/protocol/shadowircd.c
index 78eff5bc9..0061a538b 100644
--- a/src/protocol/shadowircd.c
+++ b/src/protocol/shadowircd.c
@@ -106,6 +106,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
1, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -238,7 +239,7 @@ unsigned long umodes[128] = {
0, /* y */
0, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
diff --git a/src/protocol/solidircd.c b/src/protocol/solidircd.c
index 4cafcddd1..b0f948794 100644
--- a/src/protocol/solidircd.c
+++ b/src/protocol/solidircd.c
@@ -107,6 +107,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
1, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -269,7 +270,7 @@ unsigned long umodes[128] = {
UMODE_y, /* y */
UMODE_z, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
char myCsmodes[128] = {
diff --git a/src/protocol/ultimate2.c b/src/protocol/ultimate2.c
index 5353de42f..2e6125861 100644
--- a/src/protocol/ultimate2.c
+++ b/src/protocol/ultimate2.c
@@ -105,6 +105,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
0, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
diff --git a/src/protocol/ultimate3.c b/src/protocol/ultimate3.c
index 88701ab3d..16186481a 100644
--- a/src/protocol/ultimate3.c
+++ b/src/protocol/ultimate3.c
@@ -105,6 +105,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
1, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -285,7 +286,7 @@ unsigned long umodes[128] = {
0, /* y */
0, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
diff --git a/src/protocol/unreal31.c b/src/protocol/unreal31.c
index 0a65b4726..08781ca0f 100644
--- a/src/protocol/unreal31.c
+++ b/src/protocol/unreal31.c
@@ -107,6 +107,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
0, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
diff --git a/src/protocol/unreal32.c b/src/protocol/unreal32.c
index 83a41f1c9..d4c526d14 100644
--- a/src/protocol/unreal32.c
+++ b/src/protocol/unreal32.c
@@ -107,6 +107,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
1, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
@@ -197,7 +198,7 @@ unsigned long umodes[128] = {
0, /* y */
UMODE_z, /* z */
0, 0, 0, /* { | } */
- 0, 0 /* ~ ‚ */
+ 0, 0 /* ~ � */
};
char myCsmodes[128] = {
diff --git a/src/protocol/viagra.c b/src/protocol/viagra.c
index c62c6776b..8638204b7 100644
--- a/src/protocol/viagra.c
+++ b/src/protocol/viagra.c
@@ -106,6 +106,7 @@ IRCDVar myIrcd[] = {
0, /* p10 */
NULL, /* character set */
1, /* reports sync state */
+ 0, /* CIDR channelbans */
}
,
{NULL}
diff --git a/src/users.c b/src/users.c
index bf3b5c2ac..44faaf9d5 100644
--- a/src/users.c
+++ b/src/users.c
@@ -506,7 +506,7 @@ User *do_nick(const char *source, char *nick, char *username, char *host,
if (!strcmp(vhost, "*")) {
vhost = NULL;
if (debug)
- alog("debug: new user with no vhost in NICK command: %s", nick);
+ alog("debug: new user�with no vhost in NICK command: %s", nick);
}
}
}
@@ -921,30 +921,13 @@ int is_oper(User * user)
/* Is the given user ban-excepted? */
int is_excepted(ChannelInfo * ci, User * user)
{
- int count, i;
- int isexcepted = 0;
- char **excepts;
-
- if (!ci->c)
- return 0;
-
- if (!ircd->except) {
+ if (!ci->c || !ircd->except)
return 0;
- }
- count = ci->c->exceptcount;
- excepts = scalloc(sizeof(char *) * count, 1);
- memcpy(excepts, ci->c->excepts, sizeof(char *) * count);
+ if (elist_match_user(ci->c->excepts, user))
+ return 1;
- for (i = 0; i < count; i++) {
- if (match_usermask(excepts[i], user)
- || match_userip(excepts[i], user, user->hostip)) {
- isexcepted = 1;
- break;
- }
- }
- free(excepts);
- return isexcepted;
+ return 0;
}
/*************************************************************************/
@@ -952,28 +935,13 @@ int is_excepted(ChannelInfo * ci, User * user)
/* Is the given MASK ban-excepted? */
int is_excepted_mask(ChannelInfo * ci, char *mask)
{
- int count, i;
- int isexcepted = 0;
- char **excepts;
-
- if (!ci->c)
- return 0;
-
- if (!ircd->except) {
+ if (!ci->c || !ircd->except)
return 0;
- }
- count = ci->c->exceptcount;
- excepts = scalloc(sizeof(char *) * count, 1);
- memcpy(excepts, ci->c->excepts, sizeof(char *) * count);
+ if (elist_match_mask(ci->c->excepts, mask, 0))
+ return 1;
- for (i = 0; i < count; i++) {
- if (match_wild_nocase(excepts[i], mask)) {
- isexcepted = 1;
- }
- }
- free(excepts);
- return isexcepted;
+ return 0;
}