* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "UserClient.c"
+#include "UserClient.h"
#include "IOHandler.h"
+#include "ServerSocket.h"
+#include "UserSession.h"
+#include "tools.h"
+#include "IRCClient.h"
static void userclient_callback(struct IOEvent *event);
iofd->state = IO_CONNECTED;
iofd->read_lines = 1;
iohandler_update(iofd);
- client = malloc(sizeof(*client));
+ client = calloc(1, sizeof(*client));
client->iofd = iofd;
+ iofd->data = client;
client->server = server;
server->clientcount++;
+ struct UserLogin *login = calloc(1, sizeof(*login));
+ client->user = login;
+ login->client = client;
+
+
//add UserClient to the list
- sock->prev = NULL;
- sock->next = serversockets;
- serversockets->prev = sock;
- serversockets = sock;
+ client->prev = NULL;
+ client->next = userclients;
+ if(userclients)
+ userclients->prev = client;
+ userclients = client;
//let's say hello to the client
- iohandler_printf(iofd, "NOTICE AUTH :*** TransparentIRC " TRANSIRC_VERSION " (use /quote transirc for more information)");
+ iohandler_printf(iofd, "NOTICE AUTH :*** [TransparentIRC] TransparentIRC v" TRANSIRC_VERSION " (use /quote transirc for more information)");
}
void userclient_close(struct UserClient *client) {
+ if(client->flags & USERCLIENT_LOGGED_IN) {
+ usersession_client_close(client->user);
+ } else {
+ struct UserLogin *login = client->user;
+ if(client->flags & USERCLIENT_LOGIN_PROCESSING) {
+ usersession_login_abort(login);
+ }
+ if(login->username)
+ free(login->username);
+ if(login->realname)
+ free(login->realname);
+ if(login->password)
+ free(login->password);
+ if(login->nick)
+ free(login->nick);
+ if(login->reject_reason)
+ free(login->reject_reason);
+ if(login->session_class)
+ free(login->session_class);
+ if(login->bind_address)
+ free(login->bind_address);
+ if(login->server_address)
+ free(login->server_address);
+ free(login);
+ }
iohandler_close(client->iofd);
client->server->clientcount--;
if(client->prev)
userclients = client->next;
if(client->next)
client->next->prev = client->prev;
+
free(client);
}
void userclient_close_server(struct ServerSocket *server, int keep_clients) {
struct UserClient *client, *next_client;
for(client = userclients; client; client = next_client) {
+ next_client = client->next;
if(client->server == server) {
if(keep_clients)
client->server = NULL;
}
}
+static void userclient_recv(struct UserClient *client, char *line) {
+ if(!stricmplen(line, "TRANSIRC ", 9)) {
+ /*
+ char *argv[MAXNUMPARAMS];
+ int argc = parse_line(line, argv, 1);
+ */
+
+ } else if(!(client->flags & USERCLIENT_LOGGED_IN)) {
+ struct UserLogin *login = client->user;
+ char *argv[MAXNUMPARAMS];
+ int argc = parse_line(line, argv, 1);
+ if(argc < 3) return;
+ if(!stricmp(argv[1], "PASS")) {
+ char *delimiter = strchr(argv[2], ':');
+ if(login->password)
+ free(login->password);
+ if(delimiter) {
+ *delimiter = '\0';
+ delimiter++;
+ if(login->username)
+ free(login->username);
+ login->username = strdup(argv[2]);
+ login->password = strdup(delimiter);
+ } else
+ login->password = strdup(argv[2]);
+ } else if(!stricmp(argv[1], "USER") && argc >= 6) {
+ if(!login->username)
+ login->username = strdup(argv[2]);
+ login->realname = strdup(argv[5]);
+ } else if(!stricmp(argv[1], "NICK")) {
+ if(login->nick)
+ free(login->nick);
+ login->nick = strdup(argv[2]);
+ if(!login->password) {
+ iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] You need to send your LOC data. Try /quote PASS <username>:<password>");
+ }
+ }
+ if(login->username && login->password && login->nick && login->realname && !(client->flags & USERCLIENT_LOGIN_PROCESSING)) {
+ //try to login
+ iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] Checking login...");
+ usersession_login(login);
+ }
+ } else {
+ struct UserSession *session = client->user;
+ if(!stricmplen(line, "QUIT", 4))
+ return;
+
+ if(session->irc)
+ ircclient_send(session->irc, line);
+ }
+}
+
+void userclient_login_failed(struct UserLogin *login, char *reason) {
+ iohandler_printf(login->client->iofd, "NOTICE AUTH :*** [TransparentIRC] Login rejected");
+ userclient_close(login->client);
+}
+
+void userclient_login_successful(struct UserLogin *login, struct UserSession *session, int recover) {
+ struct UserClient *client = login->client;
+ iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] Login accepted.");
+ if(login->username)
+ free(login->username);
+ if(login->password)
+ free(login->password);
+ if(login->nick)
+ free(login->nick);
+ free(login);
+ client->user = session;
+ client->flags |= USERCLIENT_LOGGED_IN;
+ if(recover) {
+ iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] Recovering previous link (Nick: %s).", session->nick);
+ ircclient_recover_session(session);
+ }
+}
+
static void userclient_callback(struct IOEvent *event) {
+ struct UserClient *client = event->iofd->data;
switch(event->type) {
case IOEVENT_RECV:
- char *line = event->data.recv_str;
- iohandler_printf(event->iofd, "reply: %s", line);
+ userclient_recv(client, event->data.recv_str);
break;
case IOEVENT_CLOSED:
- userclient_close(event->iofd);
+ userclient_close(client);
+ break;
+ default:
break;
}
}