From ca36726bf7b495fc8054e5c9acf93be6f155b8a0 Mon Sep 17 00:00:00 2001
From: Přemysl Janouch <p.janouch@gmail.com>
Date: Fri, 22 May 2015 22:13:28 +0200
Subject: degesch: parse and use RPL_USERHOST

---
 degesch.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 45 insertions(+), 3 deletions(-)

diff --git a/degesch.c b/degesch.c
index 6aff5f7..4bcb1d9 100644
--- a/degesch.c
+++ b/degesch.c
@@ -4335,9 +4335,7 @@ irc_on_registered (struct server *s, const char *nickname)
 	s->state = IRC_REGISTERED;
 	refresh_prompt (s->ctx);
 
-	// TODO: parse any response and store the result for us in app_context;
-	//   this enables proper message splitting on output;
-	//   we can also use WHOIS if it's not supported (optional by RFC 2812)
+	// XXX: we can also use WHOIS if it's not supported (optional by RFC 2812)
 	irc_send (s, "USERHOST %s", s->irc_user->nickname);
 
 	const char *autojoin = get_config_string (s->config, "autojoin");
@@ -4347,6 +4345,47 @@ irc_on_registered (struct server *s, const char *nickname)
 	// TODO: rejoin all current channels (mark those we've left manually?)
 }
 
+static void
+irc_handle_rpl_userhost (struct server *s, const struct irc_message *msg)
+{
+	if (msg->params.len < 2)
+		return;
+
+	const char *response = msg->params.vector[1];
+	struct str_vector v;
+	str_vector_init (&v);
+	split_str_ignore_empty (response, ' ', &v);
+
+	for (size_t i = 0; i < v.len; i++)
+	{
+		char *nick = v.vector[i];
+		char *equals = strchr (nick, '=');
+
+		if (!equals || equals == nick)
+			continue;
+
+		// User is an IRC operator
+		if (equals[-1] == '*')
+			equals[-1] = '\0';
+		else
+			equals[ 0] = '\0';
+
+		// TODO: make use of this (away status polling?)
+		char away_status = equals[1];
+		if (!strchr ("+-", away_status))
+			continue;
+
+		char *userhost = equals + 2;
+		if (irc_is_this_us (s, nick))
+		{
+			free (s->irc_user_host);
+			s->irc_user_host = xstrdup (userhost);
+		}
+	}
+
+	str_vector_free (&v);
+}
+
 static void
 irc_process_numeric (struct server *s,
 	const struct irc_message *msg, unsigned long numeric)
@@ -4386,6 +4425,9 @@ irc_process_numeric (struct server *s,
 		// TODO: initialize key_strxfrm according to server properties;
 		//   note that collisions may arise on reconnecting
 		break;
+	case IRC_RPL_USERHOST:
+		irc_handle_rpl_userhost (s, msg);
+		break;
 	case IRC_RPL_NAMREPLY:
 		// TODO: find the channel and if found, push nicks to names_buf
 		break;
-- 
cgit v1.2.3-70-g09d2