#include "XMPPThread/internal.h" #include #include #include #include #include #include #include static char * SubscriptionHash(ParseeData *data, char *from, char *to) { uint8_t *sum; char *hash; size_t len; len = strlen(from) + 1 + strlen(to); sum = Malloc(len); memset(sum, 0x00, len); memcpy(&sum[0], from, strlen(from)); memcpy(&sum[strlen(from) + 1], to, strlen(to)); hash = Base64Encode(sum, len); Free(sum); return hash; } static void DecodeSubscription(ParseeData *data, char *hash, char **from, char **to) { char *sum; if (!data || !hash || !from || !to) { return; } sum = Base64Decode(hash, strlen(hash)); *from = StrDuplicate(sum); *to = StrDuplicate(sum + strlen(sum) + 1); Free(sum); } void AddPresenceSubscriber(ParseeData *data, char *from, char *to) { Db *database; DbRef *ref; char *hash; if (!data || !from || !to) { return; } database = data->db; hash = SubscriptionHash(data, from, to); ref = DbCreate(database, 2, "subs", hash); if (!ref) { goto end; } HashMapSet(DbJson(ref), "from", JsonValueString(from)); HashMapSet(DbJson(ref), "to", JsonValueString(to)); /* I don't think we need more information right now */ end: DbUnlock(database, ref); Free(hash); } bool IsSubscribed(ParseeData *data, char *user, char *to) { Db *database; char *hash; bool ret; if (!data || !user || !to) { return false; } database = data->db; hash = SubscriptionHash(data, user, to); ret = DbExists(database, 2, "subs", hash); Free(hash); return ret; } void ParseeBroadcastStanza(ParseeData *data, char *from, XMLElement *stanza) { XMPPComponent *jabber = data ? data->jabber : NULL; Array *entries; size_t i; if (!data || !from || !stanza) { return; } /* Copy our stanza so that we can freely modify it */ stanza = XMLCopy(stanza); /* Start doing a storm on Mt. Subs. */ entries = DbList(data->db, 1, "subs"); for (i = 0; i < ArraySize(entries); i++) { char *entry = ArrayGet(entries, i); char *entry_from = NULL, *entry_to = NULL; char *storm_id; /* ooe */ XMLElement *sub; DecodeSubscription(data, entry, &entry_from, &entry_to); if (!StrEquals(entry_to, from)) { goto end; } Log(LOG_DEBUG, "PRESENCE SYSTEM: " "We should be brotkasting straight to %s (from %s)", entry_from, from ); sub = XMLCopy(stanza); XMLAddAttr(sub, "from", from); XMLAddAttr(sub, "to", entry_from); /* TODO: Should we store IDs somewhere? */ XMLAddAttr(sub, "id", (storm_id = StrRandom(16))); pthread_mutex_lock(&jabber->write_lock); XMLEncode(jabber->stream, sub); StreamFlush(jabber->stream); pthread_mutex_unlock(&jabber->write_lock); XMLFreeElement(sub); Free(storm_id); end: Free(entry_from); Free(entry_to); } DbListFree(entries); XMLFreeElement(stanza); }