diff --git a/doc/example.conf b/doc/example.conf index 042364f3..cb584516 100755 --- a/doc/example.conf +++ b/doc/example.conf @@ -318,6 +318,7 @@ channel { burst_topicwho = yes; kick_on_split_riding = no; only_ascii_channels = no; + resv_forcepart = yes; }; serverhide { diff --git a/doc/reference.conf b/doc/reference.conf index f23050aa..326520ff 100755 --- a/doc/reference.conf +++ b/doc/reference.conf @@ -739,6 +739,11 @@ channel { * or non-ASCII). */ only_ascii_channels = no; + + /* resv_forcepart: force any local users to part a channel + * when a RESV is issued. + */ + resv_forcepart = yes; }; diff --git a/include/s_conf.h b/include/s_conf.h index 6a10c56a..750bfbd3 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -238,6 +238,7 @@ struct config_channel_entry int burst_topicwho; int kick_on_split_riding; int only_ascii_channels; + int resv_forcepart; }; struct config_server_hide diff --git a/modules/m_info.c b/modules/m_info.c index 3be948d3..d3ddb3b8 100644 --- a/modules/m_info.c +++ b/modules/m_info.c @@ -572,6 +572,12 @@ static struct InfoStruct info_table[] = { &ConfigChannel.use_knock, "Enable /KNOCK", }, + { + "resv_forcepart", + OUTPUT_BOOLEAN_YN, + { &ConfigChannel.resv_forcepart }, + "Force-part local users on channel RESV" + }, { "disable_hidden", OUTPUT_BOOLEAN_YN, diff --git a/modules/m_resv.c b/modules/m_resv.c index 3cbf4a86..faf4066a 100644 --- a/modules/m_resv.c +++ b/modules/m_resv.c @@ -67,6 +67,7 @@ static void cluster_resv(struct Client *source_p, int temp_time, static void handle_remote_unresv(struct Client *source_p, const char *name); static void remove_resv(struct Client *source_p, const char *name); static int remove_resv_from_file(struct Client *source_p, const char *name); +static void resv_chan_forcepart(const char *name, const char *reason, int temp_time); /* * mo_resv() @@ -231,6 +232,7 @@ parse_resv(struct Client *source_p, const char *name, aconf->name = rb_strdup(name); aconf->passwd = rb_strdup(reason); add_to_resv_hash(aconf->name, aconf); + resv_chan_forcepart(aconf->name, aconf->passwd, temp_time); if(temp_time > 0) { @@ -638,3 +640,54 @@ remove_resv_from_file(struct Client *source_p, const char *name) return 1; } + +static void +resv_chan_forcepart(const char *name, const char *reason, int temp_time) +{ + rb_dlink_node *ptr; + rb_dlink_node *next_ptr; + struct Channel *chptr; + struct membership *msptr; + struct Client *target_p; + + if(!ConfigChannel.resv_forcepart) + return; + + /* for each user on our server in the channel list + * send them a PART, and notify opers. + */ + chptr = find_channel(name); + if(chptr != NULL) + { + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) + { + msptr = ptr->data; + target_p = msptr->client_p; + + if(IsExemptResv(target_p)) + continue; + + sendto_server(target_p, chptr, CAP_TS6, NOCAPS, + ":%s PART %s", target_p->id, chptr->chname); + + sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s", + target_p->name, target_p->username, + target_p->host, chptr->chname, target_p->name); + + remove_user_from_channel(msptr); + + /* notify opers & user they were removed from the channel */ + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Forced PART for %s!%s@%s from %s (%s)", + target_p->name, target_p->username, + target_p->host, name, reason); + + if(temp_time > 0) + sendto_one_notice(target_p, ":*** Channel %s is temporarily unavailable on this server.", + name); + else + sendto_one_notice(target_p, ":*** Channel %s is no longer available on this server.", + name); + } + } +} diff --git a/src/newconf.c b/src/newconf.c index 36d05175..2d0b63dd 100644 --- a/src/newconf.c +++ b/src/newconf.c @@ -2190,6 +2190,7 @@ static struct ConfEntry conf_channel_table[] = { "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 }, { "\0", 0, NULL, 0, NULL } }; diff --git a/src/s_conf.c b/src/s_conf.c index 94e8669d..7acb5734 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -814,6 +814,7 @@ set_default_conf(void) ConfigChannel.default_split_server_count = 10; ConfigChannel.no_join_on_split = NO; ConfigChannel.no_create_on_split = YES; + ConfigChannel.resv_forcepart = YES; ConfigServerHide.flatten_links = 0; ConfigServerHide.links_delay = 300;