- First big part of modulized extended channelmodes system

This commit is contained in:
Bram Matthys 2003-07-29 17:07:17 +00:00
parent ded7f11727
commit 41a0896d6d
19 changed files with 1016 additions and 56 deletions

21
Changes
View file

@ -2280,3 +2280,24 @@ seen. gmtime warning still there
- Will now error at too large cloak keys (2147483647 and greater) because it's dangerous
and could cause cloak key differences (ex: mixed ia32&ia64 networks).
- Some minor text/documentation fixes.
- First big part of modulized extended channelmodes system:
- Adds room for at least 32 (new) channel modes.
- Supports both paramless and 1-parameter modes.
- Modulized: modules can add new channelmodes, but are unloadable (permanent).
- Everything is ifdef'd, and EXTCMODE is disabled by default in config.h
- It will send CHANMODES= in the PROTOCTL message on server link, this enables
servers and services to see which modes are supported and of what type
they are (1-parameter, paramless, etc).
And now the bad part:
- The system has not been fully tested, it will contain bugs (for example I'm
aware of some memory leaks).
- A few features are missing: warning/error on linking if chanmodes mismatch, unloading
of channel modes (not planned soon), 005 broadcasts on change and maybe more..
- The function (and maybe variable) names will be changed in the next weeks/months
- You should be carefull with parameter modes + services. Things will get desynced
if services don't recognize it's a parameter mode. This also applies to clients
without 005 CHANMODES= support.
- No documentation
I really suggest module coders to wait a few weeks till the system is ready..
In the meantime, don't report bugs or ask for support on this.

View file

