X-Git-Url: http://git.pk910.de/?p=NeonServV5.git;a=blobdiff_plain;f=src%2FHandleInfoHandler.c;h=8a8a46ce3a0ce205b422c01907c28f62c9e78835;hp=c03abcee713ca6f499ea357478a28684172b4c25;hb=HEAD;hpb=ee9e9778466f1f9a7f1f2c3991afa138f368a5fe diff --git a/src/HandleInfoHandler.c b/src/HandleInfoHandler.c index c03abce..8a8a46c 100644 --- a/src/HandleInfoHandler.c +++ b/src/HandleInfoHandler.c @@ -1,5 +1,5 @@ -/* HandleInfoHandler.c - NeonServ v5.1 - * Copyright (C) 2011 Philipp Kreil (pk910) +/* HandleInfoHandler.c - NeonServ v5.6 + * Copyright (C) 2011-2012 Philipp Kreil (pk910) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,70 +18,101 @@ #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" +#define MAXCALLBACKS 3 + struct HandleInfoQueueEntry { - struct ClientSocket *client; - void *callback; - void *data; + char *auth; + void *callback[MAXCALLBACKS]; + int module_id[MAXCALLBACKS]; + void *data[MAXCALLBACKS]; struct HandleInfoQueueEntry *next; }; -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"); + printf_log("main", LOG_ERROR, "%s:%d malloc() failed", __FILE__, __LINE__); return NULL; } + SYNCHRONIZE(cache_sync); entry->next = NULL; - entry->client = client; - if(last_entry) - last_entry->next = entry; + if(client->handleinfo_last) + client->handleinfo_last->next = entry; else - last_entry = entry; - if(!first_entry) - first_entry = entry; + client->handleinfo_first = entry; + client->handleinfo_last = entry; + DESYNCHRONIZE(cache_sync); 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(!client->handleinfo_first) return NULL; + SYNCHRONIZE(cache_sync); + struct HandleInfoQueueEntry *entry = client->handleinfo_first; if(freeEntry) { - if(entry == first_entry) - first_entry = entry->next; - if(entry == last_entry) { - struct HandleInfoQueueEntry *last = NULL; - for(last = first_entry; last; last = last->next) - if(last->next == NULL) break; - last_entry = last; + client->handleinfo_first = entry->next; + if(entry == client->handleinfo_last) { + client->handleinfo_last = NULL; } } + DESYNCHRONIZE(cache_sync); return entry; } -void lookup_authname(char *auth, authlookup_callback_t callback, void *data) { +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; + free(entry); + } + client->handleinfo_last = NULL; + client->handleinfo_first = NULL; + DESYNCHRONIZE(cache_sync); +} + +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)) { + for(entry = bot->handleinfo_first; entry; entry = entry->next) { + if(!stricmp(entry->auth, auth)) { + int i = 0; + 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; + } + } + } + } if(bot->flags & SOCKET_FLAG_PREFERRED) break; } if(bot == NULL) return; - struct HandleInfoQueueEntry* entry = addHandleInfoQueueEntry(bot); - entry->callback = callback; - entry->data = data; + entry = addHandleInfoQueueEntry(bot); + 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; + for(i = 1; i < MAXCALLBACKS; i++) + entry->data[i] = NULL; putsock(bot, "PRIVMSG " AUTHSERV_NICK " :ACCOUNTINFO *%s", auth); } @@ -95,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: @@ -104,33 +137,111 @@ 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(®istered); + 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); - authlookup_callback_t *callback = entry->callback; - callback(auth, exists, entry->data); - free(entry); + #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; + if(!entry->module_id[i] || module_loaded(entry->module_id[i])) + callback(entry->auth, exists, registered, entry->data[i]); + } + free(entry->auth); + free(entry); + } } } void init_handleinfohandler() { - bind_privnotice(recv_notice); + bind_privnotice(recv_notice, 0); } 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; + }