static mowgli_node_t *charybdis_next_matching_ban(channel_t *c, user_t *u, int type, mowgli_node_t *first) { chanban_t *cb; mowgli_node_t *n; char hostbuf[NICKLEN+USERLEN+HOSTLEN]; char realbuf[NICKLEN+USERLEN+HOSTLEN]; char ipbuf[NICKLEN+USERLEN+HOSTLEN]; char strippedmask[NICKLEN+USERLEN+HOSTLEN+CHANNELLEN+2]; char *p; bool negate, matched; int exttype; channel_t *target_c; snprintf(hostbuf, sizeof hostbuf, "%s!%s@%s", u->nick, u->user, u->vhost); snprintf(realbuf, sizeof realbuf, "%s!%s@%s", u->nick, u->user, u->host); /* will be nick!user@ if ip unknown, doesn't matter */ snprintf(ipbuf, sizeof ipbuf, "%s!%s@%s", u->nick, u->user, u->ip); MOWGLI_ITER_FOREACH(n, first) { cb = n->data; if (cb->type != type) continue; /* * strip any banforwards from the mask. (SRV-73) * charybdis itself doesn't support banforward but i don't feel like copying * this stuff into ircd-seven and it is possible that charybdis may support them * one day. * --nenolod */ mowgli_strlcpy(strippedmask, cb->mask, sizeof strippedmask); p = strrchr(strippedmask, '$'); if (p != NULL && p != strippedmask) *p = 0; if ((!match(strippedmask, hostbuf) || !match(strippedmask, realbuf) || !match(strippedmask, ipbuf) || !match_cidr(strippedmask, ipbuf))) return n; if (strippedmask[0] == '$') { p = strippedmask + 1; negate = *p == '~'; if (negate) p++; exttype = *p++; if (exttype == '\0') continue; /* check parameter */ if (*p++ != ':') p = NULL; switch (exttype) { case 'a': matched = u->myuser != NULL && !(u->myuser->flags & MU_WAITAUTH) && (p == NULL || !match(p, entity(u->myuser)->name)); break; case 'c': if (p == NULL) continue; target_c = channel_find(p); if (target_c == NULL || (target_c->modes & (CMODE_PRIV | CMODE_SEC))) continue; matched = chanuser_find(target_c, u) != NULL; break; case 'o': matched = is_ircop(u); break; case 'r': if (p == NULL) continue; matched = !match(p, u->gecos); break; case 's': if (p == NULL) continue; matched = !match(p, u->server->name); break; case 'x': if (p == NULL) continue; matched = extgecos_match(p, u); break; default: continue; } if (negate ^ matched) return n; } }
static mowgli_node_t *inspircd_next_matching_ban(channel_t *c, user_t *u, int type, mowgli_node_t *first) { chanban_t *cb; mowgli_node_t *n; char hostbuf[NICKLEN+USERLEN+HOSTLEN]; char realbuf[NICKLEN+USERLEN+HOSTLEN]; char ipbuf[NICKLEN+USERLEN+HOSTLEN]; char *p; snprintf(hostbuf, sizeof hostbuf, "%s!%s@%s", u->nick, u->user, u->vhost); snprintf(realbuf, sizeof realbuf, "%s!%s@%s", u->nick, u->user, u->host); /* will be nick!user@ if ip unknown, doesn't matter */ snprintf(ipbuf, sizeof ipbuf, "%s!%s@%s", u->nick, u->user, u->ip); MOWGLI_ITER_FOREACH(n, first) { channel_t *target_c; cb = n->data; if (cb->type != type) continue; if ((!match(cb->mask, hostbuf) || !match(cb->mask, realbuf) || !match(cb->mask, ipbuf)) || !match_cidr(cb->mask, ipbuf)) return n; if (cb->mask[1] == ':' && strchr("MRUjrm", cb->mask[0])) { bool matched = false; p = cb->mask + 2; if (*(p - 1) != ':') p = NULL; switch (cb->mask[0]) { case 'M': case 'R': matched = u->myuser != NULL && !(u->myuser->flags & MU_WAITAUTH) && (p == NULL || !match(p, entity(u->myuser)->name)); break; case 'U': matched = u->myuser == NULL; break; case 'j': if (p == NULL) continue; target_c = channel_find(p); if (target_c == NULL || (target_c->modes & (CMODE_PRIV | CMODE_SEC))) continue; matched = chanuser_find(target_c, u) != NULL; break; case 'r': if (p == NULL) continue; matched = !match(p, u->gecos); break; case 'm': matched = (!match(p, hostbuf) || !match(p, realbuf) || !match(p, ipbuf)) || !match_cidr(p, ipbuf); break; default: continue; } if (matched) return n; } }