mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 10:45:11 +00:00
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...
434 lines
14 KiB
C
434 lines
14 KiB
C
#ifndef PARSEE_PARSEE_H
|
|
#define PARSEE_PARSEE_H
|
|
|
|
/*-* <p>Some fields used as Parsee-specific functions/structures.</p>
|
|
* <p>TODO: Consider separating some declarations here...</p>
|
|
* --------
|
|
* Writren-By: LDA */
|
|
typedef struct ParseeData ParseeData;
|
|
|
|
#include <Cytoplasm/HttpServer.h>
|
|
#include <Cytoplasm/HttpRouter.h>
|
|
#include <Cytoplasm/HttpClient.h>
|
|
#include <Cytoplasm/Stream.h>
|
|
#include <Cytoplasm/Db.h>
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <Command.h>
|
|
#include <XMPP.h>
|
|
|
|
#define PARSEE_VERBOSE_NONE 0
|
|
#define PARSEE_VERBOSE_LOG 1
|
|
#define PARSEE_VERBOSE_TIMINGS 2
|
|
#define PARSEE_VERBOSE_STANZA 3
|
|
#define PARSEE_VERBOSE_COMICAL 53 /* MINUTES */
|
|
|
|
typedef struct ParseeConfig {
|
|
/* -------- MATRIX -------- */
|
|
char *as_token, *hs_token;
|
|
/* id here is "Parsee XMPP". */
|
|
char *sender_localpart;
|
|
char *namespace_base;
|
|
|
|
char *server_base;
|
|
char *listen_as;
|
|
char *media_base;
|
|
int port;
|
|
|
|
/* Homeserver port info */
|
|
char *homeserver_host;
|
|
int homeserver_port;
|
|
|
|
|
|
/* ------- JABBER -------- */
|
|
char *component_host;
|
|
char *shared_comp_secret;
|
|
int component_port;
|
|
size_t max_stanza_size;
|
|
|
|
/* ------- DB -------- */
|
|
char *db_path;
|
|
size_t db_size;
|
|
|
|
/* - COMMAND-LINE FLAGS - */
|
|
int xmpp_threads, http_threads;
|
|
} ParseeConfig;
|
|
|
|
typedef struct ParseeData {
|
|
const ParseeConfig *config;
|
|
HttpRouter *router;
|
|
CommandRouter *handler;
|
|
|
|
XMPPComponent *jabber;
|
|
|
|
Db *db;
|
|
char *id;
|
|
|
|
int verbosity;
|
|
|
|
HashMap *oid_servers;
|
|
pthread_mutex_t oidl;
|
|
} ParseeData;
|
|
|
|
typedef struct Argument {
|
|
bool end;
|
|
|
|
char argument;
|
|
bool value_req;
|
|
|
|
const char *value_descr;
|
|
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__))
|
|
#define GrabObject(obj, ...) JsonValueAsObject(JsonGet(obj, __VA_ARGS__))
|
|
#define GrabArray(obj, ...) JsonValueAsArray(JsonGet(obj, __VA_ARGS__))
|
|
|
|
/* Milliseconds to UNIT macros, to be used like 30 SECONDS and 1 MINUTES
|
|
* in timestamps */
|
|
#define SECONDS * 1000
|
|
#define MINUTES * 60 SECONDS
|
|
#define HOURS * 60 MINUTES
|
|
|
|
/* Size units(using 2^10 as a reference), to be used like the time units */
|
|
#define B * 1
|
|
#define KB * 1024 B
|
|
#define MB * 1024 KB
|
|
#define GB * 1024 MB
|
|
|
|
/* A base64-encoded Parsee logo */
|
|
extern const char media_parsee_logo[];
|
|
|
|
/* An ASCII-art rendition of "小橋".
|
|
* I'm sorry for its quality. If anyone wants to redraw it, feel free. */
|
|
#define PARSEE_ASCII_LINES 8
|
|
extern const char *parsee_ascii[PARSEE_ASCII_LINES];
|
|
|
|
/**
|
|
* Prints the Parsee ASCII logo.
|
|
* ------------
|
|
* Modifies: the logger output */
|
|
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);
|
|
|
|
/** Generates a valid, getopt-style argument list from a end-terminated
|
|
* argument list.
|
|
* ------------
|
|
* Returns: a valid string to be used in getopt and the likes[HEAP]
|
|
* Modifies: NOTHING */
|
|
extern char * ParseeGenerateGetopt(const Argument *list);
|
|
|
|
/** Generates a help screen to the logger.
|
|
* ------------
|
|
* Returns: NOTHING
|
|
* Modifies: NOTHING */
|
|
extern void ParseeGenerateHelp(const Argument *list);
|
|
|
|
/** Generates a hexadecimal version of the SHA-256 digest of the
|
|
* original string.
|
|
* ----------------
|
|
* Returns: a hexadecimal string[HEAP]
|
|
* Modifies: NOTHING */
|
|
extern char * ParseeSHA256(char *string);
|
|
|
|
/** Generates a hexadecimal version of the SHA-1 digest of the
|
|
* original string.
|
|
* ----------------
|
|
* Returns: a hexadecimal string[HEAP]
|
|
* Modifies: NOTHING */
|
|
extern char * ParseeSHA1(char *string);
|
|
|
|
/* Initialises a Parsee config from scratch, and writes to it
|
|
* as JSON in the CWD. */
|
|
extern void ParseeConfigInit(void);
|
|
|
|
/* Loads a Parsee config from a JSON filepath. */
|
|
extern void ParseeConfigLoad(char *);
|
|
|
|
/* Retrieves the Parsee config if loaded. */
|
|
extern const ParseeConfig * ParseeConfigGet(void);
|
|
|
|
/* Exports the Parsee config as a YAML document. */
|
|
extern void ParseeExportConfigYAML(Stream *);
|
|
|
|
/* Destroys the Parsee configuration */
|
|
extern void ParseeConfigFree(void);
|
|
|
|
/* Creates and destroys a data structure, stored on the heap. */
|
|
extern ParseeData * ParseeInitData(XMPPComponent *);
|
|
extern void ParseeFreeData(ParseeData *);
|
|
|
|
extern HttpClientContext * ParseeCreateRequest(const ParseeConfig *, HttpRequestMethod, char *);
|
|
|
|
/* Sends headers, and writes the JSON object. */
|
|
extern HttpStatus ParseeSetRequestJSON(HttpClientContext *, HashMap *);
|
|
|
|
/* This function is called on every event received, and routes/manages it. */
|
|
extern void ParseeEventHandler(ParseeData *, HashMap *);
|
|
|
|
/* Verifies if a user is a Parsee puppet user. */
|
|
extern bool ParseeIsPuppet(const ParseeConfig *, char *);
|
|
|
|
/* Decodes a local JID for a user into a string. */
|
|
extern char * ParseeDecodeLocalJID(const ParseeConfig *, char *);
|
|
|
|
/* Encodes a JID into a Parsee localpart */
|
|
extern char * ParseeEncodeJID(const ParseeConfig *, char *, bool);
|
|
|
|
/* Gets the localpart of a MXID */
|
|
extern char * ParseeGetLocal(char *);
|
|
|
|
/* Encodes an MXID to a valid Jabber ID head */
|
|
extern char * ParseeEncodeMXID(char *);
|
|
|
|
/* Decodes a Jabber ID head into a valid MXID */
|
|
extern char * ParseeDecodeMXID(char *);
|
|
|
|
|
|
/** Callback function for the Parsee HTTP handler, to be used by
|
|
* the HTTP thread itself.
|
|
* --------
|
|
* UB-If: not used as the HTTP callback function
|
|
* Returns: NOTHING */
|
|
extern void ParseeRequest(HttpServerContext *, void *);
|
|
|
|
/* A pthread callback used for listening to a component */
|
|
extern void * ParseeXMPPThread(void *data);
|
|
|
|
/** Wait for any stanza with an "id" attribute of {identifier},
|
|
* with an optional timeout in milliseconds of {ts} if it is positive.
|
|
* --------
|
|
* UB-If: called in the XMPP dispatcher thread itself
|
|
* Returns: NULL | XMLElement[LA:HEAP]
|
|
* Modifies: NONE */
|
|
extern XMLElement * ParseeAwaitStanza(char *identifier, int64_t ts);
|
|
|
|
/** Returns the amount of unprocessed stanzas in the XMPP thread, which
|
|
* can be used by admins to guess load.
|
|
* --------
|
|
* UB-If: called in the XMPP dispatcher thread itself
|
|
* Returns: amount of stanzas in the FIFO
|
|
* Modifies: NONE */
|
|
extern size_t ParseeCongestion(void);
|
|
|
|
/* Finds the room a DM is associated to, from a Matrix user and a Jabber
|
|
* ID. */
|
|
extern char * ParseeFindDMRoom(ParseeData *data, char *mxid, char *jid);
|
|
|
|
/* Gets a DM ID from a Matrix and Jabber user */
|
|
extern char * ParseeGetDMID(char *mxid, char *jid);
|
|
|
|
/** Creates a DM mapping in the database.
|
|
* -------------------------
|
|
* Modifies: the Parsee database
|
|
* See-Also: ParseeDeleteDM */
|
|
extern void ParseePushDMRoom(ParseeData *, char *mxid, char *jid, char *r);
|
|
|
|
/** Destroys a DM mapping from the database, making it effectively non-existant.
|
|
* ---------------------
|
|
* Modifies: the Parsee database
|
|
* See-Also: ParseePushDMRoom */
|
|
extern void ParseeDeleteDM(ParseeData *data, char *mxid, char *jid);
|
|
|
|
/* Trims the component from a JID */
|
|
extern char * ParseeTrimJID(char *jid);
|
|
|
|
/* Gets the component from a JID */
|
|
extern char * ParseeGetResource(char *jid);
|
|
|
|
/* Decodes a room alias into a MUC JID */
|
|
extern char * ParseeDecodeLocalMUC(const ParseeConfig *c, char *alias);
|
|
|
|
/* Decodes an encoded string(from an MXID/Room ID) into a JID */
|
|
extern char * ParseeDecodeJID(char *str, char term);
|
|
|
|
/* Creates a Room/MUC mapping, and returns it's chat ID. */
|
|
extern char * ParseePushMUC(ParseeData *, char *room_id, char *jid);
|
|
|
|
/* Finds a chat ID from a MUC JID */
|
|
extern char * ParseeGetFromMUCID(ParseeData *, char *jid);
|
|
|
|
/* Finds a chat ID from a room ID */
|
|
extern char * ParseeGetFromRoomID(ParseeData *, char *room_id);
|
|
|
|
/* Finds the room ID from a chat ID */
|
|
extern char * ParseeGetRoomID(ParseeData *, char *chat_id);
|
|
|
|
/* Finds the MUC JID from a chat ID */
|
|
extern char * ParseeGetMUCID(ParseeData *, char *chat_id);
|
|
|
|
/* Pushes a stanza ID to a chat ID */
|
|
extern void ParseePushStanza(ParseeData *, char *chat_id, char *stanza_id, char *origin_id, char *event, char *sender);
|
|
extern void ParseePushDMStanza(ParseeData *, char *room_id, char *stanza_id, char *origin_id, char *event, char *sender);
|
|
|
|
/* Checks if a stanza is not duplicated in a chat ID */
|
|
extern bool ParseeVerifyStanza(ParseeData *, char *chat_id, char *stanza_id);
|
|
|
|
/* Gets the stanza ID and sender of an event */
|
|
extern bool ParseeGetStanzaInfo(ParseeData *, char *c_id, char *e, char **st, char **se);
|
|
extern bool ParseeGetDMStanzaInfo(ParseeData *, char *r_id, char *e, char **st, char **se);
|
|
extern bool ParseeGetOrigin(ParseeData *data, char *chat_id, char *ev, char **o);
|
|
extern bool ParseeGetDMOrigin(ParseeData *data, char *chat_id, char *ev, char **o);
|
|
|
|
/* Sends presence requests for every MUC around as a fake JID */
|
|
extern void ParseeSendPresence(ParseeData *);
|
|
|
|
extern bool ParseeInitialiseSignals(HttpServer *, pthread_t, XMPPComponent *);
|
|
|
|
/* Job used to cleanup Parsee data that isn't necessary anymore. */
|
|
extern void ParseeCleanup(void *data);
|
|
|
|
/* Finds the offset of the first line without a '>' at its start. */
|
|
extern int ParseeFindDatastart(char *data);
|
|
|
|
/* Finds the offset of the first line without a '>' at its start(as
|
|
* Unicode codepoints). */
|
|
extern int ParseeFindDatastartU(char *data);
|
|
|
|
|
|
/* XMPP-ifies a message event to XEP-0393 if possible. */
|
|
extern char * ParseeXMPPify(HashMap *event);
|
|
|
|
/* Finds an event ID from an ID in the stanza's attributes */
|
|
extern char * ParseeEventFromID(ParseeData *d, char *c_id, char *ori_id);
|
|
extern char * ParseeEventFromSID(ParseeData *d, char *c_id, char *ori_id);
|
|
|
|
extern char * ParseeDMEventFromID(ParseeData *d, char *r_id, char *ori_id);
|
|
extern char * ParseeDMEventFromSID(ParseeData *d, char *r_id, char *ori_id);
|
|
|
|
/* Gets a Parsee "shim" link to an MXC, usable as unauth for a limited time */
|
|
extern char * ParseeToUnauth(ParseeData *data, char *mxc);
|
|
|
|
extern void ParseeInitialiseOIDTable(void);
|
|
extern void ParseePushOIDTable(char *muc, char *occupant);
|
|
extern char *ParseeLookupOID(char *muc);
|
|
extern void ParseeDestroyOIDTable(void);
|
|
|
|
extern void ParseeInitialiseJIDTable(void);
|
|
extern void ParseePushJIDTable(char *muc, char *bare);
|
|
extern char *ParseeLookupJID(char *muc);
|
|
extern void ParseeDestroyJIDTable(void);
|
|
|
|
extern void ParseeInitialiseHeadTable(void);
|
|
extern void ParseePushHeadTable(char *room, char *id);
|
|
extern char *ParseeLookupHead(char *room);
|
|
extern void ParseeDestroyHeadTable(void);
|
|
|
|
extern void ParseeInitialiseNickTable(void);
|
|
extern void ParseePushNickTable(char *muc, char *mxid, char *nick);
|
|
extern char *ParseeLookupNick(char *muc, char *mxid);
|
|
extern void ParseeDestroyNickTable(void);
|
|
|
|
/** Disables a user/room/MUC's ability to interact from Parsee, and attempts
|
|
* to ban them from rooms where Parsee has the ability to do so ("noflying").
|
|
* ---------------
|
|
* Returns: NOTHING
|
|
* See-Also: ParseeManageBan
|
|
* Modifies: the database */
|
|
extern void ParseeGlobalBan(ParseeData *, char *user, char *reason);
|
|
|
|
/** Verifies if a user was banned globally. If so (and if {room} is set),
|
|
* tries to ban the user from it.
|
|
* ---------------
|
|
* Returns: NOTHING
|
|
* See-Also: ParseeManageBan
|
|
* Modifies: the database */
|
|
extern bool ParseeManageBan(ParseeData *, char *user, char *room);
|
|
|
|
/* Same as ParseeVerifyStanza, but DMs */
|
|
extern bool ParseeVerifyDMStanza(ParseeData *data, char *room_id, char *id);
|
|
|
|
|
|
/** Checks if a Matrix/XMPP user is considered as "administrator" by
|
|
* Parsee.
|
|
* ----------------------
|
|
* Returns: (whenever the user is an admin)
|
|
* Modifies: NOTHING */
|
|
extern bool ParseeIsAdmin(ParseeData *data, char *user);
|
|
|
|
/** Measures Parsee's overall uptime.
|
|
* ----------------
|
|
* Returns: uptime since the call to Main in milliseconds.
|
|
* Modifies: NOTHING */
|
|
extern uint64_t ParseeUptime(void);
|
|
|
|
/** Turns a duration into a nice <code>"X minutes, Y seconds"</code>
|
|
* string.
|
|
* ---------
|
|
* Returns: A human-readable string showing the duration[LA:HEAP]
|
|
* Modifies: NOTHING */
|
|
extern char * ParseeStringifyDate(uint64_t millis);
|
|
|
|
/** Generates the Jabber ID of the main Parsee user available.
|
|
* ----------------------
|
|
* Returns: An XMPP JID[LA:HEAP]
|
|
* Thrasher: Free */
|
|
extern char * ParseeJID(ParseeData *data);
|
|
|
|
/** Generates the MXID of the main Parsee user available.
|
|
* ----------------------
|
|
* Returns: A Matrix ID[LA:HEAP]
|
|
* Thrasher: Free */
|
|
extern char * ParseeMXID(ParseeData *data);
|
|
|
|
/** Prints an _fatal_ and _strange_, error message, then congratulates
|
|
* the user for it(an "achievement").<br/>
|
|
* Use this for errors that have <i>no business</i> happening, at all.
|
|
* NOTE to users: If you see this, <u><i>OPEN AN ISSUE</i></u>.
|
|
* ---------------------------------------------------
|
|
* Returns: NOTHING | NORETURN */
|
|
extern void ParseeAchievement(const char *func, const char *msg, bool die);
|
|
#define Achievement(msg, die) ParseeAchievement(__func__, msg, die)
|
|
|
|
/** Generates a 'matrix.to' URL from a Matrix ID, to be used for
|
|
* linking to a room, user, etc...
|
|
* ----------------------
|
|
* Returns: A Matrix URL[LA:HEAP]
|
|
* Thrasher: Free */
|
|
extern char * ParseeGenerateMTO(char *common_id);
|
|
|
|
/** Sets the amount of XMPP/HTTP threads to use
|
|
* ----------------------
|
|
* Returns: NOTHING
|
|
* Modifies: the Parsee config */
|
|
extern void ParseeSetThreads(int xmpp, int http);
|
|
|
|
/** Computes an HMAC (with SHA-256) with a known key, and a generic message.
|
|
* --------------
|
|
* Returns: a hex representation of the HMAC[HEAP].
|
|
* Thrasher: Free
|
|
* Modifies: NOTHING */
|
|
extern char * ParseeHMAC(char *key, uint8_t *msg, size_t msglen);
|
|
#define ParseeHMACS(key, msg) ParseeHMAC(key, (uint8_t *) msg, strlen(msg))
|
|
|
|
/** Broadcasts a stanza from a user to any that may be interested by it
|
|
* (PEP or subscription)
|
|
* -------------------------------------
|
|
* Returns: NOTHING */
|
|
extern void ParseeBroadcastStanza(ParseeData *data, char *from, XMLElement *s);
|
|
|
|
/** Destroys the mapping between a MUC and a room from a chat ID.
|
|
* ----------------
|
|
* Modifies: the DB's room mappings
|
|
* Returns: NOTHING */
|
|
extern void ParseeUnlinkRoom(ParseeData *data, char *chat_id);
|
|
|
|
/** Verifies if there is no whitelists OR that a MUC's server is whitelisted.
|
|
* ----------------------
|
|
* Returns: if a MUC is to be allowed
|
|
* Modifies: NOTHING */
|
|
extern bool ParseeIsMUCWhitelisted(ParseeData *data, char *muc);
|
|
|
|
#endif
|