]> jfr.im git - irc/rqf/shadowircd.git/commitdiff
Add channel metadata system.
authorB.Greenham <redacted>
Thu, 4 Mar 2010 20:08:16 +0000 (15:08 -0500)
committerB.Greenham <redacted>
Thu, 4 Mar 2010 20:08:16 +0000 (15:08 -0500)
include/channel.h
modules/core/m_metadata.c
src/channel.c
src/s_serv.c

index 1cbcb1df63a49bd40e3ee73816bc1fccec9b1cf6..381e5e3c4ee47ae32eb1852da832e828010667aa 100644 (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 */
index 889bd88dcf1a02ea56fb9c35f84cc4d6e1d72370..dc85dfb0ab73fb57fd4406faf92fda8ce9fa18fa 100644 (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);
-}
\ No newline at end of file
+       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);
+       }
+}
index 4dd6b829aa36289a1d288940fbbdfb70a213511b..44c8d9fbc3c8b93edfe90e63a7cd80809e4f8c92 100644 (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);
+}
index e66c02114b237274a6ef49ecb3e44af22505483b..6693c2fdc4a41a725b60d61e182d62e09c405543 100644 (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');