static void handle_client_cmd(CLIENT_REC *client, char *cmd, char *args, const char *data) { GSList *tmp; if (!client->connected) { handle_client_connect_cmd(client, cmd, args); return; } if (g_strcmp0(cmd, "QUIT") == 0) { remove_client(client); return; } if (g_strcmp0(cmd, "PING") == 0) { /* Reply to PING, if the target parameter is either proxy_adress, our own nick or empty. */ char *params, *origin, *target; params = event_get_params(args, 2, &origin, &target); if (*target == '\0' || g_ascii_strcasecmp(target, client->proxy_address) == 0 || g_ascii_strcasecmp(target, client->nick) == 0) { proxy_outdata(client, ":%s PONG %s :%s\r\n", client->proxy_address, client->proxy_address, origin); g_free(params); return; } g_free(params); } if (g_strcmp0(cmd, "PROXY") == 0) { if (g_ascii_strcasecmp(args, "CTCP ON") == 0) { /* client wants all ctcps */ client->want_ctcp = 1; for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) { CLIENT_REC *rec = tmp->data; if ((g_ascii_strcasecmp(client->listen->ircnet,rec->listen->ircnet) == 0) && /* kludgy way to check if the clients aren't the same */ (client->recv_tag != rec->recv_tag)) { if (rec->want_ctcp == 1) proxy_outdata(rec, ":%s NOTICE %s :Another client is now receiving CTCPs sent to %s\r\n", rec->proxy_address, rec->nick, rec->listen->ircnet); rec->want_ctcp = 0; } } proxy_outdata(client, ":%s NOTICE %s :You're now receiving CTCPs sent to %s\r\n", client->proxy_address, client->nick,client->listen->ircnet); } else if (g_ascii_strcasecmp(args, "CTCP OFF") == 0) { /* client wants proxy to handle all ctcps */ client->want_ctcp = 0; proxy_outdata(client, ":%s NOTICE %s :Proxy is now handling itself CTCPs sent to %s\r\n", client->proxy_address, client->nick, client->listen->ircnet); } else { signal_emit("proxy client command", 3, client, args, data); } return; } if (client->server == NULL || !client->server->connected) { proxy_outdata(client, ":%s NOTICE %s :Not connected to server\r\n", client->proxy_address, client->nick); return; } /* check if the command could be redirected */ if (g_strcmp0(cmd, "WHO") == 0) grab_who(client, args); else if (g_strcmp0(cmd, "WHOWAS") == 0) proxy_redirect_event(client, "whowas", 1, args, -1); else if (g_strcmp0(cmd, "WHOIS") == 0) { char *p; /* convert dots to spaces */ for (p = args; *p != '\0'; p++) if (*p == ',') *p = ' '; proxy_redirect_event(client, "whois", 1, args, TRUE); } else if (g_strcmp0(cmd, "ISON") == 0) proxy_redirect_event(client, "ison", 1, args, -1); else if (g_strcmp0(cmd, "USERHOST") == 0) proxy_redirect_event(client, "userhost", 1, args, -1); else if (g_strcmp0(cmd, "MODE") == 0) { /* convert dots to spaces */ char *slist, *str, mode, *p; int argc; p = strchr(args, ' '); if (p != NULL) *p++ = '\0'; mode = p == NULL ? '\0' : *p; slist = g_strdup(args); argc = 1; for (p = slist; *p != '\0'; p++) { if (*p == ',') { *p = ' '; argc++; } } /* get channel mode / bans / exception / invite list */ str = g_strdup_printf("%s %s", args, slist); switch (mode) { case '\0': proxy_redirect_event(client, "mode channel", argc, str, -1); break; case 'b': proxy_redirect_event(client, "mode b", argc, str, -1); break; case 'e': proxy_redirect_event(client, "mode e", argc, str, -1); break; case 'I': proxy_redirect_event(client, "mode I", argc, str, -1); break; } g_free(str); g_free(slist); } else if (g_strcmp0(cmd, "PRIVMSG") == 0) { /* send the message to other clients as well */ char *params, *target, *msg; params = event_get_params(args, 2 | PARAM_FLAG_GETREST, &target, &msg); proxy_outserver_all_except(client, "PRIVMSG %s", args); ignore_next = TRUE; if (*msg != '\001' || msg[strlen(msg)-1] != '\001') { signal_emit(ischannel(*target) ? "message own_public" : "message own_private", 4, client->server, msg, target, target); } else if (strncmp(msg+1, "ACTION ", 7) == 0) { /* action */ msg[strlen(msg)-1] = '\0'; signal_emit("message irc own_action", 3, client->server, msg+8, target); } else { /* CTCP */ char *p; msg[strlen(msg)-1] = '\0'; p = strchr(msg, ' '); if (p != NULL) *p++ = '\0'; else p = ""; signal_emit("message irc own_ctcp", 4, client->server, msg+1, p, target); } ignore_next = FALSE; g_free(params); } else if (g_strcmp0(cmd, "PING") == 0) { proxy_redirect_event(client, "ping", 1, NULL, TRUE); } else if (g_strcmp0(cmd, "AWAY") == 0) { /* set the away reason */ if (args != NULL) { g_free(client->server->away_reason); client->server->away_reason = g_strdup(args); } } irc_send_cmd(client->server, data); }
static void sig_listen_client(CLIENT_REC *client, gint handle) { char tmpbuf[1024], *str, *cmd, *args, *p; int ret, recvlen; g_return_if_fail(client != NULL); for (;;) { recvlen = net_receive(handle, tmpbuf, sizeof(tmpbuf)); ret = line_split(tmpbuf, recvlen, &str, &client->buffer); if (ret == -1) { /* connection lost */ remove_client(proxy_data, client); break; } if (ret == 0) break; if (client->server == NULL) continue; cmd = g_strdup(str); args = strchr(cmd, ' '); if (args != NULL) *args++ = '\0'; else args = ""; if (*args == ':') args++; g_strup(cmd); if (!client->connected) { if (proxy_data->password != NULL && strcmp(cmd, "PASS") == 0) { if (strcmp(proxy_data->password, args) != 0) { /* wrong password! */ remove_client(proxy_data, client); break; } client->pass_sent = TRUE; } else if (strcmp(cmd, "NICK") == 0) client->nick = g_strdup(args); else if (strcmp(cmd, "USER") == 0) { if (client->nick == NULL || (proxy_data->password != NULL && !client->pass_sent)) { /* stupid client didn't send us NICK/PASS or, kill it */ remove_client(proxy_data, client); break; } client->connected = TRUE; plugin_proxy_dump_data(client); } } else if (strcmp(cmd, "QUIT") == 0) { remove_client(proxy_data, client); break; } else if (strcmp(cmd, "PING") == 0) { net_transmit(handle, "PONG proxy :nick\n", 17); } else { net_transmit(net_sendbuffer_handle(client->server->handle), str, strlen(str)); net_transmit(net_sendbuffer_handle(client->server->handle), "\n", 1); if (strcmp(cmd, "WHO") == 0) { grab_who(client, args); } else if (strcmp(cmd, "WHOIS") == 0) { /* convert dots to spaces */ for (p = args; *p != '\0'; p++) if (*p == ',') *p = ' '; proxy_redirect_event(client, args, 2, "event 318", -1, "event 402", -1, "event 401", 1, "event 311", 1, "event 301", 1, "event 312", 1, "event 313", 1, "event 317", 1, "event 319", 1, NULL); } else if (strcmp(cmd, "ISON") == 0) { proxy_redirect_event(client, NULL, 1, "event 303", -1, NULL); } else if (strcmp(cmd, "USERHOST") == 0) { proxy_redirect_event(client, args, 1, "event 302", -1, "event 401", 1, NULL); } else if (strcmp(cmd, "MODE") == 0) { /* convert dots to spaces */ gchar *slist, *str, mode; gint argc; p = strchr(args, ' '); if (p != NULL) *p++ = '\0'; mode = p == NULL ? '\0' : *p; slist = g_strdup(args); argc = 1; for (p = slist; *p != '\0'; p++) { if (*p == ',') { *p = ' '; argc++; } } /* get channel mode / bans / exception / invite list */ str = g_strdup_printf("%s %s", args, slist); switch (mode) { case '\0': while (argc-- > 0) proxy_redirect_event(client, str, 3, "event 403", 1, "event 443", 1, "event 324", 1, NULL); break; case 'b': while (argc-- > 0) proxy_redirect_event(client, str, 2, "event 403", 1, "event 368", 1, "event 367", 1, NULL); break; case 'e': while (argc-- > 0) proxy_redirect_event(client, str, 4, "event 403", 1, "event 482", 1, "event 472", -1, "event 349", 1, "event 348", 1, NULL); break; case 'I': while (argc-- > 0) proxy_redirect_event(client, str, 4, "event 403", 1, "event 482", 1, "event 472", -1, "event 347", 1, "event 346", 1, NULL); break; } g_free(str); g_free(slist); } } g_free(cmd); } }