#ifndef PARSEE_PARSEE_H #define PARSEE_PARSEE_H /*-*

Some fields used as Parsee-specific functions/structures.

*

TODO: Consider separating some declarations here...

* -------- * Writren-By: LDA */ typedef struct ParseeData ParseeData; #include #include #include #include #include #include #include #include #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 "X minutes, Y seconds" * 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").
* Use this for errors that have no business happening, at all. * NOTE to users: If you see this, OPEN AN ISSUE. * --------------------------------------------------- * 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