Add user metadata.
This commit is contained in:
parent
ee36f72f5d
commit
fb87421d0e
|
@ -84,6 +84,8 @@ struct User
|
||||||
char *away; /* pointer to away message */
|
char *away; /* pointer to away message */
|
||||||
int refcnt; /* Number of times this block is referenced */
|
int refcnt; /* Number of times this block is referenced */
|
||||||
|
|
||||||
|
struct Dictionary *metadata;
|
||||||
|
|
||||||
char suser[NICKLEN+1];
|
char suser[NICKLEN+1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -311,6 +313,12 @@ struct ListClient
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Metadata
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
const char *value;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* status macros.
|
* status macros.
|
||||||
*/
|
*/
|
||||||
|
@ -613,4 +621,8 @@ extern char *generate_uid(void);
|
||||||
void allocate_away(struct Client *);
|
void allocate_away(struct Client *);
|
||||||
void free_away(struct Client *);
|
void free_away(struct Client *);
|
||||||
|
|
||||||
|
extern struct Metadata *user_metadata_add(struct Client *target, const char *name, const char *value, int propegate);
|
||||||
|
extern void user_metadata_delete(struct Client *target, const char *name, int propegate);
|
||||||
|
extern struct Metadata *user_metadata_find(struct Client *target, const char *name);
|
||||||
|
|
||||||
#endif /* INCLUDED_client_h */
|
#endif /* INCLUDED_client_h */
|
||||||
|
|
|
@ -42,6 +42,7 @@ CORE_SRCS = \
|
||||||
core/m_kick.c \
|
core/m_kick.c \
|
||||||
core/m_kill.c \
|
core/m_kill.c \
|
||||||
core/m_message.c \
|
core/m_message.c \
|
||||||
|
core/m_metadata.c \
|
||||||
core/m_mode.c \
|
core/m_mode.c \
|
||||||
core/m_nick.c \
|
core/m_nick.c \
|
||||||
core/m_part.c \
|
core/m_part.c \
|
||||||
|
|
91
src/client.c
91
src/client.c
|
@ -1659,6 +1659,7 @@ struct User *
|
||||||
make_user(struct Client *client_p)
|
make_user(struct Client *client_p)
|
||||||
{
|
{
|
||||||
struct User *user;
|
struct User *user;
|
||||||
|
struct Dictionary *metadata;
|
||||||
|
|
||||||
user = client_p->user;
|
user = client_p->user;
|
||||||
if(!user)
|
if(!user)
|
||||||
|
@ -1666,6 +1667,9 @@ make_user(struct Client *client_p)
|
||||||
user = (struct User *) rb_bh_alloc(user_heap);
|
user = (struct User *) rb_bh_alloc(user_heap);
|
||||||
user->refcnt = 1;
|
user->refcnt = 1;
|
||||||
client_p->user = user;
|
client_p->user = user;
|
||||||
|
|
||||||
|
metadata = irc_dictionary_create(irccmp);
|
||||||
|
client_p->user->metadata = metadata;
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
@ -1705,10 +1709,19 @@ free_user(struct User *user, struct Client *client_p)
|
||||||
{
|
{
|
||||||
free_away(client_p);
|
free_away(client_p);
|
||||||
|
|
||||||
|
/* get rid of any metadata the user may have */
|
||||||
|
if(IsOper(client_p))
|
||||||
|
{
|
||||||
|
user_metadata_delete(client_p, "swhois", 0);
|
||||||
|
user_metadata_delete(client_p, "operstring", 0);
|
||||||
|
}
|
||||||
|
user_metadata_delete(client_p, "OACCEPT", 0);
|
||||||
|
|
||||||
if(--user->refcnt <= 0)
|
if(--user->refcnt <= 0)
|
||||||
{
|
{
|
||||||
if(user->away)
|
if(user->away)
|
||||||
rb_free((char *) user->away);
|
rb_free((char *) user->away);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sanity check
|
* sanity check
|
||||||
*/
|
*/
|
||||||
|
@ -1924,3 +1937,81 @@ error_exit_client(struct Client *client_p, int error)
|
||||||
|
|
||||||
exit_client(client_p, client_p, &me, errmsg);
|
exit_client(client_p, client_p, &me, errmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* user_metadata_add
|
||||||
|
*
|
||||||
|
* inputs - pointer to client struct
|
||||||
|
* - name of metadata item you wish to add
|
||||||
|
* - value of metadata item
|
||||||
|
* - 1 if metadata should be propegated, 0 if not
|
||||||
|
* output - none
|
||||||
|
* side effects - metadata is added to the user in question
|
||||||
|
* - metadata is propegated if propegate is set.
|
||||||
|
*/
|
||||||
|
struct Metadata *
|
||||||
|
user_metadata_add(struct Client *target, const char *name, const char *value, int propegate)
|
||||||
|
{
|
||||||
|
struct Metadata *md;
|
||||||
|
|
||||||
|
if(irc_dictionary_find(target->user->metadata, name) != NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
md = rb_malloc(sizeof(struct Metadata));
|
||||||
|
md->name = rb_strdup(name);
|
||||||
|
md->value = rb_strdup(value);
|
||||||
|
|
||||||
|
irc_dictionary_add(target->user->metadata, md->name, md);
|
||||||
|
|
||||||
|
if(propegate)
|
||||||
|
sendto_match_servs(&me, "*", CAP_ENCAP, NOCAPS, "ENCAP * METADATA ADD %s %s :%s",
|
||||||
|
target->name, name, value);
|
||||||
|
|
||||||
|
return md;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* user_metadata_delete
|
||||||
|
*
|
||||||
|
* inputs - pointer to client struct
|
||||||
|
* - name of metadata item you wish to delete
|
||||||
|
* output - none
|
||||||
|
* side effects - metadata is deleted from the user in question
|
||||||
|
* - deletion is propegated if propegate is set
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
user_metadata_delete(struct Client *target, const char *name, int propegate)
|
||||||
|
{
|
||||||
|
struct Metadata *md = user_metadata_find(target, name);
|
||||||
|
|
||||||
|
if(!md)
|
||||||
|
return;
|
||||||
|
|
||||||
|
irc_dictionary_delete(target->user->metadata, md->name);
|
||||||
|
|
||||||
|
rb_free(md);
|
||||||
|
|
||||||
|
if(propegate)
|
||||||
|
sendto_match_servs(&me, "*", CAP_ENCAP, NOCAPS, "ENCAP * METADATA DELETE %s %s",
|
||||||
|
target->name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* user_metadata_find
|
||||||
|
*
|
||||||
|
* inputs - pointer to client struct
|
||||||
|
* - name of metadata item you wish to read
|
||||||
|
* output - the requested metadata, if it exists, elsewise null.
|
||||||
|
* side effects -
|
||||||
|
*/
|
||||||
|
struct Metadata *
|
||||||
|
user_metadata_find(struct Client *target, const char *name)
|
||||||
|
{
|
||||||
|
if(!target->user)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(!target->user->metadata)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return irc_dictionary_retrieve(target->user->metadata, name);
|
||||||
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ static const char *core_module_table[] = {
|
||||||
"m_kick",
|
"m_kick",
|
||||||
"m_kill",
|
"m_kill",
|
||||||
"m_message",
|
"m_message",
|
||||||
|
"m_metadata",
|
||||||
"m_mode",
|
"m_mode",
|
||||||
"m_nick",
|
"m_nick",
|
||||||
"m_part",
|
"m_part",
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include "msg.h"
|
#include "msg.h"
|
||||||
#include "reject.h"
|
#include "reject.h"
|
||||||
#include "sslproc.h"
|
#include "sslproc.h"
|
||||||
|
#include "irc_dictionary.h"
|
||||||
|
|
||||||
#ifndef INADDR_NONE
|
#ifndef INADDR_NONE
|
||||||
#define INADDR_NONE ((unsigned int) 0xffffffff)
|
#define INADDR_NONE ((unsigned int) 0xffffffff)
|
||||||
|
@ -469,6 +470,8 @@ burst_TS6(struct Client *client_p)
|
||||||
char *t;
|
char *t;
|
||||||
int tlen, mlen;
|
int tlen, mlen;
|
||||||
int cur_len = 0;
|
int cur_len = 0;
|
||||||
|
struct Metadata *md;
|
||||||
|
struct DictionaryIter iter;
|
||||||
|
|
||||||
hclientinfo.client = hchaninfo.client = client_p;
|
hclientinfo.client = hchaninfo.client = client_p;
|
||||||
|
|
||||||
|
@ -520,6 +523,12 @@ burst_TS6(struct Client *client_p)
|
||||||
use_id(target_p), target_p->user->suser);
|
use_id(target_p), target_p->user->suser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DICTIONARY_FOREACH(md, &iter, target_p->user->metadata)
|
||||||
|
{
|
||||||
|
sendto_one(client_p, ":%s ENCAP * METADATA %s %s :%s",
|
||||||
|
use_id(target_p), use_id(target_p), md->name, md->value);
|
||||||
|
}
|
||||||
|
|
||||||
if(ConfigFileEntry.burst_away && !EmptyString(target_p->user->away))
|
if(ConfigFileEntry.burst_away && !EmptyString(target_p->user->away))
|
||||||
sendto_one(client_p, ":%s AWAY :%s",
|
sendto_one(client_p, ":%s AWAY :%s",
|
||||||
use_id(target_p),
|
use_id(target_p),
|
||||||
|
|
|
@ -1031,6 +1031,11 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char
|
||||||
|
|
||||||
Count.oper--;
|
Count.oper--;
|
||||||
|
|
||||||
|
/* Do we need to propegate these? I'm not 100% sure
|
||||||
|
* so we should test it when we have a testnet */
|
||||||
|
user_metadata_delete(source_p, "OPERSTRING", 1);
|
||||||
|
user_metadata_delete(source_p, "SWHOIS", 1);
|
||||||
|
|
||||||
if(MyConnect(source_p))
|
if(MyConnect(source_p))
|
||||||
{
|
{
|
||||||
source_p->umodes &= ~ConfigFileEntry.oper_only_umodes;
|
source_p->umodes &= ~ConfigFileEntry.oper_only_umodes;
|
||||||
|
|
Loading…
Reference in New Issue