#include #include #include #include #include #include #include #include #include #include static pthread_mutex_t cond_var_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER; void ParseeWakeupThread(void) { pthread_mutex_lock(&cond_var_lock); pthread_cond_signal(&cond_var); pthread_mutex_unlock(&cond_var_lock); } static void ParseeDMHandler(char *room, char *from, XMLElement *data, const ParseeConfig *c) { ASSend( c, room, from, "m.room.message", MatrixCreateMessage(data->data) ); } void * ParseeXMPPThread(void *argp) { ParseeData *args = argp; XMPPComponent *jabber = args->jabber; XMLElement *stanza = NULL; while (true) { XMLElement *body = NULL; XMLElement *data = NULL; XMLElement *stanza_id = NULL; char *to, *room, *from, *from_matrix; char *chat_id, *mroom_id; stanza = XMLDecode(jabber->stream, false); if (!stanza) { continue; } if (StrEquals(stanza->name, "presence")) { XMLFreeElement(stanza); continue; } else if (StrEquals(stanza->name, "message")) { size_t i; if (XMPPIsKiller(stanza)) { const char *killer = "killer"; const char *suspend="suspend"; from = HashMapGet(stanza->attrs, "from"); if (!strncmp(from, killer, strlen(killer))) { XMLFreeElement(stanza); break; } else if (!strncmp(from, suspend, strlen(suspend))) { XMLFreeElement(stanza); pthread_mutex_lock(&cond_var_lock); pthread_cond_wait(&cond_var, &cond_var_lock); pthread_mutex_unlock(&cond_var_lock); continue; } } body = XMLookForUnique(stanza, "body"); if (!body) { XMLFreeElement(stanza); continue; } stanza_id = XMLookForUnique(stanza, "stanza-id"); to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to")); from = HashMapGet(stanza->attrs, "from"); from_matrix = ParseeEncodeJID(args->config, from, true); room = ParseeFindDMRoom(args, to, from); data = ArrayGet(body->children, 0); /* TODO: Consider having rich messages, and move that out * to separate functions */ chat_id = ParseeGetFromMUCID(args, from); mroom_id = ParseeGetRoomID(args, chat_id); if (room) { ParseeDMHandler(room, from_matrix, data, args->config); } if (mroom_id && !XMPPIsParseeStanza(stanza)) { char *res = ParseeGetResource(from); char *encoded = ParseeEncodeJID(args->config, from, false); char *s_id_str = HashMapGet(stanza_id->attrs, "id"); /* TODO: Create smarter puppet names, and send presence * in every room at Parsee's bootup. */ if (ParseeVerifyStanza(args, chat_id, s_id_str)) { ASRegisterUser(args->config, encoded); ASSetName(args->config, encoded, res); ASJoin(args->config, mroom_id, encoded); ASSend( args->config, mroom_id, encoded, "m.room.message", MatrixCreateMessage(data->data) ); ParseePushStanza(args, chat_id, s_id_str); } Free(res); Free(encoded); } Free(chat_id); Free(mroom_id); Free(from_matrix); Free(room); Free(to); } else { Log(LOG_WARNING, "Unknown stanza '%s':", stanza->name); XMLEncode(StreamStdout(), stanza); StreamPrintf(StreamStdout(), "\n"); StreamFlush(StreamStdout()); } XMLFreeElement(stanza); } return NULL; }