From 765d839d3c25cf804d7c0f8dbf82ad5f04b09a12 Mon Sep 17 00:00:00 2001 From: Elizabeth Jennifer Myers Date: Fri, 12 Aug 2011 20:33:10 -0400 Subject: [PATCH] Port ircd-seven banfowards to charybdis. nenolod gave the thumbs-up to port ircd-seven banfowards to charybdis to spb for a while, and people have asked about it. Might as well do it since it's a slow weekend. Note that as a side effect use_forward is removed from the config and unconditionally enabled! --- doc/example.conf | 7 +-- doc/reference.conf | 7 +-- extensions/extb_canjoin.c | 2 +- include/channel.h | 13 +++-- include/s_conf.h | 1 - modules/core/m_join.c | 47 ++++++++------- modules/core/m_mode.c | 11 +++- modules/m_info.c | 6 -- modules/m_knock.c | 4 +- src/channel.c | 34 +++++++---- src/chmode.c | 120 +++++++++++++++++++++++++------------- src/match.c | 2 +- src/newconf.c | 1 - src/s_conf.c | 1 - src/s_user.c | 5 -- src/supported.c | 3 +- 16 files changed, 154 insertions(+), 110 deletions(-) diff --git a/doc/example.conf b/doc/example.conf index 68957548..bfce3277 100755 --- a/doc/example.conf +++ b/doc/example.conf @@ -46,7 +46,7 @@ serverinfo { name = "hades.arpa"; sid = "42X"; description = "charybdis test server"; - network_name = "AthemeNET"; + network_name = "StaticBox"; network_desc = "Your IRC network."; hub = yes; @@ -84,7 +84,7 @@ serverinfo { admin { name = "Lazy admin (lazya)"; - description = "AthemeNET client server"; + description = "StaticBox client server"; email = "nobody@127.0.0.1"; }; @@ -326,7 +326,6 @@ channel { use_invex = yes; use_except = yes; use_knock = yes; - use_forward = yes; knock_delay = 5 minutes; knock_delay_channel = 1 minute; max_chans_per_user = 15; @@ -356,7 +355,7 @@ serverhide { * They are used in pairs of one host/rejection reason. * * These settings should be adequate for most networks, and are (presently) - * required for use on AthemeNet. + * required for use on StaticBox. * * Word to the wise: Do not use blacklists like SPEWS for blocking IRC * connections. diff --git a/doc/reference.conf b/doc/reference.conf index 5855c305..32e5bfa7 100755 --- a/doc/reference.conf +++ b/doc/reference.conf @@ -679,11 +679,6 @@ channel { */ use_except = yes; - /* forward: Enable/disable channel mode +f, a channel to forward - * users to if they can't join because of +i etc. - */ - use_forward = yes; - /* knock: Allows users to request an invite to a channel that * is locked somehow (+ikl). If the channel is +p or you are banned * the knock will not be sent. @@ -806,7 +801,7 @@ serverhide { * They are used in pairs of one host/rejection reason. * * These settings should be adequate for most networks, and are (presently) - * required for use on AthemeNet. + * required for use on StaticBox. * * Word to the wise: Do not use blacklists like SPEWS for blocking IRC * connections. diff --git a/extensions/extb_canjoin.c b/extensions/extb_canjoin.c index a45c0d31..3b3c95ba 100644 --- a/extensions/extb_canjoin.c +++ b/extensions/extb_canjoin.c @@ -61,7 +61,7 @@ static int eb_canjoin(const char *data, struct Client *client_p, return EXTBAN_INVALID; #endif recurse = 1; - ret = is_banned(chptr2, client_p, NULL, NULL, NULL) == CHFL_BAN ? EXTBAN_MATCH : EXTBAN_NOMATCH; + ret = is_banned(chptr2, client_p, NULL, NULL, NULL, NULL) == CHFL_BAN ? EXTBAN_MATCH : EXTBAN_NOMATCH; recurse = 0; return ret; } diff --git a/include/channel.h b/include/channel.h index 8e83cb2c..fcf226d5 100644 --- a/include/channel.h +++ b/include/channel.h @@ -97,6 +97,7 @@ struct Ban char *banstr; char *who; time_t when; + char *forward; rb_dlink_node node; }; @@ -210,7 +211,7 @@ void init_channels(void); struct Channel *allocate_channel(const char *chname); void free_channel(struct Channel *chptr); -struct Ban *allocate_ban(const char *, const char *); +struct Ban *allocate_ban(const char *, const char *, const char *); void free_ban(struct Ban *bptr); @@ -221,10 +222,11 @@ extern int can_send(struct Channel *chptr, struct Client *who, extern int flood_attack_channel(int p_or_n, struct Client *source_p, struct Channel *chptr, char *chname); extern int is_banned(struct Channel *chptr, struct Client *who, - struct membership *msptr, const char *, const char *); + struct membership *msptr, const char *, const char *, const char **); extern int is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr, const char *, const char *); -extern int can_join(struct Client *source_p, struct Channel *chptr, char *key); +extern int can_join(struct Client *source_p, struct Channel *chptr, char *key, + char **forward); extern struct membership *find_channel_membership(struct Channel *, struct Client *); extern const char *find_channel_status(struct membership *msptr, int combine); @@ -269,9 +271,10 @@ extern void set_channel_mlock(struct Client *client_p, struct Client *source_p, extern struct ChannelMode chmode_table[256]; extern int add_id(struct Client *source_p, struct Channel *chptr, const char *banid, - rb_dlink_list * list, long mode_type); + const char *forward, rb_dlink_list * list, long mode_type); -extern int del_id(struct Channel *chptr, const char *banid, rb_dlink_list * list, long mode_type); +extern struct Ban * del_id(struct Channel *chptr, const char *banid, rb_dlink_list * list, + long mode_type); extern ExtbanFunc extban_table[256]; diff --git a/include/s_conf.h b/include/s_conf.h index 10aba3aa..7c732e07 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -238,7 +238,6 @@ struct config_channel_entry int use_except; int use_invex; int use_knock; - int use_forward; int knock_delay; int knock_delay_channel; int max_bans; diff --git a/modules/core/m_join.c b/modules/core/m_join.c index 070d8588..1cdf4342 100644 --- a/modules/core/m_join.c +++ b/modules/core/m_join.c @@ -89,9 +89,16 @@ static int pargs; */ static struct Channel * check_forward(struct Client *source_p, struct Channel *chptr, - char *key) + char *key, int *err) { int depth = 0, i; + char *next = NULL; + + /* The caller (m_join) is only interested in the reason + * for the original channel. + */ + if ((*err = can_join(source_p, chptr, key, &next)) == 0) + return chptr; /* User is +Q */ if (IsNoForward(source_p)) @@ -99,7 +106,7 @@ check_forward(struct Client *source_p, struct Channel *chptr, while (depth < 16) { - chptr = find_channel(chptr->mode.forward); + chptr = find_channel(next); /* Can only forward to existing channels */ if (chptr == NULL) return NULL; @@ -112,10 +119,10 @@ check_forward(struct Client *source_p, struct Channel *chptr, /* Don't forward to +Q channel */ if (chptr->mode.mode & MODE_DISFORWARD) return NULL; - i = can_join(source_p, chptr, key); + i = can_join(source_p, chptr, key, &next); if (i == 0) return chptr; - if (i != ERR_INVITEONLYCHAN && i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_CHANNELISFULL) + if (next == NULL) return NULL; depth++; } @@ -132,7 +139,7 @@ static int m_join(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { static char jbuf[BUFSIZE]; - struct Channel *chptr = NULL; + struct Channel *chptr = NULL, *chptr2 = NULL; struct ConfItem *aconf; char *name; char *key = NULL; @@ -287,24 +294,22 @@ m_join(struct Client *client_p, struct Client *source_p, int parc, const char *p } } - /* can_join checks for +i key, bans etc */ - if((i = can_join(source_p, chptr, key))) + /* If check_forward returns NULL, they couldn't join and there wasn't a usable forward channel. */ + if(!(chptr2 = check_forward(source_p, chptr, key, &i))) { - if ((i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_INVITEONLYCHAN && i != ERR_CHANNELISFULL) || - (!ConfigChannel.use_forward || (chptr = check_forward(source_p, chptr, key)) == NULL)) - { - /* might be wrong, but is there any other better location for such? - * see extensions/chm_operonly.c for other comments on this - * -- dwr - */ - if(i != ERR_CUSTOM) - sendto_one(source_p, form_str(i), me.name, source_p->name, name); + /* might be wrong, but is there any other better location for such? + * see extensions/chm_operonly.c for other comments on this + * -- dwr + */ + if(i != ERR_CUSTOM) + sendto_one(source_p, form_str(i), me.name, source_p->name, name); - continue; - } - - sendto_one_numeric(source_p, ERR_LINKCHANNEL, form_str(ERR_LINKCHANNEL), name, chptr->chname); + continue; } + else if(chptr != chptr2) + sendto_one_numeric(source_p, ERR_LINKCHANNEL, form_str(ERR_LINKCHANNEL), name, chptr2->chname); + + chptr = chptr2; if(flags == 0 && !IsOper(source_p) && !IsExemptSpambot(source_p)) @@ -1120,7 +1125,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode) len = rb_sprintf(pbuf, "%d:%d ", mode->join_num, mode->join_time); pbuf += len; } - if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ConfigChannel.use_forward) + if(mode->forward[0] && strcmp(oldmode->forward, mode->forward)) { if(dir != MODE_ADD) { diff --git a/modules/core/m_mode.c b/modules/core/m_mode.c index 86d1207f..f4b837bc 100644 --- a/modules/core/m_mode.c +++ b/modules/core/m_mode.c @@ -247,7 +247,7 @@ ms_bmask(struct Client *client_p, struct Client *source_p, int parc, const char static char parabuf[BUFSIZE]; struct Channel *chptr; rb_dlink_list *banlist; - const char *s; + char *s, *forward; char *t; char *mbuf; char *pbuf; @@ -342,7 +342,14 @@ ms_bmask(struct Client *client_p, struct Client *source_p, int parc, const char if(tlen > MODEBUFLEN) break; - if(add_id(fakesource_p, chptr, s, banlist, mode_type)) + if((forward = strchr(s+1, '$')) != NULL) + { + *forward++ = '\0'; + if(*forward == '\0') + forward = NULL; + } + + if(add_id(fakesource_p, chptr, s, forward, banlist, mode_type)) { /* this new one wont fit.. */ if(mlen + MAXMODEPARAMS + plen + tlen > BUFSIZE - 5 || diff --git a/modules/m_info.c b/modules/m_info.c index 08e2f470..456b846e 100644 --- a/modules/m_info.c +++ b/modules/m_info.c @@ -602,12 +602,6 @@ static struct InfoStruct info_table[] = { &ConfigChannel.use_invex, "Enable chanmode +I (invite exceptions)", }, - { - "use_forward", - OUTPUT_BOOLEAN_YN, - &ConfigChannel.use_forward, - "Enable chanmode +f (channel forwarding)", - }, { "use_knock", OUTPUT_BOOLEAN_YN, diff --git a/modules/m_knock.c b/modules/m_knock.c index 4afe9df5..e85cce39 100644 --- a/modules/m_knock.c +++ b/modules/m_knock.c @@ -115,8 +115,8 @@ m_knock(struct Client *client_p, struct Client *source_p, int parc, const char * if(MyClient(source_p)) { /* don't allow a knock if the user is banned */ - if(is_banned(chptr, source_p, NULL, NULL, NULL) == CHFL_BAN || - is_quieted(chptr, source_p, NULL, NULL, NULL) == CHFL_BAN) + if(is_banned(chptr, source_p, NULL, NULL, NULL, NULL) == CHFL_BAN || + is_quieted(chptr, source_p, NULL, NULL, NULL) == CHFL_BAN) { sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN, form_str(ERR_CANNOTSENDTOCHAN), name); diff --git a/src/channel.c b/src/channel.c index 5a134235..4d4d2560 100644 --- a/src/channel.c +++ b/src/channel.c @@ -105,12 +105,13 @@ free_channel(struct Channel *chptr) } struct Ban * -allocate_ban(const char *banstr, const char *who) +allocate_ban(const char *banstr, const char *who, const char *forward) { struct Ban *bptr; bptr = rb_bh_alloc(ban_heap); bptr->banstr = rb_strdup(banstr); bptr->who = rb_strdup(who); + bptr->forward = forward ? rb_strdup(forward) : NULL; return (bptr); } @@ -120,6 +121,7 @@ free_ban(struct Ban *bptr) { rb_free(bptr->banstr); rb_free(bptr->who); + rb_free(bptr->forward); rb_bh_free(ban_heap, bptr); } @@ -522,7 +524,7 @@ del_invite(struct Channel *chptr, struct Client *who) */ int is_banned(struct Channel *chptr, struct Client *who, struct membership *msptr, - const char *s, const char *s2) + const char *s, const char *s2, const char **forward) { char src_host[NICKLEN + USERLEN + HOSTLEN + 6]; char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6]; @@ -616,6 +618,9 @@ is_banned(struct Channel *chptr, struct Client *who, struct membership *msptr, } } + if (actualBan && actualBan->forward && forward) + *forward = actualBan->forward; + return ((actualBan ? CHFL_BAN : 0)); } @@ -728,12 +733,12 @@ is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr, /* can_join() * * input - client to check, channel to check for, key - * output - reason for not being able to join, else 0 + * output - reason for not being able to join, else 0, channel name to forward to * side effects - * caveats - this function should only be called on a local user. */ int -can_join(struct Client *source_p, struct Channel *chptr, char *key) +can_join(struct Client *source_p, struct Channel *chptr, char *key, char **forward) { rb_dlink_node *invite = NULL; rb_dlink_node *ptr; @@ -770,12 +775,22 @@ can_join(struct Client *source_p, struct Channel *chptr, char *key) } } - if((is_banned(chptr, source_p, NULL, src_host, src_iphost)) == CHFL_BAN) + if((is_banned(chptr, source_p, NULL, src_host, src_iphost, forward)) == CHFL_BAN) { moduledata.approved = ERR_BANNEDFROMCHAN; goto finish_join_check; } + if(*chptr->mode.key && (EmptyString(key) || irccmp(chptr->mode.key, key))) + { + moduledata.approved = ERR_BADCHANNELKEY; + goto finish_join_check; + } + + /* All checks from this point on will forward... */ + if(forward) + *forward = chptr->mode.forward; + if(chptr->mode.mode & MODE_INVITEONLY) { RB_DLINK_FOREACH(invite, source_p->user->invited.head) @@ -802,9 +817,6 @@ can_join(struct Client *source_p, struct Channel *chptr, char *key) } } - if(*chptr->mode.key && (EmptyString(key) || irccmp(chptr->mode.key, key))) - moduledata.approved = ERR_BADCHANNELKEY; - if(chptr->mode.limit && rb_dlink_list_length(&chptr->members) >= (unsigned long) chptr->mode.limit) i = ERR_CHANNELISFULL; @@ -887,7 +899,7 @@ can_send(struct Channel *chptr, struct Client *source_p, struct membership *mspt if(can_send_banned(msptr)) moduledata.approved = CAN_SEND_NO; } - else if(is_banned(chptr, source_p, msptr, NULL, NULL) == CHFL_BAN + else if(is_banned(chptr, source_p, msptr, NULL, NULL, NULL) == CHFL_BAN || is_quieted(chptr, source_p, msptr, NULL, NULL) == CHFL_BAN) moduledata.approved = CAN_SEND_NO; } @@ -992,7 +1004,7 @@ find_bannickchange_channel(struct Client *client_p) if (can_send_banned(msptr)) return chptr; } - else if (is_banned(chptr, client_p, msptr, src_host, src_iphost) == CHFL_BAN + else if (is_banned(chptr, client_p, msptr, src_host, src_iphost, NULL) == CHFL_BAN || is_quieted(chptr, client_p, msptr, src_host, src_iphost) == CHFL_BAN) return chptr; } @@ -1224,7 +1236,7 @@ channel_modes(struct Channel *chptr, struct Client *client_p) chptr->mode.join_time); } - if(*chptr->mode.forward && (ConfigChannel.use_forward || !IsClient(client_p))) + if(*chptr->mode.forward) { *mbuf++ = 'f'; diff --git a/src/chmode.c b/src/chmode.c index a268fdc5..38ff8d88 100644 --- a/src/chmode.c +++ b/src/chmode.c @@ -65,6 +65,7 @@ static int mode_count; static int mode_limit; static int mode_limit_simple; static int mask_pos; +static int removed_mask_pos; char cflagsbuf[256]; char cflagsmyinfo[256]; @@ -103,14 +104,6 @@ construct_cflags_strings(void) switch (chmode_flags[i]) { - case MODE_EXLIMIT: - case MODE_DISFORWARD: - if(ConfigChannel.use_forward) - { - *ptr++ = (char) i; - } - - break; case MODE_REGONLY: if(rb_dlink_list_length(&service_list)) { @@ -210,12 +203,12 @@ get_channel_access(struct Client *source_p, struct membership *msptr) /* add_id() * - * inputs - client, channel, id to add, type + * inputs - client, channel, id to add, type, forward * outputs - 0 on failure, 1 on success * side effects - given id is added to the appropriate list */ int -add_id(struct Client *source_p, struct Channel *chptr, const char *banid, +add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const char *forward, rb_dlink_list * list, long mode_type) { struct Ban *actualBan; @@ -259,7 +252,7 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, else rb_strlcpy(who, source_p->name, sizeof(who)); - actualBan = allocate_ban(realban, who); + actualBan = allocate_ban(realban, who, forward); actualBan->when = rb_current_time(); rb_dlinkAdd(actualBan, &actualBan->node, list); @@ -274,17 +267,17 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, /* del_id() * * inputs - channel, id to remove, type - * outputs - 0 on failure, 1 on success - * side effects - given id is removed from the appropriate list + * outputs - pointer to ban that was removed, if any + * side effects - given id is removed from the appropriate list and returned */ -int +struct Ban * del_id(struct Channel *chptr, const char *banid, rb_dlink_list * list, long mode_type) { rb_dlink_node *ptr; struct Ban *banptr; if(EmptyString(banid)) - return 0; + return NULL; RB_DLINK_FOREACH(ptr, list->head) { @@ -299,11 +292,11 @@ del_id(struct Channel *chptr, const char *banid, rb_dlink_list * list, long mode if(mode_type == CHFL_BAN || mode_type == CHFL_QUIET || mode_type == CHFL_EXCEPTION) chptr->bants++; - return 1; + return banptr; } } - return 0; + return NULL; } /* check_string() @@ -347,10 +340,11 @@ pretty_mask(const char *idmask) { static char mask_buf[BUFSIZE]; int old_mask_pos; - char *nick, *user, *host; + char *nick, *user, *host, *forward = NULL; char splat[] = "*"; - char *t, *at, *ex; - char ne = 0, ue = 0, he = 0; /* save values at nick[NICKLEN], et all */ + char *t, *at, *ex, *ex2; + char ne = 0, ue = 0, he = 0, fe = 0; /* save values at nick[NICKLEN], et all */ + char e2 = 0; /* save value that delimits forward channel */ char *mask; mask = LOCAL_COPY(idmask); @@ -376,7 +370,7 @@ pretty_mask(const char *idmask) return mask_buf + old_mask_pos; } - at = ex = NULL; + at = ex = ex2 = NULL; if((t = strchr(mask, '@')) != NULL) { at = t; @@ -398,6 +392,15 @@ pretty_mask(const char *idmask) if(*mask != '\0') user = mask; } + + if((t = strchr(host, '!')) != NULL || (t = strchr(host, '$')) != NULL) + { + ex2 = t; + e2 = *t; + *t++= '\0'; + if (*t != '\0') + forward = t; + } } else if((t = strchr(mask, '!')) != NULL) { @@ -408,7 +411,7 @@ pretty_mask(const char *idmask) if(*t != '\0') user = t; } - else if(strchr(mask, '.') != NULL || strchr(mask, ':') != NULL || strchr(mask, '/') != NULL) + else if(strchr(mask, '.') != NULL || strchr(mask, ':') != NULL) { if(*mask != '\0') host = mask; @@ -435,20 +438,32 @@ pretty_mask(const char *idmask) he = host[HOSTLEN]; host[HOSTLEN] = '\0'; } + if(forward && strlen(forward) > CHANNELLEN) + { + fe = forward[CHANNELLEN]; + forward[CHANNELLEN] = '\0'; + } - mask_pos += rb_sprintf(mask_buf + mask_pos, "%s!%s@%s", nick, user, host) + 1; + if (forward) + mask_pos += rb_sprintf(mask_buf + mask_pos, "%s!%s@%s$%s", nick, user, host, forward) + 1; + else + mask_pos += rb_sprintf(mask_buf + mask_pos, "%s!%s@%s", nick, user, host) + 1; /* restore mask, since we may need to use it again later */ if(at) *at = '@'; if(ex) *ex = '!'; + if(ex2) + *ex2 = e2; if(ne) nick[NICKLEN - 1] = ne; if(ue) user[USERLEN] = ue; if(he) host[HOSTLEN] = he; + if(fe) + forward[CHANNELLEN] = fe; return mask_buf + old_mask_pos; } @@ -534,11 +549,6 @@ chm_simple(struct Client *source_p, struct Channel *chptr, /* setting + */ if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type)) { - /* if +f is disabled, ignore an attempt to set +QF locally */ - if(!ConfigChannel.use_forward && MyClient(source_p) && - (c == 'Q' || c == 'F')) - return; - chptr->mode.mode |= mode_type; mode_changes[mode_count].letter = c; @@ -653,8 +663,7 @@ chm_ban(struct Client *source_p, struct Channel *chptr, int alevel, int parc, int *parn, const char **parv, int *errors, int dir, char c, long mode_type) { - const char *mask; - const char *raw_mask; + char *mask, *raw_mask, *forward; rb_dlink_list *list; rb_dlink_node *ptr; struct Ban *banptr; @@ -745,10 +754,16 @@ chm_ban(struct Client *source_p, struct Channel *chptr, RB_DLINK_FOREACH(ptr, list->head) { + char buf[BANLEN]; banptr = ptr->data; + if(banptr->forward) + rb_snprintf(buf, sizeof(buf), "%s$%s", banptr->banstr, banptr->forward); + else + rb_strlcpy(buf, banptr->banstr, sizeof(buf)); + sendto_one(source_p, form_str(rpl_list), me.name, source_p->name, chptr->chname, - banptr->banstr, banptr->who, banptr->when); + buf, banptr->who, banptr->when); } sendto_one(source_p, form_str(rpl_endlist), me.name, source_p->name, chptr->chname); return; @@ -783,6 +798,17 @@ chm_ban(struct Client *source_p, struct Channel *chptr, else mask = pretty_mask(raw_mask); + /* Look for a $ after the first character. + * As the first character, it marks an extban; afterwards + * it delimits a forward channel. + */ + if ((forward = strchr(mask+1, '$')) != NULL) + { + *forward++ = '\0'; + if (*forward == '\0') + forward = NULL; + } + /* we'd have problems parsing this, hyb6 does it too * also make sure it will always fit on a line with channel * name etc. @@ -803,9 +829,12 @@ chm_ban(struct Client *source_p, struct Channel *chptr, /* dont allow local clients to overflow the banlist, dont * let remote servers set duplicate bans */ - if(!add_id(source_p, chptr, mask, list, mode_type)) + if(!add_id(source_p, chptr, mask, forward, list, mode_type)) return; + if(forward) + forward[-1]= '$'; + mode_changes[mode_count].letter = c; mode_changes[mode_count].dir = MODE_ADD; mode_changes[mode_count].caps = caps; @@ -816,20 +845,33 @@ chm_ban(struct Client *source_p, struct Channel *chptr, } else if(dir == MODE_DEL) { - if(del_id(chptr, mask, list, mode_type) == 0) + struct Ban *removed; + static char buf[BANLEN * MAXMODEPARAMS]; + int old_removed_mask_pos = removed_mask_pos; + if((removed = del_id(chptr, mask, list, mode_type)) == NULL) { /* mask isn't a valid ban, check raw_mask */ - if(del_id(chptr, raw_mask, list, mode_type)) + if((removed = del_id(chptr, raw_mask, list, mode_type)) != NULL) mask = raw_mask; } + if(removed && removed->forward) + removed_mask_pos += rb_snprintf(buf, sizeof(buf), "%s$%s", removed->banstr, removed->forward); + else + removed_mask_pos += rb_strlcpy(buf, mask, sizeof(buf)); + if(removed) + { + free_ban(removed); + removed = NULL; + } + mode_changes[mode_count].letter = c; mode_changes[mode_count].dir = MODE_DEL; mode_changes[mode_count].caps = caps; mode_changes[mode_count].nocaps = 0; mode_changes[mode_count].mems = mems; mode_changes[mode_count].id = NULL; - mode_changes[mode_count++].arg = mask; + mode_changes[mode_count++].arg = buf + old_removed_mask_pos; } } @@ -1131,11 +1173,6 @@ chm_forward(struct Client *source_p, struct Channel *chptr, struct membership *msptr; const char *forward; - /* if +f is disabled, ignore local attempts to set it */ - if(!ConfigChannel.use_forward && MyClient(source_p) && - (dir == MODE_ADD) && (parc > *parn)) - return; - if(dir == MODE_QUERY || (dir == MODE_ADD && parc <= *parn)) { if (!(*errors & SM_ERR_RPL_F)) @@ -1214,7 +1251,7 @@ chm_forward(struct Client *source_p, struct Channel *chptr, mode_changes[mode_count].dir = MODE_ADD; mode_changes[mode_count].caps = 0; mode_changes[mode_count].nocaps = 0; - mode_changes[mode_count].mems = ConfigChannel.use_forward ? ALL_MEMBERS : ONLY_SERVERS; + mode_changes[mode_count].mems = ALL_MEMBERS; mode_changes[mode_count].id = NULL; mode_changes[mode_count++].arg = forward; } @@ -1614,6 +1651,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p, struct Client *fakesource_p; mask_pos = 0; + removed_mask_pos = 0; mode_count = 0; mode_limit = 0; mode_limit_simple = 0; diff --git a/src/match.c b/src/match.c index 18d7472f..626859d8 100644 --- a/src/match.c +++ b/src/match.c @@ -691,7 +691,7 @@ const unsigned int CharAttrs[] = { /* ! */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C, /* " */ PRINT_C | CHAN_C | NONEOS_C, /* # */ PRINT_C | MWILD_C | CHANPFX_C | CHAN_C | NONEOS_C, -/* $ */ PRINT_C | CHAN_C | NONEOS_C | USER_C, +/* $ */ PRINT_C | NONEOS_C | USER_C, /* % */ PRINT_C | CHAN_C | NONEOS_C, /* & */ PRINT_C | CHANPFX_C | CHAN_C | NONEOS_C, /* ' */ PRINT_C | CHAN_C | NONEOS_C, diff --git a/src/newconf.c b/src/newconf.c index 8f8dd380..0063bf76 100644 --- a/src/newconf.c +++ b/src/newconf.c @@ -2276,7 +2276,6 @@ static struct ConfEntry conf_channel_table[] = { "use_except", CF_YESNO, NULL, 0, &ConfigChannel.use_except }, { "use_invex", CF_YESNO, NULL, 0, &ConfigChannel.use_invex }, { "use_knock", CF_YESNO, NULL, 0, &ConfigChannel.use_knock }, - { "use_forward", CF_YESNO, NULL, 0, &ConfigChannel.use_forward }, { "resv_forcepart", CF_YESNO, NULL, 0, &ConfigChannel.resv_forcepart }, { "channel_target_change", CF_YESNO, NULL, 0, &ConfigChannel.channel_target_change }, { "disable_local_channels", CF_YESNO, NULL, 0, &ConfigChannel.disable_local_channels }, diff --git a/src/s_conf.c b/src/s_conf.c index 43acbdbe..42c274c5 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -757,7 +757,6 @@ set_default_conf(void) ConfigChannel.use_except = YES; ConfigChannel.use_invex = YES; ConfigChannel.use_knock = YES; - ConfigChannel.use_forward = YES; ConfigChannel.knock_delay = 300; ConfigChannel.knock_delay_channel = 60; ConfigChannel.max_chans_per_user = 15; diff --git a/src/s_user.c b/src/s_user.c index 3e7fa710..8e2c4817 100644 --- a/src/s_user.c +++ b/src/s_user.c @@ -1073,11 +1073,6 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char } /* FALLTHROUGH */ default: - if (MyConnect(source_p) && *pm == 'Q' && !ConfigChannel.use_forward) { - badflag = YES; - break; - } - if((flag = user_modes[(unsigned char) *pm])) { if(MyConnect(source_p) diff --git a/src/supported.c b/src/supported.c index ff59396d..8610e1ee 100644 --- a/src/supported.c +++ b/src/supported.c @@ -228,10 +228,9 @@ isupport_chanmodes(const void *ptr) { static char result[80]; - rb_snprintf(result, sizeof result, "%s%sbq,k,%slj,%s", + rb_snprintf(result, sizeof result, "%s%sbq,k,flj,%s", ConfigChannel.use_except ? "e" : "", ConfigChannel.use_invex ? "I" : "", - ConfigChannel.use_forward ? "f" : "", cflagsbuf); return result; }