mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-09 14:43:12 +02:00
Move channel mode +l to module chanmodes/limit
(and all the code related to it)
This commit is contained in:
@@ -145,6 +145,7 @@ loadmodule "svswatch";
|
||||
|
||||
/*** Channel modes ***/
|
||||
loadmodule "chanmodes/key"; /* +k */
|
||||
loadmodule "chanmodes/limit"; /* +l */
|
||||
loadmodule "chanmodes/inviteonly"; /* +i */
|
||||
loadmodule "chanmodes/secret"; /* +s */
|
||||
loadmodule "chanmodes/private"; /* +p */
|
||||
|
||||
+1
-3
@@ -1956,7 +1956,6 @@ struct Mode {
|
||||
long mode; /**< Core modes set on this channel (one of MODE_*) */
|
||||
Cmode_t extmode; /**< Other ("extended") channel modes set on this channel */
|
||||
void *extmodeparams[MAXPARAMMODES+1]; /**< Parameters for extended channel modes */
|
||||
int limit; /**< The +l limit in effect (eg: 40), if any - otherwise 0 */
|
||||
};
|
||||
|
||||
/* flags for Link if used to contain Watch --k4be */
|
||||
@@ -2120,14 +2119,13 @@ struct Ban {
|
||||
#define MODE_HALFOP 0x0100
|
||||
#define MODE_EXCEPT 0x0200
|
||||
#define MODE_BAN 0x0400
|
||||
#define MODE_LIMIT 0x4000
|
||||
#define MODE_RGSTR 0x8000
|
||||
#define MODE_INVEX 0x8000000
|
||||
|
||||
/*
|
||||
* mode flags which take another parameter (With PARAmeterS)
|
||||
*/
|
||||
#define MODE_WPARAS (MODE_HALFOP|MODE_CHANOP|MODE_VOICE|MODE_CHANOWNER|MODE_CHANADMIN|MODE_BAN|MODE_KEY|MODE_LIMIT|MODE_EXCEPT|MODE_INVEX)
|
||||
#define MODE_WPARAS (MODE_HALFOP|MODE_CHANOP|MODE_VOICE|MODE_CHANOWNER|MODE_CHANADMIN|MODE_BAN|MODE_KEY|MODE_EXCEPT|MODE_INVEX)
|
||||
/*
|
||||
* Undefined here, these are used in conjunction with the above modes in
|
||||
* the source.
|
||||
|
||||
@@ -53,7 +53,6 @@ static mp_pool_t *channel_pool = NULL;
|
||||
* These are +ntmispklr and also the list modes +vhoaq and +beI.
|
||||
*/
|
||||
CoreChannelModeTable corechannelmodetable[] = {
|
||||
{MODE_LIMIT, 'l', 1, 1},
|
||||
{MODE_VOICE, 'v', 1, 1},
|
||||
{MODE_HALFOP, 'h', 0, 1},
|
||||
{MODE_CHANOP, 'o', 0, 1},
|
||||
@@ -596,10 +595,6 @@ int has_channel_mode(Channel *channel, char mode)
|
||||
tab++;
|
||||
}
|
||||
|
||||
/* Special handling for +l (needed??) */
|
||||
if (channel->mode.limit && (mode == 'l'))
|
||||
return 1;
|
||||
|
||||
return 0; /* Not found */
|
||||
}
|
||||
|
||||
@@ -682,19 +677,6 @@ void channel_modes(Client *client, char *mbuf, char *pbuf, size_t mbuf_size, siz
|
||||
}
|
||||
}
|
||||
|
||||
if (channel->mode.limit)
|
||||
{
|
||||
if (mbuf_size) {
|
||||
*mbuf++ = 'l';
|
||||
mbuf_size--;
|
||||
}
|
||||
if (ismember) {
|
||||
ircsnprintf(pbuf, pbuf_size, "%d ", channel->mode.limit);
|
||||
pbuf_size-=strlen(pbuf);
|
||||
pbuf+=strlen(pbuf);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i <= Channelmode_highest; i++)
|
||||
{
|
||||
if (Channelmode_Table[i].flag &&
|
||||
|
||||
@@ -32,7 +32,7 @@ INCLUDES = ../../include/channel.h \
|
||||
../../include/version.h ../../include/whowas.h
|
||||
|
||||
R_MODULES= \
|
||||
key.so inviteonly.so secret.so private.so \
|
||||
key.so limit.so inviteonly.so secret.so private.so \
|
||||
noexternalmsgs.so \
|
||||
nocolor.so stripcolor.so issecure.so permanent.so floodprot.so \
|
||||
noctcp.so link.so censor.so delayjoin.so noknock.so noinvite.so operonly.so \
|
||||
@@ -58,6 +58,10 @@ key.so: key.c $(INCLUDES)
|
||||
$(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \
|
||||
-o key.so key.c
|
||||
|
||||
limit.so: limit.c $(INCLUDES)
|
||||
$(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \
|
||||
-o limit.so limit.c
|
||||
|
||||
inviteonly.so: inviteonly.c $(INCLUDES)
|
||||
$(CC) $(CFLAGS) $(MODULEFLAGS) -DDYNAMIC_LINKING \
|
||||
-o inviteonly.so inviteonly.c
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Channel Mode +l
|
||||
* (C) Copyright 2021 Syzop and the UnrealIRCd team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 1, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "unrealircd.h"
|
||||
|
||||
ModuleHeader MOD_HEADER
|
||||
= {
|
||||
"chanmodes/limit",
|
||||
"6.0",
|
||||
"Channel Mode +l",
|
||||
"UnrealIRCd Team",
|
||||
"unrealircd-6",
|
||||
};
|
||||
|
||||
typedef struct ChannelLimit ChannelLimit;
|
||||
struct ChannelLimit {
|
||||
int limit;
|
||||
};
|
||||
|
||||
/* Global variables */
|
||||
ModDataInfo *mdlimit = NULL;
|
||||
Cmode_t EXTMODE_LIMIT = 0L;
|
||||
|
||||
#define IsLimit(x) ((x)->mode.extmode & EXTMODE_LIMIT)
|
||||
|
||||
/* Just for buffers, nothing else */
|
||||
#define LIMITLEN 32
|
||||
|
||||
/* Forward declarations */
|
||||
int limit_can_join(Client *client, Channel *channel, char *key, char *parv[]);
|
||||
int cmode_limit_is_ok(Client *client, Channel *channel, char mode, char *para, int type, int what);
|
||||
void *cmode_limit_put_param(void *r_in, char *param);
|
||||
char *cmode_limit_get_param(void *r_in);
|
||||
char *cmode_limit_conv_param(char *param_in, Client *client, Channel *channel);
|
||||
void cmode_limit_free_param(void *r);
|
||||
void *cmode_limit_dup_struct(void *r_in);
|
||||
int cmode_limit_sjoin_check(Channel *channel, void *ourx, void *theirx);
|
||||
int transform_channel_limit(char *param);
|
||||
|
||||
MOD_INIT()
|
||||
{
|
||||
CmodeInfo creq;
|
||||
ModDataInfo mreq;
|
||||
|
||||
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||
|
||||
memset(&creq, 0, sizeof(creq));
|
||||
creq.paracount = 1;
|
||||
creq.is_ok = cmode_limit_is_ok;
|
||||
creq.flag = 'l';
|
||||
creq.put_param = cmode_limit_put_param;
|
||||
creq.get_param = cmode_limit_get_param;
|
||||
creq.conv_param = cmode_limit_conv_param;
|
||||
creq.free_param = cmode_limit_free_param;
|
||||
creq.dup_struct = cmode_limit_dup_struct;
|
||||
creq.sjoin_check = cmode_limit_sjoin_check;
|
||||
CmodeAdd(modinfo->handle, creq, &EXTMODE_LIMIT);
|
||||
|
||||
HookAdd(modinfo->handle, HOOKTYPE_CAN_JOIN, 0, limit_can_join);
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
MOD_LOAD()
|
||||
{
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
MOD_UNLOAD()
|
||||
{
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
/** Can the user join the channel? */
|
||||
int limit_can_join(Client *client, Channel *channel, char *key, char *parv[])
|
||||
{
|
||||
ChannelLimit *r = (ChannelLimit *)GETPARASTRUCT(channel, 'l');
|
||||
|
||||
/* Is the channel +l? */
|
||||
if (r && r->limit && (channel->users >= r->limit))
|
||||
{
|
||||
Hook *h;
|
||||
for (h = Hooks[HOOKTYPE_CAN_JOIN_LIMITEXCEEDED]; h; h = h->next)
|
||||
{
|
||||
int i = (*(h->func.intfunc))(client,channel,key,parv);
|
||||
if (i != 0)
|
||||
return i;
|
||||
}
|
||||
return ERR_CHANNELISFULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmode_limit_is_ok(Client *client, Channel *channel, char mode, char *param, int type, int what)
|
||||
{
|
||||
if ((type == EXCHK_ACCESS) || (type == EXCHK_ACCESS_ERR))
|
||||
{
|
||||
/* Permitted for +hoaq */
|
||||
if (IsUser(client) && is_skochanop(client, channel))
|
||||
return EX_ALLOW;
|
||||
return EX_DENY;
|
||||
} else
|
||||
if (type == EXCHK_PARAM)
|
||||
{
|
||||
/* Actually any value is valid, we just morph it */
|
||||
return EX_ALLOW;
|
||||
}
|
||||
|
||||
/* fallthrough -- should not be used */
|
||||
return EX_DENY;
|
||||
}
|
||||
|
||||
void *cmode_limit_put_param(void *k_in, char *param)
|
||||
{
|
||||
ChannelLimit *fld = (ChannelLimit *)k_in;
|
||||
|
||||
if (!fld)
|
||||
fld = safe_alloc(sizeof(ChannelLimit));
|
||||
|
||||
fld->limit = transform_channel_limit(param);
|
||||
|
||||
return fld;
|
||||
}
|
||||
|
||||
char *cmode_limit_get_param(void *r_in)
|
||||
{
|
||||
ChannelLimit *r = (ChannelLimit *)r_in;
|
||||
static char retbuf[32];
|
||||
|
||||
if (!r)
|
||||
return NULL;
|
||||
|
||||
snprintf(retbuf, sizeof(retbuf), "%d", r->limit);
|
||||
return retbuf;
|
||||
}
|
||||
|
||||
char *cmode_limit_conv_param(char *param, Client *client, Channel *channel)
|
||||
{
|
||||
static char retbuf[32];
|
||||
int v = transform_channel_limit(param);
|
||||
snprintf(retbuf, sizeof(retbuf), "%d", v);
|
||||
return retbuf;
|
||||
}
|
||||
|
||||
void cmode_limit_free_param(void *r)
|
||||
{
|
||||
safe_free(r);
|
||||
}
|
||||
|
||||
void *cmode_limit_dup_struct(void *r_in)
|
||||
{
|
||||
ChannelLimit *r = (ChannelLimit *)r_in;
|
||||
ChannelLimit *w = safe_alloc(sizeof(ChannelLimit));
|
||||
|
||||
memcpy(w, r, sizeof(ChannelLimit));
|
||||
|
||||
return (void *)w;
|
||||
}
|
||||
|
||||
int cmode_limit_sjoin_check(Channel *channel, void *ourx, void *theirx)
|
||||
{
|
||||
ChannelLimit *our = (ChannelLimit *)ourx;
|
||||
ChannelLimit *their = (ChannelLimit *)theirx;
|
||||
|
||||
if (our->limit == their->limit)
|
||||
return EXSJ_SAME;
|
||||
else if (our->limit > their->limit)
|
||||
return EXSJ_WEWON;
|
||||
else
|
||||
return EXSJ_THEYWON;
|
||||
}
|
||||
|
||||
int transform_channel_limit(char *param)
|
||||
{
|
||||
int v = atoi(param);
|
||||
if (v <= 0)
|
||||
v = 1; /* setting +l with a negative number makes no sense */
|
||||
if (v > 1000000)
|
||||
v = 1000000; /* some kind of limit, 1 million (mrah...) */
|
||||
return v;
|
||||
}
|
||||
@@ -446,7 +446,7 @@ CMD_FUNC(cmd_invite)
|
||||
invite_operoverride_msg(client, channel, "b", "ban");
|
||||
else if (has_channel_mode(channel, 'i'))
|
||||
invite_operoverride_msg(client, channel, "i", "invite only");
|
||||
else if (channel->mode.limit)
|
||||
else if (has_channel_mode(channel, 'l'))
|
||||
invite_operoverride_msg(client, channel, "l", "user limit");
|
||||
else if (has_channel_mode(channel, 'k'))
|
||||
invite_operoverride_msg(client, channel, "k", "key");
|
||||
|
||||
@@ -116,24 +116,6 @@ int _can_join(Client *client, Channel *channel, char *key, char *parv[])
|
||||
if (is_invited(client, channel))
|
||||
return 0; /* allowed to walk through all the other modes */
|
||||
|
||||
if (channel->users >= channel->mode.limit)
|
||||
{
|
||||
/* Hmmm.. don't really like this.. and not at this place */
|
||||
|
||||
for (h = Hooks[HOOKTYPE_CAN_JOIN_LIMITEXCEEDED]; h; h = h->next)
|
||||
{
|
||||
i = (*(h->func.intfunc))(client,channel,key,parv);
|
||||
if (i != 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
/* We later check again for this limit (in case +L was not set) */
|
||||
}
|
||||
|
||||
|
||||
if ((channel->mode.limit && channel->users >= channel->mode.limit))
|
||||
return (ERR_CHANNELISFULL);
|
||||
|
||||
if (banned)
|
||||
return (ERR_BANNEDFROMCHAN);
|
||||
|
||||
|
||||
+4
-51
@@ -36,7 +36,7 @@ int do_mode_char(Channel *channel, long modetype, char modechar, char *param,
|
||||
u_int *pcount, char pvar[MAXMODEPARAMS][MODEBUFLEN + 3], long my_access);
|
||||
int do_extmode_char(Channel *channel, Cmode *handler, char *param, u_int what,
|
||||
Client *client, u_int *pcount, char pvar[MAXMODEPARAMS][MODEBUFLEN + 3]);
|
||||
void make_mode_str(Channel *channel, long oldm, Cmode_t oldem, long oldl, int pcount,
|
||||
void make_mode_str(Channel *channel, long oldm, Cmode_t oldem, int pcount,
|
||||
char pvar[MAXMODEPARAMS][MODEBUFLEN + 3], char *mode_buf, char *para_buf,
|
||||
size_t mode_buf_size, size_t para_buf_size);
|
||||
|
||||
@@ -498,7 +498,7 @@ void _do_mode(Channel *channel, Client *client, MessageTag *recv_mtags, int parc
|
||||
* Reconstructs the mode string, to make it look clean. mode_buf will
|
||||
* contain the +x-y stuff, and the parabuf will contain the parameters.
|
||||
*/
|
||||
void make_mode_str(Channel *channel, long oldm, Cmode_t oldem, long oldl, int pcount,
|
||||
void make_mode_str(Channel *channel, long oldm, Cmode_t oldem, int pcount,
|
||||
char pvar[MAXMODEPARAMS][MODEBUFLEN + 3], char *mode_buf, char *para_buf,
|
||||
size_t mode_buf_size, size_t para_buf_size)
|
||||
{
|
||||
@@ -592,29 +592,6 @@ void make_mode_str(Channel *channel, long oldm, Cmode_t oldem, long oldl, int pc
|
||||
}
|
||||
|
||||
*x = '\0';
|
||||
/* user limit */
|
||||
if (channel->mode.limit != oldl)
|
||||
{
|
||||
if (channel->mode.limit == 0)
|
||||
{
|
||||
if (what != MODE_DEL)
|
||||
{
|
||||
*x++ = '-';
|
||||
what = MODE_DEL;
|
||||
}
|
||||
*x++ = 'l';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (what != MODE_ADD)
|
||||
{
|
||||
*x++ = '+';
|
||||
what = MODE_ADD;
|
||||
}
|
||||
*x++ = 'l';
|
||||
ircsnprintf(para_buf, para_buf_size, "%s%d ", para_buf, channel->mode.limit);
|
||||
}
|
||||
}
|
||||
/* reconstruct bkov chain */
|
||||
for (cnt = 0; cnt < pcount; cnt++)
|
||||
{
|
||||
@@ -1003,29 +980,6 @@ process_listmode:
|
||||
(what == MODE_ADD) ? '+' : '-', tc, target->name);
|
||||
(*pcount)++;
|
||||
break;
|
||||
case MODE_LIMIT:
|
||||
if (what == MODE_ADD)
|
||||
{
|
||||
int v;
|
||||
REQUIRE_PARAMETER()
|
||||
v = atoi(param);
|
||||
if (v < 0)
|
||||
v = 1; /* setting +l with a negative number makes no sense */
|
||||
if (v > 1000000)
|
||||
v = 1000000; /* some kind of limit, 1 million (mrah...) */
|
||||
if (channel->mode.limit == v)
|
||||
break;
|
||||
channel->mode.limit = v;
|
||||
}
|
||||
else
|
||||
{
|
||||
retval = 0;
|
||||
if (!channel->mode.limit)
|
||||
break;
|
||||
channel->mode.limit = 0;
|
||||
RunHook2(HOOKTYPE_MODECHAR_DEL, channel, (int)modechar);
|
||||
}
|
||||
break;
|
||||
case MODE_BAN:
|
||||
REQUIRE_PARAMETER()
|
||||
if (!(tmpstr = mode_ban_handler(client, channel, param, what, EXBTYPE_BAN, &channel->banlist)))
|
||||
@@ -1265,7 +1219,7 @@ void _set_mode(Channel *channel, Client *client, int parc, char *parv[], u_int *
|
||||
int found = 0;
|
||||
int sent_mlock_warning = 0;
|
||||
unsigned int htrig = 0;
|
||||
long oldm, oldl;
|
||||
long oldm;
|
||||
int checkrestr = 0, warnrestr = 1;
|
||||
int extm = 1000000; /* (default value not used but stops gcc from complaining) */
|
||||
Cmode_t oldem;
|
||||
@@ -1274,7 +1228,6 @@ void _set_mode(Channel *channel, Client *client, int parc, char *parv[], u_int *
|
||||
*pcount = 0;
|
||||
|
||||
oldm = channel->mode.mode;
|
||||
oldl = channel->mode.limit;
|
||||
oldem = channel->mode.extmode;
|
||||
if (RESTRICT_CHANNELMODES && !ValidatePermissionsForPath("immune:restrict-channelmodes",client,NULL,channel,NULL)) /* "cache" this */
|
||||
checkrestr = 1;
|
||||
@@ -1398,7 +1351,7 @@ void _set_mode(Channel *channel, Client *client, int parc, char *parv[], u_int *
|
||||
} /* switch(*curchr) */
|
||||
} /* for loop through mode letters */
|
||||
|
||||
make_mode_str(channel, oldm, oldem, oldl, *pcount, pvar, modebuf, parabuf, sizeof(modebuf), sizeof(parabuf));
|
||||
make_mode_str(channel, oldm, oldem, *pcount, pvar, modebuf, parabuf, sizeof(modebuf), sizeof(parabuf));
|
||||
|
||||
#ifndef NO_OPEROVERRIDE
|
||||
if ((htrig == 1) && IsUser(client))
|
||||
|
||||
@@ -707,11 +707,6 @@ getnick:
|
||||
strlcpy(modebuf, "-", sizeof modebuf);
|
||||
parabuf[0] = '\0';
|
||||
b = 1;
|
||||
/* however, is this really going to happen at all? may be unneeded */
|
||||
if (oldmode.limit && !channel->mode.limit)
|
||||
{
|
||||
Addsingle('l');
|
||||
}
|
||||
|
||||
/* First, check if we have something they don't have..
|
||||
* note that: oldmode.* = us, channel->mode.* = them.
|
||||
@@ -804,16 +799,6 @@ getnick:
|
||||
|
||||
/* now, if we had diffent para modes - this loop really could be done better, but */
|
||||
|
||||
/* +l (limit) difference? */
|
||||
if (oldmode.limit && channel->mode.limit && (oldmode.limit != channel->mode.limit))
|
||||
{
|
||||
channel->mode.limit = MAX(oldmode.limit, channel->mode.limit);
|
||||
if (oldmode.limit != channel->mode.limit)
|
||||
{
|
||||
Addit('l', my_itoa(channel->mode.limit));
|
||||
}
|
||||
}
|
||||
|
||||
/* Now, check for any param differences in extended channel modes..
|
||||
* note that: oldmode.* = us, channel->mode.* = them.
|
||||
* if we win: copy oldmode to channel mode, if they win: send the mode
|
||||
|
||||
Reference in New Issue
Block a user