예제 #1
0
static void
process_named_servermsg (session *sess, char *buf, char *rawname, char *word_eol[],
								 const message_tags_data *tags_data)
{
	sess = sess->server->server_session;

	if (!strncmp (buf, "PING ", 5))
	{
		tcp_sendf (sess->server, "PONG %s\r\n", buf + 5);
		return;
	}
	if (!strncmp (buf, "ERROR", 5))
	{
		EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVERERROR, sess, buf + 7, NULL, NULL, NULL,
									  0, tags_data->timestamp);
		return;
	}
	if (!strncmp (buf, "NOTICE ", 7))
	{
		buf = word_eol[3];
		if (*buf == ':')
			buf++;
		EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVNOTICE, sess, buf, 
									  sess->server->servername, NULL, NULL, 0,
									  tags_data->timestamp);
		return;
	}
	if (!strncmp (buf, "AUTHENTICATE", 12))
	{
		inbound_sasl_authenticate (sess->server, word_eol[2]);
		return;
	}

	EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVTEXT, sess, buf, sess->server->servername,
								  rawname, NULL, 0, tags_data->timestamp);
}
예제 #2
0
static void
process_named_msg (session *sess, char *type, char *word[], char *word_eol[],
						 const message_tags_data *tags_data)
{
	server *serv = sess->server;
	char ip[128], nick[NICKLEN];
	char *text, *ex;
	int len = strlen (type);

	/* fill in the "ip" and "nick" buffers */
	ex = strchr (word[1], '!');
	if (!ex)							  /* no '!', must be a server message */
	{
		safe_strcpy (ip, word[1], sizeof (ip));
		safe_strcpy (nick, word[1], sizeof (nick));
	} else
	{
		safe_strcpy (ip, ex + 1, sizeof (ip));
		ex[0] = 0;
		safe_strcpy (nick, word[1], sizeof (nick));
		ex[0] = '!';
	}

	if (len == 4)
	{
		guint32 t;

		t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); 	
		/* this should compile to a bunch of: CMP.L, JE ... nice & fast */
		switch (t)
		{
		case WORDL('J','O','I','N'):
			{
				char *chan = word[3];
				char *account = word[4];
				char *realname = word_eol[5];

				if (account && strcmp (account, "*") == 0)
					account = NULL;
				if (realname && *realname == ':')
					realname++;
				if (*chan == ':')
					chan++;
				if (!serv->p_cmp (nick, serv->nick))
					inbound_ujoin (serv, chan, nick, ip, tags_data);
				else
					inbound_join (serv, chan, nick, ip, account, realname,
									  tags_data);
			}
			return;

		case WORDL('K','I','C','K'):
			{
				char *kicked = word[4];
				char *reason = word_eol[5];
				if (*kicked)
				{
					if (*reason == ':')
						reason++;
					if (!strcmp (kicked, serv->nick))
	 					inbound_ukick (serv, word[3], nick, reason, tags_data);
					else
						inbound_kick (serv, word[3], kicked, nick, reason, tags_data);
				}
			}
			return;

		case WORDL('K','I','L','L'):
			{
				char *reason = word_eol[4];
				if (*reason == ':')
					reason++;

				EMIT_SIGNAL_TIMESTAMP (XP_TE_KILL, sess, nick, reason, NULL, NULL,
											  0, tags_data->timestamp);
			}
			return;

		case WORDL('M','O','D','E'):
			handle_mode (serv, word, word_eol, nick, FALSE, tags_data);	/* modes.c */
			return;

		case WORDL('N','I','C','K'):
			inbound_newnick (serv, nick, 
								  (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3],
								  FALSE, tags_data);
			return;

		case WORDL('P','A','R','T'):
			{
				char *chan = word[3];
				char *reason = word_eol[4];

				if (*chan == ':')
					chan++;
				if (*reason == ':')
					reason++;
				if (!strcmp (nick, serv->nick))
					inbound_upart (serv, chan, ip, reason, tags_data);
				else
					inbound_part (serv, chan, nick, ip, reason, tags_data);
			}
			return;

		case WORDL('P', 'I', 'N', 'G'):
			tcp_sendf (sess->server, "PONG %s\r\n", word_eol[3]);
			return;

		case WORDL('P','O','N','G'):
			inbound_ping_reply (serv->server_session,
									  (word[4][0] == ':') ? word[4] + 1 : word[4],
									  word[3], tags_data);
			return;

		case WORDL('Q','U','I','T'):
			inbound_quit (serv, nick, ip,
							  (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3],
							  tags_data);
			return;

		case WORDL('A','W','A','Y'):
			inbound_away_notify (serv, nick,
										(word_eol[3][0] == ':') ? word_eol[3] + 1 : NULL,
										tags_data);
			return;
		}

		goto garbage;
	}

	else if (len >= 5)
	{
		guint32 t;

		t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]); 	
		/* this should compile to a bunch of: CMP.L, JE ... nice & fast */
		switch (t)
		{

		case WORDL('A','C','C','O'):
			inbound_account (serv, nick, word[3], tags_data);
			return;

		case WORDL('A', 'U', 'T', 'H'):
			inbound_sasl_authenticate (sess->server, word_eol[3]);
			return;

		case WORDL('C', 'H', 'G', 'H'):
			inbound_user_info (sess, NULL, word[3], word[4], NULL, nick, NULL,
							   NULL, 0xff, tags_data);
			return;

		case WORDL('I','N','V','I'):
			if (ignore_check (word[1], IG_INVI))
				return;
			
			if (word[4][0] == ':')
				EMIT_SIGNAL_TIMESTAMP (XP_TE_INVITED, sess, word[4] + 1, nick,
											  serv->servername, NULL, 0,
											  tags_data->timestamp);
			else
				EMIT_SIGNAL_TIMESTAMP (XP_TE_INVITED, sess, word[4], nick,
											  serv->servername, NULL, 0,
											  tags_data->timestamp);
				
			return;

		case WORDL('N','O','T','I'):
			{
				int id = FALSE;								/* identified */

				text = word_eol[4];
				if (*text == ':')
				{
					text++;
				}

#ifdef USE_OPENSSL
				/* QuakeNet CHALLENGE upon our request */
				if (serv->loginmethod == LOGIN_CHALLENGEAUTH && !serv->p_cmp (word[1], CHALLENGEAUTH_FULLHOST)
				    && !strncmp (text, "CHALLENGE ", 10) && *serv->password)
				{
					char *response;
					ircnet *net = serv->network;
					char *user = net && net->user ? net->user : prefs.hex_irc_user_name;

					response = challengeauth_response (user, serv->password, word[5]);

					tcp_sendf (serv, "PRIVMSG %s :CHALLENGEAUTH %s %s %s\r\n",
						CHALLENGEAUTH_NICK,
						user,
						response,
						CHALLENGEAUTH_ALGO);

					g_free (response);
					return;									/* omit the CHALLENGE <hash> ALGOS message */
				}
#endif

				if (serv->have_idmsg)
				{
					if (*text == '+')
					{
						id = TRUE;
						text++;
					} else if (*text == '-')
						text++;
				}

				if (!ignore_check (word[1], IG_NOTI))
					inbound_notice (serv, word[3], nick, text, ip, id, tags_data);
			}
			return;

		case WORDL('P','R','I','V'):
			{
				char *to = word[3];
				int len;
				int id = FALSE;	/* identified */
				if (*to)
				{
					/* Handle limited channel messages, for now no special event */
					if (strchr (serv->chantypes, to[0]) == NULL
						&& strchr (serv->nick_prefixes, to[0]) != NULL)
						to++;
						
					text = word_eol[4];
					if (*text == ':')
						text++;
					if (serv->have_idmsg)
					{
						if (*text == '+')
						{
							id = TRUE;
							text++;
						} else if (*text == '-')
							text++;
					}
					len = strlen (text);
					if (text[0] == 1 && text[len - 1] == 1)	/* ctcp */
					{
						text[len - 1] = 0;
						text++;
						if (g_ascii_strncasecmp (text, "ACTION", 6) != 0)
							flood_check (nick, ip, serv, sess, 0);
						if (g_ascii_strncasecmp (text, "DCC ", 4) == 0)
							/* redo this with handle_quotes TRUE */
							process_data_init (word[1], word_eol[1], word, word_eol, TRUE, FALSE);
						ctcp_handle (sess, to, nick, ip, text, word, word_eol, id,
										 tags_data);
					} else
					{
						if (is_channel (serv, to))
						{
							if (ignore_check (word[1], IG_CHAN))
								return;
							inbound_chanmsg (serv, NULL, to, nick, text, FALSE, id,
												  tags_data);
						} else
						{
							if (ignore_check (word[1], IG_PRIV))
								return;
							inbound_privmsg (serv, nick, ip, text, id, tags_data);
						}
					}
				}
			}
			return;

		case WORDL('T','O','P','I'):
			inbound_topicnew (serv, nick, word[3],
									(word_eol[4][0] == ':') ? word_eol[4] + 1 : word_eol[4],
									tags_data);
			return;

		case WORDL('W','A','L','L'):
			text = word_eol[3];
			if (*text == ':')
				text++;
			EMIT_SIGNAL_TIMESTAMP (XP_TE_WALLOPS, sess, nick, text, NULL, NULL, 0,
										  tags_data->timestamp);
			return;
		}
	}

	else if (len == 3)
	{
		guint32 t;

		t = WORDL((guint8)type[0], (guint8)type[1], (guint8)type[2], (guint8)type[3]);
		switch (t)
		{
			case WORDL('C','A','P','\0'):
				if (strncasecmp (word[4], "ACK", 3) == 0)
				{
					inbound_cap_ack (serv, word[1], 
										  word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5],
										  tags_data);
				}
				else if (strncasecmp (word[4], "LS", 2) == 0 || strncasecmp (word[4], "NEW", 3) == 0)
				{
					inbound_cap_ls (serv, word[1], 
										 word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5],
										 tags_data);
				}
				else if (strncasecmp (word[4], "NAK", 3) == 0)
				{
					inbound_cap_nak (serv, tags_data);
				}
				else if (strncasecmp (word[4], "LIST", 4) == 0)	
				{
					inbound_cap_list (serv, word[1], 
											word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5],
											tags_data);
				}
				else if (strncasecmp (word[4], "DEL", 3) == 0)
				{
					inbound_cap_del (serv, word[1],
											word[5][0] == ':' ? word_eol[5] + 1 : word_eol[5],
											tags_data);
				}

				return;
		}
	}

garbage:
	/* unknown message */
	PrintTextTimeStampf (sess, tags_data->timestamp, "GARBAGE: %s\n", word_eol[1]);
}