[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:
LDA 2024-10-19 16:58:48 +02:00
parent d9b5141eb5
commit ff5f085b7f
24 changed files with 114 additions and 152 deletions

View file

@ -33,7 +33,7 @@ jobs:
- name: Build Parsee
run: |
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
make && make ayadoc
- name: Install Parsee

View file

@ -97,6 +97,9 @@ restricted to Parsee admins, with permission from MUC owners, too
support XMPP->Matrix bridging.
- 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.
- 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
If you know things about XMPP or Matrix, yet aren't familiar with C99, or just

View file

@ -445,10 +445,15 @@ main_build(int argc, char *argv[])
if (repo)
{
char *lf = strchr(repo, '\n');
*lf = '\0';
if (lf)
{
*lf = '\0';
}
}
else
{
repo = strdup("N/A");
}
while ((opt = getopt(argc, argv, "sl")) != -1)
{
@ -465,8 +470,9 @@ main_build(int argc, char *argv[])
}
makefile = fopen("Makefile", "w");
fprintf(makefile, "# Autogenerated POSIX Makefile\n");
fprintf(makefile, "# Ideally do not touch.\n\n");
fprintf(makefile, "# Autogenerated POSIX Makefile from Parsee\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, "include build.conf\n\n");
fprintf(makefile, "AYAYAS=ayaya\n");

View file

@ -40,6 +40,8 @@ FileInfoFromXMPP(XMLElement *stanza)
file = XMLookForTKV(sims,
"file", "xmlns", "urn:xmpp:jingle:apps:file-transfer:5"
);
/* TODO: We'll definitely need MIME types to do things like
* WebXDC */
if (!file)
{
return NULL;

View file

@ -1,5 +1,6 @@
#include <Cytoplasm/HttpServer.h>
#include <Cytoplasm/Cytoplasm.h>
#include <Cytoplasm/Platform.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Util.h>
#include <Cytoplasm/Cron.h>
@ -81,6 +82,13 @@ Main(Array *args, HashMap *env)
Log(LOG_INFO, "=======================");
Log(LOG_INFO, "(C)opyright 2024 LDA");
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());
{

View file

@ -62,6 +62,12 @@ ParseeConfigLoad(char *conf)
CopyToInt(component_port, "component_port");
CopyToStr(component_host, "component_host");
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");

View file

@ -59,6 +59,7 @@ ParseeInitData(XMPPComponent *comp)
{
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, "(Parsee still needs an upgradepath mechanism.)");
DbUnlock(data->db, ref);
DbClose(data->db);
@ -126,8 +127,6 @@ ParseeCleanup(void *datp)
uint64_t ts = UtilTsMillis();
size_t entries = 0;
Log(LOG_DEBUG, "Cleaning up...");
chats = DbList(data->db, 1, "chats");
for (i = 0; i < ArraySize(chats); i++)
@ -242,7 +241,6 @@ ParseeCleanup(void *datp)
DbUnlock(data->db, ref);
}
DbListFree(chats);
Log(LOG_DEBUG, "Cleant up %d entries...", entries);
}
void

View file

@ -25,6 +25,8 @@ SignalHandler(int signal)
if (signal == SIGPIPE)
{
Log(LOG_DEBUG, "Caught a SIGPIPE...");
XMPPFinishCompStream(jabber);
pthread_join(xmpp_thr, NULL);
return;
}
}

View file

@ -237,13 +237,8 @@ WriteoutStanza(StanzaBuilder *builder, XMPPComponent *jabber)
}
elem = ExportStanza(builder);
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, elem);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, elem);
XMLFreeElement(elem);
return;
}
StanzaBuilder *

View file

@ -11,6 +11,7 @@
#include <errno.h>
#include <netdb.h>
#include <StringStream.h>
#include <Parsee.h>
#include <XML.h>
@ -134,7 +135,7 @@ XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared)
}
break;
}
if (ev->type != XML_LEXER_STARTELEM ||
if (!ev || ev->type != XML_LEXER_STARTELEM ||
!StrEquals(ev->element, "stream:stream"))
{
Log(LOG_ERR, "Excepted stream:stream element.");
@ -159,10 +160,9 @@ XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared)
}
break;
}
if (ev->type != XML_LEXER_ELEM ||
if (!ev || ev->type != XML_LEXER_ELEM ||
!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, "Another service (possibly Parsee) may have taken over.");
Log(LOG_ERR, "");
@ -213,3 +213,18 @@ XMPPEndCompStream(XMPPComponent *comp)
Free(comp->host);
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);
}

View file

