Exemple #1
0
static void dump_join(IRC_CHANNEL_REC *channel, CLIENT_REC *client)
{
	GSList *tmp, *nicks;
	GString *str;
	int first;

	proxy_outserver(client, "JOIN %s", channel->name);

	str = g_string_new(NULL);
	create_names_start(str, channel, client);

	first = TRUE;
	nicks = nicklist_getnicks(CHANNEL(channel));
	for (tmp = nicks; tmp != NULL; tmp = tmp->next) {
		NICK_REC *nick = tmp->data;

		if (str->len >= 500) {
			g_string_append_c(str, '\n');
			proxy_outdata(client, "%s", str->str);
			create_names_start(str, channel, client);
			first = TRUE;
		}

		if (first)
			first = FALSE;
		else
			g_string_append_c(str, ' ');

		if (nick->other)
                        g_string_append_c(str, nick->other);
		else if (nick->op)
                        g_string_append_c(str, '@');
		else if (nick->halfop)
                        g_string_append_c(str, '%');
		else if (nick->voice)
                        g_string_append_c(str, '+');
		g_string_append(str, nick->nick);
	}
	g_slist_free(nicks);

	g_string_append_c(str, '\n');
	proxy_outdata(client, "%s", str->str);
	g_string_free(str, TRUE);

	proxy_outdata(client, ":%s 366 %s %s :End of /NAMES list.\n",
		      client->proxy_address, client->nick, channel->name);
	/* this is needed because the topic may be encoded into other charsets internaly */
	if (channel->topic != NULL) {
		proxy_outdata(client, ":%s 332 %s %s :%s\n",
			      client->proxy_address, client->nick,
			      channel->name, recode_out(channel->topic, channel->name));
	}
}
Exemple #2
0
static void sig_dump(CLIENT_REC *client, const char *data)
{
	g_return_if_fail(client != NULL);
	g_return_if_fail(data != NULL);

	proxy_outdata(client, data);
}
Exemple #3
0
void proxy_outserver_all_except(CLIENT_REC *client, const char *data, ...)
{
	va_list args;
	GSList *tmp;
	char *str;

	g_return_if_fail(client != NULL);
	g_return_if_fail(data != NULL);

	va_start(args, data);

	str = g_strdup_vprintf(data, args);
	for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
		CLIENT_REC *rec = tmp->data;

		if (rec->connected && rec != client &&
		    rec->server == client->server) {
			proxy_outdata(rec, ":%s!%s@proxy %s\n", rec->nick,
				      settings_get_str("user_name"), str);
		}
	}
	g_free(str);

	va_end(args);
}
Exemple #4
0
void proxy_client_reset_nick(CLIENT_REC *client)
{
	if (client->server == NULL ||
	    strcmp(client->nick, client->server->nick) == 0)
		return;

	proxy_outdata(client, ":%s!proxy NICK :%s\n",
		      client->nick, client->server->nick);

	g_free(client->nick);
	client->nick = g_strdup(client->server->nick);
}
Exemple #5
0
static void proxy_server_disconnected(CLIENT_REC *client,
				      IRC_SERVER_REC *server)
{
	GSList *tmp;

	proxy_outdata(client, ":%s NOTICE %s :Connection lost to server %s\r\n",
		      client->proxy_address, client->nick,
		      server->connrec->address);

	for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
		IRC_CHANNEL_REC *rec = tmp->data;

		proxy_outserver(client, "PART %s :Connection lost to server",
				rec->name);
	}
}
Exemple #6
0
void proxy_outserver(CLIENT_REC *client, const char *data, ...)
{
	va_list args;
	char *str;

	g_return_if_fail(client != NULL);
	g_return_if_fail(data != NULL);

	va_start(args, data);

	str = g_strdup_vprintf(data, args);
	proxy_outdata(client, ":%s!%s@proxy %s\n", client->nick,
		      settings_get_str("user_name"), str);
	g_free(str);

	va_end(args);
}
Exemple #7
0
static void event_connected(IRC_SERVER_REC *server)
{
	GSList *tmp;
        const char *chatnet;

	if (!IS_IRC_SERVER(server))
		return;

        chatnet = server->connrec->chatnet;
	for (tmp = proxy_clients; tmp != NULL; tmp = tmp->next) {
		CLIENT_REC *rec = tmp->data;

		if (rec->connected && rec->server == NULL &&
		    (g_strcmp0(rec->listen->ircnet, "*") == 0 ||
		     (chatnet != NULL &&
		      g_ascii_strcasecmp(chatnet, rec->listen->ircnet) == 0))) {
			proxy_outdata(rec, ":%s NOTICE %s :Connected to server\r\n",
				      rec->proxy_address, rec->nick);
			rec->server = server;
			proxy_client_reset_nick(rec);
		}
	}
}
Exemple #8
0
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);
}
Exemple #9
0
void proxy_dump_data(CLIENT_REC *client)
{
	GString *isupport_out, *paramstr;
	char **paramlist, **tmp;
	int count;

	proxy_client_reset_nick(client);

	/* welcome info */
	proxy_outdata(client, ":%s 001 %s :Welcome to the Internet Relay Network\n", client->proxy_address, client->nick);
	proxy_outdata(client, ":%s 002 %s :Your host is irssi-proxy, running version %s\n", client->proxy_address, client->nick, IRSSI_VERSION);
	proxy_outdata(client, ":%s 003 %s :This server was created ...\n", client->proxy_address, client->nick);
	if (client->server == NULL || !client->server->emode_known)
		proxy_outdata(client, ":%s 004 %s %s %s oirw abiklmnopqstv\n", client->proxy_address, client->nick, client->proxy_address, IRSSI_VERSION);
	else
		proxy_outdata(client, ":%s 004 %s %s %s oirw abeIiklmnopqstv\n", client->proxy_address, client->nick, client->proxy_address, IRSSI_VERSION);

	if (client->server != NULL && client->server->isupport_sent) {
		isupport_out = g_string_new(NULL);
		g_hash_table_foreach(client->server->isupport, proxy_dump_data_005, isupport_out);
		if (isupport_out->len > 0)
			g_string_truncate(isupport_out, isupport_out->len-1);

		proxy_outdata(client, ":%s 005 %s ", client->proxy_address, client->nick);

		paramstr = g_string_new(NULL);
		paramlist = g_strsplit(isupport_out->str, " ", -1);
		count = 0;
		tmp = paramlist;

		for (;; tmp++) {
			if (*tmp != NULL) {
				g_string_sprintfa(paramstr, "%s ", *tmp);
				if (++count < 15)
					continue;
			}

			count = 0;
			if (paramstr->len > 0)
				g_string_truncate(paramstr, paramstr->len-1);
			g_string_sprintfa(paramstr, " :are supported by this server\n");
			proxy_outdata(client, "%s", paramstr->str);
			g_string_truncate(paramstr, 0);
			g_string_sprintf(paramstr, ":%s 005 %s ", client->proxy_address, client->nick);

			if (*tmp == NULL || tmp[1] == NULL)
				break;
		}

		g_string_free(isupport_out, TRUE);
		g_string_free(paramstr, TRUE);
		g_strfreev(paramlist);
	}

	proxy_outdata(client, ":%s 251 %s :There are 0 users and 0 invisible on 1 servers\n", client->proxy_address, client->nick);
	proxy_outdata(client, ":%s 255 %s :I have 0 clients, 0 services and 0 servers\n", client->proxy_address, client->nick);
	proxy_outdata(client, ":%s 422 %s :MOTD File is missing\n", client->proxy_address, client->nick);

	/* user mode / away status */
	if (client->server != NULL) {
		if (client->server->usermode != NULL) {
			proxy_outserver(client, "MODE %s :+%s",
					client->server->nick,
					client->server->usermode);
		}
		if (client->server->usermode_away) {
			proxy_outdata(client, ":%s 306 %s :You have been marked as being away\n",
				      client->proxy_address, client->nick);
		}

		/* Send channel joins */
		g_slist_foreach(client->server->channels, (GFunc) dump_join, client);
	}
}