mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 13:45:10 +00:00
148 lines
3.2 KiB
C
148 lines
3.2 KiB
C
#include "XMPPThread/internal.h"
|
|
|
|
#include <Cytoplasm/Memory.h>
|
|
#include <Cytoplasm/Base64.h>
|
|
#include <Cytoplasm/Json.h>
|
|
#include <Cytoplasm/Log.h>
|
|
#include <Cytoplasm/Str.h>
|
|
#include <Cytoplasm/Db.h>
|
|
|
|
#include <string.h>
|
|
|
|
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);
|
|
|
|
}
|