mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 10:45:11 +00:00
[FIX/MOD] Stanza send function, fix some errors
Negociating stanza sizes seems to be real trouble. Also this code is now `-fanalyzer'-safe! Also kills the last GNUMakefile present. It wasn't even used...
This commit is contained in:
parent
d9b5141eb5
commit
ff5f085b7f
24 changed files with 114 additions and 152 deletions
|
|
@ -33,7 +33,7 @@ jobs:
|
||||||
- name: Build Parsee
|
- name: Build Parsee
|
||||||
run: |
|
run: |
|
||||||
cc configure.c -o configure && ./configure
|
cc configure.c -o configure && ./configure
|
||||||
echo 'CFLAGS=-Werror -Wall -Wextra -pedantic' >> build.conf
|
echo 'CFLAGS=-Werror -Wall -Wextra -pedantic -fanalyzer' >> build.conf
|
||||||
cat build.conf
|
cat build.conf
|
||||||
make && make ayadoc
|
make && make ayadoc
|
||||||
- name: Install Parsee
|
- name: Install Parsee
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,9 @@ restricted to Parsee admins, with permission from MUC owners, too
|
||||||
support XMPP->Matrix bridging.
|
support XMPP->Matrix bridging.
|
||||||
- Manage MUC DMs in a reasonable manner. Thanks `@freeoffers4u:matrix.org` for being
|
- Manage MUC DMs in a reasonable manner. Thanks `@freeoffers4u:matrix.org` for being
|
||||||
a fucking annoyance and DMing an old Parsee semi-anon user for no clear reason.
|
a fucking annoyance and DMing an old Parsee semi-anon user for no clear reason.
|
||||||
|
- Make Parsee cope well with unexcepted stream closures (e.g: with an XMPP server
|
||||||
|
turning off, etc...). Shutting it off seems like an easy solution, but would go
|
||||||
|
against principles.
|
||||||
|
|
||||||
## DONATING/CONTRIBUTING
|
## DONATING/CONTRIBUTING
|
||||||
If you know things about XMPP or Matrix, yet aren't familiar with C99, or just
|
If you know things about XMPP or Matrix, yet aren't familiar with C99, or just
|
||||||
|
|
|
||||||
12
configure.c
12
configure.c
|
|
@ -445,10 +445,15 @@ main_build(int argc, char *argv[])
|
||||||
if (repo)
|
if (repo)
|
||||||
{
|
{
|
||||||
char *lf = strchr(repo, '\n');
|
char *lf = strchr(repo, '\n');
|
||||||
*lf = '\0';
|
if (lf)
|
||||||
|
{
|
||||||
|
*lf = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
repo = strdup("N/A");
|
repo = strdup("N/A");
|
||||||
|
}
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "sl")) != -1)
|
while ((opt = getopt(argc, argv, "sl")) != -1)
|
||||||
{
|
{
|
||||||
|
|
@ -465,8 +470,9 @@ main_build(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
makefile = fopen("Makefile", "w");
|
makefile = fopen("Makefile", "w");
|
||||||
fprintf(makefile, "# Autogenerated POSIX Makefile\n");
|
fprintf(makefile, "# Autogenerated POSIX Makefile from Parsee\n");
|
||||||
fprintf(makefile, "# Ideally do not touch.\n\n");
|
fprintf(makefile, "# Ideally do not touch, unless you have a very ");
|
||||||
|
fprintf(makefile, "good reason to do it. \n\n");
|
||||||
fprintf(makefile, ".POSIX: \n");
|
fprintf(makefile, ".POSIX: \n");
|
||||||
fprintf(makefile, "include build.conf\n\n");
|
fprintf(makefile, "include build.conf\n\n");
|
||||||
fprintf(makefile, "AYAYAS=ayaya\n");
|
fprintf(makefile, "AYAYAS=ayaya\n");
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ FileInfoFromXMPP(XMLElement *stanza)
|
||||||
file = XMLookForTKV(sims,
|
file = XMLookForTKV(sims,
|
||||||
"file", "xmlns", "urn:xmpp:jingle:apps:file-transfer:5"
|
"file", "xmlns", "urn:xmpp:jingle:apps:file-transfer:5"
|
||||||
);
|
);
|
||||||
|
/* TODO: We'll definitely need MIME types to do things like
|
||||||
|
* WebXDC */
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include <Cytoplasm/HttpServer.h>
|
#include <Cytoplasm/HttpServer.h>
|
||||||
#include <Cytoplasm/Cytoplasm.h>
|
#include <Cytoplasm/Cytoplasm.h>
|
||||||
|
#include <Cytoplasm/Platform.h>
|
||||||
#include <Cytoplasm/Memory.h>
|
#include <Cytoplasm/Memory.h>
|
||||||
#include <Cytoplasm/Util.h>
|
#include <Cytoplasm/Util.h>
|
||||||
#include <Cytoplasm/Cron.h>
|
#include <Cytoplasm/Cron.h>
|
||||||
|
|
@ -81,6 +82,13 @@ Main(Array *args, HashMap *env)
|
||||||
Log(LOG_INFO, "=======================");
|
Log(LOG_INFO, "=======================");
|
||||||
Log(LOG_INFO, "(C)opyright 2024 LDA");
|
Log(LOG_INFO, "(C)opyright 2024 LDA");
|
||||||
Log(LOG_INFO, "(This program is free software, see LICENSE.)");
|
Log(LOG_INFO, "(This program is free software, see LICENSE.)");
|
||||||
|
|
||||||
|
#ifdef PLATFORM_IPHONE
|
||||||
|
Log(LOG_WARNING, "Wait. Are you running this on an iPhone?");
|
||||||
|
Log(LOG_WARNING, "You *ought* to have spoofed this, haven't you?");
|
||||||
|
Log(LOG_WARNING, "Simply jealous of you for doing this.");
|
||||||
|
#endif
|
||||||
|
|
||||||
LogConfigIndent(LogConfigGlobal());
|
LogConfigIndent(LogConfigGlobal());
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,12 @@ ParseeConfigLoad(char *conf)
|
||||||
CopyToInt(component_port, "component_port");
|
CopyToInt(component_port, "component_port");
|
||||||
CopyToStr(component_host, "component_host");
|
CopyToStr(component_host, "component_host");
|
||||||
CopyToStr(shared_comp_secret, "shared_secret");
|
CopyToStr(shared_comp_secret, "shared_secret");
|
||||||
|
CopyToInt(max_stanza_size, "max_stanza_size");
|
||||||
|
if (!config->max_stanza_size)
|
||||||
|
{
|
||||||
|
/* Standard XMPP "minimum" maximum */
|
||||||
|
config->max_stanza_size = 10 KB;
|
||||||
|
}
|
||||||
|
|
||||||
CopyToStr(media_base, "media_base");
|
CopyToStr(media_base, "media_base");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ ParseeInitData(XMPPComponent *comp)
|
||||||
{
|
{
|
||||||
Log(LOG_WARNING, "Version mismatch(curr=%s db=%s).", VERSION, version);
|
Log(LOG_WARNING, "Version mismatch(curr=%s db=%s).", VERSION, version);
|
||||||
Log(LOG_WARNING, "Yeah. You may want to _not_ do that.");
|
Log(LOG_WARNING, "Yeah. You may want to _not_ do that.");
|
||||||
|
Log(LOG_WARNING, "(Parsee still needs an upgradepath mechanism.)");
|
||||||
|
|
||||||
DbUnlock(data->db, ref);
|
DbUnlock(data->db, ref);
|
||||||
DbClose(data->db);
|
DbClose(data->db);
|
||||||
|
|
@ -126,8 +127,6 @@ ParseeCleanup(void *datp)
|
||||||
uint64_t ts = UtilTsMillis();
|
uint64_t ts = UtilTsMillis();
|
||||||
size_t entries = 0;
|
size_t entries = 0;
|
||||||
|
|
||||||
Log(LOG_DEBUG, "Cleaning up...");
|
|
||||||
|
|
||||||
chats = DbList(data->db, 1, "chats");
|
chats = DbList(data->db, 1, "chats");
|
||||||
|
|
||||||
for (i = 0; i < ArraySize(chats); i++)
|
for (i = 0; i < ArraySize(chats); i++)
|
||||||
|
|
@ -242,7 +241,6 @@ ParseeCleanup(void *datp)
|
||||||
DbUnlock(data->db, ref);
|
DbUnlock(data->db, ref);
|
||||||
}
|
}
|
||||||
DbListFree(chats);
|
DbListFree(chats);
|
||||||
Log(LOG_DEBUG, "Cleant up %d entries...", entries);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ SignalHandler(int signal)
|
||||||
if (signal == SIGPIPE)
|
if (signal == SIGPIPE)
|
||||||
{
|
{
|
||||||
Log(LOG_DEBUG, "Caught a SIGPIPE...");
|
Log(LOG_DEBUG, "Caught a SIGPIPE...");
|
||||||
|
XMPPFinishCompStream(jabber);
|
||||||
|
pthread_join(xmpp_thr, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -237,13 +237,8 @@ WriteoutStanza(StanzaBuilder *builder, XMPPComponent *jabber)
|
||||||
}
|
}
|
||||||
|
|
||||||
elem = ExportStanza(builder);
|
elem = ExportStanza(builder);
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, elem);
|
||||||
XMLEncode(jabber->stream, elem);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
|
|
||||||
XMLFreeElement(elem);
|
XMLFreeElement(elem);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StanzaBuilder *
|
StanzaBuilder *
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#include <StringStream.h>
|
||||||
#include <Parsee.h>
|
#include <Parsee.h>
|
||||||
#include <XML.h>
|
#include <XML.h>
|
||||||
|
|
||||||
|
|
@ -134,7 +135,7 @@ XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ev->type != XML_LEXER_STARTELEM ||
|
if (!ev || ev->type != XML_LEXER_STARTELEM ||
|
||||||
!StrEquals(ev->element, "stream:stream"))
|
!StrEquals(ev->element, "stream:stream"))
|
||||||
{
|
{
|
||||||
Log(LOG_ERR, "Excepted stream:stream element.");
|
Log(LOG_ERR, "Excepted stream:stream element.");
|
||||||
|
|
@ -159,10 +160,9 @@ XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ev->type != XML_LEXER_ELEM ||
|
if (!ev || ev->type != XML_LEXER_ELEM ||
|
||||||
!StrEquals(ev->element, "handshake"))
|
!StrEquals(ev->element, "handshake"))
|
||||||
{
|
{
|
||||||
Log(LOG_DEBUG, "type=%d elem='%s'", ev->type, ev->element);
|
|
||||||
Log(LOG_ERR, "Excepted empty handshake reply, got nonsense.");
|
Log(LOG_ERR, "Excepted empty handshake reply, got nonsense.");
|
||||||
Log(LOG_ERR, "Another service (possibly Parsee) may have taken over.");
|
Log(LOG_ERR, "Another service (possibly Parsee) may have taken over.");
|
||||||
Log(LOG_ERR, "");
|
Log(LOG_ERR, "");
|
||||||
|
|
@ -213,3 +213,18 @@ XMPPEndCompStream(XMPPComponent *comp)
|
||||||
Free(comp->host);
|
Free(comp->host);
|
||||||
Free(comp);
|
Free(comp);
|
||||||
}
|
}
|
||||||
|
void
|
||||||
|
XMPPSendStanza(XMPPComponent *comp, XMLElement *stanza)
|
||||||
|
{
|
||||||
|
if (!comp || !stanza)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&comp->write_lock);
|
||||||
|
/* TODO: Find a way to negociate to the server about stanza size
|
||||||
|
* (beyond the 10KB limit that is REQUIRED by XMPP standards) */
|
||||||
|
XMLEncode(comp->stream, stanza);
|
||||||
|
StreamFlush(comp->stream);
|
||||||
|
pthread_mutex_unlock(&comp->write_lock);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,6 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
|
||||||
|
|
||||||
iq_query = XMLCreateTag("iq");
|
iq_query = XMLCreateTag("iq");
|
||||||
query = XMLCreateTag("query");
|
query = XMLCreateTag("query");
|
||||||
|
|
||||||
|
|
@ -35,8 +33,7 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
|
||||||
|
|
||||||
{
|
{
|
||||||
XMLElement *identity;
|
XMLElement *identity;
|
||||||
XMLEncode(jabber->stream, iq_query);
|
XMPPSendStanza(jabber, iq_query);
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
XMLFreeElement(iq_query);
|
XMLFreeElement(iq_query);
|
||||||
|
|
||||||
/* Except an IQ reply. 10 seconds of timeout is pretty
|
/* Except an IQ reply. 10 seconds of timeout is pretty
|
||||||
|
|
@ -46,7 +43,6 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
|
||||||
if (!iq_query || !StrEquals(iq_query->name, "iq"))
|
if (!iq_query || !StrEquals(iq_query->name, "iq"))
|
||||||
{
|
{
|
||||||
XMLFreeElement(iq_query);
|
XMLFreeElement(iq_query);
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
query = XMLookForUnique(iq_query, "query");
|
query = XMLookForUnique(iq_query, "query");
|
||||||
|
|
@ -57,7 +53,6 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
|
||||||
"conference"))
|
"conference"))
|
||||||
{
|
{
|
||||||
XMLFreeElement(iq_query);
|
XMLFreeElement(iq_query);
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,7 +68,6 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
|
||||||
XMLFreeElement(iq_query);
|
XMLFreeElement(iq_query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,7 +110,6 @@ XMPPRequestVoice(XMPPComponent *jabber, char *from, char *muc)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
|
||||||
stanza = XMLCreateTag("message");
|
stanza = XMLCreateTag("message");
|
||||||
XMLAddAttr(stanza, "id", (identifier = StrRandom(32)));
|
XMLAddAttr(stanza, "id", (identifier = StrRandom(32)));
|
||||||
XMLAddAttr(stanza, "from", from);
|
XMLAddAttr(stanza, "from", from);
|
||||||
|
|
@ -160,9 +153,7 @@ XMPPRequestVoice(XMPPComponent *jabber, char *from, char *muc)
|
||||||
}
|
}
|
||||||
XMLAddChild(stanza, x);
|
XMLAddChild(stanza, x);
|
||||||
}
|
}
|
||||||
XMLEncode(jabber->stream, stanza);
|
XMPPSendStanza(jabber, stanza);
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
|
|
||||||
XMLFreeElement(stanza);
|
XMLFreeElement(stanza);
|
||||||
Free(identifier);
|
Free(identifier);
|
||||||
|
|
@ -177,8 +168,6 @@ XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, int time, bool
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&comp->write_lock);
|
|
||||||
|
|
||||||
presence = XMLCreateTag("presence");
|
presence = XMLCreateTag("presence");
|
||||||
x = XMLCreateTag("x");
|
x = XMLCreateTag("x");
|
||||||
XMLAddAttr(presence, "from", (from = StrConcat(3, fr, "@", comp->host)));
|
XMLAddAttr(presence, "from", (from = StrConcat(3, fr, "@", comp->host)));
|
||||||
|
|
@ -212,14 +201,10 @@ XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, int time, bool
|
||||||
XMLAddChild(presence, x);
|
XMLAddChild(presence, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
XMLEncode(comp->stream, presence);
|
XMPPSendStanza(comp, presence);
|
||||||
StreamFlush(comp->stream);
|
|
||||||
|
|
||||||
XMLFreeElement(presence);
|
XMLFreeElement(presence);
|
||||||
Free(from);
|
Free(from);
|
||||||
|
|
||||||
pthread_mutex_unlock(&comp->write_lock);
|
|
||||||
|
|
||||||
if (ret && (reply = ParseeAwaitStanza(id, 500)))
|
if (ret && (reply = ParseeAwaitStanza(id, 500)))
|
||||||
{
|
{
|
||||||
bool exit_code = true;
|
bool exit_code = true;
|
||||||
|
|
@ -246,8 +231,6 @@ XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&comp->write_lock);
|
|
||||||
|
|
||||||
presence = XMLCreateTag("presence");
|
presence = XMLCreateTag("presence");
|
||||||
XMLAddAttr(presence, "from", (from = StrConcat(3, fr, "@", comp->host)));
|
XMLAddAttr(presence, "from", (from = StrConcat(3, fr, "@", comp->host)));
|
||||||
XMLAddAttr(presence, "to", muc);
|
XMLAddAttr(presence, "to", muc);
|
||||||
|
|
@ -265,12 +248,9 @@ XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
|
||||||
|
|
||||||
XMPPAnnotatePresence(presence);
|
XMPPAnnotatePresence(presence);
|
||||||
|
|
||||||
XMLEncode(comp->stream, presence);
|
XMPPSendStanza(comp, presence);
|
||||||
StreamFlush(comp->stream);
|
|
||||||
|
|
||||||
XMLFreeElement(presence);
|
XMLFreeElement(presence);
|
||||||
Free(from);
|
Free(from);
|
||||||
Free(id);
|
Free(id);
|
||||||
|
|
||||||
pthread_mutex_unlock(&comp->write_lock);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,13 +66,9 @@ XMPPRetract(XMPPComponent *comp, char *fr, char *to, char *type, char *redact)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&comp->write_lock);
|
XMPPSendStanza(comp, message);
|
||||||
XMLEncode(comp->stream, message);
|
|
||||||
StreamFlush(comp->stream);
|
|
||||||
XMLFreeElement(message);
|
XMLFreeElement(message);
|
||||||
|
|
||||||
pthread_mutex_unlock(&comp->write_lock);
|
|
||||||
|
|
||||||
Free(from);
|
Free(from);
|
||||||
Free(ident);
|
Free(ident);
|
||||||
}
|
}
|
||||||
|
|
@ -85,6 +81,8 @@ XMPPIsParseeStanza(XMLElement *stanza)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: Check if the user is a trustworthy Parsee puppet instead of some
|
||||||
|
* guy sending random stanzas */
|
||||||
return !!XMLookForUnique(stanza, "x-parsee");
|
return !!XMLookForUnique(stanza, "x-parsee");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,10 +264,7 @@ XMPPSendDisco(ParseeData *data, char *from, char *to)
|
||||||
XMLAddChild(iq, query);
|
XMLAddChild(iq, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, iq);
|
||||||
XMLEncode(jabber->stream, iq);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(iq);
|
XMLFreeElement(iq);
|
||||||
|
|
||||||
ret = ParseeAwaitStanza(identifier, 1.25 SECONDS);
|
ret = ParseeAwaitStanza(identifier, 1.25 SECONDS);
|
||||||
|
|
|
||||||
|
|
@ -274,10 +274,7 @@ XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
|
||||||
x = XMPPFormifyCommand(m, cmd, from);
|
x = XMPPFormifyCommand(m, cmd, from);
|
||||||
XMLAddChild(command_xml, x);
|
XMLAddChild(command_xml, x);
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, iq);
|
||||||
XMLEncode(jabber->stream, iq);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(iq);
|
XMLFreeElement(iq);
|
||||||
|
|
||||||
goto end;
|
goto end;
|
||||||
|
|
@ -305,10 +302,7 @@ XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
|
||||||
XMPPExecuteCommand(m, cmd, from, command_xml, NULL);
|
XMPPExecuteCommand(m, cmd, from, command_xml, NULL);
|
||||||
XMLAddChild(iq, command_xml);
|
XMLAddChild(iq, command_xml);
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, iq);
|
||||||
XMLEncode(jabber->stream, iq);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(iq);
|
XMLFreeElement(iq);
|
||||||
|
|
||||||
InvalidateSession(m, session_id);
|
InvalidateSession(m, session_id);
|
||||||
|
|
@ -348,10 +342,7 @@ XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
|
||||||
XMPPExecuteCommand(m, cmd, from, command_xml, x_form);
|
XMPPExecuteCommand(m, cmd, from, command_xml, x_form);
|
||||||
XMLAddChild(iq, command_xml);
|
XMLAddChild(iq, command_xml);
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, iq);
|
||||||
XMLEncode(jabber->stream, iq);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(iq);
|
XMLFreeElement(iq);
|
||||||
|
|
||||||
InvalidateSession(m, session_given);
|
InvalidateSession(m, session_given);
|
||||||
|
|
|
||||||
|
|
@ -72,11 +72,7 @@ PEPAvatarEvent(PEPManager *m, XMLElement *stanza, XMLElement *item)
|
||||||
char *url = HashMapGet(item->attrs, "url");
|
char *url = HashMapGet(item->attrs, "url");
|
||||||
XMLElement *request = CreateAvatarRequest(from, to, id);
|
XMLElement *request = CreateAvatarRequest(from, to, id);
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, request);
|
||||||
XMLEncode(jabber->stream, request);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
|
|
||||||
XMLFreeElement(request);
|
XMLFreeElement(request);
|
||||||
|
|
||||||
(void) url; /* TODO */
|
(void) url; /* TODO */
|
||||||
|
|
|
||||||
|
|
@ -113,10 +113,7 @@ PEPVCardEvent(PEPManager *m, XMLElement *stanza, XMLElement *item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, reply);
|
||||||
XMLEncode(jabber->stream, reply);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(reply);
|
XMLFreeElement(reply);
|
||||||
(void) item;
|
(void) item;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,11 +131,7 @@ ParseeBroadcastStanza(ParseeData *data, char *from, XMLElement *stanza)
|
||||||
/* TODO: Should we store IDs somewhere? */
|
/* TODO: Should we store IDs somewhere? */
|
||||||
XMLAddAttr(sub, "id", (storm_id = StrRandom(16)));
|
XMLAddAttr(sub, "id", (storm_id = StrRandom(16)));
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, sub);
|
||||||
XMLEncode(jabber->stream, sub);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
|
|
||||||
XMLFreeElement(sub);
|
XMLFreeElement(sub);
|
||||||
Free(storm_id);
|
Free(storm_id);
|
||||||
end:
|
end:
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,7 @@ ParseeXMPPThread(void *argp)
|
||||||
stanza = XMLDecode(jabber->stream, false);
|
stanza = XMLDecode(jabber->stream, false);
|
||||||
if (!stanza)
|
if (!stanza)
|
||||||
{
|
{
|
||||||
|
/* Try to check if an error is abound */
|
||||||
if (args->verbosity >= PARSEE_VERBOSE_COMICAL)
|
if (args->verbosity >= PARSEE_VERBOSE_COMICAL)
|
||||||
{
|
{
|
||||||
Log(LOG_DEBUG, "RECEIVED EOF.");
|
Log(LOG_DEBUG, "RECEIVED EOF.");
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,14 @@ GenerateAvatarData(ParseeData *data, char *mxid)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
b64 = Base64Encode(out, len);
|
b64 = Base64Encode(out, len);
|
||||||
|
if (!b64 || strlen(b64) > 64 KB) /* We still have stanza limitations. Thanks, Array.
|
||||||
|
* TODO: Communicate with the server to discover it. */
|
||||||
|
{
|
||||||
|
Free(b64);
|
||||||
|
Free(mime);
|
||||||
|
b64 = StrDuplicate(media_parsee_logo); /* TODO: Different assets! */
|
||||||
|
mime = StrDuplicate("image/png");
|
||||||
|
}
|
||||||
|
|
||||||
elem = XMLCreateTag("PHOTO");
|
elem = XMLCreateTag("PHOTO");
|
||||||
type = XMLCreateTag("TYPE");
|
type = XMLCreateTag("TYPE");
|
||||||
|
|
@ -145,11 +153,7 @@ IQDiscoGet(ParseeData *args, XMPPComponent *jabber, XMLElement *stanza)
|
||||||
}
|
}
|
||||||
XMLAddChild(iq_reply, query);
|
XMLAddChild(iq_reply, query);
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, iq_reply);
|
||||||
XMLEncode(jabber->stream, iq_reply);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
|
|
||||||
XMLFreeElement(iq_reply);
|
XMLFreeElement(iq_reply);
|
||||||
|
|
||||||
(void) args;
|
(void) args;
|
||||||
|
|
@ -386,10 +390,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
XMPPShoveCommandList(thr->info->m, to, q);
|
XMPPShoveCommandList(thr->info->m, to, q);
|
||||||
XMLAddChild(iq_reply, q);
|
XMLAddChild(iq_reply, q);
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, iq_reply);
|
||||||
XMLEncode(jabber->stream, iq_reply);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(iq_reply);
|
XMLFreeElement(iq_reply);
|
||||||
}
|
}
|
||||||
else if (XMLookForTKV(stanza, "vCard", "xmlns", "vcard-temp"))
|
else if (XMLookForTKV(stanza, "vCard", "xmlns", "vcard-temp"))
|
||||||
|
|
@ -427,10 +428,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
XMLAddChild(iqVCard, vCard);
|
XMLAddChild(iqVCard, vCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, iqVCard);
|
||||||
XMLEncode(jabber->stream, iqVCard);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(iqVCard);
|
XMLFreeElement(iqVCard);
|
||||||
Free(to_matrix);
|
Free(to_matrix);
|
||||||
Free(name);
|
Free(name);
|
||||||
|
|
@ -457,10 +455,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
XMLAddChild(iqVCard, vCard);
|
XMLAddChild(iqVCard, vCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, iqVCard);
|
||||||
XMLEncode(jabber->stream, iqVCard);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(iqVCard);
|
XMLFreeElement(iqVCard);
|
||||||
Free(to_matrix);
|
Free(to_matrix);
|
||||||
Free(name);
|
Free(name);
|
||||||
|
|
@ -474,7 +469,10 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
);
|
);
|
||||||
if (a_items)
|
if (a_items)
|
||||||
{
|
{
|
||||||
/* Do, without regret, start shoving an avatar out the bus */
|
/* Do, without regret, start shoving an avatar out the bus.
|
||||||
|
* NOTE: I explicitely choose to not do any manipulation
|
||||||
|
* because messing with random user images is inherently a
|
||||||
|
* risk I do *not* want to take. */
|
||||||
char *to_matrix = ParseeDecodeMXID(to);
|
char *to_matrix = ParseeDecodeMXID(to);
|
||||||
char *avatar = ASGetAvatar(args->config, NULL, to_matrix);
|
char *avatar = ASGetAvatar(args->config, NULL, to_matrix);
|
||||||
char *buf, *mime;
|
char *buf, *mime;
|
||||||
|
|
@ -484,6 +482,13 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
|
|
||||||
ASGrab(args->config, avatar, &mime, &buf, &len);
|
ASGrab(args->config, avatar, &mime, &buf, &len);
|
||||||
b64 = Base64Encode(buf, len);
|
b64 = Base64Encode(buf, len);
|
||||||
|
if (!b64 || strlen(b64) > 64 KB)
|
||||||
|
{
|
||||||
|
Free(b64);
|
||||||
|
Free(mime);
|
||||||
|
b64 = StrDuplicate(media_parsee_logo); /* TODO: Different assets! */
|
||||||
|
mime = StrDuplicate("image/png");
|
||||||
|
}
|
||||||
Free(buf);
|
Free(buf);
|
||||||
|
|
||||||
Log(LOG_DEBUG, "IQ-GET: PUBSUB AVATAR OF=%s", to_matrix);
|
Log(LOG_DEBUG, "IQ-GET: PUBSUB AVATAR OF=%s", to_matrix);
|
||||||
|
|
@ -513,10 +518,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
XMLAddChild(reply, ps);
|
XMLAddChild(reply, ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, reply);
|
||||||
XMLEncode(jabber->stream, reply);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(reply);
|
XMLFreeElement(reply);
|
||||||
|
|
||||||
Free(to_matrix);
|
Free(to_matrix);
|
||||||
|
|
@ -554,10 +556,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
XMLAddChild(query, version);
|
XMLAddChild(query, version);
|
||||||
XMLAddChild(iq_reply, query);
|
XMLAddChild(iq_reply, query);
|
||||||
|
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, iq_reply);
|
||||||
XMLEncode(jabber->stream, iq_reply);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(iq_reply);
|
XMLFreeElement(iq_reply);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -370,19 +370,13 @@ end_error:
|
||||||
ps = CreatePubsubRequest(
|
ps = CreatePubsubRequest(
|
||||||
parsee, decode_from, "urn:xmpp:avatar:metadata"
|
parsee, decode_from, "urn:xmpp:avatar:metadata"
|
||||||
);
|
);
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, ps);
|
||||||
XMLEncode(jabber->stream, ps);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(ps);
|
XMLFreeElement(ps);
|
||||||
|
|
||||||
ps = CreatePubsubRequest(
|
ps = CreatePubsubRequest(
|
||||||
parsee, trim, "urn:xmpp:avatar:metadata"
|
parsee, trim, "urn:xmpp:avatar:metadata"
|
||||||
);
|
);
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
XMPPSendStanza(jabber, ps);
|
||||||
XMLEncode(jabber->stream, ps);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
XMLFreeElement(ps);
|
XMLFreeElement(ps);
|
||||||
if (args->verbosity >= PARSEE_VERBOSE_TIMINGS)
|
if (args->verbosity >= PARSEE_VERBOSE_TIMINGS)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -158,13 +158,17 @@ PresenceStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
char *room = ParseeGetBridgedRoom(args, stanza);
|
char *room = ParseeGetBridgedRoom(args, stanza);
|
||||||
char *decode_from, *real_matrix;
|
char *decode_from, *real_matrix;
|
||||||
char *matrix_user_pl = ParseeEncodeJID(args->config, trim, false);
|
char *matrix_user_pl = ParseeEncodeJID(args->config, trim, false);
|
||||||
char *affiliation = HashMapGet(item->attrs, "affiliation");
|
char *affiliation = item ? HashMapGet(item->attrs, "affiliation") : NULL;
|
||||||
char *role = HashMapGet(item->attrs, "role");
|
char *role = item ? HashMapGet(item->attrs, "role") : NULL;
|
||||||
int power_level = 0;
|
int power_level = 0;
|
||||||
char *parsee = ParseeMXID(args);
|
char *parsee = ParseeMXID(args);
|
||||||
char *parsee_j = ParseeJID(args);
|
char *parsee_j = ParseeJID(args);
|
||||||
|
|
||||||
Free(trim);
|
Free(trim);
|
||||||
|
if (!item)
|
||||||
|
{
|
||||||
|
goto end_item;
|
||||||
|
}
|
||||||
|
|
||||||
if (jid)
|
if (jid)
|
||||||
{
|
{
|
||||||
|
|
@ -280,7 +284,7 @@ PresenceStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
Free(chat_id);
|
Free(chat_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
end_item:
|
||||||
Free(from);
|
Free(from);
|
||||||
Free(decode_from);
|
Free(decode_from);
|
||||||
Free(real_matrix);
|
Free(real_matrix);
|
||||||
|
|
@ -376,11 +380,8 @@ PresenceStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
|
||||||
vcard_request = CreateVCardRequest(
|
vcard_request = CreateVCardRequest(
|
||||||
from, HashMapGet(stanza->attrs, "from")
|
from, HashMapGet(stanza->attrs, "from")
|
||||||
);
|
);
|
||||||
pthread_mutex_lock(&jabber->write_lock);
|
|
||||||
XMLEncode(jabber->stream, vcard_request);
|
|
||||||
StreamFlush(jabber->stream);
|
|
||||||
pthread_mutex_unlock(&jabber->write_lock);
|
|
||||||
|
|
||||||
|
XMPPSendStanza(jabber, vcard_request);
|
||||||
XMLFreeElement(vcard_request);
|
XMLFreeElement(vcard_request);
|
||||||
Free(from);
|
Free(from);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ typedef struct ParseeConfig {
|
||||||
char *component_host;
|
char *component_host;
|
||||||
char *shared_comp_secret;
|
char *shared_comp_secret;
|
||||||
int component_port;
|
int component_port;
|
||||||
|
size_t max_stanza_size;
|
||||||
|
|
||||||
/* ------- DB -------- */
|
/* ------- DB -------- */
|
||||||
char *db_path;
|
char *db_path;
|
||||||
|
|
@ -80,6 +81,7 @@ typedef struct Argument {
|
||||||
const char *description;
|
const char *description;
|
||||||
} Argument;
|
} Argument;
|
||||||
|
|
||||||
|
/* A few helpful macros to make JSON less of a PITA */
|
||||||
#define GrabString(obj, ...) JsonValueAsString(JsonGet(obj, __VA_ARGS__))
|
#define GrabString(obj, ...) JsonValueAsString(JsonGet(obj, __VA_ARGS__))
|
||||||
#define GrabInteger(obj, ...) JsonValueAsInteger(JsonGet(obj, __VA_ARGS__))
|
#define GrabInteger(obj, ...) JsonValueAsInteger(JsonGet(obj, __VA_ARGS__))
|
||||||
#define GrabBoolean(obj, ...) JsonValueAsBoolean(JsonGet(obj, __VA_ARGS__))
|
#define GrabBoolean(obj, ...) JsonValueAsBoolean(JsonGet(obj, __VA_ARGS__))
|
||||||
|
|
@ -114,6 +116,9 @@ extern void ParseePrintASCII(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if two versions of Parsee can be considered "compatible".
|
* Checks if two versions of Parsee can be considered "compatible".
|
||||||
|
* This is mainly used for things like database operations. TODO:
|
||||||
|
* Make an auto-upgrade system to comply with the (undocumented)
|
||||||
|
* rule of "Don't Make The Sysadmin Think About Parsee Too Much".
|
||||||
* ---------------
|
* ---------------
|
||||||
* Modifies: NOTHING */
|
* Modifies: NOTHING */
|
||||||
extern bool ParseeIsCompatible(char *ver1, char *ver2);
|
extern bool ParseeIsCompatible(char *ver1, char *ver2);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include <Cytoplasm/Stream.h>
|
#include <Cytoplasm/Stream.h>
|
||||||
|
|
||||||
/* Creates a string stream writer. The referenced buffer must be in the heap,
|
/* Creates a string stream writer. The referenced buffer must be in the heap,
|
||||||
* or NULL. */
|
* or NULL for an empty string. */
|
||||||
extern Stream * StrStreamWriter(char **buffer);
|
extern Stream * StrStreamWriter(char **buffer);
|
||||||
|
|
||||||
/* Creates a string stream reader. The referenced buffer may be everywhere. */
|
/* Creates a string stream reader. The referenced buffer may be everywhere. */
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,13 @@ extern XMPPComponent * XMPPInitialiseCompStream(char *host, int port);
|
||||||
* after XMPPInitialiseCompStream. */
|
* after XMPPInitialiseCompStream. */
|
||||||
extern bool XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared);
|
extern bool XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared);
|
||||||
|
|
||||||
|
/** Writes an XML stanza through a component, while making sure any locking
|
||||||
|
* work is done.
|
||||||
|
* -----------------------
|
||||||
|
* Modifies: {comp}, the XMPP stream
|
||||||
|
* See-Also: XMPPInitialiseCompStream, XMPPAuthenticateCompStream, XMPP-core RFC */
|
||||||
|
extern void XMPPSendStanza(XMPPComponent *comp, XMLElement *stanza);
|
||||||
|
|
||||||
/* Makes a user join/leave a MUC */
|
/* Makes a user join/leave a MUC */
|
||||||
extern bool XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, int secs, bool ret);
|
extern bool XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, int secs, bool ret);
|
||||||
extern void XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *r);
|
extern void XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *r);
|
||||||
|
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
# Makefile for building Parsee
|
|
||||||
# ================================
|
|
||||||
# TODO: Consider making something akin to a configure script that checks
|
|
||||||
# for dependencies, or maybe even use *autoconf* (the devil!)
|
|
||||||
|
|
||||||
|
|
||||||
# =========================== Parsee Flags =============================
|
|
||||||
NAME=Parsee
|
|
||||||
VERSION=0.0.0
|
|
||||||
REPOSITORY=$(shell git remote get-url origin)
|
|
||||||
|
|
||||||
# =========================== Compilation Flags ============================
|
|
||||||
CYTO_INC=/usr/local/include/ # Where Cytoplasm's include path is
|
|
||||||
# located.
|
|
||||||
CYTO_LIB=/usr/local/lib # Where's Cytoplasm's library is
|
|
||||||
# located.
|
|
||||||
|
|
||||||
SOURCE=.
|
|
||||||
OBJECT=out
|
|
||||||
CC=cc
|
|
||||||
CFLAGS=-I$(SOURCE) -I$(CYTO_INC) -DNAME="\"$(NAME)\"" -DVERSION="\"$(VERSION)\"" -DREPOSITORY=\"$(REPOSITORY)\" -g -ggdb -Wall -Werror
|
|
||||||
LDFLAGS=-L $(CYTO_LIB) -lCytoplasm -g -ggdb
|
|
||||||
# ============================ Compilation =================================
|
|
||||||
SRC_FILES:=$(shell find $(SOURCE) -name '*.c')
|
|
||||||
OBJ_FILES:=${subst $(SOURCE)/,$(OBJECT)/,$(patsubst %.c, %, $(SRC_FILES))}
|
|
||||||
|
|
||||||
all: $(OBJ_FILES)
|
|
||||||
|
|
||||||
$(OBJECT)/%: $(SOURCE)/%.c
|
|
||||||
@mkdir -p $(shell dirname "$@")
|
|
||||||
$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf $(OBJECT)
|
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue