1 /* UserClient.c - TransparentIRC 0.1
2 * Copyright (C) 2011-2012 Philipp Kreil (pk910)
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.
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.
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/>.
17 #include "UserClient.h"
18 #include "IOHandler.h"
19 #include "ServerSocket.h"
20 #include "UserSession.h"
22 #include "IRCClient.h"
24 static void userclient_callback(struct IOEvent *event);
26 static struct UserClient *userclients = NULL;
28 void userclient_accepted(struct ServerSocket *server, int sockfd) {
29 struct UserClient *client;
30 struct IODescriptor *iofd = iohandler_add(sockfd, IOTYPE_CLIENT, userclient_callback);
32 iofd->state = IO_CONNECTED;
34 iohandler_update(iofd);
35 client = calloc(1, sizeof(*client));
38 client->server = server;
39 server->clientcount++;
41 struct UserLogin *login = calloc(1, sizeof(*login));
43 login->client = client;
46 //add UserClient to the list
48 client->next = userclients;
50 userclients->prev = client;
53 //let's say hello to the client
54 iohandler_printf(iofd, "NOTICE AUTH :*** [TransparentIRC] TransparentIRC v" TRANSIRC_VERSION " (use /quote transirc for more information)");
57 void userclient_close(struct UserClient *client) {
58 if(client->flags & USERCLIENT_LOGGED_IN) {
59 usersession_client_close(client->user);
61 struct UserLogin *login = client->user;
62 if(client->flags & USERCLIENT_LOGIN_PROCESSING) {
63 usersession_login_abort(login);
66 free(login->username);
68 free(login->realname);
70 free(login->password);
73 if(login->reject_reason)
74 free(login->reject_reason);
75 if(login->session_class)
76 free(login->session_class);
77 if(login->bind_address)
78 free(login->bind_address);
79 if(login->server_address)
80 free(login->server_address);
83 iohandler_close(client->iofd);
84 client->server->clientcount--;
86 client->prev->next = client->next;
88 userclients = client->next;
90 client->next->prev = client->prev;
95 void userclient_close_server(struct ServerSocket *server, int keep_clients) {
96 struct UserClient *client, *next_client;
97 for(client = userclients; client; client = next_client) {
98 next_client = client->next;
99 if(client->server == server) {
101 client->server = NULL;
103 userclient_close(client);
108 static void userclient_recv(struct UserClient *client, char *line) {
109 if(!stricmplen(line, "TRANSIRC ", 9)) {
111 char *argv[MAXNUMPARAMS];
112 int argc = parse_line(line, argv, 1);
115 } else if(!(client->flags & USERCLIENT_LOGGED_IN)) {
116 struct UserLogin *login = client->user;
117 char *argv[MAXNUMPARAMS];
118 int argc = parse_line(line, argv, 1);
120 if(!stricmp(argv[1], "PASS")) {
121 char *delimiter = strchr(argv[2], ':');
123 free(login->password);
128 free(login->username);
129 login->username = strdup(argv[2]);
130 login->password = strdup(delimiter);
132 login->password = strdup(argv[2]);
133 } else if(!stricmp(argv[1], "USER") && argc >= 6) {
135 login->username = strdup(argv[2]);
136 login->realname = strdup(argv[5]);
137 } else if(!stricmp(argv[1], "NICK")) {
140 login->nick = strdup(argv[2]);
141 if(!login->password) {
142 iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] You need to send your LOC data. Try /quote PASS <username>:<password>");
145 if(login->username && login->password && login->nick && login->realname && !(client->flags & USERCLIENT_LOGIN_PROCESSING)) {
147 iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] Checking login...");
148 usersession_login(login);
151 struct UserSession *session = client->user;
152 if(!stricmplen(line, "QUIT", 4))
156 ircclient_send(session->irc, line);
160 void userclient_login_failed(struct UserLogin *login, char *reason) {
161 iohandler_printf(login->client->iofd, "NOTICE AUTH :*** [TransparentIRC] Login rejected");
162 userclient_close(login->client);
165 void userclient_login_successful(struct UserLogin *login, struct UserSession *session, int recover) {
166 struct UserClient *client = login->client;
167 iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] Login accepted.");
169 free(login->username);
171 free(login->password);
175 client->user = session;
176 client->flags |= USERCLIENT_LOGGED_IN;
178 iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] Recovering previous link (Nick: %s).", session->nick);
184 static void userclient_callback(struct IOEvent *event) {
185 struct UserClient *client = event->iofd->data;
186 switch(event->type) {
188 userclient_recv(client, event->data.recv_str);
191 userclient_close(client);