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 <XML.h>
|
||||
|
||||
#include "XMPPThread/internal.h"
|
||||
|
||||
bool
|
||||
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)
|
||||
{
|
||||
XMLElement *presence, *x, *reply, *history, *photo;
|
||||
IQFeatures *features;
|
||||
char *from, *id, *stime = "3600";
|
||||
if (!comp || !fr || !muc)
|
||||
{
|
||||
|
|
@ -189,7 +192,15 @@ XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, int time, bool
|
|||
XMLAddChild(x, history);
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -225,6 +236,7 @@ void
|
|||
XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
|
||||
{
|
||||
XMLElement *presence;
|
||||
IQFeatures *features;
|
||||
char *from, *id;
|
||||
if (!comp || !fr || !muc)
|
||||
{
|
||||
|
|
@ -246,7 +258,16 @@ XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -159,27 +159,6 @@ XMPPGetReply(XMLElement *elem)
|
|||
|
||||
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 *
|
||||
XMPPGetModeration(XMLElement *stanza)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,33 +12,86 @@
|
|||
|
||||
#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. */
|
||||
char *
|
||||
XMPPGenerateVer(void)
|
||||
XMPPGenerateVer(IQFeatures *features)
|
||||
{
|
||||
char *S = NULL;
|
||||
unsigned char *Sha = NULL;
|
||||
Array *identities = ArrayCreate();
|
||||
Array *features = ArrayCreate();
|
||||
size_t i;
|
||||
|
||||
/* Initialise identity table, to be sorted */
|
||||
#define IdentitySimple(cat, Type, Name) { \
|
||||
XMPPIdentity *id = Malloc(sizeof(*id)); \
|
||||
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++)
|
||||
ArraySort(features->identity, IdentitySort);
|
||||
for (i = 0; i < ArraySize(features->identity); i++)
|
||||
{
|
||||
XMPPIdentity *identity = ArrayGet(identities, i);
|
||||
XMPPIdentity *identity = ArrayGet(features->identity, i);
|
||||
char *id_chunk = StrConcat(7,
|
||||
identity->category, "/",
|
||||
identity->type, "/",
|
||||
|
|
@ -50,10 +103,10 @@ XMPPGenerateVer(void)
|
|||
Free(id_chunk);
|
||||
}
|
||||
|
||||
ArraySort(features, ((int (*) (void *, void *)) ICollate));
|
||||
for (i = 0; i < ArraySize(features); i++)
|
||||
ArraySort(features->adverts, ((int (*) (void *, void *)) ICollate));
|
||||
for (i = 0; i < ArraySize(features->adverts); i++)
|
||||
{
|
||||
char *feature = ArrayGet(features, i);
|
||||
char *feature = ArrayGet(features->adverts, i);
|
||||
char *tmp = S;
|
||||
S = StrConcat(3, S, feature, "<");
|
||||
Free(tmp);
|
||||
|
|
@ -64,16 +117,28 @@ XMPPGenerateVer(void)
|
|||
S = Base64Encode((const char *) Sha, 20);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
XMLElement *iq_reply, *query;
|
||||
IQFeatures *features = CreateIQFeatures();
|
||||
|
||||
from = HashMapGet(stanza->attrs, "from");
|
||||
to = HashMapGet(stanza->attrs, "to");
|
||||
|
|
@ -164,8 +165,14 @@ IQDiscoGet(ParseeData *args, XMPPComponent *jabber, XMLElement *stanza)
|
|||
XMLAddAttr(iq_reply, "id", id);
|
||||
|
||||
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);
|
||||
XMLAddAttr(query, "node", node);
|
||||
|
||||
|
|
@ -173,6 +180,7 @@ IQDiscoGet(ParseeData *args, XMPPComponent *jabber, XMLElement *stanza)
|
|||
Free(ver);
|
||||
}
|
||||
XMLAddChild(iq_reply, query);
|
||||
FreeIQFeatures(features);
|
||||
|
||||
XMPPSendStanza(jabber, iq_reply, args->config->max_stanza_size);
|
||||
XMLFreeElement(iq_reply);
|
||||
|
|
|
|||
|
|
@ -32,13 +32,17 @@
|
|||
IdentitySimple("client", "pc", NAME " v" VERSION " bridge") \
|
||||
IdentitySimple("component", "generic", "Parsee's component")
|
||||
|
||||
typedef struct PEPManager PEPManager;
|
||||
typedef void (*PEPEvent)(PEPManager *m, XMLElement *stanza, XMLElement *item);
|
||||
|
||||
typedef struct IQFeatures {
|
||||
Array *identity;
|
||||
Array *adverts;
|
||||
} IQFeatures;
|
||||
typedef struct XMPPIdentity {
|
||||
char *category, *type, *lang, *name;
|
||||
} XMPPIdentity;
|
||||
|
||||
typedef struct PEPManager PEPManager;
|
||||
typedef void (*PEPEvent)(PEPManager *m, XMLElement *stanza, XMLElement *item);
|
||||
|
||||
typedef struct XMPPThread XMPPThread;
|
||||
typedef struct XMPPThreadInfo {
|
||||
/* 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 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 * ParseeGetEventFromID(ParseeData *data, XMLElement *stanza, char *id);
|
||||
char * ParseeGetReactedEvent(ParseeData *data, XMLElement *stanza);
|
||||
|
|
|
|||
|
|
@ -98,16 +98,6 @@ extern char * XMPPGetReply(XMLElement *elem);
|
|||
* See-Also: https://xmpp.org/extensions/xep-0425.html */
|
||||
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);
|
||||
|
||||
#include <Parsee.h>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue