From a686449a4d96026d17ccde4ede4254e307d28a7f Mon Sep 17 00:00:00 2001 From: LDA Date: Wed, 17 Jul 2024 23:44:11 +0200 Subject: [PATCH] [FIX] Remove duplicate file sorry bros oh btw mein jid ist lda@freetards.xyz --- src/XMPPThread/XMPPThread.c | 381 ------------------------------------ 1 file changed, 381 deletions(-) delete mode 100644 src/XMPPThread/XMPPThread.c diff --git a/src/XMPPThread/XMPPThread.c b/src/XMPPThread/XMPPThread.c deleted file mode 100644 index 9bc561a..0000000 --- a/src/XMPPThread/XMPPThread.c +++ /dev/null @@ -1,381 +0,0 @@ -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "XMPPThread/internal.h" - -/* Generates a SHA-256 hash of the ver field. */ -char * -XMPPGenerateVer(void) -{ - char *S = NULL; - unsigned char *Sha = NULL; - Array *identities = ArrayCreate(); - Array *features = ArrayCreate(); - size_t i; - - /* Initialise identity table, to be sorted */ -#define IdentitySimple(cat, Type, Name) { \ - XMPPIdentity *id = Malloc(sizeof(*id)); \ - id->category = cat; \ - id->lang = NULL; \ - id->type = Type; \ - id->name = Name; \ - ArrayAdd(identities, id); } - IQ_IDENTITY -#undef IdentitySimple -#define AdvertiseSimple(feature) ArrayAdd(features, feature); - IQ_ADVERT -#undef AdvertiseSimple - ArraySort(identities, IdentitySort); - for (i = 0; i < ArraySize(identities); i++) - { - XMPPIdentity *identity = ArrayGet(identities, i); - char *id_chunk = StrConcat(7, - identity->category, "/", - identity->type, "/", - identity->lang, "/", - identity->name); - char *tmp = S; - S = StrConcat(3, S, id_chunk, "<"); - Free(tmp); - Free(id_chunk); - } - - ArraySort(features, ((int (*) (void *, void *)) ICollate)); - for (i = 0; i < ArraySize(features); i++) - { - char *feature = ArrayGet(features, i); - char *tmp = S; - S = StrConcat(3, S, feature, "<"); - Free(tmp); - } - - Sha = Sha1(S); - Free(S); - S = Base64Encode((const char *) Sha, 20); - Free(Sha); - - ArrayFree(features); - for (i = 0; i < ArraySize(identities); i++) - { - XMPPIdentity *identity = ArrayGet(identities, i); - /* We don't have to do anything here. */ - Free(identity); - } - ArrayFree(identities); - - return S; -} - -XMLElement * -RetrieveStanza(XMPPThread *thread) -{ - XMLElement *ret = NULL; - - pthread_mutex_lock(&thread->info->lock); - ret = ArrayDelete(thread->info->stanzas, 0); - pthread_mutex_unlock(&thread->info->lock); - - return ret; -} -static void -PushStanza(XMPPThreadInfo *info, XMLElement *stanza) -{ - pthread_mutex_lock(&info->lock); - ArrayAdd(info->stanzas, stanza); - pthread_mutex_unlock(&info->lock); -} - -static void * -XMPPDispatcher(void *argp) -{ - XMPPThread *thread = argp; - ParseeData *args = thread->info->args; - - while (thread->info->running) - { - XMLElement *stanza = RetrieveStanza(thread); - - /* TODO: I've seen some spikes in some threads. */ - if (!stanza) - { - UtilSleepMillis(5); - continue; - } - - if (StrEquals(stanza->name, "presence")) - { - PresenceStanza(args, stanza); - XMLFreeElement(stanza); - continue; - } - else if (StrEquals(stanza->name, "message")) - { - if (!MessageStanza(args, stanza, thread)) - { - continue; - } - } - else if (StrEquals(stanza->name, "iq")) - { - IQStanza(args, stanza, thread); - } - else - { - Log(LOG_WARNING, "Unknown stanza '%s':", stanza->name); - XMLEncode(StreamStdout(), stanza); - StreamPrintf(StreamStdout(), "\n"); - StreamFlush(StreamStdout()); - } - XMLFreeElement(stanza); - } - - return NULL; -} - -typedef struct XMPPAwait { - pthread_mutex_t cond_lock; - pthread_cond_t condition; - bool usable; - - XMLElement *stanza; -} XMPPAwait; - -static pthread_mutex_t await_lock = PTHREAD_MUTEX_INITIALIZER; -static HashMap *await_table = NULL; -static XMPPThreadInfo info; - -size_t -ParseeCongestion(void) -{ - size_t congestion; - pthread_mutex_lock(&info.lock); - congestion = ArraySize(info.stanzas); - pthread_mutex_unlock(&info.lock); - - return congestion; -} - -void * -ParseeXMPPThread(void *argp) -{ - ParseeData *args = argp; - XMPPComponent *jabber = args->jabber; - XMLElement *stanza = NULL; - size_t i; - - /* Initialise the await table */ - await_table = HashMapCreate(); - - /* Initialise the command manager, and add all ad-hoc commands */ - info.m = XMPPCreateManager(args); - { - XMPPCommand *cmd; -#define XMPP_COMMAND(f,n,t,s) \ - cmd = XMPPBasicCmd( \ - n, t, f \ - ); \ - s \ - XMPPRegisterCommand(info.m, cmd); - XMPPCOMMANDS -#undef XMPP_COMMAND - } - - /* Initialise the FIFO */ - info.stanzas = ArrayCreate(); - pthread_mutex_init(&info.lock, NULL); - - /* ... and its readers. */ - /* TODO: Make that configurable. */ - info.available_dispatchers = 16; - info.dispatchers = Malloc( - sizeof(*info.dispatchers) * info.available_dispatchers - ); - - info.args = args; - info.jabber = jabber; - info.running = true; - pthread_mutex_init(&info.chk_lock, NULL); - - for (i = 0; i < info.available_dispatchers; i++) - { - pthread_t *thr = &info.dispatchers[i].thr; - info.dispatchers[i].info = &info; - - pthread_create(thr, NULL, XMPPDispatcher, &info.dispatchers[i]); - } - - while (true) - { - char *id; - - stanza = XMLDecode(jabber->stream, false); - if (!stanza) - { - break; - } - - id = HashMapGet(stanza->attrs, "id"); - if (id) - { - XMPPAwait *await; - /* Lock out the table to see if we're awaiting. */ - pthread_mutex_lock(&await_lock); - if ((await = HashMapGet(await_table, id))) - { - pthread_mutex_lock(&await->cond_lock); - await->stanza = stanza; - pthread_cond_broadcast(&await->condition); - pthread_mutex_unlock(&await->cond_lock); - - HashMapDelete(await_table, id); - - pthread_mutex_unlock(&await_lock); - continue; - } - pthread_mutex_unlock(&await_lock); - } - - /* Push it into the stanza FIFO. A dispatcher thread should then - * be able to freely grab a value(locked by a mutex). We can't make - * dispatchers read stanzas on their own, since that's _not_ how - * streams work, but this should mitigate some issues, and allow a - * few threads to be busy, while the rest of Parsee works. */ - PushStanza(&info, stanza); - } - - info.running = false; - Log(LOG_INFO, "Joining subthreads..."); - for (i = 0; i < info.available_dispatchers; i++) - { - pthread_t thr = info.dispatchers[i].thr; - pthread_join(thr, NULL); - } - Log(LOG_INFO, "Joined subthreads..."); - Free(info.dispatchers); - - for (i = 0; i < ArraySize(info.stanzas); i++) - { - XMLFreeElement(ArrayGet(info.stanzas, i)); - } - ArrayFree(info.stanzas); - - HashMapFree(await_table); - - pthread_mutex_destroy(&info.lock); - - XMPPFreeManager(info.m); - return NULL; -} - -#include -#include - -/* TODO: This function does NIT behave well. */ -XMLElement * -ParseeAwaitStanza(char *identifier, int64_t timeout) -{ - /* TODO: Pthreads HATE me using Malloc here, so I'm abusing stackspace. - * Not *too much* of a problem, just a weird oddity. If anyone has a clue - * on why that happens (at least on ARM64 with a Pi4 running Debian), let - * me know! */ - XMPPAwait awa; - XMLElement *stanza; - struct timespec ts; - if (!identifier) - { - return NULL; - } - - /* Convert into an absolute timeout. - * ================================= - * XXX: For anyone using timespecs: MAKE ABSOLUTELY FUCKING SURE YOUR NANOS - * ARE IN RANGE. THIS UNIRONICALLY CAUSED SOME REAL CONCURRENCY ERRORS ON MY - * SIDE FROM TV_NSEC OVERFLOWING AND TIMEDWAIT RETURNING EINVAL. */ - if (timeout > 0) - { - int64_t seconds = timeout / (1 SECONDS); - int64_t msecond = timeout % (1 SECONDS); - - clock_gettime(CLOCK_REALTIME, &ts); - - ts.tv_sec += seconds ; - ts.tv_nsec+= msecond * 1000000 ; - if (ts.tv_nsec > 999999999) - { - int64_t sec_delta = ts.tv_nsec / 1000000000; - int64_t nsc_delta = ts.tv_nsec % 1000000000; - - ts.tv_nsec = nsc_delta; - ts.tv_sec += sec_delta; - } - - (void) msecond; - } - - pthread_mutex_lock(&await_lock); - - pthread_cond_init(&awa.condition, NULL); - pthread_mutex_init(&awa.cond_lock, NULL); - awa.stanza = NULL; - - HashMapSet(await_table, identifier, &awa); - pthread_mutex_unlock(&await_lock); - - pthread_mutex_lock(&awa.cond_lock); - while (!awa.stanza) - { - int code; - - if (timeout <= 0) - { - pthread_cond_wait(&awa.condition, &awa.cond_lock); - continue; - } - code = pthread_cond_timedwait(&awa.condition, &awa.cond_lock, &ts); - if (code == ETIMEDOUT) - { - /* Timeout detected, give up regardless of the status of our - * search. */ - HashMapDelete(await_table, identifier); - pthread_mutex_unlock(&await_lock); - break; - } - if (code == EINVAL) - { - Log(LOG_ERR, "=========== Achievement GET! ==========="); - Log(LOG_ERR, "%s: TIMEDWAIT RETURNED EINVAL.", __func__); - Log(LOG_ERR, "THIS IS, LET'S SAY, NOT GOOD, AND A SIGN OF "); - Log(LOG_ERR, "A PROGRAMMER ERROR. PLEASE PKILL -9 PARSEE."); - Log(LOG_ERR, ""); - Log(LOG_ERR, "YOU, HOWEVER, GET TO WIN AN AWARD FOR THIS."); - Log(LOG_ERR, "I AM SIMPLY JEALOUS OF YOU GETTING SUCH A "); - Log(LOG_ERR, "GOOD ERROR MESSAGE."); - Log(LOG_ERR, "=========== Achievement GET! ==========="); - } - } - - stanza = awa.stanza; - pthread_mutex_unlock(&awa.cond_lock); - - pthread_cond_destroy(&awa.condition); - pthread_mutex_destroy(&awa.cond_lock); - return stanza; -}