1
0
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:
Bram Matthys
2021-08-22 11:45:08 +02:00
parent 1533c6431e
commit 24f73c28e4
9 changed files with 209 additions and 107 deletions
+1
View File
@@ -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
View File
@@ -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.
-18
View File
@@ -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 &&
+5 -1
View File
@@ -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
+197
View File
@@ -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;
}
+1 -1
View File
@@ -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");
-18
View File
@@ -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
View File
@@ -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))
-15
View File
@@ -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