src/chanserv.c (cmd_mode): Use MCP_NO_APASS, and unparse the mode
change for display.
(chan_opt_usergreeting): Use MCP_NO_APASS here too.
(chanserv_conf_read): Likewise.
(chanserv_channel_read): Likewise.
src/opserv.c (cmd_kick): Do not let users try to kick services.
src/proto.h (MCP_NO_APASS): New flag.
src/proto-p10.c (irc_user_mode_chars): Allow displaying +x.
(mod_usermode): Treat +h as setting +x also.
(mod_chanmode_parse): Reject +A and +U when passed MCP_NO_APASS.
struct userData *uData;
struct mod_chanmode *change;
short base_oplevel;
struct userData *uData;
struct mod_chanmode *change;
short base_oplevel;
base_oplevel = 1;
else
base_oplevel = 1 + UL_OWNER - uData->access;
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);
+ change = mod_chanmode_parse(channel, argv+1, argc-1, MCP_KEY_FREE|MCP_REGISTERED|MCP_NO_APASS, base_oplevel);
if(!change)
{
reply("MSG_INVALID_MODES", unsplit_string(argv+1, argc-1, NULL));
if(!change)
{
reply("MSG_INVALID_MODES", unsplit_string(argv+1, argc-1, NULL));
}
modcmd_chanmode_announce(change);
}
modcmd_chanmode_announce(change);
+ mod_chanmode_format(change, fmt);
mod_chanmode_free(change);
mod_chanmode_free(change);
- reply("CSMSG_MODES_SET", unsplit_string(argv+1, argc-1, NULL));
+ reply("CSMSG_MODES_SET", fmt);
static MODCMD_FUNC(chan_opt_modes)
{
struct mod_chanmode *new_modes;
static MODCMD_FUNC(chan_opt_modes)
{
struct mod_chanmode *new_modes;
{
memset(&channel->channel_info->modes, 0, sizeof(channel->channel_info->modes));
}
{
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, 0)))
+ else if(!(new_modes = mod_chanmode_parse(channel, argv+1, argc-1, MCP_KEY_FREE|MCP_REGISTERED|MCP_NO_APASS, 0)))
{
reply("CSMSG_INVALID_MODE_LOCK", unsplit_string(argv+1, argc-1, NULL));
return 0;
{
reply("CSMSG_INVALID_MODE_LOCK", unsplit_string(argv+1, argc-1, NULL));
return 0;
str = "+nt";
safestrncpy(mode_line, str, sizeof(mode_line));
ii = split_line(mode_line, 0, ArrayLength(modes), modes);
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, 0))
+ if((change = mod_chanmode_parse(NULL, modes, ii, MCP_KEY_FREE|MCP_NO_APASS, 0))
&& (change->argc < 2))
{
chanserv_conf.default_modes = *change;
&& (change->argc < 2))
{
chanserv_conf.default_modes = *change;
if(!IsSuspended(cData)
&& (str = database_get_data(channel, KEY_MODES, RECDB_QSTRING))
&& (argc = split_line(str, 0, ArrayLength(argv), argv))
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, 0))) {
+ && (modes = mod_chanmode_parse(cNode, argv, argc, MCP_KEY_FREE|MCP_NO_APASS, 0))) {
cData->modes = *modes;
if(off_channel > 0)
cData->modes.modes_set |= MODE_REGISTERED;
cData->modes = *modes;
if(off_channel > 0)
cData->modes.modes_set |= MODE_REGISTERED;
reply("OSMSG_NOT_ON_CHANNEL", target->nick, channel->name);
return 0;
}
reply("OSMSG_NOT_ON_CHANNEL", target->nick, channel->name);
return 0;
}
+ if (IsService(target)) {
+ reply("MSG_SERVICE_IMMUNE", target->nick);
+ return 0;
+ }
KickChannelUser(target, channel, cmd->parent->bot, reason);
return 1;
}
KickChannelUser(target, channel, cmd->parent->bot, reason);
return 1;
}
static struct channelList dead_channels;
/* These correspond to 1 << X: 012345678901234567 */
static struct channelList dead_channels;
/* These correspond to 1 << X: 012345678901234567 */
-const char irc_user_mode_chars[] = "o iw dkgn I";
+const char irc_user_mode_chars[] = "o iw dkgn x I";
static struct userNode *AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *numeric, const char *userinfo, unsigned long timestamp, const char *realip);
static struct userNode *AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *numeric, const char *userinfo, unsigned long timestamp, const char *realip);
char mask[MAXLEN];
char *host, *ident;
unsigned int ii;
char mask[MAXLEN];
char *host, *ident;
unsigned int ii;
for (ii=0; (*word != ' ') && (*word != '\0'); )
mask[ii++] = *word++;
mask[ii] = 0;
for (ii=0; (*word != ' ') && (*word != '\0'); )
mask[ii++] = *word++;
mask[ii] = 0;
ident = NULL;
host = mask;
}
ident = NULL;
host = mask;
}
+ user->modes |= FLAGS_HIDDEN_HOST;
assign_fakehost(user, host, ident, 0, 0);
}
break;
assign_fakehost(user, host, ident, 0, 0);
}
break;
+ if (flags & MCP_NO_APASS)
+ goto error;
if (add)
{
if ((in_arg >= argc)
if (add)
{
if ((in_arg >= argc)
+ if (flags & MCP_NO_APASS)
+ goto error;
if (add) {
if ((in_arg >= argc)
|| keyncpy(change->new_apass, modes[in_arg++], sizeof(change->new_apass)))
if (add) {
if ((in_arg >= argc)
|| keyncpy(change->new_apass, modes[in_arg++], sizeof(change->new_apass)))
#define MCP_REGISTERED 0x0008 /* chan is already registered; do not allow changes to MODE_REGISTERED */
#define MCP_UPASS_FREE 0x0010 /* -U without a key argument */
#define MCP_APASS_FREE 0x0020 /* -A without a key argument */
#define MCP_REGISTERED 0x0008 /* chan is already registered; do not allow changes to MODE_REGISTERED */
#define MCP_UPASS_FREE 0x0010 /* -U without a key argument */
#define MCP_APASS_FREE 0x0020 /* -A without a key argument */
+#define MCP_NO_APASS 0x0040 /* Do not allow +/-A or +/-U */
#define MC_ANNOUNCE 0x0100 /* send a mod_chanmode() change out */
#define MC_NOTIFY 0x0200 /* make local callbacks to announce */
#ifdef NDEBUG
#define MC_ANNOUNCE 0x0100 /* send a mod_chanmode() change out */
#define MC_NOTIFY 0x0200 /* make local callbacks to announce */
#ifdef NDEBUG