removed unused code in bots.c
[NeonServV5.git] / src / HandleInfoHandler.c
1 /* HandleInfoHandler.c - NeonServ v5.6
2  * Copyright (C) 2011-2012  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 "ChanNode.h"
22 #include "IRCEvents.h"
23 #include "tools.h"
24 #include "modules.h"
25
26 #define AUTHSERV_NICK "AuthServ"
27
28 #define MAXCALLBACKS 3
29
30 struct HandleInfoQueueEntry {
31     char *auth;
32     void *callback[MAXCALLBACKS];
33     int module_id[MAXCALLBACKS];
34     void *data[MAXCALLBACKS];
35     
36     struct HandleInfoQueueEntry *next;
37 };
38
39 static struct HandleInfoQueueEntry* addHandleInfoQueueEntry(struct ClientSocket *client) {
40     struct HandleInfoQueueEntry *entry = malloc(sizeof(*entry));
41     if (!entry)
42     {
43         perror("malloc() failed");
44         return NULL;
45     }
46     SYNCHRONIZE(cache_sync);
47     entry->next = NULL;
48     if(client->handleinfo_last)
49         client->handleinfo_last->next = entry;
50     else
51         client->handleinfo_first = entry;
52     client->handleinfo_last = entry;
53     DESYNCHRONIZE(cache_sync);
54     return entry;
55 }
56
57 static struct HandleInfoQueueEntry* getNextHandleInfoQueueEntry(struct ClientSocket *client, int freeEntry) {
58     if(!client->handleinfo_first) return NULL;
59     SYNCHRONIZE(cache_sync);
60     struct HandleInfoQueueEntry *entry = client->handleinfo_first;
61     if(freeEntry) {
62         client->handleinfo_first = entry->next;
63         if(entry == client->handleinfo_last) {
64             client->handleinfo_last = NULL;
65         }
66     }
67     DESYNCHRONIZE(cache_sync);
68     return entry;
69 }
70
71 void clear_handleinfoqueue(struct ClientSocket *client) {
72     if(!client->handleinfo_first) return;
73     SYNCHRONIZE(cache_sync);
74     struct HandleInfoQueueEntry *entry, *next;
75     for(entry = client->handleinfo_first; entry; entry = next) {
76         next = entry->next;
77         free(entry);
78     }
79     client->handleinfo_last = NULL;
80     client->handleinfo_first = NULL;
81     DESYNCHRONIZE(cache_sync);
82 }
83
84 void lookup_authname(char *auth, int module_id, authlookup_callback_t callback, void *data) {
85     struct ClientSocket *bot;
86     struct HandleInfoQueueEntry* entry;
87     for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
88         for(entry = bot->handleinfo_first; entry; entry = entry->next) {
89             if(!stricmp(entry->auth, auth)) {
90                 int i = 0;
91                 for(i = 1; i < MAXCALLBACKS; i++) {
92                     if(!entry->callback[i]) {
93                         entry->callback[i] = callback;
94                         entry->module_id[i] = module_id;
95                         entry->data[i] = data;
96                         return;
97                     }
98                 }
99             }
100         }
101         if(bot->flags & SOCKET_FLAG_PREFERRED)
102             break;
103     }
104     if(bot == NULL) return;
105     entry = addHandleInfoQueueEntry(bot);
106     int i;
107     entry->auth = strdup(auth);
108     entry->callback[0] = callback;
109     entry->module_id[0] = module_id;
110     for(i = 1; i < MAXCALLBACKS; i++)
111         entry->callback[i] = NULL;
112     entry->data[0] = data;
113     for(i = 1; i < MAXCALLBACKS; i++)
114         entry->data[i] = NULL;
115     putsock(bot, "PRIVMSG " AUTHSERV_NICK " :ACCOUNTINFO *%s", auth);
116 }
117
118 static void recv_notice(struct UserNode *user, struct UserNode *target, char *message) {
119     if(stricmp(user->nick, AUTHSERV_NICK)) return;
120     struct ClientSocket *bot;
121     for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
122         if(bot->user == target) break;
123     }
124     if(!bot) return;
125     char *auth = NULL;
126     int do_match = 0, exists = 0;
127     char *tmp;
128     time_t registered = time(0);
129     struct tm *timeinfo;
130     //messages to parse:
131     //  Account * has not been registered.
132     //  Account information for Skynet:
133     if(!match("Account * has not been registered.", message)) {
134         do_match = 1;
135         tmp = strstr(message, "\002");
136         auth = tmp+1;
137         tmp = strstr(auth, "\002");
138         *tmp = '\0';
139     } else if(!match("Account information for *", message)) {
140         do_match = 2;
141         exists = 1;
142         tmp = strstr(message, "\002");
143         auth = tmp+1;
144         tmp = strstr(auth, "\002");
145         *tmp = '\0';
146     } else if(!match("  Registered on: *", message)) {
147         do_match = 1;
148         exists = 1;
149         tmp = strstr(message, ": ");
150         tmp += 2;
151         timeinfo = localtime(&registered);
152         timeinfo->tm_year = 0;
153         //parse time
154         //Sat Nov 19 14:52:57 2011
155         tmp = strchr(tmp, ' ');
156         if(!tmp) goto errparse;
157         tmp++;
158         char *tmp2 = strchr(tmp, ' ');
159         if(!tmp2) goto errparse;
160         *tmp2 = '\0';
161         if(!stricmp(tmp, "Jan"))
162             timeinfo->tm_mon = 0;
163         else if(!stricmp(tmp, "Feb"))
164             timeinfo->tm_mon = 1;
165         else if(!stricmp(tmp, "Mar"))
166             timeinfo->tm_mon = 2;
167         else if(!stricmp(tmp, "Apr"))
168             timeinfo->tm_mon = 3;
169         else if(!stricmp(tmp, "May"))
170             timeinfo->tm_mon = 4;
171         else if(!stricmp(tmp, "Jun"))
172             timeinfo->tm_mon = 5;
173         else if(!stricmp(tmp, "Jul"))
174             timeinfo->tm_mon = 6;
175         else if(!stricmp(tmp, "Aug"))
176             timeinfo->tm_mon = 7;
177         else if(!stricmp(tmp, "Sep"))
178             timeinfo->tm_mon = 8;
179         else if(!stricmp(tmp, "Oct"))
180             timeinfo->tm_mon = 9;
181         else if(!stricmp(tmp, "Nov"))
182             timeinfo->tm_mon = 10;
183         else if(!stricmp(tmp, "Dec"))
184             timeinfo->tm_mon = 11;
185         tmp = tmp2 + 1;
186         tmp2 = strchr(tmp, ' ');
187         if(!tmp2) goto errparse;
188         *tmp2 = '\0';
189         timeinfo->tm_mday = atoi(tmp);
190         tmp = tmp2 + 1;
191         if(*tmp == ' ') tmp++;
192         tmp2 = strchr(tmp, ':');
193         if(!tmp2) goto errparse;
194         *tmp2 = '\0';
195         timeinfo->tm_hour = atoi(tmp);
196         tmp = tmp2 + 1;
197         tmp2 = strchr(tmp, ':');
198         if(!tmp2) goto errparse;
199         *tmp2 = '\0';
200         timeinfo->tm_min = atoi(tmp);
201         tmp = tmp2 + 1;
202         tmp2 = strchr(tmp, ' ');
203         if(!tmp2) goto errparse;
204         *tmp2 = '\0';
205         timeinfo->tm_sec = atoi(tmp);
206         tmp = tmp2 + 1;
207         timeinfo->tm_year = atoi(tmp) - 1900;
208         registered = mktime(timeinfo);
209     }
210     errparse:
211     
212     if(do_match) {
213         #ifdef HAVE_THREADS
214         unsigned int tid = (unsigned int) pthread_self_tid();
215         while(!clientsocket_parseorder_top(tid)) {
216             usleep(1000); //1ms
217         }
218         #endif
219         struct HandleInfoQueueEntry* entry = getNextHandleInfoQueueEntry(bot, ((do_match != 2) ? 1 : 0));
220         if(entry) {
221             if(do_match == 2) {
222                 free(entry->auth);
223                 entry->auth = strdup(auth);
224                 return;
225             }
226             authlookup_callback_t *callback;
227             int i;
228             for(i = 0; i < MAXCALLBACKS; i++) {
229                 callback = entry->callback[i];
230                 if(!callback) break;
231                 if(!entry->module_id[i] || module_loaded(entry->module_id[i]))
232                     callback(entry->auth, exists, registered, entry->data[i]);
233             }
234             free(entry->auth);
235             free(entry);
236         }
237     }
238 }
239
240 void init_handleinfohandler() {
241     bind_privnotice(recv_notice, 0);
242 }
243
244 void free_handleinfohandler() {
245     
246 }