@ -18,8 +18,6 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
return false;
}
pthread_mutex_lock(&jabber->write_lock);
iq_query = XMLCreateTag("iq");
query = XMLCreateTag("query");
@ -35,8 +33,7 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
{
XMLElement *identity;
XMLEncode(jabber->stream, iq_query);
StreamFlush(jabber->stream);
XMPPSendStanza(jabber, iq_query);
XMLFreeElement(iq_query);
/* 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"))
{
XMLFreeElement(iq_query);
pthread_mutex_unlock(&jabber->write_lock);
return false;
}
query = XMLookForUnique(iq_query, "query");
@ -57,7 +53,6 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
"conference"))
{
XMLFreeElement(iq_query);
pthread_mutex_unlock(&jabber->write_lock);
return false;
}
@ -73,7 +68,6 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
XMLFreeElement(iq_query);
}
}
pthread_mutex_unlock(&jabber->write_lock);
return true;
}
@ -116,7 +110,6 @@ XMPPRequestVoice(XMPPComponent *jabber, char *from, char *muc)
return;
}
pthread_mutex_lock(&jabber->write_lock);
stanza = XMLCreateTag("message");
XMLAddAttr(stanza, "id", (identifier = StrRandom(32)));
XMLAddAttr(stanza, "from", from);
@ -160,9 +153,7 @@ XMPPRequestVoice(XMPPComponent *jabber, char *from, char *muc)
}
XMLAddChild(stanza, x);
}
XMLEncode(jabber->stream, stanza);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, stanza);
XMLFreeElement(stanza);
Free(identifier);
@ -177,8 +168,6 @@ XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc, char *hash, int time, bool
return false;
}
pthread_mutex_lock(&comp->write_lock);
presence = XMLCreateTag("presence");
x = XMLCreateTag("x");
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);
}
XMLEncode(comp->stream, presence);
StreamFlush(comp->stream);
XMPPSendStanza(comp, presence);
XMLFreeElement(presence);
Free(from);
pthread_mutex_unlock(&comp->write_lock);
if (ret && (reply = ParseeAwaitStanza(id, 500)))
{
bool exit_code = true;
@ -246,8 +231,6 @@ XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
return;
}
pthread_mutex_lock(&comp->write_lock);
presence = XMLCreateTag("presence");
XMLAddAttr(presence, "from", (from = StrConcat(3, fr, "@", comp->host)));
XMLAddAttr(presence, "to", muc);
@ -265,12 +248,9 @@ XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
XMPPAnnotatePresence(presence);
XMLEncode(comp->stream, presence);
StreamFlush(comp->stream);
XMPPSendStanza(comp, presence);
XMLFreeElement(presence);
Free(from);
Free(id);
pthread_mutex_unlock(&comp->write_lock);
}

View file

@ -66,13 +66,9 @@ XMPPRetract(XMPPComponent *comp, char *fr, char *to, char *type, char *redact)
}
pthread_mutex_lock(&comp->write_lock);
XMLEncode(comp->stream, message);
StreamFlush(comp->stream);
XMPPSendStanza(comp, message);
XMLFreeElement(message);
pthread_mutex_unlock(&comp->write_lock);
Free(from);
Free(ident);
}
@ -85,6 +81,8 @@ XMPPIsParseeStanza(XMLElement *stanza)
return false;
}
/* TODO: Check if the user is a trustworthy Parsee puppet instead of some
* guy sending random stanzas */
return !!XMLookForUnique(stanza, "x-parsee");
}
@ -266,10 +264,7 @@ XMPPSendDisco(ParseeData *data, char *from, char *to)
XMLAddChild(iq, query);
}
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, iq);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, iq);
XMLFreeElement(iq);
ret = ParseeAwaitStanza(identifier, 1.25 SECONDS);

View file

@ -274,10 +274,7 @@ XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
x = XMPPFormifyCommand(m, cmd, from);
XMLAddChild(command_xml, x);
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, iq);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, iq);
XMLFreeElement(iq);
goto end;
@ -305,10 +302,7 @@ XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
XMPPExecuteCommand(m, cmd, from, command_xml, NULL);
XMLAddChild(iq, command_xml);
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, iq);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, iq);
XMLFreeElement(iq);
InvalidateSession(m, session_id);
@ -348,10 +342,7 @@ XMPPManageCommand(XMPPCommandManager *m, XMLElement *stanza, ParseeData *data)
XMPPExecuteCommand(m, cmd, from, command_xml, x_form);
XMLAddChild(iq, command_xml);
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, iq);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, iq);
XMLFreeElement(iq);
InvalidateSession(m, session_given);

View file

@ -72,11 +72,7 @@ PEPAvatarEvent(PEPManager *m, XMLElement *stanza, XMLElement *item)
char *url = HashMapGet(item->attrs, "url");
XMLElement *request = CreateAvatarRequest(from, to, id);
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, request);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, request);
XMLFreeElement(request);
(void) url; /* TODO */

View file

@ -113,10 +113,7 @@ PEPVCardEvent(PEPManager *m, XMLElement *stanza, XMLElement *item)
}
}
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, reply);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, reply);
XMLFreeElement(reply);
(void) item;
}

View file

