tried to reorder the program structure and build process
[NeonServV5.git] / src / HandleInfoHandler.c
1
2 #include "HandleInfoHandler.h"
3 #include "ClientSocket.h"
4 #include "UserNode.h"
5 #include "IRCEvents.h"
6 #include "tools.h"
7
8 #define AUTHSERV_NICK "AuthServ"
9
10 struct HandleInfoQueueEntry {
11     struct ClientSocket *client;
12     void *callback;
13     void *data;
14     
15     struct HandleInfoQueueEntry *next;
16 };
17
18 static struct HandleInfoQueueEntry *first_entry = NULL, *last_entry = NULL;
19
20 static struct HandleInfoQueueEntry* addHandleInfoQueueEntry(struct ClientSocket *client) {
21     struct HandleInfoQueueEntry *entry = malloc(sizeof(*entry));
22     if (!entry)
23     {
24         perror("malloc() failed");
25         return NULL;
26     }
27     entry->next = NULL;
28     entry->client = client;
29     if(last_entry)
30         last_entry->next = entry;
31     else
32         last_entry = entry;
33     if(!first_entry)
34         first_entry = entry;
35     return entry;
36 }
37
38 static struct HandleInfoQueueEntry* getNextHandleInfoQueueEntry(struct ClientSocket *client, int freeEntry) {
39     if(!first_entry) return NULL;
40     struct HandleInfoQueueEntry *entry;
41     for(entry = first_entry; entry; entry = entry->next) {
42         if(entry->client == client)
43             break;
44     }
45     if(entry == NULL) return NULL;
46     if(freeEntry) {
47         if(entry == first_entry)
48             first_entry = entry->next;
49         if(entry == last_entry) {
50             struct HandleInfoQueueEntry *last;
51             for(last = first_entry; last; last = last->next)
52                 if(last->next == NULL) break;
53             last_entry = last;
54         }
55     }
56     return entry;
57 }
58
59 void lookup_authname(char *auth, authlookup_callback_t callback, void *data) {
60     struct ClientSocket *bot;
61     for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
62         if(bot->flags & SOCKET_FLAG_PREFERRED)
63             break;
64     }
65     if(bot == NULL) return;
66     struct HandleInfoQueueEntry* entry = addHandleInfoQueueEntry(bot);
67     entry->callback = callback;
68     entry->data = data;
69     putsock(bot, "PRIVMSG " AUTHSERV_NICK " :ACCOUNTINFO *%s", auth);
70 }
71
72 static void recv_notice(struct UserNode *user, struct UserNode *target, char *message) {
73     if(stricmp(user->nick, AUTHSERV_NICK)) return;
74     struct ClientSocket *bot;
75     for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
76         if(bot->user == target) break;
77     }
78     if(!bot) return;
79     char *auth = NULL;
80     int do_match = 0, exists = 0;
81     char *tmp;
82     //messages to parse:
83     //  Account * has not been registered.
84     //  Account information for Skynet:
85     if(!match("Account * has not been registered.", message)) {
86         do_match = 1;
87         tmp = strstr(message, "\002");
88         auth = tmp+1;
89         tmp = strstr(auth, "\002");
90         *tmp = '\0';
91     }
92     if(!match("Account information for *", message)) {
93         do_match = 1;
94         exists = 1;
95         tmp = strstr(message, "\002");
96         auth = tmp+1;
97         tmp = strstr(auth, "\002");
98         *tmp = '\0';
99     }
100     if(do_match) {
101         struct HandleInfoQueueEntry* entry = getNextHandleInfoQueueEntry(bot, 1);
102         authlookup_callback_t *callback = entry->callback;
103         callback(auth, exists, entry->data);
104         free(entry);
105     }
106 }
107
108 void init_handleinfohandler() {
109     bind_privnotice(recv_notice);
110 }
111
112 void free_handleinfohandler() {
113     struct HandleInfoQueueEntry *entry, *next;
114     for(entry = first_entry; entry; entry = next) {
115         next = entry->next;
116         free(entry);
117     }
118     first_entry = NULL;
119     last_entry = NULL;
120 }