Add moddata_localclient(), which is for locally connected clients only.

Make the silence module use this.
This commit is contained in:
Bram Matthys 2019-09-15 09:20:12 +02:00
parent 654919f2c4
commit b2f32c1746
No known key found for this signature in database
GPG key ID: BF8116B163EAAE98
6 changed files with 110 additions and 19 deletions

View file

@ -231,15 +231,17 @@
#endif
/* Maximum number of ModData objects that may be attached to an object */
/* UnrealIRCd 4.0.0 - 4.0.13: 8, 8, 4, 4
* UnrealIRCd 4.0.14+ : 12, 8, 4, 4
/* UnrealIRCd 4.0.0 - 4.0.13: 8, 8, 4, 4
* UnrealIRCd 4.0.14+ : 12, 8, 4, 4
* UnrealIRCd 5.0.0 : 12, 8, 8, 4, 4, 500, 500
*/
#define MODDATA_MAX_CLIENT 12
#define MODDATA_MAX_CHANNEL 8
#define MODDATA_MAX_MEMBER 4
#define MODDATA_MAX_MEMBERSHIP 4
#define MODDATA_MAX_LOCALVAR 500
#define MODDATA_MAX_GLOBALVAR 500
#define MODDATA_MAX_CLIENT 12
#define MODDATA_MAX_LOCALCLIENT 8
#define MODDATA_MAX_CHANNEL 8
#define MODDATA_MAX_MEMBER 4
#define MODDATA_MAX_MEMBERSHIP 4
#define MODDATA_MAX_LOCALVAR 500
#define MODDATA_MAX_GLOBALVAR 500
/* If EXPERIMENTAL is #define'd then all users will receive a notice about
* this when they connect, along with a pointer to bugs.unrealircd.org where

View file

@ -128,7 +128,15 @@ typedef struct {
Module *owner; /**< Module that owns this snomask */
} Snomask;
typedef enum ModDataType { MODDATATYPE_LOCALVAR=1, MODDATATYPE_GLOBALVAR=2, MODDATATYPE_CLIENT=3, MODDATATYPE_CHANNEL=4, MODDATATYPE_MEMBER=5, MODDATATYPE_MEMBERSHIP=6 } ModDataType;
typedef enum ModDataType {
MODDATATYPE_LOCALVAR = 1,
MODDATATYPE_GLOBALVAR = 2,
MODDATATYPE_CLIENT = 3,
MODDATATYPE_LOCALCLIENT = 4,
MODDATATYPE_CHANNEL = 5,
MODDATATYPE_MEMBER = 6,
MODDATATYPE_MEMBERSHIP = 7,
} ModDataType;
typedef struct ModDataInfo ModDataInfo;
@ -146,6 +154,7 @@ struct ModDataInfo {
};
#define moddata_client(acptr, md) acptr->moddata[md->slot]
#define moddata_localclient(acptr, md) acptr->local->moddata[md->slot]
#define moddata_channel(chptr, md) chptr->moddata[md->slot]
#define moddata_member(m, md) m->moddata[md->slot]
#define moddata_membership(m, md) m->moddata[md->slot]
@ -795,12 +804,15 @@ extern void CommandOverrideDel(CommandOverride *ovr);
extern int CallCommandOverride(CommandOverride *ovr, Client *cptr, Client *sptr, MessageTag *mtags, int parc, char *parv[]);
extern void moddata_free_client(Client *acptr);
extern void moddata_free_localclient(Client *acptr);
extern void moddata_free_channel(Channel *chptr);
extern void moddata_free_member(Member *m);
extern void moddata_free_membership(Membership *m);
extern ModDataInfo *findmoddata_byname(char *name, ModDataType type);
extern int moddata_client_set(Client *acptr, char *varname, char *value);
extern char *moddata_client_get(Client *acptr, char *varname);
extern int moddata_localclient_set(Client *acptr, char *varname, char *value);
extern char *moddata_localclient_get(Client *acptr, char *varname);
extern int LoadPersistentPointerX(ModuleInfo *modinfo, char *varshortname, void **var, void (*free_variable)(ModData *m));
#define LoadPersistentPointer(modinfo, var, free_variable) LoadPersistentPointerX(modinfo, #var, (void **)&var, free_variable)

View file