@ -131,11 +131,7 @@ ParseeBroadcastStanza(ParseeData *data, char *from, XMLElement *stanza)
/* 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);
XMPPSendStanza(jabber, sub);
XMLFreeElement(sub);
Free(storm_id);
end:

View file

@ -198,6 +198,7 @@ ParseeXMPPThread(void *argp)
stanza = XMLDecode(jabber->stream, false);
if (!stanza)
{
/* Try to check if an error is abound */
if (args->verbosity >= PARSEE_VERBOSE_COMICAL)
{
Log(LOG_DEBUG, "RECEIVED EOF.");

View file

@ -65,6 +65,14 @@ GenerateAvatarData(ParseeData *data, char *mxid)
goto end;
}
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");
type = XMLCreateTag("TYPE");
@ -145,11 +153,7 @@ IQDiscoGet(ParseeData *args, XMPPComponent *jabber, XMLElement *stanza)
}
XMLAddChild(iq_reply, query);
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, iq_reply);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, iq_reply);
XMLFreeElement(iq_reply);
(void) args;
@ -386,10 +390,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
XMPPShoveCommandList(thr->info->m, to, q);
XMLAddChild(iq_reply, q);
}
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, iq_reply);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, iq_reply);
XMLFreeElement(iq_reply);
}
else if (XMLookForTKV(stanza, "vCard", "xmlns", "vcard-temp"))
@ -427,10 +428,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
XMLAddChild(iqVCard, vCard);
}
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, iqVCard);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, iqVCard);
XMLFreeElement(iqVCard);
Free(to_matrix);
Free(name);
@ -457,10 +455,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
XMLAddChild(iqVCard, vCard);
}
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, iqVCard);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, iqVCard);
XMLFreeElement(iqVCard);
Free(to_matrix);
Free(name);
@ -474,7 +469,10 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
);
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 *avatar = ASGetAvatar(args->config, NULL, to_matrix);
char *buf, *mime;
@ -484,6 +482,13 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
ASGrab(args->config, avatar, &mime, &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);
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);
}
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, reply);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, reply);
XMLFreeElement(reply);
Free(to_matrix);
@ -554,10 +556,7 @@ IQGet(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
XMLAddChild(query, version);
XMLAddChild(iq_reply, query);
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, iq_reply);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, iq_reply);
XMLFreeElement(iq_reply);
}
else

View file

@ -370,19 +370,13 @@ end_error:
ps = CreatePubsubRequest(
parsee, decode_from, "urn:xmpp:avatar:metadata"
);
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, ps);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, ps);
XMLFreeElement(ps);
ps = CreatePubsubRequest(
parsee, trim, "urn:xmpp:avatar:metadata"
);
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, ps);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMPPSendStanza(jabber, ps);
XMLFreeElement(ps);
if (args->verbosity >= PARSEE_VERBOSE_TIMINGS)
{

View file

@ -158,13 +158,17 @@ PresenceStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
char *room = ParseeGetBridgedRoom(args, stanza);
char *decode_from, *real_matrix;
char *matrix_user_pl = ParseeEncodeJID(args->config, trim, false);
char *affiliation = HashMapGet(item->attrs, "affiliation");
char *role = HashMapGet(item->attrs, "role");
char *affiliation = item ? HashMapGet(item->attrs, "affiliation") : NULL;
char *role = item ? HashMapGet(item->attrs, "role") : NULL;
int power_level = 0;
char *parsee = ParseeMXID(args);
char *parsee_j = ParseeJID(args);
Free(trim);
if (!item)
{
goto end_item;
}
if (jid)
{
@ -280,7 +284,7 @@ PresenceStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
Free(chat_id);
}
end_item:
Free(from);
Free(decode_from);
Free(real_matrix);
@ -376,11 +380,8 @@ PresenceStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr)
vcard_request = CreateVCardRequest(
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);
Free(from);
}

View file

@ -45,6 +45,7 @@ typedef struct ParseeConfig {
char *component_host;
char *shared_comp_secret;
int component_port;
size_t max_stanza_size;
/* ------- DB -------- */
char *db_path;
@ -80,6 +81,7 @@ typedef struct Argument {
const char *description;
} Argument;
/* A few helpful macros to make JSON less of a PITA */
#define GrabString(obj, ...) JsonValueAsString(JsonGet(obj, __VA_ARGS__))
#define GrabInteger(obj, ...) JsonValueAsInteger(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".
* 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 */
extern bool ParseeIsCompatible(char *ver1, char *ver2);

View file

@ -4,7 +4,7 @@
#include <Cytoplasm/Stream.h>
/* 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);
/* Creates a string stream reader. The referenced buffer may be everywhere. */

View file

@ -29,6 +29,13 @@ extern XMPPComponent * XMPPInitialiseCompStream(char *host, int port);
* after XMPPInitialiseCompStream. */
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 */
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);

View file

@ -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)