X-Git-Url: http://git.pk910.de/?p=ircu2.10.12-pk.git;a=blobdiff_plain;f=ircd%2Fchannel.c;h=e22935c4c10c585a0c8ef348938a1a7dce68dd8b;hp=1bba9b8e070c89cdd2ec1c2f81ffbb678452a783;hb=bb5d6a24f02155e2252474809cd5e7161fa29b93;hpb=3c606acaad5d1b78a3c6a2a5ab6bfd18ce1145da diff --git a/ircd/channel.c b/ircd/channel.c index 1bba9b8..e22935c 100644 --- a/ircd/channel.c +++ b/ircd/channel.c @@ -374,7 +374,7 @@ struct Membership* find_channel_member(struct Client* cptr, struct Channel* chpt * @param[in] banlist The list of bans to test. * @return Pointer to a matching ban, or NULL if none exit. */ -struct Ban *find_ban(struct Client *cptr, struct Ban *banlist) +static struct Ban *find_ban_with_nick(struct Client *cptr, const char *nick, struct Ban *banlist) { char nu[NICKLEN + USERLEN + 2]; char tmphost[HOSTLEN + 1]; @@ -386,7 +386,7 @@ struct Ban *find_ban(struct Client *cptr, struct Ban *banlist) /* Build nick!user and alternate host names. */ ircd_snprintf(0, nu, sizeof(nu), "%s!%s", - cli_name(cptr), cli_user(cptr)->username); + (nick ? nick : cli_name(cptr)), cli_user(cptr)->username); ircd_ntoa_r(iphost, &cli_ip(cptr)); /* Check for all three possible hosts: @@ -439,6 +439,10 @@ struct Ban *find_ban(struct Client *cptr, struct Ban *banlist) return found; } +struct Ban *find_ban(struct Client *cptr, struct Ban *banlist) { + return find_ban_with_nick(cptr, NULL, banlist); +} + /** * This function returns true if the user is banned on the said channel. * This function will check the ban cache if applicable, otherwise will @@ -462,6 +466,13 @@ static int is_banned(struct Membership* member) } } +static int is_banned_with_nick(struct Membership* member, const char *nick) { + if (find_ban_with_nick(member->user, nick, member->channel->banlist)) + return 1; + else + return 0; +} + /** add a user to a channel. * adds a user to a channel by adding another link to the channels member * chain. @@ -783,7 +794,8 @@ int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int r */ if (!member) { if ((chptr->mode.mode & (MODE_NOPRIVMSGS|MODE_MODERATED)) || - ((chptr->mode.mode & MODE_REGONLY) && !IsAccount(cptr))) + ((chptr->mode.mode & MODE_REGONLY) && !IsAccount(cptr)) || + ((chptr->mode.mode & MODE_SSLCHAN) && !IsSSL(cptr))) return 0; else return !find_ban(cptr, chptr->banlist); @@ -796,11 +808,12 @@ int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int r * the name of the first channel banned on. * * @param cptr The client + * @param new_nick The new nick of the client * * @returns the name of the first channel banned on, or NULL if the user * can change nicks. */ -const char* find_no_nickchange_channel(struct Client* cptr) +const char* find_no_nickchange_channel(struct Client* cptr, const char *new_nick) { if (MyUser(cptr)) { struct Membership* member; @@ -810,7 +823,8 @@ const char* find_no_nickchange_channel(struct Client* cptr) continue; if ((member->channel->mode.mode & MODE_MODERATED) || (member->channel->mode.mode & MODE_REGONLY && !IsAccount(cptr)) - || is_banned(member)) + || (member->channel->mode.mode & MODE_SSLCHAN && !IsSSL(cptr)) + || is_banned(member) || (new_nick && is_banned_with_nick(member, new_nick))) return member->channel->chname; } } @@ -877,6 +891,8 @@ void channel_modes(struct Client *cptr, char *mbuf, char *pbuf, int buflen, *mbuf++ = 'Q'; if (chptr->mode.mode & MODE_AUDITORIUM) *mbuf++ = 'u'; + if (chptr->mode.mode & MODE_SSLCHAN) + *mbuf++ = 'S'; if (chptr->mode.limit) { *mbuf++ = 'l'; ircd_snprintf(0, pbuf, buflen, "%u", chptr->mode.limit); @@ -1280,36 +1296,12 @@ static void send_ban_list(struct Client* cptr, struct Channel* chptr) assert(0 != cptr); assert(0 != chptr); - for (lp = chptr->banlist; lp; lp = lp->next) { - if(!(lp->flags & BAN_EXCEPTION)) - send_reply(cptr, RPL_BANLIST, chptr->chname, lp->banstr, - lp->who, lp->when); - } + for (lp = chptr->banlist; lp; lp = lp->next) + send_reply(cptr, RPL_BANLIST, chptr->chname, lp->banstr, lp->who, lp->when); send_reply(cptr, RPL_ENDOFBANLIST, chptr->chname); } -/** send an exceptionlist to a client for a channel - * - * @param cptr Client to send the exceptionlist to. - * @param chptr Channel whose exceptionlist to send. - */ -static void send_exception_list(struct Client* cptr, struct Channel* chptr) -{ - struct Ban* lp; - - assert(0 != cptr); - assert(0 != chptr); - - for (lp = chptr->banlist; lp; lp = lp->next) { - if(lp->flags & BAN_EXCEPTION) - send_reply(cptr, RPL_EXCEPTIONLIST, chptr->chname, lp->banstr, - lp->who, lp->when); - } - - send_reply(cptr, RPL_ENDOFEXCEPTIONLIST, chptr->chname); -} - /** Get a channel block, creating if necessary. * Get Channel block for chname (and allocate a new channel * block, if it didn't exists before). @@ -1611,7 +1603,6 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) MODE_PERSIST, 'z', MODE_NOCOLOUR, 'c', MODE_NOCTCP, 'C', -/* MODE_EXCEPTION, 'e', */ /* MODE_ALTCHAN, 'F', */ /* MODE_NOFLOOD, 'f', */ MODE_ACCESS, 'a', @@ -1619,6 +1610,7 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) MODE_NONOTICE, 'N', MODE_QUARANTINE, 'Q', MODE_AUDITORIUM, 'u', + MODE_SSLCHAN, 'S', 0x0, 0x0 }; static ulong64 local_flags[] = { @@ -1710,14 +1702,14 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) bufptr[(*bufptr_i)++] = MB_TYPE(mbuf, i) & MODE_CHANOP ? 'o' : 'v'; totalbuflen -= IRCD_MAX(9, tmp) + 1; } - } else if (MB_TYPE(mbuf, i) & (MODE_BAN | MODE_EXCEPTION | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD)) { + } else if (MB_TYPE(mbuf, i) & (MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD)) { tmp = strlen(MB_STRING(mbuf, i)); if ((totalbuflen - tmp) <= 0) /* don't overflow buffer */ MB_TYPE(mbuf, i) |= MODE_SAVE; /* save for later */ else { char mode_char; - switch(MB_TYPE(mbuf, i) & (MODE_BAN | MODE_EXCEPTION | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD)) + switch(MB_TYPE(mbuf, i) & (MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD)) { case MODE_APASS: mode_char = 'A'; @@ -1725,9 +1717,6 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) case MODE_UPASS: mode_char = 'U'; break; - case MODE_EXCEPTION: - mode_char = 'e'; - break; case MODE_ALTCHAN: mode_char = 'F'; break; @@ -1811,7 +1800,7 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) build_string(strptr, strptr_i, cli_name(MB_CLIENT(mbuf, i)), 0, ' '); /* deal with bans... */ - else if (MB_TYPE(mbuf, i) & (MODE_BAN | MODE_EXCEPTION)) + else if (MB_TYPE(mbuf, i) & (MODE_BAN)) build_string(strptr, strptr_i, MB_STRING(mbuf, i), 0, ' '); /* deal with keys... */ @@ -1927,7 +1916,7 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) build_string(strptr, strptr_i, NumNick(MB_CLIENT(mbuf, i)), ' '); /* deal with modes that take strings */ - else if (MB_TYPE(mbuf, i) & (MODE_KEY | MODE_BAN | MODE_EXCEPTION | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD)) + else if (MB_TYPE(mbuf, i) & (MODE_KEY | MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD)) build_string(strptr, strptr_i, MB_STRING(mbuf, i), 0, ' '); /* @@ -2063,7 +2052,7 @@ modebuf_mode(struct ModeBuf *mbuf, ulong64 mode) MODE_TOPICLIMIT | MODE_INVITEONLY | MODE_NOPRIVMSGS | MODE_REGONLY | MODE_DELJOINS | MODE_WASDELJOINS | MODE_REGISTERED | MODE_PERSIST | MODE_NOCOLOUR | MODE_NOCTCP | MODE_NOAMSGS | MODE_NONOTICE | - MODE_QUARANTINE | MODE_AUDITORIUM); + MODE_QUARANTINE | MODE_AUDITORIUM | MODE_SSLCHAN); if (!(mode & ~(MODE_ADD | MODE_DEL))) /* don't add empty modes... */ return; @@ -2235,13 +2224,13 @@ modebuf_extract(struct ModeBuf *mbuf, char *buf) MODE_PERSIST, 'z', MODE_NOCOLOUR, 'c', MODE_NOCTCP, 'C', -/* MODE_EXCEPTION, 'e', */ MODE_NOAMSGS, 'M', MODE_NONOTICE, 'N', MODE_QUARANTINE, 'Q', MODE_ALTCHAN, 'F', MODE_ACCESS, 'a', MODE_AUDITORIUM, 'u', + MODE_SSLCHAN, 'S', MODE_NOFLOOD, 'f', 0x0, 0x0 }; @@ -2351,7 +2340,6 @@ mode_invite_clear(struct Channel *chan) #define DONE_KEY_DEL 0x80 /**< We've removed the key */ #define DONE_UPASS_DEL 0x100 /**< We've removed the user pass */ #define DONE_APASS_DEL 0x200 /**< We've removed the admin pass */ -#define DONE_EXCEPTIONLIST 0x400 /**< We've sent the exception list */ #define DONE_ALTCHAN 0x800 /**< We've set the altchan */ #define DONE_ACCESS 0x1000 /**< We've set the access */ #define DONE_NOFLOOD 0x2000 /**< We've set the noflood options */ @@ -2567,15 +2555,17 @@ mode_parse_altchan(struct ParseState *state, ulong64 *flag_p) if (!IsChannelName(t_str) || !strIsIrcCh(t_str) || strlen(t_str) > IRCD_MIN(CHANNELLEN, feature_int(FEAT_CHANNELLEN)) || t_str[0] == '&') /* only parse it if it's a valid channel name! */ return; - struct Channel *chptr; - struct Membership *member; - if (!(chptr = FindChannel(t_str))) + if(!(state->flags & MODE_PARSE_FORCE)) { + struct Channel *chptr; + struct Membership *member; + if (!(chptr = FindChannel(t_str))) return; - if(!(member = find_member_link(chptr, state->sptr))) + if(!(member = find_member_link(chptr, state->sptr))) return; - if(!IsChanOp(member)) { + if(!IsChanOp(member)) { send_notoper(state); return; + } } if (!(state->flags & MODE_PARSE_WIPEOUT) && @@ -2619,10 +2609,13 @@ mode_parse_altchan(struct ParseState *state, ulong64 *flag_p) modebuf_mode_string(state->mbuf, state->dir | flag_p[0], t_str, 0); if (state->flags & MODE_PARSE_SET) { - if (state->dir == MODE_DEL) /* remove the old altchan */ + if (state->dir == MODE_DEL) { /* remove the old altchan */ *state->chptr->mode.altchan = '\0'; - else + state->chptr->mode.mode &= ~flag_p[0]; + } else { ircd_strncpy(state->chptr->mode.altchan, t_str, CHANNELLEN); + state->chptr->mode.mode |= flag_p[0]; + } } } @@ -2714,10 +2707,13 @@ mode_parse_noflood(struct ParseState *state, ulong64 *flag_p) modebuf_mode_string(state->mbuf, state->dir | flag_p[0], t_str, 0); if (state->flags & MODE_PARSE_SET) { - if (state->dir == MODE_DEL) /* remove the old noflood */ + if (state->dir == MODE_DEL) { /* remove the old noflood */ *state->chptr->mode.noflood = '\0'; - else + state->chptr->mode.mode &= ~flag_p[0]; + } else { ircd_strncpy(state->chptr->mode.noflood, t_str, CHANNELLEN); + state->chptr->mode.mode |= flag_p[0]; + } } if (state->dir == MODE_ADD) { @@ -2729,6 +2725,7 @@ mode_parse_noflood(struct ParseState *state, ulong64 *flag_p) state->chptr->mode.noflood_value = noflood_value; } else { //removed the mode so free all flood objects + state->chptr->mode.noflood_value = 0; struct Membership *member; for(member = state->chptr->members; member; member = member->next_member) { struct MemberFlood *floodnode; @@ -3295,19 +3292,9 @@ mode_parse_ban(struct ParseState *state, ulong64 *flag_p) struct Ban *ban, *newban; if (state->parc <= 0) { /* Not enough args, send ban list */ - if (MyUser(state->sptr)) { - if (*flag_p == MODE_EXCEPTION) { - if (!(state->done & DONE_EXCEPTIONLIST)) { - send_exception_list(state->sptr, state->chptr); - state->done |= DONE_EXCEPTIONLIST; - } - } - else { - if (!(state->done & DONE_BANLIST)) { - send_ban_list(state->sptr, state->chptr); - state->done |= DONE_BANLIST; - } - } + if (MyUser(state->sptr) && !(state->done & DONE_BANLIST)) { + send_ban_list(state->sptr, state->chptr); + state->done |= DONE_BANLIST; } return; } @@ -3384,8 +3371,7 @@ mode_process_bans(struct ParseState *state) } else if (ban->flags & BAN_DEL) { /* Deleted a ban? */ char *bandup; DupString(bandup, ban->banstr); - modebuf_mode_string(state->mbuf, MODE_DEL | ((ban->flags & BAN_EXCEPTION) ? MODE_EXCEPTION : MODE_BAN), - bandup, 1); + modebuf_mode_string(state->mbuf, MODE_DEL | MODE_BAN, bandup, 1); if (state->flags & MODE_PARSE_SET) { /* Ok, make it take effect */ if (prevban) /* clip it out of the list... */ @@ -3424,14 +3410,13 @@ mode_process_bans(struct ParseState *state) char *bandup; /* add the ban to the buffer */ DupString(bandup, ban->banstr); - modebuf_mode_string(state->mbuf, MODE_ADD | ((ban->flags & BAN_EXCEPTION) ? MODE_EXCEPTION : MODE_BAN), - bandup, 1); + modebuf_mode_string(state->mbuf, MODE_ADD | MODE_BAN, bandup, 1); if (state->flags & MODE_PARSE_SET) { /* create a new ban */ newban = make_ban(ban->banstr); strcpy(newban->who, ban->who); newban->when = ban->when; - newban->flags = ban->flags & (BAN_IPMASK | BAN_EXCEPTION); + newban->flags = ban->flags & BAN_IPMASK; newban->next = state->chptr->banlist; /* and link it in */ state->chptr->banlist = newban; @@ -3774,13 +3759,13 @@ mode_parse(struct ModeBuf *mbuf, struct Client *cptr, struct Client *sptr, MODE_PERSIST, 'z', MODE_NOCOLOUR, 'c', MODE_NOCTCP, 'C', -/* MODE_EXCEPTION, 'e',*/ MODE_NOAMSGS, 'M', MODE_NONOTICE, 'N', MODE_QUARANTINE, 'Q', MODE_ALTCHAN, 'F', MODE_ACCESS, 'a', MODE_AUDITORIUM, 'u', + MODE_SSLCHAN, 'S', MODE_NOFLOOD, 'f', MODE_ADD, '+', MODE_DEL, '-', @@ -3871,9 +3856,6 @@ mode_parse(struct ModeBuf *mbuf, struct Client *cptr, struct Client *sptr, if (IsServer(cptr) || feature_bool(FEAT_OPLEVELS)) mode_parse_upass(&state, flag_p); break; - -/* case 'e': - if(MyUser(state.sptr) && !(state.flags & MODE_PARSE_FORCE) && !feature_bool(FEAT_EXCEPT_ENABLE)) break;*/ case 'b': /* deal with bans */ mode_parse_ban(&state, flag_p); break; @@ -4410,7 +4392,7 @@ int ext_amsg_block(struct Client *cptr, struct Channel *chptr, const char *msg) * --pk910 2011/7/1 */ int ext_noflood_block(struct Client *cptr, struct Channel *chptr) { - if(chptr->mode.noflood == NULL || !chptr->mode.noflood) return 0; + if(!*chptr->mode.noflood) return 0; struct Membership *member = find_member_link(chptr, cptr); if(!member) return 0; //TODO: we've no check for -n channels implemented, yet //check if this user is really affected by +f