static CHANSERV_FUNC(cmd_register)
{
- struct mod_chanmode *change;
struct handle_info *handle;
struct chanData *cData;
struct modeNode *mn;
return 0;
}
- if(!IsHelping(user) && (!(mn = GetUserMode(channel, user)) || !(mn->modes & MODE_CHANOP)))
+ if(!IsHelping(user)
+ && (!(mn = GetUserMode(channel, user)) || !(mn->modes & MODE_CHANOP)))
{
reply("CSMSG_MUST_BE_OPPED", channel->name);
return 0;
scan_user_presence(add_channel_user(cData, handle, UL_OWNER, 0, NULL), NULL);
cData->modes = chanserv_conf.default_modes;
if(off_channel > 0)
- cData->modes.modes_set |= MODE_REGISTERED;
- change = mod_chanmode_dup(&cData->modes, 1);
- change->args[change->argc].mode = MODE_CHANOP;
- change->args[change->argc].u.member = AddChannelUser(chanserv, channel);
- change->argc++;
- mod_chanmode_announce(chanserv, channel, change);
- mod_chanmode_free(change);
+ cData->modes.modes_set |= MODE_REGISTERED;
+ if (IsOffChannel(cData))
+ {
+ mod_chanmode_announce(chanserv, channel, &cData->modes);
+ }
+ else
+ {
+ struct mod_chanmode *change = mod_chanmode_dup(&cData->modes, 1);
+ change->args[change->argc].mode = MODE_CHANOP;
+ change->args[change->argc].u.member = AddChannelUser(chanserv, channel);
+ change->argc++;
+ mod_chanmode_announce(chanserv, channel, change);
+ mod_chanmode_free(change);
+ }
/* Initialize the channel's max user record. */
cData->max = channel->members.used;
static void
merge_data(struct chanData *source, struct chanData *target)
{
+ /* Use more recent visited and owner-transfer time; use older
+ * registered time. Bitwise or may_opchan. Use higher max.
+ * Do not touch last_refresh, ban count or user counts.
+ */
if(source->visited > target->visited)
target->visited = source->visited;
+ if(source->registered < target->registered)
+ target->registered = source->registered;
+ if(source->ownerTransfer > target->ownerTransfer)
+ target->ownerTransfer = source->ownerTransfer;
+ if(source->may_opchan)
+ target->may_opchan = 1;
+ if(source->max > target->max)
+ target->max = source->max;
}
static void
}
static int
-bad_channel_ban(struct chanNode *channel, struct userNode *user, const char *ban, int *victimCount, struct modeNode **victims)
+bad_channel_ban(struct chanNode *channel, struct userNode *user, const char *ban, unsigned int *victimCount, struct modeNode **victims)
{
unsigned int ii;
if(IsService(mn->user))
continue;
- if(!user_matches_glob(mn->user, ban, 1))
+ if(!user_matches_glob(mn->user, ban, MATCH_USENICK | MATCH_VISIBLE))
continue;
if(protect_user(mn->user, user, channel->channel_info))
{
for(ii = count = 0; ii < bans->used; ++ii)
{
- match[ii] = user_matches_glob(actee, bans->list[ii]->ban, 1);
+ match[ii] = user_matches_glob(actee, bans->list[ii]->ban,
+ MATCH_USENICK | MATCH_VISIBLE);
if(match[ii])
count++;
}
while(ban)
{
if(actee)
- for( ; ban && !user_matches_glob(actee, ban->mask, 1);
+ for( ; ban && !user_matches_glob(actee, ban->mask,
+ MATCH_USENICK | MATCH_VISIBLE);
ban = ban->next);
else
for( ; ban && !match_ircglobs(mask, ban->mask);
static CHANSERV_FUNC(cmd_mode)
{
+ struct userData *uData;
struct mod_chanmode *change;
-
+ short base_oplevel;
+
if(argc < 2)
{
change = &channel->channel_info->modes;
return 1;
}
- change = mod_chanmode_parse(channel, argv+1, argc-1, MCP_KEY_FREE|MCP_REGISTERED);
+ uData = GetChannelUser(channel->channel_info, user->handle_info);
+ if (!uData)
+ base_oplevel = MAXOPLEVEL;
+ else if (uData->access >= UL_OWNER)
+ base_oplevel = 1;
+ else
+ base_oplevel = 1 + UL_OWNER - uData->access;
+ change = mod_chanmode_parse(channel, argv+1, argc-1, MCP_KEY_FREE|MCP_REGISTERED, base_oplevel);
if(!change)
{
reply("MSG_INVALID_MODES", unsplit_string(argv+1, argc-1, NULL));
reply("CSMSG_CHANNEL_USERS", cData->userCount);
reply("CSMSG_CHANNEL_BANS", cData->banCount);
reply("CSMSG_CHANNEL_VISITED", intervalString(buffer, now - cData->visited, user->handle_info));
- reply("CSMSG_CHANNEL_REGISTERED", intervalString(buffer, now - cData->registered, user->handle_info));
privileged = IsStaff(user);
+ if(privileged)
+ reply("CSMSG_CHANNEL_REGISTERED", intervalString(buffer, now - cData->registered, user->handle_info));
if(((uData && uData->access >= UL_COOWNER) || privileged) && cData->registrar)
reply("CSMSG_CHANNEL_REGISTRAR", cData->registrar);
{
struct suspended *suspended = data;
struct chanNode *channel;
- struct mod_chanmode change;
if(!suspended->expires || (now < suspended->expires))
suspended->revoked = now;
channel = suspended->cData->channel;
suspended->cData->channel = channel;
suspended->cData->flags &= ~CHANNEL_SUSPENDED;
- mod_chanmode_init(&change);
- change.argc = 1;
- change.args[0].mode = MODE_CHANOP;
- change.args[0].u.member = AddChannelUser(chanserv, channel);
- mod_chanmode_announce(chanserv, channel, &change);
+ if(!IsOffChannel(suspended->cData))
+ {
+ struct mod_chanmode change;
+ mod_chanmode_init(&change);
+ change.argc = 1;
+ change.args[0].mode = MODE_CHANOP;
+ change.args[0].u.member = AddChannelUser(chanserv, channel);
+ mod_chanmode_announce(chanserv, channel, &change);
+ }
}
static CHANSERV_FUNC(cmd_csuspend)
{
memset(&channel->channel_info->modes, 0, sizeof(channel->channel_info->modes));
}
- else if(!(new_modes = mod_chanmode_parse(channel, argv+1, argc-1, MCP_KEY_FREE|MCP_REGISTERED)))
+ else if(!(new_modes = mod_chanmode_parse(channel, argv+1, argc-1, MCP_KEY_FREE|MCP_REGISTERED, 0)))
{
reply("CSMSG_INVALID_MODE_LOCK", unsplit_string(argv+1, argc-1, NULL));
return 0;
new_owner = GetChannelAccess(cData, new_owner_hi);
if(!new_owner)
{
- reply("CSMSG_NO_CHAN_USER", new_owner_hi->handle, channel->name);
- return 0;
+ if(force)
+ {
+ new_owner = add_channel_user(cData, new_owner_hi, UL_COOWNER, 0, NULL);
+ }
+ else
+ {
+ reply("CSMSG_NO_CHAN_USER", new_owner_hi->handle, channel->name);
+ return 0;
+ }
}
if((chanserv_get_owned_count(new_owner_hi) >= chanserv_conf.max_owned) && !force)
{
unsigned int ii;
for(ii = 0; ii < channel->banlist.used; ii++)
{
- if(user_matches_glob(user, channel->banlist.list[ii]->ban, 1))
+ if(user_matches_glob(user, channel->banlist.list[ii]->ban, MATCH_USENICK | MATCH_VISIBLE))
{
/* Riding a netburst. Naughty. */
KickChannelUser(user, channel, chanserv, "User from far side of netsplit should have been banned - bye.");
{
/* Not joining through a ban. */
for(bData = cData->bans;
- bData && !user_matches_glob(user, bData->mask, 1);
- bData = bData->next);
+ bData && !user_matches_glob(user, bData->mask, MATCH_USENICK | MATCH_VISIBLE);
+ bData = bData->next);
if(bData)
{
|| IsSuspended(channel->channel_info))
continue;
for(jj = 0; jj < channel->banlist.used; ++jj)
- if(user_matches_glob(user, channel->banlist.list[jj]->ban, 1))
+ if(user_matches_glob(user, channel->banlist.list[jj]->ban, MATCH_USENICK | MATCH_VISIBLE))
break;
if(jj < channel->banlist.used)
continue;
for(ban = channel->channel_info->bans; ban; ban = ban->next)
{
char kick_reason[MAXLEN];
- if(!user_matches_glob(user, ban->mask, 1))
+ if(!user_matches_glob(user, ban->mask, MATCH_USENICK | MATCH_VISIBLE))
continue;
change.args[0].mode = MODE_BAN;
change.args[0].u.hostmask = ban->mask;
continue;
/* Look for a matching ban already on the channel. */
for(jj = 0; jj < channel->banlist.used; ++jj)
- if(user_matches_glob(user, channel->banlist.list[jj]->ban, 1))
+ if(user_matches_glob(user, channel->banlist.list[jj]->ban, MATCH_USENICK | MATCH_VISIBLE))
break;
/* Need not act if we found one. */
if(jj < channel->banlist.used)
/* Look for a matching ban in this channel. */
for(bData = channel->channel_info->bans; bData; bData = bData->next)
{
- if(!user_matches_glob(user, bData->mask, 1))
+ if(!user_matches_glob(user, bData->mask, MATCH_USENICK | MATCH_VISIBLE))
continue;
change.args[0].u.hostmask = bData->mask;
mod_chanmode_announce(chanserv, channel, &change);
str = "+nt";
safestrncpy(mode_line, str, sizeof(mode_line));
ii = split_line(mode_line, 0, ArrayLength(modes), modes);
- if((change = mod_chanmode_parse(NULL, modes, ii, MCP_KEY_FREE)) && (change->argc < 2))
+ if((change = mod_chanmode_parse(NULL, modes, ii, MCP_KEY_FREE, 0))
+ && (change->argc < 2))
{
chanserv_conf.default_modes = *change;
mod_chanmode_free(change);
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 ? atoi(str) : 0;
}
s_expires = database_get_data(rd->d.object, KEY_EXPIRES, RECDB_QSTRING);
owner = database_get_data(rd->d.object, KEY_OWNER, RECDB_QSTRING);
reason = database_get_data(rd->d.object, KEY_REASON, RECDB_QSTRING);
+ if (!reason || !owner)
+ return;
set_time = set ? (time_t)strtoul(set, NULL, 0) : now;
triggered_time = triggered ? (time_t)strtoul(triggered, NULL, 0) : 0;
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))) {
+ && (modes = mod_chanmode_parse(cNode, argv, argc, MCP_KEY_FREE, 0))) {
cData->modes = *modes;
if(off_channel > 0)
cData->modes.modes_set |= MODE_REGISTERED;