Beispiel #1
0
void
inbound_privmsg (server *serv, char *from, char *ip, char *text, int id,
					  const message_tags_data *tags_data)
{
	session *sess;
	struct User *user;
	char idtext[64];
	gboolean nodiag = FALSE;

	sess = find_dialog (serv, from);

	if (sess || prefs.hex_gui_autoopen_dialog)
	{
		/*0=ctcp  1=priv will set hex_gui_autoopen_dialog=0 here is flud detected */
		if (!sess)
		{
			if (flood_check (from, ip, serv, current_sess, 1))
				/* Create a dialog session */
				sess = inbound_open_dialog (serv, from, tags_data);
			else
				sess = serv->server_session;
			if (!sess)
				return; /* ?? */
		}

		if (ip && ip[0])
			set_topic (sess, ip, ip);
		inbound_chanmsg (serv, NULL, NULL, from, text, FALSE, id, tags_data);
		return;
	}

	sess = find_session_from_nick (from, serv);
	if (!sess)
	{
		sess = serv->front_session;
		nodiag = TRUE; /* We don't want it to look like a normal message in front sess */
	}

	user = userlist_find (sess, from);
	if (user)
	{
		user->lasttalk = time (0);
		if (user->account)
			id = TRUE;
	}
	
	inbound_make_idtext (serv, idtext, sizeof (idtext), id);

	if (sess->type == SESS_DIALOG && !nodiag)
		EMIT_SIGNAL_TIMESTAMP (XP_TE_DPRIVMSG, sess, from, text, idtext, NULL, 0,
									  tags_data->timestamp);
	else
		EMIT_SIGNAL_TIMESTAMP (XP_TE_PRIVMSG, sess, from, text, idtext, NULL, 0, 
									  tags_data->timestamp);
}
Beispiel #2
0
void
inbound_privmsg (server * serv, char *from, char *ip, char *text, int id)
{
    session *sess;
    char idtext[64];

    sess = find_dialog (serv, from);

    if (sess || prefs.autodialog)
    {
        /*0=ctcp  1=priv will set autodialog=0 here is flud detected */
        if (!sess)
        {
            if (flood_check (from, ip, serv, current_sess, 1))
                /* Create a dialog session */
                sess = inbound_open_dialog (serv, from);
            else
                sess = serv->server_session;
            if (!sess)
                return;     /* ?? */
        }

        if (ip && ip[0])
        {
            if (prefs.logging && sess->logfd != -1 &&
                    (!sess->topic || strcmp (sess->topic, ip)))
            {
                char tbuf[1024];
                snprintf (tbuf, sizeof (tbuf), "[%s has address %s]\n",
                          from, ip);
                write (sess->logfd, tbuf, strlen (tbuf));
            }
            set_topic (sess, ip, ip);
        }
        inbound_chanmsg (serv, NULL, NULL, from, text, FALSE, id);
        return;
    }

    inbound_make_idtext (serv, idtext, sizeof (idtext), id);

    sess = find_session_from_nick (from, serv);
    if (!sess)
    {
        sess = serv->front_session;
        EMIT_SIGNAL (XP_TE_PRIVMSG, sess, from, text, idtext, NULL, 0);
        return;
    }

    if (sess->type == SESS_DIALOG)
        EMIT_SIGNAL (XP_TE_DPRIVMSG, sess, from, text, idtext, NULL, 0);
    else
        EMIT_SIGNAL (XP_TE_PRIVMSG, sess, from, text, idtext, NULL, 0);
}
Beispiel #3
0
bool		exec_client(fds c, double tdt)
{
  char		*s;

  s = getcmd(c);
  if (((c && (c->trick) && ((t_client*)c->trick)->close) || !fds_alive(c)) &&
      (c->write || net_close(c)))
    return (true);
  if (!(c->trick) || !(((t_client*)c->trick)->_m))
    return (mod_discovery(c, &s));
  s = flood_check(c, s);
  if (scheduler_(c, tdt))
    return (scheduler_dispatch(c));
  else if (!scheduler_active(c) && callback_(c, s, tdt))
    return (callback_handler(c, s));
  else if (s && !scheduler_active(c) && (find_action(c, s) != -1))
    flood_read(c);
  return (true);
}
Beispiel #4
0
void
inbound_action (session *sess, char *chan, char *from, char *ip, char *text, int fromme, int id)
{
	session *def = sess;
	server *serv = sess->server;
	struct User *user;
	char nickchar[2] = "\000";
	char idtext[64];
	int privaction = FALSE;

	if (!fromme)
	{
		if (is_channel (serv, chan))
		{
			sess = find_channel (serv, chan);
		} else
		{
			/* it's a private action! */
			privaction = TRUE;
			/* find a dialog tab for it */
			sess = find_dialog (serv, from);
			/* if non found, open a new one */
			if (!sess && prefs.hex_gui_autoopen_dialog)
			{
				/* but only if it wouldn't flood */
				if (flood_check (from, ip, serv, current_sess, 1))
					sess = inbound_open_dialog (serv, from);
				else
					sess = serv->server_session;
			}
			if (!sess)
			{
				sess = find_session_from_nick (from, serv);
				/* still not good? */
				if (!sess)
					sess = serv->front_session;
			}
		}
	}

	if (!sess)
		sess = def;

	if (sess != current_tab)
	{
		if (fromme)
		{
			sess->msg_said = FALSE;
			sess->new_data = TRUE;
		} else
		{
			sess->msg_said = TRUE;
			sess->new_data = FALSE;
		}
	}

	user = userlist_find (sess, from);
	if (user)
	{
		nickchar[0] = user->prefix[0];
		user->lasttalk = time (0);
	}

	inbound_make_idtext (serv, idtext, sizeof (idtext), id);

	if (!fromme && !privaction)
	{
		if (is_hilight (from, text, sess, serv))
		{
			EMIT_SIGNAL (XP_TE_HCHANACTION, sess, from, text, nickchar, idtext, 0);
			return;
		}
	}

	if (fromme)
		EMIT_SIGNAL (XP_TE_UACTION, sess, from, text, nickchar, idtext, 0);
	else if (!privaction)
		EMIT_SIGNAL (XP_TE_CHANACTION, sess, from, text, nickchar, idtext, 0);
	else if (sess->type == SESS_DIALOG)
		EMIT_SIGNAL (XP_TE_DPRIVACTION, sess, from, text, idtext, NULL, 0);
	else
		EMIT_SIGNAL (XP_TE_PRIVACTION, sess, from, text, idtext, NULL, 0);
}
Beispiel #5
0
static void
process_named_msg (session *sess, char *type, char *word[], char *word_eol[])
{
	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];

				if (*chan == ':')
					chan++;
				if (!serv->p_cmp (nick, serv->nick))
					inbound_ujoin (serv, chan, nick, ip);
				else
					inbound_join (serv, chan, nick, ip);
			}
			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);
					else
						inbound_kick (serv, word[3], kicked, nick, reason);
				}
			}
			return;

		case WORDL('K','I','L','L'):
			EMIT_SIGNAL (XP_TE_KILL, sess, nick, word_eol[5], NULL, NULL, 0);
			return;

		case WORDL('M','O','D','E'):
			handle_mode (serv, word, word_eol, nick, FALSE);	/* 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);
			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);
				else
					inbound_part (serv, chan, nick, ip, reason);
			}
			return;

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

		case WORDL('Q','U','I','T'):
			inbound_quit (serv, nick, ip,
							  (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3]);
			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('I','N','V','I'):
			if (ignore_check (word[1], IG_INVI))
				return;
			
			if (word[4][0] == ':')
				EMIT_SIGNAL (XP_TE_INVITED, sess, word[4] + 1, nick,
								 serv->servername, NULL, 0);
			else
				EMIT_SIGNAL (XP_TE_INVITED, sess, word[4], nick,
								 serv->servername, NULL, 0);
				
			return;

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

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

				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);
			}
			return;

		case WORDL('P','R','I','V'):
			{
				char *to = word[3];
				int len;
				int id = FALSE;	/* identified */
				if (*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 (strncasecmp (text, "ACTION", 6) != 0)
							flood_check (nick, ip, serv, sess, 0);
						if (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);
					} else
					{
						if (is_channel (serv, to))
						{
							if (ignore_check (word[1], IG_CHAN))
								return;
							inbound_chanmsg (serv, NULL, to, nick, text, FALSE, id);
						} else
						{
							if (ignore_check (word[1], IG_PRIV))
								return;
							inbound_privmsg (serv, nick, ip, text, id);
						}
					}
				}
			}
			return;

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

		case WORDL('W','A','L','L'):
			text = word_eol[3];
			if (*text == ':')
				text++;
			EMIT_SIGNAL (XP_TE_WALLOPS, sess, nick, text, NULL, NULL, 0);
			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)
			{
				if (strncasecmp(word[5][0]==':' ? word[5]+1 : word[5],
					"identify-msg", 12) == 0)
				{
					serv->have_idmsg = TRUE;
					tcp_send_len(serv, "CAP END\r\n", 9);
				}
			}
			else if (strncasecmp(word[4], "LS", 2) == 0)
			{
				if (strstr(word_eol[5], "identify-msg") != 0)
					tcp_send_len(serv, "CAP REQ :identify-msg\r\n", 23);
				else
					tcp_send_len(serv, "CAP END\r\n", 9);
			}
			else if (strncasecmp(word[4], "NAK",3) == 0)
			{
				tcp_send_len(serv, "CAP END\r\n", 9);
			}
			return;
		}
	}

