Exemplo n.º 1
0
static session *
inbound_open_dialog (server * serv, char *from)
{
    session *sess;

    sess = new_ircwindow (serv, from, SESS_DIALOG, 0);
    /* for playing sounds */
    EMIT_SIGNAL (XP_TE_OPENDIALOG, sess, NULL, NULL, NULL, NULL, 0);

    return sess;
}
Exemplo n.º 2
0
void
inbound_ping_reply (session * sess, char *timestring, char *from)
{
    unsigned long tim, nowtim, dif;
    int lag = 0;
    char outbuf[64];

    if (strncmp (timestring, "LAG", 3) == 0)
    {
        timestring += 3;
        lag = 1;
    }

    tim = strtoul (timestring, NULL, 10);
    nowtim = make_ping_time ();
    dif = nowtim - tim;

    sess->server->ping_recv = time (0);

    if (lag)
    {
        sess->server->lag_sent = 0;
        sess->server->lag = dif / 1000;
        fe_set_lag (sess->server, dif / 100000);
        return;
    }

    if (atol (timestring) == 0)
    {
        if (sess->server->lag_sent)
            sess->server->lag_sent = 0;
        else
            EMIT_SIGNAL (XP_TE_PINGREP, sess, from, "?", NULL, NULL, 0);
    }
    else
    {
        snprintf (outbuf, sizeof (outbuf), "%ld.%ld%ld", dif / 1000000,
                  (dif / 100000) % 10, dif % 10);
        EMIT_SIGNAL (XP_TE_PINGREP, sess, from, outbuf, NULL, NULL, 0);
    }
}
Exemplo n.º 3
0
void
inbound_next_nick (session *sess, char *nick)
{
	sess->server->nickcount++;

	switch (sess->server->nickcount)
	{
	case 2:
		sess->server->p_change_nick (sess->server, prefs.nick2);
		EMIT_SIGNAL (XP_TE_NICKCLASH, sess, nick, prefs.nick2, NULL, NULL, 0);
		break;

	case 3:
		sess->server->p_change_nick (sess->server, prefs.nick3);
		EMIT_SIGNAL (XP_TE_NICKCLASH, sess, nick, prefs.nick3, NULL, NULL, 0);
		break;

	default:
		EMIT_SIGNAL (XP_TE_NICKFAIL, sess, NULL, NULL, NULL, NULL, 0);
	}
}
Exemplo n.º 4
0
void
inbound_topictime (server *serv, char *chan, char *nick, time_t stamp)
{
	char *tim = ctime (&stamp);
	session *sess = find_channel (serv, chan);

	if (!sess)
		sess = serv->server_session;

	tim[24] = 0;	/* get rid of the \n */
	EMIT_SIGNAL (XP_TE_TOPICDATE, sess, chan, nick, tim, NULL, 0);
}
Exemplo n.º 5
0
void
inbound_sasl_authenticate (server *serv, char *data)
{
		ircnet *net = (ircnet*)serv->network;
		char *user, *pass = NULL;
		const char *mech = sasl_mechanisms[serv->sasl_mech];

		/* Got a list of supported mechanisms from inspircd */
		if (strchr (data, ',') != NULL)
		{
			inbound_sasl_supportedmechs (serv, data);
			return;
		}

		if (net->user && !(net->flags & FLAG_USE_GLOBAL))
			user = net->user;
		else
			user = prefs.hex_irc_user_name;

		switch (serv->sasl_mech)
		{
		case MECH_PLAIN:
			pass = encode_sasl_pass_plain (user, serv->password);
			break;
#ifdef USE_OPENSSL
		case MECH_BLOWFISH:
			pass = encode_sasl_pass_blowfish (user, serv->password, data);
			break;
		case MECH_AES:
			pass = encode_sasl_pass_aes (user, serv->password, data);
			break;
		case MECH_EXTERNAL:
			pass = g_strdup ("+");
			break;
#endif
		}

		if (pass == NULL)
		{
			/* something went wrong abort */
			serv->sent_saslauth = TRUE; /* prevent trying PLAIN */
			tcp_sendf (serv, "AUTHENTICATE *\r\n");
			return;
		}

		serv->sent_saslauth = TRUE;
		tcp_sendf (serv, "AUTHENTICATE %s\r\n", pass);
		g_free (pass);

		
		EMIT_SIGNAL (XP_TE_SASLAUTH, serv->server_session, user, (char*)mech);
}
Exemplo n.º 6
0
void
do_dns (session *sess, char *nick, char *host)
{
	char *po;
	char tbuf[1024];

	po = strrchr (host, '@');
	if (po)
		host = po + 1;
	EMIT_SIGNAL (XP_TE_RESOLVINGUSER, sess, nick, host, NULL, NULL, 0);
	snprintf (tbuf, sizeof (tbuf), "exec -d %s %s", prefs.hex_dnsprogram, host);
	handle_command (sess, tbuf, FALSE);
}
Exemplo n.º 7
0
void
inbound_foundip (session *sess, char *ip)
{
	struct hostent *HostAddr;

	HostAddr = gethostbyname (ip);
	if (HostAddr)
	{
		prefs.dcc_ip = ((struct in_addr *) HostAddr->h_addr)->s_addr;
		EMIT_SIGNAL (XP_TE_FOUNDIP, sess,
						 inet_ntoa (*((struct in_addr *) HostAddr->h_addr)),
						 NULL, NULL, NULL, 0);
	}
}
Exemplo n.º 8
0
void
inbound_topic (server * serv, char *chan, char *topic_text)
{
    session *sess = find_channel (serv, chan);

    if (sess)
    {
        set_topic (sess, topic_text, topic_text);
    }
    else
        sess = serv->server_session;

    EMIT_SIGNAL (XP_TE_TOPIC, sess, chan, topic_text, NULL, NULL, 0);
}
Exemplo n.º 9
0
void
inbound_ujoin (server *serv, char *chan, char *nick, char *ip)
{
	session *sess;

	/* already joined? probably a bnc */
	sess = find_channel (serv, chan);
	if (!sess)
	{
		/* see if a window is waiting to join this channel */
		sess = find_session_from_waitchannel (chan, serv);
		if (!sess)
		{
			/* find a "<none>" tab and use that */
			sess = find_unused_session (serv);
			if (!sess)
				/* last resort, open a new tab/window */
				sess = new_ircwindow (serv, chan, SESS_CHANNEL);
		}
	}

	safe_strcpy (sess->channel, chan, CHANLEN);

	fe_set_channel (sess);
	fe_set_title (sess);
	fe_set_nonchannel (sess, TRUE);
	clear_user_list (sess);

	if (prefs.logging)
		log_open (sess);

	sess->waitchannel[0] = 0;
	sess->ignore_date = TRUE;
	sess->ignore_mode = TRUE;
	sess->ignore_names = TRUE;
	sess->end_of_names = FALSE;

	/* sends a MODE */
	serv->p_join_info (sess->server, chan);

	EMIT_SIGNAL (XP_TE_UJOIN, sess, nick, chan, ip, NULL, 0);

	if (prefs.userhost)
	{
		/* sends WHO #channel */
		serv->p_user_list (sess->server, chan);
		sess->doing_who = TRUE;
	}
}
Exemplo n.º 10
0
void
inbound_ukick (server *serv, char *chan, char *kicker, char *reason)
{
	session *sess = find_channel (serv, chan);
	if (sess)
	{
		EMIT_SIGNAL (XP_TE_UKICK, sess, serv->nick, chan, kicker, reason, 0);
		clear_channel (sess);
		if (prefs.hex_irc_auto_rejoin)
		{
			serv->p_join (serv, chan, sess->channelkey);
			safe_strcpy (sess->waitchannel, chan, CHANLEN);
		}
	}
}
Exemplo n.º 11
0
void
inbound_topicnew (server *serv, char *nick, char *chan, char *topic)
{
	session *sess;
	char *stripped_topic;

	sess = find_channel (serv, chan);
	if (sess)
	{
		EMIT_SIGNAL (XP_TE_NEWTOPIC, sess, nick, topic, chan, NULL, 0);
		stripped_topic = strip_color (topic, -1, STRIP_ALL);
		set_topic (sess, topic, stripped_topic);
		g_free (stripped_topic);
	}
}
Exemplo n.º 12
0
void
inbound_away_notify (server *serv, char *nick, char *reason)
{
	session *sess = NULL;
	GSList *list;

	list = sess_list;
	while (list)
	{
		sess = list->data;
		if (sess->server == serv)
		{
			userlist_set_away (sess, nick, reason ? TRUE : FALSE);
			if (sess == serv->front_session && notify_is_in_list (serv, nick))
			{
				if (reason)
					EMIT_SIGNAL (XP_TE_NOTIFYAWAY, sess, nick, reason, NULL, NULL, 0);
				else
					EMIT_SIGNAL (XP_TE_NOTIFYBACK, sess, nick, NULL, NULL, NULL, 0);
			}
		}
		list = list->next;
	}
}
Exemplo n.º 13
0
void
inbound_topicnew (server *serv, char *nick, char *chan, char *topic)
{
	session *sess;
	char *new_topic;

	sess = find_channel (serv, chan);
	if (sess)
	{
		new_topic = strip_color (topic);
		set_topic (sess, new_topic);
		free (new_topic);
		EMIT_SIGNAL (XP_TE_NEWTOPIC, sess, nick, topic, chan, NULL, 0);
	}
}
Exemplo n.º 14
0
void
inbound_topic (server *serv, char *chan, char *topic_text)
{
	session *sess = find_channel (serv, chan);
	char *new_topic;

	if (sess)
	{
		new_topic = strip_color (topic_text);
		set_topic (sess, new_topic);
		free (new_topic);
	} else
		sess = serv->server_session;

	EMIT_SIGNAL (XP_TE_TOPIC, sess, chan, topic_text, NULL, NULL, 0);
}
Exemplo n.º 15
0
static void
notify_announce_offline (server * serv, struct notify_per_server *servnot,
								char *nick, int quiet)
{
	session *sess;

	sess = serv->front_session;

	servnot->ison = FALSE;
	servnot->lastoff = time (0);
	if (!quiet)
		EMIT_SIGNAL (XP_TE_NOTIFYOFFLINE, sess, nick, serv->servername,
						 server_get_network (serv, TRUE), NULL, 0);
	fe_notify_update (nick);
	fe_notify_update (0);
}
Exemplo n.º 16
0
void
inbound_topic (server *serv, char *chan, char *topic_text)
{
	session *sess = find_channel (serv, chan);
	char *stripped_topic;

	if (sess)
	{
		stripped_topic = strip_color (topic_text, -1, STRIP_ALL);
		set_topic (sess, topic_text, stripped_topic);
		g_free (stripped_topic);
	} else
		sess = serv->server_session;

	EMIT_SIGNAL (XP_TE_TOPIC, sess, chan, topic_text, NULL, NULL, 0);
}
Exemplo n.º 17
0
void
inbound_topic (server * serv, char *chan, char *topic_text)
{
    session *sess = find_channel (serv, chan);

    if (sess)
    {
        if (!prefs.topic_color)
            set_topic(sess, topic_text, strip_color(topic_text, -1, STRIP_ALL));
        else
            set_topic(sess, topic_text, topic_text);
    }
    else
        sess = serv->server_session;

    EMIT_SIGNAL (XP_TE_TOPIC, sess, chan, topic_text, NULL, NULL, 0);
}
Exemplo n.º 18
0
void
inbound_banlist (session *sess, time_t stamp, char *chan, char *mask, char *banner)
{
	char *time_str = ctime (&stamp);
	server *serv = sess->server;

	time_str[19] = 0;	/* get rid of the \n */
	if (stamp == 0)
		time_str = "";

	sess = find_channel (serv, chan);
	if (!sess)
		sess = serv->front_session;
   if (!fe_is_banwindow (sess))
		EMIT_SIGNAL (XP_TE_BANLIST, sess, chan, mask, banner, time_str, 0);
	else
		fe_add_ban_list (sess, mask, banner, time_str);
}
Exemplo n.º 19
0
void
lag_check (void)
{
	server *serv;
	GSList *list = serv_list;
	unsigned long tim;
	char tbuf[128];
	time_t now = time (0);
	time_t lag;

	tim = make_ping_time ();

	while (list)
	{
		serv = list->data;
		if (serv->connected && serv->end_of_motd)
		{
			lag = now - serv->ping_recv;
			if (prefs.hex_net_ping_timeout != 0 && lag > prefs.hex_net_ping_timeout && lag > 0)
			{
				sprintf (tbuf, "%" G_GINT64_FORMAT, (gint64) lag);
				EMIT_SIGNAL (XP_TE_PINGTIMEOUT, serv->server_session, tbuf, NULL,
								 NULL, NULL, 0);
				if (prefs.hex_net_auto_reconnect)
					serv->auto_reconnect (serv, FALSE, -1);
			}
			else
			{
				g_snprintf (tbuf, sizeof (tbuf), "LAG%lu", tim);
				serv->p_ping (serv, "", tbuf);
				
				if (!serv->lag_sent)
				{
					serv->lag_sent = tim;
					fe_set_lag (serv, -1);
				}
			}
		}
		list = list->next;
	}
}
Exemplo n.º 20
0
static void
dcc_abort (struct DCC *dcc)
{
	if (dcc)
	{
		switch (dcc->dccstat)
		{
		case STAT_QUEUED:
		case STAT_CONNECTING:
		case STAT_ACTIVE:
			dcc_close (dcc, STAT_ABORTED, FALSE);

			EMIT_SIGNAL (XP_TE_DCCABORT, dcc->serv->front_session,
							 dcctypes[(int) dcc->type], file_part (dcc->file),
							 dcc->nick, NULL, 0);
			break;
		default:
			dcc_close (dcc, 0, TRUE);
		}
	}
}
Exemplo n.º 21
0
void
inbound_away (server * serv, char *nick, char *msg)
{
    struct away_msg *away = server_away_find_message (serv, nick);
    session *sess = NULL;
    GSList *list;

    if (away && !strcmp (msg, away->message))   /* Seen the msg before? */
    {
        if (prefs.show_away_once && !serv->inside_whois)
            return;
    }
    else
    {
        server_away_save_message (serv, nick, msg);
    }

    if (prefs.irc_whois_front)
        sess = serv->front_session;
    else
    {
        if (!serv->inside_whois)
            sess = find_session_from_nick (nick, serv);
        if (!sess)
            sess = serv->server_session;
    }

    /* possibly hide the output */
    if (!serv->inside_whois || !serv->skip_next_whois)
        EMIT_SIGNAL (XP_TE_WHOIS5, sess, nick, msg, NULL, NULL, 0);

    list = sess_list;
    while (list)
    {
        sess = list->data;
        if (sess->server == serv)
            userlist_set_away (sess, nick, TRUE);
        list = list->next;
    }
}
Exemplo n.º 22
0
void
inbound_notice (server *serv, char *to, char *nick, char *msg, char *ip, int id)
{
	char *po,*ptr=to;
	session *sess = 0;
	int server_notice = FALSE;

	if (is_channel (serv, ptr))
		sess = find_channel (serv, ptr);

	if (!sess && ptr[0] == '@')
	{
		ptr++;
		sess = find_channel (serv, ptr);
	}

	if (!sess && ptr[0] == '%')
	{
		ptr++;
		sess = find_channel (serv, ptr);
	}

	if (!sess && ptr[0] == '+')
	{
		ptr++;
		sess = find_channel (serv, ptr);
	}

	if (strcmp (nick, ip) == 0)
		server_notice = TRUE;

	if (!sess)
	{
		ptr = 0;
		if (prefs.hex_gui_tab_notices)
		{
			int stype = server_notice ? SESS_SNOTICES : SESS_NOTICES;
			sess = find_session_from_type (stype, serv);
			if (!sess)
			{
				if (stype == SESS_NOTICES)
					sess = new_ircwindow (serv, "(notices)", SESS_NOTICES, 0);
				else
					sess = new_ircwindow (serv, "(snotices)", SESS_SNOTICES, 0);
				fe_set_channel (sess);
				fe_set_title (sess);
				fe_set_nonchannel (sess, FALSE);
				userlist_clear (sess);
				log_open_or_close (sess);
			}
			/* Avoid redundancy with some Undernet notices */
			if (!strncmp (msg, "*** Notice -- ", 14))
				msg += 14;
		} else
		{
											/* paranoia check */
			if (msg[0] == '[' && (!serv->have_idmsg || id))
			{
				/* guess where chanserv meant to post this -sigh- */
				if (!g_ascii_strcasecmp (nick, "ChanServ") && !find_dialog (serv, nick))
				{
					char *dest = strdup (msg + 1);
					char *end = strchr (dest, ']');
					if (end)
					{
						*end = 0;
						sess = find_channel (serv, dest);
					}
					free (dest);
				}
			}
			if (!sess)
				sess = find_session_from_nick (nick, serv);
		}
		if (!sess)
		{
			if (server_notice)	
				sess = serv->server_session;
			else
				sess = serv->front_session;
		}
	}

	if (msg[0] == 1)
	{
		msg++;
		if (!strncmp (msg, "PING", 4))
		{
			inbound_ping_reply (sess, msg + 5, nick);
			return;
		}
	}
	po = strchr (msg, '\001');
	if (po)
		po[0] = 0;

	if (server_notice)
		EMIT_SIGNAL (XP_TE_SERVNOTICE, sess, msg, nick, NULL, NULL, 0);
	else if (ptr)
		EMIT_SIGNAL (XP_TE_CHANNOTICE, sess, nick, to, msg, NULL, 0);
	else
		EMIT_SIGNAL (XP_TE_NOTICE, sess, nick, msg, NULL, NULL, 0);
}
Exemplo n.º 23
0
void
inbound_notice (server * serv, char *to, char *nick, char *msg, char *ip,
                int id)
{
    char *po, *ptr = to;
    session *sess = 0;
    int server_notice = FALSE;

    if (is_channel (serv, ptr))
        sess = find_channel (serv, ptr);

    if (!sess && ptr[0] == '@')
    {
        ptr++;
        sess = find_channel (serv, ptr);
    }

    if (!sess && ptr[0] == '%')
    {
        ptr++;
        sess = find_channel (serv, ptr);
    }

    if (!sess && ptr[0] == '+')
    {
        ptr++;
        sess = find_channel (serv, ptr);
    }

    if (strcmp (nick, ip) == 0)
        server_notice = TRUE;

    if (!sess)
    {
        ptr = 0;

        /* paranoia check */
        if (msg[0] == '[' && (!serv->have_idmsg || id))
        {
            /* guess where a services bot meant to put this */
            if (!find_dialog (serv, nick))
            {
                char *dest = strdup (msg + 1);
                char *end = strchr (dest, ']');
                if (end)
                {
                    *end = 0;
                    sess = find_channel (serv, dest);
                }
                free (dest);
            }
        }

        if (!sess)
        {
            if (server_notice)
                sess = serv->server_session;
            else
                sess = serv->front_session;
        }
    }

    if (msg[0] == 1)
    {
        msg++;
        if (!strncmp (msg, "PING", 4))
        {
            inbound_ping_reply (sess, msg + 5, nick);
            return;
        }
    }
    po = strchr (msg, '\001');
    if (po)
        po[0] = 0;

    if (server_notice)
        EMIT_SIGNAL (XP_TE_SERVNOTICE, sess, msg, nick, NULL, NULL, 0);
    else if (ptr)
        EMIT_SIGNAL (XP_TE_CHANNOTICE, sess, nick, to, msg, NULL, 0);
    else
        EMIT_SIGNAL (XP_TE_NOTICE, sess, nick, msg, NULL, NULL, 0);
}
Exemplo n.º 24
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);
}
Exemplo n.º 25
0
static void
handle_single_mode (mode_run *mr, char sign, char mode, char *nick,
						  char *chan, char *arg, int quiet, int is_324)
{
	session *sess;
	server *serv = mr->serv;
	char outbuf[4];
	char *cm = serv->chanmodes;
	gboolean supportsq = FALSE;

	outbuf[0] = sign;
	outbuf[1] = 0;
	outbuf[2] = mode;
	outbuf[3] = 0;

	sess = find_channel (serv, chan);
	if (!sess || !is_channel (serv, chan))
	{
		/* got modes for a chan we're not in! probably nickmode +isw etc */
		sess = serv->front_session;
		goto genmode;
	}

	/* is this a nick mode? */
	if (strchr (serv->nick_modes, mode))
	{
		/* update the user in the userlist */
		userlist_update_mode (sess, /*nickname */ arg, mode, sign);
	} else
	{
		if (!is_324 && !sess->ignore_mode && mode_chanmode_type(serv, mode) >= 1)
			record_chan_mode (sess, sign, mode, arg);
	}

	/* Is q a chanmode on this server? */
	if (cm)
		while (*cm)
		{
			if (*cm == ',')
				break;
			if (*cm == 'q')
				supportsq = TRUE;
			cm++;
		}

	switch (sign)
	{
	case '+':
		switch (mode)
		{
		case 'k':
			safe_strcpy (sess->channelkey, arg, sizeof (sess->channelkey));
			fe_update_channel_key (sess);
			fe_update_mode_buttons (sess, mode, sign);
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANSETKEY, sess, nick, arg, NULL, NULL, 0);
			return;
		case 'l':
			sess->limit = atoi (arg);
			fe_update_channel_limit (sess);
			fe_update_mode_buttons (sess, mode, sign);
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANSETLIMIT, sess, nick, arg, NULL, NULL, 0);
			return;
		case 'o':
			if (!quiet)
				mr->op = mode_cat (mr->op, arg);
			return;
		case 'h':
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANHOP, sess, nick, arg, NULL, NULL, 0);
			return;
		case 'v':
			if (!quiet)
				mr->voice = mode_cat (mr->voice, arg);
			return;
		case 'b':
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANBAN, sess, nick, arg, NULL, NULL, 0);
			return;
		case 'e':
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANEXEMPT, sess, nick, arg, NULL, NULL, 0);
			return;
		case 'I':
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANINVITE, sess, nick, arg, NULL, NULL, 0);
			return;
		case 'q':
			if (!supportsq)
				break; /* +q is owner on this server */
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANQUIET, sess, nick, arg, NULL, NULL, 0);
			return;
		}
		break;
	case '-':
		switch (mode)
		{
		case 'k':
			sess->channelkey[0] = 0;
			fe_update_channel_key (sess);
			fe_update_mode_buttons (sess, mode, sign);
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANRMKEY, sess, nick, NULL, NULL, NULL, 0);
			return;
		case 'l':
			sess->limit = 0;
			fe_update_channel_limit (sess);
			fe_update_mode_buttons (sess, mode, sign);
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANRMLIMIT, sess, nick, NULL, NULL, NULL, 0);
			return;
		case 'o':
			if (!quiet)
				mr->deop = mode_cat (mr->deop, arg);
			return;
		case 'h':
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANDEHOP, sess, nick, arg, NULL, NULL, 0);
			return;
		case 'v':
			if (!quiet)
				mr->devoice = mode_cat (mr->devoice, arg);
			return;
		case 'b':
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANUNBAN, sess, nick, arg, NULL, NULL, 0);
			return;
		case 'e':
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANRMEXEMPT, sess, nick, arg, NULL, NULL, 0);
			return;
		case 'I':
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANRMINVITE, sess, nick, arg, NULL, NULL, 0);
			return;
		case 'q':
			if (!supportsq)
				break; /* -q is owner on this server */
			if (!quiet)
				EMIT_SIGNAL (XP_TE_CHANUNQUIET, sess, nick, arg, NULL, NULL, 0);
			return;
		}
	}

	fe_update_mode_buttons (sess, mode, sign);

 genmode:
	/* Received umode +e. If we're waiting to send JOIN then send now! */
	if (mode == 'e' && sign == '+' && !serv->p_cmp (chan, serv->nick))
		inbound_identified (serv);

	if (!quiet)
	{
		if (*arg)
		{
			char *buf = malloc (strlen (chan) + strlen (arg) + 2);
			sprintf (buf, "%s %s", chan, arg);
			EMIT_SIGNAL (XP_TE_CHANMODEGEN, sess, nick, outbuf, outbuf + 2, buf, 0);
			free (buf);
		} else
			EMIT_SIGNAL (XP_TE_CHANMODEGEN, sess, nick, outbuf, outbuf + 2, chan, 0);
	}
}
Exemplo n.º 26
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]);
}
Exemplo n.º 27
0
static void
process_numeric (session * sess, int n,
					  char *word[], char *word_eol[], char *text)
{
	server *serv = sess->server;
	/* show whois is the server tab */
	session *whois_sess = serv->server_session;

	/* unless this setting is on */
	if (prefs.irc_whois_front)
		whois_sess = serv->front_session;

	switch (n)
	{
	case 1:
		inbound_login_start (sess, word[3], word[1]);
		/* if network is PTnet then you must get your IP address
			from "001" server message */
		if ((strncmp(word[7], "PTnet", 5) == 0) &&
			(strncmp(word[8], "IRC", 3) == 0) &&
			(strncmp(word[9], "Network", 7) == 0) &&
			(strrchr(word[10], '@') != NULL))
		{
			serv->use_who = FALSE;
			if (prefs.ip_from_server)
				inbound_foundip (sess, strrchr(word[10], '@')+1);
		}

		/* use /NICKSERV */
		if (strcasecmp (word[7], "DALnet") == 0 ||
			 strcasecmp (word[7], "BRASnet") == 0)
			serv->nickservtype = 1;

		/* use /NS */
		else if (strcasecmp (word[7], "FreeNode") == 0)
			serv->nickservtype = 2;

		goto def;

	case 4:	/* check the ircd type */
		serv->use_listargs = FALSE;
		serv->modes_per_line = 3;		/* default to IRC RFC */
		if (strncmp (word[5], "bahamut", 7) == 0)				/* DALNet */
		{
			serv->use_listargs = TRUE;		/* use the /list args */
		} else if (strncmp (word[5], "u2.10.", 6) == 0)		/* Undernet */
		{
			serv->use_listargs = TRUE;		/* use the /list args */
			serv->modes_per_line = 6;		/* allow 6 modes per line */
		} else if (strncmp (word[5], "glx2", 4) == 0)
		{
			serv->use_listargs = TRUE;		/* use the /list args */
		}
		goto def;

	case 5:
		inbound_005 (serv, word);
		goto def;

	case 263:	/*Server load is temporarily too heavy */
		if (fe_is_chanwindow (sess->server))
		{
			fe_chan_list_end (sess->server);
			fe_message (word_eol[5] + 1, FE_MSG_ERROR);
		}
		goto def;

	case 290:	/* CAPAB reply */
		if (strstr (word_eol[1], "IDENTIFY-MSG"))
		{
			serv->have_idmsg = TRUE;
			break;
		}
		goto def;

	case 301:
		inbound_away (serv, word[4],
						(word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5]);
		break;

	case 302:
		if (serv->skip_next_userhost)
		{
			char *eq = strchr (word[4], '=');
			if (eq)
			{
				*eq = 0;
				if (!serv->p_cmp (word[4] + 1, serv->nick))
				{
					char *at = strrchr (eq + 1, '@');
					if (at)
						inbound_foundip (sess, at + 1);
				}
			}

			serv->skip_next_userhost = FALSE;
			break;
		}
		else goto def;

	case 303:
		word[4]++;
		notify_markonline (serv, word);
		break;

	case 305:
		inbound_uback (serv);
		goto def;

	case 306:
		inbound_uaway (serv);
		goto def;

	case 312:
		if (!serv->skip_next_whois)
			EMIT_SIGNAL (XP_TE_WHOIS3, whois_sess, word[4], word_eol[5], NULL, NULL, 0);
		else
			inbound_user_info (sess, NULL, NULL, NULL, word[5], word[4], NULL, 0xff);
		break;

	case 311:	/* WHOIS 1st line */
		serv->inside_whois = 1;
		inbound_user_info_start (sess, word[4]);
		if (!serv->skip_next_whois)
			EMIT_SIGNAL (XP_TE_WHOIS1, whois_sess, word[4], word[5],
							 word[6], word_eol[8] + 1, 0);
		else
			inbound_user_info (sess, NULL, word[5], word[6], NULL, word[4],
									 word_eol[8][0] == ':' ? word_eol[8] + 1 : word_eol[8], 0xff);
		break;

	case 314:	/* WHOWAS */
		inbound_user_info_start (sess, word[4]);
		EMIT_SIGNAL (XP_TE_WHOIS1, whois_sess, word[4], word[5],
						 word[6], word_eol[8] + 1, 0);
		break;

	case 317:
		if (!serv->skip_next_whois)
		{
			time_t timestamp = (time_t) atol (word[6]);
			long idle = atol (word[5]);
			char *tim;
			char outbuf[64];

			snprintf (outbuf, sizeof (outbuf),
						"%02ld:%02ld:%02ld", idle / 3600, (idle / 60) % 60,
						idle % 60);
			if (timestamp == 0)
				EMIT_SIGNAL (XP_TE_WHOIS4, whois_sess, word[4],
								 outbuf, NULL, NULL, 0);
			else
			{
				tim = ctime (&timestamp);
				tim[19] = 0; 	/* get rid of the \n */
				EMIT_SIGNAL (XP_TE_WHOIS4T, whois_sess, word[4],
								 outbuf, tim, NULL, 0);
			}
		}
		break;

	case 318:	/* END OF WHOIS */
		if (!serv->skip_next_whois)
			EMIT_SIGNAL (XP_TE_WHOIS6, whois_sess, word[4], NULL,
							 NULL, NULL, 0);
		serv->skip_next_whois = 0;
		serv->inside_whois = 0;
		break;

	case 313:
	case 319:
		if (!serv->skip_next_whois)
			EMIT_SIGNAL (XP_TE_WHOIS2, whois_sess, word[4],
							 word_eol[5] + 1, NULL, NULL, 0);
		break;

	case 307:	/* dalnet version */
	case 320:	/* :is an identified user */
		if (!serv->skip_next_whois)
			EMIT_SIGNAL (XP_TE_WHOIS_ID, whois_sess, word[4],
							 word_eol[5] + 1, NULL, NULL, 0);
		break;

	case 321:
		if (!fe_is_chanwindow (sess->server))
			EMIT_SIGNAL (XP_TE_CHANLISTHEAD, serv->server_session, NULL, NULL, NULL, NULL, 0);
		break;

	case 322:
		if (fe_is_chanwindow (sess->server))
		{
			fe_add_chan_list (sess->server, word[4], word[5], word_eol[6] + 1);
		} else
		{
			PrintTextf (serv->server_session, "%-16s %-7d %s\017\n",
							word[4], atoi (word[5]), word_eol[6] + 1);
		}
		break;

	case 323:
		if (!fe_is_chanwindow (sess->server))
			EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, word[1], word[2], NULL, 0);
		else
			fe_chan_list_end (sess->server);
		break;

	case 324:
		sess = find_channel (serv, word[4]);
		if (!sess)
			sess = serv->server_session;
		if (sess->ignore_mode)
			sess->ignore_mode = FALSE;
		else
			EMIT_SIGNAL (XP_TE_CHANMODES, sess, word[4], word_eol[5],
							 NULL, NULL, 0);
		fe_update_mode_buttons (sess, 't', '-');
		fe_update_mode_buttons (sess, 'n', '-');
		fe_update_mode_buttons (sess, 's', '-');
		fe_update_mode_buttons (sess, 'i', '-');
		fe_update_mode_buttons (sess, 'p', '-');
		fe_update_mode_buttons (sess, 'm', '-');
		fe_update_mode_buttons (sess, 'l', '-');
		fe_update_mode_buttons (sess, 'k', '-');
		handle_mode (serv, word, word_eol, "", TRUE);
		break;

	case 329:
		sess = find_channel (serv, word[4]);
		if (sess)
		{
			if (sess->ignore_date)
				sess->ignore_date = FALSE;
			else
				channel_date (sess, word[4], word[5]);
		}
		break;

	case 330:
		if (!serv->skip_next_whois)
			EMIT_SIGNAL (XP_TE_WHOIS_AUTH, whois_sess, word[4],
							 word_eol[6] + 1, word[5], NULL, 0);
		break;

	case 332:
		inbound_topic (serv, word[4],
						(word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5]);
		break;

	case 333:
		inbound_topictime (serv, word[4], word[5], atol (word[6]));
		break;

#if 0
	case 338:  /* Undernet Real user@host, Real IP */
		EMIT_SIGNAL (XP_TE_WHOIS_REALHOST, sess, word[4], word[5], word[6], 
			(word_eol[7][0]==':') ? word_eol[7]+1 : word_eol[7], 0);
		break;
#endif

	case 341:						  /* INVITE ACK */
		EMIT_SIGNAL (XP_TE_UINVITE, sess, word[4], word[5], serv->servername,
						 NULL, 0);
		break;

	case 352:						  /* WHO */
		{
			unsigned int away = 0;
			session *who_sess = find_channel (serv, word[4]);

			if (*word[9] == 'G')
				away = 1;

			inbound_user_info (sess, word[4], word[5], word[6], word[7],
									 word[8], word_eol[11], away);

			/* try to show only user initiated whos */
			if (!who_sess || !who_sess->doing_who)
				EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, word[1],
								 word[2], NULL, 0);
		}
		break;

	case 354:	/* undernet WHOX: used as a reply for irc_away_status */
		{
			unsigned int away = 0;
			session *who_sess;

			/* irc_away_status sends out a "152" */
			if (!strcmp (word[4], "152"))
			{
				who_sess = find_channel (serv, word[5]);

				if (*word[7] == 'G')
					away = 1;

				/* :SanJose.CA.us.undernet.org 354 z1 152 #zed1 z1 H@ */
				inbound_user_info (sess, word[5], 0, 0, 0, word[6], 0, away);

				/* try to show only user initiated whos */
				if (!who_sess || !who_sess->doing_who)
					EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text,
									 word[1], word[2], NULL, 0);
			} else
				goto def;
		}
		break;

	case 315:						  /* END OF WHO */
		{
			session *who_sess;
			who_sess = find_channel (serv, word[4]);
			if (who_sess)
			{
				if (!who_sess->doing_who)
					EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text,
									 word[1], word[2], NULL, 0);
				who_sess->doing_who = FALSE;
			} else
			{
				if (!serv->doing_dns)
					EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text,
									 word[1], word[2], NULL, 0);
				serv->doing_dns = FALSE;
			}
		}
		break;

	case 348:	/* +e-list entry */
		if (!inbound_banlist (sess, atol (word[7]), word[4], word[5], word[6], TRUE))
			goto def;
		break;

	case 349:	/* end of exemption list */
		sess = find_channel (serv, word[4]);
		if (!sess)
		{
			sess = serv->front_session;
			goto def;
		}
		if (!fe_is_banwindow (sess))
			goto def;
		fe_ban_list_end (sess, TRUE);
		break;

	case 353:						  /* NAMES */
		inbound_nameslist (serv, word[5],
							(word_eol[6][0] == ':') ? word_eol[6] + 1 : word_eol[6]);
		break;

	case 366:
		if (!inbound_nameslist_end (serv, word[4]))
			goto def;
		break;

	case 367: /* banlist entry */
		inbound_banlist (sess, atol (word[7]), word[4], word[5], word[6], FALSE);
		break;

	case 368:
		sess = find_channel (serv, word[4]);
		if (!sess)
		{
			sess = serv->front_session;
			goto def;
		}
		if (!fe_is_banwindow (sess))
			goto def;
		fe_ban_list_end (sess, FALSE);
		break;

	case 369:	/* WHOWAS end */
	case 406:	/* WHOWAS error */
		EMIT_SIGNAL (XP_TE_SERVTEXT, whois_sess, text, word[1], word[2], NULL, 0);
		serv->inside_whois = 0;
		break;

	case 372:	/* motd text */
	case 375:	/* motd start */
		if (!prefs.skipmotd || serv->motd_skipped)
			EMIT_SIGNAL (XP_TE_MOTD, serv->server_session, text, NULL, NULL,
							 NULL, 0);
		break;

	case 376:	/* end of motd */
	case 422:	/* motd file is missing */
		inbound_login_end (sess, text);
		break;

	case 433:	/* nickname in use */
	case 432:	/* erroneous nickname */
		if (serv->end_of_motd)
			goto def;
		inbound_next_nick (sess,  word[4]);
		break;

	case 437:
		if (serv->end_of_motd || is_channel (serv, word[4]))
			goto def;
		inbound_next_nick (sess, word[4]);
		break;

	case 471:
		EMIT_SIGNAL (XP_TE_USERLIMIT, sess, word[4], NULL, NULL, NULL, 0);
		break;

	case 473:
		EMIT_SIGNAL (XP_TE_INVITE, sess, word[4], NULL, NULL, NULL, 0);
		break;

	case 474:
		EMIT_SIGNAL (XP_TE_BANNED, sess, word[4], NULL, NULL, NULL, 0);
		break;

	case 475:
		EMIT_SIGNAL (XP_TE_KEYWORD, sess, word[4], NULL, NULL, NULL, 0);
		break;

	case 601:
		notify_set_offline (serv, word[4], FALSE);
		break;

	case 605:
		notify_set_offline (serv, word[4], TRUE);
		break;

	case 600:
	case 604:
		notify_set_online (serv, word[4]);
		break;

	default:

		if (serv->inside_whois && word[4][0])
		{
			/* some unknown WHOIS reply, ircd coders make them up weekly */
			if (!serv->skip_next_whois)
				EMIT_SIGNAL (XP_TE_WHOIS_SPECIAL, whois_sess, word[4],
								(word_eol[5][0] == ':') ? word_eol[5] + 1 : word_eol[5],
								 word[2], NULL, 0);
			return;
		}

	def:
		if (is_channel (serv, word[4]))
		{
			session *realsess = find_channel (serv, word[4]);
			if (!realsess)
				realsess = serv->server_session;
			EMIT_SIGNAL (XP_TE_SERVTEXT, realsess, text, word[1], word[2], NULL, 0);
		} else
		{
			EMIT_SIGNAL (XP_TE_SERVTEXT, serv->server_session, text, word[1],
							 word[2], NULL, 0);
		}
	}
}
Exemplo n.º 28
0
void
handle_ctcp (struct session *sess, char *outbuf, char *to, char *nick,
				 char *msg, char *word[], char *word_eol[])
{
	char *po;
	session *chansess;

	if (!strncasecmp (msg, "VERSION", 7) && !prefs.hidever)
	{
		sprintf (outbuf, "NOTICE %s :\001VERSION xchat "VERSION" %s (PicoGUI)\001\r\n",
					nick, get_cpu_str ());
		tcp_send (sess->server, outbuf);
	}

	if (!ctcp_check (sess, outbuf, nick, word, word_eol, word[4] + 2))
	{
		if (!strncasecmp (msg, "ACTION", 6))
		{
			po = strchr (msg + 7, '\001');
			if (po)
				po[0] = 0;
			channel_action (sess, outbuf, to, nick, msg + 7, FALSE);
			return;
		}
		if (!strncasecmp (msg, "DCC", 3))
		{
			handle_dcc (sess, outbuf, nick, word, word_eol);
			return;
		}
		if (!strncasecmp (msg, "SOUND", 5))
		{
			po = strchr (word[5], '\001');
			if (po)
				po[0] = 0;
			EMIT_SIGNAL (XP_TE_CTCPSND, sess->server->front_session, word[5],
							 nick, NULL, NULL, 0);
			sprintf (outbuf, "%s/%s", prefs.sounddir, word[5]);
			if (strchr (word[5], '/') == 0 && access (outbuf, R_OK) == 0)
			{
				sprintf (outbuf, "%s %s/%s", prefs.soundcmd, prefs.sounddir,
							word[5]);
				xchat_exec (outbuf);
			}
			return;
		}
	}

	po = strchr (msg, '\001');
	if (po)
		po[0] = 0;
	if (!is_channel (sess->server, to))
	{
		EMIT_SIGNAL (XP_TE_CTCPGEN, sess->server->front_session, msg, nick,
						 NULL, NULL, 0);
	} else
	{
		chansess = find_session_from_channel (to, sess->server);
		if (chansess)
		{
			EMIT_SIGNAL (XP_TE_CTCPGENC, chansess, msg, nick, to, NULL, 0);
			return;
		}
		EMIT_SIGNAL (XP_TE_CTCPGENC, sess->server->front_session, msg, nick, to,
						 NULL, 0);
	}
}
Exemplo n.º 29
0
void
handle_mode (server * serv, char *word[], char *word_eol[],
				 char *nick, int numeric_324)
{
	session *sess;
	char *chan;
	char *modes;
	char *argstr;
	char sign;
	int len;
	int arg;
	int i, num_args;
	int num_modes;
	int offset = 3;
	int all_modes_have_args = FALSE;
	int using_front_tab = FALSE;
	mode_run mr;

	mr.serv = serv;
	mr.op = mr.deop = mr.voice = mr.devoice = NULL;

	/* numeric 324 has everything 1 word later (as opposed to MODE) */
	if (numeric_324)
		offset++;

	chan = word[offset];
	modes = word[offset + 1];
	if (*modes == ':')
		modes++;

	if (*modes == 0)
		return;	/* beyondirc's blank modes */

	sess = find_channel (serv, chan);
	if (!sess)
	{
		sess = serv->front_session;
		using_front_tab = TRUE;
	}
	/* remove trailing space */
	len = strlen (word_eol[offset]) - 1;
	if (word_eol[offset][len] == ' ')
		word_eol[offset][len] = 0;

	if (prefs.hex_irc_raw_modes && !numeric_324)
		EMIT_SIGNAL (XP_TE_RAWMODES, sess, nick, word_eol[offset], 0, 0, 0);

	if (numeric_324 && !using_front_tab)
	{
		if (sess->current_modes)
			free (sess->current_modes);
		sess->current_modes = strdup (word_eol[offset+1]);
	}

	sign = *modes;
	modes++;
	arg = 1;

	/* count the number of arguments (e.g. after the -o+v) */
	num_args = 0;
	i = 1;
	while ((i + offset + 1) < PDIWORDS)
	{
		i++;
		if (!(*word[i + offset]))
			break;
		num_args++;
	}

	/* count the number of modes (without the -/+ chars */
	num_modes = 0;
	i = 0;
	while (i < strlen (modes))
	{
		if (modes[i] != '+' && modes[i] != '-')
			num_modes++;
		i++;
	}

	if (num_args == num_modes)
		all_modes_have_args = TRUE;

	while (*modes)
	{
		switch (*modes)
		{
		case '-':
		case '+':
			/* print all the grouped Op/Deops */
			mode_print_grouped (sess, nick, &mr);
			sign = *modes;
			break;
		default:
			argstr = "";
			if ((all_modes_have_args || mode_has_arg (serv, sign, *modes)) && arg < (num_args+1))
			{
				arg++;
				argstr = word[arg + offset];
			}
			handle_single_mode (&mr, sign, *modes, nick, chan,
									  argstr, numeric_324 || prefs.hex_irc_raw_modes,
									  numeric_324);
		}

		modes++;
	}

	/* update the title at the end, now that the mode update is internal now */
	if (!using_front_tab)
		fe_set_title (sess);

	/* print all the grouped Op/Deops */
	mode_print_grouped (sess, nick, &mr);
}
Exemplo n.º 30
0
void
ctcp_handle (session *sess, char *to, char *nick,
				 char *msg, char *word[], char *word_eol[], int id)
{
	char *po;
	session *chansess;
	server *serv = sess->server;
	char outbuf[1024];

	/* consider DCC to be different from other CTCPs */
	if (!strncasecmp (msg, "DCC", 3))
	{
		/* but still let CTCP replies override it */
		if (!ctcp_check (sess, nick, word, word_eol, word[4] + 2))
		{
			if (!ignore_check (word[1], IG_DCC))
				handle_dcc (sess, nick, word, word_eol);
		}
		return;
	}

	/* consider ACTION to be different from other CTCPs. Check
      ignore as if it was a PRIV/CHAN. */
	if (!strncasecmp (msg, "ACTION ", 7))
	{
		if (is_channel (serv, to))
		{
			/* treat a channel action as a CHAN */
			if (ignore_check (word[1], IG_CHAN))
				return;
		} else
		{
			/* treat a private action as a PRIV */
			if (ignore_check (word[1], IG_PRIV))
				return;
		}

		/* but still let CTCP replies override it */
		if (ctcp_check (sess, nick, word, word_eol, word[4] + 2))
			goto generic;

		inbound_action (sess, to, nick, msg + 7, FALSE, id);
		return;
	}

	if (ignore_check (word[1], IG_CTCP))
		return;

	if (!strcasecmp (msg, "VERSION") && !prefs.hidever)
	{
#ifdef FE_AQUA
		snprintf (outbuf, sizeof (outbuf), "VERSION X-Chat Aqua %s (xchat "PACKAGE_VERSION") %s",
                  prefs.xchat_aqua_version, get_cpu_str ());
#else
		snprintf (outbuf, sizeof (outbuf), "VERSION xchat "PACKAGE_VERSION" %s",
					 get_cpu_str ());
#endif
		serv->p_nctcp (serv, nick, outbuf);
	}

	if (!ctcp_check (sess, nick, word, word_eol, word[4] + 2))
	{
		if (!strncasecmp (msg, "SOUND", 5))
		{
			po = strchr (word[5], '\001');
			if (po)
				po[0] = 0;

			if (is_channel (sess->server, to))
			{
				chansess = find_channel (sess->server, to);
				if (!chansess)
					chansess = sess;

				EMIT_SIGNAL (XP_TE_CTCPSNDC, chansess, word[5],
								 nick, to, NULL, 0);
			} else
			{
				EMIT_SIGNAL (XP_TE_CTCPSND, sess->server->front_session, word[5],
								 nick, NULL, NULL, 0);
			}

			/* don't let IRCers specify path */
#ifdef WIN32
			if (strchr (word[5], '/') == NULL && strchr (word[5], '\\') == NULL)
#else
			if (strchr (word[5], '/') == NULL)
#endif
				sound_play (word[5], TRUE);
			return;
		}
	}

generic:
	po = strchr (msg, '\001');
	if (po)
		po[0] = 0;

	if (!is_channel (sess->server, to))
	{
		EMIT_SIGNAL (XP_TE_CTCPGEN, sess->server->front_session, msg, nick,
						 NULL, NULL, 0);
	} else
	{
		chansess = find_channel (sess->server, to);
		if (!chansess)
			chansess = sess;
		EMIT_SIGNAL (XP_TE_CTCPGENC, chansess, msg, nick, to, NULL, 0);
	}
}