Add channel metadata system.

This commit is contained in:
B.Greenham 2010-03-04 15:08:16 -05:00
parent 3da167f207
commit 6f659342dc
4 changed files with 129 additions and 11 deletions

View File

@ -72,6 +72,8 @@ struct Channel
unsigned int join_count; /* joins within delta */
unsigned int join_delta; /* last ts of join */
struct Dictionary *c_metadata;
unsigned long bants;
time_t channelts;
char *chname;
@ -90,6 +92,12 @@ struct membership
unsigned long bants;
};
struct c_Metadata
{
const char *name;
const char *value;
};
#define BANLEN 195
struct Ban
{
@ -296,4 +304,8 @@ extern void user_join(struct Client * client_p, struct Client * source_p, const
extern void do_join_0(struct Client *client_p, struct Client *source_p);
extern int check_channel_name_loc(struct Client *source_p, const char *name);
extern struct Metadata *channel_metadata_add(struct Channel *target, const char *name, const char *value, int propegate);
extern void channel_metadata_delete(struct Channel *target, const char *name, int propegate);
extern struct Metadata *channel_metadata_find(struct Channel *target, const char *name);
#endif /* INCLUDED_channel_h */

View File

@ -33,16 +33,32 @@ DECLARE_MODULE_AV1(metadata, NULL, NULL, metadata_clist, NULL, NULL, "$Revision$
void
me_metadata(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
struct Client *target_p;
if(parv[2][0] == '#')
{
struct Channel *chptr;
if((target_p = find_client(parv[2])) == NULL)
return;
if((chptr = find_channel(parv[2])) == NULL)
return;
if(!target_p->user)
return;
if(!strcmp(parv[1], "ADD") && parv[4] != NULL)
channel_metadata_add(chptr, parv[3], parv[4], 0);
if(!strcmp(parv[1], "DELETE") && parv[3] != NULL)
channel_metadata_delete(chptr, parv[3], 0);
}
if(!strcmp(parv[1], "ADD") && parv[4] != NULL)
user_metadata_add(target_p, parv[3], parv[4], 0);
if(!strcmp(parv[1], "DELETE") && parv[3] != NULL)
user_metadata_delete(target_p, parv[3], 0);
}
else
{
struct Client *target_p;
if((target_p = find_client(parv[2])) == NULL)
return;
if(!target_p->user)
return;
if(!strcmp(parv[1], "ADD") && parv[4] != NULL)
user_metadata_add(target_p, parv[3], parv[4], 0);
if(!strcmp(parv[1], "DELETE") && parv[3] != NULL)
user_metadata_delete(target_p, parv[3], 0);
}
}

View File

@ -42,6 +42,7 @@
#include "s_newconf.h"
#include "logger.h"
#include "packet.h"
#include "irc_dictionary.h"
struct config_channel_entry ConfigChannel;
rb_dlink_list global_channel_list;
@ -92,14 +93,19 @@ struct Channel *
allocate_channel(const char *chname)
{
struct Channel *chptr;
struct Dictionary *c_metadata;
chptr = rb_bh_alloc(channel_heap);
chptr->chname = rb_strdup(chname);
c_metadata = irc_dictionary_create(irccmp);
chptr->c_metadata = c_metadata;
return (chptr);
}
void
free_channel(struct Channel *chptr)
{
/* insert deletion of metadata here! */
rb_free(chptr->chname);
rb_bh_free(channel_heap, chptr);
}
@ -1891,3 +1897,81 @@ void user_join(struct Client * client_p, struct Client * source_p, const char *
return;
}
/*
* channel_metadata_add
*
* inputs - pointer to channel 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 channel in question
* - metadata is propegated if propegate is set.
*/
struct Metadata *
channel_metadata_add(struct Channel *target, const char *name, const char *value, int propegate)
{
struct Metadata *md;
if(irc_dictionary_find(target->c_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->c_metadata, md->name, md);
if(propegate)
sendto_match_servs(&me, "*", CAP_ENCAP, NOCAPS, "ENCAP * METADATA ADD %s %s :%s",
target->chname, name, value);
return md;
}
/*
* channel_metadata_delete
*
* inputs - pointer to channel struct
* - name of metadata item you wish to delete
* output - none
* side effects - metadata is deleted from the channel in question
* - deletion is propegated if propegate is set
*/
void
channel_metadata_delete(struct Channel *target, const char *name, int propegate)
{
struct Metadata *md = channel_metadata_find(target, name);
if(!md)
return;
irc_dictionary_delete(target->c_metadata, md->name);
rb_free(md);
if(propegate)
sendto_match_servs(&me, "*", CAP_ENCAP, NOCAPS, "ENCAP * METADATA DELETE %s %s",
target->chname, name);
}
/*
* channel_metadata_find
*
* inputs - pointer to channel struct
* - name of metadata item you wish to read
* output - the requested metadata, if it exists, elsewise null.
* side effects -
*/
struct Metadata *
channel_metadata_find(struct Channel *target, const char *name)
{
if(!target)
return NULL;
if(!target->c_metadata)
return NULL;
return irc_dictionary_retrieve(target->c_metadata, name);
}

View File

@ -525,7 +525,7 @@ burst_TS6(struct Client *client_p)
DICTIONARY_FOREACH(md, &iter, target_p->user->metadata)
{
sendto_one(client_p, ":%s ENCAP * METADATA %s %s :%s",
sendto_one(client_p, ":%s ENCAP * METADATA ADD %s %s :%s",
use_id(target_p), use_id(target_p), md->name, md->value);
}
@ -587,6 +587,12 @@ burst_TS6(struct Client *client_p)
}
sendto_one(client_p, "%s", buf);
DICTIONARY_FOREACH(md, &iter, chptr->c_metadata)
{
sendto_one(client_p, ":%s ENCAP * METADATA ADD %s %s :%s",
use_id(target_p), use_id(target_p), md->name, md->value);
}
if(rb_dlink_list_length(&chptr->banlist) > 0)
burst_modes_TS6(client_p, chptr, &chptr->banlist, 'b');