#define KEY_EXPIRES "expires"
#define KEY_TRIGGERED "triggered"
-#define CHANNEL_DEFAULT_FLAGS (0)
+#define CHANNEL_DEFAULT_FLAGS (CHANNEL_OFFCHANNEL)
#define CHANNEL_DEFAULT_OPTIONS "lmoooanpcnat"
/* Administrative messages */
{ "CSMSG_SET_MODES", "$bModes $b %s" },
{ "CSMSG_SET_NODELETE", "$bNoDelete $b %s" },
{ "CSMSG_SET_DYNLIMIT", "$bDynLimit $b %s" },
+ { "CSMSG_SET_OFFCHANNEL", "$bOffChannel $b %s" },
{ "CSMSG_SET_USERINFO", "$bUserInfo $b %d" },
{ "CSMSG_SET_GIVE_VOICE", "$bGiveVoice $b %d" },
{ "CSMSG_SET_TOPICSNARF", "$bTopicSnarf $b %d" },
struct userNode *chanserv;
dict_t note_types;
+int off_channel;
static dict_t plain_dnrs, mask_dnrs, handle_dnrs;
static struct log_type *CS_LOG;
static void
unregister_channel(struct chanData *channel, const char *reason)
{
+ struct mod_chanmode change;
char msgbuf[MAXLEN];
/* After channel unregistration, the following must be cleaned
timeq_del(0, NULL, channel, TIMEQ_IGNORE_FUNC | TIMEQ_IGNORE_WHEN);
+ mod_chanmode_init(&change);
+ change.modes_clear |= MODE_REGISTERED;
+ mod_chanmode_announce(chanserv, channel->channel, &change);
+
while(channel->users)
del_channel_user(channel->users, 0);
while(channel->bans)
del_channel_ban(channel->bans);
- if(channel->topic) free(channel->topic);
- if(channel->registrar) free(channel->registrar);
- if(channel->greeting) free(channel->greeting);
- if(channel->user_greeting) free(channel->user_greeting);
- if(channel->topic_mask) free(channel->topic_mask);
+ free(channel->topic);
+ free(channel->registrar);
+ free(channel->greeting);
+ free(channel->user_greeting);
+ free(channel->topic_mask);
- if(channel->prev) channel->prev->next = channel->next;
- else channelList = channel->next;
+ if(channel->prev)
+ channel->prev->next = channel->next;
+ else
+ channelList = channel->next;
- if(channel->next) channel->next->prev = channel->prev;
+ if(channel->next)
+ channel->next->prev = channel->prev;
if(channel->suspended)
{
}
channel->channel->channel_info = NULL;
- if(channel->notes)
- dict_delete(channel->notes);
+ dict_delete(channel->notes);
sprintf(msgbuf, "%s %s", channel->channel->name, reason);
if(!IsSuspended(channel))
DelChannelUser(chanserv, channel->channel, msgbuf, 0);
CHANNEL_BINARY_OPTION("CSMSG_SET_DYNLIMIT", CHANNEL_DYNAMIC_LIMIT);
}
+static MODCMD_FUNC(chan_opt_offchannel)
+{
+ struct chanData *cData = channel->channel_info;
+ int value;
+
+ if(argc > 1)
+ {
+ /* Set flag according to value. */
+ if(enabled_string(argv[1]))
+ {
+ if(!IsOffChannel(cData))
+ DelChannelUser(chanserv, channel, "Going off-channel.", 0);
+ cData->flags |= CHANNEL_OFFCHANNEL;
+ value = 1;
+ }
+ else if(disabled_string(argv[1]))
+ {
+ if(IsOffChannel(cData))
+ {
+ struct mod_chanmode change;
+ mod_chanmode_init(&change);
+ change.argc = 1;
+ change.args[0].mode = MODE_CHANOP;
+ change.args[0].member = AddChannelUser(chanserv, channel);
+ mod_chanmode_announce(chanserv, channel, &change);
+ }
+ cData->flags &= ~CHANNEL_OFFCHANNEL;
+ value = 0;
+ }
+ else
+ {
+ reply("MSG_INVALID_BINARY", argv[1]);
+ return 0;
+ }
+ }
+ else
+ {
+ /* Find current option value. */
+ value = (cData->flags & CHANNEL_OFFCHANNEL) ? 1 : 0;
+ }
+
+ if(value)
+ reply("CSMSG_SET_OFFCHANNEL", user_find_message(user, "MSG_ON"));
+ else
+ reply("CSMSG_SET_OFFCHANNEL", user_find_message(user, "MSG_OFF"));
+ return 1;
+}
+
static MODCMD_FUNC(chan_opt_defaults)
{
struct userData *uData;
&& IsUserAutoInvite(channel)
&& (channel->access >= channel->channel->lvlOpts[lvlInviteMe])
&& !self->burst
- && !user->uplink->burst)
+ && !user->uplink->burst)
irc_invite(chanserv, user, cn);
continue;
}
}
static void
-handle_part(struct userNode *user, struct chanNode *channel, UNUSED_ARG(const char *reason))
+handle_part(struct modeNode *mn, UNUSED_ARG(const char *reason))
{
struct chanData *cData;
struct userData *uData;
- cData = channel->channel_info;
- if(!cData || IsSuspended(cData) || IsLocal(user))
+ cData = mn->channel->channel_info;
+ if(!cData || IsSuspended(cData) || IsLocal(mn->user))
return;
- if((cData->flags & CHANNEL_DYNAMIC_LIMIT) && !channel->join_flooded)
+ if((cData->flags & CHANNEL_DYNAMIC_LIMIT) && !mn->channel->join_flooded)
{
/* Allow for a bit of padding so that the limit doesn't
track the user count exactly, which could get annoying. */
- if((channel->limit - channel->members.used) > chanserv_conf.adjust_threshold + 5)
+ if((mn->channel->limit - mn->channel->members.used) > chanserv_conf.adjust_threshold + 5)
{
timeq_del(0, chanserv_adjust_limit, cData, TIMEQ_IGNORE_WHEN);
timeq_add(now + chanserv_conf.adjust_delay, chanserv_adjust_limit, cData);
}
}
- if((uData = GetTrueChannelAccess(cData, user->handle_info)))
+ if((uData = GetTrueChannelAccess(cData, mn->user->handle_info)))
{
- scan_user_presence(uData, user);
+ scan_user_presence(uData, mn->user);
uData->seen = now;
}
- if(IsHelping(user) && IsSupportHelper(user))
+ if(IsHelping(mn->user) && IsSupportHelper(mn->user))
{
unsigned int ii, jj;
for(ii = 0; ii < chanserv_conf.support_channels.used; ++ii)
{
- for(jj = 0; jj < user->channels.used; ++jj)
- if(user->channels.list[jj]->channel == chanserv_conf.support_channels.list[ii])
+ for(jj = 0; jj < mn->user->channels.used; ++jj)
+ if(mn->user->channels.list[jj]->channel == chanserv_conf.support_channels.list[ii])
break;
- if(jj < user->channels.used)
+ if(jj < mn->user->channels.used)
break;
}
if(ii == chanserv_conf.support_channels.used)
- HANDLE_CLEAR_FLAG(user->handle_info, HELPING);
+ HANDLE_CLEAR_FLAG(mn->user->handle_info, HELPING);
}
}
else
strlist = alloc_string_list(2);
chanserv_conf.old_ban_names = strlist;
+ /* the variable itself is actually declared in proto-common.c; this is equally
+ * parse issue. */
+ str = database_get_data(conf_node, "off_channel", RECDB_QSTRING);
+ off_channel = (str && enabled_string(str)) ? 1 : 0;
}
static void
/* We could use suspended->expires and suspended->revoked to
* set the CHANNEL_SUSPENDED flag, but we don't. */
}
- else if(cData->flags & CHANNEL_SUSPENDED)
+ else if(IsSuspended(cData))
{
suspended = calloc(1, sizeof(*suspended));
suspended->issued = 0;
suspended->cData = cData;
}
else
- suspended = NULL;
+ suspended = NULL; /* to squelch a warning */
- if((cData->flags & CHANNEL_SUSPENDED)
- && suspended->expires
- && (suspended->expires <= now))
- {
- cData->flags &= ~CHANNEL_SUSPENDED;
+ if(IsSuspended(cData)) {
+ if(suspended->expires > now)
+ timeq_add(suspended->expires, chanserv_expire_suspension, suspended);
+ else if(suspended->expires)
+ cData->flags &= ~CHANNEL_SUSPENDED;
}
- if(!(cData->flags & CHANNEL_SUSPENDED))
- {
+ if((!off_channel || !IsOffChannel(cData)) && !IsSuspended(cData)) {
struct mod_chanmode change;
mod_chanmode_init(&change);
change.argc = 1;
change.args[0].member = AddChannelUser(chanserv, cNode);
mod_chanmode_announce(chanserv, cNode, &change);
}
- else if(suspended->expires > now)
- {
- timeq_add(suspended->expires, chanserv_expire_suspension, suspended);
- }
str = database_get_data(channel, KEY_REGISTERED, RECDB_QSTRING);
cData->registered = str ? (time_t)strtoul(str, NULL, 0) : now;
str = database_get_data(channel, KEY_TOPIC, RECDB_QSTRING);
cData->topic = str ? strdup(str) : NULL;
- if((str = database_get_data(channel, KEY_MODES, RECDB_QSTRING))
+ if(!IsSuspended(cData)
+ && (str = database_get_data(channel, KEY_MODES, RECDB_QSTRING))
&& (argc = split_line(str, 0, ArrayLength(argv), argv))
&& (modes = mod_chanmode_parse(cNode, argv, argc, MCP_KEY_FREE))) {
cData->modes = *modes;
+ cData->modes.modes_set |= MODE_REGISTERED;
if(cData->modes.argc > 1)
cData->modes.argc = 1;
- if(!IsSuspended(cData))
- mod_chanmode_announce(chanserv, cNode, &cData->modes);
+ mod_chanmode_announce(chanserv, cNode, &cData->modes);
mod_chanmode_free(modes);
}
DEFINE_CHANNEL_OPTION(ctcpusers);
DEFINE_CHANNEL_OPTION(ctcpreaction);
DEFINE_CHANNEL_OPTION(inviteme);
+ if(off_channel)
+ DEFINE_CHANNEL_OPTION(offchannel);
modcmd_register(chanserv_module, "set defaults", chan_opt_defaults, 1, 0, "access", "owner", NULL);
/* Alias set topic to set defaulttopic for compatibility. */