From 665c0fad3ca5608bf886dd739ca47dfdf1827d13 Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 24 May 2012 21:16:14 +0200 Subject: [PATCH] keep in sync with OGN upstream (SVN-322 && SVN-323) && fixed ISUPPORT (005) raw (read RFC!) --- include/channel.h | 7 +-- include/numeric.h | 4 +- include/supported.h | 2 +- ircd/channel.c | 123 +++++++++++++++++++++++++++----------------- ircd/m_clearmode.c | 7 +-- ircd/s_err.c | 4 +- 6 files changed, 90 insertions(+), 57 deletions(-) diff --git a/include/channel.h b/include/channel.h index 63cb19c..b3deec8 100644 --- a/include/channel.h +++ b/include/channel.h @@ -139,14 +139,15 @@ typedef signed long long long64; #define MODE_AUDITORIUM 0x200000000LLU /**< +u Auditorium */ #define MODE_NOFLOOD 0x400000000LLU /**< +f NoFlood */ #define MODE_SSLCHAN 0x800000000LLU /**< +S SSL Channel */ +#define MODE_BANEXCEPTION 0x1000000000LLU /**< +e Ban exception */ /** mode flags which take another parameter (With PARAmeterS) */ -#define MODE_WPARAS (MODE_CHANOP|MODE_HALFOP|MODE_VOICE|MODE_BAN|MODE_KEY|MODE_LIMIT|MODE_APASS|MODE_UPASS|MODE_ALTCHAN|MODE_ACCESS|MODE_NOFLOOD) +#define MODE_WPARAS (MODE_CHANOP|MODE_HALFOP|MODE_VOICE|MODE_BAN|MODE_KEY|MODE_LIMIT|MODE_APASS|MODE_UPASS|MODE_ALTCHAN|MODE_ACCESS|MODE_NOFLOOD|MODE_BANEXCEPTION) /** Available Channel modes */ -#define infochanmodes feature_bool(FEAT_OPLEVELS) ? "AcCbhiklmMnNopsStuUvrDRzQu" : "cCbhiklmMnNopsStuvrDRzQu" +#define infochanmodes feature_bool(FEAT_OPLEVELS) ? "AcCbehiklmMnNopsStuUvrDRzQu" : "cCbehiklmMnNopsStuvrDRzQu" /** Available Channel modes that take parameters */ -#define infochanmodeswithparams feature_bool(FEAT_OPLEVELS) ? "AbfhkloUvFa" : "bfhklovFa" +#define infochanmodeswithparams feature_bool(FEAT_OPLEVELS) ? "AbefhkloUvFa" : "befhklovFa" #define HoldChannel(x) (!(x)) /** name invisible */ diff --git a/include/numeric.h b/include/numeric.h index 30e54d9..4b144e7 100644 --- a/include/numeric.h +++ b/include/numeric.h @@ -268,8 +268,8 @@ extern const struct Numeric* get_error_numeric(int err); #define RPL_ISSUEDINVITE 345 /* Undernet extension */ #define RPL_INVITELIST 346 /* IRCnet, Undernet extension */ #define RPL_ENDOFINVITELIST 347 /* IRCnet, Undernet extension */ -/* RPL_EXCEPTLIST 348 IRCnet extension */ -/* RPL_ENDOFEXCEPTLIST 349 IRCnet extension */ +#define RPL_EXCEPTLIST 348 /* IRCnet extension */ +#define RPL_ENDOFEXCEPTLIST 349 /* IRCnet extension */ #define RPL_VERSION 351 #define RPL_WHOREPLY 352 /* See also RPL_ENDOFWHO */ diff --git a/include/supported.h b/include/supported.h index 5bbd5be..87807a1 100644 --- a/include/supported.h +++ b/include/supported.h @@ -65,7 +65,7 @@ #define FEATURESVALUES2 NICKLEN, TOPICLEN, AWAYLEN, TOPICLEN, \ feature_int(FEAT_CHANNELLEN), CHANNELLEN, \ (feature_bool(FEAT_LOCAL_CHANNELS) ? "#&" : "#"), "(ohv)@%+", "@%+", \ - (feature_bool(FEAT_OPLEVELS) ? "b,AkU,alfF,cCimMnNprstuDdRz" : "b,k,alfF,cCimMnNprstuDdRz"), \ + (feature_bool(FEAT_OPLEVELS) ? "be,AkU,alfF,cCimMnNprstuDdRz" : "be,k,alfF,cCimMnNprstuDdRz"), \ "rfc1459", feature_str(FEAT_NETWORK) #endif /* INCLUDED_supported_h */ 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; diff --git a/ircd/m_clearmode.c b/ircd/m_clearmode.c index 2695574..2e02bb0 100644 --- a/ircd/m_clearmode.c +++ b/ircd/m_clearmode.c @@ -128,6 +128,7 @@ do_clearmode(struct Client *cptr, struct Client *sptr, struct Channel *chptr, MODE_NOCOLOUR, 'c', MODE_NOCTCP, 'C', MODE_NOAMSGS, 'M', + MODE_BANEXCEPTION, 'e', 0x0, 0x0 }; int *flag_p; @@ -194,12 +195,12 @@ do_clearmode(struct Client *cptr, struct Client *sptr, struct Channel *chptr, } /* Deal with users on the channel */ - if (del_mode & (MODE_BAN | MODE_CHANOP | MODE_HALFOP | MODE_VOICE)) + if (del_mode & (MODE_BAN | MODE_BANEXCEPTION | MODE_CHANOP | MODE_HALFOP | MODE_VOICE)) for (member = chptr->members; member; member = member->next_member) { if (IsZombie(member)) /* we ignore zombies */ continue; - if (del_mode & MODE_BAN) /* If we cleared bans, clear the valid flags */ + if (del_mode & (MODE_BAN | MODE_BANEXCEPTION)) /* If we cleared bans, clear the valid flags */ ClearBanValid(member); /* Drop channel operator status */ @@ -285,7 +286,7 @@ int mo_clearmode(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { struct Channel *chptr; - char *control = "ovpsmikbl"; /* default control string */ + char *control = "ovpsmikble"; /* default control string */ const char *chname, *qreason; int force = 0; diff --git a/ircd/s_err.c b/ircd/s_err.c index cc9ccf8..e5531d7 100644 --- a/ircd/s_err.c +++ b/ircd/s_err.c @@ -728,9 +728,9 @@ static Numeric replyTable[] = { /* 347 */ { RPL_ENDOFINVITELIST, ":End of Invite List", "347" }, /* 348 */ - { 0 }, + { RPL_EXCEPTLIST, "%s %s %s %Tu", "348" }, /* 349 */ - { 0 }, + { RPL_ENDOFEXCEPTLIST, "%s :End of Channel Exception List", "349" }, /* 350 */ { 0 }, /* 351 */ -- 2.20.1