--- /dev/null
+
+#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;
+}
--- /dev/null
+#include "tools.h"
+
+/* copied from IRCU 2.10.12 match.c */
+/*
+ * Compare if a given string (name) matches the given
+ * mask (which can contain wild cards: '*' - match any
+ * number of chars, '?' - match any single character.
+ *
+ * return 0, if match
+ * 1, if no match
+ *
+ * Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
+ * Rewritten by Timothy Vogelsang (netski), net@astrolink.org
+ */
+int match(const char *mask, const char *name)
+{
+ const char *m = mask, *n = name;
+ const char *m_tmp = mask, *n_tmp = name;
+ int star_p;
+
+ for (;;) switch (*m) {
+ case '\0':
+ if (!*n)
+ return 0;
+ backtrack:
+ if (m_tmp == mask)
+ return 1;
+ m = m_tmp;
+ n = ++n_tmp;
+ if (*n == '\0')
+ return 1;
+ break;
+ case '\\':
+ m++;
+ /* allow escaping to force capitalization */
+ if (*m++ != *n++)
+ goto backtrack;
+ break;
+ case '*': case '?':
+ for (star_p = 0; ; m++) {
+ if (*m == '*')
+ star_p = 1;
+ else if (*m == '?') {
+ if (!*n++)
+ goto backtrack;
+ } else break;
+ }
+ if (star_p) {
+ if (!*m)
+ return 0;
+ else if (*m == '\\') {
+ m_tmp = ++m;
+ if (!*m)
+ return 1;
+ for (n_tmp = n; *n && *n != *m; n++) ;
+ } else {
+ m_tmp = m;
+ for (n_tmp = n; *n && ToLower(*n) != ToLower(*m); n++) ;
+ }
+ }
+ /* and fall through */
+ default:
+ if (!*n)
+ return *m != '\0';
+ if (ToLower(*m) != ToLower(*n))
+ goto backtrack;
+ m++;
+ n++;
+ break;
+ }
+}
\ No newline at end of file