@ -56,7 +56,7 @@ help Opercmds {
" LAG SETHOST SETIDENT CHGHOST CHGIDENT";
" CHGNAME SQUIT CONNECT DCCDENY UNDCCDENY";
" SAJOIN SAPART SAMODE RPING TRACE";
" OPERMOTD SDESC MKPASSWD CLOSE";
" OPERMOTD SDESC MKPASSWD CLOSE MODULE";
" ==----------------oOo---------------==";
};
@ -926,6 +926,16 @@ help Mkpasswd {
" Example: MKPASSWD crypt mpsare";
};
help Module {
" This will give you a list of all modules loaded in the form:";
" *** name - version (description) [optional flags here]";
" flags can be:";
" [PERM]: permanent module (not possible to unload/reload)";
" [Unloading]: module is in the process of unloading";
" -";
" Syntax: MODULE";
};
help Close {
" This command will disconnect all unknown connections from the";
" IRC server.";

View file

@ -226,6 +226,18 @@ extern struct SLink *find_user_link( /* struct SLink *, struct Client * */ );
/* IRCu/Hybrid/Unreal way now :) -Stskeeps */
#ifdef EXTCMODE
#define EXPAR1 extchmstr[0]
#define EXPAR2 extchmstr[1]
#define EXPAR3 extchmstr[2]
#define EXPAR4 extchmstr[3]
#else
#define EXPAR1 ""
#define EXPAR2 ""
#define EXPAR3 ""
#define EXPAR4 ""
#endif /* EXTCMODE */
#define PROTOCTL_CLIENT_1 \
"MAP" \
" KNOCK" \
@ -248,6 +260,18 @@ extern struct SLink *find_user_link( /* struct SLink *, struct Client * */ );
MAXTARGETS, \
TOPICLEN
#ifdef PREFIX_AQ
#define CHPFIX "(qaohv)~&@%+"
#define CHPAR1 "be"
#else
#define CHPFIX "(ohv)@%+"
#define CHPAR1 "beqa"
#endif /* PREFIX_AQ */
#define CHPAR2 "k"
#define CHPAR3 "lfL"
#define CHPAR4 "psmntirRcOAQKVGCuzNSM"
#define PROTOCTL_CLIENT_2 \
"WALLCHOPS" \
" WATCH=%i" \
@ -255,39 +279,27 @@ extern struct SLink *find_user_link( /* struct SLink *, struct Client * */ );
" MODES=%i" \
" CHANTYPES=%s" \
" PREFIX=%s" \
" CHANMODES=%s,%s,%s,%s" \
" CHANMODES=%s%s,%s%s,%s%s,%s%s" \
" NETWORK=%s" \
" CASEMAPPING=%s" \
" :are supported by this server"
#ifndef PREFIX_AQ
#define PROTOCTL_PARAMETERS_2 \
MAXWATCH, \
MAXSILES, \
MAXMODEPARAMS, \
"#", \
"(ohv)@%+", \
"beqa", \
"kfL", \
"l", \
"psmntirRcOAQKVGCuzNSM", \
ircnet005, \
"ascii"
#else
#define PROTOCTL_PARAMETERS_2 \
MAXWATCH, \
MAXSILES, \
MAXMODEPARAMS, \
"#", \
"(qaohv)~&@%+", \
"be", \
"kfL", \
"l", \
"psmntirRcOAQKVGCuzNSM", \
ircnet005, \
"ascii"
#endif
/* Server-Server PROTOCTL -Stskeeps */
MAXWATCH, \
MAXSILES, \
MAXMODEPARAMS, \
"#", \
CHPFIX, \
CHPAR1, EXPAR1, \
CHPAR2, EXPAR2, \
CHPAR3, EXPAR3, \
"psmntirRcOAQKVGCuzNSM", EXPAR4, \
ircnet005, \
"ascii"
/* Server-Server PROTOCTL -Stskeeps
* Please check send_proto() for more. -- Syzop
*/
#define PROTOCTL_SERVER "NOQUIT" \
" TOKEN" \
" NICKv2" \

View file

@ -544,6 +544,13 @@
*/
#define SIXBONE_HACK
/*
* Extended channel modes. This extends the channel modes with yet another
* 32 possible modes which can also be used in modules.
* This is currently considered experimental however.
*/
#undef EXTCMODE
/* ------------------------- END CONFIGURATION SECTION -------------------- */
#define MOTD MPATH
#define RULES RPATH

View file

@ -585,3 +585,16 @@ extern char trouble_info[1024];
extern void rejoin_doparts(aClient *sptr);
extern void rejoin_dojoinandmode(aClient *sptr);
extern void ident_failed(aClient *cptr);
extern char extchmstr[4][64];
#ifdef EXTCMODE
extern int extcmode_default_requirechop(aClient *, aChannel *, char *, int, int);
extern int extcmode_default_requirehalfop(aClient *, aChannel *, char *, int, int);
extern int extcmode_delete(char);
extern ExtCMode extcmode_get(aExtCMtable *);
extern void extcmode_init(void);
extern aExtCMtableParam *extcmode_get_struct(aExtCMtableParam *, char);
extern void make_extcmodestr();
extern aExtCMtableParam *extcmode_duplicate_paramlist(aExtCMtableParam *);
extern void extcmode_free_paramlist(aExtCMtableParam *);
#endif

View file

@ -163,6 +163,7 @@ struct _Module
ModuleChild *children;
ModuleObject *objects;
ModuleInfo modinfo; /* Used to store handle info for module */
unsigned permanent:1; /* permanent module? (can't unload/reload) */
};
/*
* Symbol table

View file

@ -1218,9 +1218,118 @@ struct ListOptions {
TS topictimemax;
};
#ifdef EXTCMODE
#define EXTCMODETABLESZ 32
typedef unsigned long ExtCMode;
/** These define's are used for the aExtCMtable->is_ok() routines.
* (these 3 type of checks are seperated because of operoverride and stuff)
*/
#define EXCHK_ACCESS 0 /* Check access */
#define EXCHK_ACCESS_ERR 1 /* Check access and send error if needed */
#define EXCHK_PARAM 2 /* Check parameter and send error if needed */
#define EXSJ_SAME 0 /* Parameters are the same */
#define EXSJ_WEWON 1 /* We won! w00t */
#define EXSJ_THEYWON 2 /* They won :( */
typedef struct ExtCMtable aExtCMtable;
typedef struct ExtCMtableParam aExtCMtableParam;
/** Extended channel mode table.
* This table contains all extended channelmode info like the flag, mode, their
* functions, etc..
*/
struct ExtCMtable {
/** mode character (like 'Z') */
char flag;
/** unique flag (like 0x10) */
ExtCMode mode;
/** # of paramters (1 or 0) */
int paracount;
/** access and parameter checking.
* aClient *: the client
* aChannel *: the channel
* para *: the parameter (NULL for paramless modes)
* int: check type (see EXCHK_*)
* int: what (MODE_ADD or MODE_DEL)
* return value: 1=ok, 0=bad
*/
int (*is_ok)(aClient *,aChannel *, char *para, int, int);
/** NOTE: The routines below are NULL for paramless modes */
/** Store parameter in memory for channel.
* aExtCMtableParam *: the list (usually chptr->mode.extmodeparams).
* char *: the parameter.
* return value: the head of the list, RTFS if you wonder why.
* design notes: only alloc a new paramstruct if you need to, search for
* any current one first (like in case of mode +y 5 and then +y 6 later without -y).
*/
aExtCMtableParam * (*put_param)(aExtCMtableParam *, char *);
/** Get readable string version" of the stored parameter.
* aExtCMtableParam *: the list (usually chptr->mode.extmodeparams).
* return value: a pointer to the string (temp. storage)
*/
char * (*get_param)(aExtCMtableParam *);
/** Convert input parameter to output.
* Like +l "1aaa" becomes "1".
* char *: the input parameter.
* return value: pointer to output string (temp. storage)
*/
char * (*conv_param)(char *);
/** free and remove parameter from list.
* aExtCMtableParam *: the list (usually chptr->mode.extmodeparams).
* return value: the head of the list, RTFS if you wonder why.
*/
aExtCMtableParam * (*free_param)(aExtCMtableParam *);
/** duplicate a struct and return a pointer to duplicate.
* This is usually just a malloc + memcpy.
* aExtCMtableParam *: source struct itself (no list).
* return value: pointer to newly allocated struct.
*/
aExtCMtableParam * (*dup_struct)(aExtCMtableParam *);
/** Compares 2 parameters and decides who wins the sjoin fight.
* When syncing channel modes (m_sjoin) a parameter conflict may occur, things like
* +l 5 vs +l 10. This function should determinate who wins the fight, this decision
* should of course not be random but the same at every server on the net.
* examples of such comparisons are "highest wins" (+l) and a strcmp() check (+k/+L).
* aChannel *: channel the fight is about.
* aExtCMtableParam *: our parameter
* aExtCMtableParam *: their parameter
*/
int (*sjoin_check)(aChannel *, aExtCMtableParam *, aExtCMtableParam *);
};
extern aExtCMtable *ExtCMode_Table;
extern unsigned short ExtCMode_highest;
#define EXTCM_PAR_HEADER aExtCMtableParam *prev, *next; char flag;
struct ExtCMtableParam {
EXTCM_PAR_HEADER
/** other fields are placed after this header in your own paramstruct */
};
#endif /* EXTCMODE */
/* mode structure for channels */
struct SMode {
long mode;
#ifdef EXTCMODE
ExtCMode extmode;
aExtCMtableParam *extmodeparam;
#endif
int limit;
char key[KEYLEN + 1];
char link[LINKLEN + 1];

View file

@ -35,7 +35,7 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ
SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/EXTCMODES.OBJ
MOD_FILES=SRC/L_COMMANDS.OBJ SRC/M_CHGHOST.OBJ SRC/M_SDESC.OBJ SRC/M_SETIDENT.OBJ \
SRC/M_SETNAME.OBJ SRC/M_SETHOST.OBJ SRC/M_CHGIDENT.OBJ SRC/M_SVSMOTD.OBJ \
@ -231,6 +231,9 @@ src/cidr.obj: src/cidr.c $(INCLUDES)
src/random.obj: src/random.c $(INCLUDES)
$(CC) $(CFLAGS) src/random.c
src/extcmodes.obj: src/extcmodes.c $(INCLUDES)
$(CC) $(CFLAGS) src/extcmodes.c
src/ssl.obj: src/ssl.c $(INCLUDES)
$(CC) $(CFLAGS) src/ssl.c

View file

@ -38,7 +38,7 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ
SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/EXTCMODES.OBJ
MOD_FILES=SRC/L_COMMANDS.OBJ SRC/M_CHGHOST.OBJ SRC/M_SDESC.OBJ SRC/M_SETIDENT.OBJ \
SRC/M_SETNAME.OBJ SRC/M_SETHOST.OBJ SRC/M_CHGIDENT.OBJ SRC/M_SVSMOTD.OBJ \
@ -234,6 +234,9 @@ src/cidr.obj: src/cidr.c $(INCLUDES)
src/random.obj: src/random.c $(INCLUDES)
$(CC) $(CFLAGS) src/random.c
src/extcmodes.obj: src/extcmodes.c $(INCLUDES)
$(CC) $(CFLAGS) src/extcmodes.c
src/ssl.obj: src/ssl.c $(INCLUDES)
$(CC) $(CFLAGS) src/ssl.c

View file

@ -45,7 +45,7 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/ZIP.OBJ
SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/ZIP.OBJ SRC/EXTCMODES.OBJ
MOD_FILES=SRC/L_COMMANDS.OBJ SRC/M_CHGHOST.OBJ SRC/M_SDESC.OBJ SRC/M_SETIDENT.OBJ \
SRC/M_SETNAME.OBJ SRC/M_SETHOST.OBJ SRC/M_CHGIDENT.OBJ SRC/M_SVSMOTD.OBJ \
@ -241,6 +241,9 @@ src/cidr.obj: src/cidr.c $(INCLUDES)
src/random.obj: src/random.c $(INCLUDES)
$(CC) $(CFLAGS) src/random.c
src/extcmodes.obj: src/extcmodes.c $(INCLUDES)
$(CC) $(CFLAGS) src/extcmodes.c
src/zip.obj: src/zip.c $(INCLUDES)
$(CC) $(CFLAGS) src/zip.c

View file

@ -40,7 +40,7 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \
SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \
SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \
SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \
SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/ZIP.OBJ
SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ SRC/ZIP.OBJ SRC/EXTCMODES.OBJ
MOD_FILES=SRC/L_COMMANDS.OBJ SRC/M_CHGHOST.OBJ SRC/M_SDESC.OBJ SRC/M_SETIDENT.OBJ \
SRC/M_SETNAME.OBJ SRC/M_SETHOST.OBJ SRC/M_CHGIDENT.OBJ SRC/M_SVSMOTD.OBJ \
@ -236,6 +236,9 @@ src/cidr.obj: src/cidr.c $(INCLUDES)
src/random.obj: src/random.c $(INCLUDES)
$(CC) $(CFLAGS) src/random.c
src/extcmodes.obj: src/extcmodes.c $(INCLUDES)
$(CC) $(CFLAGS) src/extcmodes.c
src/zip.obj: src/zip.c $(INCLUDES)
$(CC) $(CFLAGS) src/zip.c

View file

@ -28,7 +28,7 @@ OBJS=auth.o aln.o badwords.o channel.o cloak.o crule.o dbuf.o \
s_bsd.o s_conf.o s_debug.o s_err.o s_extra.o s_kline.o \
s_misc.o s_numeric.o s_serv.o s_svs.o $(STRTOUL) socket.o \
ssl.o s_user.o scache.o send.o support.o umodes.o \
version.o webtv.o whowas.o zip.o cidr.o random.o
version.o webtv.o whowas.o zip.o cidr.o random.o extcmodes.o
SRC=$(OBJS:%.o=%.c)
@ -240,5 +240,8 @@ cidr.o: cidr.c $(INCLUDES)
random.o: random.c $(INCLUDES)
$(CC) $(CFLAGS) -c random.c
extcmodes.o: extcmodes.c $(INCLUDES)
$(CC) $(CFLAGS) -c extcmodes.c
# DO NOT DELETE THIS LINE -- make depend depends on it.

View file

@ -83,8 +83,15 @@ static int check_channelmask(aClient *, aClient *, char *);
int del_banid(aChannel *, char *);
static void set_mode(aChannel *, aClient *, int, char **, u_int *,
char[MAXMODEPARAMS][MODEBUFLEN + 3], int);
#ifdef EXTCMODE
static void make_mode_str(aChannel *, long, ExtCMode, long, int,
char[MAXMODEPARAMS][MODEBUFLEN + 3], char *, char *, char);
#else
static void make_mode_str(aChannel *, long, long, int,
char[MAXMODEPARAMS][MODEBUFLEN + 3], char *, char *, char);
#endif
static int do_mode_char(aChannel *, long, char, char *,
u_int, aClient *,
u_int *, char[MAXMODEPARAMS][MODEBUFLEN + 3], char);
@ -168,13 +175,20 @@ void make_cmodestr(void)
{
char *p = &cmodestring[0];
aCtab *tab = &cFlagTab[0];
#ifdef EXTCMODE
int i;
#endif
while (tab->mode != 0x0)
{
*p = tab->flag;
p++;
tab++;
}
#ifdef EXTCMODE
for (i=0; i <= ExtCMode_highest; i++)
if (ExtCMode_Table[i].flag)
*p++ = ExtCMode_Table[i].flag;
#endif
*p = '\0';
}
@ -829,8 +843,12 @@ void channel_modes(aClient *cptr, char *mbuf, char *pbuf, aChannel *chptr)
{
aCtab *tab = &cFlagTab[0];
char bcbuf[1024];
#ifdef EXTCMODE
int i;
#endif
*mbuf++ = '+';
/* Paramless first */
while (tab->mode != 0x0)
{
if ((chptr->mode.mode & tab->mode))
@ -838,6 +856,14 @@ void channel_modes(aClient *cptr, char *mbuf, char *pbuf, aChannel *chptr)
*mbuf++ = tab->flag;
tab++;
}
#ifdef EXTCMODE
for (i=0; i <= ExtCMode_highest; i++)
{
if (ExtCMode_Table[i].flag && !ExtCMode_Table[i].paracount &&
(chptr->mode.extmode & ExtCMode_Table[i].mode))
*mbuf++ = ExtCMode_Table[i].flag;
}
#endif
if (chptr->mode.limit)
{
*mbuf++ = 'l';
@ -884,6 +910,18 @@ void channel_modes(aClient *cptr, char *mbuf, char *pbuf, aChannel *chptr)
}
}
#ifdef EXTCMODE
for (i=0; i <= ExtCMode_highest; i++)
{
if (ExtCMode_Table[i].flag && ExtCMode_Table[i].paracount &&
(chptr->mode.extmode & ExtCMode_Table[i].mode))
{
*mbuf++ = ExtCMode_Table[i].flag;
strcat(pbuf, ExtCMode_Table[i].get_param(chptr->mode.extmodeparam));
strcat(pbuf, " ");
}
}
#endif
*mbuf++ = '\0';
return;
@ -1319,10 +1357,7 @@ void bounce_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[])
{
char pvar[MAXMODEPARAMS][MODEBUFLEN + 3];
int pcount;
long oldm, oldl;
oldm = chptr->mode.mode;
oldl = chptr->mode.limit;
set_mode(chptr, cptr, parc, parv, &pcount, pvar, 1);
if (chptr->creationtime)
@ -1343,13 +1378,10 @@ void do_mode(aChannel *chptr, aClient *cptr, aClient *sptr, int parc, char *parv
{
char pvar[MAXMODEPARAMS][MODEBUFLEN + 3];
int pcount;
long oldm, oldl;
char tschange = 0, isbounce = 0; /* fwd'ing bounce */
if (**parv == '&')
isbounce = 1;
oldm = chptr->mode.mode;
oldl = chptr->mode.limit;
set_mode(chptr, sptr, parc, parv, &pcount, pvar, 0);
@ -1455,14 +1487,22 @@ void do_mode(aChannel *chptr, aClient *cptr, aClient *sptr, int parc, char *parv
* contain the +x-y stuff, and the parabuf will contain the parameters.
* If bounce is set to 1, it will make the string it needs for a bounce.
*/
#ifdef EXTCMODE
void make_mode_str(aChannel *chptr, long oldm, ExtCMode oldem, long oldl, int pcount,
char pvar[MAXMODEPARAMS][MODEBUFLEN + 3], char *mode_buf, char *para_buf, char bounce)
#else
void make_mode_str(aChannel *chptr, long oldm, long oldl, int pcount,
char pvar[MAXMODEPARAMS][MODEBUFLEN + 3], char *mode_buf, char *para_buf, char bounce)
#endif
{
char tmpbuf[MODEBUFLEN+3], *tmpstr;
aCtab *tab = &cFlagTab[0];
char *x = mode_buf;
int what, cnt, z;
#ifdef EXTCMODE
int i;
#endif
char *m;
what = 0;
@ -1488,6 +1528,25 @@ void make_mode_str(aChannel *chptr, long oldm, long oldl, int pcount,
}
tab++;
}
#ifdef EXTCMODE
/* + paramless extmodes... */
for (i=0; i <= ExtCMode_highest; i++)
{
if (!ExtCMode_Table[i].flag || ExtCMode_Table[i].paracount)
continue;
/* have it now and didn't have it before? */
if ((chptr->mode.extmode & ExtCMode_Table[i].mode) &&
!(oldem & ExtCMode_Table[i].mode))
{
if (what != MODE_ADD)
{
*x++ = bounce ? '-' : '+';
what = MODE_ADD;
}
*x++ = ExtCMode_Table[i].flag;
}
}
#endif
*x = '\0';
/* - param-less modes */
@ -1509,6 +1568,28 @@ void make_mode_str(aChannel *chptr, long oldm, long oldl, int pcount,
tab++;
}
#ifdef EXTCMODE
/* - extmodes (both "param modes" and paramless don't have
* any params when unsetting...
*/
for (i=0; i <= ExtCMode_highest; i++)
{
if (!ExtCMode_Table[i].flag /* || ExtCMode_Table[i].paracount */)
continue;
/* don't have it now and did have it before */
if (!(chptr->mode.extmode & ExtCMode_Table[i].mode) &&
(oldem & ExtCMode_Table[i].mode))
{
if (what != MODE_DEL)
{
*x++ = bounce ? '+' : '-';
what = MODE_DEL;
}
*x++ = ExtCMode_Table[i].flag;
}
}
#endif
*x = '\0';
/* user limit */
if (chptr->mode.limit != oldl)
@ -1566,7 +1647,12 @@ void make_mode_str(aChannel *chptr, long oldm, long oldl, int pcount,
*m = '\0';
}
if (bounce)
{
chptr->mode.mode = oldm;
#ifdef EXTCMODE
chptr->mode.extmode = oldem;
#endif
}
z = strlen(para_buf);
if (para_buf[z - 1] == ' ')
para_buf[z - 1] = '\0';
@ -2208,6 +2294,88 @@ int do_mode_char(aChannel *chptr, long modetype, char modechar, char *param,
return retval;
}
#ifdef EXTCMODE
/** Check access and if granted, set the extended chanmode to the requested value in memory.
* note: if bounce is requested then the mode will not be set.
* @returns amount of params eaten (0 or 1)
*/
int do_extmode_char(aChannel *chptr, int modeindex, char *param, u_int what,
aClient *cptr, u_int *pcount, char pvar[MAXMODEPARAMS][MODEBUFLEN + 3],
char bounce)
{
int paracnt = (what == MODE_ADD) ? ExtCMode_Table[modeindex].paracount : 0;
int x;
/* Expected a param and it isn't there? */
if (paracnt && (!param || (*pcount >= MAXMODEPARAMS)))
return 0;
if (!IsServer(cptr) &&
#ifndef NO_OPER_OVERRIDE
!IsSkoAdmin(cptr) &&
#endif
(ExtCMode_Table[modeindex].is_ok(cptr, chptr, param, EXCHK_ACCESS_ERR, what) == FALSE))
return paracnt; /* Denied & error msg sent */
/* Check for multiple changes in 1 command (like +y-y+y 1 2, or +yy 1 2). */
for (x = 0; x < *pcount; x++)
{
if (pvar[x][1] == ExtCMode_Table[modeindex].flag)
{
/* this is different than the old chanmode system, coz:
* "mode #chan +kkL #a #b #c" will get "+kL #a #b" which is wrong :p.
* we do eat the parameter. -- Syzop
*/
return paracnt;
}
}
/* w00t... a parameter mode */
if (ExtCMode_Table[modeindex].paracount)
{
if (what == MODE_DEL)
{
if (!(chptr->mode.extmode & ExtCMode_Table[modeindex].mode))
return paracnt; /* There's nothing to remove! [TODO: -> 0] */
/* del means any parameter is ok, the one-who-is-set will be used */
ircsprintf(pvar[*pcount], "-%c", ExtCMode_Table[modeindex].flag);
} else {
/* add: is the parameter ok? */
if (ExtCMode_Table[modeindex].is_ok(cptr, chptr, param, EXCHK_PARAM, what) == FALSE)
return paracnt;
/* is it already set at the same value? if so, ignore it. */
if (chptr->mode.extmode & ExtCMode_Table[modeindex].mode)
{
char *p, *p2;
p = ExtCMode_Table[modeindex].get_param(chptr->mode.extmodeparam);
p2 = ExtCMode_Table[modeindex].conv_param(param);
if (p && p2 && !strcmp(p, p2))
return paracnt; /* ignore... */
}
ircsprintf(pvar[*pcount], "+%c%s",
ExtCMode_Table[modeindex].flag, ExtCMode_Table[modeindex].conv_param(param));
(*pcount)++;
}
}
if (bounce) /* bounce here means: only check access and return return value */
return paracnt;
if (what == MODE_ADD)
{ /* + */
chptr->mode.extmode |= ExtCMode_Table[modeindex].mode;
if (ExtCMode_Table[modeindex].paracount)
chptr->mode.extmodeparam = ExtCMode_Table[modeindex].put_param(chptr->mode.extmodeparam, param);
} else
{ /* - */
chptr->mode.extmode &= ~(ExtCMode_Table[modeindex].mode);
if (ExtCMode_Table[modeindex].paracount)
chptr->mode.extmodeparam = ExtCMode_Table[modeindex].free_param(chptr->mode.extmodeparam);
}
return paracnt;
}
#endif /* EXTCMODE */
/*
* ListBits(bitvalue, bitlength);
* written by Stskeeps
@ -2254,13 +2422,18 @@ void set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pco
unsigned int htrig = 0;
long oldm, oldl;
int checkrestr = 0, warnrestr = 1;
#ifdef EXTCMODE
int extm;
ExtCMode oldem;
#endif
paracount = 1;
*pcount = 0;
oldm = chptr->mode.mode;
oldl = chptr->mode.limit;
#ifdef EXTCMODE
oldem = chptr->mode.extmode;
#endif
if (RESTRICT_CHANNELMODES && MyClient(cptr) && !IsAnOper(cptr) && !IsServer(cptr)) /* "cache" this */
checkrestr = 1;
@ -2297,11 +2470,22 @@ void set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pco
tab++;
}
if (found == 1)
{
modetype = foundat.mode;
} else {
#ifdef EXTCMODE
/* Maybe in extmodes */
for (extm=0; extm <= ExtCMode_highest; extm++)
{
if (ExtCMode_Table[extm].flag == *curchr)
{
found = 2;
break;
}
}
#endif
}
if (found == 0)
modetype = 0;
if (modetype == 0)
{
if (!MyClient(cptr))
break;
@ -2325,12 +2509,26 @@ void set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pco
}
#ifndef NO_OPEROVERRIDE
if (found == 1)
{
if ((Halfop_mode(modetype) == FALSE) && opermode == 2 && htrig != 1)
{
opermode = 0;
htrig = 1;
}
#endif
}
#ifdef EXTCMODE
else if (found == 2) {
/* Extended mode */
if ((ExtCMode_Table[extm].is_ok(cptr, chptr, parv[paracount], EXCHK_ACCESS, what) == FALSE) &&
(opermode == 2) && (htrig != 1))
{
opermode = 0;
htrig = 1;
}
}
#endif /* EXTCMODE */
#endif /* !NO_OPEROVERRIDE */
/* We can afford to send off a param */
if (parc <= paracount)
@ -2338,15 +2536,29 @@ void set_mode(aChannel *chptr, aClient *cptr, int parc, char *parv[], u_int *pco
if (parv[paracount] &&
strlen(parv[paracount]) >= MODEBUFLEN)
parv[paracount][MODEBUFLEN-1] = '\0';
if (found == 1)
{
paracount +=
do_mode_char(chptr, modetype, *curchr,
parv[paracount], what, cptr, pcount, pvar,
bounce);
}
#ifdef EXTCMODE
else if (found == 2)
{
paracount += do_extmode_char(chptr, extm, parv[paracount],
what, cptr, pcount, pvar, bounce);
}
#endif /* EXTCMODE */
break;
}
}
#ifdef EXTCMODE
make_mode_str(chptr, oldm, oldem, oldl, *pcount, pvar, modebuf, parabuf, bounce);
#else
make_mode_str(chptr, oldm, oldl, *pcount, pvar, modebuf, parabuf, bounce);
#endif
#ifndef NO_OPEROVERRIDE
if (htrig == 1)
@ -4982,6 +5194,11 @@ CMD_FUNC(m_sjoin)
{
aCtab *acp;
bcopy(&chptr->mode, &oldmode, sizeof(Mode));
#ifdef EXTCMODE
/* Fun.. we have to duplicate all extended modes too... */
oldmode.extmodeparam = NULL;
oldmode.extmodeparam = extcmode_duplicate_paramlist(chptr->mode.extmodeparam);
#endif
/* merge the modes */
strlcpy(modebuf, parv[3], sizeof modebuf);
parabuf[0] = '\0';
@ -5023,7 +5240,27 @@ CMD_FUNC(m_sjoin)
oldmode.msgs, oldmode.per);
Addit('f', modeback);
}
#ifdef EXTCMODE
/* First, check if we have something they don't have..
* note that: oldmode.* = us, chptr->mode.* = them.
*/
for (i=0; i <= ExtCMode_highest; i++)
{
if ((ExtCMode_Table[i].flag) &&
(oldmode.extmode & ExtCMode_Table[i].mode) &&
!(chptr->mode.extmode & ExtCMode_Table[i].mode))
{
if (ExtCMode_Table[i].paracount)
{
char *parax = ExtCMode_Table[i].get_param(oldmode.extmodeparam);
Addit(ExtCMode_Table[i].flag, parax);
} else {
Addsingle(ExtCMode_Table[i].flag);
}
}
}
#endif
/* Add single char modes... */
for (acp = cFlagTab; acp->mode; acp++)
{
if ((oldmode.mode & acp->mode) &&
@ -5072,6 +5309,27 @@ CMD_FUNC(m_sjoin)
Addit('f', modeback);
}
#ifdef EXTCMODE
/* Now, check if they have something we don't have..
* note that: oldmode.* = us, chptr->mode.* = them.
*/
for (i=0; i <= ExtCMode_highest; i++)
{
if ((ExtCMode_Table[i].flag) &&
!(oldmode.extmode & ExtCMode_Table[i].mode) &&
(chptr->mode.extmode & ExtCMode_Table[i].mode))
{
if (ExtCMode_Table[i].paracount)
{
char *parax = ExtCMode_Table[i].get_param(chptr->mode.extmodeparam);
Addit(ExtCMode_Table[i].flag, parax);
} else {
Addsingle(ExtCMode_Table[i].flag);
}
}
}
#endif
/* now, if we had diffent para modes - this loop really could be done better, but */
/* do we have an difference? */
@ -5133,6 +5391,43 @@ CMD_FUNC(m_sjoin)
}
}
#ifdef EXTCMODE
/* Now, check for any param differences in extended channel modes..
* note that: oldmode.* = us, chptr->mode.* = them.
* if we win: copy oldmode to chptr mode, if they win: send the mode
*/
for (i=0; i <= ExtCMode_highest; i++)
{
if (ExtCMode_Table[i].flag && ExtCMode_Table[i].paracount &&
(oldmode.extmode & ExtCMode_Table[i].mode) &&
(chptr->mode.extmode & ExtCMode_Table[i].mode))
{
int r;
char *parax;
r = ExtCMode_Table[i].sjoin_check(chptr, oldmode.extmodeparam, chptr->mode.extmodeparam);
switch (r)
{
case EXSJ_WEWON:
parax = ExtCMode_Table[i].get_param(oldmode.extmodeparam);
Debug((DEBUG_DEBUG, "sjoin: we won: '%s'", parax));
chptr->mode.extmodeparam = ExtCMode_Table[i].put_param(oldmode.extmodeparam, parax);
break;
case EXSJ_THEYWON:
parax = ExtCMode_Table[i].get_param(chptr->mode.extmodeparam);
Debug((DEBUG_DEBUG, "sjoin: they won: '%s'", parax));
Addit(ExtCMode_Table[i].flag, parax);
break;
case EXSJ_SAME:
Debug((DEBUG_DEBUG, "sjoin: equal"));
break;
default:
ircd_log(LOG_ERROR, "channel.c:m_sjoin:param diff checker: got unk. retval 0x%x??", r);
break;
}
}
}
#endif
Addsingle('\0');
if (modebuf[1])
@ -5144,6 +5439,11 @@ CMD_FUNC(m_sjoin)
sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s %s",
sptr->name, chptr->chname, modebuf, parabuf);
}
#ifdef EXTCMODE
/* free the oldmode.* crap :( */
extcmode_free_paramlist(oldmode.extmodeparam);
oldmode.extmodeparam = NULL; /* just to be sure ;) */
#endif
}
/* we should be synched by now, */

