Пример #1
0
static void
log_write (session *sess, char *text, time_t ts)
{
	char *temp;
	char *stamp;
	char *file;
	int len;

	if (sess->text_logging == SET_DEFAULT)
	{
		if (!prefs.hex_irc_logging)
			return;
	}
	else
	{
		if (sess->text_logging != SET_ON)
			return;
	}

	if (sess->logfd == -1)
		log_open (sess);

	/* change to a different log file? */
	file = log_create_pathname (sess->server->servername, sess->channel,
										 server_get_network (sess->server, FALSE));
	if (file)
	{
		if (g_access (file, F_OK) != 0)
		{
			close (sess->logfd);
			sess->logfd = log_open_file (sess->server->servername, sess->channel,
												  server_get_network (sess->server, FALSE));
		}
		g_free (file);
	}

	if (prefs.hex_stamp_log)
	{
		if (!ts) ts = time(0);
		len = get_stamp_str (prefs.hex_stamp_log_format, ts, &stamp);
		if (len)
		{
			write (sess->logfd, stamp, len);
			g_free (stamp);
		}
	}
	temp = strip_color (text, -1, STRIP_ALL);
	len = strlen (temp);
	write (sess->logfd, temp, len);
	/* lots of scripts/plugins print without a \n at the end */
	if (temp[len - 1] != '\n')
		write (sess->logfd, "\n", 1);	/* emulate what xtext would display */
	g_free (temp);
}
Пример #2
0
void
chanopt_save (session *sess)
{
	int i;
	guint8 vals;
	guint8 valm;
	chanopt_in_memory *co;
	char *network;

	if (sess->channel[0] == 0)
		return;

	network = server_get_network (sess->server, FALSE);
	if (!network)
		return;

	/* 2. reconcile sess with what we loaded from disk */

	co = chanopt_find (network, sess->channel, TRUE);

	i = 0;
	while (i < sizeof (chanopt) / sizeof (channel_options))
	{
		vals = G_STRUCT_MEMBER(guint8, sess, chanopt[i].offset);
		valm = G_STRUCT_MEMBER(guint8, co, chanopt[i].offset);

		if (vals != valm)
		{
			*(guint8 *)G_STRUCT_MEMBER_P(co, chanopt[i].offset) = vals;
			chanopt_changed = TRUE;
		}

		i++;
	}
}
Пример #3
0
void
chanopt_load (session *sess)
{
	int i;
	guint8 val;
	chanopt_in_memory *co;
	char *network;

	if (sess->channel[0] == 0)
		return;

	network = server_get_network (sess->server, FALSE);
	if (!network)
		return;

	if (!chanopt_open)
	{
		chanopt_open = TRUE;
		chanopt_load_all ();
	}

	co = chanopt_find (network, sess->channel, FALSE);
	if (!co)
		return;

	/* fill in all the sess->xxxxx fields */
	i = 0;
	while (i < sizeof (chanopt) / sizeof (channel_options))
	{
		val = G_STRUCT_MEMBER(guint8, co, chanopt[i].offset);
		*(guint8 *)G_STRUCT_MEMBER_P(sess, chanopt[i].offset) = val;
		i++;
	}
}
Пример #4
0
static char *
scrollback_get_filename (session *sess)
{
	char *net, *chan, *buf, *ret = NULL;

	net = server_get_network (sess->server, FALSE);
	if (!net)
		return NULL;

	net = log_create_filename (net);
	buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "scrollback" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S "%s.txt", get_xdir (), net, "");
	mkdir_p (buf);
	g_free (buf);

	chan = log_create_filename (sess->channel);
	if (chan[0])
		buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "scrollback" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S "%s.txt", get_xdir (), net, chan);
	else
		buf = NULL;
	g_free (chan);
	g_free (net);

	if (buf)
	{
		ret = g_filename_from_utf8 (buf, -1, NULL, NULL, NULL);
		g_free (buf);
	}

	return ret;
}
Пример #5
0
static void
notify_announce_online (server * serv, struct notify_per_server *servnot,
								char *nick)
{
	session *sess;

	sess = serv->front_session;

	servnot->lastseen = time (0);
	if (servnot->ison)
		return;

	servnot->ison = TRUE;
	servnot->laston = time (0);
	EMIT_SIGNAL (XP_TE_NOTIFYONLINE, sess, nick, serv->servername,
					 server_get_network (serv, TRUE), NULL, 0);
	fe_notify_update (nick);
	fe_notify_update (0);

	if (prefs.whois_on_notifyonline)
	{

	    /* Let's do whois with idle time (like in /quote WHOIS %s %s) */

	    char *wii_str = malloc (strlen (nick) * 2 + 2);
	    sprintf (wii_str, "%s %s", nick, nick);
	    serv->p_whois (serv, wii_str);
	    free (wii_str);
	}
}
Пример #6
0
static void
process_private(gpointer *params)
{
	session *sess  = params[0];
	gchar *from    = params[1];
	gchar *message = params[2];

	const char *network = server_get_network(sess->server, FALSE);
	if (!network)
		network = sess->server->connected ? sess->server->servername : NULL;

	if (FromNick(from, prefs.irc_no_hilight))
		return;

	if (prefs.input_tray_priv)
	{
		tray_set_flash(ICON_HILIGHT);

		tray_priv_count++;
		if (tray_priv_count == 1)
			tray_set_tipf(_("GChat: Private message from: %s (%s)"),
								from, network);
		else
			tray_set_tipf(_("GChat: %u private messages, latest from: %s (%s)"),
								tray_priv_count, from, network);
	}

	if (prefs.input_balloon_priv)
		tray_set_balloonf(message, _("GChat: Private message from: %s (%s)"),
								 from, network);
}
Пример #7
0
static void
process_invited(gpointer *params)
{
	gchar **word  = params[1];
	gchar *from   = params[2];
	server *serv  = params[3];

	gchar *channel = word[4][0] == ':' ? word[4] + 1 : word[4];

	const char *network = server_get_network(serv, FALSE);
	if (!network)
		network = serv->connected ? serv->servername : NULL;

	if (FromNick(from, prefs.irc_no_hilight))
		return;

	if (prefs.input_tray_priv)
	{
		tray_set_flash(ICON_HILIGHT);

		tray_invite_count++;
		if (tray_invite_count == 1)
			tray_set_tipf(_("GChat: Invite from: %s (%s) to %s"),
								from, network, channel);
		else
			tray_set_tipf(_("GChat: %u private messages, latest from: %s (%s) to %s"),
								tray_priv_count, from, network, channel);
	}

	if (prefs.input_balloon_priv)
		tray_set_balloonf("", _("GChat: Invite from: %s (%s) to %s"),
								 from, network, channel);
}
Пример #8
0
void
nick_command_parse (session *sess, char *cmd, char *nick, char *allnick)
{
	char *buf;
	char *host = _("Host unknown");
	struct User *user;
	int len;

/*	if (sess->type == SESS_DIALOG)
	{
		buf = (char *)(GTK_ENTRY (sess->gui->topic_entry)->text);
		buf = strrchr (buf, '@');
		if (buf)
			host = buf + 1;
	} else*/
	{
		user = userlist_find (sess, nick);
		if (user && user->hostname)
			host = strchr (user->hostname, '@') + 1;
	}

	/* this can't overflow, since popup->cmd is only 256 */
	len = strlen (cmd) + strlen (nick) + strlen (allnick) + 512;
	buf = malloc (len);

	auto_insert (buf, len, cmd, 0, 0, allnick, sess->channel, "",
					 server_get_network (sess->server, TRUE), host,
					 sess->server->nick, nick);

	nick_command (sess, buf);

	free (buf);
}
Пример #9
0
static void
process_dcc(gpointer *params)
{
	session *sess = params[0];
	gchar *nick   = params[1];

	const char *network = server_get_network(sess->server, FALSE);
	if (!network)
		network = sess->server->connected ? sess->server->servername : NULL;

	if (prefs.input_tray_priv)
	{
		tray_set_flash(ICON_FILE);

		tray_dcc_count++;
		if (tray_dcc_count == 1)
			tray_set_tipf(_("GChat: DCC offer from: %s (%s)"),
								nick, network ? network : "unknown network");
		else
			tray_set_tipf(_("GChat: %u DCC offers, latest from: %s (%s)"),
								tray_dcc_count, nick, network ? network : "unknown network");
	}

	if (prefs.input_balloon_priv)
		tray_set_balloonf("", _("GChat: DCC offer from: %s (%s)"),
								nick, network ? network : "unknown network");
}
Пример #10
0
xchat_context* xchat_find_context(xchat_plugin *ph, const char *servname, const char *channel)
{
	GSList *slist, *clist, *sessions = nullptr;
	server *serv;
	session *sess;
	char *netname;

	if (servname == nullptr && channel == nullptr)
		return current_sess;

	slist = serv_list;
	while (slist)
	{
		serv = (server*)slist->data;
		netname = server_get_network(serv, TRUE);

		if (servname == nullptr ||
			 rfc_casecmp(servname, serv->servername) == 0 ||
			 strcasecmp(servname, serv->hostname) == 0 ||
			 strcasecmp(servname, netname) == 0)
		{
			if (channel == nullptr)
				return serv->front_session;

			clist = sess_list;
			while (clist)
			{
				sess = (session*)clist->data;
				if (sess->server == serv)
				{
					if (rfc_casecmp(channel, sess->channel) == 0)
					{
						if (sess->server == ph->context->server)
						{
							g_slist_free(sessions);
							return sess;
						}
						else
						{
							sessions = g_slist_prepend(sessions, sess);
						}
					}
				}
				clist = clist->next;
			}
		}
		slist = slist->next;
	}

	if (sessions)
	{
		sessions = g_slist_reverse(sessions);
		sess = (session*)sessions->data;
		g_slist_free(sessions);
		return sess;
	}

	return nullptr;
}
Пример #11
0
session *
plugin_find_context (const char *servname, const char *channel, server *current_server)
{
	GSList *slist, *clist, *sessions = NULL;
	server *serv;
	session *sess;
	char *netname;

	if (servname == NULL && channel == NULL)
		return current_sess;

	slist = serv_list;
	while (slist)
	{
		serv = slist->data;
		netname = server_get_network (serv, TRUE);

		if (servname == NULL ||
			 rfc_casecmp (servname, serv->servername) == 0 ||
			 g_ascii_strcasecmp (servname, serv->hostname) == 0 ||
			 g_ascii_strcasecmp (servname, netname) == 0)
		{
			if (channel == NULL)
				return serv->front_session;

			clist = sess_list;
			while (clist)
			{
				sess = clist->data;
				if (sess->server == serv)
				{
					if (rfc_casecmp (channel, sess->channel) == 0)
					{
						if (sess->server == current_server)
						{
							g_slist_free (sessions);
							return sess;
						} else
						{
							sessions = g_slist_prepend (sessions, sess);
						}
					}
				}
				clist = clist->next;
			}
		}
		slist = slist->next;
	}

	if (sessions)
	{
		sessions = g_slist_reverse (sessions);
		sess = sessions->data;
		g_slist_free (sessions);
		return sess;
	}

	return NULL;
}
Пример #12
0
static void
log_open (session *sess)
{
	static gboolean log_error = FALSE;

	log_close (sess);
	sess->logfd = log_open_file (sess->server->servername, sess->channel,
										  server_get_network (sess->server, FALSE));

	if (!log_error && sess->logfd == -1)
	{
		char message[512];

		snprintf (message, sizeof (message), _("* Can't open log file(s) for writing. Check the\npermissions on %s"),
			log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE)));

		fe_message (message, FE_MSG_WAIT | FE_MSG_ERROR);
		log_error = TRUE;
	}
}
Пример #13
0
static void
log_open (session *sess)
{
	static gboolean log_error = FALSE;

	log_close (sess);
	sess->logfd = log_open_file (sess->server->servername, sess->channel,
										  server_get_network (sess->server, FALSE));

	if (!log_error && sess->logfd == -1)
	{
		char *filename = log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE));
		char *message = g_strdup_printf (_("* Can't open log file(s) for writing. Check the\npermissions on %s"), filename);

		g_free (filename);

		fe_message (message, FE_MSG_WAIT | FE_MSG_ERROR);

		g_free (message);

		log_error = TRUE;
	}
}
Пример #14
0
static void
ctcp_reply (session *sess, char *nick, char *word[], char *word_eol[],
				char *conf)
{
	char tbuf[4096];	/* can receive 2048 from IRC, so this is enough */

	conf = strdup (conf);
	/* process %C %B etc */
	check_special_chars (conf, TRUE);
	auto_insert (tbuf, sizeof (tbuf), conf, word, word_eol, "", "", word_eol[5],
					 server_get_network (sess->server, TRUE), "", "", nick);
	free (conf);
	handle_command (sess, tbuf, FALSE);
}
Пример #15
0
static int
notify_netcmp (char *str, void *serv)
{
	char *net = despacify_dup (server_get_network (serv, TRUE));

	if (rfc_casecmp (str, net) == 0)
	{
		free (net);
		return 0;	/* finish & return FALSE from token_foreach() */
	}

	free (net);
	return 1;	/* keep going... */
}
Пример #16
0
void
signal_printer_notify_online(gpointer *params)
{
	session *sess  = params[0];
	gchar *nick    = params[1];
	server *serv   = params[2];

	gchar *servername = g_strdup((gchar *)serv->servername);
	gchar *network    = g_strdup((gchar *)server_get_network(serv, TRUE));

	session_print_format(sess, "notify online", nick, servername, network);

	g_free(servername);
	g_free(network);
}
Пример #17
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);
}
Пример #18
0
static char* scrollback_get_filename(session *sess, char *buf, int max)
{
	char *net, *chan;

	net = server_get_network(sess->server, FALSE);
	if (!net)
		return nullptr;

	snprintf(buf, max, "%s/scrollback/%s/%s.txt", get_xdir_fs(), net, "");
	mkdir_p(buf);

	chan = log_create_filename(sess->channel);
	snprintf(buf, max, "%s/scrollback/%s/%s.txt", get_xdir_fs(), net, chan);
	free(chan);

	return buf;
}
Пример #19
0
static char *
scrollback_get_filename (session *sess)
{
	char *net, *chan, *buf;

	net = server_get_network (sess->server, FALSE);
	if (!net)
		return NULL;

	buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "scrollback" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S "%s.txt", get_xdir (), net, "");
	mkdir_p (buf);
	g_free (buf);

	chan = log_create_filename (sess->channel);
	buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "scrollback" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S "%s.txt", get_xdir (), net, chan);
	free (chan);

	return buf;
}
Пример #20
0
const char* xchat_list_str(xchat_plugin *ph, xchat_list *xlist, const char *name)
{
	unsigned int hash = str_hash(name);
	void* data = ph->context;
	int type = LIST_CHANNELS;

	// a nullptr xlist is a shortcut to current "channels" context
	if (xlist)
	{
		data = xlist->pos->data;
		type = xlist->type;
	}

	switch (type)
	{
	case LIST_CHANNELS:
		switch (hash)
		{
		case 0x2c0b7d03: // channel
			return ((session*)data)->channel;
		case 0x577e0867: // chantypes
			return ((session*)data)->server->chantypes;
		case 0x38b735af: // context
			return (const char*)data;	// this is a session*
		case 0x6de15a2e: // network
			return server_get_network (((session*)data)->server, FALSE);
		case 0x8455e723: // nickprefixes
			return ((session*)data)->server->nick_prefixes;
		case 0x829689ad: // nickmodes
			return ((session*)data)->server->nick_modes;
		case 0xca022f43: // server
			return ((session*)data)->server->servername;
		}
		break;

	case LIST_DCC:
		switch (hash)
		{
		case 0x3d9ad31e:	// destfile
			return ((DCC*)data)->destfile;
		case 0x2ff57c:		// file
			return ((DCC*)data)->file;
		case 0x339763:		// nick
			return ((DCC*)data)->nick;
		}
		break;

	case LIST_IGNORE:
		switch (hash)
		{
		case 0x3306ec:	// mask
			return ((ignore*)data)->mask;
		}
		break;

	case LIST_NOTIFY:
		switch (hash)
		{
		case 0x4e49ec05:	// networks
			return ((notify*)data)->networks;
		case 0x339763:		// nick
			return ((notify*)data)->name;
		}
		break;

	case LIST_USERS:
		switch (hash)
		{
		case 0x339763: // nick
			return ((User*)data)->nick;
		case 0x30f5a8: // host
			return ((User*)data)->hostname;
		case 0xc594b292: // prefix
			return ((User*)data)->prefix;
		case 0xccc6d529: // realname
			return ((User*)data)->realname;
		}
		break;
	}

	return nullptr;
}
Пример #21
0
const char *
hexchat_list_str (hexchat_plugin *ph, hexchat_list *xlist, const char *name)
{
	guint32 hash = str_hash (name);
	gpointer data = ph->context;
	int type = LIST_CHANNELS;

	/* a NULL xlist is a shortcut to current "channels" context */
	if (xlist)
	{
		data = xlist->pos->data;
		type = xlist->type;
	}

	switch (type)
	{
	case LIST_CHANNELS:
		switch (hash)
		{
		case 0x2c0b7d03: /* channel */
			return ((session *)data)->channel;
		case 0x8cea5e7c: /* channelkey */
			return ((session *)data)->channelkey;
		case 0x5716ab1e: /* chanmodes */
			return ((session*)data)->server->chanmodes;
		case 0x577e0867: /* chantypes */
			return ((session *)data)->server->chantypes;
		case 0x38b735af: /* context */
			return data;	/* this is a session * */
		case 0x6de15a2e: /* network */
			return server_get_network (((session *)data)->server, FALSE);
		case 0x8455e723: /* nickprefixes */
			return ((session *)data)->server->nick_prefixes;
		case 0x829689ad: /* nickmodes */
			return ((session *)data)->server->nick_modes;
		case 0xca022f43: /* server */
			return ((session *)data)->server->servername;
		}
		break;

	case LIST_DCC:
		switch (hash)
		{
		case 0x3d9ad31e:	/* destfile */
			return ((struct DCC *)data)->destfile;
		case 0x2ff57c:	/* file */
			return ((struct DCC *)data)->file;
		case 0x339763: /* nick */
			return ((struct DCC *)data)->nick;
		}
		break;

	case LIST_IGNORE:
		switch (hash)
		{
		case 0x3306ec:	/* mask */
			return ((struct ignore *)data)->mask;
		}
		break;

	case LIST_NOTIFY:
		switch (hash)
		{
		case 0x4e49ec05:	/* networks */
			return ((struct notify *)data)->networks;
		case 0x339763: /* nick */
			return ((struct notify *)data)->name;
		}
		break;

	case LIST_USERS:
		switch (hash)
		{
		case 0xb9d38a2d: /* account */
			return ((struct User *)data)->account;
		case 0x339763: /* nick */
			return ((struct User *)data)->nick;
		case 0x30f5a8: /* host */
			return ((struct User *)data)->hostname;
		case 0xc594b292: /* prefix */
			return ((struct User *)data)->prefix;
		case 0xccc6d529: /* realname */
			return ((struct User *)data)->realname;
		}
		break;
	}

	return NULL;
}
Пример #22
0
const char *
hexchat_get_info (hexchat_plugin *ph, const char *id)
{
	session *sess;
	guint32 hash;

	/*                 1234567890 */
	if (!strncmp (id, "event_text", 10))
	{
		char *e = (char *)id + 10;
		if (*e == ' ') e++;	/* 2.8.0 only worked without a space */
		return text_find_format_string (e);
	}

	hash = str_hash (id);
	/* do the session independant ones first */
	switch (hash)
	{
		case 0x325acab5:	/* libdirfs */
#ifdef USE_PLUGIN
			return plugin_get_libdir ();
#else
			return NULL;
#endif

		case 0x14f51cd8: /* version */
			return PACKAGE_VERSION;

		case 0xdd9b1abd:	/* xchatdir */
		case 0xe33f6c4a:	/* xchatdirfs */
		case 0xd00d220b:	/* configdir */
			return get_xdir ();
	}

	sess = ph->context;
	if (!is_session (sess))
	{
		DEBUG(PrintTextf(0, "%s\thexchat_get_info called without a valid context.\n", ph->name));
		return NULL;
	}

	switch (hash)
	{
	case 0x2de2ee: /* away */
		if (sess->server->is_away)
			return sess->server->last_away_reason;
		return NULL;

  	case 0x2c0b7d03: /* channel */
		return sess->channel;

	case 0x2c0d614c: /* charset */
		{
			const char *locale;

			if (sess->server->encoding)
				return sess->server->encoding;

			locale = NULL;
			g_get_charset (&locale);
			return locale;
		}

	case 0x30f5a8: /* host */
		return sess->server->hostname;

	case 0x1c0e99c1: /* inputbox */
		return fe_get_inputbox_contents (sess);

	case 0x633fb30:	/* modes */
		return sess->current_modes;

	case 0x6de15a2e:	/* network */
		return server_get_network (sess->server, FALSE);

	case 0x339763: /* nick */
		return sess->server->nick;

	case 0x4889ba9b: /* password */
	case 0x438fdf9: /* nickserv */
		if (sess->server->network)
			return ((ircnet *)sess->server->network)->pass;
		return NULL;

	case 0xca022f43: /* server */
		if (!sess->server->connected)
			return NULL;
		return sess->server->servername;

	case 0x696cd2f: /* topic */
		return sess->topic;

	case 0x3419f12d: /* gtkwin_ptr */
		return fe_gui_info_ptr (sess, 1);

	case 0x506d600b: /* native win_ptr */
		return fe_gui_info_ptr (sess, 0);

	case 0x6d3431b5: /* win_status */
		switch (fe_gui_info (sess, 0))	/* check window status */
		{
		case 0: return "normal";
		case 1: return "active";
		case 2: return "hidden";
		}
		return NULL;
	}

	return NULL;
}
Пример #23
0
const char* xchat_get_info(xchat_plugin *ph, const char *id)
{
	session *sess;
	unsigned int hash;

	// 1234567890
	if (!strncmp(id, "event_text", 10))
	{
		char *e = (char*)id + 10;
		if (*e == ' ') e++;	// 2.8.0 only worked without a space
		return text_find_format_string(e);
	}

	hash = str_hash(id);
	// do the session independant ones first
	switch (hash)
	{
	case 0x325acab5:	// libdirfs
		return XCHATLIBDIR;

	case 0x14f51cd8: // version
		return PACKAGE_VERSION;

	case 0xdd9b1abd:	// xchatdir
		return get_xdir_utf8();

	case 0xe33f6c4a:	// xchatdirfs
		return get_xdir_fs();
	}

	sess = ph->context;
	if (!is_session(sess))
	{
		DEBUG(PrintTextf(0, "%s\txchat_get_info called without a valid context.\n", ph->name));
		return nullptr;
	}

	switch (hash)
	{
	case 0x2de2ee: // away
		if (sess->server->is_away)
			return sess->server->last_away_reason;
		return nullptr;

	case 0x2c0b7d03: // channel
		return sess->channel;

	case 0x2c0d614c: // charset
		{
			const char *locale;

			if (sess->server->encoding)
				return sess->server->encoding;

			locale = nullptr;
			g_get_charset(&locale);
			return locale;
		}

	case 0x30f5a8: // host
		return sess->server->hostname;

	case 0x1c0e99c1: // inputbox
		return fe_get_inputbox_contents(sess);

	case 0x633fb30:	// modes
		return sess->current_modes;

	case 0x6de15a2e:	// network
		return server_get_network(sess->server, FALSE);

	case 0x339763: // nick
		return sess->server->nick;

	case 0x438fdf9: // nickserv
		if (sess->server->network)
			return ((ircnet*)sess->server->network)->nickserv;
		return nullptr;

	case 0xca022f43: // server
		if (!sess->server->connected)
			return nullptr;
		return sess->server->servername;

	case 0x696cd2f: // topic
		return sess->topic;

	case 0x3419f12d: // gtkwin_ptr
		return (const char*)fe_gui_info_ptr(sess, 1);

	case 0x506d600b: // native win_ptr
		return (const char*)fe_gui_info_ptr(sess, 0);

	case 0x6d3431b5: // win_status
		switch (fe_gui_info(sess, 0))	// check window status
		{
		case 0: return "normal";
		case 1: return "active";
		case 2: return "hidden";
		}
		return nullptr;
	}

	return nullptr;
}
Пример #24
0
static void
joind_show_dialog (server *serv)
{
	GtkWidget *dialog1;
	GtkWidget *dialog_vbox1;
	GtkWidget *vbox1;
	GtkWidget *hbox1;
	GtkWidget *image1;
	GtkWidget *vbox2;
	GtkWidget *label;
	GtkWidget *radiobutton1;
	GtkWidget *radiobutton2;
	GtkWidget *radiobutton3;
	GSList *radiobutton1_group;
	GtkWidget *hbox2;
	GtkWidget *entry1;
	GtkWidget *checkbutton1;
	GtkWidget *dialog_action_area1;
	GtkWidget *okbutton1;
	char buf[256];
	char buf2[256];

	serv->gui->joind_win = dialog1 = gtk_dialog_new ();
	gtk_window_set_title (GTK_WINDOW (dialog1), _("XChat: Connection Complete"));
	gtk_window_set_type_hint (GTK_WINDOW (dialog1), GDK_WINDOW_TYPE_HINT_DIALOG);
	gtk_window_set_position (GTK_WINDOW (dialog1), GTK_WIN_POS_MOUSE);

	dialog_vbox1 = GTK_DIALOG (dialog1)->vbox;
	gtk_widget_show (dialog_vbox1);

	vbox1 = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (vbox1);
	gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 0);

	hbox1 = gtk_hbox_new (FALSE, 0);
	gtk_widget_show (hbox1);
	gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);

	image1 = gtk_image_new_from_stock ("gtk-yes", GTK_ICON_SIZE_DIALOG);
	gtk_widget_show (image1);
	gtk_box_pack_start (GTK_BOX (hbox1), image1, FALSE, TRUE, 24);
	gtk_misc_set_alignment (GTK_MISC (image1), 0.5, 0.06);

	vbox2 = gtk_vbox_new (FALSE, 10);
	gtk_container_set_border_width (GTK_CONTAINER (vbox2), 6);
	gtk_widget_show (vbox2);
	gtk_box_pack_start (GTK_BOX (hbox1), vbox2, TRUE, TRUE, 0);

	snprintf (buf2, sizeof (buf2), _("Connection to %s complete."),
				 server_get_network (serv, TRUE));
	snprintf (buf, sizeof (buf), "\n<b>%s</b>", buf2);
	label = gtk_label_new (buf);
	gtk_widget_show (label);
	gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

	label = gtk_label_new (_("In the Server-List window, no channel (chat room) has been entered to be automatically joined for this network."));
	gtk_widget_show (label);
	gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
	GTK_LABEL (label)->wrap = TRUE;
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

	label = gtk_label_new (_("What would you like to do next?"));
	gtk_widget_show (label);
	gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

	serv->gui->joind_radio1 = radiobutton1 = gtk_radio_button_new_with_mnemonic (NULL, _("_Nothing, I'll join a channel later."));
	gtk_widget_show (radiobutton1);
	gtk_box_pack_start (GTK_BOX (vbox2), radiobutton1, FALSE, FALSE, 0);
	radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton1));

	hbox2 = gtk_hbox_new (FALSE, 0);
	gtk_widget_show (hbox2);
	gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);

	serv->gui->joind_radio2 = radiobutton2 = gtk_radio_button_new_with_mnemonic (NULL, _("_Join this channel:"));
	gtk_widget_show (radiobutton2);
	gtk_box_pack_start (GTK_BOX (hbox2), radiobutton2, FALSE, FALSE, 0);
	gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton2), radiobutton1_group);
	radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton2));

	serv->gui->joind_entry = entry1 = gtk_entry_new ();
	gtk_entry_set_text (GTK_ENTRY (entry1), "#");
	gtk_widget_show (entry1);
	gtk_box_pack_start (GTK_BOX (hbox2), entry1, TRUE, TRUE, 8);

	snprintf (buf, sizeof (buf), "<small>     %s</small>",
				 _("If you know the name of the channel you want to join, enter it here."));
	label = gtk_label_new (buf);
	gtk_widget_show (label);
	gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

	radiobutton3 = gtk_radio_button_new_with_mnemonic (NULL, _("O_pen the Channel-List window."));
	gtk_widget_show (radiobutton3);
	gtk_box_pack_start (GTK_BOX (vbox2), radiobutton3, FALSE, FALSE, 0);
	gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton3), radiobutton1_group);
	radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton3));

	snprintf (buf, sizeof (buf), "<small>     %s</small>",
				 _("Retrieving the Channel-List may take a minute or two."));
	label = gtk_label_new (buf);
	gtk_widget_show (label);
	gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0);
	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
	gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);

	serv->gui->joind_check = checkbutton1 = gtk_check_button_new_with_mnemonic (_("_Always show this dialog after connecting."));
	if (prefs.gui_join_dialog)
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton1), TRUE);
	gtk_widget_show (checkbutton1);
	gtk_box_pack_start (GTK_BOX (vbox1), checkbutton1, FALSE, FALSE, 0);

	dialog_action_area1 = GTK_DIALOG (dialog1)->action_area;
	gtk_widget_show (dialog_action_area1);
	gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);

	okbutton1 = gtk_button_new_from_stock ("gtk-ok");
	gtk_widget_show (okbutton1);
	gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog1)->action_area), okbutton1, FALSE, TRUE, 0);
	GTK_WIDGET_SET_FLAGS (okbutton1, GTK_CAN_DEFAULT);

	g_signal_connect (G_OBJECT (dialog1), "destroy",
							G_CALLBACK (joind_destroy_cb), serv);
	g_signal_connect (G_OBJECT (entry1), "focus_in_event",
							G_CALLBACK (joind_entryfocus_cb), serv);
	g_signal_connect (G_OBJECT (entry1), "activate",
							G_CALLBACK (joind_entryenter_cb), okbutton1);
	g_signal_connect (G_OBJECT (radiobutton2), "toggled",
							G_CALLBACK (joind_radio2_cb), serv);
	g_signal_connect (G_OBJECT (okbutton1), "clicked",
							G_CALLBACK (joind_ok_cb), serv);

	gtk_widget_grab_focus (okbutton1);
	gtk_widget_show_all (dialog1);
}
Пример #25
0
void
notify_gui_update (void)
{
	struct notify *notify;
	struct notify_per_server *servnot;
	GSList *list = notify_list;
	GSList *slist;
	gchar *name, *status, *server, *seen;
	int online, servcount;
	time_t lastseen;
	char agobuf[128];

	GtkListStore *store;
	GtkTreeView *view;
	GtkTreeIter iter;
	gboolean valid;	/* true if we don't need to append a new tree row */

	if (!notify_window)
		return;

	view = g_object_get_data (G_OBJECT (notify_window), "view");
	store = GTK_LIST_STORE (gtk_tree_view_get_model (view));
	valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);

	while (list)
	{
		notify = (struct notify *) list->data;
		name = notify->name;
		status = _("Offline");
		server = "";

		online = FALSE;
		lastseen = 0;
		/* First see if they're online on any servers */
		slist = notify->server_list;
		while (slist)
		{
			servnot = (struct notify_per_server *) slist->data;
			if (servnot->ison)
				online = TRUE;
			if (servnot->lastseen > lastseen)
				lastseen = servnot->lastseen;
			slist = slist->next;
		}

		if (!online)				  /* Offline on all servers */
		{
			if (!lastseen)
				seen = _("Never");
			else
			{
				snprintf (agobuf, sizeof (agobuf), _("%d minutes ago"), (int)(time (0) - lastseen) / 60);
				seen = agobuf;
			}
			if (!valid)	/* create new tree row if required */
				gtk_list_store_append (store, &iter);
			gtk_list_store_set (store, &iter, 0, name, 1, status,
			                    2, server, 3, seen, 4, &colors[4], 5, NULL, -1);
			if (valid)
				valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);

		} else
		{
			/* Online - add one line per server */
			servcount = 0;
			slist = notify->server_list;
			status = _("Online");
			while (slist)
			{
				servnot = (struct notify_per_server *) slist->data;
				if (servnot->ison)
				{
					if (servcount > 0)
						name = "";
					server = server_get_network (servnot->server, TRUE);

					snprintf (agobuf, sizeof (agobuf), _("%d minutes ago"), (int)(time (0) - lastseen) / 60);
					seen = agobuf;

					if (!valid)	/* create new tree row if required */
						gtk_list_store_append (store, &iter);
					gtk_list_store_set (store, &iter, 0, name, 1, status,
					                    2, server, 3, seen, 4, &colors[3], 5, servnot, -1);
					if (valid)
						valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);

					servcount++;
				}
				slist = slist->next;
			}
		}
		
		list = list->next;
	}

	while (valid)
	{
		GtkTreeIter old = iter;
		/* get next iter now because removing invalidates old one */
		valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store),
                                      &iter);
		gtk_list_store_remove (store, &old);
	}
}
Пример #26
0
void
chanlist_opengui (server *serv, int do_refresh)
{
	GtkWidget *vbox, *hbox, *table, *wid, *view;
	char tbuf[256];
	GtkListStore *store;

	if (serv->gui->chanlist_window)
	{
		mg_bring_tofront (serv->gui->chanlist_window);
		return;
	}

	snprintf (tbuf, sizeof tbuf, _("XChat: Channel List (%s)"),
				 server_get_network (serv, TRUE));

	serv->gui->chanlist_pending_rows = NULL;
	serv->gui->chanlist_tag = 0;
	serv->gui->chanlist_flash_tag = 0;
	serv->gui->chanlist_data_stored_rows = NULL;

	if (!serv->gui->chanlist_minusers)
		serv->gui->chanlist_minusers = 5;

	if (!serv->gui->chanlist_maxusers)
		serv->gui->chanlist_maxusers = 9999;

	serv->gui->chanlist_window =
		mg_create_generic_tab ("ChanList", tbuf, FALSE, TRUE, chanlist_closegui,
								serv, 640, 480, &vbox, serv);

	gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
	gtk_box_set_spacing (GTK_BOX (vbox), 12);

	/* make a label to store the user/channel info */
	wid = gtk_label_new (NULL);
	gtk_box_pack_start (GTK_BOX (vbox), wid, 0, 0, 0);
	gtk_widget_show (wid);
	serv->gui->chanlist_label = wid;

	/* ============================================================= */

	store = (GtkListStore *) custom_list_new();
	view = gtkutil_treeview_new (vbox, GTK_TREE_MODEL (store), NULL, -1);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (view->parent),
													 GTK_SHADOW_IN);
	serv->gui->chanlist_list = view;

	g_signal_connect (G_OBJECT (view), "row_activated",
							G_CALLBACK (chanlist_dclick_cb), serv);
	g_signal_connect (G_OBJECT (view), "button-press-event",
							G_CALLBACK (chanlist_button_cb), serv);

	chanlist_add_column (view, COL_CHANNEL, 96, _("Channel"), FALSE);
	chanlist_add_column (view, COL_USERS,   50, _("Users"),   TRUE);
	chanlist_add_column (view, COL_TOPIC,   50, _("Topic"),   FALSE);
	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
	/* this is a speed up, but no horizontal scrollbar :( */
	/*gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE);*/
	gtk_widget_show (view);

	/* ============================================================= */

	table = gtk_table_new (4, 4, FALSE);
	gtk_table_set_col_spacings (GTK_TABLE (table), 12);
	gtk_table_set_row_spacings (GTK_TABLE (table), 3);
	gtk_box_pack_start (GTK_BOX (vbox), table, 0, 1, 0);
	gtk_widget_show (table);

	wid = gtkutil_button (NULL, GTK_STOCK_FIND, 0, chanlist_search_pressed, serv,
								 _("_Search"));
	serv->gui->chanlist_search = wid;
	gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 3, 4,
							GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);

	wid = gtkutil_button (NULL, GTK_STOCK_REFRESH, 0, chanlist_refresh, serv,
								 _("_Download List"));
	serv->gui->chanlist_refresh = wid;
	gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 2, 3,
							GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);

	wid = gtkutil_button (NULL, GTK_STOCK_SAVE_AS, 0, chanlist_save, serv,
								 _("Save _List..."));
	serv->gui->chanlist_savelist = wid;
	gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 1, 2,
							GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);

	wid = gtkutil_button (NULL, GTK_STOCK_JUMP_TO, 0, chanlist_join, serv,
						 _("_Join Channel"));
	serv->gui->chanlist_join = wid;
	gtk_table_attach (GTK_TABLE (table), wid, 3, 4, 0, 1,
							GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);

	/* ============================================================= */

	wid = gtk_label_new (_("Show only:"));
	gtk_misc_set_alignment (GTK_MISC (wid), 0, 0.5);
	gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 3, 4,
							GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
	gtk_widget_show (wid);

	hbox = gtk_hbox_new (0, 0);
	gtk_box_set_spacing (GTK_BOX (hbox), 9);
	gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 3, 4,
							GTK_FILL, GTK_FILL, 0, 0);
	gtk_widget_show (hbox);

	wid = gtk_label_new (_("channels with"));
	gtk_box_pack_start (GTK_BOX (hbox), wid, 0, 0, 0);
	gtk_widget_show (wid);

	wid = gtk_spin_button_new_with_range (1, 999999, 1);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (wid),
										serv->gui->chanlist_minusers);
	g_signal_connect (G_OBJECT (wid), "value_changed",
							G_CALLBACK (chanlist_minusers), serv);
	gtk_box_pack_start (GTK_BOX (hbox), wid, 0, 0, 0);
	gtk_widget_show (wid);
	serv->gui->chanlist_min_spin = wid;

	wid = gtk_label_new (_("to"));
	gtk_box_pack_start (GTK_BOX (hbox), wid, 0, 0, 0);
	gtk_widget_show (wid);

	wid = gtk_spin_button_new_with_range (1, 999999, 1);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (wid),
										serv->gui->chanlist_maxusers);
	g_signal_connect (G_OBJECT (wid), "value_changed",
							G_CALLBACK (chanlist_maxusers), serv);
	gtk_box_pack_start (GTK_BOX (hbox), wid, 0, 0, 0);
	gtk_widget_show (wid);

	wid = gtk_label_new (_("users."));
	gtk_box_pack_start (GTK_BOX (hbox), wid, 0, 0, 0);
	gtk_widget_show (wid);

	/* ============================================================= */

	wid = gtk_label_new (_("Look in:"));
	gtk_misc_set_alignment (GTK_MISC (wid), 0, 0.5);
	gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 2, 3,
							GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
	gtk_widget_show (wid);

	hbox = gtk_hbox_new (0, 0);
	gtk_box_set_spacing (GTK_BOX (hbox), 12);
	gtk_table_attach (GTK_TABLE (table), hbox, 1, 2, 2, 3,
							GTK_FILL, GTK_FILL, 0, 0);
	gtk_widget_show (hbox);

	wid = gtk_check_button_new_with_label (_("Channel name"));
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wid), TRUE);
	gtk_signal_connect (GTK_OBJECT (wid), "toggled",
							  GTK_SIGNAL_FUNC
							  (chanlist_match_channel_button_toggled), serv);
	gtk_box_pack_start (GTK_BOX (hbox), wid, 0, 0, 0);
	gtk_widget_show (wid);

	wid = gtk_check_button_new_with_label (_("Topic"));
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wid), TRUE);
	gtk_signal_connect (GTK_OBJECT (wid), "toggled",
							  GTK_SIGNAL_FUNC (chanlist_match_topic_button_toggled),
							  serv);
	gtk_box_pack_start (GTK_BOX (hbox), wid, 0, 0, 0);
	gtk_widget_show (wid);

	serv->gui->chanlist_match_wants_channel = 1;
	serv->gui->chanlist_match_wants_topic = 1;

	/* ============================================================= */

	wid = gtk_label_new (_("Search type:"));
	gtk_misc_set_alignment (GTK_MISC (wid), 0, 0.5);
	gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 1, 2,
							GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
	gtk_widget_show (wid);

	wid = gtk_combo_box_new_text ();
	gtk_combo_box_append_text (GTK_COMBO_BOX (wid), _("Simple Search"));
	gtk_combo_box_append_text (GTK_COMBO_BOX (wid), _("Pattern Match (Wildcards)"));
