mirror of https://github.com/pissnet/pissircd.git
318 lines
6.8 KiB
C
318 lines
6.8 KiB
C
/*
|
|
* Example module for ModData usage
|
|
* NEVER LOAD THIS ON A LIVE SERVER!!
|
|
*
|
|
* (C) Copyright 2014 Bram Matthys and the UnrealIRCd team
|
|
* License: GPLv2
|
|
*/
|
|
|
|
#include "unrealircd.h"
|
|
|
|
CMD_FUNC(cmd_mdex);
|
|
|
|
ModuleHeader MOD_HEADER
|
|
= {
|
|
"mdex",
|
|
"5.0",
|
|
"Command /MDEX",
|
|
"UnrealIRCd Team",
|
|
"unrealircd-5",
|
|
};
|
|
|
|
ModDataInfo *mdex_cli = NULL, *mdex_chan = NULL, *mdex_member = NULL, *mdex_membership = NULL;
|
|
void mdex_free(ModData *m);
|
|
char *mdex_serialize(ModData *m);
|
|
void mdex_unserialize(char *str, ModData *m);
|
|
|
|
MOD_INIT()
|
|
{
|
|
ModDataInfo mreq;
|
|
|
|
memset(&mreq, 0, sizeof(mreq));
|
|
mreq.name = "mdex";
|
|
mreq.free = mdex_free;
|
|
mreq.serialize = mdex_serialize;
|
|
mreq.unserialize = mdex_unserialize;
|
|
mreq.sync = 1;
|
|
mreq.type = MODDATATYPE_CLIENT;
|
|
mdex_cli = ModDataAdd(modinfo->handle, mreq);
|
|
if (!mdex_cli)
|
|
abort();
|
|
mreq.type = MODDATATYPE_CHANNEL;
|
|
mdex_chan = ModDataAdd(modinfo->handle, mreq);
|
|
if (!mdex_cli)
|
|
abort();
|
|
mreq.type = MODDATATYPE_MEMBER;
|
|
mdex_member = ModDataAdd(modinfo->handle, mreq);
|
|
if (!mdex_cli)
|
|
abort();
|
|
mreq.type = MODDATATYPE_MEMBERSHIP;
|
|
mdex_membership = ModDataAdd(modinfo->handle, mreq);
|
|
if (!mdex_cli)
|
|
abort();
|
|
|
|
CommandAdd(modinfo->handle, "MDEX", cmd_mdex, MAXPARA, CMD_USER);
|
|
|
|
return MOD_SUCCESS;
|
|
}
|
|
|
|
MOD_LOAD()
|
|
{
|
|
return MOD_SUCCESS;
|
|
}
|
|
|
|
|
|
MOD_UNLOAD()
|
|
{
|
|
return MOD_SUCCESS;
|
|
}
|
|
|
|
CMD_FUNC(cmd_mdex)
|
|
{
|
|
char *action, *type, *objname, *varname, *value;
|
|
ModDataInfo *md;
|
|
|
|
if (!IsOper(client) || (parc < 5) || BadPtr(parv[4]))
|
|
return 0;
|
|
|
|
action = parv[1]; /* get / set */
|
|
type = parv[2];
|
|
objname = parv[3];
|
|
#ifdef DEBUGMODE
|
|
varname = parv[4];
|
|
#else
|
|
varname = "mdex";
|
|
#endif
|
|
value = parv[5]; /* may be NULL */
|
|
|
|
if (!strcmp(action, "set"))
|
|
{
|
|
if (!strcmp(type, "client"))
|
|
{
|
|
Client *target = find_client(objname, NULL);
|
|
md = findmoddata_byname(varname, MODDATATYPE_CLIENT);
|
|
if (!md || !md->unserialize || !md->free || !target)
|
|
return 0;
|
|
if (value)
|
|
md->unserialize(value, &moddata_client(target, md));
|
|
else
|
|
{
|
|
md->free(&moddata_client(target, md));
|
|
memset(&moddata_client(target, md), 0, sizeof(ModData));
|
|
}
|
|
broadcast_md_client(md, target, &moddata_client(target, md));
|
|
} else
|
|
if (!strcmp(type, "channel"))
|
|
{
|
|
Channel *channel = find_channel(objname, NULL);
|
|
md = findmoddata_byname(varname, MODDATATYPE_CHANNEL);
|
|
if (!md || !md->unserialize || !md->free || !channel)
|
|
return 0;
|
|
if (value)
|
|
md->unserialize(value, &moddata_channel(channel, md));
|
|
else
|
|
{
|
|
md->free(&moddata_channel(channel, md));
|
|
memset(&moddata_channel(channel, md), 0, sizeof(ModData));
|
|
}
|
|
broadcast_md_channel(md, channel, &moddata_channel(channel, md));
|
|
} else
|
|
if (!strcmp(type, "member"))
|
|
{
|
|
Client *target;
|
|
Channel *channel;
|
|
Member *m;
|
|
char *p;
|
|
|
|
/* for member the object name is like '#channel/Syzop' */
|
|
p = strchr(objname, ':');
|
|
if (!p)
|
|
return 0;
|
|
*p++ = '\0';
|
|
|
|
channel = find_channel(objname, NULL);
|
|
if (!channel)
|
|
return 0;
|
|
|
|
target = find_person(p, NULL);
|
|
if (!target)
|
|
return 0;
|
|
|
|
m = find_member_link(channel->members, target);
|
|
if (!m)
|
|
return 0;
|
|
|
|
md = findmoddata_byname(varname, MODDATATYPE_MEMBER);
|
|
if (!md || !md->unserialize || !md->free)
|
|
return 0;
|
|
|
|
if (value)
|
|
md->unserialize(value, &moddata_member(m, md));
|
|
else
|
|
{
|
|
md->free(&moddata_member(m, md));
|
|
memset(&moddata_member(m, md), 0, sizeof(ModData));
|
|
}
|
|
broadcast_md_member(md, channel, m, &moddata_member(m, md));
|
|
} else
|
|
if (!strcmp(type, "membership"))
|
|
{
|
|
Client *target;
|
|
Channel *channel;
|
|
Membership *m;
|
|
char *p;
|
|
|
|
/* for membership the object name is like 'Syzop/#channel' */
|
|
p = strchr(objname, ':');
|
|
if (!p)
|
|
return 0;
|
|
*p++ = '\0';
|
|
|
|
target = find_person(objname, NULL);
|
|
if (!target)
|
|
return 0;
|
|
|
|
channel = find_channel(p, NULL);
|
|
if (!channel)
|
|
return 0;
|
|
|
|
m = find_membership_link(target->user->channel, channel);
|
|
if (!m)
|
|
return 0;
|
|
|
|
md = findmoddata_byname(varname, MODDATATYPE_MEMBERSHIP);
|
|
if (!md || !md->unserialize || !md->free)
|
|
return 0;
|
|
|
|
if (value)
|
|
md->unserialize(value, &moddata_membership(m, md));
|
|
else
|
|
{
|
|
md->free(&moddata_membership(m, md));
|
|
memset(&moddata_membership(m, md), 0, sizeof(ModData));
|
|
}
|
|
broadcast_md_membership(md, target, m, &moddata_membership(m, md));
|
|
}
|
|
} else
|
|
if (!strcmp(action, "get"))
|
|
{
|
|
if (!strcmp(type, "client"))
|
|
{
|
|
Client *target = find_client(objname, NULL);
|
|
char *str;
|
|
|
|
md = findmoddata_byname(varname, MODDATATYPE_CLIENT);
|
|
if (!md || !md->serialize || !target)
|
|
return 0;
|
|
str = md->serialize(&moddata_client(target, md));
|
|
if (str)
|
|
sendnotice(client, "Value: %s", str ? str : "<null>");
|
|
else
|
|
sendnotice(client, "No value set");
|
|
} else
|
|
if (!strcmp(type, "channel"))
|
|
{
|
|
Channel *channel = find_channel(objname, NULL);
|
|
char *str;
|
|
|
|
md = findmoddata_byname(varname, MODDATATYPE_CHANNEL);
|
|
if (!md || !md->serialize || !channel)
|
|
return 0;
|
|
str = md->serialize(&moddata_channel(channel, md));
|
|
if (str)
|
|
sendnotice(client, "Value: %s", str ? str : "<null>");
|
|
else
|
|
sendnotice(client, "No value set");
|
|
} else
|
|
if (!strcmp(type, "member"))
|
|
{
|
|
Client *target;
|
|
Channel *channel;
|
|
Member *m;
|
|
char *p, *str;
|
|
|
|
/* for member the object name is like '#channel/Syzop' */
|
|
p = strchr(objname, ':');
|
|
if (!p)
|
|
return 0;
|
|
*p++ = '\0';
|
|
|
|
channel = find_channel(objname, NULL);
|
|
if (!channel)
|
|
return 0;
|
|
|
|
target = find_person(p, NULL);
|
|
if (!target)
|
|
return 0;
|
|
|
|
m = find_member_link(channel->members, target);
|
|
if (!m)
|
|
return 0;
|
|
|
|
md = findmoddata_byname(varname, MODDATATYPE_MEMBER);
|
|
if (!md || !md->serialize)
|
|
return 0;
|
|
|
|
str = md->serialize(&moddata_member(m, md));
|
|
if (str)
|
|
sendnotice(client, "Value: %s", str ? str : "<null>");
|
|
else
|
|
sendnotice(client, "No value set");
|
|
} else
|
|
if (!strcmp(type, "membership"))
|
|
{
|
|
Client *target;
|
|
Channel *channel;
|
|
Membership *m;
|
|
char *p, *str;
|
|
|
|
/* for membership the object name is like 'Syzop/#channel' */
|
|
p = strchr(objname, ':');
|
|
if (!p)
|
|
return 0;
|
|
*p++ = '\0';
|
|
|
|
target = find_person(objname, NULL);
|
|
if (!target)
|
|
return 0;
|
|
|
|
channel = find_channel(p, NULL);
|
|
if (!channel)
|
|
return 0;
|
|
|
|
m = find_membership_link(target->user->channel, channel);
|
|
if (!m)
|
|
return 0;
|
|
|
|
md = findmoddata_byname(varname, MODDATATYPE_MEMBERSHIP);
|
|
if (!md || !md->serialize)
|
|
return 0;
|
|
|
|
str = md->serialize(&moddata_membership(m, md));
|
|
if (str)
|
|
sendnotice(client, "Value: %s", str ? str : "<null>");
|
|
else
|
|
sendnotice(client, "No value set");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void mdex_free(ModData *m)
|
|
{
|
|
safe_free(m->str);
|
|
}
|
|
|
|
char *mdex_serialize(ModData *m)
|
|
{
|
|
if (!m->str)
|
|
return NULL;
|
|
return m->str;
|
|
}
|
|
|
|
void mdex_unserialize(char *str, ModData *m)
|
|
{
|
|
safe_strdup(m->str, str);
|
|
}
|