loadmodule "extensions/sno_globaloper.so";
#loadmodule "extensions/sno_whois.so";
-/* Modesets, load only one */
-loadmodule "modes/shadowircd.so";
-#loadmodule "modes/charybdis.so";
-
serverinfo {
name = "hades.arpa";
sid = "42X";
channel {
autochanmodes = "nt";
+ admin_on_channel_create = no;
exemptchanops = "NT";
use_halfop = yes;
use_admin = yes;
use_invex = yes;
use_except = yes;
use_knock = yes;
+ use_forward = yes;
use_local_channels = yes;
knock_delay = 5 minutes;
knock_delay_channel = 1 minute;
cycle_host_change = yes;
host_in_topic = yes;
resv_forcepart = yes;
+ channel_target_change = yes;
};
serverhide {
target = "InfoServ";
};
+ alias "GroupServ" {
+ target = "GroupServ";
+ };
+
alias "NS" {
target = "NickServ";
};
target = "InfoServ";
};
+ alias "GS" {
+ target = "GroupServ";
+ };
+
general {
hide_error_messages = opers;
hide_spoof_ips = yes;
#static_quit = "I like turtles!";
servicestring = "is a Network Service";
disable_fake_channels = no;
+ hide_channel_below_users = 3;
tkline_expire_notices = no;
default_floodcount = 10;
failed_oper_notice = yes;
loadmodule "extensions/sno_globaloper.so";
#loadmodule "extensions/sno_whois.so";
-/* modesets: Modesets are modules that enable various user and channel
- * modes. When enabled, they enable usermodes and channel modes equivalent
- * to the named ircd. This is useful for linking to other TS6 IRCds.
- * If you do not know what this does or do not know if you need it
- * then you should just load modes/shadowircd.so for full functionality.
- * Without any modeset loaded, you will only have the modes that are included
- * in ircd-ratbox. Unloading a modeset while the ircd is running is possible,
- * but will be confusing for users, as it will leave all existent unloaded
- * modes in place without users being able to remove them. Said modes will,
- * however, not function. You should be able to load a module that provides
- * more modes than your current (say, going from charybdis to shadowircd)
- * on the fly without any problems. The slight exception to this is unloading
- * a module that provides quiets (cmode +q). Users affected by quiets will
- * have to part and rejoin the channel before the quiet will cease affecting
- * them. In addition, unloaded modes will remain in the IRCd's VERSION reply
- * until restart. For these reasons, it is highly recommended to restart if you wish
- * to change modeset.
- * Modesets currently only affect cmodes.
- * You should only load one of these at a time.
- * Modules are listed in order of highest functionality to least,
- * while no module provides the least functionality of all. */
-
-loadmodule "modes/shadowircd.so";
-#loadmodule "modes/charybdis.so";
-
/* serverinfo {}: Contains information about the server. (OLD M:) */
serverinfo {
*/
autochanmodes = "nt";
+ /* admin_on_channel_create: If set to yes, users joining new channels
+ * will be given +ao instead of just +o. Requires use_admin.
+ */
+ admin_on_channel_create = no;
+
/* exemptchanops: Channel modes that any form of channel ops (+aoh)
* will be exempt from. Even if the mode is set, it will not apply to the
* channel ops if it is listed in this option. Valid modes are cCDTNGK.
*/
use_except = yes;
+ /* forward: Enable/disable channel mode +f, which allows you to set
+ * a channel to forward users to if they can't join because of +i etc.
+ * Disabling this option via rehash will leave all previously set
+ * forwards hanging around, though they will not do anything. For
+ * this reason, you may want to restart to disable this option.
+ */
+ 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.
* when a RESV is issued.
*/
resv_forcepart = yes;
+
+ /* channel target change: restrict how many channels users can
+ * message per unit of time. IRC operators, channel operators and
+ * voiced users are exempt.
+ */
+ channel_target_change = yes;
};
target = "InfoServ";
};
+ alias "GroupServ" {
+ target = "GroupServ";
+ };
+
alias "NS" {
target = "NickServ";
};
target = "InfoServ";
};
+ alias "GS" {
+ target = "GroupServ";
+ };
+
/* The general block contains many of the options that were once compiled
* in options in config.h. The general block is read at start time.
*/
*/
disable_fake_channels = no;
+ /* hide_channel_below_users: Amount of users a channel must have in it
+ * before it is shown in a standard LIST. This can be overridden by
+ * invoking LIST like: /LIST <3
+ */
+ hide_channel_below_users = 3;
+
/* tkline_expire_notices: give a notice to opers when a tkline
* expires
*/
{
rb_dlink_node node;
struct Mode mode;
+ char *mode_lock;
char *topic;
char *topic_info;
time_t topic_time;
long mode_type;
};
-/* modes added by the module files in modes/ */
-struct module_modes
-{
- unsigned int MODE_REGONLY;
- unsigned int MODE_NOCTCP; /* Block CTCPs directed to this channel */
- unsigned int MODE_NOCOLOR;
- unsigned int MODE_EXLIMIT; /* exempt from list limits, +b/+e/+I/+q */
- unsigned int MODE_PERMANENT; /* permanant channel, +P */
- unsigned int MODE_OPMODERATE; /* send rejected messages to ops */
- unsigned int MODE_FREEINVITE; /* allow free use of /invite */
- unsigned int MODE_FREETARGET; /* can be forwarded to without authorization */
- unsigned int MODE_DISFORWARD; /* disable channel forwarding */
- unsigned int MODE_THROTTLE; /* throttle joins */
- unsigned int MODE_FORWARD;
- unsigned int MODE_NONOTICE; /* Block notices directed to this channel */
- unsigned int MODE_NOACTION; /* Block CTCP ACTION directed to this channel */
- unsigned int MODE_NOKICK; /* Disable /kick on this channel */
- unsigned int MODE_NONICK; /* Disable /nick for anyone on this channel */
- unsigned int MODE_NOCAPS; /* Block messages in all capital letters */
- unsigned int MODE_NOREJOIN; /* Block rejoin immediately after kick */
- unsigned int MODE_NOREPEAT; /* Block repeat messages */
- unsigned int MODE_NOOPERKICK; /* disallow kicking opers */
-
- unsigned int CHFL_QUIET;
-};
-
typedef int (*ExtbanFunc)(const char *data, struct Client *client_p,
struct Channel *chptr, long mode_type);
#define MODE_TOPICLIMIT 0x0008
#define MODE_INVITEONLY 0x0010
#define MODE_NOPRIVMSGS 0x0020
+#define MODE_REGONLY 0x0040
+#define MODE_NOCOLOR 0x0080
+#define MODE_EXLIMIT 0x0100 /* exempt from list limits, +b/+e/+I/+q */
+#define MODE_PERMANENT 0x0200 /* permanant channel, +P */
+#define MODE_OPMODERATE 0x0400 /* send rejected messages to ops */
+#define MODE_FREEINVITE 0x0800 /* allow free use of /invite */
+#define MODE_FREETARGET 0x1000 /* can be forwarded to without authorization */
+#define MODE_DISFORWARD 0x2000 /* disable channel forwarding */
+#define MODE_NOCTCP 0x8000 /* Block CTCPs directed to this channel */
+#define MODE_NONOTICE 0x10000 /* Block notices directed to this channel */
+#define MODE_NOACTION 0x20000 /* Block CTCP ACTION directed to this channel */
+#define MODE_NOKICK 0x40000 /* Disable /kick on this channel */
+#define MODE_NONICK 0x80000 /* Disable /nick for anyone on this channel */
+#define MODE_NOCAPS 0x100000 /* Block messages in all capital letters */
+#define MODE_NOREJOIN 0x200000 /* Block rejoin immediately after kick */
+#define MODE_NOREPEAT 0x400000 /* Block repeat messages */
+#define MODE_NOOPERKICK 0x800000 /* disallow kicking opers */
#define CHFL_BAN 0x10000000 /* ban channel flag */
#define CHFL_EXCEPTION 0x20000000 /* exception to ban channel flag */
#define CHFL_INVEX 0x40000000
+#define CHFL_QUIET 0x80000000
/* mode flags for direction indication */
#define MODE_QUERY 0
extern rb_dlink_list global_channel_list;
void init_channels(void);
-void init_module_modes(void);
struct Channel *allocate_channel(const char *chname);
void free_channel(struct Channel *chptr);
extern void set_channel_mode(struct Client *client_p, struct Client *source_p,
struct Channel *chptr, struct membership *msptr, int parc, const char *parv[]);
+ extern void set_channel_mlock(struct Client *client_p, struct Client *source_p,
+ struct Channel *chptr, const char *newmlock, int propagate);
extern struct ChannelMode chmode_table[256];
unsigned char compression_level;
int disable_fake_channels;
+ int hide_channel_below_users;
int dots_in_ident;
int failed_oper_notice;
int anti_nick_flood;
{
char * autochanmodes;
char * exemptchanops;
+ int admin_on_channel_create;
int use_halfop;
int use_admin;
int use_except;
int use_invex;
int use_knock;
+ int use_forward;
int use_local_channels;
int knock_delay;
int knock_delay_channel;
int cycle_host_change;
int host_in_topic;
int resv_forcepart;
+ int channel_target_change;
int exempt_cmode_c;
int exempt_cmode_C;
static int ms_join(struct Client *, struct Client *, int, const char **);
static int ms_sjoin(struct Client *, struct Client *, int, const char **);
-struct module_modes ModuleModes;
-
struct Message join_msgtab = {
"JOIN", 0, 0, 0, MFLG_SLOW,
{mg_unreg, {m_join, 2}, {ms_join, 2}, mg_ignore, mg_ignore, {m_join, 2}}
if((target_p = find_person(parv[1])) == NULL)
return 0;
+ if(!MyClient(target_p))
+ return 0;
+
user_join(&me, target_p, parv[2], NULL);
return 0;
}
source_p->servptr->name,
chptr->chname, modebuf, parabuf);
*omodebuf = *modebuf = *parabuf = '\0';
+
+ /* since we're dropping our modes, we want to clear the mlock as well. --nenolod */
+ set_channel_mlock(client_p, source_p, chptr, NULL, FALSE);
}
if(!IsMember(source_p, chptr))
/* Update capitalization in channel name, this makes the
* capitalization timestamped like modes are -- jilles */
strcpy(chptr->chname, parv[2]);
+
+ /* since we're dropping our modes, we want to clear the mlock as well. --nenolod */
+ set_channel_mlock(client_p, source_p, chptr, NULL, FALSE);
}
if(*modebuf != '\0')
{
fl = 0;
- for (i = 0; i < 2; i++)
+ for (i = 0; i < 4; i++)
{
if(*s == '!')
{
para[pargs++] = target_p->name;
}
}
- if(fl & CHFL_CHANOP)
+ else if(fl & CHFL_CHANOP)
{
*mbuf++ = 'o';
para[pargs++] = target_p->name;
para[pargs++] = target_p->name;
}
}
- if(fl & CHFL_HALFOP)
+ else if(fl & CHFL_HALFOP)
{
*mbuf++ = 'h';
para[pargs++] = target_p->name;
CheckEmpty(para[2]), CheckEmpty(para[3]));
}
- if(!joins && !(chptr->mode.mode & ModuleModes.MODE_PERMANENT) && isnew)
+ if(!joins && !(chptr->mode.mode & MODE_PERMANENT) && isnew)
{
destroy_channel(chptr);
len = rb_sprintf(pbuf, "%d:%d ", mode->join_num, mode->join_time);
pbuf += len;
}
- if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ModuleModes.MODE_FORWARD)
+ if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ConfigChannel.use_forward)
{
if(dir != MODE_ADD)
{
#include "tgchange.h"
#include "inline/stringops.h"
#include "irc_dictionary.h"
-#include "channel.h"
static int m_message(int, const char *, struct Client *, struct Client *, int, const char **);
static int m_privmsg(struct Client *, struct Client *, int, const char **);
static void expire_tgchange(void *unused);
static struct ev_entry *expire_tgchange_event;
-struct module_modes ModuleModes;
-
static int
modinit(void)
{
source_p->localClient->last = rb_current_time();
}
- if(chptr->mode.mode & ModuleModes.MODE_NOREPEAT)
+ if(chptr->mode.mode & MODE_NOREPEAT)
{
rb_strlcpy(text2, text, BUFSIZE);
strip_unprintable(text2);
channel_metadata_add(chptr, "NOREPEAT", text2, 0);
}
- if(chptr->mode.mode & ModuleModes.MODE_NOCOLOR && (!ConfigChannel.exempt_cmode_c || !is_any_op(msptr)))
+ if(chptr->mode.mode & MODE_NOCOLOR && (!ConfigChannel.exempt_cmode_c || !is_any_op(msptr)))
{
rb_strlcpy(text2, text, BUFSIZE);
strip_colour(text2);
/* chanops and voiced can flood their own channel with impunity */
if((result = can_send(chptr, source_p, NULL)))
{
+ if(result != CAN_SEND_OPV && MyClient(source_p) &&
+ !IsOper(source_p) &&
+ !add_channel_target(source_p, chptr))
+ {
+ sendto_one(source_p, form_str(ERR_TARGCHANGE),
+ me.name, source_p->name, chptr->chname);
+ return;
+ }
if(result == CAN_SEND_OPV ||
!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
{
- if (strlen(text) > 10 && chptr->mode.mode & ModuleModes.MODE_NOCAPS && (!ConfigChannel.exempt_cmode_G || !is_any_op(msptr)))
+ if (strlen(text) > 10 && chptr->mode.mode & MODE_NOCAPS && (!ConfigChannel.exempt_cmode_G || !is_any_op(msptr)))
{
rb_strlcpy(text2, text, BUFSIZE);
strip_unprintable(text2);
return;
}
}
- if (p_or_n != PRIVMSG && chptr->mode.mode & ModuleModes.MODE_NONOTICE && (!ConfigChannel.exempt_cmode_T || !is_any_op(msptr)))
+ if (p_or_n != PRIVMSG && chptr->mode.mode & MODE_NONOTICE && (!ConfigChannel.exempt_cmode_T || !is_any_op(msptr)))
{
sendto_one_numeric(source_p, 404, "%s :Cannot send to channel - Notices are disallowed (+T set)", chptr->chname);
return;
}
- if (p_or_n != NOTICE && chptr->mode.mode & ModuleModes.MODE_NOACTION &&
+ if (p_or_n != NOTICE && chptr->mode.mode & MODE_NOACTION &&
!strncasecmp(text + 1, "ACTION", 6) &&
(!ConfigChannel.exempt_cmode_D || !is_any_op(msptr)))
{
if (p_or_n != NOTICE && *text == '\001' &&
strncasecmp(text + 1, "ACTION", 6))
{
- if (chptr->mode.mode & ModuleModes.MODE_NOCTCP && (!ConfigChannel.exempt_cmode_C || !is_any_op(msptr)))
+ if (chptr->mode.mode & MODE_NOCTCP && (!ConfigChannel.exempt_cmode_C || !is_any_op(msptr)))
{
sendto_one_numeric(source_p, 404, "%s :Cannot send to channel - CTCPs to this channel are disallowed (+C set)", chptr->chname);
return;
"%s %s :%s", command, chptr->chname, text);
}
}
- else if(chptr->mode.mode & ModuleModes.MODE_OPMODERATE &&
+ else if(chptr->mode.mode & MODE_OPMODERATE &&
(!(chptr->mode.mode & MODE_NOPRIVMSGS) ||
IsMember(source_p, chptr)))
{
+ if(MyClient(source_p) && !IsOper(source_p) &&
+ !add_channel_target(source_p, chptr))
+ {
+ sendto_one(source_p, form_str(ERR_TARGCHANGE),
+ me.name, source_p->name, chptr->chname);
+ return;
+ }
if(!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
{
sendto_channel_opmod(client_p, source_p, chptr,
{
char text2[BUFSIZE];
- if(chptr->mode.mode & ModuleModes.MODE_NOCOLOR)
+ if(chptr->mode.mode & MODE_NOCOLOR)
{
rb_strlcpy(text2, text, BUFSIZE);
strip_colour(text2);
}
}
- if(chptr->mode.mode & ModuleModes.MODE_OPMODERATE &&
+ if(chptr->mode.mode & MODE_OPMODERATE &&
(!(chptr->mode.mode & MODE_NOPRIVMSGS) ||
IsMember(source_p, chptr)))
{
if(MyClient(source_p))
{
+ /*
+ * XXX: Controversial? Allow target users to send replies
+ * through a +g. Rationale is that people can presently use +g
+ * as a way to taunt users, e.g. harass them and hide behind +g
+ * as a way of griefing. --nenolod
+ */
+ if(p_or_n != NOTICE && MyClient(source_p) &&
+ IsSetCallerId(source_p) &&
+ IsSetSCallerId(source_p) &&
+ !accept_message(target_p, source_p))
+ {
+ if(rb_dlink_list_length(&source_p->localClient->allow_list) <
+ ConfigFileEntry.max_accept)
+ {
+ rb_dlinkAddAlloc(target_p, &source_p->localClient->allow_list);
+ rb_dlinkAddAlloc(source_p, &target_p->on_allow_list);
+ }
+ else
+ {
+ sendto_one_numeric(source_p, ERR_OWNMODE,
+ form_str(ERR_OWNMODE),
+ target_p->name, "+g");
+ return;
+ }
+ }
+
/* reset idle time for message only if its not to self
* and its not a notice */
if(p_or_n != NOTICE)
#include "packet.h"
#include "s_newconf.h"
-struct module_modes ModuleModes;
-
static int m_mode(struct Client *, struct Client *, int, const char **);
static int ms_mode(struct Client *, struct Client *, int, const char **);
static int ms_tmode(struct Client *, struct Client *, int, const char **);
+ static int ms_mlock(struct Client *, struct Client *, int, const char **);
static int ms_bmask(struct Client *, struct Client *, int, const char **);
struct Message mode_msgtab = {
"TMODE", 0, 0, 0, MFLG_SLOW,
{mg_ignore, mg_ignore, {ms_tmode, 4}, {ms_tmode, 4}, mg_ignore, mg_ignore}
};
+ struct Message mlock_msgtab = {
+ "MLOCK", 0, 0, 0, MFLG_SLOW,
+ {mg_ignore, mg_ignore, {ms_mlock, 3}, {ms_mlock, 3}, mg_ignore, mg_ignore}
+ };
struct Message bmask_msgtab = {
"BMASK", 0, 0, 0, MFLG_SLOW,
{mg_ignore, mg_ignore, mg_ignore, {ms_bmask, 5}, mg_ignore, mg_ignore}
};
- mapi_clist_av1 mode_clist[] = { &mode_msgtab, &tmode_msgtab, &bmask_msgtab, NULL };
+ mapi_clist_av1 mode_clist[] = { &mode_msgtab, &tmode_msgtab, &mlock_msgtab, &bmask_msgtab, NULL };
DECLARE_MODULE_AV1(mode, NULL, NULL, mode_clist, NULL, NULL, "$Revision: 1006 $");
return 0;
}
+ static int
+ ms_mlock(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+ {
+ struct Channel *chptr = NULL;
+
+ /* Now, try to find the channel in question */
+ if(!IsChanPrefix(parv[2][0]) || !check_channel_name(parv[2]))
+ {
+ sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), parv[2]);
+ return 0;
+ }
+
+ chptr = find_channel(parv[2]);
+
+ if(chptr == NULL)
+ {
+ sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+ form_str(ERR_NOSUCHCHANNEL), parv[2]);
+ return 0;
+ }
+
+ /* TS is higher, drop it. */
+ if(atol(parv[1]) > chptr->channelts)
+ return 0;
+
+ if(IsServer(source_p))
+ set_channel_mlock(client_p, source_p, chptr, parv[3], TRUE);
+
+ return 0;
+ }
+
static int
ms_bmask(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
case 'q':
banlist = &chptr->quietlist;
- mode_type = ModuleModes.CHFL_QUIET;
+ mode_type = CHFL_QUIET;
mems = ALL_MEMBERS;
break;
&ConfigFileEntry.default_floodcount,
"Startup value of FLOODCOUNT",
},
+ {
+ "hide_channel_below_users",
+ OUTPUT_DECIMAL,
+ &ConfigFileEntry.hide_channel_below_users,
+ "Hide channels below this many users in standard /LIST output",
+ },
{
"default_adminstring",
OUTPUT_STRING,
&ConfigChannel.host_in_topic,
"Defines whether a topicsetters host or just nick is shown on TOPIC",
},
+ {
+ "admin_on_channel_create",
+ OUTPUT_BOOLEAN_YN,
+ &ConfigChannel.admin_on_channel_create,
+ "Give users +ao on channel create",
+ },
{
"use_halfop",
OUTPUT_BOOLEAN_YN,
&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,
static int h_can_create_channel;
static int h_channel_join;
-struct module_modes ModuleModes;
-
/* init_channels()
*
* input -
h_can_create_channel = register_hook("can_create_channel");
}
-/* is this the best place to put this? */
-/* init_module_modes()
- *
- * input -
- * output -
- * side effects - various MODE_ values are set to 0
- */
-void
-init_module_modes()
-{
- ModuleModes.MODE_REGONLY = 0;
- ModuleModes.MODE_NOCTCP = 0;
- ModuleModes.MODE_NOCOLOR = 0;
- ModuleModes.MODE_EXLIMIT = 0;
- ModuleModes.MODE_PERMANENT = 0;
- ModuleModes.MODE_OPMODERATE = 0;
- ModuleModes.MODE_FREEINVITE = 0;
- ModuleModes.MODE_FREETARGET = 0;
- ModuleModes.MODE_DISFORWARD = 0;
- ModuleModes.MODE_THROTTLE = 0;
- ModuleModes.MODE_FORWARD = 0;
- ModuleModes.MODE_NONOTICE = 0;
- ModuleModes.MODE_NOACTION = 0;
- ModuleModes.MODE_NOKICK = 0;
- ModuleModes.MODE_NONICK = 0;
- ModuleModes.MODE_NOCAPS = 0;
- ModuleModes.MODE_NOREJOIN = 0;
- ModuleModes.MODE_NOREPEAT = 0;
- ModuleModes.MODE_NOOPERKICK = 0;
-
- ModuleModes.CHFL_QUIET = 0;
-}
-
-
/*
* allocate_channel - Allocates a channel
*/
{
channel_metadata_clear(chptr);
rb_free(chptr->chname);
+ rb_free(chptr->mode_lock);
rb_bh_free(channel_heap, chptr);
}
if(client_p->servptr == &me)
rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers);
- if(!(chptr->mode.mode & ModuleModes.MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
+ if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
destroy_channel(chptr);
rb_bh_free(member_heap, msptr);
if(client_p->servptr == &me)
rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers);
- if(!(chptr->mode.mode & ModuleModes.MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
+ if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0)
destroy_channel(chptr);
rb_bh_free(member_heap, msptr);
struct Ban *actualBan = NULL;
struct Ban *actualExcept = NULL;
- /* check to make sure quiets even exist on this server first */
- if(ModuleModes.CHFL_QUIET == 0)
- return 0;
-
if(!MyClient(who))
return 0;
if(match(actualBan->banstr, s) ||
match(actualBan->banstr, s2) ||
match_cidr(actualBan->banstr, s2) ||
- match_extban(actualBan->banstr, who, chptr, ModuleModes.CHFL_QUIET) ||
+ match_extban(actualBan->banstr, who, chptr, CHFL_QUIET) ||
(s3 != NULL && match(actualBan->banstr, s3)))
break;
else
if(chptr->mode.limit &&
rb_dlink_list_length(&chptr->members) >= (unsigned long) chptr->mode.limit)
i = ERR_CHANNELISFULL;
- if(chptr->mode.mode & ModuleModes.MODE_REGONLY && EmptyString(source_p->user->suser))
+ if(chptr->mode.mode & MODE_REGONLY && EmptyString(source_p->user->suser))
i = ERR_NEEDREGGEDNICK;
/* join throttling stuff --nenolod */
- /* only check for throttles if they exist on this server --Taros */
- else if(ModuleModes.MODE_THROTTLE)
+ else if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0)
{
- if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0)
- {
- if ((rb_current_time() - chptr->join_delta <=
- chptr->mode.join_time) && (chptr->join_count >=
- chptr->mode.join_num))
- i = ERR_THROTTLE;
- }
+ if ((rb_current_time() - chptr->join_delta <=
+ chptr->mode.join_time) && (chptr->join_count >=
+ chptr->mode.join_num))
+ i = ERR_THROTTLE;
}
/* allow /invite to override +l/+r/+j also -- jilles */
{
msptr = ptr->data;
chptr = msptr->chptr;
- if (chptr->mode.mode & ModuleModes.MODE_NONICK && (!ConfigChannel.exempt_cmode_N || !is_any_op(msptr)))
+ if (chptr->mode.mode & MODE_NONICK && (!ConfigChannel.exempt_cmode_N || !is_any_op(msptr)))
return chptr;
}
return NULL;
chptr->mode.join_time);
}
- if(*chptr->mode.forward && (ModuleModes.MODE_FORWARD || !IsClient(client_p)))
+ if(*chptr->mode.forward && (ConfigChannel.use_forward || !IsClient(client_p)))
{
*mbuf++ = 'f';
if (hash_find_resv(chptr->chname))
return NULL;
/* Don't forward to +Q channel */
- if (chptr->mode.mode & ModuleModes.MODE_DISFORWARD)
+ if (chptr->mode.mode & MODE_DISFORWARD)
return NULL;
i = can_join(source_p, chptr, key);
if (i == 0)
continue;
}
- flags = CHFL_CHANOP;
+ if(ConfigChannel.admin_on_channel_create && ConfigChannel.use_admin)
+ flags = CHFL_ADMIN | CHFL_CHANOP;
+ else
+ flags = CHFL_CHANOP;
}
if((rb_dlink_list_length(&source_p->user->channel) >=
me.name, get_oper_name(source_p), chptr->chname);
}
else if ((i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_INVITEONLYCHAN && i != ERR_CHANNELISFULL) ||
- (!ModuleModes.MODE_FORWARD || (chptr = check_forward(source_p, chptr, key)) == NULL))
+ (!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
#define SM_ERR_NOPRIVS 0x00000400
#define SM_ERR_RPL_Q 0x00000800
#define SM_ERR_RPL_F 0x00001000
+ #define SM_ERR_MLOCK 0x00002000
#define MAXMODES_SIMPLE 46 /* a-zA-Z except bqeIov */
int chmode_flags[256];
-struct module_modes ModuleModes;
-
/* OPTIMIZE ME! -- dwr */
void
construct_cflags_strings(void)
chmode_flags[i] = 0;
}
- if(chmode_flags[i] == ModuleModes.MODE_DISFORWARD)
+ switch (chmode_flags[i])
{
- if (ModuleModes.MODE_FORWARD)
+ case MODE_EXLIMIT:
+ case MODE_DISFORWARD:
+ if(ConfigChannel.use_forward)
{
- *ptr++ = (char) i;
+ *ptr++ = (char) i;
}
- }
- else if(chmode_flags[i] == ModuleModes.MODE_REGONLY)
- {
- if (rb_dlink_list_length(&service_list))
+
+ break;
+ case MODE_REGONLY:
+ if(rb_dlink_list_length(&service_list))
{
- *ptr++ = (char) i;
+ *ptr++ = (char) i;
+ }
+
+ break;
+ default:
+ if(chmode_flags[i] != 0)
+ {
+ *ptr++ = (char) i;
}
- }
- else if(chmode_flags[i] != ModuleModes.MODE_EXLIMIT && chmode_flags[i] != 0)
- {
- *ptr++ = (char) i;
}
/* Should we leave orphaned check here? -- dwr */
*/
if(MyClient(source_p))
{
- if((rb_dlink_list_length(&chptr->banlist) + rb_dlink_list_length(&chptr->exceptlist) + rb_dlink_list_length(&chptr->invexlist) + rb_dlink_list_length(&chptr->quietlist)) >= (chptr->mode.mode & ModuleModes.MODE_EXLIMIT ? ConfigChannel.max_bans_large : ConfigChannel.max_bans))
+ if((rb_dlink_list_length(&chptr->banlist) + rb_dlink_list_length(&chptr->exceptlist) + rb_dlink_list_length(&chptr->invexlist) + rb_dlink_list_length(&chptr->quietlist)) >= (chptr->mode.mode & MODE_EXLIMIT ? ConfigChannel.max_bans_large : ConfigChannel.max_bans))
{
sendto_one(source_p, form_str(ERR_BANLISTFULL),
me.name, source_p->name, chptr->chname, realban);
rb_dlinkAdd(actualBan, &actualBan->node, list);
/* invalidate the can_send() cache */
- if(mode_type == CHFL_BAN || mode_type == ModuleModes.CHFL_QUIET || mode_type == CHFL_EXCEPTION)
+ if(mode_type == CHFL_BAN || mode_type == CHFL_QUIET || mode_type == CHFL_EXCEPTION)
chptr->bants++;
return 1;
free_ban(banptr);
/* invalidate the can_send() cache */
- if(mode_type == CHFL_BAN || mode_type == ModuleModes.CHFL_QUIET || mode_type == CHFL_EXCEPTION)
+ if(mode_type == CHFL_BAN || mode_type == CHFL_QUIET || mode_type == CHFL_EXCEPTION)
chptr->bants++;
return 1;
if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type))
{
/* if +f is disabled, ignore an attempt to set +QF locally */
- if(!ModuleModes.MODE_FORWARD && MyClient(source_p) &&
+ if(!ConfigChannel.use_forward && MyClient(source_p) &&
(c == 'Q' || c == 'F'))
return;
int mems;
int override = 0;
- if(mode_type == CHFL_BAN)
+ switch (mode_type)
{
+ case CHFL_BAN:
list = &chptr->banlist;
errorval = SM_ERR_RPL_B;
rpl_list = RPL_BANLIST;
rpl_endlist = RPL_ENDOFBANLIST;
mems = ALL_MEMBERS;
caps = 0;
- }
- else if(mode_type == CHFL_EXCEPTION)
- {
+ break;
+
+ case CHFL_EXCEPTION:
/* if +e is disabled, allow all but +e locally */
if(!ConfigChannel.use_except && MyClient(source_p) &&
((dir == MODE_ADD) && (parc > *parn)))
mems = ONLY_CHANOPS;
else
mems = ONLY_SERVERS;
- }
- else if(mode_type == CHFL_INVEX)
- {
+ break;
+
+ case CHFL_INVEX:
/* if +I is disabled, allow all but +I locally */
if(!ConfigChannel.use_invex && MyClient(source_p) &&
(dir == MODE_ADD) && (parc > *parn))
mems = ONLY_CHANOPS;
else
mems = ONLY_SERVERS;
- }
- else if(mode_type == ModuleModes.CHFL_QUIET)
- {
+ break;
+
+ case CHFL_QUIET:
list = &chptr->quietlist;
errorval = SM_ERR_RPL_Q;
rpl_list = RPL_QUIETLIST;
rpl_endlist = RPL_ENDOFQUIETLIST;
mems = ALL_MEMBERS;
caps = 0;
- }
- else
- {
+ break;
+
+ default:
sendto_realops_snomask(SNO_GENERAL, L_ALL, "chm_ban() called with unknown type!");
return;
+ break;
}
if(dir == 0 || parc <= *parn)
/* non-ops cant see +eI lists.. */
if(alevel != CHFL_CHANOP && alevel != CHFL_ADMIN && alevel != CHFL_HALFOP && mode_type != CHFL_BAN &&
- mode_type != ModuleModes.CHFL_QUIET)
+ mode_type != CHFL_QUIET)
{
if(IsOverride(source_p))
{
int override = 0;
/* if +f is disabled, ignore local attempts to set it */
- if(!ModuleModes.MODE_FORWARD && MyClient(source_p) &&
+ if(!ConfigChannel.use_forward && MyClient(source_p) &&
(dir == MODE_ADD) && (parc > *parn))
return;
form_str(ERR_NOSUCHCHANNEL), forward);
return;
}
- if(MyClient(source_p) && !(targptr->mode.mode & ModuleModes.MODE_FREETARGET))
+ if(MyClient(source_p) && !(targptr->mode.mode & MODE_FREETARGET))
{
if((msptr = find_channel_membership(targptr, source_p)) == NULL ||
- !is_any_op(msptr))
+ is_any_op(msptr))
{
if(IsOverride(source_p))
override = 1;
mode_changes[mode_count].dir = MODE_ADD;
mode_changes[mode_count].caps = 0;
mode_changes[mode_count].nocaps = 0;
- mode_changes[mode_count].mems = ModuleModes.MODE_FORWARD ? ALL_MEMBERS : ONLY_SERVERS;
+ mode_changes[mode_count].mems = ConfigChannel.use_forward ? ALL_MEMBERS : ONLY_SERVERS;
mode_changes[mode_count].id = NULL;
mode_changes[mode_count].override = override;
mode_changes[mode_count++].arg = forward;
}
/* *INDENT-OFF* */
-/* Only RFC and ircd-ratbox modes are held in this table
- * All other modes are added via loading modules in shadowircd/modes
- * Such is documented in the comments for each mode, ex: C - NOCTCP. */
struct ChannelMode chmode_table[256] =
{
{chm_nosuch, 0 }, /* 0x00 */
{chm_nosuch, 0 }, /* @ */
{chm_nosuch, 0 }, /* A */
{chm_nosuch, 0 }, /* B */
- {chm_nosuch, 0 }, /* C - MODE_NOCTCP */
- {chm_nosuch, 0 }, /* D - MODE_NOACTION */
- {chm_nosuch, 0 }, /* E - MODE_NOKICK */
- {chm_nosuch, 0 }, /* F - MODE_FREETARGET */
- {chm_nosuch, 0 }, /* G - MODE_NOCAPS */
+ {chm_simple, MODE_NOCTCP }, /* C */
+ {chm_simple, MODE_NOACTION }, /* D */
+ {chm_simple, MODE_NOKICK }, /* E */
+ {chm_simple, MODE_FREETARGET }, /* F */
+ {chm_simple, MODE_NOCAPS }, /* G */
{chm_nosuch, 0 }, /* H */
{chm_ban, CHFL_INVEX }, /* I */
- {chm_nosuch, 0 }, /* J - MODE_NOREJOIN */
- {chm_nosuch, 0 }, /* K - MODE_NOREPEAT */
- {chm_nosuch, 0 }, /* L - MODE_EXLIMIT */
- {chm_nosuch, 0 }, /* M - MODE_NOOPERKICK */
- {chm_nosuch, 0 }, /* N - MODE_NONICK */
+ {chm_simple, MODE_NOREJOIN }, /* J */
+ {chm_simple, MODE_NOREPEAT }, /* K */
+ {chm_staff, MODE_EXLIMIT }, /* L */
+ {chm_hidden, MODE_NOOPERKICK }, /* M */
+ {chm_simple, MODE_NONICK }, /* N */
{chm_nosuch, 0 }, /* O */
- {chm_nosuch, 0 }, /* P - MODE_PERMANENT */
- {chm_nosuch, 0 }, /* Q - MODE_DISFORWARD */
+ {chm_staff, MODE_PERMANENT }, /* P */
+ {chm_simple, MODE_DISFORWARD }, /* Q */
{chm_nosuch, 0 }, /* R */
{chm_nosuch, 0 }, /* S */
- {chm_nosuch, 0 }, /* T - MODE_NONOTICE */
+ {chm_simple, MODE_NONOTICE }, /* T */
{chm_nosuch, 0 }, /* U */
{chm_nosuch, 0 }, /* V */
{chm_nosuch, 0 }, /* W */
{chm_nosuch, 0 },
{chm_admin, 0 }, /* a */
{chm_ban, CHFL_BAN }, /* b */
- {chm_nosuch, 0 }, /* c - MODE_NOCOLOR */
+ {chm_simple, MODE_NOCOLOR }, /* c */
{chm_nosuch, 0 }, /* d */
{chm_ban, CHFL_EXCEPTION }, /* e */
- {chm_nosuch, 0 }, /* f - MODE_FORWARD */
- {chm_nosuch, 0 }, /* g - MODE_FREEINVITE */
+ {chm_forward, 0 }, /* f */
+ {chm_simple, MODE_FREEINVITE }, /* g */
{chm_halfop, 0 }, /* h */
{chm_simple, MODE_INVITEONLY }, /* i */
- {chm_nosuch, 0 }, /* j - MODE_THROTTLE */
+ {chm_throttle, 0 }, /* j */
{chm_key, 0 }, /* k */
{chm_limit, 0 }, /* l */
{chm_simple, MODE_MODERATED }, /* m */
{chm_simple, MODE_NOPRIVMSGS }, /* n */
{chm_op, 0 }, /* o */
{chm_simple, MODE_PRIVATE }, /* p */
- {chm_nosuch, 0 }, /* q - CHFL_QUIET */
- {chm_nosuch, 0 }, /* r - MODE_REGONLY */
+ {chm_ban, CHFL_QUIET }, /* q */
+ {chm_regonly, MODE_REGONLY }, /* r */
{chm_simple, MODE_SECRET }, /* s */
{chm_simple, MODE_TOPICLIMIT }, /* t */
{chm_nosuch, 0 }, /* u */
{chm_nosuch, 0 }, /* w */
{chm_nosuch, 0 }, /* x */
{chm_nosuch, 0 }, /* y */
- {chm_nosuch, 0 }, /* z - MODE_OPMODERATE */
+ {chm_simple, MODE_OPMODERATE }, /* z */
{chm_nosuch, 0 }, /* 0x7b */
{chm_nosuch, 0 }, /* 0x7c */
dir = MODE_QUERY;
break;
default:
+ /* If this mode char is locked, don't allow local users to change it. */
+ if (MyClient(source_p) && chptr->mode_lock && strchr(chptr->mode_lock, c))
+ {
+ if (!(errors & SM_ERR_MLOCK))
+ sendto_one_numeric(source_p,
+ ERR_MLOCKRESTRICTED,
+ form_str(ERR_MLOCKRESTRICTED),
+ chptr->chname,
+ c,
+ chptr->mode_lock);
+ errors |= SM_ERR_MLOCK;
+ continue;
+ }
chmode_table[(unsigned char) c].set_func(fakesource_p, chptr, alevel,
parc, &parn, parv,
&errors, dir, c,
if(MyClient(source_p) || rb_dlink_list_length(&serv_list) > 1)
send_cap_mode_changes(client_p, source_p, chptr, mode_changes, mode_count);
}
+
+ /* set_channel_mlock()
+ *
+ * inputs - client, source, channel, params
+ * output -
+ * side effects - channel mlock is changed / MLOCK is propagated
+ */
+ void
+ set_channel_mlock(struct Client *client_p, struct Client *source_p,
+ struct Channel *chptr, const char *newmlock, int propagate)
+ {
+ rb_free(chptr->mode_lock);
+ chptr->mode_lock = newmlock ? rb_strdup(newmlock) : NULL;
+
+ if (propagate)
+ {
+ sendto_server(client_p, NULL, CAP_TS6 | CAP_MLOCK, NOCAPS, ":%s MLOCK %ld %s :%s",
+ source_p->id, (long) chptr->channelts, chptr->chname,
+ chptr->mode_lock ? chptr->mode_lock : "");
+ }
+ }
{ "anti_spam_exit_message_time", CF_TIME, NULL, 0, &ConfigFileEntry.anti_spam_exit_message_time },
{ "use_part_messages", CF_YESNO, NULL, 0, &ConfigFileEntry.use_part_messages },
{ "disable_fake_channels", CF_YESNO, NULL, 0, &ConfigFileEntry.disable_fake_channels },
+ { "hide_channel_below_users", CF_INT, NULL, 0, &ConfigFileEntry.hide_channel_below_users },
{ "min_nonwildcard_simple", CF_INT, NULL, 0, &ConfigFileEntry.min_nonwildcard_simple },
{ "non_redundant_klines", CF_YESNO, NULL, 0, &ConfigFileEntry.non_redundant_klines },
{ "tkline_expire_notices", CF_YESNO, NULL, 0, &ConfigFileEntry.tkline_expire_notices },
{ "only_ascii_channels", CF_YESNO, NULL, 0, &ConfigChannel.only_ascii_channels },
{ "cycle_host_change", CF_YESNO, NULL, 0, &ConfigChannel.cycle_host_change },
{ "host_in_topic", CF_YESNO, NULL, 0, &ConfigChannel.host_in_topic },
+ { "admin_on_channel_create", CF_YESNO, NULL, 0, &ConfigChannel.admin_on_channel_create },
{ "use_halfop", CF_YESNO, NULL, 0, &ConfigChannel.use_halfop },
{ "use_admin", CF_YESNO, NULL, 0, &ConfigChannel.use_admin },
{ "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 },
{ "use_local_channels", CF_YESNO, NULL, 0, &ConfigChannel.use_local_channels },
{ "resv_forcepart", CF_YESNO, NULL, 0, &ConfigChannel.resv_forcepart },
+ { "channel_target_change", CF_YESNO, NULL, 0, &ConfigChannel.channel_target_change },
{ "exempt_cmode_c", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_c },
{ "exempt_cmode_C", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_C },
{ "exempt_cmode_D", CF_YESNO, NULL, 0, &ConfigChannel.exempt_cmode_D },
ConfigFileEntry.failed_oper_notice = YES;
ConfigFileEntry.anti_nick_flood = NO;
ConfigFileEntry.disable_fake_channels = NO;
+ ConfigFileEntry.hide_channel_below_users = 3;
ConfigFileEntry.max_nick_time = 20;
ConfigFileEntry.max_nick_changes = 5;
ConfigFileEntry.max_accept = 20;
ConfigChannel.autochanmodes = rb_strdup("nt");
ConfigChannel.exemptchanops = rb_strdup("");
+ ConfigChannel.admin_on_channel_create = NO;
ConfigChannel.use_halfop = YES;
ConfigChannel.use_admin = YES;
ConfigChannel.use_except = YES;
ConfigChannel.use_invex = YES;
ConfigChannel.use_knock = YES;
+ ConfigChannel.use_forward = YES;
ConfigChannel.use_local_channels = YES;
ConfigChannel.knock_delay = 300;
ConfigChannel.knock_delay_channel = 60;
ConfigChannel.no_join_on_split = NO;
ConfigChannel.no_create_on_split = YES;
ConfigChannel.resv_forcepart = YES;
+ ConfigChannel.channel_target_change = YES;
ConfigChannel.exempt_cmode_c = NO;
ConfigChannel.exempt_cmode_C = NO;
#include "substitution.h"
#include "chmode.h"
-struct module_modes ModuleModes;
-
static void report_and_set_user_flags(struct Client *, struct ConfItem *);
void user_welcome(struct Client *source_p);
source_p->preClient->dnsbl_listed->hits++;
sendto_realops_snomask(SNO_REJ, L_ALL,
- "%s [%s] is being disconnected due to being listed in DNS Blacklist %s",
- source_p->name, source_p->sockhost, source_p->preClient->dnsbl_listed->host);
+ "%s (%s@%s) is being disconnected due to being listed in DNS Blacklist %s",
+ source_p->name, source_p->username, source_p->sockhost, source_p->preClient->dnsbl_listed->host);
add_reject(source_p, NULL, NULL);
exit_client(client_p, source_p, &me, "*** Banned (DNS blacklist)");
expire_umode_p(void *data)
{
struct Client *source_p = data;
- char *parv[4] = {source_p->name, source_p->name, "-p", NULL};
+ const char *parv[4] = {source_p->name, source_p->name, "-p", NULL};
source_p->localClient->override_timeout_event = NULL;
user_mode(source_p, source_p, 3, parv);
}
}
/* FALLTHROUGH */
default:
- if (MyConnect(source_p) && *pm == 'Q' && !ModuleModes.MODE_FORWARD) {
+ if (MyConnect(source_p) && *pm == 'Q' && !ConfigChannel.use_forward) {
badflag = YES;
break;
}