#ifndef WIN32
	gtk_combo_box_append_text (GTK_COMBO_BOX (wid), _("Regular Expression"));
#endif
	gtk_combo_box_set_active (GTK_COMBO_BOX (wid), serv->gui->chanlist_search_type);
	gtk_table_attach (GTK_TABLE (table), wid, 1, 2, 1, 2,
							GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
	g_signal_connect (G_OBJECT (wid), "changed",
							G_CALLBACK (chanlist_combo_cb), serv);
	gtk_widget_show (wid);

	/* ============================================================= */

	wid = gtk_label_new (_("Find:"));
	gtk_misc_set_alignment (GTK_MISC (wid), 0, 0.5);
	gtk_table_attach (GTK_TABLE (table), wid, 0, 1, 0, 1,
							GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
	gtk_widget_show (wid);

	wid = gtk_entry_new_with_max_length (255);
	gtk_signal_connect (GTK_OBJECT (wid), "changed",
							  GTK_SIGNAL_FUNC (chanlist_find_cb), serv);
	gtk_signal_connect (GTK_OBJECT (wid), "activate",
							  GTK_SIGNAL_FUNC (chanlist_search_pressed),
							  (gpointer) serv);
	gtk_table_attach (GTK_TABLE (table), wid, 1, 2, 0, 1,
							GTK_EXPAND | GTK_FILL, 0, 0, 0);
	gtk_widget_show (wid);
	serv->gui->chanlist_wild = wid;

	chanlist_find_cb (wid, serv);

	/* ============================================================= */

	wid = gtk_vseparator_new ();
	gtk_table_attach (GTK_TABLE (table), wid, 2, 3, 0, 5,
							GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
	gtk_widget_show (wid);

	g_signal_connect (G_OBJECT (serv->gui->chanlist_window), "destroy",
							G_CALLBACK (chanlist_destroy_widget), serv);

	/* reset the counters. */
	chanlist_reset_counters (serv);

	serv->gui->chanlist_tag = g_timeout_add (250, (GSourceFunc)chanlist_timeout, serv);

	if (do_refresh)
		chanlist_do_refresh (serv);

	chanlist_update_buttons (serv);
	gtk_widget_show (serv->gui->chanlist_window);
	gtk_widget_grab_focus (serv->gui->chanlist_refresh);
}
Пример #27
0
int
chanopt_command (session *sess, char *tbuf, char *word[], char *word_eol[])
{
	int dots, i = 0, j, p = 0;
	guint8 val;
	int offset = 2;
	char *find;
	gboolean quiet = FALSE;
	int newval = -1;

	if (!strcmp (word[2], "-quiet"))
	{
		quiet = TRUE;
		offset++;
	}

	find = word[offset++];

	if (word[offset][0])
	{
		if (!g_ascii_strcasecmp (word[offset], "ON"))
			newval = 1;
		else if (!g_ascii_strcasecmp (word[offset], "OFF"))
			newval = 0;
		else if (word[offset][0] == 'u')
			newval = SET_DEFAULT;
		else
			newval = atoi (word[offset]);
	}

	if (!quiet)
		PrintTextf (sess, "\002Network\002: %s \002Channel\002: %s\n",
						sess->server->network ? server_get_network (sess->server, TRUE) : _("<none>"),
						sess->channel[0] ? sess->channel : _("<none>"));

	while (i < sizeof (chanopt) / sizeof (channel_options))
	{
		if (find[0] == 0 || match (find, chanopt[i].name) || (chanopt[i].alias && match (find, chanopt[i].alias)))
		{
			if (newval != -1)	/* set new value */
			{
				*(guint8 *)G_STRUCT_MEMBER_P(sess, chanopt[i].offset) = newval;
			}

			if (!quiet)	/* print value */
			{
				strcpy (tbuf, chanopt[i].name);
				p = strlen (tbuf);

				tbuf[p++] = 3;
				tbuf[p++] = '2';

				dots = 20 - strlen (chanopt[i].name);

				for (j = 0; j < dots; j++)
					tbuf[p++] = '.';
				tbuf[p++] = 0;

				val = G_STRUCT_MEMBER (guint8, sess, chanopt[i].offset);
				PrintTextf (sess, "%s\0033:\017 %s", tbuf, chanopt_value (val));
			}
		}
		i++;
	}

	return TRUE;
}