added HandleInfoHandler.c with lookup_authname()
[NeonServV5.git] / HandleInfoHandler.c
diff --git a/HandleInfoHandler.c b/HandleInfoHandler.c
new file mode 100644 (file)
index 0000000..6673552
--- /dev/null
@@ -0,0 +1,117 @@
+
+#include "HandleInfoHandler.h"
+#include "ClientSocket.h"
+#include "UserNode.h"
+#include "IRCEvents.h"
+#include "tools.h"
+
+#define AUTHSERV_NICK "AuthServ"
+
+struct HandleInfoQueueEntry {
+    void *callback;
+    void *data;
+};
+
+static struct HandleInfoQueueEntry *first_entry = NULL, *last_entry = NULL;
+
+static struct HandleInfoQueueEntry* addHandleInfoQueueEntry(struct ClientSocket *client) {
+    struct HandleInfoQueueEntry *entry = malloc(sizeof(*entry));
+    if (!entry)
+    {
+        perror("malloc() failed");
+        return NULL;
+    }
+    entry->next = NULL;
+    entry->client = client;
+    if(last_entry)
+        last_entry->next = entry;
+    else
+        last_entry = entry;
+    if(!first_entry)
+        first_entry = entry;
+    return entry;
+}
+
+static struct HandleInfoQueueEntry* getNextHandleInfoQueueEntry(struct ClientSocket *client, int freeEntry) {
+    if(!first_entry) return NULL;
+    struct HandleInfoQueueEntry *entry;
+    for(entry = first_entry; entry; entry = entry->next) {
+        if(entry->client == client)
+            break;
+    }
+    if(entry == NULL) return NULL;
+    if(freeEntry) {
+        if(entry == first_entry)
+            first_entry = entry->next;
+        if(entry == last_entry) {
+            struct HandleInfoQueueEntry *last;
+            for(last = first_entry; last; last = last->next)
+                if(last->next == NULL) break;
+            last_entry = last;
+        }
+    }
+    return entry;
+}
+
+void lookup_authname(char *auth, authlookup_callback_t callback, void *data) {
+    struct ClientSocket *bot;
+    for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+        if(bot->flags & SOCKET_FLAG_PREFERRED)
+            break;
+    }
+    if(bot == NULL) return;
+    struct HandleInfoQueueEntry* entry = addHandleInfoQueueEntry(bot);
+    entry->callback = callback;
+    entry->data = data;
+    putsock(bot, "PRIVMSG " AUTHSERV_NICK " :HANDLEINFO *%s", auth);
+}
+
+static void recv_notice(struct UserNode *user, struct UserNode *target, char *message) {
+    if(stricmp(user->nick, AUTHSERV_NICK)) return;
+    struct ClientSocket *bot;
+    for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
+        if(bot->user == target) break;
+    }
+    if(!bot) return;
+    char *auth;
+    int match = 0, exists = 0;
+    char *tmp;
+    //messages to parse:
+    //  Account * has not been registered.
+    //  Account information for Skynet:
+    if(!match("Account * has not been registered.", message)) {
+        match = 1;
+        tmp = strstr(message, "\002");
+        auth = tmp+1;
+        tmp = strstr(auth, "\002");
+        *tmp = '\0';
+    }
+    if(!match("Account information for *", message)) {
+        match = 1;
+        exists = 1;
+        tmp = strstr(message, "\002");
+        auth = tmp+1;
+        tmp = strstr(auth, "\002");
+        *tmp = '\0';
+    }
+    if(match) {
+        struct HandleInfoQueueEntry* entry = getNextHandleInfoQueueEntry(client, 1);
+        authlookup_callback_t *callback = entry->callback;
+        callback(auth, exists, entry->data);
+        free(entry);
+    }
+}
+
+void init_handleinfohandler() {
+    bind_privnotice(recv_notice);
+}
+
+void free_handleinfohandler() {
+    struct HandleInfoQueueEntry *entry, *next;
+    for(entry = first_entry; entry; entry = next) {
+        next = entry->next;
+        free(entry);
+    }
+    first_entry = NULL;
+    last_entry = NULL;
+}