garbage:
	/* unknown message */
	PrintTextf (sess, "GARBAGE: %s\n", word_eol[1]);
}
Beispiel #6
0
static void inbound_privmsg_helper(char *nickchar, char *prefixchar, char *idtext,
				   int *is_highlight, msg_destination *action_type,
				   session **initial_session, server *serv, char **chan,
				   char *from, char *ip, char *text, int *from_me, int *id,
				   const message_tags_data *tags_data)
{
	struct User *user;
	session *sess = *initial_session;

	if (*from_me && sess == NULL)
	{
		*action_type = MSGDEST_DIRECT;
		sess = serv->front_session;
	}
	else if (*chan && is_channel (serv, *chan))
	{
		*action_type = MSGDEST_CHANNEL;
		sess = find_channel (serv, *chan);
	}
	else if (*chan && strchr(serv->nick_prefixes, **chan) && is_channel (serv, *chan + 1))
	{
		*action_type = MSGDEST_PREFIX;
		prefixchar[0] = **chan;
		++*chan;
		sess = find_channel (serv, *chan);
	}
	else
	{
		char *target = *from_me ? *chan : from;
		session *userquery = find_dialog (serv, target);
		if (!userquery)
		{
			if (prefs.hex_gui_autoopen_dialog && flood_check (target, ip, serv, current_sess, 1))
			{
				*action_type = MSGDEST_PRIVATE;
				sess = inbound_open_dialog (serv, target, tags_data);
			}
			else
			{
				*action_type = MSGDEST_DIRECT;
				sess = serv->front_session;
			}
		}
		else
		{
			*action_type = MSGDEST_PRIVATE;
			sess = userquery;
		}
	}

	*is_highlight = is_hilight (from, text, sess, serv);

	if (sess != current_tab)
	{
		if (*from_me)
		{
			sess->msg_said = FALSE;
			sess->new_data = TRUE;
		} else
		{
			sess->msg_said = TRUE;
			sess->new_data = FALSE;
		}
		lastact_update (sess);
	}

	user = userlist_find (sess, from);
	if (user)
	{
		nickchar[0] = user->prefix[0];
		user->lasttalk = time (0);
		if (user->account)
			*id = TRUE;
		if (user->me)
			*from_me = TRUE;
	}

	inbound_make_idtext (serv, idtext, sizeof (idtext), *id);

	*initial_session = sess;
}
Beispiel #7
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','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('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
				if (!strncmp (text, "CHALLENGE ", 10))		/* QuakeNet CHALLENGE upon our request */
				{
					char *response = challengeauth_response (((ircnet *)serv->network)->user ? ((ircnet *)serv->network)->user : prefs.hex_irc_user_name, serv->password, word[5]);

					tcp_sendf (serv, "PRIVMSG %s :CHALLENGEAUTH %s %s %s\r\n",
						CHALLENGEAUTH_NICK,
						((ircnet *)serv->network)->user ? ((ircnet *)serv->network)->user : prefs.hex_irc_user_name,
						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)
				{
					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);
				}

				return;
		}
	}