@ -979,6 +979,7 @@ struct LocalClient {
char *sni_servername; /**< Servername as sent by client via SNI (Server Name Indication) in SSL/TLS, otherwise NULL */
int cap_protocol; /**< CAP protocol in use. At least 300 for any CAP capable client. 302 for 3.2, etc.. */
int identbufcnt; /**< Counter for 'ident' reading code */
ModData moddata[MODDATA_MAX_LOCALCLIENT]; /**< LocalClient attached module data, used by the ModData system */
};
/** User information (persons, not servers), you use sptr->user to access these (see also @link Client @endlink).

View file

@ -60,6 +60,7 @@ ModDataInfo *ModDataAdd(Module *module, ModDataInfo req)
if (((req.type == MODDATATYPE_LOCALVAR) && (slotav >= MODDATA_MAX_LOCALVAR)) ||
((req.type == MODDATATYPE_GLOBALVAR) && (slotav >= MODDATA_MAX_GLOBALVAR)) ||
((req.type == MODDATATYPE_CLIENT) && (slotav >= MODDATA_MAX_CLIENT)) ||
((req.type == MODDATATYPE_LOCALCLIENT) && (slotav >= MODDATA_MAX_LOCALCLIENT)) ||
((req.type == MODDATATYPE_CHANNEL) && (slotav >= MODDATA_MAX_CHANNEL)) ||
((req.type == MODDATATYPE_MEMBER) && (slotav >= MODDATA_MAX_MEMBER)) ||
((req.type == MODDATATYPE_MEMBERSHIP) && (slotav >= MODDATA_MAX_MEMBERSHIP)))
@ -98,7 +99,7 @@ moddataadd_isok:
void moddata_free_client(Client *acptr)
{
ModDataInfo *md;
ModDataInfo *md;
for (md = MDInfo; md; md = md->next)
if (md->type == MODDATATYPE_CLIENT)
@ -110,10 +111,24 @@ ModDataInfo *md;
memset(acptr->moddata, 0, sizeof(acptr->moddata));
}
void moddata_free_localclient(Client *acptr)
{
ModDataInfo *md;
for (md = MDInfo; md; md = md->next)
if (md->type == MODDATATYPE_LOCALCLIENT)
{
if (md->free && moddata_localclient(acptr, md).ptr)
md->free(&moddata_localclient(acptr, md));
}
memset(acptr->moddata, 0, sizeof(acptr->moddata));
}
// FIXME: this is never called
void moddata_free_channel(Channel *chptr)
{
ModDataInfo *md;
ModDataInfo *md;
for (md = MDInfo; md; md = md->next)
if (md->type == MODDATATYPE_CHANNEL)
@ -127,7 +142,7 @@ ModDataInfo *md;
void moddata_free_member(Member *m)
{
ModDataInfo *md;
ModDataInfo *md;
for (md = MDInfo; md; md = md->next)
if (md->type == MODDATATYPE_MEMBER)
@ -171,16 +186,25 @@ void unload_moddata_commit(ModDataInfo *md)
case MODDATATYPE_CLIENT:
{
Client *acptr;
list_for_each_entry(acptr, &lclient_list, lclient_node)
list_for_each_entry(acptr, &client_list, client_node)
{
if (md->free && moddata_client(acptr, md).ptr)
{
md->free(&moddata_client(acptr, md));
}
memset(&moddata_client(acptr, md), 0, sizeof(ModData));
}
break;
}
case MODDATATYPE_LOCALCLIENT:
{
Client *acptr;
list_for_each_entry(acptr, &lclient_list, lclient_node)
{
if (md->free && moddata_localclient(acptr, md).ptr)
md->free(&moddata_localclient(acptr, md));
memset(&moddata_localclient(acptr, md), 0, sizeof(ModData));
}
break;
}
case MODDATATYPE_CHANNEL:
{
Channel *chptr;
@ -333,6 +357,56 @@ char *moddata_client_get(Client *acptr, char *varname)
return md->serialize(&moddata_client(acptr, md)); /* can be NULL */
}
/** Set ModData for LocalClient (via variable name, string value) */
int moddata_localclient_set(Client *acptr, char *varname, char *value)
{
ModDataInfo *md;
if (!MyConnect(acptr))
abort();
md = findmoddata_byname(varname, MODDATATYPE_LOCALCLIENT);
if (!md)
return 0;
if (value)
{
/* SET */
md->unserialize(value, &moddata_localclient(acptr, md));
}
else
{
/* UNSET */
md->free(&moddata_localclient(acptr, md));
memset(&moddata_localclient(acptr, md), 0, sizeof(ModData));
}
/* If 'sync' field is set and the client is not in pre-registered
* state then broadcast the new setting.
*/
if (md->sync && (IsUser(acptr) || IsServer(acptr) || IsMe(acptr)))
broadcast_md_client_cmd(NULL, &me, acptr, md->name, value);
return 1;
}
/** Get ModData for LocalClient (via variable name) */
char *moddata_localclient_get(Client *acptr, char *varname)
{
ModDataInfo *md;
if (!MyConnect(acptr))
abort();
md = findmoddata_byname(varname, MODDATATYPE_LOCALCLIENT);
if (!md)
return NULL;
return md->serialize(&moddata_localclient(acptr, md)); /* can be NULL */
}
/** Set localvar or globalvar moddata (via variable name, string value) */
int moddata_localvar_set(char *varname, char *value)
{

View file

@ -495,6 +495,8 @@ static void exit_one_client(Client *sptr, MessageTag *mtags_i, const char *comme
/* Free module related data for this client */
moddata_free_client(sptr);
if (MyConnect(sptr))
moddata_free_localclient(sptr);
/* Remove sptr from the client list */
if (*sptr->id)

View file

@ -46,7 +46,7 @@ struct Silence
ModDataInfo *silence_md = NULL;
/* Macros */
#define SILENCELIST(x) ((Silence *)moddata_client(x, silence_md).ptr)
#define SILENCELIST(x) ((Silence *)moddata_localclient(x, silence_md).ptr)
/* Forward declarations */
int _is_silenced(Client *, Client *);
@ -71,7 +71,7 @@ MOD_INIT()
memset(&mreq, 0, sizeof(mreq));
mreq.name = "silence";
mreq.type = MODDATATYPE_CLIENT;
mreq.type = MODDATATYPE_LOCALCLIENT;
mreq.free = silence_md_free;
silence_md = ModDataAdd(modinfo->handle, mreq);
if (!silence_md)
@ -159,7 +159,7 @@ int _del_silence(Client *sptr, const char *mask)
{
if (mycmp(mask, s->mask) == 0)
{
DelListItemUnchecked(s, moddata_client(sptr, silence_md).ptr);
DelListItemUnchecked(s, moddata_localclient(sptr, silence_md).ptr);
safe_free(s);
return 1;
}
@ -199,7 +199,7 @@ int _add_silence(Client *sptr, const char *mask, int senderr)
/* Add the new entry */
s = safe_alloc(sizeof(Silence)+strlen(mask));
strcpy(s->mask, mask); /* safe, allocated above */
AddListItemUnchecked(s, moddata_client(sptr, silence_md).ptr);
AddListItemUnchecked(s, moddata_localclient(sptr, silence_md).ptr);
return 0;
}