char *away; /* pointer to away message */
int refcnt; /* Number of times this block is referenced */
+ struct Dictionary *metadata;
+
char suser[NICKLEN+1];
};
*/
};
+struct Metadata
+{
+ const char *name;
+ const char *value;
+};
+
/*
* status macros.
*/
void allocate_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 */
make_user(struct Client *client_p)
{
struct User *user;
+ struct Dictionary *metadata;
user = client_p->user;
if(!user)
user = (struct User *) rb_bh_alloc(user_heap);
user->refcnt = 1;
client_p->user = user;
+
+ metadata = irc_dictionary_create(irccmp);
+ client_p->user->metadata = metadata;
}
return user;
}
{
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->away)
rb_free((char *) user->away);
+
/*
* sanity check
*/
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);
+}
#include "msg.h"
#include "reject.h"
#include "sslproc.h"
+#include "irc_dictionary.h"
#ifndef INADDR_NONE
#define INADDR_NONE ((unsigned int) 0xffffffff)
char *t;
int tlen, mlen;
int cur_len = 0;
+ struct Metadata *md;
+ struct DictionaryIter iter;
hclientinfo.client = hchaninfo.client = client_p;
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))
sendto_one(client_p, ":%s AWAY :%s",
use_id(target_p),