garbage:
	/* unknown message */
	PrintTextTimeStampf (sess, tags_data->timestamp, "GARBAGE: %s\n", word_eol[1]);
}
Beispiel #8
0
void
inbound_privmsg (server *serv, char *from, char *ip, char *text, int id)
{
	session *sess;
	struct User *user;
	char idtext[64];
	gboolean nodiag = FALSE;

	sess = find_dialog (serv, from);

	if (sess || prefs.hex_gui_autoopen_dialog)
	{
		/*0=ctcp  1=priv will set hex_gui_autoopen_dialog=0 here is flud detected */
		if (!sess)
		{
			if (flood_check (from, ip, serv, current_sess, 1))
				/* Create a dialog session */
				sess = inbound_open_dialog (serv, from);
			else
				sess = serv->server_session;
			if (!sess)
				return; /* ?? */
		}

		if (ip && ip[0])
		{
			if (prefs.hex_irc_logging && sess->logfd != -1 &&
				(!sess->topic || strcmp(sess->topic, ip)))
			{
				char tbuf[1024];
				snprintf (tbuf, sizeof (tbuf), "[%s has address %s]\n", from, ip);
				write (sess->logfd, tbuf, strlen (tbuf));
			}
			set_topic (sess, ip, ip);
		}
		inbound_chanmsg (serv, NULL, NULL, from, text, FALSE, id);
		return;
	}

	sess = find_session_from_nick (from, serv);
	if (!sess)
	{
		sess = serv->front_session;
		nodiag = TRUE; /* We don't want it to look like a normal message in front sess */
	}

	user = userlist_find (sess, from);
	if (user)
	{
		user->lasttalk = time (0);
		if (user->account)
			id = TRUE;
	}
	
	inbound_make_idtext (serv, idtext, sizeof (idtext), id);

	if (sess->type == SESS_DIALOG && !nodiag)
		EMIT_SIGNAL (XP_TE_DPRIVMSG, sess, from, text, idtext, NULL, 0);
	else
		EMIT_SIGNAL (XP_TE_PRIVMSG, sess, from, text, idtext, NULL, 0);
}
Beispiel #9
0
static void
process_named_msg (session *sess, char *type, char *word[], char *word_eol[])
{
    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];

            if (*chan == ':')
                chan++;
            if (!serv->p_cmp (nick, serv->nick))
                inbound_ujoin (serv, chan, nick, ip);
            else
                inbound_join (serv, chan, nick, ip);
        }
        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);
                else
                    inbound_kick (serv, word[3], kicked, nick, reason);
            }
        }
        return;

        case WORDL('K','I','L','L'):
            EMIT_SIGNAL (XP_TE_KILL, sess, nick, word_eol[5], NULL, NULL, 0);
            return;

        case WORDL('M','O','D','E'):
            handle_mode (serv, word, word_eol, nick, FALSE);	/* 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);
            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);
            else
                inbound_part (serv, chan, nick, ip, reason);
        }
        return;

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

        case WORDL('Q','U','I','T'):
            inbound_quit (serv, nick, ip,
                          (word_eol[3][0] == ':') ? word_eol[3] + 1 : word_eol[3]);
            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('I','N','V','I'):
            if (ignore_check (word[1], IG_INVI))
                return;

            if (word[4][0] == ':')
                EMIT_SIGNAL (XP_TE_INVITED, sess, word[4] + 1, nick,
                             serv->servername, NULL, 0);
            else
                EMIT_SIGNAL (XP_TE_INVITED, sess, word[4], nick,
                             serv->servername, NULL, 0);

            return;

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

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

            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);
        }
        return;

        case WORDL('P','R','I','V'):
        {
            char *to = word[3];
            int len;
            int id = FALSE;	/* identified */
            if (*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);
                } else
                {
                    if (is_channel (serv, to))
                    {
                        if (ignore_check (word[1], IG_CHAN))
                            return;
                        inbound_chanmsg (serv, NULL, to, nick, text, FALSE, id);
                    } else
                    {
                        if (ignore_check (word[1], IG_PRIV))
                            return;
                        inbound_privmsg (serv, nick, ip, text, id);
                    }
                }
            }
        }
        return;

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

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

    else if (len == 3)
    {
        guint32 t;
        guint32 want_cap;		/* format the CAP REQ string based on previous capabilities being requested or not */
        guint32 want_sasl;		/* CAP END shouldn't be sent when SASL is requested, it needs further responses */
        char *pass;				/* buffer for SASL password */
        char buffer[256];		/* buffer for requesting capabilities and emitting the signal */

        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)
            {
                EMIT_SIGNAL (XP_TE_CAPACK, sess->server->server_session, word[1], word[5][0]==':' ? ++word_eol[5] : word_eol[5], NULL, NULL, 0);

                if (strstr (word_eol[5], "identify-msg") != 0)
                {
                    serv->have_idmsg = TRUE;
                }

                if (strstr (word_eol[5], "multi-prefix") != 0)
                {
                    serv->have_namesx = TRUE;
                }

                if (strstr (word_eol[5], "sasl") != 0)
                {
                    serv->have_sasl = TRUE;
                    EMIT_SIGNAL (XP_TE_SASLAUTH, serv->server_session, sess->server->sasluser, NULL, NULL, NULL, 0);
                    tcp_send_len (serv, "AUTHENTICATE PLAIN\r\n", 20);

                    pass = encode_sasl_pass (sess->server->sasluser, sess->server->saslpassword);
                    tcp_sendf (sess->server, "AUTHENTICATE %s\r\n", pass);
                    free (pass);
                }
            }
            else if (strncasecmp (word[4], "LS", 2) == 0)
            {
                EMIT_SIGNAL (XP_TE_CAPLIST, serv->server_session, word[1], word[5][0]==':' ? ++word_eol[5] : word_eol[5], NULL, NULL, 0);
                want_cap = 0;
                want_sasl = 0;

                if (strstr (word_eol[5], "identify-msg") != 0)
                {
                    strcpy (buffer, "CAP REQ :identify-msg");
                    want_cap = 1;
                }
                if (strstr (word_eol[5], "multi-prefix") != 0)
                {
                    want_cap ? strcat (buffer, " multi-prefix") : strcpy (buffer, "CAP REQ :multi-prefix");
                    want_cap = 1;
                }
                /* if the SASL password is set, request SASL auth */
                if (strstr (word_eol[5], "sasl") != 0 && strlen (sess->server->saslpassword) != 0)
                {
                    want_cap ? strcat (buffer, " sasl") : strcpy (buffer, "CAP REQ :sasl");
                    want_sasl = 1;
                }

                if (want_cap)
                {
                    /* buffer + 9 = emit buffer without "CAP REQ :" */
                    EMIT_SIGNAL (XP_TE_CAPREQ, sess->server->server_session, buffer + 9, NULL, NULL, NULL, 0);
                    tcp_sendf (serv, "%s\r\n", buffer);
                }
                if (!want_sasl)
                {
                    /* if we use SASL, CAP END is dealt via raw numerics */
                    tcp_send_len (serv, "CAP END\r\n", 9);
                }
            }
            else if (strncasecmp (word[4], "NAK", 3) == 0)
            {
                tcp_send_len (serv, "CAP END\r\n", 9);
            }

            return;
        }
    }

garbage:
    /* unknown message */
    PrintTextf (sess, "GARBAGE: %s\n", word_eol[1]);
}