222
src/extcmodes.c Normal file
View file

@ -0,0 +1,222 @@
/************************************************************************
* IRC - Internet Relay Chat, s_unreal.c
* (C) 2003 Bram Matthys (Syzop) and the UnrealIRCd Team
*
* See file AUTHORS in IRC package for additional names of
* the programmers.
*
* 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 "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "proto.h"
#include "channel.h"
#include "version.h"
#include <time.h>
#ifdef _WIN32
#include <sys/timeb.h>
#endif
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <fcntl.h>
#include "h.h"
#ifdef EXTCMODE
extern char cmodestring[512];
extern void make_cmodestr(void);
char extchmstr[4][64];
aExtCMtable *ExtCMode_Table = NULL;
unsigned short ExtCMode_highest = 0;
void make_extcmodestr()
{
char *p;
int i;
extchmstr[0][0] = extchmstr[1][0] = extchmstr[2][0] = extchmstr[3][0] = '\0';
/* type 1: lists (like b/e) */
/* [NOT IMPLEMENTED IN EXTCMODES] */
/* type 2: 1 par to set/unset */
/* [NOT IMPLEMENTED] */
/* type 3: 1 param to set, 0 params to unset */
p = extchmstr[2];
for (i=0; i <= ExtCMode_highest; i++)
if (ExtCMode_Table[i].paracount && ExtCMode_Table[i].flag)
*p++ = ExtCMode_Table[i].flag;
*p = '\0';
/* type 4: paramless modes */
p = extchmstr[3];
for (i=0; i <= ExtCMode_highest; i++)
if (!ExtCMode_Table[i].paracount && ExtCMode_Table[i].flag)
*p++ = ExtCMode_Table[i].flag;
*p = '\0';
printf("dect: %s/%s/%s/%s\n", extchmstr[0], extchmstr[1], extchmstr[2], extchmstr[3]);
}
void extcmode_init(void)
{
ExtCMode val = 1;
int i;
ExtCMode_Table = (aExtCMtable *)MyMalloc(sizeof(aExtCMtable) * EXTCMODETABLESZ);
bzero(ExtCMode_Table, sizeof(aExtCMtable) * EXTCMODETABLESZ);
for (i = 0; i < EXTCMODETABLESZ; i++)
{
ExtCMode_Table[i].mode = val;
val *= 2;
}
ExtCMode_highest = 0;
memset(&extchmstr, 0, sizeof(extchmstr));
}
ExtCMode extcmode_get(aExtCMtable *req)
{
short i = 0, j = 0;
ExtCMode tmp;
while (i < EXTCMODETABLESZ)
{
if (!ExtCMode_Table[i].flag)
break;
i++;
}
if (i == EXTCMODETABLESZ)
{
Debug((DEBUG_DEBUG, "extcmode_get failed, no space"));
return 0;
}
tmp = ExtCMode_Table[i].mode;
memcpy(&ExtCMode_Table[i], req, sizeof(aExtCMtable));
ExtCMode_Table[i].mode = tmp;
Debug((DEBUG_DEBUG, "extcmode_get(flag = '%c') returning %04x",
req->flag, ExtCMode_Table[i].mode));
/* Update extended channel mode table highest */
for (j = 0; j < EXTCMODETABLESZ; j++)
if (ExtCMode_Table[j].flag)
if (j > ExtCMode_highest)
ExtCMode_highest = j;
make_cmodestr();
make_extcmodestr();
return (ExtCMode_Table[i].mode);
}
int extcmode_delete(char ch)
{
int i = 0;
Debug((DEBUG_DEBUG, "extcmode_delete %c", ch));
/* TODO: remove from all channels */
while (i < EXTCMODETABLESZ)
{
if (ExtCMode_Table[i].flag == ch)
{
ExtCMode_Table[i].flag = '\0';
return 1;
}
i++;
}
return -1;
}
/** searches in chptr extmode parameters and returns entry or NULL. */
aExtCMtableParam *extcmode_get_struct(aExtCMtableParam *p, char ch)
{
while(p)
{
if (p->flag == ch)
return p;
p = p->next;
}
return NULL;
}
/* bit inefficient :/ */
aExtCMtableParam *extcmode_duplicate_paramlist(aExtCMtableParam *lst)
{
int i;
aExtCMtable *tbl;
aExtCMtableParam *head = NULL, *n;
while(lst)
{
tbl = NULL;
for (i=0; i <= ExtCMode_highest; i++)
{
if (ExtCMode_Table[i].flag == lst->flag)
{
tbl = &ExtCMode_Table[i]; /* & ? */
break;
}
}
n = tbl->dup_struct(lst);
if (head)
{
AddListItem(n, head);
} else {
head = n;
}
lst = lst->next;
}
return head;
}
void extcmode_free_paramlist(aExtCMtableParam *lst)
{
aExtCMtableParam *n; /* prolly not needed but I'm afraid of aliasing and stuff :p */
while(lst)
{
n = lst;
DelListItem(n, lst);
}
}
int extcmode_default_requirechop(aClient *cptr, aChannel *chptr, char *para, int checkt, int what)
{
if (IsPerson(cptr) && is_chan_op(cptr, chptr))
return 1;
return 0;
}
int extcmode_default_requirehalfop(aClient *cptr, aChannel *chptr, char *para, int checkt, int what)
{
if (IsPerson(cptr) &&
(is_chan_op(cptr, chptr) || is_half_op(cptr, chptr)))
return 1;
return 0;
}
#endif /* EXTCMODE */

