*** VERSION 5.2.0 ***
[NeonServV5.git] / src / HandleInfoHandler.c
1 /* HandleInfoHandler.c - NeonServ v5.2
2  * Copyright (C) 2011  Philipp Kreil (pk910)
3  * 
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License 
15  * along with this program. If not, see <http://www.gnu.org/licenses/>. 
16  */
17
18 #include "HandleInfoHandler.h"
19 #include "ClientSocket.h"
20 #include "UserNode.h"
21 #include "IRCEvents.h"
22 #include "tools.h"
23
24 #define AUTHSERV_NICK "AuthServ"
25
26 struct HandleInfoQueueEntry {
27     struct ClientSocket *client;
28     void *callback;
29     void *data;
30     
31     struct HandleInfoQueueEntry *next;
32 };
33
34 static struct HandleInfoQueueEntry *first_entry = NULL, *last_entry = NULL;
35
36 static struct HandleInfoQueueEntry* addHandleInfoQueueEntry(struct ClientSocket *client) {
37     struct HandleInfoQueueEntry *entry = malloc(sizeof(*entry));
38     if (!entry)
39     {
40         perror("malloc() failed");
41         return NULL;
42     }
43     entry->next = NULL;
44     entry->client = client;
45     if(last_entry)
46         last_entry->next = entry;
47     else
48         last_entry = entry;
49     if(!first_entry)
50         first_entry = entry;
51     return entry;
52 }
53
54 static struct HandleInfoQueueEntry* getNextHandleInfoQueueEntry(struct ClientSocket *client, int freeEntry) {
55     if(!first_entry) return NULL;
56     struct HandleInfoQueueEntry *entry;
57     for(entry = first_entry; entry; entry = entry->next) {
58         if(entry->client == client)
59             break;
60     }
61     if(entry == NULL) return NULL;
62     if(freeEntry) {
63         if(entry == first_entry)
64             first_entry = entry->next;
65         if(entry == last_entry) {
66             struct HandleInfoQueueEntry *last = NULL;
67             for(last = first_entry; last; last = last->next)
68                 if(last->next == NULL) break;
69             last_entry = last;
70         }
71     }
72     return entry;
73 }
74
75 void lookup_authname(char *auth, authlookup_callback_t callback, void *data) {
76     struct ClientSocket *bot;
77     for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
78         if(bot->flags & SOCKET_FLAG_PREFERRED)
79             break;
80     }
81     if(bot == NULL) return;
82     struct HandleInfoQueueEntry* entry = addHandleInfoQueueEntry(bot);
83     entry->callback = callback;
84     entry->data = data;
85     putsock(bot, "PRIVMSG " AUTHSERV_NICK " :ACCOUNTINFO *%s", auth);
86 }
87
88 static void recv_notice(struct UserNode *user, struct UserNode *target, char *message) {
89     if(stricmp(user->nick, AUTHSERV_NICK)) return;
90     struct ClientSocket *bot;
91     for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
92         if(bot->user == target) break;
93     }
94     if(!bot) return;
95     char *auth = NULL;
96     int do_match = 0, exists = 0;
97     char *tmp;
98     //messages to parse:
99     //  Account * has not been registered.
100     //  Account information for Skynet:
101     if(!match("Account * has not been registered.", message)) {
102         do_match = 1;
103         tmp = strstr(message, "\002");
104         auth = tmp+1;
105         tmp = strstr(auth, "\002");
106         *tmp = '\0';
107     }
108     if(!match("Account information for *", message)) {
109         do_match = 1;
110         exists = 1;
111         tmp = strstr(message, "\002");
112         auth = tmp+1;
113         tmp = strstr(auth, "\002");
114         *tmp = '\0';
115     }
116     if(do_match) {
117         struct HandleInfoQueueEntry* entry = getNextHandleInfoQueueEntry(bot, 1);
118         if(entry) {
119             authlookup_callback_t *callback = entry->callback;
120             callback(auth, exists, entry->data);
121             free(entry);
122         }
123     }
124 }
125
126 void init_handleinfohandler() {
127     bind_privnotice(recv_notice);
128 }
129
130 void free_handleinfohandler() {
131     struct HandleInfoQueueEntry *entry, *next;
132     for(entry = first_entry; entry; entry = next) {
133         next = entry->next;
134         free(entry);
135     }
136     first_entry = NULL;
137     last_entry = NULL;
138 }