d336d7fc15a42f9e769c8ffe34f1d9b942e58e4b
[NeonServV5.git] / cmd_neonserv_register.c
1
2 #include "cmd_neonserv.h"
3
4 /*
5 * argv[0] - channel
6 * argv[0/1] - nick / *auth
7 */
8 static AUTHLOOKUP_CALLBACK(neonserv_cmd_register_auth_lookup);
9 static USERAUTH_CALLBACK(neonserv_cmd_register_nick_lookup);
10 static void neonserv_cmd_register_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *channel, char *auth);
11
12 struct neonserv_cmd_register_cache {
13     struct ClientSocket *client, *textclient;
14     struct UserNode *user;
15     struct ChanNode *chan;
16     struct Event *event;
17     char *nick;
18     char *channel;
19 };
20
21 CMD_BIND(neonserv_cmd_register) {
22     MYSQL_RES *res;
23     MYSQL_ROW row;
24     char *channel = argv[0];
25     if(!is_valid_chan(channel)) {
26         reply(getTextBot(), user, "NS_INVALID_CHANNEL_NAME", argv[0]);
27         return;
28     }
29     printf_mysql_query("SELECT `botid` FROM `bot_channels` LEFT JOIN `bots` ON `bot_channels`.`botid` = `bots`.`id` LEFT JOIN `channels` ON `bot_channels`.`chanid` = `channels`.`channel_id` WHERE `channel_name` = '%s' AND `botclass` = '%d'", escape_string(channel), client->botid);
30     res = mysql_use();
31     if ((row = mysql_fetch_row(res)) != NULL) {
32         reply(getTextBot(), user, "NS_REGISTER_ALREADY", argv[0], client->user->nick);
33         return;
34     }
35     //check own access
36     if(argv[1][0] == '*') {
37         //we've got an auth
38         argv[1]++;
39         printf_mysql_query("SELECT `user_user` FROM `users` WHERE `user_user` = '%s'", escape_string(argv[1]));
40         res = mysql_use();
41         if ((row = mysql_fetch_row(res)) != NULL) {
42             neonserv_cmd_register_async1(client, getTextBot(), user, chan, event, channel, row[0]);
43         } else {
44             //we need to create a new user...
45             //but first lookup the auth to check if it really exists
46             struct neonserv_cmd_register_cache *cache = malloc(sizeof(*cache));
47             if (!cache) {
48                 perror("malloc() failed");
49                 return;
50             }
51             cache->client = client;
52             cache->textclient = getTextBot();
53             cache->user = user;
54             cache->chan = chan;
55             cache->event = event;
56             cache->nick = strdup(argv[1]);
57             cache->channel = strdup(channel);
58             lookup_authname(argv[1], neonserv_cmd_register_auth_lookup, cache);
59         }
60     } else {
61         struct UserNode *cuser = getUserByNick(argv[1]);
62         if(!cuser) {
63             cuser = createTempUser(argv[1]);
64             cuser->flags |= USERFLAG_ISTMPUSER;
65         }
66         if(cuser->flags & USERFLAG_ISAUTHED) {
67             neonserv_cmd_register_async1(client, getTextBot(), user, chan, event, channel, cuser->auth);
68         } else {
69             struct neonserv_cmd_register_cache *cache = malloc(sizeof(*cache));
70             if (!cache) {
71                 perror("malloc() failed");
72                 return;
73             }
74             cache->client = client;
75             cache->textclient = getTextBot();
76             cache->user = user;
77             cache->chan = chan;
78             cache->event = event;
79             cache->nick = strdup(argv[1]);
80             cache->channel = strdup(channel);
81             get_userauth(cuser, neonserv_cmd_register_nick_lookup, cache);
82         }
83     }
84 }
85
86 static AUTHLOOKUP_CALLBACK(neonserv_cmd_register_auth_lookup) {
87     struct neonserv_cmd_register_cache *cache = data;
88     if(!exists) {
89         //AUTH_DOES_NOT_EXIST
90         reply(cache->textclient, cache->user, "NS_AUTH_UNKNOWN", cache->nick);
91     } else
92         neonserv_cmd_register_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, cache->channel, auth);
93     free(cache->channel);
94     free(cache->nick);
95     free(cache);
96 }
97
98 static USERAUTH_CALLBACK(neonserv_cmd_register_nick_lookup) {
99     struct neonserv_cmd_register_cache *cache = data;
100     if(!user) {
101         //USER_DOES_NOT_EXIST
102         reply(cache->textclient, cache->user, "NS_USER_UNKNOWN", cache->nick);
103     }
104     else if(!(user->flags & USERFLAG_ISAUTHED)) {
105         //USER_NOT_AUTHED
106         reply(cache->textclient, cache->user, "NS_USER_NEED_AUTH", cache->nick);
107     }
108     else
109         neonserv_cmd_register_async1(cache->client, cache->textclient, cache->user, cache->chan, cache->event, cache->channel, user->auth);
110     free(cache->channel);
111     free(cache->nick);
112     free(cache);
113 }
114
115 static void neonserv_cmd_register_async1(struct ClientSocket *client, struct ClientSocket *textclient, struct UserNode *user, struct ChanNode *chan, struct Event *event, char *channel, char *auth) {
116     //we've got a valid auth now...
117     MYSQL_RES *res;
118     MYSQL_ROW row, row2;
119     int userid, adminid;
120     printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(user->auth));
121     res = mysql_use();
122     if ((row = mysql_fetch_row(res)) != NULL)
123         adminid = atoi(row[0]);
124     else
125         adminid = 0;
126     printf_mysql_query("SELECT `user_id` FROM `users` WHERE `user_user` = '%s'", escape_string(auth));
127     res = mysql_use();
128     if ((row = mysql_fetch_row(res)) != NULL) {
129         userid = atoi(row[0]);
130     } else {
131         printf_mysql_query("INSERT INTO `users` (`user_user`) VALUES ('%s')", escape_string(auth));
132         userid = (int) mysql_insert_id(mysql_conn);
133     }
134     printf_mysql_query("SELECT `id`, `max_channels`, `defaulttrigger` FROM `bots` WHERE `botclass` = '%d' ORDER BY `register_priority` DESC", client->botid);
135     res = mysql_use();
136     int botid = 0;
137     char *bottrigger;
138     while ((row = mysql_fetch_row(res)) != NULL) {
139         //check channel count
140         printf_mysql_query("SELECT COUNT(*) FROM `bot_channels` WHERE `botid` = '%s'", row[0]);
141         row2 = mysql_fetch_row(mysql_use());
142         if(atoi(row2[0]) < atoi(row[1])) {
143             botid = atoi(row[0]);
144             bottrigger = row[2];
145             break;
146         }
147     }
148     if(!botid) {
149         reply(textclient, user, "NS_REGISTER_FULL");
150         return;
151     }
152     int chanid;
153     printf_mysql_query("SELECT `channel_id` FROM `channels` WHERE `channel_name` = '%s'", escape_string(channel));
154     res = mysql_use();
155     if ((row = mysql_fetch_row(res)) != NULL) {
156         chanid = atoi(row[0]);
157         printf_mysql_query("UPDATE `channels` SET `channel_registered` = UNIX_TIMESTAMP(), `channel_registrator` = '%d' WHERE `channel_id` = '%d'", adminid, chanid);
158     } else {
159         printf_mysql_query("INSERT INTO `channels` (`channel_name`, `channel_registered`, `channel_registrator`) VALUES ('%s', UNIX_TIMESTAMP(), '%d')", escape_string(channel), adminid);
160         chanid = (int) mysql_insert_id(mysql_conn);
161     }
162     struct ClientSocket *bot;
163     for(bot = getBots(SOCKET_FLAG_READY, NULL); bot; bot = getBots(SOCKET_FLAG_READY, bot)) {
164         if(bot->clientid == botid)
165             break;
166     }
167     if(bot) {
168         putsock(bot, "JOIN %s", channel);
169     } else
170         reply(textclient, user, "NS_REGISTER_DISCONNECTED");
171     printf_mysql_query("INSERT INTO `bot_channels` (`botid`, `chanid`, `trigger`) VALUES ('%d', '%d', '%s')", botid, chanid, bottrigger);
172     printf_mysql_query("DELETE FROM `chanusers` WHERE `chanuser_cid` = '%d'", chanid);
173     printf_mysql_query("INSERT INTO `chanusers` (`chanuser_cid`, `chanuser_uid`, `chanuser_access`) VALUES ('%d', '%d', '%d')", chanid, userid, 500);
174     reply(textclient, user, "NS_REGISTER_DONE", channel, auth);
175     logEvent(event);
176 }