diff options
author | viper 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 |
---|---|---|
committer | viper 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 |
commit | 790dc8a4bf326a7598fc41aa8c018e867edee33a (patch) | |
tree | 281aa0f14877734a92336a21355eb945a8d1517e /src | |
parent | 482a8aa766c9e1a96ff63b44ed319fe51588c35c (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.c | 57 | ||||
-rw-r--r-- | src/botserv.c | 33 | ||||
-rw-r--r-- | src/channels.c | 592 | ||||
-rw-r--r-- | src/chanserv.c | 25 | ||||
-rw-r--r-- | src/core/cs_clear.c | 87 | ||||
-rw-r--r-- | src/core/os_clearmodes.c | 79 | ||||
-rw-r--r-- | src/misc.c | 168 | ||||
-rw-r--r-- | src/protocol/bahamut.c | 3 | ||||
-rw-r--r-- | src/protocol/charybdis.c | 9 | ||||
-rw-r--r-- | src/protocol/dreamforge.c | 3 | ||||
-rw-r--r-- | src/protocol/hybrid.c | 7 | ||||
-rw-r--r-- | src/protocol/inspircd10.c | 1 | ||||
-rw-r--r-- | src/protocol/inspircd11.c | 1 | ||||
-rw-r--r-- | src/protocol/plexus2.c | 3 | ||||
-rw-r--r-- | src/protocol/plexus3.c | 3 | ||||
-rw-r--r-- | src/protocol/ptlink.c | 3 | ||||
-rw-r--r-- | src/protocol/rageircd.c | 3 | ||||
-rw-r--r-- | src/protocol/ratbox.c | 3 | ||||
-rw-r--r-- | src/protocol/shadowircd.c | 3 | ||||
-rw-r--r-- | src/protocol/solidircd.c | 3 | ||||
-rw-r--r-- | src/protocol/ultimate2.c | 1 | ||||
-rw-r--r-- | src/protocol/ultimate3.c | 3 | ||||
-rw-r--r-- | src/protocol/unreal31.c | 1 | ||||
-rw-r--r-- | src/protocol/unreal32.c | 3 | ||||
-rw-r--r-- | src/protocol/viagra.c | 1 | ||||
-rw-r--r-- | src/users.c | 50 |
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; } |