X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/634d32a31094a4077368aeb9b5d961c49d5a2dea..37e08c82c2958b3b96ada2bf76a9578f1dbbb2b3:/src/tools.c diff --git a/src/tools.c b/src/tools.c index 4c00172..ce3c936 100644 --- a/src/tools.c +++ b/src/tools.c @@ -367,6 +367,10 @@ irc_strtolower(char *str) { int irccasecmp(const char *stra, const char *strb) { + if (!stra) + return -1; + if (!strb) + return 1; while (*stra && (tolower(*stra) == tolower(*strb))) stra++, strb++; return tolower(*stra) - tolower(*strb); @@ -602,11 +606,15 @@ int is_overmask(char *mask) } int -user_matches_glob(struct userNode *user, const char *orig_glob, int flags) +user_matches_glob(struct userNode *user, const char *orig_glob, int flags, int shared) { char *tmpglob, *glob, *marker; char exttype = 0; - int extreverse = 0, is_extended = 0; + int extreverse = 0, is_extended = 0, match = 0, banned = 0; + unsigned int count, n; + struct modeNode *mn; + struct chanNode *channel; + struct banNode *ban; /* Make a writable copy of the glob */ glob = alloca(strlen(orig_glob)+1); @@ -637,7 +645,7 @@ user_matches_glob(struct userNode *user, const char *orig_glob, int flags) if (is_extended) { log_module(MAIN_LOG, LOG_DEBUG, "Extended ban. T (%c) R (%d) M (%s)", exttype, extreverse, glob); switch (exttype) { - case 'a': + case 'a': // account if (user->handle_info) { if (extreverse) { if (0 != strcasecmp(glob, user->handle_info->handle)) @@ -651,8 +659,96 @@ user_matches_glob(struct userNode *user, const char *orig_glob, int flags) return 1; } return match_ircglob(user->hostname, glob); + case 'c': // another channel + if (!strstr(glob, "#")) + return -1; + + if (extreverse) { + for (n=count=0; nchannels.used; n++) { + mn = user->channels.list[n]; + match = 0; + + if (*glob == '#') { + if (0 == strcasecmp(glob, mn->channel->name)) + match = 1; + } else { + if (0 == strcasecmp(glob+1, mn->channel->name)) { + if ((*glob == '@') && (mn->modes & MODE_CHANOP)) + match = 1; + else if ((*glob == '%') && (mn->modes & MODE_HALFOP)) + match = 1; + else if ((*glob == '+') && (mn->modes & MODE_VOICE)) + match = 1; + } + } + + if (match == 0) + banned = 1; + else { + banned = 0; + break; + } + } + } else { + for (n=count=0; nchannels.used; n++) { + mn = user->channels.list[n]; + match = 0; + + if (*glob == '#') { + if (0 == strcasecmp(glob, mn->channel->name)) + match = 1; + } else { + if (0 == strcasecmp(glob+1, mn->channel->name)) { + if ((*glob == '@') && (mn->modes & MODE_CHANOP)) + match = 1; + else if ((*glob == '%') && (mn->modes & MODE_HALFOP)) + match = 1; + else if ((*glob == '+') && (mn->modes & MODE_VOICE)) + match = 1; + } + } + + if (match == 1) + banned = 1; + } + } + + if (banned) + return 1; + else + return match_ircglob(user->hostname, glob); + case 'j': + if (shared == 0) { + if (*glob != '#') + return -1; + if ((channel = GetChannel(glob))) { + for (n = 0; n < channel->banlist.used; n++) { + ban = channel->banlist.list[n]; + if (user_matches_glob(user, ban->ban, flags, 1)) + return 1; + } + } + } + return match_ircglob(user->hostname, glob); + case 'n': /* this is handled ircd side */ + return match_ircglob(user->hostname, glob); + case 'q': /* this is handled ircd side */ + return match_ircglob(user->hostname, glob); + case 't': /* this is handled ircd side */ + return match_ircglob(user->hostname, glob); + case 'R': /* this is handled ircd side */ + return match_ircglob(user->hostname, glob); + case 'm': // mute by mark + if(user->mark && !strcmp(glob, user->mark)) + return true; + else + return false; + + case 'M': // mute by mark unless authed + return false; // can never match a logged in user + default: - return 0; + return -1; } } @@ -701,7 +797,8 @@ user_matches_glob(struct userNode *user, const char *orig_glob, int flags) /* If only matching the visible hostnames, bail early. */ if ((flags & MATCH_VISIBLE) && IsHiddenHost(user) - && (IsFakeHost(user) || (hidden_host_suffix && user->handle_info))) + && (IsFakeHost(user) || (hidden_host_suffix && user->handle_info) || + user->crypthost || user->cryptip)) return 0; /* If it might be an IP glob, test that. */ if (!glob[strspn(glob, "0123456789./*?")]