$NetBSD: patch-ab,v 1.2 2010/05/17 20:13:25 sketch Exp $

--- src/fe-common/fe-icb.c.orig	2002-04-27 21:56:18.000000000 +0100
+++ src/fe-common/fe-icb.c	2010-05-17 20:52:23.000000000 +0100
@@ -18,12 +18,15 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
+#include <time.h>
+
 #include "module.h"
 #include "module-formats.h"
 #include "signals.h"
 #include "commands.h"
 #include "servers-setup.h"
 #include "levels.h"
+#include "nicklist.h"
 
 #include "icb.h"
 #include "icb-servers.h"
@@ -33,16 +36,84 @@
 #include "printtext.h"
 #include "themes.h"
 
+static void icb_channel_change_topic(ICB_SERVER_REC *server,
+				const char *topic, const char *setby,
+				time_t settime)
+{
+	if (topic != NULL) {
+		g_free_not_null(server->group->topic);
+		server->group->topic = g_strdup(topic);
+	}
+
+	if (setby != NULL) {
+		g_free_not_null(server->group->topic_by);
+		server->group->topic_by = g_strdup(setby);
+	}
+
+	server->group->topic_time = settime;
+
+	signal_emit("channel topic changed", 1, server->group);
+}
+
 static void event_status(ICB_SERVER_REC *server, const char *data)
 {
 	char **args;
+	int len;
+	char *oldnick, *newnick;
+	char *topic, *setby, *p1, *p2;
 
 	/* FIXME: status messages should probably divided into their own
 	   signals so irssi could track joins, parts, etc. */
 	args = icb_split(data, 2);
 	printformat(server, server->group->name, MSGLEVEL_CRAP,
 		    ICBTXT_STATUS, args[0], args[1]);
-        icb_split_free(args);
+
+	len = strlen("Name");
+	if (strncmp(args[0],"Name",len) == 0) {
+		oldnick = g_strdup(args[1]);
+		p2 = strchr(oldnick, ' ');
+		if (p2 != NULL) {
+			*p2 = '\0';
+			/* make sure it's me changing the nick */
+			if (strcmp(oldnick, server->connrec->nick) == 0) {
+				newnick = strrchr(args[1], ' ');
+				if (newnick != NULL) {
+					newnick++;  /* skip the space */
+					server_change_nick(SERVER(server), newnick);
+					nicklist_rename(SERVER(server), server->connrec->nick, newnick);
+					g_free(server->connrec->nick);
+					server->connrec->nick = g_strdup(newnick);
+				}
+			}
+		}
+		g_free(oldnick);
+	}
+
+	/* sample topic msg: nick changed the topic to \"test 1\" */
+	len = strlen("Topic");
+	if (strncmp(args[0],"Topic",len) == 0) {
+		p1 = strchr(args[1], '"');
+		p2 = strrchr(args[1], '"');
+
+		/* make sure there's something between those quotes */
+		if (p1) {
+			p1++;
+			topic = g_strdup(p1);
+			p2 = strrchr(topic, '"');
+			*p2 = '\0';
+
+			setby = g_strdup(args[1]);
+			p2 = strchr(setby, ' ');
+			*p2 = '\0';
+
+			icb_channel_change_topic(server, topic, setby, time(NULL));
+
+			g_free(topic);
+			g_free(setby);
+		}
+	}
+
+	icb_split_free(args);
 }
 
 static void event_error(ICB_SERVER_REC *server, const char *data)
@@ -84,12 +155,67 @@
         icb_split_free(args);
 }
 
+static void idle_time(char *buf, size_t bufsize, time_t idle)
+{
+#define MIN_LEN		60UL
+#define HOUR_LEN	3600UL
+#define DAY_LEN		86400UL
+#define WEEK_LEN	604800UL
+
+	if (idle >= WEEK_LEN)
+		snprintf(buf, bufsize, "%2dw%2dd",
+			 (int)(idle/WEEK_LEN), (int)((idle%WEEK_LEN)/DAY_LEN));
+	else if (idle >= DAY_LEN)
+		snprintf(buf, bufsize, "%2dd%2dh",
+			 (int)(idle/DAY_LEN), (int)((idle%DAY_LEN)/HOUR_LEN));
+	else if (idle >= HOUR_LEN)
+		snprintf(buf, bufsize, "%2dh%2dm",
+			 (int)(idle/HOUR_LEN), (int)((idle%HOUR_LEN)/MIN_LEN));
+	else if (idle >= MIN_LEN)
+		snprintf(buf, bufsize, "%2dm%2ds",
+			 (int)(idle/MIN_LEN), (int)(idle%MIN_LEN));
+	else
+		snprintf(buf, bufsize, "   %2ds", (int)idle);
+}
+
+static void cmdout_wl(ICB_SERVER_REC *server, char **args)
+{
+	struct tm *logintime;
+	char logbuf[20];
+	char idlebuf[20];
+	char line[255];
+	time_t temptime;
+
+	/* "wl" : In a who listing, a line of output listing a user. Has the following format:
+
+	* Field 1: String indicating whether user is moderator or not. Usually "*" for
+	* moderator, and " " for not.
+	* Field 2: Nickname of user.
+	* Field 3: Number of seconds user has been idle.
+	* Field 4: Response Time. No longer in use.
+	* Field 5: Login Time. Unix time_t format. Seconds since Jan. 1, 1970 GMT.
+	* Field 6: Username of user.
+	* Field 7: Hostname of user.
+	* Field 8: Registration status.
+	*/
+	temptime = strtol(args[4], NULL, 10);
+	logintime = gmtime(&temptime);
+	strftime(logbuf, sizeof(logbuf), "%b %e %H:%M", logintime);
+	temptime = strtol(args[2], NULL, 10);
+	idle_time(idlebuf, sizeof(idlebuf), temptime);
+
+	snprintf(line, sizeof(line), "*** %c%-14.14s %6.6s %12.12s %s@%s %s",
+		  args[0][0] == ' '?' ':'*', args[1], idlebuf, logbuf, args[5],
+		  args[6], args[7]);
+	printtext(server, NULL, MSGLEVEL_CRAP, line);
+}
+
 static void cmdout_default(ICB_SERVER_REC *server, char **args)
 {
 	char *data;
 
 	data = g_strjoinv(" ", args+1);
-	printtext(server, server->group->name, MSGLEVEL_CRAP, "%s", data);
+	printtext(server, NULL, MSGLEVEL_CRAP, "%s", data);
         g_free(data);
 }
 
@@ -115,6 +241,7 @@
         signal_add("icb event beep", (SIGNAL_FUNC) event_beep);
         signal_add("icb event open", (SIGNAL_FUNC) event_open);
         signal_add("icb event personal", (SIGNAL_FUNC) event_personal);
+        signal_add("icb cmdout wl", (SIGNAL_FUNC) cmdout_wl);
         signal_add("default icb cmdout", (SIGNAL_FUNC) cmdout_default);
 
 	signal_add("server add fill", (SIGNAL_FUNC) sig_server_add_fill);
@@ -131,6 +258,7 @@
         signal_remove("icb event beep", (SIGNAL_FUNC) event_beep);
         signal_remove("icb event open", (SIGNAL_FUNC) event_open);
         signal_remove("icb event personal", (SIGNAL_FUNC) event_personal);
+        signal_remove("icb cmdout wl", (SIGNAL_FUNC) cmdout_wl);
         signal_remove("default icb cmdout", (SIGNAL_FUNC) cmdout_default);
 
 	signal_remove("server add fill", (SIGNAL_FUNC) sig_server_add_fill);
