+
+#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;
+}