mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 13:45:10 +00:00
[MOD] Start not hardcoding discovery features
The eventual goal here is to have different disco replies for specific kinds of JID, effectively allowing us to have MUCs. Yeah.
This commit is contained in:
parent
5ff92dda3d
commit
2e566c73fc
6 changed files with 148 additions and 66 deletions
|
|
@ -8,6 +8,8 @@
|
||||||
#include <Parsee.h>
|
#include <Parsee.h>
|
||||||
#include <XML.h>
|
#include <XML.h>
|
||||||
|
|
||||||
|
#include "XMPPThread/internal.h"
|
||||||
|
|
||||||
bool
|
bool
|
||||||
XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
|
XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
|
||||||
{
|
{
|
||||||
|
|
@ -162,6 +164,7 @@ bool
|
||||||
XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, int time, bool ret)
|
XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, int time, bool ret)
|
||||||
{
|
{
|
||||||
XMLElement *presence, *x, *reply, *history, *photo;
|
XMLElement *presence, *x, *reply, *history, *photo;
|
||||||
|
IQFeatures *features;
|
||||||
char *from, *id, *stime = "3600";
|
char *from, *id, *stime = "3600";
|
||||||
if (!comp || !fr || !muc)
|
if (!comp || !fr || !muc)
|
||||||
{
|
{
|
||||||
|
|
@ -189,7 +192,15 @@ XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, int time, bool
|
||||||
XMLAddChild(x, history);
|
XMLAddChild(x, history);
|
||||||
|
|
||||||
XMLAddChild(presence, x);
|
XMLAddChild(presence, x);
|
||||||
XMPPAnnotatePresence(presence);
|
features = CreateIQFeatures();
|
||||||
|
#define IdentitySimple(cat, Type, Name) AddIQIdentity(features, cat, NULL, Type, Name);
|
||||||
|
IQ_IDENTITY
|
||||||
|
#undef IdentitySimple
|
||||||
|
#define AdvertiseSimple(feature) AdvertiseIQFeature(features, feature);
|
||||||
|
IQ_ADVERT
|
||||||
|
#undef AdvertiseSimple
|
||||||
|
XMPPAnnotatePresence(presence, features);
|
||||||
|
FreeIQFeatures(features);
|
||||||
|
|
||||||
if (hash)
|
if (hash)
|
||||||
{
|
{
|
||||||
|
|
@ -225,6 +236,7 @@ void
|
||||||
XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
|
XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
|
||||||
{
|
{
|
||||||
XMLElement *presence;
|
XMLElement *presence;
|
||||||
|
IQFeatures *features;
|
||||||
char *from, *id;
|
char *from, *id;
|
||||||
if (!comp || !fr || !muc)
|
if (!comp || !fr || !muc)
|
||||||
{
|
{
|
||||||
|
|
@ -246,7 +258,16 @@ XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
|
||||||
XMLAddChild(presence, status);
|
XMLAddChild(presence, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
XMPPAnnotatePresence(presence);
|
features = CreateIQFeatures();
|
||||||
|
#define IdentitySimple(cat, Type, Name) AddIQIdentity(features, cat, NULL, Type, Name);
|
||||||
|
IQ_IDENTITY
|
||||||
|
#undef IdentitySimple
|
||||||
|
#define AdvertiseSimple(feature) AdvertiseIQFeature(features, feature);
|
||||||
|
IQ_ADVERT
|
||||||
|
#undef AdvertiseSimple
|
||||||
|
XMPPAnnotatePresence(presence, features);
|
||||||
|
FreeIQFeatures(features);
|
||||||
|
|
||||||
|
|
||||||
XMPPSendStanza(comp, presence, 10000);
|
XMPPSendStanza(comp, presence, 10000);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -159,27 +159,6 @@ XMPPGetReply(XMLElement *elem)
|
||||||
|
|
||||||
return HashMapGet(rep->attrs, "id");
|
return HashMapGet(rep->attrs, "id");
|
||||||
}
|
}
|
||||||
void
|
|
||||||
XMPPAnnotatePresence(XMLElement *presence)
|
|
||||||
{
|
|
||||||
XMLElement *c;
|
|
||||||
char *ver;
|
|
||||||
if (!presence)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ver = XMPPGenerateVer();
|
|
||||||
c = XMLCreateTag("c");
|
|
||||||
XMLAddAttr(c, "xmlns", "http://jabber.org/protocol/caps");
|
|
||||||
XMLAddAttr(c, "hash", "sha-1");
|
|
||||||
XMLAddAttr(c, "node", REPOSITORY);
|
|
||||||
XMLAddAttr(c, "ver", ver);
|
|
||||||
|
|
||||||
Free(ver);
|
|
||||||
XMLAddChild(presence, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
XMPPGetModeration(XMLElement *stanza)
|
XMPPGetModeration(XMLElement *stanza)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,33 +12,86 @@
|
||||||
|
|
||||||
#include "XMPPThread/internal.h"
|
#include "XMPPThread/internal.h"
|
||||||
|
|
||||||
|
IQFeatures *
|
||||||
|
CreateIQFeatures(void)
|
||||||
|
{
|
||||||
|
IQFeatures *ret = Malloc(sizeof(*ret));
|
||||||
|
|
||||||
|
ret->identity = ArrayCreate();
|
||||||
|
ret->adverts = ArrayCreate();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
FreeIQFeatures(IQFeatures *features)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
if (!features)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ArraySize(features->adverts); i++)
|
||||||
|
{
|
||||||
|
Free(ArrayGet(features->adverts, i));
|
||||||
|
}
|
||||||
|
ArrayFree(features->adverts);
|
||||||
|
|
||||||
|
for (i = 0; i < ArraySize(features->identity); i++)
|
||||||
|
{
|
||||||
|
XMPPIdentity *identity = ArrayGet(features->identity, i);
|
||||||
|
|
||||||
|
Free(identity->category);
|
||||||
|
Free(identity->type);
|
||||||
|
Free(identity->lang);
|
||||||
|
Free(identity->name);
|
||||||
|
|
||||||
|
Free(identity);
|
||||||
|
}
|
||||||
|
ArrayFree(features->identity);
|
||||||
|
|
||||||
|
Free(features);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AdvertiseIQFeature(IQFeatures *f, char *feature)
|
||||||
|
{
|
||||||
|
if (!f || !feature)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayAdd(f->adverts, StrDuplicate(feature));
|
||||||
|
}
|
||||||
|
void
|
||||||
|
AddIQIdentity(IQFeatures *f, char *cat, char *lang, char *type, char *name)
|
||||||
|
{
|
||||||
|
XMPPIdentity *identity;
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
identity = Malloc(sizeof(*identity));
|
||||||
|
identity->category = StrDuplicate(cat);
|
||||||
|
identity->type = StrDuplicate(type);
|
||||||
|
identity->lang = StrDuplicate(lang);
|
||||||
|
identity->name = StrDuplicate(name);
|
||||||
|
ArrayAdd(f->identity, identity);
|
||||||
|
}
|
||||||
/* Generates a SHA-256 hash of the ver field. */
|
/* Generates a SHA-256 hash of the ver field. */
|
||||||
char *
|
char *
|
||||||
XMPPGenerateVer(void)
|
XMPPGenerateVer(IQFeatures *features)
|
||||||
{
|
{
|
||||||
char *S = NULL;
|
char *S = NULL;
|
||||||
unsigned char *Sha = NULL;
|
unsigned char *Sha = NULL;
|
||||||
Array *identities = ArrayCreate();
|
|
||||||
Array *features = ArrayCreate();
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
/* Initialise identity table, to be sorted */
|
/* Initialise identity table, to be sorted */
|
||||||
#define IdentitySimple(cat, Type, Name) { \
|
ArraySort(features->identity, IdentitySort);
|
||||||
XMPPIdentity *id = Malloc(sizeof(*id)); \
|
for (i = 0; i < ArraySize(features->identity); i++)
|
||||||
id->category = cat; \
|
|
||||||
id->lang = NULL; \
|
|
||||||
id->type = Type; \
|
|
||||||
id->name = Name; \
|
|
||||||
ArrayAdd(identities, id); }
|
|
||||||
IQ_IDENTITY
|
|
||||||
#undef IdentitySimple
|
|
||||||
#define AdvertiseSimple(feature) ArrayAdd(features, feature);
|
|
||||||
IQ_ADVERT
|
|
||||||
#undef AdvertiseSimple
|
|
||||||
ArraySort(identities, IdentitySort);
|
|
||||||
for (i = 0; i < ArraySize(identities); i++)
|
|
||||||
{
|
{
|
||||||
XMPPIdentity *identity = ArrayGet(identities, i);
|
XMPPIdentity *identity = ArrayGet(features->identity, i);
|
||||||
char *id_chunk = StrConcat(7,
|
char *id_chunk = StrConcat(7,
|
||||||
identity->category, "/",
|
identity->category, "/",
|
||||||
identity->type, "/",
|
identity->type, "/",
|
||||||
|
|
@ -50,10 +103,10 @@ XMPPGenerateVer(void)
|
||||||
Free(id_chunk);
|
Free(id_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArraySort(features, ((int (*) (void *, void *)) ICollate));
|
ArraySort(features->adverts, ((int (*) (void *, void *)) ICollate));
|
||||||
for (i = 0; i < ArraySize(features); i++)
|
for (i = 0; i < ArraySize(features->adverts); i++)
|
||||||
{
|
{
|
||||||
char *feature = ArrayGet(features, i);
|
char *feature = ArrayGet(features->adverts, i);
|
||||||
char *tmp = S;
|
char *tmp = S;
|
||||||
S = StrConcat(3, S, feature, "<");
|
S = StrConcat(3, S, feature, "<");
|
||||||
Free(tmp);
|
Free(tmp);
|
||||||
|
|
@ -64,16 +117,28 @@ XMPPGenerateVer(void)
|
||||||
S = Base64Encode((const char *) Sha, 20);
|
S = Base64Encode((const char *) Sha, 20);
|
||||||
Free(Sha);
|
Free(Sha);
|
||||||
|
|
||||||
ArrayFree(features);
|
|
||||||
for (i = 0; i < ArraySize(identities); i++)
|
|
||||||
{
|
|
||||||
XMPPIdentity *identity = ArrayGet(identities, i);
|
|
||||||
/* We don't have to do anything here. */
|
|
||||||
Free(identity);
|
|
||||||
}
|
|
||||||
ArrayFree(identities);
|
|
||||||
|
|
||||||
return S;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
XMPPAnnotatePresence(XMLElement *presence, IQFeatures *features)
|
||||||
|
{
|
||||||
|
XMLElement *c;
|
||||||
|
char *ver;
|
||||||
|
if (!presence || !features)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ver = XMPPGenerateVer(features);
|
||||||
|
c = XMLCreateTag("c");
|
||||||
|
XMLAddAttr(c, "xmlns", "http://jabber.org/protocol/caps");
|
||||||
|
XMLAddAttr(c, "hash", "sha-1");
|
||||||
|
XMLAddAttr(c, "node", REPOSITORY);
|
||||||
|
XMLAddAttr(c, "ver", ver);
|
||||||
|
|
||||||
|
Free(ver);
|
||||||
|
XMLAddChild(presence, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ IQDiscoGet(ParseeData *args, XMPPComponent *jabber, XMLElement *stanza)
|
||||||
{
|
{
|
||||||
char *from, *to, *id;
|
char *from, *to, *id;
|
||||||
XMLElement *iq_reply, *query;
|
XMLElement *iq_reply, *query;
|
||||||
|
IQFeatures *features = CreateIQFeatures();
|
||||||
|
|
||||||
from = HashMapGet(stanza->attrs, "from");
|
from = HashMapGet(stanza->attrs, "from");
|
||||||
to = HashMapGet(stanza->attrs, "to");
|
to = HashMapGet(stanza->attrs, "to");
|
||||||
|
|
@ -164,8 +165,14 @@ IQDiscoGet(ParseeData *args, XMPPComponent *jabber, XMLElement *stanza)
|
||||||
XMLAddAttr(iq_reply, "id", id);
|
XMLAddAttr(iq_reply, "id", id);
|
||||||
|
|
||||||
query = IQGenerateQuery();
|
query = IQGenerateQuery();
|
||||||
|
#define IdentitySimple(cat, Type, Name) AddIQIdentity(features, cat, NULL, Type, Name);
|
||||||
|
IQ_IDENTITY
|
||||||
|
#undef IdentitySimple
|
||||||
|
#define AdvertiseSimple(feature) AdvertiseIQFeature(features, feature);
|
||||||
|
IQ_ADVERT
|
||||||
|
#undef AdvertiseSimple
|
||||||
{
|
{
|
||||||
char *ver = XMPPGenerateVer();
|
char *ver = XMPPGenerateVer(features);
|
||||||
char *node = StrConcat(3, REPOSITORY, "#", ver);
|
char *node = StrConcat(3, REPOSITORY, "#", ver);
|
||||||
XMLAddAttr(query, "node", node);
|
XMLAddAttr(query, "node", node);
|
||||||
|
|
||||||
|
|
@ -173,6 +180,7 @@ IQDiscoGet(ParseeData *args, XMPPComponent *jabber, XMLElement *stanza)
|
||||||
Free(ver);
|
Free(ver);
|
||||||
}
|
}
|
||||||
XMLAddChild(iq_reply, query);
|
XMLAddChild(iq_reply, query);
|
||||||
|
FreeIQFeatures(features);
|
||||||
|
|
||||||
XMPPSendStanza(jabber, iq_reply, args->config->max_stanza_size);
|
XMPPSendStanza(jabber, iq_reply, args->config->max_stanza_size);
|
||||||
XMLFreeElement(iq_reply);
|
XMLFreeElement(iq_reply);
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,17 @@
|
||||||
IdentitySimple("client", "pc", NAME " v" VERSION " bridge") \
|
IdentitySimple("client", "pc", NAME " v" VERSION " bridge") \
|
||||||
IdentitySimple("component", "generic", "Parsee's component")
|
IdentitySimple("component", "generic", "Parsee's component")
|
||||||
|
|
||||||
typedef struct PEPManager PEPManager;
|
typedef struct IQFeatures {
|
||||||
typedef void (*PEPEvent)(PEPManager *m, XMLElement *stanza, XMLElement *item);
|
Array *identity;
|
||||||
|
Array *adverts;
|
||||||
|
} IQFeatures;
|
||||||
typedef struct XMPPIdentity {
|
typedef struct XMPPIdentity {
|
||||||
char *category, *type, *lang, *name;
|
char *category, *type, *lang, *name;
|
||||||
} XMPPIdentity;
|
} XMPPIdentity;
|
||||||
|
|
||||||
|
typedef struct PEPManager PEPManager;
|
||||||
|
typedef void (*PEPEvent)(PEPManager *m, XMLElement *stanza, XMLElement *item);
|
||||||
|
|
||||||
typedef struct XMPPThread XMPPThread;
|
typedef struct XMPPThread XMPPThread;
|
||||||
typedef struct XMPPThreadInfo {
|
typedef struct XMPPThreadInfo {
|
||||||
/* A FIFO of stanzas inbound, to be read by dispatcher
|
/* A FIFO of stanzas inbound, to be read by dispatcher
|
||||||
|
|
@ -65,6 +69,21 @@ struct XMPPThread {
|
||||||
int ICollate(unsigned char *cata, unsigned char *catb);
|
int ICollate(unsigned char *cata, unsigned char *catb);
|
||||||
int IdentitySort(void *idap, void *idbp);
|
int IdentitySort(void *idap, void *idbp);
|
||||||
|
|
||||||
|
IQFeatures * CreateIQFeatures(void);
|
||||||
|
void AddIQIdentity(IQFeatures *, char *category, char *lang, char *type, char *name);
|
||||||
|
void AdvertiseIQFeature(IQFeatures *, char *feature);
|
||||||
|
void FreeIQFeatures(IQFeatures *);
|
||||||
|
|
||||||
|
/** Generate the B64-encoded SHA-256 hash for the 'ver' field in caps.
|
||||||
|
* --------
|
||||||
|
* Returns: A base64 encoded ver hash[LA:HEAP]
|
||||||
|
* Modifies: NOTHING
|
||||||
|
* See-Also: https://xmpp.org/extensions/xep-0115.html */
|
||||||
|
char * XMPPGenerateVer(IQFeatures *features);
|
||||||
|
|
||||||
|
/* Annotates a presence with https://xmpp.org/extensions/xep-0115.html */
|
||||||
|
void XMPPAnnotatePresence(XMLElement *presence, IQFeatures *features);
|
||||||
|
|
||||||
char * ParseeGetBridgedRoom(ParseeData *data, XMLElement *stanza);
|
char * ParseeGetBridgedRoom(ParseeData *data, XMLElement *stanza);
|
||||||
char * ParseeGetEventFromID(ParseeData *data, XMLElement *stanza, char *id);
|
char * ParseeGetEventFromID(ParseeData *data, XMLElement *stanza, char *id);
|
||||||
char * ParseeGetReactedEvent(ParseeData *data, XMLElement *stanza);
|
char * ParseeGetReactedEvent(ParseeData *data, XMLElement *stanza);
|
||||||
|
|
|
||||||
|
|
@ -98,16 +98,6 @@ extern char * XMPPGetReply(XMLElement *elem);
|
||||||
* See-Also: https://xmpp.org/extensions/xep-0425.html */
|
* See-Also: https://xmpp.org/extensions/xep-0425.html */
|
||||||
extern char * XMPPGetModeration(XMLElement *stanza);
|
extern char * XMPPGetModeration(XMLElement *stanza);
|
||||||
|
|
||||||
/** Generate the B64-encoded SHA-256 hash for the 'ver' field in caps.
|
|
||||||
* --------
|
|
||||||
* Returns: A base64 encoded ver hash[LA:HEAP]
|
|
||||||
* Modifies: NOTHING
|
|
||||||
* See-Also: https://xmpp.org/extensions/xep-0115.html */
|
|
||||||
extern char * XMPPGenerateVer(void);
|
|
||||||
|
|
||||||
/* Annotates a presence with https://xmpp.org/extensions/xep-0115.html */
|
|
||||||
extern void XMPPAnnotatePresence(XMLElement *presence);
|
|
||||||
|
|
||||||
extern bool XMPPHasError(XMLElement *stanza, char *type);
|
extern bool XMPPHasError(XMLElement *stanza, char *type);
|
||||||
|
|
||||||
#include <Parsee.h>
|
#include <Parsee.h>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue