Merge branch 'development'
[NeonServV5.git] / src / HandleInfoHandler.c
index c194935eab2c4906e7de94904e8e626a58bd4137..8a8a46ce3a0ce205b422c01907c28f62c9e78835 100644 (file)
@@ -1,4 +1,4 @@
-/* HandleInfoHandler.c - NeonServ v5.3
+/* HandleInfoHandler.c - NeonServ v5.6
  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
  * 
  * This program is free software: you can redistribute it and/or modify
 #include "HandleInfoHandler.h"
 #include "ClientSocket.h"
 #include "UserNode.h"
+#include "ChanNode.h"
 #include "IRCEvents.h"
 #include "tools.h"
+#include "modules.h"
+#include "log.h"
 
 #define AUTHSERV_NICK "AuthServ"
 
@@ -28,6 +31,7 @@
 struct HandleInfoQueueEntry {
     char *auth;
     void *callback[MAXCALLBACKS];
+    int module_id[MAXCALLBACKS];
     void *data[MAXCALLBACKS];
     
     struct HandleInfoQueueEntry *next;
@@ -37,20 +41,23 @@ static struct HandleInfoQueueEntry* addHandleInfoQueueEntry(struct ClientSocket
     struct HandleInfoQueueEntry *entry = malloc(sizeof(*entry));
     if (!entry)
     {
-        perror("malloc() failed");
+        printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__);
         return NULL;
     }
+    SYNCHRONIZE(cache_sync);
     entry->next = NULL;
     if(client->handleinfo_last)
         client->handleinfo_last->next = entry;
     else
         client->handleinfo_first = entry;
     client->handleinfo_last = entry;
+    DESYNCHRONIZE(cache_sync);
     return entry;
 }
 
 static struct HandleInfoQueueEntry* getNextHandleInfoQueueEntry(struct ClientSocket *client, int freeEntry) {
     if(!client->handleinfo_first) return NULL;
+    SYNCHRONIZE(cache_sync);
     struct HandleInfoQueueEntry *entry = client->handleinfo_first;
     if(freeEntry) {
         client->handleinfo_first = entry->next;
@@ -58,11 +65,13 @@ static struct HandleInfoQueueEntry* getNextHandleInfoQueueEntry(struct ClientSoc
             client->handleinfo_last = NULL;
         }
     }
+    DESYNCHRONIZE(cache_sync);
     return entry;
 }
 
 void clear_handleinfoqueue(struct ClientSocket *client) {
     if(!client->handleinfo_first) return;
+    SYNCHRONIZE(cache_sync);
     struct HandleInfoQueueEntry *entry, *next;
     for(entry = client->handleinfo_first; entry; entry = next) {
         next = entry->next;
@@ -70,9 +79,10 @@ void clear_handleinfoqueue(struct ClientSocket *client) {
     }
     client->handleinfo_last = NULL;
     client->handleinfo_first = NULL;
+    DESYNCHRONIZE(cache_sync);
 }
 
-void lookup_authname(char *auth, authlookup_callback_t callback, void *data) {
+void lookup_authname(char *auth, int module_id, authlookup_callback_t callback, void *data) {
     struct ClientSocket *bot;
     struct HandleInfoQueueEntry* entry;
     for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
@@ -82,6 +92,7 @@ void lookup_authname(char *auth, authlookup_callback_t callback, void *data) {
                 for(i = 1; i < MAXCALLBACKS; i++) {
                     if(!entry->callback[i]) {
                         entry->callback[i] = callback;
+                        entry->module_id[i] = module_id;
                         entry->data[i] = data;
                         return;
                     }
@@ -96,6 +107,7 @@ void lookup_authname(char *auth, authlookup_callback_t callback, void *data) {
     int i;
     entry->auth = strdup(auth);
     entry->callback[0] = callback;
+    entry->module_id[0] = module_id;
     for(i = 1; i < MAXCALLBACKS; i++)
         entry->callback[i] = NULL;
     entry->data[0] = data;
@@ -114,6 +126,8 @@ static void recv_notice(struct UserNode *user, struct UserNode *target, char *me
     char *auth = NULL;
     int do_match = 0, exists = 0;
     char *tmp;
+    time_t registered = time(0);
+    struct tm *timeinfo;
     //messages to parse:
     //  Account * has not been registered.
     //  Account information for Skynet:
@@ -123,24 +137,100 @@ static void recv_notice(struct UserNode *user, struct UserNode *target, char *me
         auth = tmp+1;
         tmp = strstr(auth, "\002");
         *tmp = '\0';
-    }
-    if(!match("Account information for *", message)) {
-        do_match = 1;
+    } else if(!match("Account information for *", message)) {
+        do_match = 2;
         exists = 1;
         tmp = strstr(message, "\002");
         auth = tmp+1;
         tmp = strstr(auth, "\002");
         *tmp = '\0';
+    } else if(!match("  Registered on: *", message)) {
+        do_match = 1;
+        exists = 1;
+        tmp = strstr(message, ": ");
+        tmp += 2;
+        timeinfo = localtime(&registered);
+        timeinfo->tm_year = 0;
+        //parse time
+        //Sat Nov 19 14:52:57 2011
+        tmp = strchr(tmp, ' ');
+        if(!tmp) goto errparse;
+        tmp++;
+        char *tmp2 = strchr(tmp, ' ');
+        if(!tmp2) goto errparse;
+        *tmp2 = '\0';
+        if(!stricmp(tmp, "Jan"))
+            timeinfo->tm_mon = 0;
+        else if(!stricmp(tmp, "Feb"))
+            timeinfo->tm_mon = 1;
+        else if(!stricmp(tmp, "Mar"))
+            timeinfo->tm_mon = 2;
+        else if(!stricmp(tmp, "Apr"))
+            timeinfo->tm_mon = 3;
+        else if(!stricmp(tmp, "May"))
+            timeinfo->tm_mon = 4;
+        else if(!stricmp(tmp, "Jun"))
+            timeinfo->tm_mon = 5;
+        else if(!stricmp(tmp, "Jul"))
+            timeinfo->tm_mon = 6;
+        else if(!stricmp(tmp, "Aug"))
+            timeinfo->tm_mon = 7;
+        else if(!stricmp(tmp, "Sep"))
+            timeinfo->tm_mon = 8;
+        else if(!stricmp(tmp, "Oct"))
+            timeinfo->tm_mon = 9;
+        else if(!stricmp(tmp, "Nov"))
+            timeinfo->tm_mon = 10;
+        else if(!stricmp(tmp, "Dec"))
+            timeinfo->tm_mon = 11;
+        tmp = tmp2 + 1;
+        tmp2 = strchr(tmp, ' ');
+        if(!tmp2) goto errparse;
+        *tmp2 = '\0';
+        timeinfo->tm_mday = atoi(tmp);
+        tmp = tmp2 + 1;
+        if(*tmp == ' ') tmp++;
+        tmp2 = strchr(tmp, ':');
+        if(!tmp2) goto errparse;
+        *tmp2 = '\0';
+        timeinfo->tm_hour = atoi(tmp);
+        tmp = tmp2 + 1;
+        tmp2 = strchr(tmp, ':');
+        if(!tmp2) goto errparse;
+        *tmp2 = '\0';
+        timeinfo->tm_min = atoi(tmp);
+        tmp = tmp2 + 1;
+        tmp2 = strchr(tmp, ' ');
+        if(!tmp2) goto errparse;
+        *tmp2 = '\0';
+        timeinfo->tm_sec = atoi(tmp);
+        tmp = tmp2 + 1;
+        timeinfo->tm_year = atoi(tmp) - 1900;
+        registered = mktime(timeinfo);
     }
+    errparse:
+    
     if(do_match) {
-        struct HandleInfoQueueEntry* entry = getNextHandleInfoQueueEntry(bot, 1);
+        #ifdef HAVE_THREADS
+        unsigned int tid = (unsigned int) pthread_self_tid();
+        while(!clientsocket_parseorder_top(tid)) {
+            usleep(1000); //1ms
+        }
+        #endif
+        struct HandleInfoQueueEntry* entry = getNextHandleInfoQueueEntry(bot, ((do_match != 2) ? 1 : 0));
         if(entry) {
+            if(do_match == 2) {
+                free(entry->auth);
+                entry->auth = strdup(auth);
+                return;
+            }
             authlookup_callback_t *callback;
             int i;
             for(i = 0; i < MAXCALLBACKS; i++) {
                 callback = entry->callback[i];
                 if(!callback) break;
-                callback(auth, exists, entry->data[i]);
+                if(!entry->module_id[i] || module_loaded(entry->module_id[i]))
+                    callback(entry->auth, exists, registered, entry->data[i]);
             }
             free(entry->auth);
             free(entry);
@@ -149,7 +239,7 @@ static void recv_notice(struct UserNode *user, struct UserNode *target, char *me
 }
 
 void init_handleinfohandler() {
-    bind_privnotice(recv_notice);
+    bind_privnotice(recv_notice, 0);
 }
 
 void free_handleinfohandler() {