예제 #1
0
파일: listen.c 프로젝트: kleopatra999/irssi
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);
}
예제 #2
0
파일: listen.c 프로젝트: svn2github/irssi
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);
    }
}