View file

@ -856,6 +856,9 @@ int InitwIRCD(int argc, char *argv[])
setup_signals();
init_ircstats();
umode_init();
#ifdef EXTCMODE
extcmode_init();
#endif
clear_scache_hash_table();
#ifdef FORCE_CORE
corelim.rlim_cur = corelim.rlim_max = RLIM_INFINITY;
@ -1096,6 +1099,9 @@ int InitwIRCD(int argc, char *argv[])
load_tunefile();
make_umodestr();
make_cmodestr();
#ifdef EXTCMODE
make_extcmodestr();
#endif
if (!find_Command_simple("AWAY") || !find_Command_simple("KILL") ||
!find_Command_simple("OPER") || !find_Command_simple("PING"))
{

View file

@ -89,7 +89,8 @@ Module *Module_Find(char *name)
for (p = Modules; p; p = p->next)
{
if (!(p->flags & MODFLAG_TESTING) || (p->flags & MODFLAG_DELAYED))
if (!p->permanent &&
(!(p->flags & MODFLAG_TESTING) || (p->flags & MODFLAG_DELAYED)))
continue;
if (!strcmp(p->header->name, name))
{
@ -120,6 +121,7 @@ char *Module_Create(char *path_)
ModuleHeader *mod_header;
int ret = 0;
Module *mod = NULL, **Mod_Handle = NULL;
int *x;
int betaversion,tag;
Debug((DEBUG_DEBUG, "Attempting to load module from %s",
path_));
@ -166,6 +168,10 @@ char *Module_Create(char *path_)
return (NULL);
}
mod = (Module *)Module_make(mod_header, Mod);
irc_dlsym(Mod, "permanent_module", x);
if (x && (*x == 1))
mod->permanent = 1;
irc_dlsym(Mod, "Mod_Init", Mod_Init);
if (!Mod_Init)
{
@ -310,7 +316,7 @@ void Unload_all_loaded_modules(void)
for (mi = Modules; mi; mi = next)
{
next = mi->next;
if (!(mi->flags & MODFLAG_LOADED) || (mi->flags & MODFLAG_DELAYED))
if (!(mi->flags & MODFLAG_LOADED) || (mi->flags & MODFLAG_DELAYED) || mi->permanent)
continue;
irc_dlsym(mi->dll, "Mod_Unload", Mod_Unload);
if (Mod_Unload)
@ -703,12 +709,14 @@ int m_module(aClient *cptr, aClient *sptr, int parc, char *parv[])
}
for (mi = Modules; mi; mi = mi->next)
{
char delayed[32];
char tmp[256];
tmp[0] = '\0';
if (mi->flags & MODFLAG_DELAYED)
strcpy(delayed, "[Unloading]");
strcat(tmp, "[Unloading] ");
if (mi->permanent)
strcat(tmp, "[PERM] ");
sendto_one(sptr, ":%s NOTICE %s :*** %s - %s (%s) %s", me.name, sptr->name,
mi->header->name, mi->header->version, mi->header->description,
(mi->flags & MODFLAG_DELAYED) ? delayed : "");
mi->header->name, mi->header->version, mi->header->description, tmp);
}
return 1;
}

230
src/modules/m_chmodetst.c Normal file
View file

@ -0,0 +1,230 @@
/*
* Test for modulized channelmode system, adds 2 modes:
* +w (paramless)
* +y <0-100> (1 parameter)
*
* It's incomplete (like error signaling) but for testing purposes only.
*/
#include "config.h"
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "msg.h"
#include "proto.h"
#include "channel.h"
#include <time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <io.h>
#endif
#include <fcntl.h>
#include "h.h"
#ifdef STRIPBADWORDS
#include "badwords.h"
#endif
#ifdef _WIN32
#include "version.h"
#endif
#ifndef DYNAMIC_LINKING
ModuleHeader m_chmodetst_Header
#else
#define m_chmodetst_Header Mod_Header
ModuleHeader Mod_Header
#endif
= {
"chmodetst", /* Name of module */
"channelmode test", /* Version */
"channelmode +w", /* Short description of module */
"3.2-b8-1",
NULL,
};
ExtCMode EXTCMODE_TEST = 0L; /* Just for testing */
ExtCMode EXTCMODE_TEST2 = 0L; /* Just for testing */
int permanent_module = 1;
int modey_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int what);
aExtCMtableParam * modey_put_param(aExtCMtableParam *lst, char *para);
char *modey_get_param(aExtCMtableParam *lst);
char *modey_conv_param(char *param);
aExtCMtableParam * modey_free_param(aExtCMtableParam *lst);
aExtCMtableParam *modey_dup_struct(aExtCMtableParam *src);
int modey_sjoin_check(aChannel *chptr, aExtCMtableParam *ourx, aExtCMtableParam *theirx);
aExtCMtableParam *modey_dup_struct(aExtCMtableParam *src);
int modey_sjoin_check(aChannel *chptr, aExtCMtableParam *ourx, aExtCMtableParam *theirx);
typedef struct {
EXTCM_PAR_HEADER
short val;
} aModewentry;
/* The purpose of these ifdefs, are that we can "static" link the ircd if we
* want to
*/
/* This is called on module init, before Server Ready */
#ifdef DYNAMIC_LINKING
DLLFUNC int Mod_Init(ModuleInfo *modinfo)
#else
int m_dummy_Init(ModuleInfo *modinfo)
#endif
{
aExtCMtable req;
ircd_log(LOG_ERROR, "debug: mod_init called from chmodetst module");
sendto_realops("chmodetst loading...");
/* TODO: load mode here */
/* +w doesn't do anything, it's just for testing */
memset(&req, 0, sizeof(req));
req.paracount = 0;
req.is_ok = extcmode_default_requirechop;
req.flag = 'w';
EXTCMODE_TEST = extcmode_get(&req);
/* +y doesn't do anything except that you can set/unset it with a
* numeric parameter (1-100)
*/
memset(&req, 0, sizeof(req));
req.paracount = 1;
req.is_ok = modey_is_ok;
req.put_param = modey_put_param;
req.get_param = modey_get_param;
req.conv_param = modey_conv_param;
req.free_param = modey_free_param;
req.sjoin_check = modey_sjoin_check;
req.dup_struct = modey_dup_struct;
req.flag = 'y';
EXTCMODE_TEST2 = extcmode_get(&req);
return MOD_SUCCESS;
}
/* Is first run when server is 100% ready */
#ifdef DYNAMIC_LINKING
DLLFUNC int Mod_Load(int module_load)
#else
int m_dummy_Load(int module_load)
#endif
{
return MOD_SUCCESS;
}
/* Called when module is unloaded */
#ifdef DYNAMIC_LINKING
DLLFUNC int Mod_Unload(int module_unload)
#else
int m_dummy_Unload(int module_unload)
#endif
{
/* Aaaaaaaargh... we are assumed to be a permanent module */
sendto_realops("Mod_Unload was called??? Arghhhhhh..");
return MOD_FAILED;
}
int modey_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int what)
{
short t;
if ((checkt == EXCHK_ACCESS) || (checkt == EXCHK_ACCESS_ERR))
{
if (!is_chan_op(sptr, chptr))
{
if (checkt == EXCHK_ACCESS_ERR)
sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED), me.name, sptr->name, chptr->chname);
return 0;
} else {
return 1;
}
} else
if (checkt == EXCHK_PARAM)
{
t = (short)atoi(para);
if ((t < 0) || (t > 100))
{
sendto_one(sptr, ":%s NOTICE %s :chanmode +y requires a parameter in the range 0..100",
me.name, sptr->name);
return 0;
}
return 1;
}
return 0;
}
aExtCMtableParam * modey_put_param(aExtCMtableParam *lst, char *para)
{
aModewentry *r;
r = (aModewentry *)extcmode_get_struct(lst, 'y');
Debug((DEBUG_DEBUG, "modey_put_param: get_struct returned 0x%x", r));
if (!r)
{
/* Need to create one */
r = (aModewentry *)malloc(sizeof(aModewentry));
memset(r, 0, sizeof(aModewentry));
r->flag = 'y';
AddListItem(r, lst);
}
r->val = (short)atoi(para);
return lst;
}
char *modey_get_param(aExtCMtableParam *lst)
{
aModewentry *r;
static char tmpret[16];
r = (aModewentry *)extcmode_get_struct(lst, 'y');
if (!r)
return NULL;
sprintf(tmpret, "%hu", r->val);
return tmpret;
}
/* no this is not useless, imagine the parameter "1blah" :P */
char *modey_conv_param(char *param)
{
short i;
static char tmpret2[16];
i = (short)atoi(param);
sprintf(tmpret2, "%hu", i);
return tmpret2;
}
aExtCMtableParam * modey_free_param(aExtCMtableParam *lst)
{
aModewentry *r;
r = (aModewentry *)extcmode_get_struct(lst, 'y');
Debug((DEBUG_DEBUG, "modey_free_param: lst=0x%x, r=0x%x", lst, r));
if (r)
{
DelListItem(r, lst);
free(r);
}
Debug((DEBUG_DEBUG, "modey_free_param: returning 0x%x", lst));
return lst;
}
aExtCMtableParam *modey_dup_struct(aExtCMtableParam *src)
{
aModewentry *n = (aModewentry *)malloc(sizeof(aModewentry));
memcpy(n, src, sizeof(aModewentry));
return (aExtCMtableParam *)n;
}
int modey_sjoin_check(aChannel *chptr, aExtCMtableParam *ourx, aExtCMtableParam *theirx)
{
aModewentry *our = (aModewentry *)ourx;
aModewentry *their = (aModewentry *)theirx;
if (our->val == their->val)
return EXSJ_SAME;
if (our->val > their->val)
return EXSJ_WEWON;
else
return EXSJ_THEYWON;
}

View file

@ -85,6 +85,9 @@ char serveropts[] = {
#endif
#ifdef ZIP_LINKS
'Z',
#endif
#ifdef EXTCMODE
'E',
#endif
'\0'
};

View file

@ -1065,13 +1065,16 @@ CMD_FUNC(m_server_remote)
*/
void send_proto(aClient *cptr, ConfigItem_link *aconf)
{
char buf[512];
sprintf(buf, "CHANMODES=%s%s,%s%s,%s%s,%s%s",
CHPAR1, EXPAR1, CHPAR2, EXPAR2, CHPAR3, EXPAR3, CHPAR4, EXPAR4);
#ifdef ZIP_LINKS
if (aconf->options & CONNECT_ZIP)
{
sendto_one(cptr, "PROTOCTL %s ZIP", PROTOCTL_SERVER);
sendto_one(cptr, "PROTOCTL %s ZIP %s", PROTOCTL_SERVER, buf);
} else {
#endif
sendto_one(cptr, "PROTOCTL %s", PROTOCTL_SERVER);
sendto_one(cptr, "PROTOCTL %s %s", PROTOCTL_SERVER, buf);
#ifdef ZIP_LINKS
}
#endif