X-Git-Url: http://git.pk910.de/?p=ircu2.10.12-pk.git;a=blobdiff_plain;f=ircd%2Fchannel.c;fp=ircd%2Fchannel.c;h=02cdd96c52ad48fde34a1197cae6fad234022881;hp=b82d8e0780b25c4e3d0f8a92cb7ff71fd72a6d63;hb=665c0fad3ca5608bf886dd739ca47dfdf1827d13;hpb=db1838687f0fe133bdf0d4e2572344ce623fbacf diff --git a/ircd/channel.c b/ircd/channel.c index b82d8e0..02cdd96 100644 --- a/ircd/channel.c +++ b/ircd/channel.c @@ -1318,11 +1318,31 @@ static void send_ban_list(struct Client* cptr, struct Channel* chptr) assert(0 != chptr); for (lp = chptr->banlist; lp; lp = lp->next) - send_reply(cptr, RPL_BANLIST, chptr->chname, lp->banstr, lp->who, lp->when); + if ((lp->flags & BAN_EXCEPTION) != BAN_EXCEPTION) + send_reply(cptr, RPL_BANLIST, chptr->chname, lp->banstr, lp->who, lp->when); send_reply(cptr, RPL_ENDOFBANLIST, chptr->chname); } +/** send an exception list to a client for a channel + * + * @param cptr Client to send the banlist to. + * @param chptr Channel whose exception list 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) == BAN_EXCEPTION) + send_reply(cptr, RPL_EXCEPTLIST, chptr->chname, lp->banstr, lp->who, lp->when); + + send_reply(cptr, RPL_ENDOFEXCEPTLIST, 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). @@ -1632,6 +1652,7 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) MODE_QUARANTINE, 'Q', MODE_AUDITORIUM, 'u', MODE_SSLCHAN, 'S', +/* MODE_BANEXCEPTION 'e', */ 0x0, 0x0 }; static ulong64 local_flags[] = { @@ -1728,14 +1749,14 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) bufptr[(*bufptr_i)++] = 'v'; totalbuflen -= IRCD_MAX(9, tmp) + 1; } - } else if (MB_TYPE(mbuf, i) & (MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD)) { + } else if (MB_TYPE(mbuf, i) & (MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD | MODE_BANEXCEPTION)) { 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_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD)) + switch(MB_TYPE(mbuf, i) & (MODE_BAN | MODE_APASS | MODE_UPASS | MODE_ALTCHAN | MODE_NOFLOOD | MODE_BANEXCEPTION)) { case MODE_APASS: mode_char = 'A'; @@ -1749,8 +1770,11 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) case MODE_NOFLOOD: mode_char = 'f'; break; + case MODE_BAN: + mode_char = 'b'; + break; default: - mode_char = 'b'; + mode_char = 'e'; break; } bufptr[(*bufptr_i)++] = mode_char; @@ -1826,7 +1850,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)) + else if (MB_TYPE(mbuf, i) & (MODE_BAN | MODE_BANEXCEPTION)) build_string(strptr, strptr_i, MB_STRING(mbuf, i), 0, ' '); /* deal with keys... */ @@ -1942,7 +1966,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_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 | MODE_BANEXCEPTION)) build_string(strptr, strptr_i, MB_STRING(mbuf, i), 0, ' '); /* @@ -2258,6 +2282,7 @@ modebuf_extract(struct ModeBuf *mbuf, char *buf) MODE_AUDITORIUM, 'u', MODE_SSLCHAN, 'S', MODE_NOFLOOD, 'f', +/* MODE_BANEXCEPTION, 'e', */ 0x0, 0x0 }; ulong64 add; @@ -2369,6 +2394,7 @@ mode_invite_clear(struct Channel *chan) #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 */ +#define DONE_EXCEPTLIST 0x4000 /**< We've sent the exception list */ struct ParseState { struct ModeBuf *mbuf; @@ -3322,9 +3348,14 @@ 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) && !(state->done & DONE_BANLIST)) { - send_ban_list(state->sptr, state->chptr); - state->done |= DONE_BANLIST; + if (MyUser(state->sptr)) { + if (*flag_p == MODE_BANEXCEPTION && !(state->done & DONE_EXCEPTLIST)) { + send_exception_list(state->sptr, state->chptr); + state->done |= DONE_EXCEPTLIST; + } else if (*flag_p == MODE_BAN && !(state->done & DONE_BANLIST)) { + send_ban_list(state->sptr, state->chptr); + state->done |= DONE_BANLIST; + } } return; } @@ -3390,9 +3421,9 @@ mode_process_bans(struct ParseState *state) if ((ban->flags & (BAN_DEL | BAN_ADD)) == (BAN_DEL | BAN_ADD)) { if (prevban) - prevban->next = 0; /* Break the list; ban isn't a real ban */ + prevban->next = 0; /* Break the list; ban isn't a real ban */ else - state->chptr->banlist = 0; + state->chptr->banlist = 0; count--; len -= banlen; @@ -3401,59 +3432,57 @@ 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 | MODE_BAN, bandup, 1); + modebuf_mode_string(state->mbuf, MODE_DEL | ((ban->flags & BAN_EXCEPTION) ? MODE_BANEXCEPTION : MODE_BAN), bandup, 1); if (state->flags & MODE_PARSE_SET) { /* Ok, make it take effect */ - if (prevban) /* clip it out of the list... */ - prevban->next = ban->next; - else - state->chptr->banlist = ban->next; + if (prevban) /* clip it out of the list... */ + prevban->next = ban->next; + else + state->chptr->banlist = ban->next; - count--; - len -= banlen; + count--; + len -= banlen; free_ban(ban); - changed++; - continue; /* next ban; keep prevban like it is */ + changed++; + continue; /* next ban; keep prevban like it is */ } else - ban->flags &= BAN_IPMASK; /* unset other flags */ + ban->flags &= (BAN_IPMASK | BAN_EXCEPTION); /* unset other flags */ } else if (ban->flags & BAN_ADD) { /* adding a ban? */ if (prevban) - prevban->next = 0; /* Break the list; ban isn't a real ban */ + prevban->next = 0; /* Break the list; ban isn't a real ban */ else - state->chptr->banlist = 0; + state->chptr->banlist = 0; /* If we're supposed to ignore it, do so. */ - if (ban->flags & BAN_OVERLAPPED && - !(state->flags & MODE_PARSE_BOUNCE)) { - count--; - len -= banlen; + if (ban->flags & BAN_OVERLAPPED && !(state->flags & MODE_PARSE_BOUNCE)) { + count--; + len -= banlen; } else { - if (state->flags & MODE_PARSE_SET && MyUser(state->sptr) && - (len > (feature_int(FEAT_AVBANLEN) * feature_int(FEAT_MAXBANS)) || - count > feature_int(FEAT_MAXBANS))) { - send_reply(state->sptr, ERR_BANLISTFULL, state->chptr->chname, - ban->banstr); - count--; - len -= banlen; - } else { + if (state->flags & MODE_PARSE_SET && MyUser(state->sptr) && + (len > (feature_int(FEAT_AVBANLEN) * feature_int(FEAT_MAXBANS)) || + count > feature_int(FEAT_MAXBANS))) { + send_reply(state->sptr, ERR_BANLISTFULL, state->chptr->chname, ban->banstr); + count--; + len -= banlen; + } else { char *bandup; - /* add the ban to the buffer */ + /* add the ban to the buffer */ DupString(bandup, ban->banstr); - modebuf_mode_string(state->mbuf, MODE_ADD | MODE_BAN, bandup, 1); + modebuf_mode_string(state->mbuf, MODE_ADD | ((ban->flags & BAN_EXCEPTION) ? MODE_BANEXCEPTION : MODE_BAN), bandup, 1); - if (state->flags & MODE_PARSE_SET) { /* create a new ban */ - newban = make_ban(ban->banstr); + 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; + newban->when = ban->when; + newban->flags = ban->flags & (BAN_IPMASK | BAN_EXCEPTION); - newban->next = state->chptr->banlist; /* and link it in */ - state->chptr->banlist = newban; + newban->next = state->chptr->banlist; /* and link it in */ + state->chptr->banlist = newban; - changed++; - } - } + changed++; + } + } } } @@ -3802,6 +3831,7 @@ mode_parse(struct ModeBuf *mbuf, struct Client *cptr, struct Client *sptr, MODE_AUDITORIUM, 'u', MODE_SSLCHAN, 'S', MODE_NOFLOOD, 'f', + MODE_BANEXCEPTION, 'e', MODE_ADD, '+', MODE_DEL, '-', 0x0, 0x0 @@ -3892,6 +3922,7 @@ mode_parse(struct ModeBuf *mbuf, struct Client *cptr, struct Client *sptr, mode_parse_upass(&state, flag_p); break; case 'b': /* deal with bans */ + case 'e': /* and exceptions */ mode_parse_ban(&state, flag_p); break;